From 37f7b81d959d8a2327cdd1a654ca628b40b35d98 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 22 Feb 2019 08:29:35 +0100 Subject: [PATCH 001/764] Updated config files to reflect name change --- .travis.yml | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 72862aafe..041c04bae 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,4 +16,4 @@ deploy: secure: zXFXK1GohutgqKXQ101uKcJKcf0wgCuVPFMY44Xl/JwXeLsA1CJ4aqUdoXh2ramcI+9wTVj7RR3N3/7W+2DeDCfUlj+gxw26pTV3EUnU2B1TXEz01Ar07WPHmhHJSS5tgyo9kPUqm/YBFkJuDtfx0Kp3sL6IRYDddvGv/2L1X8r3I14PxgppkU9T4FGINdClOEwfwelmxx3kjxpnTsUHZ+ztx7o+blteSf/r+pT1RDaIap80JaTy6vHwJKECRSvtpyTKEYeVmBIaA3yXqRhfMdlp8bU20t2DXoDGXWPk0GXRGXkVHE6yj64gPe/eOOesAxzv0v/vr5w4poemJ+SGwP3RSbrbVtiusD4FC6+hFBH7hiNUhxww5euvbAfNOTq2XyxtjcNmKB5/O675xGihK1gBgrsPdJ4enwkhQNrUuQBHm5wIKGiaH7t7q+T8W9JAnk3FGGuSZPg9b7AnFDQ3graxZK9mtOxi0GvE7DHinH6qErd4noGjS/KSy1fnDkCEkeplOQmvxb4w7wLMR5pePFc77NBXiR3RJDKh4QKskcvXPx58OWNffTkS2QwYPYhraNNKbUfGFBNEA4KPNmw1jYlDE/1BhOebmONpZQMP/CdcCWL+CKyTdi1/289Ak4B0iSZZN+Yx+AONzPlcvBVi+bXeXtqoIt2zMFKkr/0YFQg= on: tags: true - repo: Perryvw/TypescriptToLua + repo: Perryvw/TypeScriptToLua diff --git a/README.md b/README.md index 256287258..16ce33a05 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ A generic TypeScript to Lua transpiler. Write your code in TypeScript and publis Large projects written in lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good IDE support. This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. -[![Build Status](https://travis-ci.org/Perryvw/TypescriptToLua.svg?branch=master)](https://travis-ci.org/Perryvw/TypescriptToLua) +[![Build Status](https://travis-ci.org/Perryvw/TypeScriptToLua.svg?branch=master)](https://travis-ci.org/Perryvw/TypeScriptToLua) [![Build status](https://ci.appveyor.com/api/projects/status/github/perryvw/typescripttolua?branch=master&svg=true)](https://ci.appveyor.com/project/Perryvw/typescripttolua) [![Coverage](https://codecov.io/gh/perryvw/typescripttolua/branch/master/graph/badge.svg)](https://codecov.io/gh/perryvw/typescripttolua) From 68f36814fc7c826826e4717a9ad0fc34b5527f1a Mon Sep 17 00:00:00 2001 From: Endel Dreyer Date: Fri, 22 Feb 2019 19:47:31 -0300 Subject: [PATCH 002/764] =?UTF-8?q?add=20logo=20on=20readme=20=F0=9F=92=85?= =?UTF-8?q?=20(#441)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update README. add logo * update readme * update readme * update readme * update badges * update badges * update badges * fix links on badges on readme * fix link to travis --- README.md | 19 ++++++++++++------- logo-hq.png | Bin 0 -> 69910 bytes 2 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 logo-hq.png diff --git a/README.md b/README.md index 16ce33a05..4e6eec1ac 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,19 @@ -# TypeScriptToLua +
+ TypeScriptToLua +

+ TypeScriptToLua +

+ Build status + Build status + Coverage + Chat with us! +

+
+ A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua! Large projects written in lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good IDE support. This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. -[![Build Status](https://travis-ci.org/Perryvw/TypeScriptToLua.svg?branch=master)](https://travis-ci.org/Perryvw/TypeScriptToLua) -[![Build status](https://ci.appveyor.com/api/projects/status/github/perryvw/typescripttolua?branch=master&svg=true)](https://ci.appveyor.com/project/Perryvw/typescripttolua) -[![Coverage](https://codecov.io/gh/perryvw/typescripttolua/branch/master/graph/badge.svg)](https://codecov.io/gh/perryvw/typescripttolua) - -You can chat with us on [Discord: ![Discord](https://img.shields.io/discord/515854149821267971.svg)](https://discord.gg/BWAq58Y) - ## Documentation More detailed documentation and info on writing declarations can be found [on the wiki](https://github.com/Perryvw/TypescriptToLua/wiki). diff --git a/logo-hq.png b/logo-hq.png new file mode 100644 index 0000000000000000000000000000000000000000..a60542a975936e88c8709cfc7b6ed64161650630 GIT binary patch literal 69910 zcmbTeXH=6x*EV`13IYNu0@6_wRC@0qO(_Bz=~a3s^bSE#P?2JxiGWHCE%e?5DM}Lw zU3w3l5IW>ceBS3h=f}6cAIG&^gm}-~Gkf;za$S4-`mxqSN^(YW2!bfpRFz>6M2rQ0 zcP^5EZv?)?5`HjvsTg=Yh1+`hT6ow%3f6E-8+J7p3p*Q_jfJ(p`%fDgFv8P8$H2=# z^O2Ml+=b7A@C=`yiyIgXK{E1wZWdNfHeT$OHg*oKvNt#Dnr^Z?Sj*nj7u6KdbW^gi zcTf%Ruz4DwrDGM~WF={RQ(lf;#!m`N;9}!t!S3hc?CL4yCwueXyi(vZ;cNbz?EfC| za+1CIpG6sHK4w>fd)Tmx@`>?U35p1?i%aqeiV28_3i7ZE2?&bw3yAUyi17*tN(o3v z2??_Q&!3y%Z64OPQZVHQ|MM>Jo9s<{FE2MKetutHUp`-9KDdV+zo4X~B)@zsf@uH&2$|@2MM1)j?l?4S=Bo!5f1QdkC#KiN~D=D$x z(X_B~a3%bHmvBb^*|M^Yhl7ue^#c#M3;RDIOF8@>79eCTAz~wFA;2qPBWT4dB4KOE zDz{y&=Y->-l=5?WNST96GDXFHcpyM~THbELRxO>#G?ZvNdtT$Tswp88Nn&PIA^&Jfb<;O(s zb3?1p=jDctuFLgzn3OMn{2E3cR#532*N{_C`Mcq)FO~$K`!;Rw?dN%HNCRv5@29^$ zn7^Oezs0rP+0``wL7{@y*4EedcXzwDx3|^4GC|O^QN05Z1gRt@CmZs}%F6Qa^75_) zbgiv9%ag6$*ug0n8X7(?y_A5bPMD&8Jf#$js`Xy&ty?Xs3#jR8I^CLSEz~P85Nzq| z;~$-x!Ux^I-+aiO@LK<{0h^YVHu{zkf-VA!G@`4e6$4jSS5J}k7ug`iTKa?*C2?!n;7~MR%;G}!LsJ(=hYqW>Mp#&qYA=mrJ^?S(l>V)0({@a z$J6R04S$wLG)CkxY3bEB41i^XfZK6kpsLz=rQ#!Aze$d#Nv`PZQ43y;nwnZp`r^Nt zpV2M#rbZdmdaVRr9pcVyF6ymJ;bpFSpMkp7+1tC9=xy+Hu%fYjU_e+S?39dlS4l~U z`sK@)>mSCXjyj*UIa5vH4!r}|POKH(k*ZJv))0FtT1EJRr1;7vhJ8mor_ z9;brjL1F`LtDoNRHo|;F-#~`LNUcw^`-5A6=Xh|@?ResLcfRn%_`@FoXeQe9B|dpn zUGxP_>5d0P&Gug#N_j9Eq8}aEb(N^MW_&t>65$v|+txl$b?Uw2%u02acVnD4@B&Uz z0@P6G2jb6xKvl6ieW{7&*|n{Gt6H&tuv=T5WMpKLKj?_AQQ9r6U;S&WDjNT$zcn!T zdq}ri!>6-#J8g7pa2Q$&Ie0#Zu&NjSsUelpgPI{j_kCCL1Kyg3i;G#8sz7cYeyDp< zdoY(Q*Mz+Jc04mKTgj<`4}TofIjfIcfOXya%Vu3jvq%Jylm#mnEUgUWa5U7{ml`2z z5s6GM4}&+*cBhj&<`#llJ}NJO02|LlqjrP_nYLlp84D zvT&uHz0^E4CEwrC!KHFo!)K5@-1ubn)4iZEsQ^X=qS9 z^^F!kkdXMo@~n>J;tmzr7DjV~57w{?u{qE9p&x|y56I~tk4n6EHxQMs1qh$^8hT@=eUhVcZ$kx`j_(S{m5Z`fD-;KZi599CYhVYu!?ou(x*Q{kh zN*DaRNe{=fj?}yp$-i*pzf8_AXXt<0T{AZ9eQ$L0yIlC*wX}z3W~`Y_Ir3n`Ge$4OF(O`L^ zV0vn#c1V4_V0~v&mVg@BEuSu^zSX_3nqX3sH1iY z{91+Ale09lhJXpr;b8~ii7bBMz=KI~#M#MD%rK_s3pwq*0+dk&#zS|ZD=`*@4^R}# zAnk22JZ$PN860>*qCxq4hwTdKII`nScig92R!$u2#VmGZeUd_U&C);`L3b_7{G|kKeB*WoDcnq*`%B zl4cq8zq`r(btQ3D13uifBaBRznQEMt5Qd+nQfWd3ER(Xj(+R&PjV|~iQw9yS1B3BJ zrgd^6({+Ezyci#p&a{zOB!)Mj7i@HKf#D>Sj!egsd%_z#aQ|=4EsIZcv_yG2hx52K z?&%lR!!87R8#cZ;j=s84cKu2*DR+8&;$eBM<@yuk4cKi4N-A$X$8YHC44w}iNG;L? zsGDJEJLmoN@nMV2$p#i`W(hYZM@PrI4^K@61qEr+VyO|Yiir2BR?MTrfXNLuTXZyg z>EBTM?i=~uV7|V&QO1MlEOGpP^QITLuPKZD7)+U6#Ytc5u>kpJ^@b}*xvMxfhCt*0 zdD%y?`Vn?7{Ml)hT7|y%*~uZM_o%KbfwyjZj;6oA;6n3RBh%w=t>q2_A;rV{6qhc^ zaLk<1lkImo4iy|KVX1xDzICy8ntPuW6h$!H_0F-4Ov(PHs$*cvE~?l*LpP?7#MMpg z=7jOwhZUG_I7Ob4^D4h{~t-|m!AvdUDixX{F+?0AXxaHvmpjZHyi(hsp9ekjyI{=pbk zIP$)I`}U-E60`%M;$p z(Molkr;_*d^4eYEzx9!&WsG=jX}BYAkVV+Gn~LLv2jd=c51kM5{kdc%dfuO=J9cn% zUjYVJkGImStDu3QRD}hKKMi!dlU)bAtSm(1|+sZDlWrl=h z`Cw*(E6BHY@J++O*LHn6$87hP7s(NFiW}DV@bsh%oNWVc}(C6wthvLYOV_$CX`f0bo3&Mq+2C5*6LStP?kmu!uEQ8%W7_b1Nl zpG*(}IKs_;T;s724=x8@?d8F8zj0rg9<(%m;-NGBnug1gidAMrFRzDin07Wc7Z|tg zbhRt5OL^HlkC#OHv5F{6zQWG9mOkG1K{kJ?IPXoY?VWIDT!vSw>1Ks4J(%!P??Rl9 zYE5@p-P}yS^F28J9&T-AYip|~kyYDU=gh6**VepWvo2#p#a&%GZc*O*c^gdQ4=-&= zc`iOmZH=U^`b!8CaelwhXf*7>fg$m^bG-?CrU7-?+sgsh@BN@pY~z9vuS8_!io4Kt z9;M&x>bQ;OO2M)HO7_QY{;)qc9TAZ@mE<=2QnB z8o|^U;tjiTC&5WadH3btUsJNiR4aNrJ1@Go^(C@b&3(&;A%R5Y8=Qs*rk@U!HYYaYi9dAP5T{>b|oMsCi8Vwa1`xen5V&czn zyzpZ)eETs#;a60QftfCHL5OcscTQ0;I3fAW9fX2-s%TEg)qeChc?k`d77v=lq{yV^ zJndgyWZ72qE`D?z@2^FI|#ga^Clh5 zyhSMclmeY_rurXBlkk8KcHwX118@Dt+eaWS6Yhjn2DlT9EWxwbXeMzvzvyDb%35Hd zQ3YLI*(UBm+tP1AsM28DelVcUcXOlGX}HK0qjf06#e<%!J;JRHulF*jQLNiCd+>I_)oH}M|0eXge3R_m{VDh1BGU<* zQAu9j!XKhb4Da4~K5#|_(3^5}*FB3dHl((qG;q2TRtPhlzmoa*SY!jr zlgam*@MnR2*rmSV>Yctou(+ze&*)LFHv*gUhc0h<8b93YU<_yZj3y2~XTeHHN}j3b zM?Tbf`aJ}A{a~$Bslnw@yL8H7csXfUec58Auj64~EVX6y_ZajC1RA^CbfY^Q1nSTu z-i?~hEl&KT`x~vxi>VSQmU~epjN-N7R=G@bvNy-SpZ7g{E^BB9b-S+S_cxm3sFsiC zragL=NuUu@1y(JpoxV;>83k6V%=RI_;DVY9z1=B@j)yeQ44dTi3OB|ooFd`lmFpY8 zwZy%8^-2Z45i=cA1wkj#@A`gq1^ImBF|*?R{@N_j#qvC1Bh9ZXV_)H5;tuMns@DSu zYNanHKHA#KvHz1Ry)EX z`t|-2s}9#xVY^=a^H%M{d&pVOw?Y;QVY}8lVWg8pB3$Rgx2y-!qKbgAHK5NS# zK75$dj~nLX;?f@jCZW*l3RJL=6M63eo3u}XgO5*TQ?0tw$-#Dt8M4CeE3>u~a*muu zCu_B>K2)2;T77$MdblFjGfI@u{#_b8GcWi(sOd`_5faxFA|Jca<8R;7U}m*tPdjD zLi{ASxH|R&%$Jsy60gzHiq_b4C2SfkT(`&sAX58OEIVp`aWMc0_)t#j5;PPS7bh_PK*8)ute|cOljH{T zsD1_uHN+G^X-!UYWOe=IE^Tr{kUlD^z6L-wazPNUnb=9ntt8nANPMDz*Vn z<&C_Z{_Z@49p5v0yB|Tx6fv^HNPB|o8-#~6oP9OyiqLzN^?{0VN7P2p_*bH9^ECQ; zYJRLCxS4mZ7RWB)C>yaWZ&HS}l7$v>fJOORB)K(lSZ3EZB;~dIm`REnTC4M3CGBC zOEdJVOCWE%-Re-`{>k1rypMh%+o$p(u;VN&ET>H=uC*&q<;1~TvK0@$hm($vtscjN z*zhTMeku>dC-ngtvz`+b{12*sm@OhPzv^sY;=-_*h>&?>_Wh z{5ZU+q1b({{TSHRaF)~k!{g)h#MeVF+M}7Y9Zy%zCJKn4;+Xz^F1f_Hp759x>9DXc zEm8R7iIR7Penyp8R;`lxB@exjP@Zf7b>RKgC4j3A*`+8yGGj%(e$Wz*;|FnQd)p z*%Nj6V{M|NgQgeUbd~M^XwB-OdB>XFP=O&94PdH!5=Wc&%<2!`fsp!4T1x5&8v%EH z#L;c;8^U-yYAW*_LzVy$j?;{Lv`FmgqC!&SU8NuslfN7QI#Y-_J0>``DX#%deBqOf zcIu52!v|1kaBg7P$=UIy>=4Qve=yS;X)JlP`P2?$TyDP|;_SRuom(YteybaA6gBg+R?uA`Iipg_?KIAIdLfoBy(8&$z-VVpxe% zc;SC}ai(%e_GwNF2yD&9LFU4a`)u~`%=E^M8<8pE@G}J7ZQQZ4oRY+tpMr_wgMmjmF0}?_Jg}6TCom{9RMo2wtOd`_JKx!Db-jx=OaqrkAg` zo&%J8)Sn1iQw%N&0g+ULKFaL0n-IV<1G$irvOTq18I0axtS`CIN^W7cn2}a$z&H4* zpM=8T?%;z;@yI@1GAwX2u9c09>&GiO=^G_Wqm4&% zf3I{IkFf{#SmdGH%eI#ajqiCXH7*F}J-dM^+QV7bNzZmR{rDh9T+D?t*$4Je5uv3z zaVOUwySOQTIR9bLT=kChM|Nt+?d4GV#?+$hV8oSz#_?<^B^x!?gTnC-xxcijW5pwlaZzk@*Fl^>qS0%V8?bC=f^V>;hieO6kX`s936 zt?3jAb41sgW=z-G3^@T+jAjtF?HDbybDCIo(n#Q`(FnFJ4mmw4`;1FgfFN?GIStAv z_*nVMnQp#bgWvXSTj}0WV?zM0cBu$8z`Qderf*`&@A-SSbmX>f!V_W&>ASkdmEWx& z26^^^Sgej<|A5MDr>_QU8W@b6fm4$|=;VkMS>D%NycQ+{HM59>*lFyXYRJfktd(?N z%AJNc7Mh!z2UJeeW@cuLF@yQyq#s6TpC zu(yAC3V`QTjG~Sr6=$nthF;{*bgx(wGi?%ZR640hZ8bGA{_g$irL@4>zk;&vB^)7g z^r`W&zjxpPORX1)L`0_w`NwBn0})nW-EJ3Y(c_ga(wH55;yqnQyL7qWjewKw4vr)K z&NSsXQYcA*UpdE#zP(qM=DWd9Jf#18@bUR+CIjLZm^7(h8;_h%Vl$dc9_* zg$3XgHfV)$H$1FO>82av0YCT2o}N_%*~&flM`vW?t~de z$zul#<2T*s`)0bk)@&wMZbY3&w!ej@*~HY_I>j8Spx$HCZgQgdNySU;qc6oz{c@)O9d0oOOgTjw~KmpD5& z7r6kywD$J)7zAHYcPnrisX=;Xski>-h5Q^NDQYlO7yalW+`&5aRv0iAP-ytXZu*qA zTtnsjhgjJ?gY|!&XCS+0mGhWukE@edJhSpjU2u7XFxHlh_uuP^Z`q|L5BL4r{P^a} zYBS|}d>;3>ozIh|D*)aDGhS1HhsivCCYp6LGRJh~KVP*yEr*JKQXCDi5oi)1D(!P> z#)cvpG@+V|YTg8L1MDJxrX0HS@uvAd*cOEBWgwudu<1|Lf?obnsQfBLh~pusSM1TR za53oRx60Iq7qOu#&cUK%@L8ASKKPM-#A9)dwne@x^uOH64`+cHcX=Tv}F~jrsNm9 z7?`uY&7ZBE-l%%P9~Ve)ry;C*ci#X-f$06?=pdi%`xfS^Nu-yY9mV^;{tMGIQ^Y9$ z6dgP=0#wg_)l|sw;og-JGcPg-l6VRX0H)MllMAY|zdf#_38KiW?tLl|v3b63y)7>( zjDM&h+LrKxPN@w$}J*8N67tM;|a z4e;Fx`P1D2>3atQqF^`5!45>v^nHQs#VdEVF%{|gr7jC6hghzhtgQGuolbuM3ZKYh zxI;Dpr<>}^|WtM?k@Z{#h_Q5z67bzkM zWnSY=$4$*XXvqlgJmCQnmXn~qG})^0)xe{}!`t-SdTW{43xA%0J>N04Cz^hIkL}t) zhyfu_YHZ}r?E?fvM;6#~`S5-L2m$~0rb^5A@1CZ1tOx*o`_fwu31}tl112WJhLcWG zD2DTTs1y@^y=rO<=Ntqmv#$Wkl0~~=R>B9V;zaYcU@#J6XLR&M{;y5(?ZgL+%mqe7M6j-nRpf(p%xN%H{jmmn9tSbzc6g+LhBcqu+#Iq0sh*-rLf z8k4&@yxR7q0q46C4lb8G2EfR^~;${ zQAn6%>m)h1BE^psfi3p==IS91oZwH8H8%CIPW1so&^R?34y?tU-gcl%^p1*gq@N$S zIEkzA0z_9!0G}4;I@cb3Y!1L_hrpmFSeE+fWX8kT<1uXsI#l6b)o>!{{`1jetv$xX z5#rvV_X5-sBMJJ9$M}P}SbVbNfSh;@ffoaD#%SdFSViE=vTdLu>_$K!e&fs*tamcg zS@W*ThMXKQ*!86qy2Nhk=jk9*eJA~wn#Va=%~6Gm&Hy?Pc-vkMx#cZ~1-;`6KIbf6 z6ScRTsrEr{^ls-;8!(k@Le{DuG!$3~a|88@|DYlX)KAwic)X4eY+USBAfHgsWWE0Y z9slIiBlymXCG)SN9240L1cKi6zCK1l}dH0hN5Kv2P<62cSJ z)Pz3-DoDA0s{3nrY)n(+Is{!e3^szQdAglm_p9DGLPf#Pay}M0;x`U!?fUNoU zuhsEsQTJro#}Lk3yVK~{YqN2#BX%k&AwjS73(5&ZEL;RvRx*>qG_ZU#^xKGF>FfA& z=ed~$A{-gH@R0sCy6U?r*v_j@!NsecVP~==y-9*|(ud};tHCaSYOf*4U`6zJR>o!h z!6(wor50b(c5I0rKhp&Q+;NE$pdM*u8K9wWnA*)2B>3MoBlD*vmTjUS4Q2klGuLpu zeEt5H7lB2_=j7egXo2{27FJJhSg;m90WosAl>4mm9LK|$^7@^90LPbse0A%uruf9J z8bIRxy~x>%TR&Tcf1#$h`;Y=kBnOJ^ql3r2SgX+9-`EE*l8dUQCT~^~RZ~&gSAv8{XeYt8g4N%G~hLeh4W_KSOP+Z$&D+0J@g-3p`7@ zBDvZUq^a@c3iOYnoiA%bpFud5oY&{F=0BjI-kxMabwD-eOFPr*nrc+K%oc^gRY@5 z?aLcP&E6nnXrBMfd5!mT;!u8p&Vg=7VS>$W=tf?O+M&HZqFz%?dVemAbqyaUb=%v> zJgxp0N}J}arvlGDk^)O>AN6mJ_aKBF=YnQhkmL)rxI7-+l{e=4{YrK8sYg$X&Em<0 z6yBZXJwvEsiqTJy9Qr3mxo-zPl%r4gxL*W3RU7gfl9^Vg2k;l9crw^pi{i;s8~n|! zn3sL#L_2i4{Ju3;T;bmG;4I@RmlE~yaps=-dOxBN6Z&@P(U|?(>80VJ6G3$U4&9iX2(Kew6AVyURhWzvrDj5k2f7Zemhv!IVb)Gb zkmrMI-i2=dJ*E3TS$vhCfOh{D>zlJ>W=hwyTdPLBdEQsz4Wn@)YRhl>O(;t7GyqwV zXB{}MozL7P&w*y@^#@9dW&;Yx{)0)hI=>?ciFoXZ%nk_U?=gxXIv4V^fpxe8;~+bN z8c1BVF|NO#&s>Gz7-5oEh1{w=3FDfXZrA7c303{s;rDdq7)-Ld^7lo+2V{zwdga@t z=+YBi$Cv1Pqgs+tE1{>XUjd1F8IVD49E8*hI5mf7gp8knuK&4md3HjqKJlH3lWcue zd>;S8&rdJOawT zsu1|IJpz@H=P*OvPkVWOg0r4}K&dW3#~_dw-|rSmn=6iF#CRY63Bsw?+rTuk61v2K z--(UdHL2$MGO{jRtR9+KJ^e}`|9OQ3eWgd*M5{3Y?FB172CObt^z6(oRoXYi^0#HIwqeGz9h+CD>MDj_{jJBmu-gWn zp*`p&c0_;p>CMr-*gsbl8;Dwi+@tM!h>O0-IWn`4dvIE$5vP1Tl_`Ls!BP`V>itUA zbV>6fAG!jXdUJ!|#tL)=Ry>YEluhLdLYiFzUd38Q6ZurBy$nFUG&)P&sWHFwb@Flt z?aI%qQ#m^bU`L`G#kje-ADc$tvBe55W6|=ZuQ#4whVMhDqPHt| z2bH>-j%Ct=Nlla*{KZsJk4D7?=QbBLf;o<(=gK?wPItl#KvE&dl9 zb|(urJ-N~F1@*JD^NyTV`&*U#NcrETZ4U#f{-|7@k7AzYUL|VGku#htaStuY6(1a1 z#l3be!(c>k@5=m3*(4tYUc_k?r_w>~fA=n8-Cn~tDOW`Zby1b)54-qGsvm~{Ab!fl zZ~H7I;~`vDTU_B)m1OhqM-~1Cbn3FKfpDntV|Zl+dX;!IVa`TUKYq=4?+>e@tOYB` zz^Fv`H!NlCdOnE?b8+STPTYzB1zy;_J*}J+_8;^T&HC@!WMRGxQQRt{9T-YOg=C*D+kbveT5z9*NnfKU?i0uHmx1yhr;8d7q|a0l=my4Lf-opY z^7gpfC{r-VF=s^Zt4XK3zEiws+E>o0m;odvtrqcmsbdV|$4CwgG?xj+_Pwta0_z zwmgh7-yd(1Y543Kb{W59v)hohk?2^sE$IhUa`WTz(A=fkhIhO8GaDC$f)r1^3ld@a zo_>P&pvbQNsv4$Q5`(EoJE9iSew=QnG z->a7YLV9RfZ~^kk4y&&{=lXtaPVWzuRZsp~w}SVGx}!^Qkqlsdqf1Ze?2Q2d%zSm8 zp4Ui(@5YUpuPq_51n_8oG7z3)EH7RAJf@|ENKUy6&wL_)3;=UdWlr8=&Q#x%m9~~N zb9}RQ{NBDtKK25g?9-+&kO#EwgoS_@&8NzFwA43>ah~+j_1`5E2OLZ*oIH%PR=W^t zLzV4^5j4Fv5r^i2ZFZj7XOr)h@;~~*n?Q||SCefUBmG=jcx7?M1fc#a;M@Ia#9r6vD7F&eT3L!gG(+bg;>U1KD!tpscjAo(M~@6kV;^OSCS1bF zYh$)2edn8s@S464(#>)ZH*09foIJwJ@S8plSE0m z&-(>474k)Ol%Ft-y)5N~uA6*IK(yB5e}#C;uek{B|c^ zLEK_!t4Mp}#M-@zb++d9Wyp6Cn6>z|akQ+f-1|?w$77d_tT2yJEhilX7R?q3BRg#- zws4OaxmUSMohVb|gQZUWLL={*fD;n}{#IQ1ta2-)&Bx$D7oO*&6=q{74L!nSq9u6o z5&rcGn?DYdgk!^Z;G=h=#tL+sH+;H$oCYe}lKroZ*;QpXonZUU`(K_!3C|$!MlEHM zs2`RjKuMni$~-=zo2>ETh6(tDV654gWvwu-EX&NQ@Ep}>rL$tv!>>V;H&$!1G!P*l z*r{8Nb(QJ^%KuWp8p=;Jo)9&wqf-(wKgBS72c9;Ee6f|sOC?>=;lSPrs3t851%B}S z@!Zmudg?g^9Z%9NtDMI-vVsnG+%dMk{TWr9r4iE`-%sJ=yJ6V4x8h8A7k2xE(X?n>9Qf%@As<-@Fp7G~yI>hZLvAX#o< z@K3r?ze>Z1%huDD{n1gn2TkXV<-ZTkmQunOp-o1Im;TUIHJnG#ft)0N^rin53)Tx_ zIoi_`po;eNEjx8SsbBD)ELN^zZ47NR6A{sU1!U}v;M)}%dl~Sb9@%U7G6#(__utXy z8jK?0bUs=ar}@!YJ7wfpMZPj|$v~ECi&Hdzy!X~dv7mS+_~K5nW9V?zT^#4KER0`c z(31Du{da5qN;8)f8-kbMF>>v{`l=P_#LFr}ZyMhocUogPsDXj1AT9m)_)gmYCVh^zp;La$pV}G(V;7!2XNMD^Vl)d6U zC%l~oyZ2)=;S&KS&dDuWNY5H8-1~l{`G6O}Bf8udpSNJHOY~(6&6N1EF(6qWb~PZt z<>$=5Tvb3Jzl`GT?e zbLA%~zC^{QX^oV$jN;A0l7Xh5M7Jxu=>e6t7o!(imk{yd1#>O_>=^EPHnY)MK;)z; z@~F6>{KL!I`Z5NmYtSW|RCLq40anQPKnrnc&DoOljv$nesD}9fp$VO9O|X7jcY6=KdSz@ z_tmvp#3(PPz08BC*);d(stl5T!N7V{vLkxYuUAH^tFQFIT#s8bopI(jYiVBCb*^rj zMVCrv`5a!1`z4t_eJCX-o95hn4-wDyN*F_9N))$&TB?0}!PedjQ(Qqp`7( z9zC}t6%=C0%fj`8DJbyq_fvPIz6fg;F=YFdb$vG*o#Rpe%eryty#PwCw(jY@u$ha0 z<7&U<7RjTGskpo)F1P($$j|8trG~>i|kqmoBwuHlYn3haRLlho+ z>QQFfg#olB$)uI=jw#ynI|t5$quxf>#Qn zTkiskR0l&># zQL$N$B@qO=n-`bKeB78rOC?X|o6u${MRd}-UP^6b*#}o8yy7xE!X2b=n;H{88A%|M zjv!wApX1Z=maiQPFH4sdxkBZ6-=Avf2O^%rkH|sVNFH|M~& zUOZlMY-acA1ks8l=o0fD(qpxDxXJ4aG_oqsT_f(l^8qA=>8+uq!T#p8k|6Qhm7 zsi7Bm-v$3%k2#^J?gp!3@;~>*)lpor3*XIh%ngNRh$fDGnPP`u6YngGvVe_ehB;i| znGYkdiNe@LY9*29&}NaoVby!|pez^_Wj$%u%;02%8a zIoDl(7=A^Qy}53{&xJpV3^sTj@DIe2?4rss{qp^96xrtTe_3XDMd*D zNZKOpGCba$@n#f4gHrGK_5)(5ITW2~7<{s7C~3xd+hfT5 z!9Ok8#0chXxaIe@>syO}4v^+2$gdtJW{TY8-hc5hI^vb{kL*j==t(58{PTcyx-qFs z>gla->|Hf|<1Gmk%Jc*-$Dc5l6u@!BAg2K@>&P;4Jlwwpbz7q3DpUW->yZe^zJ9nP z)9B?@@<=$&LDTJfY7<-?dxPaI+5Y#f3=7_qXEF&q*Fox)vW);bhOm>x?Pcz$cd$MU ze-QjaoN*kuG^xg)C2}8puK8&R-0wnIvAOvY+l>4EG~oPqH++W-3b>+>u;>*MsQCrj zu!hLv@01odxs3RMDxLNpvg#6T>lEM7>x*C$3X}b$j<|w@85mscP?#`()?`6U;@o6c z>51whR8u}5kv4GbBU~8DWQ2^hNSq-Y$Tdx%zaA&?!#jQLRT-c$iQ>?(OI`!x&JcftzyxYlQ5)knI(A8Tii+6s(7D1>AyfK+JSD3(KtFAIY2|;I>t}(;d(Lu(Fb@+Z?Kby|^7iwcTbd zXqG2G0eFlETUFUxp0A_IXFqvHiCb@zr-nYSzdc?s(|*ftapJy@k5BVk24T9a%*>Ck zqoM-6Ky~XXf!q7T5LQn_Rf)5?@({@DOY_E)4z1JcZ}R&p%;MWRyv~tqms|;#v6$2h z!k_N5rAc|`%`D*M{dcUb$adXHshF$dHzdS=(9Gkn&g+JnbL&RB0y>h$d(9+=O~c(= zTP;|fY1%R!W7Qv5-90%i2A>R?BG7A~dQ1kSjpG$g`|6-NeyTxh`rB(C@|^?EN65Ot zeBUm%Z{WzUjoQJqJ*tlLdnILdB|GN4i21hOp$AG`7{vr=7Ae>M)_95zF3k%I3B57j zT>X}jA>VYmH_nCyEmQ2>G_x#0j|(}YP??rMM1 zbL$7a=#PBy(+3WRo3F5c^#R?-bZaspKy#6!rhJag^Qx#gYmU3()tIl9H4kmZnKt?4 z1(?E!TqbHOnhF)n)BxZ4G(96H{Jg(3tB8{Ic3}eE?>dNHpqQ+f3QP|cjzf)BIrB?{wPo6w6Cotz3 zQ7vH+YN z6b&*4Zv3seXl$-uYW>rcfTV>{(eZW8@!yzK!iXL&1R-a=&O=ZltYh{9W~4wqn-VV{ zDa{k5=SZ$8{#Z3C%V^c=C-0R-O2yy@X2E)sL&JxF=G+IAMjZ;Zd7;+c_!UG8pDlkIkFBvb%;ly>zrN^t{Z$xD{8NxdGz){0nrnmSwCi3` zjvSY~Mav66oP?CI`8X&YZUp@UDZ#0s55iGb=eJ|szooIET)p(u3EFNjj)PjT%XrDe zl{--@u-hvnMI28YCy)>5Jt78j3#usz}*C}`%HK&{7NfC4N25|COx>&Yjl z!}M5CI{-a%#+9G+^^51w;**w6*`ux_{c4{(J+|T)<55TxfI|fGbN^s_PK>MDW8s&} z@>s>HfRw=&du%?*VPolmVcsQR2AX+ut@iqk1ep=3n=J2DD3DcI9?KWK9C_+9+9O7b z9A|_A>BkxZeTS2U?ea8ITx!3*PER-g1IT47jgNOqsvwJK7HNeu$2rC5ns+diql`S@ z`Ft}ux8ds1aWzylM~Gf;qb|!gI=ZzM4j9TbqSELBkvVx#q{l}HH%kfGq0TGz_+bKZ zNq%*nY}-T+5gne=#A9oJC?0hK>~lH|EojnkS6)fJat?*PPdmw|rkTZ*kTn#nR7T?8 zQXe%BkV+nt>a8+RzyGJQQH+z*RuS--O<7UmR6Es=_A4lb60$96Y^1W0Y_5evU0+k);ZegF*>nd zyLx-6iWj^mCns0JNvT~KSy>y~+M$PWk&L7mTY)LH_%Fb2B@Ia;H-y-ZqV-HXwK69U zt^1N4xhGpz=acx3` zd!3yVgVR_Tnfd_c>8*Z1R|2C}Oa02>s$JL`IVe?O6vx#qJ-V~d^^jnf-xZ?r^-+`h zB_$GDQsYY#-W~kr1f#2)&(ab*6vB4C$v!FRCNEN;onn6MtoLyK+4>_q|fe z*OBk-*v9FW-0*=JaC(bBKXBo1o>s0-G%< zJtru?;ig(cXU3|l1UwJ9Ais!;ZU3p2@${={YHol^d&NTfM%y#*u!4eu=FP@q*Dzqk z=0Rnyi@im7{pgi>l>hym!JYJcb%JRfOVjr}7wj79)OUAZ9hq}ZS*=Ic)2-H0!vCoD zHEi__dwMJoTd~_r%Qoo!q#ix0)hje=@LVmdI?I3cJ?1hTR2Mv=n^LXF0Vi-jXCrk$ zY4I_=gUa*8rx>e}j7;=Ej?D6_E~WZf;nRx@O(~#ZYZ3|a`~jQxw+s|OJqSi|5`jN0 zBmkOZ*zF{m+$1DQ;X1+JGS^lCVk}TTsaX2Ytt~&cPEbzJIsx1OA2H zXYBCud=DZN$rqIc8zi{6>gU9;b(@fibiEOoCGwALrZA;Uqu*ERU|&^a8=Ml}_UM52 zF<)e%an)YBIDAqB7++A5S>rq5tq+&p@VdCYD3_Znyp4GqBuOX^B3DgK-t1iHQu!1< z_^$0SGB8Vh;GN z&1dC2_RR1v-=Ky$Nq@Y2$EYQskUXMn>P^4ge&Me)29WjUL+ld5VRaR42XfB^ zmg1*3exz*P?^mP4icB7YY(XWb_v7BjnvwnTmLjYu!mzx5r*9~~##l3|;=U}YS@d0; z4vJQ&@n8F{k_OnzS9`fCpNH*7L(7I&bCZHWx=(#jGkfzUpZMeL+t`MCrMW25;|DO&%sj`UI^#13(CvMkDYi-!lJYiIsereo9vO7F zkjPC1W-H@G-F@=yN18=zgv#N;L8g>j&iz-uc$T_=`Jag}GlCE#3}Vpi$z_@uv=PY^ zBr9JVKYb)WvDt;)kk>&8@ZvE&UE&iI$KzF!DE`5oWg#418?EtjPktAsa2iU!Ekpua zma~|=O2Fp+71RQNY$rfVtCx~LTrY80o&fON(<`VR`pzV;FxlWcN&Rb9m|#lXJiZ`Q z7hUlgw2;N55WwQu}ATX z^a6)x(%I4Rl$&NYKb`_N@T;p-N06=1D=t<~sMDBxV>9dJL7>xDBC}7ii8*x3t6Ba5 z_K6{Q^`9$}Mn#Xrp9*`H7koD1736)Wq2AZHdu;c#v|`|{;aGB%;n;TOqjhD=h`mUj zvQiI+M!{U+-Tkg0*L#KFKUhfc0MXSaP*1nM1k8`4XB&Kpl2K$i;ht_@fg9}3tsiyf zaZMU@!i0hrJ2LK#d|m!^)F2i0@0+c}758qRRQ$4NG+MDN@(=yB5|unQgH0a$>bWu& z^AtI@A^)c$7?J6)^g-Cru!wB;)W%gjMGrLCYrH!Pa2_eP=!^wiNeJlYE&&|j+Xg~J z?rkXmnxFLJHg8jSlNxRqf%@WCmd_`R8r~=vJ<58cE2*T?EGZ2F(j9_=z|tLp2rLcC64LKkfA9NU*XJLK?DL#G zF>}t$Ju~;=s<8i=Te-0{78GoY42l#)6$!oGwXNmy!@#6bP z3gL?VO#F_PBY~2TAAmZmN9IZQzfvKM+<>~#4!kFVCe{DE6xXj@|5lCB4y>N+`Jx}G zah`X4xFr%>`i-e2vqZ>K%Aip~Pq8KGn}P?ao8D8VrmUoFtF!L5BjAAPxg+>3&MJgrqnL}<-UiFMhj&5^2pl7H(H7n=mLmPBtQaTEF$~LtJ|H z+3yo1{7)1@zy16b*Zojr8AFb|TkO%iY85^+x4BfpT-F9CS)5M)rm_gfu+ zE~Wbl)@kbrPN;$A#&^d}XNRpBBa{vj`EX&U*L(-hveUnhs$kx1{Ob)W82P5jXk3{< zk2CRs6cF#r+QOr%8$)$*<2pt5&f;m>)c0fgs`cmwtmoy@RM43$!3g7`NHlTn@YMhq zx!@ISkY{5_Vv1KxnIw2y@FRD&qqd0F29>71ownH0Fm_hmb$#iy=uCbZ9W*jsWc1cB z#Iey_18(70_iyQ_pP+9pZPlneSe0sF1177XYCuNf_}#oXfjT|C{&tZhVS|gK>DXyO zVymjE2zpu#C+~ep{|MZwQ^WqfD&GF8T)GGk_ilJYoS$T+Q;CVI4cGUH*pMgc3YMh; zhz=Y0`n0Cu8xto3@NU$RJ=(XOGE4@wjRl1s*+kD88gEP$zBn->p6Kfsny^dAt}+7tho}c* zIPanKmIhkZJ4YG0wY@r=Qbxrx_x%xKw`z(`#m-!Ze&PeSo301#M&h_wN zV&`dW3YPx8*V`8X6g#@~Vv;c)oBa!BdQEcofsa*Pz)-~HRn>Cv@MB! zq2|*~1)0+AXTH}iQ7jQ-nZGwK_h&V7is#;hpj>-mfB3Jq>FJfTJ5}$p{2qVpD|CBO z?)Wv=t!SLzDdb?w1!w1=h6oz2 z#vCYI;ck2^IJ_bklA~gKeYNEJufCdeV(iaPO=s>DiF3XQMe>4BTf>96-3d$iOuF%k zPn~xcOJqwB)!Sp#YUX%}h7Gpr84qcM2XC(T(Jl3bt)LBje%@Hx8n@y%I#DPR#Eo}1 z=B`xq-%$&~0v0L%Wgnj+XZy6oI~ie$AM{ux17y%`VNJ zPUCEPfNGfFqkgo3D|6+|3cF~co?nW>c+j|3wSA_*`F4u_GK^6$)J`NNDN9V)Dx+pa z_iEo@)rkeS?PR^C*&AkrU3+7;p`$&n@S9!V-=O=~eGU^~u#JzDtINY(Yl{qDMB{g( zyGNdLisx|2J%Jy+kgHBST2vZM|Dqy6k@t4n{zkoqqq^zN=@t z4b?M9dMl|c0_D-5J+_`mGWwiH=+p9&?m%(D=+=`Nr|>R8%F>-etYFMQ~8j0Q`~^w;z1s%Z;+Yr=Q-6HGSKF>8(0eDcXJ z96Im|8Mj?Sz4=0~>k4lf|L z%2Dmtu%3GV_l_~{jI37W&Yas9M;e;1xL@>HOHf;_07vCD&TRxmJ_9GK+0oay3~KCM zfp^7T%rrr~>sRqt{~hWx6!7eE$!(W4Y|kYmHOHVov$;m3GKmJ_v(RxWX+V4juIeru zq}p@lOP@IcY_R=)hEIhmS7l`-0X1RWyXc&k)&!8Q%+n)gxP3;-?B=zQ?9Loolx>8* zT7>w0zFYnMfv}yYpdQ`qp-!pKTF<{z3oawfx4LH*SPrKzS)2edg1sh(;aC zj@3(`v1FJ8T;t*jSHQ~mj?B?XEpx3%Z4%nNfj&r=7meeJsJptSb5aR-T;Ac(Li^b| zX9JJT$)Wo^JkhmFB@9bPhD-FX0D#}oaGV!Y1^NhZK+vjZ$Jms{+hZgC6-0^a@R9zTCP|ztm?=)~*lULmC>KB`uI*!) z4tOX`z2|Sbu(X7`!bXX~ZAGRnUr_B7B4okpvy#OzO0>H26q00_0Vl zdGQTO-LjerE5^h)oe z!^DPA*iOi(-cem$ovb}l8DLV;HP%DFBuM=gFC$I#&~d+n6`{`oF)ziZ>l*E>Ta0IS zD7Td(&G-|>l4_{=tx#D53jwW@xVqj^hjbZS($5))o1+do$R&I}A1$+w%#rt2nfc-9 zL?*pnwBQPpk$?lFoJO~&QDdkI4?=@fe;Myq9WpM_BvJ^WX08`$!(YSoyzj>xUk^xo zL{7|r0t0j7`JW>9m6BpI)3p-f;#}8ui{s+reuHwDAF4?ncX1+%ii!Ch17KuOB};wt zX2;!b&U>I(he}UW{yx-3dt7^ELSJjqauPzFn#5%37_Q>o8XSnlb8HYW~m@jf|0cdaIQ*MI#l7%FrEOP^~Z{fWV-4R6q$% z-$OVqe}BqL(-mNN1(myWf(|}|2@~KaGCG0OPD{{!nftk|FM`e-`V2`hsctPAkMT2! z-zSgNFgJ*Fme>&UZ;4A8Swo2E27!`}Z&W6yfSBmC8wb2`ez(JUd+3^pmr5Ri#3S%O z!D0`0Kq%x}o*7L??(`5L^f_cjM0>m_elPzzjGw=AOt&`E{dl&2`H9F5JuX#stU%qo zkgH4{)ZH}z_mrq_oJ2GD2&aWL#?tBlp7{|;%b(J2X+{R}_1C+9fub5{oI*3ZZk#8C zq}-Iu_ERyhqm<(YLR9xDt}?Z1-}x7AUc2ox(gd}WOhDQi0@Nb-)iga9d)E(m2D%;) z%=he2uSdg@AADP*0a6D^@NE6q9<#p0`79F2e*k1+E01=;*)28ABMQ){+yr!AY?Hew zIXO8!2DJ|SV~7>yn;0IDtSBxnK9?slSzNgbNG{U9VoYi7=FpDd#@scdJ=hcan_5^m zoEB@lX`p8ATS^qJ7Jd70f4|wZ*Dis_M0{Au3fIu$uV0MIpF~S>C0`_ZO_De%vemgV zyxqu=`n>JK=%mg}z~$!5fg{6rmDv94*zKB196=Hs8R>O?iYq|BgQk-M8}KA3S!AqT z=1+~U)r#R^BXKji!~?7Z%nD%bXdbFA!gQaNn2o_DJI{0BZC-S*Q#O=`R{Sn`kywuv zjfvm@F*vfXC;p+y9MFSXLX)>H!f@J(%S?eA{>c`4=t#pPHpGm9VnR!hU+r4{B z6a(?KA)qua&4M>b1q$FVpz{~=w|hp5ccq$3_qU~I4~6fwD30E~D z2e^+e?2&yqbm<)A7+JSBk>D`*Qb1Am%)oeYXUBhTToLv&LCW~Y7cH^8H#7{8?$fb~ z*ZPUyZ#>4YyIKt|fPZ~6YUuRw`nCgkm*#yq4lo6a3aVZ+SkaAbbIsl&#Uj_IcWH@t zGmbzSrfC6cZboAaH`K1*HOu_ubM2Q))2+pJYp;iEAliqX|CIu2`V)2m@(ckyoMts5 zJXM~3n38X+%>oc^+{vBFWm1+dQ7~6xmV`0@m4PoRJmbKUx;@ppGAukwoPE8`tpJ{r zVE>SEKMZ|+hGMm^47B9feWxtbBm;%os01aSfNDj>6(EYw0VGmk6KFqLFccRM5Ku|# ztVwhP=_w5>{f;AqB)^FHDk4*$Tdxetx2;xqOdOcn*kQE>oeXmtI4-c7CQDo<)nZ1O zP6}-29@v`O$YJy`hO$U z1;&ieKtkC-PtR3DoVW%d@5_NQwI5V$7G)CU(&*7J%Z={p>LS-1NUU98MW)6J z`o`!as`#=k%K$q-SmD;;Si|VzwSxdI;c>34cw%hjx`avJ?XK?Gp=Fw|N^Deax`<=% z1g-{hvIcHo(%wX10cb*_!^11rFqXI)8yo@V7O9P<=0L2Y6dly2PsmR`(Ii$MEM_{g zWFnC4jS4ZSziiw8BFE4%F#~sqaacZf#GO!+wVYsCV+ay$U*BveVPn z42&pE*=!G-k}2Xa0iHZkFn?Jlu4{@jF~N}uLOHz>j%`!Ou0p{FbC}{v0E!!U&$sw8 zT)|$8NlaX+_dD}K_4kB^hB_AF==MS?3w_zYVZ)%dmky3v8YH{R3#^i61@QcEdl^c~ zq5&4Omw*8%<2E2L>`a)bn~D5Ai(#(=X@rabYOh>VSq8KLe+4`KULlBmvm74Y{)4Lp0mjYi%h9BF?$jAJKX~Bv?ef!SQ;8K}_Lrw` zvB!mM+l&jySMF4v4~V3_Tob;Z+>I8(p3Qov3Z%aJu#y_v(u!?a@wM~MT0wxQ`ssVB z)+Zy%Nzvt?;@v3U>H^r#41o0Kf-b*Y$fnh2q$<%wjTn;q;!j}ts(Vv9A)JuyqnB-i zJC{Yi7tQv|EhNGKENK~B0HxEFue;Yj^gKx-qNb)MH!?Ev{>D+NIjDHf7bd5VSZ=L` zQ(8a)qu964f^Xr4yzIx8_0qA*){!-OLvZ4j3HkPQZxt4g8n>vhLd^R)LU5OBy+e4sSqbi16I$<1 zymH{gvG0_^7~i@3x6WsrchWifq{Em9Z2MZl%JEEKg+QobDPwqe*h|PwS*B*xy1L!o9ohn`V!wJwCvS*E-6aMZrCvZ`gU^}l_ZuasQzR&zW~ zYA&n!G)@7MwC$0r?B*Cl-og)KaZ|R)nc@f@QRy*N;pgX%#;mM3j$nm~z=6bc z_rX_OnLFd{b?v&cf&$M!k|zv+ltE&}mA|CSdd9E^f;eb}F_^a_mRS^%q(W78>v8q< zw_bYCVTPlH}7m>IvugAFr~ zaiOE4iR)3+kTG}e4Jf7|;l*-LC;>s3m>ay%j?^si`E)ug3n#AroRo^p(`T}>vRF{# zn$}B#B&8HV*baZ^_rx%#8NOk{G*{B<=(5FgD@{!|xBaVP z8Jape9$aRO)EOkzTb{T{o~;;98MQ*2QF=3{_b0{DwTx5bO{Y_-6C#RAO3rfA&t_(3 zqJ54lS>=;K#l4)qgKCMJo!8Qfivew3P; ziedL4FC-oZ`Uh$aSFz9F#UDwbm}wQ$FfkZM)JpwPbD_X$;>|yupo=`!N=9(_mQm=m zY_Ko?(6LVI@mR%7ZNJzFy3t_c3RW_1HobwPUBeZEl;KE$XAs+$q1%RbCw08TY{A`} zfVigCz0ub-gS^=I?+SPG-Z0joZXu+nINfc|867Q9#flv;TT#0sU&uT_@BxbXHOki{ ztMmC02aIMklFzL#SbFr1boDdG@tO_x;Cjwx#98SMqtMP5aCjNzji*nvpE*);>F+hh z`qjW=?YBk_bj`yu0@IQA7;5t!q7GcR;vp#RR*t+>NT4(no5|e4*n;_ur(*{nN$K{} z44Lkl=k21$jsVxn$OA`WXmqHsE!ZJ7XS$j!`=~*A#=0I4dbJRt^bS(m<*&`Qi<3S@ z*~a?m%!o^IpqD?*SCvqfe@eJN&$~GwIpFgS*7HLQd~xBXanv;kN>3!J!+iJ>{9fR} zmInpqwanl2n(`hFh}qtZLk!!NV~nsst2;vpa&)%=N<;MPU^MMxbLulz2zu9H7QZe% z-b~1*xj$O1&6L-y!A6z5^r3= zw#`+UM6B5Gbg2_VZH$#yZb`l=6|=082s5wRI_>t6Nk@T9%5KJ`F{CFQn4Zm&yf7H~ zy>@$t9EKi`yKo(V|5%F`!e!M!wjB|{<>o+W!g$zOcDfXxJRIjUgPK+o#-dsP=ql^s z*t>@RRxMo>?B51=;FI!S)VwJ$??06e);s_r{8y6To9z&OaJV!?toEha<4OFqJF5k* zm4_~}*yj)Mph+FS1Q~h(wn)MoEPZD2^joxFS$;f8ZpMO#x-l+r)H50gI(g9Jrg4e+ z^}BjPa@k1E=9d+75m^V!=({$956Ph?aUba4T#AviKmuvSZw3T+cUg_{;A3ESc4B@u zMf&IRjY3#>1np)1_PFFNsU+ETu(v`^ldu77gQWEBS1x4FZHB#8Xlwzq(T6X&(*mK7 zAm|$Hy+^CJFWvAW%R_+A-E-h16c{rHpkl%+=S*PI=pV_wx^XYyY0pYX3gZROaOdSK zSXeblurUD2&6aZczEa7p^2;Sn$W+56cxfEJ{+k!M`OHgDKu5Pqr8*c+9tCFqIB!PN zDhsS?M_iSOla(!xBG~wTI#r}TRu2d=4&-(ySgTT-Nl+)Gz+Bgqe@q_=+LzQCW_YX) zl}dFS?cB1P34}#^BD~i>EO@Jl?OM5jJkKGgN$Zc0VPFX2%{WFZ{SjEt$}BKu3jV}2 zS=HB1D-7xhyVhFS@j#c!YV%9=-3MNhLy~c3>1?ayv8fG@cH^bem6s=LG#_a zCaHEHQY-h~XJ5MqgseyhwhB>2&4%D0g`k)_;qy4mUS9U-US7398{kZJq@zEthFV@#NyJGnt7$hc8HI5Pnsh^~MM~%z7HL->R@h zmDJZC1>Ju5;&iD?;@r8{$m2)#c`%jnZ&x?BF(+zt*H)p3wzu9>(B(zm@7M-tBJ&T| zyQ;T~@8*t1Zy%-~fx3pBHw3;-m6aoBzruOuKGn3hw;zLup=cgF8ju*Zwwv)@_FBe+ z76o9mnP5iT$d1^hH>bbys1bgZG4#fCb#}VcIL`a6FB||GM1Ype;~031w>LH(u6(9O z&1mYBG^gUGY;jCPItBs~c?}c++o#gm(BbAh=qL%tk|p$7vhDWPIfyKK-xUel@D^L9cNjC?y~pTiC$dhMqwm{CZBAx>z~-k~o$?3F3FOXl5q(>Qnsz<@AqwE} zTbMO4;YHzgumrHIcL_SLVEtMpd_meI6EI|ey~>KF%g}#wHyS7j+eh;lvjfRHZdkMr zXJO5s+PpDcp!2skwtwL;j$-)A*{bY7Y9XW0Ja&FG=l2~FM_#2QM@L5q zg@GFgTf!4S#9oGZ4CAiNR}mv|B?kKcRr(@R^|`NWP7-+kc$ij$5AV zH|N(RYEaJ{qZ0K~P$*S3DWjSGvjy@DS0?*;oRwQP_xo*f*TpOBfv!K3^AVK`aPfNg zHYEVK&;`thu#xsb?ui;sApc?UY#~SZ#6y!E)l~PB-wPmc@_)_Q~YebxIA7 zBK!MQ4i^sQf#p-->BIErDwb)829xnK4kj8hNdUd1!!*ir;Kzj7m4({zL?v-fUs6z1 zbc=kT)3HN#9RnPgd;vj0CZ?@(m3%~IMa3>sg?Q1$dtGJN7^6uHNpixs@2Np=KL^|K zlq#>t&Cn3O(A30+eS1m#w9#Kiren?S;-nxc`ehU{X&%%*>t(5Zr`$RR$gs~B%Szsa zu1Rr4klN6$QY}%i!wwkR!rd<uL#7;ICzKIu_`2n?ES)IyQSti@jjDsKwRmba`P^l31*tKasVD9K|3Lwmg z^*V^&M__qLu;7-5XMkH#7R*0D$ZF^Ik77h;(}f!kT!e66HzKl!CNM-`_Pga!w1l|{ zy0!Wx=hlb7cRk_QaM0gWXn@TR4myP#ynO3^p;u`smTd(WzsJD;^cAfIcwG~*Qa~Cp zWC*bZHjJkvcl$jmtl682`%*{g?{DO&r#H1Rw7r8pdPGM@rwW>C1(p-}+LTE!@>**a z?^kfhcziLHdja3cr)ayUHlZJL`ySg&{2xC8U~1{y37zh$usU}YJ1J%%ruQ-jVpdU| zhyX5+>7%B(Cz98pQvOO|!Qq+^skN<~sO1}Oyu?@|BP0H^vopSrKm2>*I8b{^i_tlV zmQ7=(n@~WVL4ABWGQh5{>d_teM%_mbaX)a&$6OB@y&2|yfm4k2vcB-{#U9WOSno0Z zZ+_a^W0mv=-OC4~-*$VAo?ruubXtA(-?z=2ga z{@x0oQ{QqX!{YePGzZS7$rY0Xx0PSt*;-ZtCQK4%R?K$^!F`P@%u(s{vs5kPF%(wM zrzc?r>+7~+X2u`b&_sb!q3MpDw$;a;#&d(>S#ZuQ@SYYA?>&7{z52C#c~2xs>lvfQY%WP#(7$x zA0d*We*?3A^M?ezENFhsRloS76kvXCpal%dd$~bxjF=odQ|l<9Ja8T#AAhmrL@K>D7WdehUD_=W`$<7w+NQvD(jgOapB<qtm1)cHH%0E3( zuu8GIPa2qHZ-1{g{s0bnpzOFC=)ER0aD9#Q@_A-tAa|8Y6Mr!U9Gc-TipR?CqBF|RF}XL_ z+0)dL9PR83)(=lcvVXLG{P>GiOoI7C=!~YIfw#~*a9rK6@EqmgaWH$~&73gGpIgdx zFF5-S+<|)VJwK$M_4f9fU?}LugMnVgSo1h;#$Gpxk%o9P zOLG$iVAHH))3c(2OcJ&Q&FN?Ng^B0tI(%T%Rf2+ovSO9>z>majD!nWMjKIt?^wv`V z6aH3Uo$R~$UOxfvpRdQ;zxji6Djrw7xkXyg)O30q)rX06zsSqWi)GuLJ+13F1w2&= zp3QTgtPe8)zmx)40#5$fP`yn&NPgjUtvj$I3D1w&CNyqTe7{Fpo$nzo9@PNfib*G) zmwo>HD&XH-P6u10hrBTV5ku(2XW&pna1Qqp&AZh64XNw8Bzxw!a$FB){{|HB>iX5Ur{$%B(OauQA>z*!-IGInxQ-!I))xCAker~5Q2hBPS!5k-VHxTg=6vfSeu zJFqNhmIC6~T#Btf>fTD;SzXo5TtOZId}U0O$5EFl8<@(k_#RQloXl_LP_#WMu#+{C zk+WS<$2S+=ZFG#hMMc%huyyY1>wCNS9O1B*6MU4AkYK*IS>{oI_aPA2nhukx(qO{7 zR}ag!Z~4bKw+Aq;f2jA+773Q~%eRLAne}WXZpQw}vaFt{^w-oJAznmgI0qlyjTYT) zd05u8iyl!C*_y!}7mvU}wW4;yca&zvH6lO-_Q`wM+kTFoHeAq<_i?ks+A2*pMYn48 zmw`Oe5Hjq;{mn9~?!)G(F0A}I&0nCm{zdSCE0USBqo7?ds%jP6`YFC&QTD>gpKZCt6IK}HR6}^4?w(YA1T4Bnu-8mdg z7QT8>i)Ji#d?F&!s0;_1ic~uDwYTT21qN*$!0D483?k$rzX8)OTOa{Af|8HyCWSb8 z;9Ie=R?8ZsKVhTQ74`5iY3i;=V{B!Iqn&Ows{EtI-b_UdGKxEfts5yEmkk;l8;i52 zTAQ1Fzf50I9~1cr9xNdI(EJaJ=Tl zNkg91#rXKR`CbcfQHc=O!17UlyErXYmR7PSr;lk680E*8Nr_`!PZ|?H*z3103qHyw z#wNl3Q!kvU@Vwl2<+G^z0Q#WqwP>Lcovj}+_3#_H8G1rKi=Mbh5N~dD4MP6#(7J+s zLc!KT08#f}h|WI%+bHmxNBO^0?uK+NmJvR_NZ@A?D{cTJt5l^;Ee#3--jf`a^^u70 zXg#fKkm+NQhUd$N#na10i;C=o6j`OjZt%9jQ7>$34rwPJ;H?n^(N5RNu0({3i#~4i z1KVMKdYL2fp8%Qz;OI|PC91%C^8wp$wmd+mk~b*7$0-qglkC}`-R+*bXjFOLiGQnO z^0=zx^PJ`eDu`3E+I)4W7n}IQW8PPF`>Y&|M!WNm_#%-<3bzl!!^7wGTu(&Kh)!rj z*Hd$?7*F&8NoM>{4mtKPVyU52+cOKw77 zc*)X*jTN}}MBoUv_z$EA7=qg~e2^G(Q@fIr<6Vs~F(QD)=jt1X@yt24djaBG>WRYX z&Il<8()>H`Un6IbktofaTYxyvpROk#DStM-j%)8Lg*OynQ}DL6<&QN%u%v?eifHUy zGNlag`Madja0Z>_Zs)jP{Y9k8)z@*E{cdjk9aSp%mzdG!5)P_H?++eDgChlv>CZ>y zW&xn5ZFE$qwBIdhx=9Yjz>HobP#G5>0ji(Wmn6t6cxsONi;vzULujnj2zQOuN5xrJ z0w?!(I35&3D^N?;9ew^S#}szo&7l}UUo{1CSXu!~94yV-1fHlvN63CjX}NlfU;#nL zv3N@X_|$VN2cye&JS4#XZ$rQN663S=rDRyV&BYByrmB2g1E0MCiITUFzYheJ@j zQ@_>&kNk2ofp|Tp%-~xu77KggcC8qpmo_3-f9ihc-$OWci+LnaMcTuq%CB*SIz>2i zte$jwyZpsYVQxF3#`hV zl$i|M4}vLcQ$ghghy(BG`tZ0KIlGP(HGoVwf2x_n>HgSXAE|oGdEf9LzXGr6m32ey zl~2MR?}xQ!(#n4`qh+FSTe=qilg-3|*+%(>kff(TJkqjp&v9l7h1>{$MVoWrLCo=P zdlB9Kv$cB9SGS&i&{)Y6mL03VIv4`Bgmom+?X68Wk$+ zS9XiS#}P=E%SP7R2G|w!^aXr9woJTAS$YY1kJyd-e5HeI0daFuHVc?P$}|8oHQMVT zfIcT$O}O<&s@mTlyvyEn2%! zgI)~F(X&;k2#(YopdIu{>$lH(WM-0Xk;gtyvs+KS`~9v0$z8Y?0MK4W4GRzfQTzFG z6x%Z)`uSNC9=_Nw#WeE?@z3#AOIe|O!+BsfI4oJfj`#DoF|tgjw86hJqT-s^ucv7S z>-647&5ZBxruTr@ex?Mr4)js8HdmFq#VT-M1N9U%CU zdo@*L-CaASiOOkrZxQfj^|QLE6e376l>snztrr|5#nkjt;QI!xbTV|fPg)O`mf?FJ zU%oV+8fOwu92L5()OP)S4QNm9I-;5@4FCk0^S`YnOPd`lPYX)}Uz!?j8;r0_%+_-F zaO2&KW3<6RSGT@Y@`L*vB$+8b%w$-T^4t}`SiKZ|+LfOsIPX~{<>1}K>vIjS3g~dC zG1?0pW2B;I?ukC9wL9{f1JvKzSgQA;x}UXrt1@~csJ;cTOdss0>pws(UHj|v4bV37 zY;SJ50%m_f5Oju5)Pw-=`$hP-c3ozKDS*78mpNuDpA9`dnrHpam4qtUGTxX<3^=aG zJBrUT2X^>@89WGcOe!lYy9lZ=sygiY1fn(oUXc$zX_jd@Sb^h^Crt&JEZp)_)6)Lw z-S?lmL&eDzhZ5J~<`xNLVp))dIruinGwP3Uusk2bfoWH;Vq#+2Cw^da6t0RM&@cc_ z^a+#B>+|D{va*kHoj(so0?OZN;e(KA@@$L zOP>MZwmBvQDcuodWkzqT$Lp*n3({{-<3TWaf$D4B_qR(EMJ}f9m=Pmi9X#m(wiDol~Q`npy_76 zgDi}!UVJYX(ZY(}*h#iZYId#@bEDkK#Q{^WBX`%x9&P_g_K9=2qGz8oHA*;SUAM@* zD2gk_6mbXcn-gdm4^GS{D_b&%Zh;0?KGN)u-jzi-KdSflwLpUuE5a^3=WShZw!B!$K8Qdn( zQlZJHH^VxS{>X@1&yf8ZU7D@DFB+c(?44;Y6XEb-!PRVLx$zoMGZHY@;%pY;HS23? zYMRosIK8p=<;$1f85f8CCL|Zl4Gmu3KqVc|lUGR-EppGQ905$!+x?Q0w44ZHep{gC zd2%yy7p3DKBy;wRB>&wHg#uN!b5ptV7I&Q|Uw78A8Wi^`>!%NHS-_%ZqHK@Mfs5!2 zDz)|^0FolS)Jo;+%Xe@#>1Wo`+S#M|`O5*Ik25NKDGKzq@onFC|v#6^X7=OYkzSS@jzwfZJ@x()~=Bc3;q=SRQ z&CoWrBAkSED+YHuO3X4#cxNe>KB>{=HZWwT5!I9^3~81+!lKf4^CxC~$6ok= zKySZah({NysJy7UsJ=){ijnZK2%||{HD*z^ccjnjVBVwPjK~W^L`bNx?^6!$4Q+3d z0z#v*WkCo|t+pp2vS%*yJ!!j%6En*>DWdhS;vZ5z|JjA!m?2t2N%%|(yjQ7|e%2X^E(Pp$7-iqnN9umM&k zlgHW#b_ViMvA-fZN?9^a7q_^NPEcvX4dML1%xH^B%3iR|NOGX*Fo)+NX5wzR(-^v` z*3s&JR`%kkFC1Qx^FX#=?4x8tJ&A7FIc)U!_rtl31X*wzp~%km+B-g3UdQy&VXB+_ zzMCD4xP>4?rsy`>fjF{VCk@GQP&Dyu+<*IA$m>NECn}N0s;@86o+|K9JA9@*K(sMS zHr=aC_J!jXRR)iox~aSCPa3%#gy9dpi1h^yE_5Q}<9~t^BcyA`Kj%s-MN2RWf~`m#T2-2aZy zto^uq_pav0DSs!Y&r6wR=aM8tOc-wbi0pUZtTXj{&{S$if5oxYv-Fuu1-*;Cc2ufb z^4+c%mc0?8iG_Z1m^of#vzg=zfxX_1nd4ml!7lj#txjvh!0!J3xvaZrRT1l?2|kpV z*__iV;8th8Ty9b87yC##@GXZzDz`csW}gA2aWZgf4H5v*^tT zv+vZ9$_w@$;CW|T&6!qIRJgmly3${_NRn_GXqw+qrK6$Y7`%=_8qewW;3i>psC`Fq z-*y9eVgBIfzypOup=UO~xcg(?y?M+r;Gtml;-zJ;PGz5yrStHH0VDmu`jCN^_QBO)X>jn|IF(G&xsVz_RdhBvTT{7~AN=|V zrstl${T2(;IP0p|@;j;*=Vfa%S!c_Azdcc}$gjzPyo!r~}uNquu9CVb)BHjOi)K$y4QyNj&36d8y2uyn&!QP_tISi;d5flp>~e zH4=J#%%gl*0Lja29R?vcjLnR722Rs?AQ=!X2G2^)Fv&kx9q_q_Zj~TrG!y5KQwQb- z6i_2U%7jt8f-MYgM1cQ8aQ~#oXsR0+$Nen~uYJZNy=ttdRCp&Z) zAqDF8pv zZA*xXidsmUrL!D#E*y*&E)(G*X#lgik!M5G_M9d{h6HOgv@P=Jk#v$Oi)M9XI6$!= zIkFl#!T>3dg|I=4y-ai!t1iJ;WUlQrj-=kVC4snQ$cFd>3MSOG|{eGi=H5>AnA4w5GUvrbdN)90By(V zy?c@l%gA5p!)1|h)SC_Rfy=C*7`&LAJ@$mMt;cWM zPt#X0CGT5TX)RR;nzEd9Kx`ReCSXQ(G^Lvz?C_`xmZl@cDz{h`aJm6O-yyjh*)n~W6mK)rrWo2cxyJ>CnUjod4b8~V2;Hp3&g<@c!T-@n*3R#BY^(wP#r2$bpg2MV=l)$5kSE=olfcu zOZ|ZMtNCBMgs;-xRB!R0j&KGnx&L~5-_L(-IJZ^9|3&kje%;~ob5ZMReP5zudfbCJ z+Z_r357sP2c{ElhZu?3Y?-YuyuKWfJ^11(-VP>soe_anw3a+&O`t#Nb^bQ8|0<;AX zQ~?S!Vbmex;78~c9tdK?NK0_P*U)4G)?7y&{lCePlmBE02$paUf!a6R-;$zw?7;i! zjK_snPu=B>d zZ&YTH|E{3}Pk|lbsyHwffxmiB;@{{(aN9W)^C9HlSoojg#`52kB&h#;Fa}pOSsnqR z#o%?;Ki@$H4q@jYfMvj><09R88UKB!O~8#L)S2l83$WTjj5^`Ca(>6-$fqS@XlSSj z#GDy$)*^cv3#kS^6jn>Y3Y)n;cFl&J`l=%yyi)gRDmMxwoPCIQNGzPXmYlL2Bf2#( zHQj|6spe8X`@yz$t#}fi@EcP#_0{2ac@dAPI=ndMZ{QugEi#{JrYet^>yB#Aeeh^@ zLtahN#h96>d6V^I9<0onW$Z;C=Q=)N2HQS-Uh*%tXz*j(?+ zYA2|pfIyN`?lr9J^4@92`Ch(($Hn693IHQ6)34uD5njvLN%K2i6Vwov`6)yLg;fSf z9GK00yc=5Z+mfYLNf-8e=eNVe4NsK>BL$M-<*+rHN3~C6EUEH((fEl=R!_c~p=RF{ z^P$Up{j>E0cBuDyqWm&8SLtHY2*hpH7-F}KvWLg{*v>lqXlM?C4|VY7i+nSJyul3L z3`OGh1AO1AjGy~nd>kmV&o%dy*zO6S_-98f-sU8VmA%+_EfZsrL9R>wd!Fm$^oQBW zPjQt{H$z`hZ`#p*XMxkPm6>YC$%G(zQWxWfx`DpeXe}o-{1@YM0r> zRg(rwt51mK+|4Lnr0ZkRa0@%wAe6}}I6fJ(kr1Vg;pJMozS>3glVE*z^j%`wa!m5G zH5X~^C{E74xVw243hFg{94)GD)?;LsLi^aJY}Ovx*&h3yL>vVUX9gdWF?8%&j%0qa zp^d32<)s;JZ)TmfYZaL#02=nxY|gSWQm^Di2JH(bi==^%_90)uJ!A2eluGaIR8kMl zVK4Um-DkGj?8y&RY|Ex8Kll@QpNOx4fqHn7GceC~eEq_8>sy;ac#yYcc72BFP-R)o zk+x*?qrT8qhg&B_bYk;*L-!ueZQeo!+Bof9^4#~%c2Y>8*Gu5A8ei)DK%=Lj9%DI~ z(Q8o~B1=)Qb$VH|gK4JV@`+$d=u&WB^R7d0rt5x0u;Z;l)W=KzRwW3zF9EDV*z_Dw zEh<f)p+{jvI$<9vvy>SA}(=Ow8K}Q8v!uN1(z5TGAnMJ(WYiZ_r)}qDJlp$;b7}l^&vc0`&MCE#bZ->v-70znzrU9xr zo8YzGA=mtt-NTO07NcgpA8<*}}D_iNl z5f+dIzLR3Z(b%?re>}f`>|89`R(A^Aj&i=!gzY~u{3}?|pN?~Fo;K&ZD|yr8-GGtM znK4dEp!0QWuKtzzb$EF>2zlf(zcTC6D{FaUY4N+!2aeWe`>4~u!&8sowke)n_%~j1 zJ#D)ZQq2idpo#dhg0*-?w{&|9QD*FR_%HnGyy$aG}4ktJ&CmIry`h*+2G`qUX=8{+bJjw8p)@_q?p>bwpGYW_`+p ztXijRT&`lm?K3XK#$Ipcs)nBw97!bb`b<~zXM@_tx8k|Km6R&+p{4FOmu}{;_i{)y zm?oT>BCD5HggXRvpnD~0acyd5;vm;S-*3lP0$ohBPK?bPlP5N%ycRM=aKd|He*paQ z{6_oTE$qYP(r~L#DvqOjmlBdA9DaYjnANeRaP|wB(zLh57 zhYlLKm8SX1@IPLC7eB(coIZe#?X_ErRApN}ve`X(XuDLz*VBIY{wN_ZZ!ZNQn>#kE z1@EHih&+}}X+i4137>galfH`zS@Ff-$3mA2|2hjZ4#W=I-A4Ca-$gXdZgaS0u&io< z`Ym8*4m#S~D^2iWz1iC690x=@HgUEqj0_cDiZpG7IaWL_^YYX#J6-8#k2f(CHP{`2 z(=Xlg0QWuYZalPoW!s|YV~j5*Nf=-pdyH`63Do=L7Q)vx9ZL zjZdVZr<)Z*6=-Gu*Y69LH~jp+85TyOUCEivbknCLL00p-j~5>E>xg>83r5Q_UvOEw zFwvsh3Pk+PNGN6*?d%G$|n7&vU}fA>J9Eb{)G(lcOM{VGlYC|4?{%V&=Ux2b zQ#JbVg)9?LmJ|4A_8dIj6cS>4!14Qf2VJ{E1watfTaGWNuLkS>9ea|(frq}1Da8BC zQ~ZUSv^u0|o+)l1L!FI^UMQF#317h_)n$Tp>;r1?s;c{yHfp$kZGM!3%A492w^u44 zY`S&@dvhaMN6OFBGs*uoxYWXoQO-35iscecMG72@k0ItS5s%QueTEtFW{FI`O%FszgfvES z!^4+$V-=DX7=asmrCAJ1L~q&Z(H_04OpNXPa*rA^)p-7Wx6%8hj7!JVGJsZ=GIQ%3 zQ}wvJ>PfEPCM>MQVl6I-v@+jnPOVOa2x7AcN=LTxFz0i!$2_#to1(mX)m; zgEo~G4XE+&8FATvEOx?VkKdFgJRi5bM*4A1v)ExY0z`gc=1HpCJE~-586Q?Y7$j&r zeg56@(LVq5ce~y%g-Tu)Mhb(XzIotSWdpcSY2Y02%)n2Ak8s{LNXKB>qB2WrUVzOK zLQ3pYC(9ij8w2dIYxUgMD8(~tL={`S-0LYZfl6USUqAPm>=Z7)d-NhH+6zgQ*gLl3 z^dtmK7-cwXQhNH_?JcU8pe6e}knYnCb1V<4eU)QbR#ws-yR1lU98GYt$NR0q-sbwi z06}?W@D1v4;M;;C#}e<0GlJrgbsAd<7_1Gyyt5(_BqSW&+kknGjie-4#yY0)%W%@O z(YJdf^u;BQ@O23KLrRk`0Eh|PG*Ep_&WNebnZL0`wGMJB^Y=oe2SlNynDsc-&d;CN znngUEv*>vvr#76e>(>O1=8*9pFcrI}qA=$@G~M?G6lLQcr?SWQ^rP9?*#awZdOEsZ zb-K_tSe+sfgo(h)A2Jk5CL}J#*{P;>E=Xxbm3~i9%`klM8p7o;i@TAMk}8d0$&qL; zO#J!zISoBNw>>2JD=0BC}Q%!iiiZnKUYct?uV!|YbB~;%j+_&ZF1CF~AB_?+BwnE!{Q zs|<*$S;Gq`2ofqtmr6?s0@5f_(%p-+v@|TK2&jlOOLvDzHz-JVEZyC)OXr>auK(ri znKSdw8&B{eJ+)|;N5;gN=Dq6VKL1^TdEZGZ4)fU9-7WrlG4EA~NJY1!PCItIZrc_= z;^zW-Na&9r3g6c5^I)Vb+Gc>Q!|yrdqsCFT06$Z7IXN=(ODkw=Ms)1_Hvg?s4t zR;x^Uh}|_9@5c=76{f(eb=W@z1bIpw_sbBkAq+8cM+7^ca7Pn>+EamiEh-I%cY~E)+V}Xu3j=y(k3!| zY#M8krW4$0bUQIm+-CZxC>JvxX($8Sy_qr8O`JD%V?88bO5mV0Gl%CTWnIzq z3x;Yj1dD^+CRzRLQ?1~b3`oVXdW-(N5YOr5yr0v%ipxT3-wAHNMF2v6XQfyuHyu>L z5v2z4muvCnIqJrF6A5aQ^7S=G2{U(P=l$QxLfF^C!@_K$tr!%?cg_FN;m^A`P8Bbe z=`!?~6AWA!MJ`8Q;n$nh+nSW;^v{ORH#VvJo*0DSTUTZX(8m2vm({1k9-5v;1KT`3 zJ%jh-gFO*m){^$hv(md^A^F%4aINaM7@}Uwje20-xzsZxw!Hq;G09BpaLyB&}8mVNsC!CS%<&HKmvc0FS)-le2l&vSFSuB_sn z6r`#&$a3WCaJ>o=y*gH6b17G|-Rs+|D<7IlD7JA=}KXhdH*F4$P| zJ|pBL6XroIcl@&OBg{h4w;R#qHNhO#Fv6%@ydSG59AxhCkB)G!z}+zLs53eCAeHFl zXOn@5sWX0!78%m08QW1O& z#lFSJr_X{3w$h+*6;QhIZi2N!%&wI0^*-Fr+6b@ytrp78w0Y@Gud!ceXvuXk_j)Wt z$q6CftUc&pO&7Z>9JKNmLBmu3Qk~OKkDX4RTZ$*CeY+T4Nf#^gb@A%OX>Ww$d|1vE zf~~!v-Dbu3v8CQ@8963-c=_3Bc9M6cydySl&GO=0-VS-Hxx2K&)c-m^W#NF^UOppe zBG}B{N~;^c^maRu1{p#&l~wHgcE_!70ss#XiyDonD%s!j6E6X6n6Oi{WH-7{i6sK4 zw|-X@+M@HRmf!QJWA$DRnDd~wkGtxBe{|G4y?YV?I@`%#Jh|`S1Z4;PURv2D)@m`S}zwVU=?d}>$2UlPKT2HJj$Uc6ykN(J9G`9ZgP<%8R!DNa}U&)~UDVBSbBDvAR8GZfqsD|EUUu~xW-dN(NEfF4nk$BA&&6*? z;}Bz~9sJyKesVWoOVBa*=H^sRxv_ykkODwBN~(pgM|v`D=3G+Vp{GUSQGXmvihEk&~tckmC5`s>%-|6y)LTQG}^;f(tQR zH?H!pI+>Rr93HTrYlU3dttw3p?Z>1-b&>~hxo?}Q)P0cyu^$~8)D?$i97MQv$J8)Q z|x_7e2B$WvK`BH#^1#SABb%@>av>y1NiRKRJ#aEV(wJX8-%SXn*A+y_}R55 z_@JVX@i+xVR96z?l$|92T5<26j-rtKiJCKQ6ggMtzL&82qNzdCxc3E^KC?m4+6%5k z^N;M@R{LJJV4^xSdyG8NPd3pk-=DV91JDiyQs3nqrpl)Ad+7E5(q|u`8@T2LZOXS) z@V$Oxb7m13ktfk?peM}127g( zL2upKhbuM@3-ZH=g@MA#Ek4q?iTT90u}txz(!U@@PJogxav|H*aLKdah5f#xgJH12 zRpK%73XGlRJPJeC7{Vp?rKe70UyJaj){TBl(gPPWdDwdu2JQREO+sf;x?&4cqtajc z)P&2}8VLEDKZU~PP{$x|C##*i2Yw5V&P-%!OU~ZlOFU|Xt+keeL9FgOW>Qx z{J>f>9YT)S6pw1*ndkf52l&_4HT8JY?!P{OEk{vS!*27&NSR>r_PW6B{5Yg|c-moS z3c~cyK!^2*qbj1Lkw>Gj@7Dbxu};yUj;+nJI%=^0#o#?NSN|&-U*Tr z%wvDRCtI!(fiZ~C7FozQJsGwy;xz?^w7TPukJlT@ij87zp4`9(UWO>&KPF`ElcJX^ z4z1XX$ndZbt1KR?Vg!t?G&tqAy_b^-OWSVv^7IcLCC(aj$Xy!M?sn~#{eG#=hBr)D z=P(|w?29ZRJ(n@eJ-dF*RD%^cZxc;l=~x&88q$Ai;_Q(1G(M&|2G3`6XmV4;QfCgr zig{j=iY$l`H8sj}Hh4A8G&|*fd6Rzdzz0&X3V={ZJt@#RUN+B3IZq>f?|yRm&-%r> z^P+X$RUNnii#w|F1Mkg^5Av}Yo%L9pkIh$g{sf_9&Lbqoa`}@65z1bf2Ehjjn#`>V zof<2)yBm!ONefOmoVDUrjyuJXlJ}vIR&s9jH08 z3*h{RvTAQ*kAwI-;>NM`7Fw<*FUrloVRhW`;H2diVQR)Qrd_OuVSv3p`20hLOs}0@ z4Z%P^-BJyvEDWOsOi5G*`iKBh8dM(sd)y8g3pUld46Rnrda$@ZS6A?Ri=&Zg-60_V zN|QOGK!tnOts&A-8SKG#0{(eIDrN!F$FbopSZ-LTM_*;MzN@OVN0%r>)`?3U6M(x; zxxUbYcb4=^nF;edi&OPr}k(P+ev%50K`8pe`v#$>3(CpQeu)`6!RxY00J^-0kBo=f1Sa+ zhsJpBsi`k2aBejOk5P0M;KdaSd^~`kcqfBr7 zS^b)Bg~}E1a2 zqQ~`JmHrPid0BWmN@&ehg2o5G9OYdtzJ`w6c+;h5)2E7?2Az3hSXASLe<-oBI|kny zpuhqbg#mw2O?2$9gsfg&hr+e9?`pJK?b(+{hn~1ckPn#v;Iz`t-~rb4&gUmqd%W&( z+5#N*mmjj($1xj?jt6;LMIlogvX4%5d`p2k%Xc&#s<^ngQrK-rrwoXk-cM3mr#I)1 z7P8wOs`7q^0eO{_>;oOS{jn(Fr`?qN3|IA$1V4{W{N(0`T5=cXx*KknenDJ zo(oT51n!%JG91d|Q=&{hnZB%@AG7`qc+Wjl|7RHaL_oC3aEt%s`>g%r!cZs-;^>fw zbvfiEFIWM@fbM7DA|tr{L>T$Aa={dmK7m_YWGRYZ_ZjQ4v$nD#+)JEKyUDj-p-Z9q zoBNNhL&!fwR5XN`5G5rgwO?oOtLek3wy_uqo@4#gd+=_GQ$5q5qWcIiI@kC2kFm{N z)whac%|?9BxRSUP_b!X{`wd?4iM&Xe@A!NKF|jwyvLjSr@6~6IeGkYy1s_i7C@A8G z5eQAmc!EvUcm51N2py*&KkA@0~Lh&3`0ld-li`!-J%4oRn# z*b$M&eGtW6(hE$1HAOFZN9TU0q@nq(rIYLcS}t4V9-8Aq)1TJ`$0 zrk`Snr_=uVGW0j--+zexWtQ?M`HWja071H-;wCPz4~JJBWqWf_^M|k-8L$xf-rPHH z_l!}~2xk&QsPC_Tf;~RC8oa!~ z?)fF+?)fwjbS^Ce+>aPE7t8BPnO}f`q4&9Uo==4_)YQt(PBf>kE&&Q%R_(A=m^J`6 z$Hzgxjbc&?io>2~+iq6IO-Y}3o=uxaJrCoI4Iz8nO}t&dLR2_qZaVVbV^|__mJ<3H z0y$YkR9UhFyx`;KPiX)$YcN>B=t;luzCrrU&E!rI4cml`{;LIebaaCtn9Ls6q&Vm3k13aY#d`zh>PZ)rYhWKYczsbQPKcAq=5U0h!F zWXv{aWv%Q6&U<-%9BygIu>2kZd5oq5ip*Trw|4Um|d%j-L#Y zkrkUDCGSov_AXLbi)K6>d8I6OV^f!=)V21Fy;eXmgA z-hm`R)Lqd_ftN3n+SB>i_wX?xgz}0jYeaWeQxLl(rb$l2woaaQr6S1lXDe{+-iWAm zvahYi1i=^Y{Z)vvzWS+PE)QRRt(`MS4(BdeufBhR<^uJWj;iX5bI>y`{;wqn zSY;L!rSa&0$ho#VNmBU-q)GD z*+neRt`r(m*S9cu^@y#!TK%=I*Jm~Xd9vKqY|EVta0>^rf;|C7Lhb&%OuZjy@m5w< zjX8ZK2w4;Zx5)&JmTqOKwia^7Tj8;}@G6Q~Axfqsh0EQb%*#qRX3g^#E%#&CDnSuo zzjy#%W!K0H0@OQm^Hl&`a`^D!RkCC+7b(QQHs5j`>r>j*RU1F<10GW_Ym7pX?LepY z;M${|n=(oS;@Ty#Rm-)oKL;BUyuSewEN&8Kc7eR{t(?p5N}~%!I+2F(7eV5 zPA)D#Mq}fqnwqoZii(Q7jOq_MHvwd`YYn^b~;ux}PInTTEvyl^gGMxeg#nBXP6klL}$Tg@geY@Wq zz=9{VH8roDGxn{LH^>I--_DK|>kllcP^p8Ro_K;30z3V!yl9Wlyp3?S?>cu|+*{90 zxAPrGM&tq6&+vVNSMnAEosXJHx8gDAWc5m9rlw?*xo-_xTD`#sX+GNdk2C6=N3c79 zPG&el5KmiM#n2?MB}<+LIrwT>ceecZmA{3f_-EzjzEV|pFw;Ng;Yd(Xm7?o$Ez#sL zuq#31)RLHX4FN-;WAe~mGav;^p&^K`RzOQ)>XH=@67&dj702v1qvo5cqD&aR0@NIO zI7#H)&mmsxQbnyBPn^OKrb5JUxA~xau=48 zkMn4&R+fqiyYl}W+2*>si%p$|5x|{uK`KOpRqZv5OP=R(f#+LWTaRHU<6i5Sa_h!+rcBQu z{+w>Pid)skJsi&|S*6RUi8&B{3ipqRtkZ8!LJG6%*h41wKXvg@Tj{r^&7J#&3?~9& z`d2qU0KRw$9FJqN=F7>gwgS7(q3G7*Pef7i-*QF36EaJS3LMy-tpAVhCG^dB@A_WZ3V)`-E(cS znTs3&tCj{HpoC<3v;ziRL8mexK_Bch!5#Q`JKIs!(=&aMCljekylM#5r-tU<6w>8~ ze>MpIZ?wyZNe{hwi~Bu5_ALAwi&u$k-A-lyC*jOHp$-Bzz)ExZwDyxwkXV;)}OOxX{ zK&%E7J1)IqEu)G{0dP%HgAOmXFZ${$V0^g;)PMXBe+w23kF3XVUAva=Y@DivGiXLG zM>_b`yxF@=(pS>w=9`fmaB`FAoguSQZ%u< zvf;hIJ?#BwUuE1Mc0e?MZm9eg_(-Ls`1K^j%|5JbM+Ogp;|hGv`xi;Le}TdqwrkD@ zj_VJ2t5wX!E|ycDQI+iN2mj9uwY)aS)}Be9-ArD_=dDebo-iI!ZdzBsO;=;-1!8BH zT{=yE3at%*70Pcr@lh<-e{oh46ez@tE|V*}c0NvsQ~|jG?q^C-$vyTl=v4FOFz_6? zD5c&idc_5&;7gUV`k9PrTp*0>v#Lb z{Vf6%5b?fY$^E=|O$UPhKeoXVhYk4iy-5HwrZ_Vvxl7?zdz=}AEbp<-s$faB-25bY zX;v4Nfr#$FItMJ>xGGg2a}^7A*p0QVdNC7flj#hQws=o(S$Q&Xk0 zjuKKZy2EeM_`6?eeoC+4wz|Prj4Ak&%&S#U&We z?y_@oLKBaSp&Y6LXxethtWhyvvnOiJJn2!;sXRDqUmw?xFg0F7&ylGDJw7&5tY1G} z`JL=xi50NzE}!x8ZU)j891Ye#*nFRTnnABvDllp|ySDe;)dx{oobfed_-@ua?FU)z zpT5iq%lVV2G4V#7CYgOSyxXfV)!W#-zwUe@-Psqp-aq4f6bV2L5s(l#LaYf5c}iNZYx{XlQna*nOClk~TW!TlN)I zck#fXCLz&J)7;VJ^fbRw^>m$dG}d*#<*D(ER`5wne_5g#*>&h|04oyt#&agF>`-lOPYRc80aST?cW1zEi&yl%C1B~+?|;aO|E z^Z4EOZ&Fn-Z{0TrpIm>fVJw+P%fIq*+*CfFbZBYNDuFhhr>CcXv#wV$3M|nnT_OYo zCp|`NQUQJo{nk?bBa*lm8dwmO!6UsR%cYUkZ>%^gpY#hm)sxxe{Sj}Bul@}tW@f=Q zA9(I1N=ANURmZ${#0}@LE^3J3Icsk8Iwd?w;@ziQNQ?&RDpbw@yI7J$-uwWO`=Sa%@fb-`+w(sZ)PDTrB9vJ zSFWpIkx2`tP*5{ndD*>id$K=2KOVJz+xTq}7uBhr#4 zP^dyDz`qtg#h$eU@y|%JtRHB6w;vf6n;P!BeA>BG69Tr>1}^?Qg^E6`>gizXZ_>Js z_55+9OUYz0kvcdxk>3$52udW3J~7bX3scLHl}Rg{l|>31v)j9S zw#UH|w{Fc-PGr?H0WV&7>y*fSdybZnX-@`5c&uz}YP;QV9xmGFVdIC20@7JH?LN^Pd|2WlVu7`ok>PO94M% z<7%jMqQmbV-Q{9nob-PO4yeak7HAdMDP1ER){HrJ)>kVbgt&MSHw=+o2f+PkZ(VeOu!xr&8;UM4`Wsp3H-O25Dg zr9NwTG{>321;}V)tP%%$u-Hb4>>o0|=D&Xz`69a&(`-i6)og;yYqh2AM^YC7hPbPi z&d>grdW{rRCHzruGnnl>o0QN0{rd+Cg-+>hl$SaMy-oi{MU}a4MJ)qXzfDnGneKsE z)Ck$|>T0cw*`TE(kDvSJR|Z8Y`!)qJgs}oRqp|N@8_ER54vdy(OpTjWN9FaXG<)?O z$?6nEZcQVO?4qZWz8~~me6x<%poT2mKSCYV?E-58zXV5FY=y5e=k<@i^ls=+jeU)_ ztk)uj^Xiug@*ju`{qvKi05E1F^d_eltWE-q65%7%#2AETOMO+@h%WMPYFk%iO~?|1 z;Kh$ieeLi)j!cH0{x2Q}!cn8-XVmD9tn@*SHD@;ja=-|SY$#0kJuNl!wAjMfM0L@| zH|>5lGaIry{|twXhEvA0w*5Wyza8Wnb7#T2hhou?axL_knTV6LMiD&5ft=!FYW4Sw3ZDQ5)%<85-(K=^*L1o^kHL$TN#j9G|_Gy zqmG0oQeUMqmGlZf6&0W2peqvNSXa}@ZK|m#)O{1=n#ZDRkR0si5dyfvM3P|f%N6aK z&JhWvR^&=^r9Mo}tb*@?tx@NI0^WeOro!VUUf>rI-l=gEal%!1y); zaK$q_NmgNzj;5wZG3Ry~G?0aobO6unLed-}7vNsz3znrk@;=FtUAEg&=|07eoV3fG z&<{S2vJPPdtHsUps~-z;1!oi(-L~5)CGj*Kd$K7krX_Z9_#>$%`n3<wy78YEwAVKBpMxwfMIf@d5FtrIsTsDo^rt znciamd%HUG1mo<1XjSs+K(mDET=9Ky8jkv?1o)*-n@ZGNA^xfpm_?6BY@?oA5uRHt zds1BJ7Kw;l`+HaKXZ%jk`|FjaD8;JD6IX~jU@Xah!8tGumRmjU*VJpULAXcLx-GhJ zk1yi)H0z1c*Gbm?nJABseglIgcRv?P%)2}C^Q5c)HdnSpyjz|ia{gOxJg{Qa)+kDl zjFLyRC0rUbA}nICnAKO?1cS3XYG#oaNMa|3PuaV8EqVIg@@8+-%$&EezR%n2m2!Zs zZKV)1qs#*srxtn57Y2>ihh)6wO9dl5AH9o21h>O&UnMAfLZ<6&KBz5zO_7o;<0xD- zMdEkM=mAaPCYt+4ySOC+`J-TqQCq!WX(nVo`P0L5q0ooNdss}j?lj|7P2En6mwpU9 zjh?EfKl7ENCKz1B#ojQW(38fvHiZ6xD`d7|KT<^W*#9W;!Sj)-HhH1#T(7J)#fQUb z)?aFBgu<56JAOy~_lX(NpICuvizBkUC^-f9cHx_br&Yi4=5-hC`9TM-(~~x(Pe`7x zntVIcS=7(5(`p*}H34sZk@x$iXS`es!V}{EZF7CgRoGKZan8ue;NoXkj9-ZmV{Q}= zYyW;tBUFy{Vb@y^7AKimQ=Rr(usIrLQa}6zB?@FD_yS_n&v6Ei+(8~9qlRyzCXy%) zlnt3ijg(^||2jGM$vT#;iF_aHvBn45ih!-*WLY&Y30j$F`>^A#d|g4_h0|NJuq&H3 zT*1WN-P7^mLRE_I{uw09BF_O2+*{Rg#+n#xqyYmICISbtP@OKe`dw1Y$W!kkU**Geemjy1^K(Yn~$udJ{^_2BO=!N;?hjoovIVlT*WsO^&^1H4`-1*c<-(^$t ztGeW%m*u$n(b1fEO_gP>rXw%tFA7-XlIy%^{(D@GDw+jz7h2t-+JTX6{r%LqG9##g zx599FFW+luPeH_+SeYlCkJel#}nao}i@W1F4nD^%O zU2F+VwFipyxP+Nc8jGgP!SVLD`~}Uv-IR@-5q2!G6_2t0K3@+#=VqmN_z&m@Gl-J< zbbV+hsh%KS3()|!Yh6HHT;ygmH`P8>#1r`)i0l7V%H`F$odt^T!TBWtucF&wnH`~_ zavF)+f_UJ^$_#k;Et=$r@OU;CiALI<%?rHjWYg^V^7}0f-ms0eLV^VNt*0%(6m+@| zXgY@Y-CoXHl5#<>hH9PH6K*fOei_uN`R>m(VhKhE9i>~#fS3rG!@XDW&dEAfM07dL zR@mz5`H^dP@S`J#dZB+<<^9T`C_94BAS->ka`VJ$B& zQ>`9f9zVVU5K=_$Lmtk(kX{#slbUtv~Tfc3fRK1e}^)N8cRZmzxQC&lHIJIE|cvm%Zd3? z5ZiF^p7uU7I*LOHo|2EM)UYYXaV7XgBep&OX>$_glW(D+G)XBb&{#?9PKjn!yBr|j z2SIjNly~QX+_V+9-JpzO?^yCb&@=0P983YCbVlD?0$c$~g?%=l?DD_D#VhOHng}VI z^)H{+XMegX|J&q6!%2cyuhpv=6RxsrF2#4nz{(l{KDv_c>8!i*Rjw&=n<}MPKbhM| zRGd3mzC-Qn5!drs31jFutve&5FJ-Mh6DL(g}-13M*tzG!e96dn8W z8uZ(CAJ)&(rZMPxisFYv^Sn;<&uu{&{bagHfFnS|{$z+RT%6&*#C zP#33mq9=N7yzwD+q_s(A@M7!+M3dP)WrG$|)F`<#g*i8;&uLXt$ffjrR9u{nJFpnu zZ$kA8=iZd8)+%2=8NIx6Nktplu(7bPv_%a-fCSMI374+qWq>sW08jiF*!=j7w})|( zQ;UV;!(>6$v{DZF-YMH(A=H6Fke4kk)--UF<@LOt1A^`cpje)JNKL(iVwO!MLKS@N z0t)qU8(m^xR7;+mkf0X=CUpyRuj5p(`3)`}d8QMr2ZEV0LUHyI5>~^Q`Sn zQn6koWy$4ngD((o$DaeLlC4RJ_`3v%pFq`xTj#5GV`0pO2`e!x|b6per50b zaIFV?X8|Fhsmyg9^m0`+NqvSp{6(f0qO7b@cVzBBezZoccFUm*H9b;~WuKkv!>!f$ zMcjGHx6I$H)N*Pfj4aph_>#O$sFu~skyq2?eUyl3DV2hXZqlmr*bC%^`sHc6f`*!; z$Yd_)1E*Gbqt2;O#lTnE6NMPQ*8t=SXfTL&k#~z-D=74K+#oN{72`_4iG1S|I2YvuI(i4e;5O*rXg?{khJ#l5S!&@x z8=Q-n{dUJlzRB}<`iy4D5y7cvzKm2PhJ6k z(C5(M_QxPEa-R;%kCozs{1Mn(UphvdZLlp04z&64SNwWeymJlMa*c%vqlL6xDAYO0 z`*PXvzbP-21tzE=EGidmhk0H*A7l+;1}fe6=P;6nSmpDQuB3+ulqAKpiwV= z4frmCUN)DmJB>MYEAwNwyfFj(iU%QW7=`I2~n*te`!QvM?Zlt*-LN- zCOR~om$!2{pz7RRtj^@K*P7g6RS2067+Tm8>pZE|G zI-l&B#m?9`A;#6hA%YbnAM1CkkNyTCZ(U_(hmi_!>m`@6n}!ZuXeBb@Q;?U1SZFQD z$6fd(RuQWMA={~^i>4Tel$AhB{`RnA9>LY>9nWJv3t9G_q z42^nr?Eodi0^_vYb3Wu_3+_sEACF}{(1+sab_NWHn=W2o2SRu z-_dZlY0HFipm$lIy|&{kcg;Rs?dBRVMV{U25(67Ic?NlV!tiJ3j-#UdX6*KuDRZHAm3rkuZaZgO&7xtK+u{wd<1L#4 zjr_7MaJ@Oq->6tyTQfq}+Qq*819{qG`)VBjjLri=?N+I_leyyVo}yr?Zc`dIc^#EQ zd@ks|p}M`Do>m!8{Nl~&2I6ja3}FOQ%v1c+dPj5GW)a2wliyyp_cC$LbFC2w=WNe1 zWnkUajBdz9eK|KlqaUh8&(Vnn&?}DZ@XV)56|(Xx;U@-(7l|6V#*?|tk8-Ff#?=t; zL1#ZzW+&hUx3T`Qjv&I3l3&j;|CjPQt$y*)xh~7c1(%hE^nK0zu9Hv)t$1Qy`uoZ(&t_^CoM9(@N|Bld!a{yg>p^qJMgtEnBditssjugJw3!QZ1#T%cWKybh z%n`rt;POl;?B0DUtp7Q{)@h(mRr(6SAlBCZBFODsr8wm^{HV0ly>!Sq)92tX@)8_q zAt9J9aDR7i4=vuPZmu>miXZ2la^D)=)Kos{>g;5x1VgD@&n~bowT$_Ftso=7qi3ic z4zm0bZ??8wyDL&NK_cw6%WSsvP( z!q1iym3EAm(_q(!<85f?D&zx%t=efUv9H>PS&DCfXFAp z4IE@5SebII)9MMLSpQVNr6KIzy?dP>#(yQt@IGW>WYnB4HSM@=xT`?CF`nO-NKFB$ zdHr>upTHaDR1v(N$9A9Aj{TVln`~O&(rNQ_T)*Z@pH~JW`@c1)(tyE{H;!w8bZ7mw zHN}z#w7OZ`U5cG_u7~L)$Ez173bR1Q*uzW!ushhEObMp&Hg4J_j`$)C)cD<@1?aVSBV>6%H zeD6H7Ny8k^pHM#u^+vUtAN9FEqj?t8T$(FR4H9(ZP!^RVqGJJaS-`&u_a1dAN1=3Q5e`+SVPDUhh>XM0^xko4v8LdgCUR9}>uB5;NBc0bHqLd<$u<+l z-o$X)>Clg1$L}9)kC*t(*;mVWlqrJ(&uGl~*TXfRL5}Jfq_M1Qr@8XU5HS;Xd821u z)D>-|=O2 z_{xqn8B@eN8Hwg=O`QomrTw7{e{Q8~Qi+`7PbZr(6^VPRr>8dx>>E=LHfD^fb}*h9 z#t0b15fKt9*-w_O=Au&to(Z7BE!n_`7hGbP?CzypsR@G28X=3{gDJ0RlTvc)H@2pl^v3gYc*@5y4}yw(D6?|0 zfbpXXBu>-KtxAK9hP|)gZCo8;A6szG(IsW)?JNyP<>)w!Rg5O+`tV)jjlcA~`Cyt} zmUoVCuK2vJCZ>W*&v{*|oFJXaAB`g&`x-A>oT$NpZnT6yh4KljZrREq$jN-nEA+@Y zdxHZ5+dy7+aozC4l#<`})%K7Ko!wZo-)%$#N3T@!(Li1(w9j8E7$Yu{;}4rKA#+b% zW*3R%=6q37uUA$?gV-xQO0BRfPfsyFokZxoW|~7jm$r~>%C@egh1j6P)WxCN=efaw z9=fJ*r8ohy>ow|K+L6C+(N2!;^|O0Ja=!pTq-4UDzZJ}zJH581Dy&d*p}+dI3$^Ta z^HekU$VEI3W*@U@Otk4|9Goxho@}j@jKi<|GqL{sI7;rkh+VlYvY__X{OGTVUHLUq zkccl5_jDW%Zb*5L4-!gw?lm9>jwi{y;kcO3(vLwJBfU!~d2S=5k+PTX1e=2=uUv#Q zBO`ZADj%*Xu3+)S>I16{AYPN*4GJ9E6SLGujPH_c!O1auHr5)x9rYzJkTFlbLJ*Xj~St-f(Nl6e()iN28XNXY8H36T22seDTiy% ztw@t6H@PPIi98^fA{*f=2emKd1ZJm$Q&o&q4u{e zS&ul#W7ssOeo1;K3%QaWlCp?hYA@6+c>9^V!Nzq3kThzDH`zY|&U*S%s#*l>$Afv{(Dy%=-vygf8;12G$zX zx#W-aCkxAf9OT<0MkUbovW--=F`0l0zkK-dK;HlP08(ChS8vtUJHh++Ma7R@X!7S7iCw33!QH*Y%oV3P^`Axx@M5-^ZT$vi z!|rHawi)JZi&cfUxx}^4g-_Y)2v14fTW-x~dT#_9Zci_df-x_&9DT;$ZhocDhw{Ir z)FO=1FOYs0@ZDIg){GlxNxLdlA;uYZv%tPc&hnA+W+|09cPgS#yLrQ@788VY$zVbU z^!D{VFx?1S00zZ^DR5CF`9`zGryHf?Rqg`7(8SdInAEu0;9{eqH#N%g`ZY35BTw<2 z=C?CXJ_t=aSB`mCtyw+ZIfWBHn#(31N`Y%f)=1qFWIrUZIDYD>4KB7a+~@IHaITooH7=y&5?4sb36 zr)H_>=zrn@SneVR!rq5l4b!Fto91}i&e4##Z%uqNDXWpCAz?iNL@%Qc-oJ_H;H&r= zt!ZpfEgkc#`REW)cq~}G>a6Y2WcbdxGa&%p)~@NvJE*-(myN$x0Sab#S$VlAEOQ?C zyqOkj*~CU{x5N{*k#6`Xf<`P!B}JAVrOZA5$&KkcqGW}b)A6Jn@<73ZvK443b0^sk z^Gi-SZxihD393}uL;{yE#QQg)R02133h_KRsEcc0y)r$XB^R|Bw6E@A1-T{OFb!1p z!HA1)n)SW7a4t)!TwlaF+BxQ}?zk19!@%EFJtZetBS4L$0v)RhnAIUjXlc(H_nVi0 z3g6`P6DYNasK}z%KzMN5l_lN*!+&#QdY2bS1a`ETI!!j-p;{>9rZWBj7fVdf34ilft1OB3!@8Fz1D|++V+3#W$(H?>}K?xsEus+>PrD)kv z{r`P;!%`ccmT(Baez7ppG~vQ&xg^ZlOEu+&Xjj3$QueRZqk+}dGN*WCyas3i+HYUK zzPjvbZr-h$hQ3tf@DTKuxYggQl*cJ_`}XY4AKRm%h5J>|@bh|NR%~zHMX;2imt67^ z^ih12akK#hCZe7OVSN_m+ml-zKPZT2(L>&r)>f|3Jk{l3P`+^S$`i!((bo8;iBEyy zyXscYIkH(E3(G%!6}nl`X%iAAU(U9umZ@-0>XY)h$E}}$Jz~-3K~kUdqlCZknG^!6RxP`hie$bcVSZE?&Wd+y`JX4E>6@+GM$nd{@ESv zs?K`xB+^``YzMB)9PT{DKbBzFR>m)f1n%)Gq& zO=-EQMT551Q_RT0^!d)kQ-Y(5ze95clY(y`3Va^Fb^on)$NKe)KJ7U*%%Eo>p$g0H z^y*Rmj<7by_F5h?&7HGmcm1LUNHGsKLY@ygs3i`y;GY6c_r@;33;6=w$EvWHES29% zhW+8|&4LW^@%>5Tl=xC%@zV7jDnPu9evr&2EwzBZ#0jK8q0p!7l7YqRmb8(cVB6or zd#e_to|5FL)6Zyekks&^agA0O1F-WX_KBeyc9b$W{uEd~IimW|I3L*@dvnkp3u}$x z@JsS~Wl8ZiB}yP`v*0?4=f5B46XZoY7Ob%x`vSs*e?;n7_ZAxOr*YHx-F$n2M%%4Q zM122i(Ohy|IsQ|8nXm|2vo#p_SZCA-!ECv`FCNT*f;~dOVhfAp3GpslioWu^iAZ{0 zBmvE*=JGT2P$0Fh4KKfXf-mFOJw7d}1-4=Egi`*Tn{ zux?+$)JQqiaAv>jlRWS8MT7q0<6Z-YS8&bkMcQZJ1+kjsUA5{NPk|qy7#6otn)Yi2 zoHBw-&aPSFlkP1^I4j<-=OYmu1HFO@;R2kZq+4sWRPmp~`giXDsy`8Cqc5jzp0yIV zihj6okCaD<3m*G>*X^<2{p+xyyG@tkDAD9PucsU?KrM<*+5N}`eEAwCqnjgjSLprG zHP)YxAmzh7-vyHf?APX#&?U+`20^39G=OKv5a_`x0!*4t*sKzqed8zLvPBvi-J+hBiPLpMg&jpuZt)kdZ zJAtIppAzL1KXp4c89aY0tVSuPUri~>z2TNQG|^;aG*KZ|gm|WJ)T@%<9l1O3`((Vh z$aX%2=m`cmjHgUn z%Id{=C8Tx8GFG^ns1PW)VMaxB!c2`{p(+>cI*K81Iva^S5Ty5IJz`dO;INuaZ$b z;_uD09huodZYlCS$T@QJqbfO;T#r*1)pMoJVH4mFk^bVA9|tOEnWPl=SLn1hv# zx*91RR-GC?C94+~df7^b<-=1I)x^He_5j*O)<{}h;HtVd#J0FcF z-Y&tqelmNW?-u_I2U6?ABvr0s);br0{6pqt-diMzjKceJ;L}B+bndaMyLl^D)H~|} zO`2>$cr44S6^D2!w0aQJ_g>PWCqlO|PlXJ2r9cWJs zpsjat4Ku%olz4%gc4rO@QznY%fo~b}w{PE$?T>us{cf+f2`FF2QIV38DkBaGC7R`2 z@vleW_ciXPKZO9?SZZ=I@m6zKBSSJ(Y$Rx$XBqZABI(3=bA@aqTOFyiWZd)kE(9eV z3l#`cKwNCTz<*840yT&~eFMtV+H=&p-yuTVsQ9Xpz9bvmtcDdIhF-CCd^-{PbM(-7)?;MQGzMd@^!~DZTAZW#+2s07r3r+QmXC(buiTl<|1g(2&5vG}z2aBp%n@W!!{~Cd=viB4 zMFs;<%BhUk$~9xhs;!B%()DqS$LEIpjnXb|KCSqUxJTp8AYH@@A?3J;YmkgPJ^b{g z4N>pDFJsG}INM6*an2|o>n(BDF+f5*QGy8K2_!HcZyY0F^|P$o%bcq-C$ly)_UGFz znPrPQWoAMKB;EI!InBGzTrIP2zvxi#IhL@`P;yyq{!G%_PH2sO?OWsZ1JeNBF9=Mm ze2y~1#J*1hU}mGn7w-LXVD)4&U1@U~n|rxCS#G&;bA5TK_IieX(65-E=)ndCec0bQ z>+^H#!#0Nc-noxT(uEJE+`Wq$Dpul(#1q(Arp|L^>Mom1y@&dhtB z_p{vR-ursp*PV1yELR`)R#4Iy5%z0biUo#6ToAvj;fW*13JMG=%Yt?(?VgI(J*~cJ zI3?pcTJvHAsLR_Qv}LM|dVy}8t`RT3G?<#2YNwZRVn$wJw_HjMDR}72)J~hbFyK?)1U37#-k=orlRVy9L_p+pXO~aW`>`c$Y zwfvJny@*_t^Sjf1%|&kcN59bFBSg0Z>Rt)i)CS!o=J7VM!=&h{9Z!S|;P(1}gr}yW zN-cprcpFfXv5z2E?rFjz#8=Zo;}`EoCJZ;Kf4=@Cm>>JfKkOmoZ5_b{cRZ>8>$qg# zo9tU%d6<>$DWy9RamfpB)Yu9ZT3MXgM%QQ)c(0`Xt^duU;JN1Sgnxx5O?vUk-kMI- zjPr``P`m9J&@05n=U^WbVW7{GY91_-rB}P@8a|I9R&` z_!<}M<3Tx^o}}&dkvqK7sLFS1u#ax_bKTexGoS*8Du=O`VE{5>fC|xi?fgTF3#Fn- zXuwr=-H?2wS2-Sl?m-N~xV|aCV#h76*eI&wz{fOuG|IU>NPUIG&vzbHns~lVvc`^$K1I~$+C)xqm7--6cJ#Vug)-&VI18*I_Gjz z*6jHg)tFLO!^xp~^|EjK(t~?GCJsu8zrq+O))esHt{T5j=3|^}liF{^?Cp@rpP-Y~ zZl!Nt+oP7nzxfjj9FlIHbvo>sCPkRMb-s8#QNy>sa8Rxab7V~LcRi+J;u#w(ASv~l!V%l@N^ufC|O z$4y?M&$pFy9l2$gR~0|g@1eoIb!3&Nck_v)LgLB{QAJZzI7L+JshwT6at9gmydGnn z$+vcvpYyctyn`^^JxS6%yK&)J@zeg*9&@a>j3Q**X2y)@b>g#XCD%clA=pRB3D3CN z5|Ecv(Z~Fgn%an0K6v~`1WJI-E~6_&0pr_^cFNkoH z7vxDrB*`SLIVoyU_WlPQF4;M1qWW4Ltvcw~smMw7kPEgqU5&HpW}CCk)Qd3F5ywdG z>B9ogeF%$t+XQxwft>AJuO9z1N*~FARXUQbPYeH?ZZPT>vNG3nnW_Iy>gQ1ot1N`P z-6gMe8*P? z`E!YkZmjJp^#?vu(P}nR$2=@G?s@zUR+A-#$9}a;^ir-0+#R<2eibiNEpobY^&hB+ zz3-n3d1~e(tJEQd{uJ}T*zW-oDn0guECpRLn*k@tlBfOvI_D4loh1Gi+4tFIaa)b>Q`6A!!=cy{&?NU1%3XmwK~67%`8g*g z*8j^bIa{~jl%v3GiE7bXSl~1fxpF&E2ojci>+9vV|;+qXH6( zdb4+qj~^z&i{E6q4No$sU%7(2q74+8QEHi2v)>v{w$QFNVW3^(F<|3h8+-O1Jb2K6 z%ha}JVY$${Q<*5^Bb#iSO?InBIP_7Wr-hYt6*NY?j;){Voi@O=JHLc}JT&Wn#|*?` zjT~d0xfNs&+%)c&Iwd!j^eq%kRk+QqvLjET#`c;*HZ^g@4T_1rJ7FLBJ%29VNbPle zy`ncg$gVLH1k#%*WggAWa^CuQzKQ3+O}0znf4T9b`UlRW#s0OGfB@9A&-vD!@WaQ? z`1U{wG*3phf>Y}GV8i>fNy&j%&$Aw;J^F}TB{`K zN=zAOk}IZSO=Q2DW4G-D?|vjpc}Ips@~Uyd8xpH_2=Ac}=zre=m$^HWwBy^e9nwLp zV)V>9YjTuNtL5ei%?RO}8JbDYuuwPACp|0-T=b3H3c@xs@`}8E6@K7yaq3t+@+nAa znWF10$-l`Sb|TwoncstwX8U$g*)6d@1mJ5`r#2q;C~c&BM~bi&41d|4B!~X?o1Y?a zF~c#Bh{N=yh{s=!5@ed*1Ey1v!R(-#^e}O#%(cz%yV1%imdOi5tFM~+@r3Mq6L*12 zW>e02wzTocyOmMK80C?7;o*+6bN-Oy*#8RHl|8bxi0*UUQ(JT_f}YaNO-RDOw?$4% z!4o1+yOcPI$vST6B6TmE`c+xu;aBu4R9lLyx()TmyS;w(?70!jfUt9*NKL!;>Z_wL z+fAoY>`3c)>Eo_%;ldVGra^+Ic2)4BFJw)`_TF`~;=ZsugVfC(@}A~GegG%4NP19) zj;`*dIri~6e?emE!cg53>801LE@pXv^|~hB@Q8|vs?N>m8RdpWRmUao%h|b>_zO7y z0_H6B@C-hs0mUT}8+1dD@I%Px$7msxpSmOx5I#kmJ0bb)ORqX@t9{ZLF}qzjPTpnZ zu<;L~=xST!<&+%=dQ0bVAdueaW`T~I->JUp{Ti}riE!Tbm;Mzt3=0FasRB37K{y@L z^l_Dr`M+?j?m*pll+3UP@RAO0daute>E(|~QASa1yW90B6j`&oqfp0G$SWLrNshBB zjYn337Z65}|K?aoej?%YnKPgN!VaO)A8AfUh6lwRz4=n08{3gc$Z#y|E2(%0AwcTe zWzkNeetdDZ14Lyg*57=?jTJlIb+0@FeaE`P$&dv0D9C8(d;-UsilN&V<9YfR zgQV-w3A#LE$E?b?Y`W5Gt?FwaHD2Q5#m*$%_(8q+pC4#YH7DGX{4o{bw%-ru&CX0B z7z!@_O$kCFvH_c5bn26cBPS3UJPU5WVd9q=c0^bb9*cjkex~bIndIqQc;igaUt;ki zOwWSCLDE*sa2$StFnC--mZ$0Td%(tI=G$CX5o_1=e{7eY;;mc4^bkOOtbefL+5aO= zEv_mK7+>Ln=eb^(3!7!|>$9H&K~hveb(bIc?r_{$=Q#;Q-!4fc6AN|}I{~XF`vW|| z@ME;JW$G*-E~^WBpG(Svu=_S+2O*O}QFD7c0KOS-sRx}uiu7vgpOwiUr#1(@^iAqv zTYT>JvcS8>2n#{O+pS=>UV*c*;%0$8W=5LF8S37tt$gB+VAhT!RHuc_-^u!IuV2=S zpie~|+B;nIB;|~K;33rLpqs^T!?4FS`dd|qPo9D>f)WXaDN674B^$LAYAdtm1{Z0L zv5J@q&qVb3L3>x%*%vgNk1_b$dMBt)&W5WJ)X8fQkD_E%$XyP@e#K*o(h60x0B+fD zYRc_h@9sey%W-%Am1$?I6Vt~tUZU@6z+#OyrwuxKkiy7hcxu|F1krZ2GbC2R1YPY`tfRr?JptwVS% zz>{s@H+RU0*{k@2hjugRhzZR{C`aFn@ATwn()YZ3Va~v6Zcu%oX@{|}=keZQZbh@@rvPgtAlxZJrz}y)>$T268Yi;f4PhQlA@YNT|nKZ9s|asjU58mYYEF59){t9=Jwdu>fN6KGj@ z*_B_+?~#=DN4rfW{)Y`SGib(HGrP6G?4T;C+j8^TZw;wYC~A!mvUWD!%rbg~*;frX za!=yh9+B7YZvk;Ke4#h1F5$E6>q~30Z@D!?CWDe8DLnLjK-`=Wil8!=%EQGJBW6@9 ziFSadMR%nrdt5}!MkPTvSur@N9PUu%Y~_zMqX#d{^Be{hiZqcOMy*KBTH5p5^Hi)v zXX<5ji(^~ep-sB&!3cSNW-^4HV}PHVn>*Ksq*kAjR(K)lVyY6ZKF$RfGqd@^Pvqu6oI(%ztgR2$pVhd2ARmE+h`+UJszm zd@WopPU#L}kQv;Q&4$}w*$v-6fDe*3oY;$_Tj+<2#~(e}^uYt^ST(J#7cx4TR|q1y1essShhNFiYx;;jD}lf8a@{k(Fd z2!lrXm+x&PZw!B#A-nOvuNB`aO12yNk+gDQ;+Dm8BqZ)DU*fEKGq^}`^5IMxjevu` zkA;}502S(E0^umh%-(@^b(x0B>!3EqD`H&%zabY*qak4K#r`B;)o~E=SxWYvYR@ zn;w+-IOp>@*-JA#x<60;p(36J=?f%Z{d>_)Wh#1zx&Sy0TD!9Z=WF zIR%f|%&*ISud}x=+3?zu{q?to7_R{Of}4^OGP7MJgJ>mK6n|B+)#csGO|D{`BJ{bf z%!1mb$uZ}5_wD}+8Su?EW`Xryrp(auxlLLLWn&Ip;d;xAym0$CVR_v$^TVY1*l5ok zR6ySE=Vbl&w5upz3d3pIsEeO#R2f${ym2jm=P>JH$gG91>n@$cC7~N{o_M!2dZ|>D zq4U$W&P<7-!{^M64^A<=uZiYH-C-GlMg zk4D%rWLNo!S<8ux1PPD-me%^kA(ZemQL0wVu1CG-hQ6y7BTAmpxpXJ-(f-LvHfz*$ zU5pp=OXba{MrlX9&>T1P<2Ci{)!D3X4vvG%=i=GbK{>F3e>6PCrX*K@S3F6;J~ zd%IgFr$@B+GVX3spI%Gqc~pROLB&p((mvB98$YV_RBmfL_l4=c?k*Ndb#OPW5Na0v zS@G{aJ%%0+wfYs0XPx}H)>md;MWDo$!x^tRKD#WdL@Ekt6%C`bmVipKZjpmF8Ai&g zt?BqD|7ssRhRfYgkGOWoP@bu-e4kc3d&GBzG@|LSpJRL(mV7gqCwotul(TkZ#qtzhqlely8?a+poW8R_y=F-Y{ zUN-EXm@G@+4B#&n)#R>Br}gMRSclfI*klWyzU>{vN+u4nlP<7aDTsh6MK2lZp4~gc z>4NRMimLgsj`DbAht~F+rR53luPHr_bj@`ARrU9G!PEW%GGuVCPm`<28-tDqJ3RQ1 zN~M@NcHdo@P9>MP0{dIQZ9OTTz43ki+6|`hpPt8+8gjZfZ6ZppK=>r*MY}ox%z2AX ze}tF)1(idH6CBx`twp*^<~Vw7MwH0+I)ba86#B^OkWM%d^a@y4gD=f3|Do%oCkdRcg_9Wb6a5#bE9|Bb~h z{aRH)jZAVB`Hn=9mr7BH-ci^aqjBrMC6lr@zRe$HKC-eLm){R;t!MF)?(+|Tv8V%A zM;&rMWAw6gl(X2OjJLeUb0>B)9EtQxZyd-$lfUNq+ir~sNr@w>I9ihb`hMp^&w|S8 z;UiI#6am$pL46XDQe_EvY1umww(98#60UsHn7pcOBs4SMD{N|Nx`vG37*aekdJKu9 z632JH`;ZBmVs^c=_Kq8Et*t^=AV08pu)xez(wfMsr}xF;A>Ktf z?jI;BDqaa^mso9=YDgMTB8AFi>QHsyg-bAP3j`+y)G|lB-cJ1d;4a~VY@oEYh)0BD z>Y<%%M8#%d34{$qX&`m|pa0&rYu5SIz)NeJTu>`J&n{wFvkX_>-fY`Gw3bMN!sUYX zkVedn^w0Hjo|dRF=NSym8wdS`3}Yb{ihu_h9rb&pvVMG^^qxqr>fO7KzdGhrYe)2b z0eUQW-?mFbWl^|q5&Wi~ZYX?RYY3|rznmo}Bke&jJ?gjt?Zm1@?0Pc?CDCp|VJV~6 z6kzjgjC655r#E!?ZYKtY=VVq2VU2hahc0Us-49%8FpaxnmYwF9tf`?<)f~k2VHo^y zInV}~Hp`~1m9`qWboM|iZyv&uK7_!x_UHhKaH|jYcce=E$TiMkRLLXZ_*>q^JB-=b zuf~_*`UvJ6x6pNnoX;z072gQVZ!k7Y3a<8CdGOz9Ilc$6{4Y1gkcC8M<+OX z`4A<-jwFw8C;NYt>g@waAwt+&Y1>dgem?J9B6qmO;C6=6RPSFeT=3D;m7i~^YF^A~ zXfH9y)EeXeHyg6}SQ)MSy~*aNIHZEgrx2~Dr}te}pve20_=^<9%o|#nT=VoKQsxnq z=VZX7`I{uA*C8LC?zm2fLbSBKj|AS>evoos{{5Pfr(6$G_A)pstHc^@OF8?lOqUW( z$R(S=X`64`2geDY6PFX}b%}6D`IV*PSMtZii;iFI&;~iYFePUPat98wHr~(MetDN~ z`GecSAaCAny7iO6$f6^pabF=m8-%0+@OVz@k*>)bopA!X)1#2-c;<)*1h8``Vkz*B z9#HnBR}o}~syWy+5Anohe7E$a<{4OT+>RkxX8|r_KAe-$_mNBV;axP#WSrK$6Vuv{ z6WVGSZOV}wDO}( zu*B=iZ?qgo$w`UaL@%6D_9^u{sE@bP?V|L2)JSYJY`Q<2#O3677O8TjT1Qol`~N<8dSobw4J$zMR#Tbc%->5-nmc&Ta>u`bL=*`05(Jlm5S>*(*sMe{a}WMPDYxI?HQiX-b1 zzbs>{=8&kja{#}E6B$jPP9;G4NTwTh}O&2O}<|@Ow3*=M2d!{n=l%w|R0g6!J zek%dr!z%Ujoq?QoN>{XiZtUd5+e$aW&{mp>Bi3CA*_N_>=ln)+Dz1=E@DSDFRP>3!gs($hM`jhcOXZ-FShUQob z_@4*-EEHOL84kGh#Q}?~H4i3hzK_F!V`&wjMd$k5z`)>Ri9+K21(0UNyQwF+H+%ad zNQifZ+>1o5aC~K)lnTL>6r>mW^*oBsDBG@3e@8I^()zBm27Myc!)c^JyZOCkua|8?|)J4Oq0$$ z78_0eF3pj=T(8MopBHQ=xg4Qbi(ilVrPro|a#~-qMXA#m70Gz*@#Q5TeG&d$1&x&~ z9*I0EUmK6(XT*!Z5j5%O`V>%Bd9D%#!0k{nB1zbM7RLR8bIbccIje0rdl+ME zGPdPib8NllS&&pshtABOqtP$9!=f^OzTP&qK2 zDcY>c983qfCp_ZX2seeF5t}a_l$Fg7O;P@;{37wFUFj{Xc|{d13k7gjP`QqC3AycQ z$^ta!IK4{N9NW%UL#9Lmfwp=ElNe8)j23;^6yYyZt!mWlc^FEli|F~?yy^I(LM-ik0KS{cwEh@BGJ{^37m$>Y5tA*F^SR2L44`=37Fd-5nrATHLa zS6?+>SJ5wz%>Q_e5!Vl_M)nNl^CZ(KC~Tu98K7tP+KP zVLx$qef?B}2rR<&gn{hFY_SBWnO;Sbu--CT3fJ;lr(eI&viLp|8sD3qR52&E7?eq; zwYV5racbAMIpG)KB=5OjDV90@-;`3`F!S$wlFsXzBPGOaS0CJtYvk1?0Ylw?PfcZ{hmSSngk>(NtpmGV&2S`BSmFPr^l)&^k2ML(qEGD z@U%#4*UyT6xpHi`PRfA^kB3^gkC=mDV25VGKIa&oj9Gf#z`M+1DnnuUT7i=z!_g@u zCYX>Oevh}POutBj;NX`{McHGI&C_0@8SdQ~6XHGBR43=YG(hS{9C2r$Lr6j{Hu4$x z$G`QpHc#fZ_D~#BqWy64r(C-V3oboq@`_(Z35c?tjd{V->p%mI845YD=v$tUyTNu3#o$XmU45yEWX_i^7 zS}HRx`^+?P7iG=SZ@BAWNTFXX?iE>P>wRB$UEm+G+M73}qZvN%)5A6{MZaF5tJws) zSf|7xx6GQnj${^I@;sJ)Lw|TMekiBhZkt$EK;-bVG0SW5H+9MTk>o-{#&{Thc{u#M zK@erlFuGmZ2It!gI1?7z#q`J6#4Uid%T`Z0RuE~TT4N{@FXKdsD71+@SPv!8=2}MO_}AL9~_b%l|(?Q_gr%R6$1v9+qO{QwO5Qj*ylmQOWkwG z@6-nmF21mDYHu$FXqnhzaoB6A<^?6TYI8i4i9Q`#{h~g+WK#uV zXCX`Ap-WriqaHxBtLW?NTPFdvyZRQ!VDLbg4n4cMGLdkYfzwwrn2yE&TOd6B#&fV3 z1Yj}k3Bon=^zq}_G{6CKz6u7+K$@)-iGkV>d}R1p`0~SQL>`KnU&FM*zAtx757N=2 z1M6RIgVVS_12*JTdRp3@tb^iz2xXP3raP)*rBym&u*?X71re3z(`0#ka`j}HbwLOSGlWMx)}qLvRe?zJxbDD(qJd=NwK3*w!SI9n7&b zLcxo@Y_dUse>jC-C-uQQNWgRaZ$hcXhk4jrg{8h*E^Scc`zV|Lv!4JLCx&t=E^Rj?IR(WD(8h2t^-)C_L$ucC+o- zv$ZwXau4EuFH#$Jjs?VD0{YnLl{5DrdLe|FQ@=WT?7J8Me=~yERtN{PpyUiWcq#pe z1Dy_qXnazdu&*=>rU;?EYu$$*pA0oG&_H*8`S3wovRbYMygH=d))*;6v!aDfI@+<$ z^Jcs2_TK9U3cHm^ng`NbtOkIDab;eC38cFXL;);lMYKr+hSw9g=>>g-)nG6_=-an{ zNn`_6VYdw;^3Ss>g!N)>|3q^~bLy=z$xdA}`1O+){Ra1-^a2mXu7h>dD{JdQ((B>i;2!`dLs?hGi4U!+*Vf6^<>9<)ZFmW&H`D`q*l{<~qt~{@h zDd6@uNAQn-RDmBqeo!G}@Wnx(Vvj(_Ylu9A`3X5qi(oDU#0I3;;+{LKqt*o`IKJ)R zSk1#S&U1^9S zybv%A3%Ke*v60YAMr3-DkeX|855kZN6xH8=Azjk`_A5*Fpko9pf8+kN7rUHF&$_>g zKpO95hq?E~Z?UMH=ujKh?@f2uS(aaa5Bo-m;R)j@w4JHCRv31rFsSx>?~b!ahqI|! z>JhePN00+U^>8y?N&qT4#HIRhqa4 zqyx}J8fw%#jY8d20}Xx#D9xS7@$>Uj*!Y_$)Nv_lC^#ept$b;V6axJW? zlZ0(YBG!ylRU3cPH8LvPKy4*2 z^xZq5^nYJ}Qoy(811VEHbc<%&7 zw~vQ8CIXkiH%O>a4Oz_5Q{N3R8-*RRJ7&(#E1HX95+ksZ=7@3$`nEejUf7F`0-T_1 zi1!3$A%4(4-8;u%Fe)yNtmo~$y`aYmm(;T?5Kk^*(UPR2UI z-L%mSZ5h-Q6cqgZ{Px&=9CTmxwEXa915z&X^M58yp52ebS&B#tR(quMH$Z&+rwugL z<+Audh)UZ<*4N5vEbnb-XcBn&XMCRa)YYY+0bo54g==o6*N()ke;DMUO0`W);tRp9 z-xwSmoB(h1+N0LLMNmtxuXh548oK!Dy9XfugYT5AUt){dI5_+s10KfEbC%)6^b6;f z2l-T&(DD{Yf}!vI^_AN7|* z@9)Yrxo01H$8nq&)eu`!;xPlm=ZrqL1_#Q&sG>q@-ZWGP*OXOrf03`;Aw7B<*<^6bphql4o|X>m!EHzb+TLWp7}a`VL6{6H zrIf3_jbR+NmrsQfl&VfPwYBZxa!N+ZV_YXFW>z*ydFXpADE_X;*Zm+b=7R)|U{{6M zSy`7Wb{VDsmN(qq+Pdl^gF^i{3Kd#(r@@k{x0-`i`pV?+U?~-%58V zW|D0=ofzXt-3NXRJFs^Sg!uVq!VxdxZmu1bY- z$yGT6o5bTPv^+&Qy^M{GjbB|`JI*5!A}cLj`4ln};Yzn}v;Mo7-~u1L9UL574aJ?K zj#W$k_qA;yunw*>@6H6z;_zxXAbSCp8 zm}lfMiqO2E(A;OKC`FY|tHpu0vQOBgcu^VVfm)Bo$-zz)K7>+N_r_LTxOUAo!-aHq zN)!#+2R9feDai8Ba}rMLi{{U3?(XjWD=RBInTP-PU=)hJR>TMS^8e#}{lEYH|9jp4 zZ>%7gK27nrA5w9|0oVf1Q@U6YHXJG-A5?r$N>G;NMF38vx{r@fpm7f8T}@52HK=@5 z(;hkU_^TxHSS!weqoSgPqh3& z97qrEL0`d&px+dz29T)c^n+6-3|46qf;j^nMyQQJU4f3Ha-&EZTjZ0v6^~z7UY?`9 zhDQ5QrbQVUnS06-Bd&W%s#8$BP0~cgYQz=$y2BH#{p`<OS*-s)AGtO;=7y<4wsC)&Fp`2_I5)!Tg4cFxN@86t}&6d>*E21B3Lky!pQi zgArLf-RojvX}~~SXq%p%{uDM4@?AIY<#u1RR<+p0iQDVBd}E#l*yf%56^EqJ(xvX3I~(oZ8fkNCx-J(_ZUxhW~u5agN@V5AU%a5eM@B~ShrWHA zSY#w5sZ6*eDY>on{P{*wRAl7yOEk9(vKdf6Xg)O&db4yHR9`#V+pD?t`U6zx8n=35 zky4Nz8H&x_2s!Xduh28M9|5enqkPP|=@Xp(r_t&1NX z=9p{p8%F#C6$Tl7nt(S7vG)+0ec{%euz6*v`ZFo-q=LyIK(i0T#KcH>-~T&=3}mR# zILDZ6w8cM*sXolE|0m+bcZES38=KsxrD@|K* zmka#MqtPciD8%422E4iBeGdtz`asyw|4(P9$e{V48Kh?&9V?cKEwrsrtkqz*XPRzf zz!$GD`SX@5)UTnT!Jn_N2Xd2sazqqzrZ1j3d-mFe-XtLIa&8?w`ET&U$R@<4nrmdT zgDTG}O{s{tdE-T=_HNlyEV*xVR*0s;T+ZwX|U3 z1^jwSK3Mb)l$HhfbJ zjzSIiDrckB4v600kEJ1NW%2MLHauMOERGVnO8Fx{y_@202df+mSl%xXWlT&s9As5j zG7K%Q?hDmeEg7<oTBkXE$FV`o$b1A0YKG@#Yn% zIHGEX@7%uq1-cbT^D(DtK<5HoHl?KK=>G=6LkypXUXRc<9zIp7rK?*gpVGBHN7`n} zra<1r>B!W9ML4vIzYlP`Os-DWQy?v%P(1Z;(>pQEDL@5#iR{|S$`j4IcQ-{Kijn_w z^N(GT5}0pPfIT=ys4tUH<}<+8GHCvK08D?531DH)qovgM4P_!P_){S*~z&F9J>Rg;;KjZ*skAb(cy z(xuaCn9R&lECzFF+b;YP+;6I|W_`E8F}nG)MY!5GyR6JB9b0^wlXE|q%IChW7i=MZ zJ;9h5K}uFWjBRgUUk8BQ-Aha(F$=Dfws=w{+{rUO7RhD%Ux}M@?O>UJmyPw zcJ`gAsVR@*|Na|tOBswF@tJF@1}e}&C>`bhR`#OQ-{eL)k5=$m0C zIoRw%?(fq(4K5Q*3=KW(-Q7tJssSA_$!p^AZ9OA9D);XB%_RDOSY7?UJ;fZ`{E!aR z{p{=Rw(E0T0?q%KZz(AZ0!u%-=^%Vt@XSEYzDR1QreTWAJH$OGI=k4X? zF0->(7zI%Uig*ZBO8=^#vW698nN)kgkx!BEz-c4-r-x4t2aR1VyIi-*JJk5=*Gbh5 zzq@zuQWM!lHjtp^SiIpt<-ouI`={%=w8VjYe-4;31+eNzA6Q#6EayTJ@hj}xhL2QU z5;P>R_#Vw$YmW*ge#KZ2-?CidgsK_zdk=ai_9;(wUW;s%$8pP7&Q+zP@U-ijTNoJp zDXy%n%z$@5j*k`yUEI5OuT7D5L)D}oZkZ{&yp{Y$PPMo+qGt(eN87)T=Pa1))Dp8- zEiF&sXS^aYRptpAhTzd?HmtN$Al|YQ_1q_2dcrkf)6yTSNO}Z1L4C~GRbOiDOU2o} z2MLWX#BzWV(sqTbA;D|)iJveGweeeylYzI%a`M&(s=wb~^2%rq99P`InecLU;VE>DRQ zS&y*^r?E>uH2~?K^}*GRKI?GBB^M3t# zS=s#*Bp$JT@Ibcj@%2+9y#G$`vk29+0;M~5IAV&SbRelks897r^)2XDcIi?z9*-vy zU+*a?DV@^wtJ!}@6{gF8iurK`WALlK-tXIg;dQmO`wbO`P|u$GHc70ZMn@(qx1kZu z`WV{}oAh01%P8;j)c8;A2AHRm-vPsDNBs`D1K*1J2eh0~l(I3uPjPaZi%a{O^A$x4 z(|YlvYW%vcF`%Al(0AK3AuJIBc%(rCVx3H*zu0qeaaC)69wIC)C47ImZ9119 z7l6m%SY#rXZYwEqx@MqDe4SUIhh3$x+G8m8F>H=wG&D7E;S@1_)5_%7A;NXyL?`!5 zg<3$|DR5&HV*Y2Cb>aPTva+(!F?=O4B69cs6dMls&izFE%I#PYqQOjyhnw54-*eQk z|DJT`Zm^=!2THVLChy(d-OtD|vl$nj`^jFFOXYtp=}e!^^)q!gHZ)IG?{ik={&#V! z`w=c%pP^j)V|DV{bWDe9kCRi}3ArcTsiD4#|F$-3#>31d2rcljd?okzdH~VAHRf-n zrq*&#R0u!pJuM|AWvzUIiYL`<;VKN(LhWyyq(B_g^1_rFig&l9$=?*_b*#)$AUD2cU?k@}KvEuQ%?_dU-!M5jSTSko-Ds&jF!_?{gVs{2na5)IT#uWs zF=Q%Pf6!*A8#52A8bUS)c%+2NZ|=t};(E9n7Hn0Nl$w6it+I*6x0Msi^#(5RrYc|T zI9kxSpXM==Fwe_F`_P;&t1bp{7k&!prhhqOUazQF`Hp)GErf)nC?|c@(M2#he;1zR znY`)`pW08oaldwgboefB>hTMFeEy|KwuPW&$o3n7Q_->geKynXvx>*M0;u-N@yti3yY_f>zz zA&67vG}HoBEN_5sKQu*p?(Tl4tVi&eTCC7kmH}q(!+Q6c$uU$ZClcd3dF<`&QMe=) zRaBbuK7C%=VvhqON?5-i@qvo4?hR*4gL(3wn_TmszeyvuV5Y#YM@tr(nL9Pv|J7v+l=FWiw+2!~Z|SLuI~ zRC+E(m2?kcB`hEq=^Wq^s>8PB{i~@T=$Cq|jgxNc0Bv>!3IqK3yg$Yn3%>BL0dp)l zC4VR7>dw|y(M6(7kW0Vh$pQNdrD{j%>2o*0sn#*ic&`bK{ovJVZe~!`J$eFl!8Z7f zkNf-nXvk@d3=T@&r#*<8(s{;U#tr9g9@%xv7d*Swa(jPGLaccCoJlV9$K3Gt@$oojc0;8tdeCe&IGCw-@Rg#^ opi@9x<8m|9wlwS|p(s)PwR#6<-#C_nJBCuZqj5V|(K7J=1IAw=6951J literal 0 HcmV?d00001 From 9b558d2ebadc90746db5cd15c39d0323af32f506 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 23 Feb 2019 09:57:08 -0700 Subject: [PATCH 003/764] tupleReturn improvements (#445) * tupleReturn improvements - fixed `@tupleReturn` on arrow functions - enabled inference of tupleReturn on arrow functions - preventing wrap+unpack when using spread operator on tupleReturn function * added tests for argument inference * better name --- src/LuaTransformer.ts | 22 +++++++--- src/TSHelper.ts | 43 ++++++++++++++++---- test/unit/tuples.spec.ts | 86 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 13 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index c72debaeb..e04c594da 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2972,7 +2972,15 @@ export class LuaTransformer { hasContext ? context : undefined ); - const body = ts.isBlock(node.body) ? node.body : ts.createBlock([ts.createReturn(node.body)]); + let body: ts.Block; + if (ts.isBlock(node.body)) { + body = node.body; + } else { + const returnExpression = ts.createReturn(node.body); + body = ts.createBlock([returnExpression]); + returnExpression.parent = body; + body.parent = node.body.parent; + } const [transformedBody] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); return tstl.createFunctionExpression( @@ -3053,9 +3061,10 @@ export class LuaTransformer { const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) && tsHelper.isInTupleReturnFunction(node, this.checker); const isInDestructingAssignment = tsHelper.isInDestructingAssignment(node); + const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); - const wrapResult = isTupleReturn && !isTupleReturnForward&& !isInDestructingAssignment - && returnValueIsUsed && !isLuaIterator; + const wrapResult = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment + && !isInSpread && returnValueIsUsed && !isLuaIterator; if (ts.isPropertyAccessExpression(node.expression)) { const result = this.transformPropertyCall(node); @@ -3707,8 +3716,11 @@ export class LuaTransformer { public transformSpreadElement(expression: ts.SpreadElement): ExpressionVisitResult { const innerExpression = this.transformExpression(expression.expression); - - return this.createUnpackCall(innerExpression, expression); + if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) { + return innerExpression; + } else { + return this.createUnpackCall(innerExpression, expression); + } } public transformStringLiteral(literal: ts.StringLiteralLike): tstl.StringLiteral { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index e67dfd969..347f165cb 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -187,7 +187,13 @@ export class TSHelper { public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { - const decorators = TSHelper.getCustomDecorators(checker.getTypeAtLocation(declaration), checker); + let functionType: ts.Type; + if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { + functionType = TSHelper.inferAssignedType(declaration, checker); + } else { + functionType = checker.getTypeAtLocation(declaration); + } + const decorators = TSHelper.getCustomDecorators(functionType, checker); return decorators.has(DecoratorKind.TupleReturn); } else { return false; @@ -446,15 +452,36 @@ export class TSHelper { } else if (ts.isCallExpression(expression.parent)) { // Expression being passed as argument to a function - let i = expression.parent.arguments.indexOf(expression); - if (i >= 0) { + const argumentIndex = expression.parent.arguments.indexOf(expression); + if (argumentIndex >= 0) { const parentSignature = checker.getResolvedSignature(expression.parent); - const parentSignatureDeclaration = parentSignature.getDeclaration(); - if (parentSignatureDeclaration) { - if (this.getExplicitThisParameter(parentSignatureDeclaration)) { - ++i; + if (parentSignature.parameters.length > 0) { // In case function type is 'any' + const signatureIndex = Math.min(argumentIndex, parentSignature.parameters.length - 1); + let parameterType = checker.getTypeOfSymbolAtLocation( + parentSignature.parameters[signatureIndex], + expression + ); + if (TSHelper.isArrayType(parameterType, checker)) { + // Check for elipses argument + const parentSignatureDeclaration = parentSignature.getDeclaration(); + if (parentSignatureDeclaration) { + let declarationIndex = signatureIndex; + if (this.getExplicitThisParameter(parentSignatureDeclaration)) { + // Ignore 'this' parameter + ++declarationIndex; + } + const parameterDeclaration = parentSignatureDeclaration.parameters[declarationIndex]; + if ((parameterType.flags & ts.TypeFlags.Object) !== 0 + && ((parameterType as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) !== 0 + && parameterDeclaration.dotDotDotToken) + { + // Determine type from elipsis array/tuple type + const parameterTypeReference = (parameterType as ts.TypeReference); + parameterType = parameterTypeReference.typeArguments[argumentIndex - declarationIndex]; + } + } } - return checker.getTypeAtLocation(parentSignatureDeclaration.parameters[i]); + return parameterType; } } diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 16f1bf935..796836c29 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -168,4 +168,90 @@ export class TupleTests { // Assert Expect(result).toBe(5); } + + @Test("Tuple Return on Arrow Function") + public tupleReturnOnArrowFunction(): void { + const code = + `const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; + const [a, b] = fn("foo"); + return a + b;`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } + + @Test("Tuple Return Inference") + public tupleReturnInference(): void { + const code = + `/** @tupleReturn */ interface Fn { (s: string): [string, string] } + const fn: Fn = s => [s, "bar"]; + const [a, b] = fn("foo"); + return a + b;`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } + + @Test("Tuple Return Inference as Argument") + public tupleReturnInferenceAsArgument(): void { + const code = + `/** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(fn: Fn) { + const [a, b] = fn("foo"); + return a + b; + } + return foo(s => [s, "bar"]);`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } + + @Test("Tuple Return Inference as Elipsis Argument") + public tupleReturnInferenceAsElipsisArgument(): void { + const code = + `/** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(a: number, ...fn: Fn[]) { + const [a, b] = fn[0]("foo"); + return a + b; + } + return foo(7, s => [s, "bar"]);`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } + + @Test("Tuple Return Inference as Elipsis Tuple Argument") + public tupleReturnInferenceAsElipsisTupleArgument(): void { + const code = + `/** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(a: number, ...fn: [number, Fn]) { + const [a, b] = fn[1]("foo"); + return a + b; + } + return foo(7, 17, s => [s, "bar"]);`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } + + @Test("Tuple Return in Spread") + public tupleReturnInSpread(): void { + const code = + `/** @tupleReturn */ function foo(): [string, string] { + return ["foo", "bar"]; + } + function bar(a: string, b: string) { + return a + b; + } + return bar(...foo());`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("foobar"); + } } From f7e95b9a6cf2d08cf7a1c45d6545bd4107d49202 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 23 Feb 2019 18:17:04 +0100 Subject: [PATCH 004/764] Made boolean CLI option values optional, if no value is supplied they default to true (#446) --- src/CommandLineParser.ts | 29 ++++++++++++++++++++------ test/unit/commandLineParser.spec.ts | 32 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index 4d631a501..4881adc4d 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -10,6 +10,10 @@ type ParseResult = { isValid: true; result: T } | { isValid: false, errorMessage: string}; +type ArgumentParseResult = + { isValid: true; result: T; increment?: number } + | { isValid: false, errorMessage: string }; + interface ParsedCommandLine extends ts.ParsedCommandLine { options: CompilerOptions; } @@ -190,10 +194,11 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL const argumentName = args[i].substr(2); const option = optionDeclarations[argumentName]; if (option) { - const argumentResult = getArgumentValue(argumentName, args[i + 1]); - i++; // Skip the value from being considered as argument name + const argumentResult = getArgumentValue(argumentName, i, args); if (argumentResult.isValid === true) { result[argumentName] = argumentResult.result; + // Skip value from being considered as option + i += argumentResult.increment !== undefined ? argumentResult.increment : 1; } else { return { isValid: false, errorMessage: argumentResult.errorMessage }; } @@ -209,10 +214,11 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL } if (argumentName) { - const argumentResult = getArgumentValue(argumentName, args[i + 1]); - i++; // Skip the value from being considered as argument name + const argumentResult = getArgumentValue(argumentName, i, args); if (argumentResult.isValid === true) { result[argumentName] = argumentResult.result; + // Skip value from being considered as option + i += argumentResult.increment !== undefined ? argumentResult.increment : 1; } else { return { isValid: false, errorMessage: argumentResult.errorMessage }; } @@ -232,13 +238,24 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL return { isValid: true, result: commandLine }; } -function getArgumentValue(argumentName: string, argument: string): ParseResult +function getArgumentValue( + argumentName: string, + argumentIndex: number, + args: string[] +): ArgumentParseResult { + const option = optionDeclarations[argumentName]; + const argument = args[argumentIndex + 1]; + + if (option.type === "boolean" && (argument === undefined || argument.startsWith("-"))) { + // Set boolean arguments without supplied value to true + return { isValid: true, result: true, increment: 0 }; + } + if (argument === undefined) { return { isValid: false, errorMessage: `Missing value for parameter ${argumentName}`}; } - const option = optionDeclarations[argumentName]; const value = readValue(argument, option.type, argumentName); if (option.choices) { diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts index 3b9bceacd..ab20b33d2 100644 --- a/test/unit/commandLineParser.spec.ts +++ b/test/unit/commandLineParser.spec.ts @@ -66,6 +66,8 @@ export class CommandLineParserTests @TestCase([""], false) @TestCase(["--noHeader", "true"], true) @TestCase(["--noHeader", "false"], false) + @TestCase(["--noHeader"], true) + @TestCase(["--noHeader", "--noHoisting"], true) @Test("CLI parser noHeader") public cliParserNoHeader(args: string[], expected: boolean): void { const result = parseCommandLine(args); @@ -76,6 +78,21 @@ export class CommandLineParserTests } } + @TestCase([""], false) + @TestCase(["--noHoisting", "true"], true) + @TestCase(["--noHoisting", "false"], false) + @TestCase(["--noHoisting"], true) + @TestCase(["--noHoisting", "--noHeader"], true) + @Test("CLI parser noHoisting") + public cliParserNoHoisting(args: string[], expected: boolean): void { + const result = parseCommandLine(args); + if (result.isValid === true) { + Expect(result.result.options.noHoisting).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + @TestCase([""], false) @TestCase(["--project", "tsconfig.json"], true) @TestCase(["-p", "tsconfig.json"], true) @@ -89,6 +106,21 @@ export class CommandLineParserTests } } + @Test("CLI Parser Multiple Options") + public cliParserMultipleOptions(): void { + const commandLine = "--project tsconfig.json --noHeader --noHoisting -lt 5.3"; + const result = parseCommandLine(commandLine.split(" ")); + + if (result.isValid === true) { + Expect(result.result.options.project).toBeDefined(); + Expect(result.result.options.noHeader).toBe(true); + Expect(result.result.options.noHoisting).toBe(true); + Expect(result.result.options.luaTarget).toBe(LuaTarget.Lua53); + } else { + Expect(result.isValid).toBeTruthy(); + } + } + @TestCase([""], false) @TestCase(["--help"], true) @TestCase(["-h"], true) From bbb4813e84ea1b2ea2a565264baccc66f421dda2 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 24 Feb 2019 07:51:33 -0700 Subject: [PATCH 005/764] Changed `@luaIterator` so that it must be applied to the iterator type, not the generator function. (#448) --- src/LuaTransformer.ts | 14 ++++++-------- src/TSHelper.ts | 20 +++---------------- test/unit/loops.spec.ts | 43 +++++++++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e04c594da..e752ac0f4 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1792,10 +1792,7 @@ export class LuaTransformer { // If return expression is an array literal, leave out brackets. return tstl.createReturnStatement(statement.expression.elements .map(elem => this.transformExpression(elem))); - } else if ( - !tsHelper.isTupleReturnCall(statement.expression, this.checker) - && !tsHelper.isInLuaIteratorFunction(statement, this.checker)) - { + } else if (!tsHelper.isTupleReturnCall(statement.expression, this.checker)) { // If return expression is not another TupleReturn call, unpack it const expression = this.createUnpackCall( this.transformExpression(statement.expression), @@ -1971,7 +1968,9 @@ export class LuaTransformer { public transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const luaIterator = this.transformExpression(statement.expression); - if (tsHelper.isTupleReturnCall(statement.expression, this.checker)) { + const type = this.checker.getTypeAtLocation(statement.expression); + const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); + if (tupleReturn) { // LuaIterator + TupleReturn if (ts.isVariableDeclarationList(statement.initializer)) { // Variables declared in for loop @@ -2073,7 +2072,7 @@ export class LuaTransformer { // Arrays return this.transformForOfArrayStatement(statement, body); - } else if (tsHelper.isLuaIteratorCall(statement.expression, this.checker)) { + } else if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { // LuaIterators return this.transformForOfLuaIteratorStatement(statement, body); @@ -3056,7 +3055,6 @@ export class LuaTransformer { // Check for calls on primitives to override let parameters: tstl.Expression[] = []; - const isLuaIterator = tsHelper.isLuaIteratorCall(node, this.checker); const isTupleReturn = tsHelper.isTupleReturnCall(node, this.checker); const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) && tsHelper.isInTupleReturnFunction(node, this.checker); @@ -3064,7 +3062,7 @@ export class LuaTransformer { const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); const wrapResult = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment - && !isInSpread && returnValueIsUsed && !isLuaIterator; + && !isInSpread && returnValueIsUsed; if (ts.isPropertyAccessExpression(node.expression)) { const result = this.transformPropertyCall(node); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 347f165cb..a6ec285ef 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -165,13 +165,9 @@ export class TSHelper { return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker)); } - public static isLuaIteratorCall(node: ts.Node, checker: ts.TypeChecker): boolean { - if (ts.isCallExpression(node) && node.parent && ts.isForOfStatement(node.parent)) { - const type = checker.getTypeAtLocation(node.expression); - return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); - } else { - return false; - } + public static isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); } public static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { @@ -200,16 +196,6 @@ export class TSHelper { } } - public static isInLuaIteratorFunction(node: ts.Node, checker: ts.TypeChecker): boolean { - const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); - if (declaration) { - const decorators = TSHelper.getCustomDecorators(checker.getTypeAtLocation(declaration), checker); - return decorators.has(DecoratorKind.LuaIterator); - } else { - return false; - } - } - public static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 26eb44443..8487e1510 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -525,7 +525,8 @@ export class LuaLoopTests public forofLuaIterator(): void { const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ - function luaIter(): Iterable { + interface Iter extends Iterable {} + function luaIter(): Iter { let i = 0; return (() => arr[i++]) as any; } @@ -545,7 +546,8 @@ export class LuaLoopTests public forofLuaIteratorExistingVar(): void { const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ - function luaIter(): Iterable { + interface Iter extends Iterable {} + function luaIter(): Iter { let i = 0; return (() => arr[i++]) as any; } @@ -566,7 +568,8 @@ export class LuaLoopTests public forofLuaIteratorDestructuring(): void { const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ - function luaIter(): Iterable<[string, string]> { + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { let i = 0; return (() => arr[i] && [i.toString(), arr[i++]]) as any; } @@ -586,7 +589,8 @@ export class LuaLoopTests public forofLuaIteratorDestructuringExistingVar(): void { const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ - function luaIter(): Iterable<[string, string]> { + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { let i = 0; return (() => arr[i] && [i.toString(), arr[i++]]) as any; } @@ -609,7 +613,8 @@ export class LuaLoopTests const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ /** @tupleReturn */ - function luaIter(): Iterable<[string, string]> { + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { let i = 0; /** @tupleReturn */ function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } @@ -632,7 +637,8 @@ export class LuaLoopTests const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ /** @tupleReturn */ - function luaIter(): Iterable<[string, string]> { + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { let i = 0; /** @tupleReturn */ function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } @@ -656,7 +662,8 @@ export class LuaLoopTests public forofLuaIteratorTupleReturnSingleVar(): void { const code = `/** @luaIterator */ /** @tupleReturn */ - declare function luaIter(): Iterable<[string, string]>; + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; for (let x of luaIter()) {}`; const compilerOptions = { luaLibImport: LuaLibImportKind.Require, @@ -674,7 +681,8 @@ export class LuaLoopTests public forofLuaIteratorTupleReturnSingleExistingVar(): void { const code = `/** @luaIterator */ /** @tupleReturn */ - declare function luaIter(): Iterable<[string, string]>; + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; let x: [string, string]; for (x of luaIter()) {}`; const compilerOptions = { @@ -694,14 +702,15 @@ export class LuaLoopTests const code = `const arr = ["a", "b", "c"]; /** @luaIterator */ - function luaIter(): Iterable { + interface Iter extends Iterable {} + function luaIter(): Iter { let i = 0; function iter() { return arr[i++]; } return iter as any; } - /** @luaIterator */ - function forward(): Iterable { - return luaIter(); + function forward() { + const iter = luaIter(); + return iter; } let result = ""; for (let a of forward()) { result += a; } @@ -721,16 +730,16 @@ export class LuaLoopTests `const arr = ["a", "b", "c"]; /** @luaIterator */ /** @tupleReturn */ - function luaIter(): Iterable<[string, string]> { + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { let i = 0; /** @tupleReturn */ function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } return iter as any; } - /** @luaIterator */ - /** @tupleReturn */ - function forward(): Iterable<[string, string]> { - return luaIter(); + function forward() { + const iter = luaIter(); + return iter; } let result = ""; for (let [a, b] of forward()) { result += a + b; } From f78cf46816ed825288518908a1935907ac015328 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 24 Feb 2019 16:31:09 +0100 Subject: [PATCH 006/764] Updated references after repo move --- .travis.yml | 2 +- README.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 041c04bae..14b56e048 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,4 +16,4 @@ deploy: secure: zXFXK1GohutgqKXQ101uKcJKcf0wgCuVPFMY44Xl/JwXeLsA1CJ4aqUdoXh2ramcI+9wTVj7RR3N3/7W+2DeDCfUlj+gxw26pTV3EUnU2B1TXEz01Ar07WPHmhHJSS5tgyo9kPUqm/YBFkJuDtfx0Kp3sL6IRYDddvGv/2L1X8r3I14PxgppkU9T4FGINdClOEwfwelmxx3kjxpnTsUHZ+ztx7o+blteSf/r+pT1RDaIap80JaTy6vHwJKECRSvtpyTKEYeVmBIaA3yXqRhfMdlp8bU20t2DXoDGXWPk0GXRGXkVHE6yj64gPe/eOOesAxzv0v/vr5w4poemJ+SGwP3RSbrbVtiusD4FC6+hFBH7hiNUhxww5euvbAfNOTq2XyxtjcNmKB5/O675xGihK1gBgrsPdJ4enwkhQNrUuQBHm5wIKGiaH7t7q+T8W9JAnk3FGGuSZPg9b7AnFDQ3graxZK9mtOxi0GvE7DHinH6qErd4noGjS/KSy1fnDkCEkeplOQmvxb4w7wLMR5pePFc77NBXiR3RJDKh4QKskcvXPx58OWNffTkS2QwYPYhraNNKbUfGFBNEA4KPNmw1jYlDE/1BhOebmONpZQMP/CdcCWL+CKyTdi1/289Ak4B0iSZZN+Yx+AONzPlcvBVi+bXeXtqoIt2zMFKkr/0YFQg= on: tags: true - repo: Perryvw/TypeScriptToLua + repo: TypeScriptToLua/TypeScriptToLua diff --git a/README.md b/README.md index 4e6eec1ac..1ae0d0a0d 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ @@ -15,9 +15,9 @@ A generic TypeScript to Lua transpiler. Write your code in TypeScript and publis Large projects written in lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good IDE support. This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. ## Documentation -More detailed documentation and info on writing declarations can be found [on the wiki](https://github.com/Perryvw/TypescriptToLua/wiki). +More detailed documentation and info on writing declarations can be found [on the wiki](https://github.com/TypeScriptToLua/TypescriptToLua/wiki). -Changelog can be found in [CHANGELOG.md](https://github.com/Perryvw/TypescriptToLua/blob/master/CHANGELOG.md) +Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CHANGELOG.md) ## Usage Guide @@ -51,7 +51,7 @@ Changelog can be found in [CHANGELOG.md](https://github.com/Perryvw/TypescriptTo ``` ## Contributing -All contributions are welcome, but please read our [contribution guidelines](https://github.com/Perryvw/TypescriptToLua/blob/master/CONTRIBUTING.md)! +All contributions are welcome, but please read our [contribution guidelines](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CONTRIBUTING.md)! ## Declarations The real power of this transpiler is usage together with good declarations for the Lua API provided. Some examples of Lua interface declarations can be found here: From 714854e29f66e9879abaf229f023d9f17b676f8d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 24 Feb 2019 20:30:36 +0100 Subject: [PATCH 007/764] Updated appveyor badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ae0d0a0d..b22f39992 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ TypeScriptToLua

Build status - Build status + Build status Coverage Chat with us! From 2a8846afb4b1421dff304b419b2db81af8ce5377 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 24 Feb 2019 16:01:36 -0700 Subject: [PATCH 008/764] enabled support for lua string instance methods (#449) --- src/LuaTransformer.ts | 29 +++++++++++++++++++++++++++++ test/unit/string.spec.ts | 11 +++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e752ac0f4..1fd4e46ff 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3513,6 +3513,35 @@ export class LuaTransformer { const firstParamPlusOne = this.expressionPlusOne(params[0]); return this.createStringCall("byte", node, caller, firstParamPlusOne); } + case "byte": + case "char": + case "dump": + case "find": + case "format": + case "gmatch": + case "gsub": + case "len": + case "lower": + case "match": + case "pack": + case "packsize": + case "rep": + case "reverse": + case "sub": + case "unpack": + case "upper": + // Allow lua's string instance methods + let stringVariable = this.transformExpression(expression.expression); + if (ts.isStringLiteral(expression.expression)) { + // "foo":method() needs to be ("foo"):method() + stringVariable = tstl.createParenthesizedExpression(stringVariable); + } + return tstl.createMethodCallExpression( + stringVariable, + this.transformIdentifier(expression.name), + params, + node + ); default: throw TSTLErrors.UnsupportedProperty("string", expressionName, node); } diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index b3326ec78..d82fb0b9c 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -14,6 +14,17 @@ export class StringTests }).toThrowError(TranspileError, "Unsupported property on string: testThisIsNoMember"); } + @Test("Suported lua string function") + public stringSuportedLuaFunction(): void { + Expect(util.transpileAndExecute( + `return "test".upper()`, + undefined, + undefined, + `interface String { upper(): string; }` + ) + ).toBe("TEST"); + } + @TestCase([]) @TestCase([65]) @TestCase([65, 66]) From d8a1898dda3ff12cc528c068e809df641d20615c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 25 Feb 2019 15:56:30 -0700 Subject: [PATCH 009/764] implemented more math function and value conversions (#450) * implemented more math function and value conversions, fixing round in the process * math constants: added original node and tests --- src/LuaTransformer.ts | 125 ++++++++++++++++++++++++++++++----------- test/unit/math.spec.ts | 19 +++++++ 2 files changed, 112 insertions(+), 32 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 1fd4e46ff..7676bf2ff 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3123,11 +3123,7 @@ export class LuaTransformer { const ownerType = this.checker.getTypeAtLocation(node.expression.expression); if (ownerType.symbol && ownerType.symbol.escapedName === "Math") { - return tstl.createCallExpression( - this.transformMathExpression(node.expression.name), - this.transformArguments(node.arguments), - node - ); + return this.transformMathCallExpression(node); } if (ownerType.symbol && ownerType.symbol.escapedName === "StringConstructor") { @@ -3320,34 +3316,99 @@ export class LuaTransformer { } // Transpile a Math._ property - public transformMathExpression(identifier: ts.Identifier): tstl.TableIndexExpression { - const translation = { - PI: "pi", - abs: "abs", - acos: "acos", - asin: "asin", - atan: "atan", - ceil: "ceil", - cos: "cos", - exp: "exp", - floor: "floor", - log: "log", - max: "max", - min: "min", - pow: "pow", - random: "random", - round: "round", - sin: "sin", - sqrt: "sqrt", - tan: "tan", - }; + public transformMathExpression(identifier: ts.Identifier): tstl.Expression { + const name = identifier.escapedText as string; + switch (name) { + case "PI": + const property = tstl.createStringLiteral("pi"); + const math = tstl.createIdentifier("math"); + return tstl.createTableIndexExpression(math, property, identifier); + + case "E": + case "LN10": + case "LN2": + case "LOG10E": + case "LOG2E": + case "SQRT1_2": + case "SQRT2": + return tstl.createNumericLiteral(Math[name], identifier); - if (translation[identifier.escapedText as string]) { - const property = tstl.createStringLiteral(translation[identifier.escapedText as string]); - const math = tstl.createIdentifier("math"); - return tstl.createTableIndexExpression(math, property, identifier); - } else { - throw TSTLErrors.UnsupportedProperty("math", identifier.escapedText as string, identifier); + default: + throw TSTLErrors.UnsupportedProperty("math", name, identifier); + } + } + + // Transpile a Math._ property + public transformMathCallExpression(node: ts.CallExpression): tstl.Expression { + const expression = node.expression as ts.PropertyAccessExpression; + const params = this.transformArguments(node.arguments); + const expressionName = expression.name.escapedText as string; + switch (expressionName) { + // math.tan(x / y) + case "atan2": + { + const math = tstl.createIdentifier("math"); + const atan = tstl.createStringLiteral("atan"); + const div = tstl.createBinaryExpression(params[0], params[1], tstl.SyntaxKind.DivisionOperator); + return tstl.createCallExpression(tstl.createTableIndexExpression(math, atan), [div], node); + } + + // (math.log(x) / Math.LNe) + case "log10": + case "log2": + { + const math = tstl.createIdentifier("math"); + const log1 = tstl.createTableIndexExpression(math, tstl.createStringLiteral("log")); + const logCall1 = tstl.createCallExpression(log1, params); + const e = tstl.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); + const div = tstl.createBinaryExpression(logCall1, e, tstl.SyntaxKind.DivisionOperator); + return tstl.createParenthesizedExpression(div, node); + } + + // math.log(1 + x) + case "log1p": + { + const math = tstl.createIdentifier("math"); + const log = tstl.createStringLiteral("log"); + const one = tstl.createNumericLiteral(1); + const add = tstl.createBinaryExpression(one, params[0], tstl.SyntaxKind.AdditionOperator); + return tstl.createCallExpression(tstl.createTableIndexExpression(math, log), [add], node); + } + + // math.floor(x + 0.5) + case "round": + { + const math = tstl.createIdentifier("math"); + const floor = tstl.createStringLiteral("floor"); + const half = tstl.createNumericLiteral(0.5); + const add = tstl.createBinaryExpression(params[0], half, tstl.SyntaxKind.AdditionOperator); + return tstl.createCallExpression(tstl.createTableIndexExpression(math, floor), [add], node); + } + + case "abs": + case "acos": + case "asin": + case "atan": + case "ceil": + case "cos": + case "exp": + case "floor": + case "log": + case "max": + case "min": + case "pow": + case "random": + case "sin": + case "sqrt": + case "tan": + { + const math = tstl.createIdentifier("math"); + const method = tstl.createStringLiteral(expressionName); + return tstl.createCallExpression(tstl.createTableIndexExpression(math, method), params, node); + } + + default: + throw TSTLErrors.UnsupportedProperty("math", name, expression); } } diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index ad7a37169..24652e07f 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -8,6 +8,11 @@ export class MathTests { @TestCase("Math.cos()", "math.cos();") @TestCase("Math.sin()", "math.sin();") @TestCase("Math.min()", "math.min();") + @TestCase("Math.atan2(2, 3)", "math.atan(2 / 3);") + @TestCase("Math.log2(3)", `(math.log(3) / ${Math.LN2});`) + @TestCase("Math.log10(3)", `(math.log(3) / ${Math.LN10});`) + @TestCase("Math.log1p(3)", "math.log(1 + 3);") + @TestCase("Math.round(3.3)", "math.floor(3.3 + 0.5);") @TestCase("Math.PI", "math.pi;") @Test("Math") public math(inp: string, expected: string): void { @@ -18,6 +23,20 @@ export class MathTests { Expect(lua).toBe(expected); } + @TestCase("E") + @TestCase("LN10") + @TestCase("LN2") + @TestCase("LOG10E") + @TestCase("LOG2E") + @TestCase("SQRT1_2") + @TestCase("SQRT2") + @Test("Math constant") + public mathConstant(constant: string): void { + const epsilon = 0.000001; + const code = `return Math.abs(Math.${constant} - ${Math[constant]}) <= ${epsilon}`; + Expect(util.transpileAndExecute(code)).toBe(true); + } + @TestCase("++x", "x=4;y=6") @TestCase("x++", "x=4;y=6") @TestCase("--x", "x=2;y=6") From 777d62c649d5c71420b835ab27132067b1b7eecc Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 26 Feb 2019 05:55:24 -0700 Subject: [PATCH 010/764] Destructuring nothing fix (#453) * fixes for empty destructuring * cleanup * union destructuring test * removing duplicate test --- src/LuaTransformer.ts | 25 +++++++++++++++++------ test/unit/assignmentDestructuring.spec.ts | 23 +++++++++++++++++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7676bf2ff..7d7420ca6 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1673,7 +1673,9 @@ export class LuaTransformer { throw TSTLErrors.ForbiddenEllipsisDestruction(statement); } - const vars = statement.name.elements.map(e => this.transformArrayBindingElement(e)); + const vars = statement.name.elements.length > 0 + ? statement.name.elements.map(e => this.transformArrayBindingElement(e)) + : tstl.createAnnonymousIdentifier(statement.name); // Don't unpack TupleReturn decorated functions if (statement.initializer) { @@ -2448,10 +2450,14 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment - const left = expression.left.elements.map(e => this.transformExpression(e)); + const left = expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.map(e => this.transformExpression(e)); + right = expression.right.elements.length > 0 + ? expression.right.elements.map(e => this.transformExpression(e)) + : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = [this.transformExpression(expression.right)]; } else { @@ -2479,16 +2485,20 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() - const left = expression.left.elements.map(e => this.transformExpression(e)); + const left = expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.map(e => this.transformExpression(e)); + right = expression.right.elements.length > 0 + ? expression.right.elements.map(e => this.transformExpression(e)) + : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = [this.transformExpression(expression.right)]; } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } - const tmps = expression.left.elements.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); + const tmps = left.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); const statements: tstl.Statement[] = [ tstl.createVariableDeclarationStatement(tmps, right), tstl.createAssignmentStatement(left as tstl.IdentifierOrTableIndexExpression[], tmps), @@ -4191,6 +4201,9 @@ export class LuaTransformer { const fromTypeNode = this.checker.typeToTypeNode(fromType); const toTypeNode = this.checker.typeToTypeNode(toType); + if (!fromTypeNode || !toTypeNode) { + return; + } if ((ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode))) { diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 7f8e10507..e146dac39 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -37,4 +37,27 @@ export class AssignmentDestructuringTests { // Assert Expect(lua).toBe(`local a, b = unpack(myFunc());`); } + + @TestCase("function foo(): [] { return []; }; let [] = foo();") + @TestCase("let [] = ['a', 'b', 'c'];") + @TestCase("let [] = [];") + @TestCase("let [] = [] = [];") + @TestCase("function foo(): [] { return []; }; [] = foo();") + @TestCase("[] = ['a', 'b', 'c'];") + @TestCase("[] = [];") + @TestCase("[] = [] = [];") + @Test("Empty destructuring") + public emptyDestructuring(code: string): void { + Expect(() => util.transpileAndExecute(code)).not.toThrow(); + } + + @Test("Union destructuring") + public unionDestructuring(): void { + const code = + `function foo(): [string] | [] { return ["bar"]; } + let x: string; + [x] = foo(); + return x;`; + Expect(util.transpileAndExecute(code)).toBe("bar"); + } } From 10002b59e8e361d5c738c13e97610b0271f85467 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 27 Feb 2019 00:22:45 +0500 Subject: [PATCH 011/764] Fix array.sort compare function not working (#458) * Fix array.sort compare function not working * Fix compare function not being passed * Change array.sort tests to compare with js results --- src/LuaTransformer.ts | 2 +- src/lualib/ArraySort.ts | 8 ++++++-- test/unit/lualib/lualib.spec.ts | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7d7420ca6..bbc7e59a1 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3715,7 +3715,7 @@ export class LuaTransformer { case "unshift": return this.transformLuaLibFunction(LuaLibFeature.ArrayUnshift, node, caller, ...params); case "sort": - return this.transformLuaLibFunction(LuaLibFeature.ArraySort, node, caller); + return this.transformLuaLibFunction(LuaLibFeature.ArraySort, node, caller, ...params); case "pop": return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("remove")), diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts index 18745695c..01229598d 100644 --- a/src/lualib/ArraySort.ts +++ b/src/lualib/ArraySort.ts @@ -1,7 +1,11 @@ declare namespace table { - function sort(arr: T[], compareFn?: (a: T, b: T) => number): void; + function sort(arr: T[], compareFn?: (a: T, b: T) => boolean): void; } function __TS__ArraySort(arr: T[], compareFn?: (a: T, b: T) => number): T[] { - table.sort(arr, compareFn); + if (compareFn !== undefined) { + table.sort(arr, (a, b) => compareFn(a, b) < 0); + } else { + table.sort(arr); + } return arr; } diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index be87d1084..f0f0a0257 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -352,6 +352,29 @@ export class LuaLibTests // Assert Expect(result).toBe(JSON.stringify(expected)); } + + @Test("array.sort with compare function") + @TestCase([1, 2, 3, 4, 5], "a - b", (a: number, b: number) => a - b) + @TestCase(["4", "5", "3", "2", "1"], "tonumber(a) - tonumber(b)", (a: string, b: string) => Number(a) - Number(b)) + @TestCase(["4", "5", "3", "2", "1"], "tonumber(b) - tonumber(a)", (a: string, b: string) => Number(b) - Number(a)) + public arraySortWithCompareFunction( + array: any[], + compareStr: string, + compareFn: (a: any, b: any) => number + ): void { + const result = util.transpileAndExecute( + `let testArray = ${JSON.stringify(array)}; + testArray.sort((a, b) => ${compareStr}); + return JSONStringify(testArray)`, + undefined, + undefined, + `declare function tonumber(e: any): number` + ); + + // Assert + Expect(result).toBe(JSON.stringify(array.sort(compareFn))); + } + @TestCase("true", "4", "5", 4) @TestCase("false", "4", "5", 5) @TestCase("3", "4", "5", 4) From 5bb7a0b0bf4fb3c84c6ea984e37912fba5c54801 Mon Sep 17 00:00:00 2001 From: Endel Dreyer Date: Tue, 26 Feb 2019 16:28:45 -0300 Subject: [PATCH 012/764] implement Array.prototype.findIndex. closes #456 (#457) * implement Array.prototype.findIndex. closes #456 * refactor findIndex method, add more test cases --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 2 ++ src/lualib/ArrayFindIndex.ts | 11 +++++++++++ test/unit/lualib/lualib.spec.ts | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 src/lualib/ArrayFindIndex.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 864d438f6..3db60196c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -6,6 +6,7 @@ export enum LuaLibFeature { ArrayEvery = "ArrayEvery", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", + ArrayFindIndex = "ArrayFindIndex", ArrayIndexOf = "ArrayIndexOf", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index bbc7e59a1..1f6123b3d 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3724,6 +3724,8 @@ export class LuaTransformer { ); case "forEach": return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, node, caller, ...params); + case "findIndex": + return this.transformLuaLibFunction(LuaLibFeature.ArrayFindIndex, node, caller, ...params); case "indexOf": return this.transformLuaLibFunction(LuaLibFeature.ArrayIndexOf, node, caller, ...params); case "map": diff --git a/src/lualib/ArrayFindIndex.ts b/src/lualib/ArrayFindIndex.ts new file mode 100644 index 000000000..b60190c09 --- /dev/null +++ b/src/lualib/ArrayFindIndex.ts @@ -0,0 +1,11 @@ +function __TS__ArrayFindIndex( + arr: T[], + callbackFn: (this: void, element: T, index?: number, array?: T[]) => boolean +): number { + for (let i = 0, len = arr.length; i < len; i++) { + if (callbackFn(arr[i], i, arr)) { + return i; + } + } + return -1; +} diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index f0f0a0257..bb5c7f51e 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -21,6 +21,39 @@ export class LuaLibTests Expect(result).toBe(JSON.stringify(expected)); } + @TestCase([], 3, -1) + @TestCase([0, 2, 4, 8], 10, -1) + @TestCase([0, 2, 4, 8], 8, 3) + @Test("array.findIndex[value]") + public findIndexByValue(inp: number[], searchEl: number, expected: number): void + { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index) => { + return elem === ${searchEl}; + }));` + ); + + // Assert + Expect(result).toBe(expected); + } + + @TestCase([0, 2, 4, 8], 3, 8) + @TestCase([0, 2, 4, 8], 1, 2) + @Test("array.findIndex[index]") + public findIndexByIndex(inp: number[], expected: number, value: number): void + { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index, arr) => { + return index === ${expected} && arr[${expected}] === ${value}; + }));` + ); + + // Assert + Expect(result).toBe(expected); + } + @TestCase([], "x => x") @TestCase([0, 1, 2, 3], "x => x") @TestCase([0, 1, 2, 3], "x => x*2") From daa904f3901b0d89c38bb1929d40cbd3c829dbdd Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 27 Feb 2019 23:10:25 +1000 Subject: [PATCH 013/764] Console function calls (#454) * Added console call expression translations * Added console translation tests * Fixed tests * Formatting and readability changes * Formatting change to stringFormatCall --- src/LuaTransformer.ts | 95 +++++++++++++++++++++++++++++++++++++++ test/unit/console.spec.ts | 48 ++++++++++++++++++++ 2 files changed, 143 insertions(+) create mode 100644 test/unit/console.spec.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 1f6123b3d..e83f98f7b 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3148,6 +3148,10 @@ export class LuaTransformer { return this.transformObjectCallExpression(node); } + if (ownerType.symbol && ownerType.symbol.escapedName === "Console") { + return this.transformConsoleCallExpression(node); + } + if (ownerType.symbol && ownerType.symbol.escapedName === "SymbolConstructor") { return this.transformSymbolCallExpression(node); } @@ -3676,6 +3680,97 @@ export class LuaTransformer { } } + public transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { + const method = expression.expression as ts.PropertyAccessExpression; + const methodName = method.name.escapedText; + + switch (methodName) { + case "log": + if (expression.arguments.length > 0 + && this.isStringFormatTemplate(expression.arguments[0])) { + // print(string.format([arguments])) + const stringFormatCall = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("string"), + tstl.createStringLiteral("format")), + this.transformArguments(expression.arguments) + ); + return tstl.createCallExpression( + tstl.createIdentifier("print"), + [stringFormatCall] + ); + } + // print([arguments]) + return tstl.createCallExpression( + tstl.createIdentifier("print"), + this.transformArguments(expression.arguments) + ); + case "assert": + const args = this.transformArguments(expression.arguments); + if (expression.arguments.length > 1 + && this.isStringFormatTemplate(expression.arguments[1])) { + // assert([condition], string.format([arguments])) + const stringFormatCall = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("string"), + tstl.createStringLiteral("format")), + args.slice(1) + ); + return tstl.createCallExpression( + tstl.createIdentifier("assert"), + [args[0], stringFormatCall] + ); + } + // assert() + return tstl.createCallExpression( + tstl.createIdentifier("assert"), + args + ); + case "trace": + if (expression.arguments.length > 0 + && this.isStringFormatTemplate(expression.arguments[0])) { + // print(debug.traceback(string.format([arguments]))) + const stringFormatCall = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("string"), + tstl.createStringLiteral("format")), + this.transformArguments(expression.arguments) + ); + const debugTracebackCall = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("debug"), + tstl.createStringLiteral("traceback")), + [stringFormatCall] + ); + return tstl.createCallExpression( + tstl.createIdentifier("print"), + [debugTracebackCall] + ); + } + // print(debug.traceback([arguments]))) + const debugTracebackCall = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("debug"), + tstl.createStringLiteral("traceback")), + this.transformArguments(expression.arguments) + ); + return tstl.createCallExpression( + tstl.createIdentifier("print"), + [debugTracebackCall] + ); + default: + throw TSTLErrors.UnsupportedForTarget( + `console property ${methodName}`, + this.options.luaTarget, + expression + ); + } + } + + private isStringFormatTemplate(expression: ts.Expression): boolean { + return ts.isStringLiteral(expression) && expression.text.match(/\%/g) !== null; + } + // Transpile a Symbol._ property public transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts new file mode 100644 index 000000000..b7d0a689e --- /dev/null +++ b/test/unit/console.spec.ts @@ -0,0 +1,48 @@ +import { Expect, Test, TestCase, IgnoreTest, FocusTest } from "alsatian"; +import * as util from "../src/util"; + +export class ConsoleTests { + + @TestCase("console.log()", "print();") + @TestCase('console.log("Hello")', 'print("Hello");') + @TestCase('console.log("Hello %s", "there")', 'print(string.format("Hello %s", "there"));') + @TestCase('console.log("Hello %%s", "there")', 'print(string.format("Hello %%s", "there"));') + @TestCase('console.log("Hello", "There")', 'print("Hello", "There");') + @Test("console.log") + public testConsoleLog(inp: string, expected: string): void { + // Transpile + const lua = util.transpileString(inp); + + // Assert + Expect(lua).toBe(expected); + } + + @TestCase("console.trace()", "print(debug.traceback());") + @TestCase('console.trace("message")', 'print(debug.traceback("message"));') + @TestCase('console.trace("Hello %s", "there")', 'print(debug.traceback(string.format("Hello %s", "there")));') + @TestCase('console.trace("Hello %%s", "there")', 'print(debug.traceback(string.format("Hello %%s", "there")));') + @TestCase('console.trace("Hello", "there")', 'print(debug.traceback("Hello", "there"));') + @Test("console.trace") + public testConsoleTrace(inp: string, expected: string): void { + // Transpile + const lua = util.transpileString(inp); + + // Assert + Expect(lua).toBe(expected); + } + + @TestCase("console.assert(false)", "assert(false);") + @TestCase('console.assert(false, "message")', 'assert(false, "message");') + @TestCase('console.assert(false, "message %s", "info")', 'assert(false, string.format("message %s", "info"));') + @TestCase('console.assert(false, "message %%s", "info")', 'assert(false, string.format("message %%s", "info"));') + @TestCase('console.assert(false, "message", "more")', 'assert(false, "message", "more");') + @Test("console.assert") + public testConsoleAssert(inp: string, expected: string): void { + // Transpile + const lua = util.transpileString(inp); + + // Assert + Expect(lua).toBe(expected); + } + +} \ No newline at end of file From 48e7f06a8339daa7150791d62a4519f3afbf15a0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 1 Mar 2019 23:26:30 +0100 Subject: [PATCH 014/764] Updated CI badges to reflect master branch only --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b22f39992..61009e43a 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@

TypeScriptToLua

- Build status - Build status + Build status + Build status Coverage Chat with us!

From 210449e29cbe48cdf8299559df843fbb3939e701 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 3 Mar 2019 02:21:24 +0500 Subject: [PATCH 015/764] Fix call expression transform with undefined signature (#464) * Fix call expression transform with undefined signature * Use variable for signatureDeclaration --- src/LuaTransformer.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e83f98f7b..f0c946812 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3100,7 +3100,7 @@ export class LuaTransformer { } const callPath = this.transformExpression(node.expression); - const signatureDeclaration = signature.getDeclaration(); + const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration && !ts.isPropertyAccessExpression(node.expression) && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.NonVoid @@ -3201,7 +3201,7 @@ export class LuaTransformer { } else { const parameters = this.transformArguments(node.arguments, signature); const table = this.transformExpression(node.expression.expression); - const signatureDeclaration = signature.getDeclaration(); + const signatureDeclaration = signature && signature.getDeclaration(); if (!signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { @@ -3229,7 +3229,7 @@ export class LuaTransformer { const signature = this.checker.getResolvedSignature(node); let parameters = this.transformArguments(node.arguments, signature); - const signatureDeclaration = signature.getDeclaration(); + const signatureDeclaration = signature && signature.getDeclaration(); if (!signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { // Pass left-side as context From dedee12f03883a798801974deec4ab8d259d75a4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 4 Mar 2019 09:09:35 +0100 Subject: [PATCH 016/764] Added luaOptions tsconfig object, fixed boolean parsing bug (#463) * Added luaOptions tsconfig object, fixed boolean parsing bug * Added missing quotes * Fixed mistake reading tsconfig file * Renamed tsconfig object and removed deprectation warning message for now * Adjusted tests I forgot * Really fixed all the stuff I forgot this time --- src/CommandLineParser.ts | 70 ++++++++++++++++++++++------- test/unit/commandLineParser.spec.ts | 18 +++++++- 2 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index 4881adc4d..2286bfae8 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -157,19 +157,55 @@ function readTsConfig(parsedCommandLine: ts.ParsedCommandLine): CLIParseResult } const configPath = options.project; - const configContents = fs.readFileSync(configPath).toString(); - const configJson = ts.parseConfigFileTextToJson(configPath, configContents); - const parsedJsonConfig = ts.parseJsonConfigFileContent( - configJson.config, - ts.sys, - path.dirname(configPath), - options - ); - - for (const key in parsedJsonConfig.raw) { + const parsedJsonConfig = parseTsConfigFile(configPath, options); + + return parsedJsonConfig; + } + return { isValid: true, result: parsedCommandLine }; +} + +export function parseTsConfigFile(filePath: string, existingOptions?: ts.CompilerOptions): CLIParseResult { + const configContents = fs.readFileSync(filePath).toString(); + return parseTsConfigString(configContents, filePath, existingOptions); +} + +export function parseTsConfigString( + tsConfigString: string, + configPath: string, + existingOptions?: ts.CompilerOptions +): CLIParseResult { + const configJson = ts.parseConfigFileTextToJson(configPath, tsConfigString); + const parsedJsonConfig = ts.parseJsonConfigFileContent( + configJson.config, + ts.sys, + path.dirname(configPath), + existingOptions + ); + + for (const key in parsedJsonConfig.raw) { + const option = optionDeclarations[key]; + if (option !== undefined) { + const value = readValue(parsedJsonConfig.raw[key], option.type, key); + if (option.choices) { + if (option.choices.indexOf(value) < 0) { + return { + isValid: false, + errorMessage: `Unknown ${key} value '${value}'.\nAccepted values: ${option.choices}`, + }; + } + } + // console.warn(`[Deprectated] TSTL options are moving to the luaConfig object. Adjust your tsconfig to ` + // + `look like { "compilerOptions": { }, "tstl": { } }`); + parsedJsonConfig.options[key] = value; + } + } + + // Eventually we will only look for the tstl object for tstl options + if (parsedJsonConfig.raw.tstl) { + for (const key in parsedJsonConfig.raw.tstl) { const option = optionDeclarations[key]; if (option !== undefined) { - const value = readValue(parsedJsonConfig.raw[key], option.type, key); + const value = readValue(parsedJsonConfig.raw.tstl[key], option.type, key); if (option.choices) { if (option.choices.indexOf(value) < 0) { return { @@ -182,9 +218,9 @@ function readTsConfig(parsedCommandLine: ts.ParsedCommandLine): CLIParseResult parsedJsonConfig.options[key] = value; } } - return { isValid: true, result: parsedJsonConfig }; } - return { isValid: true, result: parsedCommandLine }; + + return { isValid: true, result: parsedJsonConfig }; } function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult { @@ -270,15 +306,15 @@ function getArgumentValue( return { isValid: true, result: value }; } -function readValue(valueString: string, valueType: string, parameterName: string): string | boolean { +function readValue(value: string | boolean, valueType: string, parameterName: string): string | boolean { if (valueType === "boolean") { - return valueString === "true" || valueString === "t" + return value === true || value === "true" || value === "t" ? true : false; } else if (valueType === "enum") { - return valueString.toLowerCase(); + return value.toString().toLowerCase(); } else { - return valueString; + return value; } } diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts index ab20b33d2..000cdd4b3 100644 --- a/test/unit/commandLineParser.spec.ts +++ b/test/unit/commandLineParser.spec.ts @@ -1,6 +1,6 @@ import { Expect, Test, TestCase } from "alsatian"; -import { findConfigFile, parseCommandLine } from "../../src/CommandLineParser"; +import { findConfigFile, parseCommandLine, parseTsConfigString } from "../../src/CommandLineParser"; import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; export class CommandLineParserTests @@ -226,4 +226,20 @@ export class CommandLineParserTests const result = findConfigFile({ options: {}, fileNames: [], errors: [] }); Expect(result.isValid).toBe(false); } + + @TestCase("{}", undefined) + @TestCase(`{ noHeader: true }`, true) + @TestCase(`{ noHeader: "true" }`, true) + @TestCase(`{ tstl: { noHeader: true } }`, true) + @TestCase(`{ tstl: { noHeader: "true" } }`, true) + @Test("TsConfig noHeader") + public tsConfigNoHeader(tsConfig: string, expected: boolean): void { + const result = parseTsConfigString(tsConfig, ""); + + if (result.isValid) { + Expect(result.result.options.noHeader).toBe(expected); + } else { + Expect(result.isValid).toBeTruthy(); + } + } } From 7b9ecbb71f07c8cd001b2684a32e1452d7d610a4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 5 Mar 2019 13:58:53 -0700 Subject: [PATCH 017/764] Fixed crash related to function expression type inference (#467) * fixed crash when inferring function expression type in specific situation this occurred when a function expression was assigned to property in an object literal that itself was assigned to a type that didn't actually contain that property: let foo: {} = {bar: s => s}; * added test --- src/TSHelper.ts | 5 ++++- test/unit/assignments.spec.ts | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index a6ec285ef..e1bb18757 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -484,7 +484,10 @@ export class TSHelper { const objType = this.inferAssignedType(expression.parent.parent, checker); const property = objType.getProperty(expression.parent.name.getText()); if (!property) { - return objType.getStringIndexType(); + const stringPropertyType = objType.getStringIndexType(); + if (stringPropertyType) { + return stringPropertyType; + } } else { return checker.getTypeAtLocation(property.valueDeclaration); } diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index dda85cc20..3f087b44b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -875,6 +875,14 @@ export class AssignmentTests { Expect(util.transpileAndExecute(code)).toBe("foobar"); } + @Test("Function expression type inference in object literal assigned to narrower type") + public functionEXpressionTypeInferenceInObjectLiteralAssignedToNarrowerType(): void { + const code = + `let foo: {} = {bar: s => s}; + return (foo as {bar: (a: any) => any}).bar("foobar");`; + Expect(util.transpileAndExecute(code)).toBe("foobar"); + } + @TestCase("const foo: Foo", "s => s") @TestCase("const foo: Foo", "(s => s)") @TestCase("const foo: Foo", "function(s) { return s; }") From 52d04f9c9e6bcd21b3919d071a74de4571c8a298 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Wed, 6 Mar 2019 19:57:45 +0100 Subject: [PATCH 018/764] check origin for standard library types (#468) * detect global console * added test * actually check if type is a DOM declaration * refactor helper methods * check standard library type origins * revert for constructors * check constructors again and assume lib for no valueDeclaration * make program protected --- src/LuaTransformer.ts | 27 ++++++++++++++++----------- src/TSHelper.ts | 16 +++++++++++++++- test/unit/console.spec.ts | 21 ++++++++++++++++++++- 3 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index f0c946812..78c371017 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -47,6 +47,8 @@ export class LuaTransformer { private checker: ts.TypeChecker; protected options: CompilerOptions; + protected program: ts.Program; + private isModule: boolean; private currentSourceFile?: ts.SourceFile; @@ -68,6 +70,7 @@ export class LuaTransformer { public constructor(program: ts.Program, options: CompilerOptions) { this.checker = program.getTypeChecker(); this.options = options; + this.program = program; this.isStrict = this.options.alwaysStrict || (this.options.strict && this.options.alwaysStrict !== false) || (this.isModule && this.options.target && this.options.target >= ts.ScriptTarget.ES2015); @@ -3113,7 +3116,7 @@ export class LuaTransformer { } const expressionType = this.checker.getTypeAtLocation(node.expression); - if (expressionType.symbol && expressionType.symbol.escapedName === "SymbolConstructor") { + if (tsHelper.isStandardLibraryType(expressionType, "SymbolConstructor", this.program)) { return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); } @@ -3132,11 +3135,15 @@ export class LuaTransformer { // If the function being called is of type owner.func, get the type of owner const ownerType = this.checker.getTypeAtLocation(node.expression.expression); - if (ownerType.symbol && ownerType.symbol.escapedName === "Math") { + if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { return this.transformMathCallExpression(node); } - if (ownerType.symbol && ownerType.symbol.escapedName === "StringConstructor") { + if (tsHelper.isStandardLibraryType(ownerType, "Console", this.program)) { + return this.transformConsoleCallExpression(node); + } + + if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) { return tstl.createCallExpression( this.transformStringExpression(node.expression.name), this.transformArguments(node.arguments), @@ -3144,15 +3151,11 @@ export class LuaTransformer { ); } - if (ownerType.symbol && ownerType.symbol.escapedName === "ObjectConstructor") { + if (tsHelper.isStandardLibraryType(ownerType, "ObjectConstructor", this.program)) { return this.transformObjectCallExpression(node); } - if (ownerType.symbol && ownerType.symbol.escapedName === "Console") { - return this.transformConsoleCallExpression(node); - } - - if (ownerType.symbol && ownerType.symbol.escapedName === "SymbolConstructor") { + if (tsHelper.isStandardLibraryType(ownerType, "SymbolConstructor", this.program)) { return this.transformSymbolCallExpression(node); } @@ -3317,9 +3320,11 @@ export class LuaTransformer { // Catch math expressions if (ts.isIdentifier(node.expression)) { - if (node.expression.escapedText === "Math") { + const ownerType = this.checker.getTypeAtLocation(node.expression); + + if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { return this.transformMathExpression(node.name); - } else if (node.expression.escapedText === "Symbol") { + } else if (tsHelper.isStandardLibraryType(ownerType, "Symbol", this.program)) { // Pull in Symbol lib this.importLuaLibFeature(LuaLibFeature.Symbol); } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index e1bb18757..aa12a6fbb 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -297,7 +297,7 @@ export class TSHelper { return node.parent === undefined || ts.isExpressionStatement(node.parent) || ts.isForStatement(node.parent); } - public static isInGlobalScope(node: ts.FunctionDeclaration): boolean { + public static isInGlobalScope(node: ts.Node): boolean { let parent = node.parent; while (parent !== undefined) { if (ts.isBlock(parent)) { @@ -687,6 +687,20 @@ export class TSHelper { return firstDeclaration === node; } + public static isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean { + const source = declaration.getSourceFile(); + if (!source) { return false; } + return program.isSourceFileDefaultLibrary(source); + } + + public static isStandardLibraryType(type: ts.Type, name: string, program: ts.Program): boolean { + const symbol = type.symbol; + if (!symbol || symbol.escapedName !== name) { return false; } + const declaration = symbol.valueDeclaration; + if(!declaration) { return true; } // assume to be lib function if no valueDeclaration exists + return this.isStandardLibraryDeclaration(declaration, program); + } + public static isEnumMember(enumDeclaration: ts.EnumDeclaration, value: ts.Expression): [boolean, ts.PropertyName] { if (ts.isIdentifier(value)) { const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text); diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts index b7d0a689e..2bd1e5fab 100644 --- a/test/unit/console.spec.ts +++ b/test/unit/console.spec.ts @@ -1,4 +1,4 @@ -import { Expect, Test, TestCase, IgnoreTest, FocusTest } from "alsatian"; +import { Expect, Test, TestCase } from "alsatian"; import * as util from "../src/util"; export class ConsoleTests { @@ -45,4 +45,23 @@ export class ConsoleTests { Expect(lua).toBe(expected); } + @Test("console.differentiation") + public testConsoleDifferentiation(): void { + // Transpile + const result = util.transpileExecuteAndReturnExport(` + export class Console { + test() { return 42; } + } + + function test() { + const console = new Console(); + return console.test(); + } + + export const result = test(); + `, "result"); + Expect(result).toBe(42); + } + + } \ No newline at end of file From a30beba4f73a7142a96285802291c320a3ccb870 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 9 Mar 2019 09:58:18 -0700 Subject: [PATCH 019/764] Function inference fixes (#469) * fixed function expression inference when assigning to tuples as casts * removed FocusTest * added fix for inference in constructors --- src/TSHelper.ts | 15 +++++++-- test/unit/assignments.spec.ts | 62 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index aa12a6fbb..0b3c8422e 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -436,7 +436,7 @@ export class TSHelper { // Ignore expressions wrapped in parenthesis return this.inferAssignedType(expression.parent, checker); - } else if (ts.isCallExpression(expression.parent)) { + } else if (ts.isCallOrNewExpression(expression.parent)) { // Expression being passed as argument to a function const argumentIndex = expression.parent.arguments.indexOf(expression); if (argumentIndex >= 0) { @@ -514,11 +514,22 @@ export class TSHelper { { // Expression assigned to variable return checker.getTypeAtLocation(expression.parent.left); + + } else if (ts.isAssertionExpression(expression.parent)) { + // Expression being cast + return checker.getTypeFromTypeNode(expression.parent.type); } return checker.getTypeAtLocation(expression); } + public static getAllCallSignatures(type: ts.Type): ReadonlyArray { + if (type.isUnion()) { + return type.types.map(t => TSHelper.getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); + } + return type.getCallSignatures(); + } + public static getSignatureDeclarations( signatures: ReadonlyArray, checker: ts.TypeChecker @@ -533,7 +544,7 @@ export class TSHelper { // Infer type of function expressions/arrow functions const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); if (inferredType) { - const inferredSignatures = inferredType.getCallSignatures(); + const inferredSignatures = TSHelper.getAllCallSignatures(inferredType); if (inferredSignatures.length > 0) { signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration())); continue; diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 3f087b44b..ecf1421f4 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -973,6 +973,68 @@ export class AssignmentTests { Expect(util.transpileAndExecute(code)).toBe("foo"); } + @TestCase("(this: void, s: string) => string", "s => s") + @TestCase("(this: any, s: string) => string", "s => s") + @TestCase("(s: string) => string", "s => s") + @TestCase("(this: void, s: string) => string", "function(s) { return s; }") + @TestCase("(this: any, s: string) => string", "function(s) { return s; }") + @TestCase("(s: string) => string", "function(s) { return s; }") + @Test("Function expression type inference in union") + public functionExpressionTypeInferenceInUnion(funcType: string, funcExp: string): void { + const code = + `type U = string | number | (${funcType}); + const u: U = ${funcExp}; + return (u as ${funcType})("foo");`; + Expect(util.transpileAndExecute(code)).toBe("foo"); + } + + @TestCase("(this: void, s: string) => string", "s => s") + @TestCase("(this: any, s: string) => string", "s => s") + @TestCase("(s: string) => string", "s => s") + @TestCase("(this: void, s: string) => string", "function(s) { return s; }") + @TestCase("(this: any, s: string) => string", "function(s) { return s; }") + @TestCase("(s: string) => string", "function(s) { return s; }") + @Test("Function expression type inference in as cast") + public functionExpressionTypeInferenceInAsCast(funcType: string, funcExp: string): void { + const code = + `const fn: ${funcType} = (${funcExp}) as (${funcType}); + return fn("foo");`; + console.log(code); + Expect(util.transpileAndExecute(code)).toBe("foo"); + } + + @TestCase("(this: void, s: string) => string", "s => s") + @TestCase("(this: any, s: string) => string", "s => s") + @TestCase("(s: string) => string", "s => s") + @TestCase("(this: void, s: string) => string", "function(s) { return s; }") + @TestCase("(this: any, s: string) => string", "function(s) { return s; }") + @TestCase("(s: string) => string", "function(s) { return s; }") + @Test("Function expression type inference in type assertion") + public functionExpressionTypeInferenceInTypeAssert(funcType: string, funcExp: string): void { + const code = + `const fn: ${funcType} = <${funcType}>(${funcExp}); + return fn("foo");`; + Expect(util.transpileAndExecute(code)).toBe("foo"); + } + + @TestCase("(this: void, s: string) => string", "s => s") + @TestCase("(this: any, s: string) => string", "s => s") + @TestCase("(s: string) => string", "s => s") + @TestCase("(this: void, s: string) => string", "function(s) { return s; }") + @TestCase("(this: any, s: string) => string", "function(s) { return s; }") + @TestCase("(s: string) => string", "function(s) { return s; }") + @Test("Function expression type inference in constructor") + public functionExpresssionTypeInferenceInConstructor(funcType: string, funcExp: string): void { + const code = + `class C { + result: string; + constructor(fn: (s: string) => string) { this.result = fn("foo"); } + } + const c = new C(s => s); + return c.result;`; + Expect(util.transpileAndExecute(code)).toBe("foo"); + } + @Test("String table access") public stringTableAccess(assignType: string): void { const code = `const dict : {[key:string]:any} = {}; From 73b13b643c3be38d2cc5255347686bce769d8a1b Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 10 Mar 2019 12:04:32 -0600 Subject: [PATCH 020/764] fixed function expression inference in binary operators (#472) --- src/TSHelper.ts | 13 ++++++++----- test/unit/assignments.spec.ts | 13 +++++++++++++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 0b3c8422e..7c6e16a38 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -509,11 +509,14 @@ export class TSHelper { // Expression assigned to declaration return checker.getTypeAtLocation(expression.parent.name); - } else if (ts.isBinaryExpression(expression.parent) - && expression.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) - { - // Expression assigned to variable - return checker.getTypeAtLocation(expression.parent.left); + } else if (ts.isBinaryExpression(expression.parent)) { + if (expression.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + // Expression assigned to variable + return checker.getTypeAtLocation(expression.parent.left); + } else { + // Other binary expressions + return TSHelper.inferAssignedType(expression.parent, checker); + } } else if (ts.isAssertionExpression(expression.parent)) { // Expression being cast diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index ecf1421f4..8840018ed 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -837,6 +837,19 @@ export class AssignmentTests { + "Overloads should either be all functions or all methods, but not both."); } + @TestCase("(this: void, s: string) => string") + @TestCase("(this: any, s: string) => string") + @TestCase("(s: string) => string") + @Test("Function expression type inference in binary operator") + public functionExpressionTypeInferenceInBinaryOp(funcType: string): void { + const header = `declare const undefinedFunc: ${funcType};`; + const code = + `let func: ${funcType} = s => s; + func = undefinedFunc || (s => s); + return func("foo");`; + Expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + } + @TestCase("s => s") @TestCase("(s => s)") @TestCase("function(s) { return s; }") From 0bbae3c40566f842e6bf46feb554350559bb6f03 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 10 Mar 2019 12:49:18 -0600 Subject: [PATCH 021/764] moved static field initialization to end of class declaration (#473) --- src/LuaTransformer.ts | 36 ++++++++++++++++++------------------ test/unit/class.spec.ts | 11 +++++++++++ 2 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 78c371017..ac0e37dd3 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -494,24 +494,6 @@ export class LuaTransformer { } } - // Add static declarations - for (const field of staticFields) { - const fieldName = this.transformPropertyName(field.name); - const value = this.transformExpression(field.initializer); - - const classField = tstl.createTableIndexExpression( - this.addExportToIdentifier(tstl.cloneIdentifier(className)), - fieldName - ); - - const fieldAssign = tstl.createAssignmentStatement( - classField, - value - ); - - result.push(fieldAssign); - } - // Find first constructor with body if (!isExtension && !isMetaExtension) { const constructor = statement.members @@ -573,6 +555,24 @@ export class LuaTransformer { result.push(this.transformMethodDeclaration(method, className, isExtension || isMetaExtension)); }); + // Add static declarations + for (const field of staticFields) { + const fieldName = this.transformPropertyName(field.name); + const value = this.transformExpression(field.initializer); + + const classField = tstl.createTableIndexExpression( + this.addExportToIdentifier(tstl.cloneIdentifier(className)), + fieldName + ); + + const fieldAssign = tstl.createAssignmentStatement( + classField, + value + ); + + result.push(fieldAssign); + } + this.classStack.pop(); return result; diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 5592933e9..95e1e8fc4 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -805,4 +805,15 @@ export class ClassTests { "Cannot construct classes with decorator '@extension' or '@metaExtension'." ); } + + @Test("Class static instance of self") + public classStaticInstanceOfSelf(): void { + const code = + `class Foo { + bar = "foobar"; + static instance = new Foo(); + } + return Foo.instance.bar;`; + Expect(util.transpileAndExecute(code)).toBe("foobar"); + } } From d870f00098cde2e3e6df681851cc82c0f5edecdb Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 10 Mar 2019 13:18:48 -0600 Subject: [PATCH 022/764] fixed transforming undefined as a property name (#474) --- src/LuaTransformer.ts | 27 ++++++++++++++++----------- test/unit/objectLiteral.spec.ts | 8 ++++++++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ac0e37dd3..802f385a0 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3978,19 +3978,12 @@ export class LuaTransformer { const value = Number(propertyName.text); return tstl.createNumericLiteral(value, propertyName); } else { - return tstl.createStringLiteral(this.transformIdentifier(propertyName).text); + return tstl.createStringLiteral(this.getIdentifierText(propertyName)); } } - public transformIdentifier(expression: ts.Identifier): tstl.Identifier { - if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { - return tstl.createIdentifier("nil"); // TODO this is a hack that allows use to keep Identifier - // as return time as changing that would break a lot of stuff. - // But this should be changed to retun tstl.createNilLiteral() - // at some point. - } - - let escapedText = expression.escapedText as string; + public getIdentifierText(identifier: ts.Identifier): string { + let escapedText = identifier.escapedText as string; const underScoreCharCode = "_".charCodeAt(0); if (escapedText.length >= 3 && escapedText.charCodeAt(0) === underScoreCharCode && escapedText.charCodeAt(1) === underScoreCharCode && escapedText.charCodeAt(2) === underScoreCharCode) { @@ -3998,9 +3991,21 @@ export class LuaTransformer { } if (this.luaKeywords.has(escapedText)) { - throw TSTLErrors.KeywordIdentifier(expression); + throw TSTLErrors.KeywordIdentifier(identifier); + } + + return escapedText; + } + + public transformIdentifier(expression: ts.Identifier): tstl.Identifier { + if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + return tstl.createIdentifier("nil"); // TODO this is a hack that allows use to keep Identifier + // as return time as changing that would break a lot of stuff. + // But this should be changed to retun tstl.createNilLiteral() + // at some point. } + const escapedText = this.getIdentifierText(expression); const symbolId = this.getIdentifierSymbolId(expression); return tstl.createIdentifier(escapedText, expression, symbolId); } diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index dd94ff419..2d50879ba 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -23,4 +23,12 @@ export class ObjectLiteralTests { const result = util.transpileAndExecute(`const x = ${input}; const o = {x}; return o.x;`); Expect(result).toBe(expected); } + + @Test("undefined as object key") + public undefinedAsObjectKey(): void { + const code = + `const foo = {undefined: "foo"}; + return foo.undefined;`; + Expect(util.transpileAndExecute(code)).toBe("foo"); + } } From badd012205db7f230fed6deaf7c5167cdec94c23 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 13 Mar 2019 14:33:20 -0600 Subject: [PATCH 023/764] @luaIterator on array types (#479) * enabling use of @luaIterator on Array types * removing focustest --- src/LuaTransformer.ts | 10 +++++----- test/unit/loops.spec.ts | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 802f385a0..2a46021e2 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2073,14 +2073,14 @@ export class LuaTransformer { // Transpile body const body = tstl.createBlock(this.transformLoopBody(statement)); - if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker)) { - // Arrays - return this.transformForOfArrayStatement(statement, body); - - } else if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { + if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { // LuaIterators return this.transformForOfLuaIteratorStatement(statement, body); + } else if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker)) { + // Arrays + return this.transformForOfArrayStatement(statement, body); + } else { // TS Iterables return this.transformForOfIteratorStatement(statement, body); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 8487e1510..153e243b2 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -542,6 +542,27 @@ export class LuaLoopTests Expect(result).toBe("abc"); } + @Test("forof array lua iterator") + public forofArrayLuaIterator(): void { + const code = `const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Array {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result;`; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + Expect(result).toBe("abc"); + } + @Test("forof lua iterator with existing variable") public forofLuaIteratorExistingVar(): void { const code = `const arr = ["a", "b", "c"]; From f9a225e49c2becc20f7e36de6c5a79d74ff9838f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Fri, 15 Mar 2019 02:17:59 +1000 Subject: [PATCH 024/764] No path resolution for ambient modules (#455) * Added special console translations * Added tests * Renamed to ConsoleTests * Imported modules are not resolved * Added module tests * Refactored to isAmbientModuleDeclaration * removed interfering tests * private to public * Fixed broken test * Moved isAmbientModuleDeclaration to tsHelper * Refactored to use resolveModule param * Added noResolution decorator * Used new decorator * Correction * Fixed test * Added param to StringCompilerProgram for multiple files * Updated noResolution tests * Merged extraFiles param with input * AAA consideration and updated transpileString --- src/Compiler.ts | 25 +++++++++++++++++++------ src/Decorator.ts | 3 +++ src/LuaTransformer.ts | 18 +++++++++++------- test/src/util.ts | 5 +++-- test/unit/require.spec.ts | 14 +++++++++++++- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/Compiler.ts b/src/Compiler.ts index ff0499cfa..6b382d200 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -89,7 +89,10 @@ const defaultCompilerOptions: CompilerOptions = { }; export function createStringCompilerProgram( - input: string, options: CompilerOptions = defaultCompilerOptions, filePath = "file.ts"): ts.Program { + input: string | { [filename: string]: string }, + options: CompilerOptions = defaultCompilerOptions, + filePath = "file.ts" +): ts.Program { const compilerHost = { directoryExists: () => true, fileExists: (fileName): boolean => true, @@ -100,8 +103,17 @@ export function createStringCompilerProgram( getNewLine: () => "\n", getSourceFile: (filename: string) => { - if (filename === filePath) { - return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false); + switch (typeof input) { + case "string": + if (filename === filePath) { + return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false); + } + break; + case "object": + if (filename in input) { + return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); + } + break; } if (filename.indexOf(".d.ts") !== -1) { if (!libCache[filename]) { @@ -125,16 +137,17 @@ export function createStringCompilerProgram( // Don't write output writeFile: (name, text, writeByteOrderMark) => undefined, }; - return ts.createProgram([filePath], options, compilerHost); + const filePaths = typeof input === "string" ? [filePath] : Object.keys(input); + return ts.createProgram(filePaths, options, compilerHost); } export function transpileString( - str: string, + input: string | { [filename: string]: string }, options: CompilerOptions = defaultCompilerOptions, ignoreDiagnostics = false, filePath = "file.ts" ): string { - const program = createStringCompilerProgram(str, options, filePath); + const program = createStringCompilerProgram(input, options, filePath); if (!ignoreDiagnostics) { const diagnostics = ts.getPreEmitDiagnostics(program); diff --git a/src/Decorator.ts b/src/Decorator.ts index bf113ee71..42b775841 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -13,6 +13,8 @@ export class Decorator { return DecoratorKind.CustomConstructor; case "compilemembersonly": return DecoratorKind.CompileMembersOnly; + case "noresolution": + return DecoratorKind.NoResolution; case "pureabstract": return DecoratorKind.PureAbstract; case "phantom": @@ -42,6 +44,7 @@ export enum DecoratorKind { MetaExtension = "MetaExtension", CustomConstructor = "CustomConstructor", CompileMembersOnly = "CompileMembersOnly", + NoResolution = "NoResolution", PureAbstract = "PureAbstract", Phantom = "Phantom", TupleReturn = "TupleReturn", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2a46021e2..0777aeef8 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -318,14 +318,17 @@ export class LuaTransformer { const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), ""); - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); - if (!statement.importClause) { + const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); result.push(tstl.createExpressionStatement(requireCall)); return result; } const imports = statement.importClause.namedBindings; + const type = this.checker.getTypeAtLocation(imports); + const shouldResolve = !tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.NoResolution); + const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); + if (ts.isNamedImports(imports)) { const filteredElements = imports.elements.filter(e => { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); @@ -379,11 +382,12 @@ export class LuaTransformer { } } - private createModuleRequire(moduleSpecifier: ts.StringLiteral): tstl.CallExpression { - const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), ""); - const resolvedModuleSpecifier = tstl.createStringLiteral(this.getImportPath(importPath)); - - return tstl.createCallExpression(tstl.createIdentifier("require"), [resolvedModuleSpecifier]); + private createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { + const modulePathString = resolveModule + ? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), "")) + : moduleSpecifier.text; + const modulePath = tstl.createStringLiteral(modulePathString); + return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath]); } public transformClassDeclaration( diff --git a/test/src/util.ts b/test/src/util.ts index a27bcc851..a2da34bf4 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -12,10 +12,11 @@ import * as fs from "fs"; import { LuaTransformer } from "../../src/LuaTransformer"; export function transpileString( - str: string, + str: string | { [filename: string]: string }, options?: CompilerOptions, ignoreDiagnostics = true, - filePath = "file.ts"): string { + filePath = "file.ts" +): string { if (options) { if (options.noHeader === undefined) { options.noHeader = true; diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index 233237c5d..27c5a7432 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -23,14 +23,26 @@ export class RequireTests { expectedPath: string, options: CompilerOptions, throwsError: boolean): void { - const regex = /require\("(.*?)"\)/; // This regex extracts `hello` from require("hello") if (throwsError) { Expect(() => util.transpileString(`import * from "${usedPath}";`, options, true, filePath)).toThrow(); } else { const lua = util.transpileString(`import * from "${usedPath}";`, options, true, filePath); + const regex = /require\("(.*?)"\)/; const match = regex.exec(lua); Expect(match[1]).toBe(expectedPath); } } + @TestCase("", "src.fake") + @TestCase("/** @noResolution */", "fake") + @Test("noResolution on ambient modules causes no path alterations") + public testRequireModule(comment: string, expectedPath: string): void { + const lua = util.transpileString({ + "src/file.ts": `import * as fake from "fake";`, + "module.d.ts": `${comment} declare module "fake" {}`, + }, undefined, true, "src/file.ts"); + const regex = /require\("(.*?)"\)/; + Expect(regex.exec(lua)[1]).toBe(expectedPath); + } + } \ No newline at end of file From d9103e8328b9dbeb2cf3db77859732c70b2a6e01 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 15 Mar 2019 10:28:35 +0100 Subject: [PATCH 025/764] Feature/small bugfixes (#475) * Swapped arithmetic and logical bitwise right shift operators * Fixed bug where named class expressions would return ____ * Used tstl.createAnonymousIdentifier instead of manually creating them * Switched around bitwise right shift for 5.3 again and fixed failing test * Fixed issue with class names * Fixed shift bugs * Removed bitshiftright operator * Fixed issues with string concatenation detection * Fixed remaining tests * Fixed strange operator switch --- src/LuaAST.ts | 3 +- src/LuaPrinter.ts | 1 - src/LuaTransformer.ts | 220 +++++++++++++++++++--------------- src/TSHelper.ts | 26 ++-- test/unit/class.spec.ts | 16 +++ test/unit/expressions.spec.ts | 35 +++--- test/unit/math.spec.ts | 16 +-- tslint.json | 1 + 8 files changed, 180 insertions(+), 138 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index a973354ca..58534b996 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -70,7 +70,6 @@ export enum SyntaxKind { BitwiseOrOperator, BitwiseExclusiveOrOperator, BitwiseRightShiftOperator, - BitwiseArithmeticRightShift, BitwiseLeftShiftOperator, BitwiseNotOperator, // Unary } @@ -85,7 +84,7 @@ export type UnaryOperator = SyntaxKind.NegationOperator export type BinaryBitwiseOperator = SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator - | SyntaxKind.BitwiseArithmeticRightShift | SyntaxKind.BitwiseLeftShiftOperator; + | SyntaxKind.BitwiseLeftShiftOperator; export type BinaryOperator = SyntaxKind.AdditionOperator | SyntaxKind.SubractionOperator | SyntaxKind.MultiplicationOperator diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 0f509c593..d4d1beefb 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -31,7 +31,6 @@ export class LuaPrinter { [tstl.SyntaxKind.BitwiseOrOperator]: "|", [tstl.SyntaxKind.BitwiseExclusiveOrOperator]: "~", [tstl.SyntaxKind.BitwiseRightShiftOperator]: ">>", - [tstl.SyntaxKind.BitwiseArithmeticRightShift]: ">>>", [tstl.SyntaxKind.BitwiseLeftShiftOperator]: "<<", [tstl.SyntaxKind.BitwiseNotOperator]: "~", }; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 0777aeef8..fc31cb851 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -397,11 +397,14 @@ export class LuaTransformer { { this.classStack.push(statement); - let className = statement.name ? this.transformIdentifier(statement.name) : nameOverride; - if (!className) { + if (statement.name === undefined && nameOverride === undefined) { throw TSTLErrors.MissingClassName(statement); } + let className = nameOverride !== undefined + ? nameOverride + : this.transformIdentifier(statement.name); + const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); // Find out if this class is extension of existing class @@ -1746,8 +1749,8 @@ export class LuaTransformer { || expression.operator === ts.SyntaxKind.MinusMinusToken)) { // ++i, --i const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken - ? tstl.SyntaxKind.AdditionOperator - : tstl.SyntaxKind.SubractionOperator; + ? ts.SyntaxKind.PlusToken + : ts.SyntaxKind.MinusToken; return this.transformCompoundAssignmentStatement( expression, @@ -1760,8 +1763,8 @@ export class LuaTransformer { else if (ts.isPostfixUnaryExpression(expression)) { // i++, i-- const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken - ? tstl.SyntaxKind.AdditionOperator - : tstl.SyntaxKind.SubractionOperator; + ? ts.SyntaxKind.PlusToken + : ts.SyntaxKind.MinusToken; return this.transformCompoundAssignmentStatement( expression, @@ -2309,9 +2312,7 @@ export class LuaTransformer { case ts.SyntaxKind.NotEmittedStatement: return undefined; case ts.SyntaxKind.ClassExpression: - const className = tstl.createIdentifier("____"); - const classDeclaration = this.transformClassDeclaration(expression as ts.ClassExpression, className); - return this.createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); + return this.transformClassExpression(expression as ts.ClassExpression); case ts.SyntaxKind.PartiallyEmittedExpression: return this.transformExpression((expression as ts.PartiallyEmittedExpression).expression); default: @@ -2320,23 +2321,23 @@ export class LuaTransformer { } public transformBinaryOperation( - node: ts.Node, left: tstl.Expression, right: tstl.Expression, - operator: tstl.BinaryOperator + operator: ts.BinaryOperator, + tsOriginal: ts.Node ): tstl.Expression { switch (operator) { - case tstl.SyntaxKind.BitwiseAndOperator: - case tstl.SyntaxKind.BitwiseOrOperator: - case tstl.SyntaxKind.BitwiseExclusiveOrOperator: - case tstl.SyntaxKind.BitwiseLeftShiftOperator: - case tstl.SyntaxKind.BitwiseRightShiftOperator: - case tstl.SyntaxKind.BitwiseArithmeticRightShift: - return this.transformBinaryBitOperation(node, left, right, operator); - + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.CaretToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return this.transformBinaryBitOperation(tsOriginal, left, right, operator); default: - return tstl.createBinaryExpression(left, right, operator, node); + const luaOperator = this.transformBinaryOperator(operator, tsOriginal); + return tstl.createBinaryExpression(left, right, luaOperator, tsOriginal); } } @@ -2360,55 +2361,31 @@ export class LuaTransformer { // Transpile operators switch (expression.operatorToken.kind) { case ts.SyntaxKind.AmpersandToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseAndOperator); case ts.SyntaxKind.BarToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseOrOperator); case ts.SyntaxKind.CaretToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseExclusiveOrOperator); case ts.SyntaxKind.LessThanLessThanToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseLeftShiftOperator); case ts.SyntaxKind.GreaterThanGreaterThanToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseRightShiftOperator); case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.BitwiseArithmeticRightShift); + return this.transformBinaryBitOperation(expression, lhs, rhs, expression.operatorToken.kind); + case ts.SyntaxKind.PlusToken: case ts.SyntaxKind.AmpersandAmpersandToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.AndOperator); case ts.SyntaxKind.BarBarToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.OrOperator); - case ts.SyntaxKind.PlusToken: - // Replace string + with .. - const typeLeft = this.checker.getTypeAtLocation(expression.left); - const typeRight = this.checker.getTypeAtLocation(expression.right); - if (tsHelper.isStringType(typeLeft) || tsHelper.isStringType(typeRight)) { - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.ConcatOperator); - } - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.AdditionOperator); case ts.SyntaxKind.MinusToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.SubractionOperator); case ts.SyntaxKind.AsteriskToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.MultiplicationOperator); case ts.SyntaxKind.AsteriskAsteriskToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.PowerOperator); case ts.SyntaxKind.SlashToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.DivisionOperator); case ts.SyntaxKind.PercentToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.ModuloOperator); case ts.SyntaxKind.GreaterThanToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.GreaterThanOperator); case ts.SyntaxKind.GreaterThanEqualsToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.GreaterEqualOperator); case ts.SyntaxKind.LessThanToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.LessThanOperator); case ts.SyntaxKind.LessThanEqualsToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.LessEqualOperator); - case ts.SyntaxKind.EqualsToken: - return this.transformAssignmentExpression(expression); case ts.SyntaxKind.EqualsEqualsToken: case ts.SyntaxKind.EqualsEqualsEqualsToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.EqualityOperator); case ts.SyntaxKind.ExclamationEqualsToken: case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return this.transformBinaryOperation(expression, lhs, rhs, tstl.SyntaxKind.InequalityOperator); + return this.transformBinaryOperation(lhs, rhs, expression.operatorToken.kind, expression); + case ts.SyntaxKind.EqualsToken: + return this.transformAssignmentExpression(expression); case ts.SyntaxKind.InKeyword: const indexExpression = tstl.createTableIndexExpression(rhs, lhs); return tstl.createBinaryExpression( @@ -2566,19 +2543,10 @@ export class LuaTransformer { expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, - replacementOperator: tstl.BinaryOperator, + replacementOperator: ts.BinaryOperator, isPostfix: boolean ): tstl.CallExpression { - if (replacementOperator === tstl.SyntaxKind.AdditionOperator) { - // Check is we need to use string concat operator - const typeLeft = this.checker.getTypeAtLocation(lhs); - const typeRight = this.checker.getTypeAtLocation(rhs); - if (tsHelper.isStringType(typeLeft) || tsHelper.isStringType(typeRight)) { - replacementOperator = tstl.SyntaxKind.ConcatOperator; - } - } - const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; let right = this.transformExpression(rhs); @@ -2603,16 +2571,16 @@ export class LuaTransformer { // local ____TS_tmp = ____TS_obj[____TS_index]; // ____TS_obj[____TS_index] = ____TS_tmp ${replacementOperator} ${right}; tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, accessExpression); - const operatorExpression = this.transformBinaryOperation(expression, tmp, right, replacementOperator); + const operatorExpression = this.transformBinaryOperation(tmp, right, replacementOperator, expression); assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); } else { // local ____TS_tmp = ____TS_obj[____TS_index] ${replacementOperator} ${right}; // ____TS_obj[____TS_index] = ____TS_tmp; const operatorExpression = this.transformBinaryOperation( - expression, accessExpression, right, - replacementOperator + replacementOperator, + expression ); tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, operatorExpression); assignStatement = tstl.createAssignmentStatement(accessExpression, tmp); @@ -2621,7 +2589,7 @@ export class LuaTransformer { return this.createImmediatelyInvokedFunctionExpression( [objAndIndexDeclaration, tmpDeclaration, assignStatement], tmp, - lhs.parent + expression ); } else if (isPostfix) { @@ -2632,16 +2600,16 @@ export class LuaTransformer { const tmpIdentifier = tstl.createIdentifier("____TS_tmp"); const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, left); const operatorExpression = this.transformBinaryOperation( - expression, tmpIdentifier, right, - replacementOperator + replacementOperator, + expression ); const assignStatement = this.transformAssignment(lhs, operatorExpression); return this.createImmediatelyInvokedFunctionExpression( [tmpDeclaration, assignStatement], tmpIdentifier, - lhs.parent + expression ); } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { @@ -2650,40 +2618,96 @@ export class LuaTransformer { // ${left} = ____TS_tmp; // return ____TS_tmp const tmpIdentifier = tstl.createIdentifier("____TS_tmp"); - const operatorExpression = this.transformBinaryOperation(lhs.parent, left, right, replacementOperator); + const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, expression); const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatement = this.transformAssignment(lhs, tmpIdentifier); return this.createImmediatelyInvokedFunctionExpression( [tmpDeclaration, assignStatement], tmpIdentifier, - lhs.parent + expression ); } else { // Simple expressions // ${left} = ${right}; return ${right} - const operatorExpression = this.transformBinaryOperation(lhs.parent, left, right, replacementOperator); + const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, expression); const assignStatement = this.transformAssignment(lhs, operatorExpression); - return this.createImmediatelyInvokedFunctionExpression([assignStatement], left, lhs.parent); + return this.createImmediatelyInvokedFunctionExpression([assignStatement], left, expression); + } + } + + public transformBinaryOperator(operator: ts.BinaryOperator, node: ts.Node): tstl.BinaryOperator { + switch (operator) { + // Bitwise operators + case ts.SyntaxKind.BarToken: + return tstl.SyntaxKind.BitwiseOrOperator; + case ts.SyntaxKind.CaretToken: + return tstl.SyntaxKind.BitwiseExclusiveOrOperator; + case ts.SyntaxKind.AmpersandToken: + return tstl.SyntaxKind.BitwiseAndOperator; + case ts.SyntaxKind.LessThanLessThanToken: + return tstl.SyntaxKind.BitwiseLeftShiftOperator; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + throw TSTLErrors.UnsupportedKind("right shift operator (use >>> instead)", operator, node); + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return tstl.SyntaxKind.BitwiseRightShiftOperator; + // Regular operators + case ts.SyntaxKind.AmpersandAmpersandToken: + return tstl.SyntaxKind.AndOperator; + case ts.SyntaxKind.BarBarToken: + return tstl.SyntaxKind.OrOperator; + case ts.SyntaxKind.MinusToken: + return tstl.SyntaxKind.SubractionOperator; + case ts.SyntaxKind.PlusToken: + if (ts.isBinaryExpression(node)) { + // Check is we need to use string concat operator + const typeLeft = this.checker.getTypeAtLocation(node.left); + const typeRight = this.checker.getTypeAtLocation(node.right); + if (tsHelper.isStringType(typeLeft) || tsHelper.isStringType(typeRight)) { + return tstl.SyntaxKind.ConcatOperator; + } + } + return tstl.SyntaxKind.AdditionOperator; + case ts.SyntaxKind.AsteriskToken: + return tstl.SyntaxKind.MultiplicationOperator; + case ts.SyntaxKind.AsteriskAsteriskToken: + return tstl.SyntaxKind.PowerOperator; + case ts.SyntaxKind.SlashToken: + return tstl.SyntaxKind.DivisionOperator; + case ts.SyntaxKind.PercentToken: + return tstl.SyntaxKind.ModuloOperator; + case ts.SyntaxKind.GreaterThanToken: + return tstl.SyntaxKind.GreaterThanOperator; + case ts.SyntaxKind.GreaterThanEqualsToken: + return tstl.SyntaxKind.GreaterEqualOperator; + case ts.SyntaxKind.LessThanToken: + return tstl.SyntaxKind.LessThanOperator; + case ts.SyntaxKind.LessThanEqualsToken: + return tstl.SyntaxKind.LessEqualOperator; + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + return tstl.SyntaxKind.EqualityOperator; + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return tstl.SyntaxKind.InequalityOperator; + default: + throw TSTLErrors.UnsupportedKind("binary operator", operator, node); } } + public transformClassExpression(expression: ts.ClassExpression): ExpressionVisitResult { + const className = tstl.createAnnonymousIdentifier(); + const classDeclaration = this.transformClassDeclaration(expression as ts.ClassExpression, className); + return this.createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); + } + public transformCompoundAssignmentStatement( node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, - replacementOperator: tstl.BinaryOperator + replacementOperator: ts.BinaryOperator ): tstl.Statement { - if (replacementOperator === tstl.SyntaxKind.AdditionOperator) { - // Check is we need to use string concat operator - const typeLeft = this.checker.getTypeAtLocation(lhs); - const typeRight = this.checker.getTypeAtLocation(rhs); - if (tsHelper.isStringType(typeLeft) || tsHelper.isStringType(typeRight)) { - replacementOperator = tstl.SyntaxKind.ConcatOperator; - } - } - const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; const right = this.transformExpression(rhs); @@ -2701,10 +2725,10 @@ export class LuaTransformer { [obj, index], [this.transformExpression(objExpression), this.transformExpression(indexExpression)]); const accessExpression = tstl.createTableIndexExpression(obj, index); const operatorExpression = this.transformBinaryOperation( - node, accessExpression, tstl.createParenthesizedExpression(right), - replacementOperator + replacementOperator, + node ); const assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); return tstl.createDoStatement([objAndIndexDeclaration, assignStatement]); @@ -2712,7 +2736,7 @@ export class LuaTransformer { } else { // Simple statements // ${left} = ${left} ${replacementOperator} ${right} - const operatorExpression = this.transformBinaryOperation(node, left, right, replacementOperator); + const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, node); return this.transformAssignment(lhs, operatorExpression); } } @@ -2764,28 +2788,28 @@ export class LuaTransformer { node: ts.Node, left: tstl.Expression, right: tstl.Expression, - operator: tstl.BinaryBitwiseOperator, + operator: ts.BinaryOperator, lib: string ): ExpressionVisitResult { let bitFunction: string; switch (operator) { - case tstl.SyntaxKind.BitwiseAndOperator: + case ts.SyntaxKind.AmpersandToken: bitFunction = "band"; break; - case tstl.SyntaxKind.BitwiseOrOperator: + case ts.SyntaxKind.BarToken: bitFunction = "bor"; break; - case tstl.SyntaxKind.BitwiseExclusiveOrOperator: + case ts.SyntaxKind.CaretToken: bitFunction = "bxor"; break; - case tstl.SyntaxKind.BitwiseLeftShiftOperator: + case ts.SyntaxKind.LessThanLessThanToken: bitFunction = "lshift"; break; - case tstl.SyntaxKind.BitwiseRightShiftOperator: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: bitFunction = "rshift"; break; - case tstl.SyntaxKind.BitwiseArithmeticRightShift: + case ts.SyntaxKind.GreaterThanGreaterThanToken: bitFunction = "arshift"; break; default: @@ -2802,7 +2826,7 @@ export class LuaTransformer { node: ts.Node, left: tstl.Expression, right: tstl.Expression, - operator: tstl.BinaryBitwiseOperator + operator: ts.BinaryOperator ): ExpressionVisitResult { switch (this.options.luaTarget) { @@ -2816,10 +2840,8 @@ export class LuaTransformer { return this.transformBinaryBitLibOperation(node, left, right, operator, "bit"); default: - if (operator === tstl.SyntaxKind.BitwiseArithmeticRightShift) { - throw TSTLErrors.UnsupportedForTarget("Bitwise >>> operator", this.options.luaTarget, node); - } - return tstl.createBinaryExpression(left, right, operator, node); + const luaOperator = this.transformBinaryOperator(operator, node); + return tstl.createBinaryExpression(left, right, luaOperator, node); } } @@ -2863,7 +2885,7 @@ export class LuaTransformer { expression, expression.operand, ts.createLiteral(1), - tstl.SyntaxKind.AdditionOperator, + ts.SyntaxKind.PlusToken, true ); @@ -2872,7 +2894,7 @@ export class LuaTransformer { expression, expression.operand, ts.createLiteral(1), - tstl.SyntaxKind.SubractionOperator, + ts.SyntaxKind.MinusToken, true ); @@ -2888,7 +2910,7 @@ export class LuaTransformer { expression, expression.operand, ts.createLiteral(1), - tstl.SyntaxKind.AdditionOperator, + ts.SyntaxKind.PlusToken, false ); @@ -2897,7 +2919,7 @@ export class LuaTransformer { expression, expression.operand, ts.createLiteral(1), - tstl.SyntaxKind.SubractionOperator, + ts.SyntaxKind.MinusToken, false ); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 7c6e16a38..9985e7451 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -262,32 +262,32 @@ export class TSHelper { return undefined; } - public static isBinaryAssignmentToken(token: ts.SyntaxKind): [boolean, tstl.BinaryOperator] { + public static isBinaryAssignmentToken(token: ts.SyntaxKind): [boolean, ts.BinaryOperator] { switch (token) { case ts.SyntaxKind.BarEqualsToken: - return [true, tstl.SyntaxKind.BitwiseOrOperator]; + return [true, ts.SyntaxKind.BarToken]; case ts.SyntaxKind.PlusEqualsToken: - return [true, tstl.SyntaxKind.AdditionOperator]; + return [true, ts.SyntaxKind.PlusToken]; case ts.SyntaxKind.CaretEqualsToken: - return [true, tstl.SyntaxKind.BitwiseExclusiveOrOperator]; + return [true, ts.SyntaxKind.CaretToken]; case ts.SyntaxKind.MinusEqualsToken: - return [true, tstl.SyntaxKind.SubractionOperator]; + return [true, ts.SyntaxKind.MinusToken]; case ts.SyntaxKind.SlashEqualsToken: - return [true, tstl.SyntaxKind.DivisionOperator]; + return [true, ts.SyntaxKind.SlashToken]; case ts.SyntaxKind.PercentEqualsToken: - return [true, tstl.SyntaxKind.ModuloOperator]; + return [true, ts.SyntaxKind.PercentToken]; case ts.SyntaxKind.AsteriskEqualsToken: - return [true, tstl.SyntaxKind.MultiplicationOperator]; + return [true, ts.SyntaxKind.AsteriskToken]; case ts.SyntaxKind.AmpersandEqualsToken: - return [true, tstl.SyntaxKind.BitwiseAndOperator]; + return [true, ts.SyntaxKind.AmpersandToken]; case ts.SyntaxKind.AsteriskAsteriskEqualsToken: - return [true, tstl.SyntaxKind.PowerOperator]; + return [true, ts.SyntaxKind.AsteriskAsteriskToken]; case ts.SyntaxKind.LessThanLessThanEqualsToken: - return [true, tstl.SyntaxKind.BitwiseLeftShiftOperator]; + return [true, ts.SyntaxKind.LessThanLessThanToken]; case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: - return [true, tstl.SyntaxKind.BitwiseRightShiftOperator]; + return [true, ts.SyntaxKind.GreaterThanGreaterThanToken]; case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - return [true, tstl.SyntaxKind.BitwiseArithmeticRightShift]; + return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]; } return [false, undefined]; diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 95e1e8fc4..314e91853 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -710,6 +710,22 @@ export class ClassTests { Expect(result).toBe("instance of b"); } + @Test("Named Class Expression") + public namedClassExpression(): void { + const result = util.transpileAndExecute( + `const a = class MyClass { + public method() { + return "foo"; + } + } + let inst = new a(); + return inst.method();` + ); + + // Assert + Expect(result).toBe("foo"); + } + @Test("classExpressionBaseClassMethod") public classExpressionBaseClassMethod(): void { const result = util.transpileAndExecute( diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 5499ae374..e0d2df5b0 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -4,6 +4,7 @@ import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; import * as ts from "typescript"; import * as util from "../src/util"; +import { TSTLErrors } from "../../src/TSTLErrors"; export class ExpressionTests { @@ -114,10 +115,10 @@ export class ExpressionTests { @TestCase("a^=b", "a = bit.bxor(a, b);") @TestCase("a<>b", "bit.rshift(a, b);") - @TestCase("a>>=b", "a = bit.rshift(a, b);") - @TestCase("a>>>b", "bit.arshift(a, b);") - @TestCase("a>>>=b", "a = bit.arshift(a, b);") + @TestCase("a>>b", "bit.arshift(a, b);") + @TestCase("a>>=b", "a = bit.arshift(a, b);") + @TestCase("a>>>b", "bit.rshift(a, b);") + @TestCase("a>>>=b", "a = bit.rshift(a, b);") @Test("Bitop [JIT]") public bitOperatorOverrideJIT(input: string, lua: string): void { const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; @@ -133,10 +134,10 @@ export class ExpressionTests { @TestCase("a^=b", "a = bit32.bxor(a, b);") @TestCase("a<>b", "bit32.rshift(a, b);") - @TestCase("a>>=b", "a = bit32.rshift(a, b);") - @TestCase("a>>>b", "bit32.arshift(a, b);") - @TestCase("a>>>=b", "a = bit32.arshift(a, b);") + @TestCase("a>>b", "bit32.arshift(a, b);") + @TestCase("a>>=b", "a = bit32.arshift(a, b);") + @TestCase("a>>>b", "bit32.rshift(a, b);") + @TestCase("a>>>=b", "a = bit32.rshift(a, b);") @Test("Bitop [5.2]") public bitOperatorOverride52(input: string, lua: string): void { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; @@ -152,20 +153,24 @@ export class ExpressionTests { @TestCase("a^=b", "a = a ~ b;") @TestCase("a<>b", "a >> b;") - @TestCase("a>>=b", "a = a >> b;") + @TestCase("a>>>b", "a >> b;") + @TestCase("a>>>=b", "a = a >> b;") @Test("Bitop [5.3]") public bitOperatorOverride53(input: string, lua: string): void { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; Expect(util.transpileString(input, options)).toBe(lua); } - @TestCase("a>>>b") - @TestCase("a>>>=b") + @TestCase("a>>b") + @TestCase("a>>=b") @Test("Unsupported bitop 5.3") public bitOperatorOverride53Unsupported(input: string): void { Expect(() => util.transpileString(input, { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None })) - .toThrowError(TranspileError, "Bitwise >>> operator is/are not supported for target Lua 5.3."); + .toThrowError(TranspileError, TSTLErrors.UnsupportedKind( + "right shift operator (use >>> instead)", + ts.SyntaxKind.GreaterThanGreaterThanToken, + undefined + ).message); } @TestCase("1+1", "1 + 1;") @@ -249,7 +254,7 @@ export class ExpressionTests { @TestCase("(inst.field + 3) & 3", (8 + 3) & 3) @TestCase("inst.field | 3", 8 | 3) @TestCase("inst.field << 3", 8 << 3) - @TestCase("inst.field >> 1", 8 >> 1) + @TestCase("inst.field >>> 1", 8 >> 1) @TestCase("inst.field = 3", 3) @TestCase(`"abc" + inst.field`, "abc8") @Test("Get accessor expression") @@ -278,7 +283,7 @@ export class ExpressionTests { @TestCase("&= 3", (4 & 3) + 4) @TestCase("|= 3", (4 | 3) + 4) @TestCase("<<= 3", (4 << 3) + 4) - @TestCase(">>= 3", (4 >> 3) + 4) + @TestCase(">>>= 3", (4 >> 3) + 4) @Test("Set accessorExpression") public setAccessorBinary(expression: string, expected: any): void { const source = `class MyClass {` diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index 24652e07f..ad9047553 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -51,7 +51,7 @@ export class MathTests { @TestCase("x &= y", "x=2;y=6") @TestCase("x ^= y", "x=5;y=6") @TestCase("x <<= y", "x=192;y=6") - @TestCase("x >>= y", "x=0;y=6") + @TestCase("x >>>= y", "x=0;y=6") @Test("Operator assignment statements") public opAssignmentStatement(statement: string, expected: string): void { const result = util.transpileAndExecute( @@ -76,7 +76,7 @@ export class MathTests { @TestCase("o.p &= a[0]", "o=2;a=6") @TestCase("o.p ^= a[0]", "o=5;a=6") @TestCase("o.p <<= a[0]", "o=192;a=6") - @TestCase("o.p >>= a[0]", "o=0;a=6") + @TestCase("o.p >>>= a[0]", "o=0;a=6") @Test("Operator assignment to simple property statements") public opSimplePropAssignmentStatement(statement: string, expected: string): void { const result = util.transpileAndExecute( @@ -101,7 +101,7 @@ export class MathTests { @TestCase("o.p.d &= a[0][0]", "o=2;a=[6,11],[7,13]") @TestCase("o.p.d ^= a[0][0]", "o=5;a=[6,11],[7,13]") @TestCase("o.p.d <<= a[0][0]", "o=192;a=[6,11],[7,13]") - @TestCase("o.p.d >>= a[0][0]", "o=0;a=[6,11],[7,13]") + @TestCase("o.p.d >>>= a[0][0]", "o=0;a=[6,11],[7,13]") @Test("Operator assignment to deep property statements") public opDeepPropAssignmentStatement(statement: string, expected: string): void { const result = util.transpileAndExecute( @@ -126,7 +126,7 @@ export class MathTests { @TestCase("of().p &= af()[i()]", "o=2;a=6") @TestCase("of().p ^= af()[i()]", "o=5;a=6") @TestCase("of().p <<= af()[i()]", "o=192;a=6") - @TestCase("of().p >>= af()[i()]", "o=0;a=6") + @TestCase("of().p >>>= af()[i()]", "o=0;a=6") @Test("Operator assignment to complex property statements") public opComplexPropAssignmentStatement(statement: string, expected: string): void { const result = util.transpileAndExecute( @@ -154,7 +154,7 @@ export class MathTests { @TestCase("of().p.d &= af()[i()][i()]", "o=2;a=[7,6],[11,13];i=2") @TestCase("of().p.d ^= af()[i()][i()]", "o=5;a=[7,6],[11,13];i=2") @TestCase("of().p.d <<= af()[i()][i()]", "o=192;a=[7,6],[11,13];i=2") - @TestCase("of().p.d >>= af()[i()][i()]", "o=0;a=[7,6],[11,13];i=2") + @TestCase("of().p.d >>>= af()[i()][i()]", "o=0;a=[7,6],[11,13];i=2") @Test("Operator assignment to complex deep property statements") public opComplexDeepPropAssignmentStatement(statement: string, expected: string): void { const result = util.transpileAndExecute( @@ -183,7 +183,7 @@ export class MathTests { @TestCase("x &= y", "2;x=2;y=6") @TestCase("x ^= y", "5;x=5;y=6") @TestCase("x <<= y", "192;x=192;y=6") - @TestCase("x >>= y", "0;x=0;y=6") + @TestCase("x >>>= y", "0;x=0;y=6") @TestCase("x + (y += 7)", "16;x=3;y=13") @TestCase("x + (y += 7)", "16;x=3;y=13") @TestCase("x++ + (y += 7)", "16;x=4;y=13") @@ -211,7 +211,7 @@ export class MathTests { @TestCase("o.p &= a[0]", "2;o=2;a=6") @TestCase("o.p ^= a[0]", "5;o=5;a=6") @TestCase("o.p <<= a[0]", "192;o=192;a=6") - @TestCase("o.p >>= a[0]", "0;o=0;a=6") + @TestCase("o.p >>>= a[0]", "0;o=0;a=6") @TestCase("o.p + (a[0] += 7)", "16;o=3;a=13") @TestCase("o.p += (a[0] += 7)", "16;o=16;a=13") @TestCase("o.p++ + (a[0] += 7)", "16;o=4;a=13") @@ -239,7 +239,7 @@ export class MathTests { @TestCase("of().p &= af()[i()]", "2;o=2;a=6") @TestCase("of().p ^= af()[i()]", "5;o=5;a=6") @TestCase("of().p <<= af()[i()]", "192;o=192;a=6") - @TestCase("of().p >>= af()[i()]", "0;o=0;a=6") + @TestCase("of().p >>>= af()[i()]", "0;o=0;a=6") @TestCase("of().p + (af()[i()] += 7)", "16;o=3;a=13") @TestCase("of().p += (af()[i()] += 7)", "16;o=16;a=13") @TestCase("of().p++ + (af()[i()] += 7)", "16;o=4;a=13") diff --git a/tslint.json b/tslint.json index c321344c9..b230c4203 100644 --- a/tslint.json +++ b/tslint.json @@ -34,6 +34,7 @@ "no-construct": true, "no-debugger": true, "no-default-export": true, + "no-duplicate-switch-case": true, "no-duplicate-variable": true, "no-inferrable-types": true, "no-namespace": [true, "allow-declarations"], From 1e0247f2e4d58d354fb1a41b41541d703dc0b45e Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 15 Mar 2019 16:20:11 -0600 Subject: [PATCH 026/764] New functions v2 (#465) * all functions take a self parameter - also added noSelf directive to add `this: void` namespace/class-wide - rewrote function assignment tests to be more thorough and maintainable - fixed bug in generators where parameters were being hidden * fixed array lib issues * a few small tweaks - fixed bad definition in one of the assign test functions - performing diagnostics on invalif function assignment tests - added check in transpileString to ensure ignoreDiagnostics command line flag is respected * split out searching for `@noSelf` to its own function * Renamed and reworded function assignment errors to make sense in new context * Replace O(N^2) function assignment tests with more focused ones to reduce overall amount of testing required. I beleive this should still catch all the known edge-cases. * fixed `this` in module test to actually access `this` and removed a leftover FocusTest reference * limited @noSelf recursion to namespaces and fixed @noSelf on class expressions * @noSelf support on interfaces and added/fixed more tests * added @noSelfInFile file-scope directive * only preventing noSelf recursion on methods now and cleaned up some tests --- src/Decorator.ts | 6 + src/LuaTransformer.ts | 34 +- src/TSHelper.ts | 72 +- src/TSTLErrors.ts | 30 +- src/lualib/ArrayConcat.ts | 6 +- src/lualib/ArrayEvery.ts | 4 +- src/lualib/ArrayFilter.ts | 4 +- src/lualib/ArrayFindIndex.ts | 3 +- src/lualib/ArrayForEach.ts | 4 +- src/lualib/ArrayIndexOf.ts | 2 +- src/lualib/ArrayMap.ts | 2 +- src/lualib/ArrayPush.ts | 2 +- src/lualib/ArrayReverse.ts | 2 +- src/lualib/ArrayShift.ts | 4 +- src/lualib/ArraySlice.ts | 2 +- src/lualib/ArraySome.ts | 4 +- src/lualib/ArraySort.ts | 4 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/ArrayUnshift.ts | 4 +- src/lualib/ClassIndex.ts | 6 +- src/lualib/ClassNewIndex.ts | 8 +- src/lualib/FunctionApply.ts | 8 +- src/lualib/FunctionBind.ts | 10 +- src/lualib/FunctionCall.ts | 8 +- src/lualib/Index.ts | 4 +- src/lualib/InstanceOf.ts | 2 +- src/lualib/Iterator.ts | 2 +- src/lualib/Map.ts | 2 +- src/lualib/NewIndex.ts | 10 +- src/lualib/ObjectAssign.ts | 2 +- src/lualib/ObjectEntries.ts | 2 +- src/lualib/ObjectKeys.ts | 2 +- src/lualib/ObjectValues.ts | 2 +- src/lualib/Set.ts | 2 +- src/lualib/StringConcat.ts | 2 +- src/lualib/StringReplace.ts | 4 +- src/lualib/StringSplit.ts | 2 +- src/lualib/Symbol.ts | 2 +- src/lualib/SymbolRegistry.ts | 4 +- src/lualib/WeakMap.ts | 2 +- src/lualib/WeakSet.ts | 2 +- test/src/util.ts | 14 +- test/translation/lua/callNamespace.lua | 2 +- .../translation/lua/functionRestArguments.lua | 2 +- .../translation/lua/modulesFunctionExport.lua | 2 +- .../lua/modulesFunctionNoExport.lua | 2 +- ...modulesNamespaceNestedWithMemberExport.lua | 2 +- .../lua/modulesNamespaceWithMemberExport.lua | 2 +- .../modulesNamespaceWithMemberNoExport.lua | 2 +- test/translation/lua/namespace.lua | 2 +- test/translation/lua/namespaceMerge.lua | 4 +- test/translation/lua/namespaceNested.lua | 2 +- test/translation/lua/namespacePhantom.lua | 2 +- test/translation/lua/returnDefault.lua | 2 +- .../lua/shorthandPropertyAssignment.lua | 2 +- test/translation/lua/tupleReturn.lua | 40 +- test/unit/assignmentDestructuring.spec.ts | 2 +- test/unit/assignments.spec.ts | 1144 +++++++++-------- test/unit/declarations.spec.ts | 11 +- test/unit/lualib/lualib.spec.ts | 2 +- test/unit/modules.spec.ts | 11 + test/unit/objectLiteral.spec.ts | 2 +- 62 files changed, 851 insertions(+), 682 deletions(-) diff --git a/src/Decorator.ts b/src/Decorator.ts index 42b775841..c18ab4dc3 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -25,6 +25,10 @@ export class Decorator { return DecoratorKind.NoClassOr; case "luaiterator": return DecoratorKind.LuaIterator; + case "noself": + return DecoratorKind.NoSelf; + case "noselfinfile": + return DecoratorKind.NoSelfInFile; } return undefined; @@ -50,4 +54,6 @@ export enum DecoratorKind { TupleReturn = "TupleReturn", NoClassOr = "NoClassOr", LuaIterator = "LuaIterator", + NoSelf = "NoSelf", + NoSelfInFile = "NoSelfInFile", } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index fc31cb851..b367495e0 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1454,16 +1454,13 @@ export class LuaTransformer { private transformGeneratorFunction( parameters: ts.NodeArray, body: ts.Block, - transformedParameters: tstl.Identifier[], - dotsLiteral: tstl.DotsLiteral, spreadIdentifier?: tstl.Identifier ): [tstl.Statement[], Scope] { this.importLuaLibFeature(LuaLibFeature.Symbol); const [functionBody, functionScope] = this.transformFunctionBody( parameters, - body, - spreadIdentifier + body ); const coroutineIdentifier = tstl.createIdentifier("____co"); @@ -1478,12 +1475,7 @@ export class LuaTransformer { tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("create") ), - [tstl.createFunctionExpression( - tstl.createBlock(functionBody), - transformedParameters, - dotsLiteral, - spreadIdentifier), - ] + [tstl.createFunctionExpression(tstl.createBlock(functionBody))] ) ); @@ -1586,6 +1578,12 @@ export class LuaTransformer { //return ____it tstl.createReturnStatement([itIdentifier]), ]; + + if (spreadIdentifier) { + const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); + block.unshift(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); + } + return [block, functionScope]; } @@ -1606,8 +1604,6 @@ export class LuaTransformer { ? this.transformGeneratorFunction( functionDeclaration.parameters, functionDeclaration.body, - params, - dotsLiteral, restParamName ) : this.transformFunctionBody( @@ -3131,14 +3127,12 @@ export class LuaTransformer { const callPath = this.transformExpression(node.expression); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration - && !ts.isPropertyAccessExpression(node.expression) - && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.NonVoid - && !ts.isElementAccessExpression(node.expression)) + && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) { + parameters = this.transformArguments(node.arguments, signature); + } else { const context = this.isStrict ? ts.createNull() : ts.createIdentifier("_G"); parameters = this.transformArguments(node.arguments, signature, context); - } else { - parameters = this.transformArguments(node.arguments, signature); } const expressionType = this.checker.getTypeAtLocation(node.expression); @@ -3885,7 +3879,7 @@ export class LuaTransformer { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { - throw TSTLErrors.UnsupportedMethodConversion(node); + throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } const params = this.transformArguments(node.arguments); const caller = this.transformExpression(expression.expression); @@ -4326,9 +4320,9 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); } else if (fromContext !== toContext && fromContext !== ContextType.None && toContext !== ContextType.None) { if (toContext === ContextType.Void) { - throw TSTLErrors.UnsupportedFunctionConversion(node, toName); + throw TSTLErrors.UnsupportedNoSelfFunctionConversion(node, toName); } else { - throw TSTLErrors.UnsupportedMethodConversion(node, toName); + throw TSTLErrors.UnsupportedSelfFunctionConversion(node, toName); } } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 9985e7451..2de95d570 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -249,6 +249,21 @@ export class TSHelper { return decMap; } + public static getCustomFileDirectives(file: ts.SourceFile): Map { + const decMap = new Map(); + if (file.statements.length > 0) { + const tags = ts.getJSDocTags(file.statements[0]); + for (const tag of tags) { + const tagName = tag.tagName.escapedText as string; + if (Decorator.isValid(tagName)) { + const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); + decMap.set(dec.kind, dec); + } + } + } + return decMap; + } + // Search up until finding a node satisfying the callback public static findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T { let current = node; @@ -559,6 +574,24 @@ export class TSHelper { return signatureDeclarations; } + public static hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean { + const scopeDeclaration = TSHelper.findFirstNodeAbove( + declaration, + (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) + ); + if (!scopeDeclaration) { + return false; + } + if (ts.isSourceFile(scopeDeclaration)) { + return TSHelper.getCustomFileDirectives(scopeDeclaration).has(DecoratorKind.NoSelfInFile); + } + const scopeType = checker.getTypeAtLocation(scopeDeclaration); + if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { + return true; + } + return TSHelper.hasNoSelfAncestor(scopeDeclaration, checker); + } + public static getDeclarationContextType( signatureDeclaration: ts.SignatureDeclaration, checker: ts.TypeChecker @@ -571,22 +604,35 @@ export class TSHelper { ? ContextType.Void : ContextType.NonVoid; } - if (ts.isMethodDeclaration(signatureDeclaration) || ts.isMethodSignature(signatureDeclaration)) { - // Method - return ContextType.NonVoid; - } - if (ts.isPropertySignature(signatureDeclaration.parent) - || ts.isPropertyDeclaration(signatureDeclaration.parent) - || ts.isPropertyAssignment(signatureDeclaration.parent)) { - // Lambda property + + if (ts.isMethodSignature(signatureDeclaration) + || ts.isMethodDeclaration(signatureDeclaration) + || ts.isConstructSignatureDeclaration(signatureDeclaration) + || ts.isConstructorDeclaration(signatureDeclaration) + || (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) + || (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent))) + { + // Class/interface methods only respect @noSelf on their parent + const scopeDeclaration = TSHelper.findFirstNodeAbove( + signatureDeclaration, + (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => + ts.isClassDeclaration(n) + || ts.isClassExpression(n) + || ts.isInterfaceDeclaration(n) + ); + const scopeType = checker.getTypeAtLocation(scopeDeclaration); + if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { + return ContextType.Void; + } return ContextType.NonVoid; } - if (ts.isBinaryExpression(signatureDeclaration.parent)) { - // Function expression: check type being assigned to - return TSHelper.getFunctionContextType( - checker.getTypeAtLocation(signatureDeclaration.parent.left), checker); + + // Walk up to find @noSelf or @noSelfOnFile + if (TSHelper.hasNoSelfAncestor(signatureDeclaration, checker)) { + return ContextType.Void; } - return ContextType.Void; + + return ContextType.NonVoid; } public static reduceContextTypes(contexts: ContextType[]): ContextType { diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 53a00cce7..f666c3abe 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -78,32 +78,30 @@ export class TSTLErrors { public static UnsupportedForTarget = (functionality: string, version: string, node: ts.Node) => new TranspileError(`${functionality} is/are not supported for target Lua ${version}.`, node); - public static UnsupportedFunctionConversion = (node: ts.Node, name?: string) => { + public static UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { if (name) { return new TranspileError( - `Unsupported conversion from method to function "${name}". ` + - `To fix, wrap the method in an arrow function.`, + `Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.`, node); } else { return new TranspileError( - `Unsupported conversion from method to function. ` + - `To fix, wrap the method in an arrow function.`, + `Unable to convert function with a 'this' parameter to function with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.`, node); } }; - public static UnsupportedMethodConversion = (node: ts.Node, name?: string) => { + public static UnsupportedSelfFunctionConversion = (node: ts.Node, name?: string) => { if (name) { return new TranspileError( - `Unsupported conversion from function to method "${name}". ` + - `To fix, wrap the function in an arrow function or declare the function with` + - ` an explicit 'this' parameter.`, + `Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` + + `To fix, wrap in an arrow function or declare with 'this: any'.`, node); } else { return new TranspileError( - `Unsupported conversion from function to method. ` + - `To fix, wrap the function in an arrow function or declare the function with` + - ` an explicit 'this' parameter.`, + `Unable to convert function with no 'this' parameter to function with 'this'. ` + + `To fix, wrap in an arrow function or declare with 'this: any'.`, node); } }; @@ -111,13 +109,13 @@ export class TSTLErrors { public static UnsupportedOverloadAssignment = (node: ts.Node, name?: string) => { if (name) { return new TranspileError( - `Unsupported assignment of mixed function/method overload to "${name}". ` + - `Overloads should either be all functions or all methods, but not both.`, + `Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` + + `Overloads should all have the same type for 'this'.`, node); } else { return new TranspileError( - `Unsupported assignment of mixed function/method overload. ` + - `Overloads should either be all functions or all methods, but not both.`, + `Unsupported assignment of function with different overloaded types for 'this'. ` + + `Overloads should all have the same type for 'this'.`, node); } }; diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index 06d5206b3..5eaf56cb7 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -1,7 +1,7 @@ -declare function pcall(func: () => any): any; -declare function type(val: any): string; +declare function pcall(this: void, func: () => any): any; +declare function type(this: void, val: any): string; -function __TS__ArrayConcat(arr1: any[], ...args: any[]): any[] { +function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { const out: any[] = []; for (const val of arr1) { out[out.length] = val; diff --git a/src/lualib/ArrayEvery.ts b/src/lualib/ArrayEvery.ts index e8434175a..cc08c2fab 100644 --- a/src/lualib/ArrayEvery.ts +++ b/src/lualib/ArrayEvery.ts @@ -1,4 +1,6 @@ -function __TS__ArrayEvery(arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean): boolean { +function __TS__ArrayEvery(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) + : boolean +{ for (let i = 0; i < arr.length; i++) { if (!callbackfn(arr[i], i, arr)) { return false; diff --git a/src/lualib/ArrayFilter.ts b/src/lualib/ArrayFilter.ts index 8f0ac2fde..2a64a7389 100644 --- a/src/lualib/ArrayFilter.ts +++ b/src/lualib/ArrayFilter.ts @@ -1,4 +1,6 @@ -function __TS__ArrayFilter(arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean): T[] { +function __TS__ArrayFilter(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) + : T[] +{ const result: T[] = []; for (let i = 0; i < arr.length; i++) { if (callbackfn(arr[i], i, arr)) { diff --git a/src/lualib/ArrayFindIndex.ts b/src/lualib/ArrayFindIndex.ts index b60190c09..53d83cb39 100644 --- a/src/lualib/ArrayFindIndex.ts +++ b/src/lualib/ArrayFindIndex.ts @@ -1,6 +1,7 @@ function __TS__ArrayFindIndex( + this: void, arr: T[], - callbackFn: (this: void, element: T, index?: number, array?: T[]) => boolean + callbackFn: (element: T, index?: number, array?: T[]) => boolean ): number { for (let i = 0, len = arr.length; i < len; i++) { if (callbackFn(arr[i], i, arr)) { diff --git a/src/lualib/ArrayForEach.ts b/src/lualib/ArrayForEach.ts index 3001915f0..6f6c931f7 100644 --- a/src/lualib/ArrayForEach.ts +++ b/src/lualib/ArrayForEach.ts @@ -1,4 +1,6 @@ -function __TS__ArrayForEach(arr: T[], callbackFn: (value: T, index?: number, array?: any[]) => any): void { +function __TS__ArrayForEach(this: void, arr: T[], callbackFn: (value: T, index?: number, array?: any[]) => any) + : void +{ for (let i = 0; i < arr.length; i++) { callbackFn(arr[i], i, arr); } diff --git a/src/lualib/ArrayIndexOf.ts b/src/lualib/ArrayIndexOf.ts index c50ce5ded..a2eb5ebf0 100644 --- a/src/lualib/ArrayIndexOf.ts +++ b/src/lualib/ArrayIndexOf.ts @@ -1,4 +1,4 @@ -function __TS__ArrayIndexOf(arr: T[], searchElement: T, fromIndex?: number): number { +function __TS__ArrayIndexOf(this: void, arr: T[], searchElement: T, fromIndex?: number): number { const len = arr.length; if (len === 0) { return -1; diff --git a/src/lualib/ArrayMap.ts b/src/lualib/ArrayMap.ts index f7ea7aa50..04ee22a48 100644 --- a/src/lualib/ArrayMap.ts +++ b/src/lualib/ArrayMap.ts @@ -1,4 +1,4 @@ -function __TS__ArrayMap(arr: T[], callbackfn: (value: T, index?: number, array?: T[]) => U): U[] { +function __TS__ArrayMap(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: T[]) => U): U[] { const newArray: U[] = []; for (let i = 0; i < arr.length; i++) { newArray[i] = callbackfn(arr[i], i, arr); diff --git a/src/lualib/ArrayPush.ts b/src/lualib/ArrayPush.ts index 8e1d8e324..f09005e44 100644 --- a/src/lualib/ArrayPush.ts +++ b/src/lualib/ArrayPush.ts @@ -1,4 +1,4 @@ -function __TS__ArrayPush(arr: T[], ...items: T[]): number { +function __TS__ArrayPush(this: void, arr: T[], ...items: T[]): number { for (const item of items) { arr[arr.length] = item; } diff --git a/src/lualib/ArrayReverse.ts b/src/lualib/ArrayReverse.ts index 3c4839417..ae1fb90dd 100644 --- a/src/lualib/ArrayReverse.ts +++ b/src/lualib/ArrayReverse.ts @@ -1,4 +1,4 @@ -function __TS__ArrayReverse(arr: any[]): any[] { +function __TS__ArrayReverse(this: void, arr: any[]): any[] { let i = 0; let j = arr.length - 1; while (i < j) { diff --git a/src/lualib/ArrayShift.ts b/src/lualib/ArrayShift.ts index a95df1a49..475886eb2 100644 --- a/src/lualib/ArrayShift.ts +++ b/src/lualib/ArrayShift.ts @@ -1,6 +1,6 @@ declare namespace table { - function remove(arr: T[], idx: number): T; + function remove(this: void, arr: T[], idx: number): T; } -function __TS__ArrayShift(arr: T[]): T { +function __TS__ArrayShift(this: void, arr: T[]): T { return table.remove(arr, 1); } diff --git a/src/lualib/ArraySlice.ts b/src/lualib/ArraySlice.ts index f3eb5b3d6..8005e9afc 100644 --- a/src/lualib/ArraySlice.ts +++ b/src/lualib/ArraySlice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 22.1.3.23 -function __TS__ArraySlice(list: T[], first: number, last: number): T[] { +function __TS__ArraySlice(this: void, list: T[], first: number, last: number): T[] { const len = list.length; let k: number; diff --git a/src/lualib/ArraySome.ts b/src/lualib/ArraySome.ts index d03e7a9fe..293e60c60 100644 --- a/src/lualib/ArraySome.ts +++ b/src/lualib/ArraySome.ts @@ -1,4 +1,6 @@ -function __TS__ArraySome(arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean): boolean { +function __TS__ArraySome(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) + : boolean +{ for (let i = 0; i < arr.length; i++) { if (callbackfn(arr[i], i, arr)) { return true; diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts index 01229598d..49fc196b0 100644 --- a/src/lualib/ArraySort.ts +++ b/src/lualib/ArraySort.ts @@ -1,7 +1,7 @@ declare namespace table { - function sort(arr: T[], compareFn?: (a: T, b: T) => boolean): void; + function sort(this: void, arr: T[], compareFn?: (this: void, a: T, b: T) => boolean): void; } -function __TS__ArraySort(arr: T[], compareFn?: (a: T, b: T) => number): T[] { +function __TS__ArraySort(this: void, arr: T[], compareFn?: (a: T, b: T) => number): T[] { if (compareFn !== undefined) { table.sort(arr, (a, b) => compareFn(a, b) < 0); } else { diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index b875d706c..a1e4e29c4 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,4 +1,4 @@ -function __TS__ArraySplice(list: T[], start: number, deleteCount: number, ...items: T[]): T[] { +function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: number, ...items: T[]): T[] { const len = list.length; diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts index cb0031100..1239033ea 100644 --- a/src/lualib/ArrayUnshift.ts +++ b/src/lualib/ArrayUnshift.ts @@ -1,7 +1,7 @@ declare namespace table { - function insert(arr: T[], idx: number, val: T): void; + function insert(this: void, arr: T[], idx: number, val: T): void; } -function __TS__ArrayUnshift(arr: T[], ...items: T[]): number { +function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { for (let i = items.length - 1; i >= 0; --i) { table.insert(arr, 1, items[i]); } diff --git a/src/lualib/ClassIndex.ts b/src/lualib/ClassIndex.ts index f879fd9aa..a231205bb 100644 --- a/src/lualib/ClassIndex.ts +++ b/src/lualib/ClassIndex.ts @@ -1,11 +1,11 @@ interface LuaClass { ____super?: LuaClass; - ____getters?: { [key: string]: (self: LuaClass) => any }; + ____getters?: { [key: string]: (this: void, self: LuaClass) => any }; } -declare function rawget(obj: T, key: K): T[K]; +declare function rawget(this: void, obj: T, key: K): T[K]; -function __TS__ClassIndex(classTable: LuaClass, key: keyof LuaClass): any { +function __TS__ClassIndex(this: void, classTable: LuaClass, key: keyof LuaClass): any { while (true) { const getters = rawget(classTable, "____getters"); if (getters) { diff --git a/src/lualib/ClassNewIndex.ts b/src/lualib/ClassNewIndex.ts index 65108c6a2..68b5db7f7 100644 --- a/src/lualib/ClassNewIndex.ts +++ b/src/lualib/ClassNewIndex.ts @@ -1,12 +1,12 @@ interface LuaClass { ____super?: LuaClass; - ____setters?: { [key: string]: (self: LuaClass, val: any) => void }; + ____setters?: { [key: string]: (this: void, self: LuaClass, val: any) => void }; } -declare function rawget(obj: T, key: K): T[K]; -declare function rawset(obj: T, key: K, val: T[K]): void; +declare function rawget(this: void, obj: T, key: K): T[K]; +declare function rawset(this: void, obj: T, key: K, val: T[K]): void; -function __TS__ClassNewIndex(classTable: LuaClass, key: keyof LuaClass, val: any): void { +function __TS__ClassNewIndex(this: void, classTable: LuaClass, key: keyof LuaClass, val: any): void { let tbl = classTable; do { const setters = rawget(tbl, "____setters"); diff --git a/src/lualib/FunctionApply.ts b/src/lualib/FunctionApply.ts index 6776f0e02..80e7b69b6 100644 --- a/src/lualib/FunctionApply.ts +++ b/src/lualib/FunctionApply.ts @@ -1,12 +1,12 @@ -declare function unpack(list: T[], i?: number, j?: number): T[]; +declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; declare namespace table { - export function unpack(list: T[], i?: number, j?: number): T[]; + export function unpack(this: void, list: T[], i?: number, j?: number): T[]; } -type ApplyFn = (...argArray: any[]) => any; +type ApplyFn = (this: void, ...argArray: any[]) => any; -function __TS__FunctionApply(fn: ApplyFn, thisArg: any, argsArray?: any[]): any { +function __TS__FunctionApply(this: void, fn: ApplyFn, thisArg: any, argsArray?: any[]): any { if (argsArray) { return fn(thisArg, (unpack || table.unpack)(argsArray)); } else { diff --git a/src/lualib/FunctionBind.ts b/src/lualib/FunctionBind.ts index e1e7675b5..09e663c91 100644 --- a/src/lualib/FunctionBind.ts +++ b/src/lualib/FunctionBind.ts @@ -1,14 +1,14 @@ -declare function unpack(list: T[], i?: number, j?: number): T[]; +declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; declare namespace table { - export function insert(t: T[], pos: number, value: T): void; + export function insert(this: void, t: T[], pos: number, value: T): void; - export function unpack(list: T[], i?: number, j?: number): T[]; + export function unpack(this: void, list: T[], i?: number, j?: number): T[]; } -type BindFn = (...argArray: any[]) => any; +type BindFn = (this: void, ...argArray: any[]) => any; -function __TS__FunctionBind(fn: BindFn, thisArg: any, ...boundArgs: any[]): (...args: any[]) => any { +function __TS__FunctionBind(this: void, fn: BindFn, thisArg: any, ...boundArgs: any[]): (...args: any[]) => any { return (...argArray: any[]) => { for (let i = 0; i < boundArgs.length; ++i) { table.insert(argArray, i + 1, boundArgs[i]); diff --git a/src/lualib/FunctionCall.ts b/src/lualib/FunctionCall.ts index fe126ccd5..66a2be373 100644 --- a/src/lualib/FunctionCall.ts +++ b/src/lualib/FunctionCall.ts @@ -1,11 +1,11 @@ -declare function unpack(list: T[], i?: number, j?: number): T[]; +declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; declare namespace table { - export function unpack(list: T[], i?: number, j?: number): T[]; + export function unpack(this: void, list: T[], i?: number, j?: number): T[]; } -type CallFn = (...argArray: any[]) => any; +type CallFn = (this: void, ...argArray: any[]) => any; -function __TS__FunctionCall(fn: CallFn, thisArg: any, ...args: any[]): any { +function __TS__FunctionCall(this: void, fn: CallFn, thisArg: any, ...args: any[]): any { return fn(thisArg, (unpack || table.unpack)(args)); } diff --git a/src/lualib/Index.ts b/src/lualib/Index.ts index a5f44081f..88c8e0035 100644 --- a/src/lualib/Index.ts +++ b/src/lualib/Index.ts @@ -5,12 +5,12 @@ interface LuaClass { declare interface LuaObject { constructor: LuaClass; - ____getters?: { [key: string]: (self: LuaObject) => any }; + ____getters?: { [key: string]: (this: void, self: LuaObject) => any }; } declare function rawget(obj: T, key: K): T[K]; -function __TS__Index(classProto: LuaObject): (tbl: LuaObject, key: keyof LuaObject) => any { +function __TS__Index(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: keyof LuaObject) => any { return (tbl, key) => { let proto = classProto; while (true) { diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index c23c3604a..b59674943 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -6,7 +6,7 @@ interface LuaObject { constructor: LuaClass; } -function __TS__InstanceOf(obj: LuaObject, classTbl: LuaClass): boolean { +function __TS__InstanceOf(this: void, obj: LuaObject, classTbl: LuaClass): boolean { if (obj !== undefined) { let luaClass = obj.constructor; while (luaClass !== undefined) { diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 805792052..b45fafe46 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,4 +1,4 @@ -function __TS__Iterator(iterable: Iterable): () => T { +function __TS__Iterator(this: void, iterable: Iterable): (this: void) => T { const iterator = iterable[Symbol.iterator](); return () => { const result = iterator.next(); diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index fd55ef62f..f47d81abb 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -1,5 +1,5 @@ /** @tupleReturn */ -declare function next(t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; +declare function next(this: void, t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; class Map { public size: number; diff --git a/src/lualib/NewIndex.ts b/src/lualib/NewIndex.ts index d50d76ab7..efe07f075 100644 --- a/src/lualib/NewIndex.ts +++ b/src/lualib/NewIndex.ts @@ -5,13 +5,15 @@ interface LuaClass { declare interface LuaObject { constructor: LuaClass; - ____setters?: { [key: string]: (self: LuaObject, val: any) => void }; + ____setters?: { [key: string]: (this: void, self: LuaObject, val: any) => void }; } -declare function rawget(obj: T, key: K): T[K]; -declare function rawset(obj: T, key: K, val: T[K]): void; +declare function rawget(this: void, obj: T, key: K): T[K]; +declare function rawset(this: void, obj: T, key: K, val: T[K]): void; -function __TS__NewIndex(classProto: LuaObject): (tbl: LuaObject, key: keyof LuaObject, val: any) => void { +function __TS__NewIndex(this: void, classProto: LuaObject) + : (this: void, tbl: LuaObject, key: keyof LuaObject, val: any) => void +{ return (tbl, key, val) => { let proto = classProto; while (true) { diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index ff0b3fb41..da49d9eb0 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,5 +1,5 @@ // https://tc39.github.io/ecma262/#sec-object.assign -function __TS__ObjectAssign(to: T, ...sources: object[]): T { +function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { if (to === undefined) { return to; } diff --git a/src/lualib/ObjectEntries.ts b/src/lualib/ObjectEntries.ts index 51f32cf10..f491bd039 100644 --- a/src/lualib/ObjectEntries.ts +++ b/src/lualib/ObjectEntries.ts @@ -1,4 +1,4 @@ -function __TS__ObjectEntries(obj: any): Array { +function __TS__ObjectEntries(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = [key, obj[key]]; diff --git a/src/lualib/ObjectKeys.ts b/src/lualib/ObjectKeys.ts index 5358acad8..8163a620a 100644 --- a/src/lualib/ObjectKeys.ts +++ b/src/lualib/ObjectKeys.ts @@ -1,4 +1,4 @@ -function __TS__ObjectKeys(obj: any): Array { +function __TS__ObjectKeys(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = key; diff --git a/src/lualib/ObjectValues.ts b/src/lualib/ObjectValues.ts index c7a17377a..e850f6a31 100644 --- a/src/lualib/ObjectValues.ts +++ b/src/lualib/ObjectValues.ts @@ -1,4 +1,4 @@ -function __TS__ObjectValues(obj: any): Array { +function __TS__ObjectValues(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = obj[key]; diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index 2b06ee1d4..e1bf8fc39 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -1,5 +1,5 @@ /** @tupleReturn */ -declare function next(t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; +declare function next(this: void, t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; class Set { public size: number; diff --git a/src/lualib/StringConcat.ts b/src/lualib/StringConcat.ts index ae90c6b61..ce3f6dd6e 100644 --- a/src/lualib/StringConcat.ts +++ b/src/lualib/StringConcat.ts @@ -1,4 +1,4 @@ -function __TS__StringConcat(str1: string, ...args: string[]): string { +function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { let out = str1; for (const arg of args) { out = out + arg; diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index 7324db680..3f51b8b43 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -1,8 +1,8 @@ declare namespace string { /** @tupleReturn */ - function gsub(source: string, searchValue: string, replaceValue: string): [string, number]; + function gsub(this: void, source: string, searchValue: string, replaceValue: string): [string, number]; } -function __TS__StringReplace(source: string, searchValue: string, replaceValue: string): string { +function __TS__StringReplace(this: void, source: string, searchValue: string, replaceValue: string): string { return string.gsub(source, searchValue, replaceValue)[0]; } diff --git a/src/lualib/StringSplit.ts b/src/lualib/StringSplit.ts index 005f57436..734dac38c 100644 --- a/src/lualib/StringSplit.ts +++ b/src/lualib/StringSplit.ts @@ -1,4 +1,4 @@ -function __TS__StringSplit(source: string, separator?: string, limit?: number): string[] { +function __TS__StringSplit(this: void, source: string, separator?: string, limit?: number): string[] { if (limit === undefined) { limit = 4294967295; } diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 2464b5f20..5c7bf0a7c 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,4 +1,4 @@ -declare function setmetatable(obj: T, metatable: any): T; +declare function setmetatable(this: void, obj: T, metatable: any): T; // tslint:disable-next-line: variable-name const ____symbolMetatable = { diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index c9c42e4e3..c1fa21df5 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -1,7 +1,7 @@ // tslint:disable-next-line: variable-name const ____symbolRegistry: Record = {}; -function __TS__SymbolRegistryFor(key: string): symbol { +function __TS__SymbolRegistryFor(this: void, key: string): symbol { if (!____symbolRegistry[key]) { ____symbolRegistry[key] = __TS__Symbol(key); } @@ -9,7 +9,7 @@ function __TS__SymbolRegistryFor(key: string): symbol { return ____symbolRegistry[key]; } -function __TS__SymbolRegistryKeyFor(sym: symbol): string { +function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string { for (const key in ____symbolRegistry) { if (____symbolRegistry[key] === sym) return key; } diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 3f92cf3df..407b268a3 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -declare function setmetatable(obj: T, metatable: any): T; +declare function setmetatable(this: void, obj: T, metatable: any): T; class WeakMap { private items: {[key: string]: TValue}; // Type of key is actually TKey diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index 7cfae57f3..cbe7b5ede 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -declare function setmetatable(obj: T, metatable: any): T; +declare function setmetatable(this: void, obj: T, metatable: any): T; class WeakSet { private items: {[key: string]: boolean}; // Key type is actually TValue diff --git a/test/src/util.ts b/test/src/util.ts index a2da34bf4..ec3f0cf73 100644 --- a/test/src/util.ts +++ b/test/src/util.ts @@ -16,7 +16,11 @@ export function transpileString( options?: CompilerOptions, ignoreDiagnostics = true, filePath = "file.ts" -): string { +): string +{ + if (ignoreDiagnostics === false) { + ignoreDiagnostics = process.argv[2] === "--ignoreDiagnostics"; + } if (options) { if (options.noHeader === undefined) { options.noHeader = true; @@ -94,9 +98,9 @@ export function transpileAndExecute( ignoreDiagnosticsOverride = process.argv[2] === "--ignoreDiagnostics" ): any { - const wrappedTsString = `declare function JSONStringify(p: any): string; - ${tsHeader ? tsHeader : ""} - function __runTest(): any {${tsStr}}`; + const wrappedTsString = `${tsHeader ? tsHeader : ""} + declare function JSONStringify(this: void, p: any): string; + function __runTest(this: void): any {${tsStr}}`; const lua = `${luaHeader ? luaHeader : ""} ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnosticsOverride)} @@ -112,7 +116,7 @@ export function transpileExecuteAndReturnExport( luaHeader?: string ): any { - const wrappedTsString = `declare function JSONStringify(p: any): string; + const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; ${tsStr}`; const lua = `return (function() diff --git a/test/translation/lua/callNamespace.lua b/test/translation/lua/callNamespace.lua index b0ec0d650..40b907163 100644 --- a/test/translation/lua/callNamespace.lua +++ b/test/translation/lua/callNamespace.lua @@ -1 +1 @@ -Namespace.myFunction(); +Namespace:myFunction(); diff --git a/test/translation/lua/functionRestArguments.lua b/test/translation/lua/functionRestArguments.lua index 25fe06c01..b440062ed 100644 --- a/test/translation/lua/functionRestArguments.lua +++ b/test/translation/lua/functionRestArguments.lua @@ -1,3 +1,3 @@ -varargsFunction = function(a, ...) +varargsFunction = function(self, a, ...) local b = ({...}); end; diff --git a/test/translation/lua/modulesFunctionExport.lua b/test/translation/lua/modulesFunctionExport.lua index 12e69553c..7b8d3dd58 100644 --- a/test/translation/lua/modulesFunctionExport.lua +++ b/test/translation/lua/modulesFunctionExport.lua @@ -1,4 +1,4 @@ local exports = exports or {}; -exports.publicFunc = function() +exports.publicFunc = function(self) end; return exports; diff --git a/test/translation/lua/modulesFunctionNoExport.lua b/test/translation/lua/modulesFunctionNoExport.lua index 37ea15ea9..59eb73913 100644 --- a/test/translation/lua/modulesFunctionNoExport.lua +++ b/test/translation/lua/modulesFunctionNoExport.lua @@ -1,2 +1,2 @@ -publicFunc = function() +publicFunc = function(self) end; diff --git a/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua b/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua index 44509f50d..bde538a11 100644 --- a/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua +++ b/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua @@ -5,7 +5,7 @@ do TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {}; local TestNestedSpace = TestSpace.TestNestedSpace; do - TestNestedSpace.innerFunc = function() + TestNestedSpace.innerFunc = function(self) end; end end diff --git a/test/translation/lua/modulesNamespaceWithMemberExport.lua b/test/translation/lua/modulesNamespaceWithMemberExport.lua index 020bcf4d5..1e267f322 100644 --- a/test/translation/lua/modulesNamespaceWithMemberExport.lua +++ b/test/translation/lua/modulesNamespaceWithMemberExport.lua @@ -2,7 +2,7 @@ local exports = exports or {}; exports.TestSpace = exports.TestSpace or {}; local TestSpace = exports.TestSpace; do - TestSpace.innerFunc = function() + TestSpace.innerFunc = function(self) end; end return exports; diff --git a/test/translation/lua/modulesNamespaceWithMemberNoExport.lua b/test/translation/lua/modulesNamespaceWithMemberNoExport.lua index b0abeb433..bdbade0fe 100644 --- a/test/translation/lua/modulesNamespaceWithMemberNoExport.lua +++ b/test/translation/lua/modulesNamespaceWithMemberNoExport.lua @@ -3,7 +3,7 @@ exports.TestSpace = exports.TestSpace or {}; local TestSpace = exports.TestSpace; do local innerFunc; - innerFunc = function() + innerFunc = function(self) end; end return exports; diff --git a/test/translation/lua/namespace.lua b/test/translation/lua/namespace.lua index bdf6664fd..f59170157 100644 --- a/test/translation/lua/namespace.lua +++ b/test/translation/lua/namespace.lua @@ -1,6 +1,6 @@ myNamespace = myNamespace or {}; do local nsMember; - nsMember = function() + nsMember = function(self) end; end diff --git a/test/translation/lua/namespaceMerge.lua b/test/translation/lua/namespaceMerge.lua index 3c515447c..7bac3efb6 100644 --- a/test/translation/lua/namespaceMerge.lua +++ b/test/translation/lua/namespaceMerge.lua @@ -25,11 +25,11 @@ MergedClass.prototype.methodB = function(self) end; MergedClass = MergedClass or {}; do - MergedClass.namespaceFunc = function() + MergedClass.namespaceFunc = function(self) end; end local mergedClass = MergedClass.new(); mergedClass:methodB(); mergedClass:propertyFunc(); MergedClass:staticMethodB(); -MergedClass.namespaceFunc(); +MergedClass:namespaceFunc(); diff --git a/test/translation/lua/namespaceNested.lua b/test/translation/lua/namespaceNested.lua index dd1006ee9..e409f968e 100644 --- a/test/translation/lua/namespaceNested.lua +++ b/test/translation/lua/namespaceNested.lua @@ -4,7 +4,7 @@ do local myNestedNamespace = myNamespace.myNestedNamespace; do local nsMember; - nsMember = function() + nsMember = function(self) end; end end diff --git a/test/translation/lua/namespacePhantom.lua b/test/translation/lua/namespacePhantom.lua index 3844b51be..63de0e172 100644 --- a/test/translation/lua/namespacePhantom.lua +++ b/test/translation/lua/namespacePhantom.lua @@ -1,2 +1,2 @@ -nsMember = function() +nsMember = function(self) end; diff --git a/test/translation/lua/returnDefault.lua b/test/translation/lua/returnDefault.lua index a0e35c570..7b013615d 100644 --- a/test/translation/lua/returnDefault.lua +++ b/test/translation/lua/returnDefault.lua @@ -1,3 +1,3 @@ -myFunc = function() +myFunc = function(self) return; end; diff --git a/test/translation/lua/shorthandPropertyAssignment.lua b/test/translation/lua/shorthandPropertyAssignment.lua index 0c5898188..96a5da700 100644 --- a/test/translation/lua/shorthandPropertyAssignment.lua +++ b/test/translation/lua/shorthandPropertyAssignment.lua @@ -1,4 +1,4 @@ local f; -f = function(x) +f = function(____, x) return ({x = x}); end; diff --git a/test/translation/lua/tupleReturn.lua b/test/translation/lua/tupleReturn.lua index c8d492bec..bc81abc3f 100644 --- a/test/translation/lua/tupleReturn.lua +++ b/test/translation/lua/tupleReturn.lua @@ -1,28 +1,28 @@ -tupleReturn = function() +tupleReturn = function(self) return 0, "foobar"; end; -tupleReturn(); -noTupleReturn(); -local a, b = tupleReturn(); -local c, d = table.unpack(noTupleReturn()); -a, b = tupleReturn(); -c, d = table.unpack(noTupleReturn()); -local e = ({tupleReturn()}); -local f = noTupleReturn(); -e = ({tupleReturn()}); -f = noTupleReturn(); -foo(({tupleReturn()})); -foo(noTupleReturn()); -tupleReturnFromVar = function() +tupleReturn(_G); +noTupleReturn(_G); +local a, b = tupleReturn(_G); +local c, d = table.unpack(noTupleReturn(_G)); +a, b = tupleReturn(_G); +c, d = table.unpack(noTupleReturn(_G)); +local e = ({tupleReturn(_G)}); +local f = noTupleReturn(_G); +e = ({tupleReturn(_G)}); +f = noTupleReturn(_G); +foo(_G, ({tupleReturn(_G)})); +foo(_G, noTupleReturn(_G)); +tupleReturnFromVar = function(self) local r = {1, "baz"}; return table.unpack(r); end; -tupleReturnForward = function() - return tupleReturn(); +tupleReturnForward = function(self) + return tupleReturn(_G); end; -tupleNoForward = function() - return ({tupleReturn()}); +tupleNoForward = function(self) + return ({tupleReturn(_G)}); end; -tupleReturnUnpack = function() - return table.unpack(tupleNoForward()); +tupleReturnUnpack = function(self) + return table.unpack(tupleNoForward(_G)); end; diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index e146dac39..985ee4472 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -5,7 +5,7 @@ import * as util from "../src/util"; export class AssignmentDestructuringTests { private readonly assignmentDestruturingTs = ` - declare function myFunc(): [number, string]; + declare function myFunc(this: void): [number, string]; let [a, b] = myFunc();`; @Test("Assignment destructuring [5.1]") diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 8840018ed..257dc2b2d 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1,27 +1,385 @@ -import { Expect, Test, TestCase } from "alsatian"; +import { Expect, Test, TestCase, TestCases } from "alsatian"; import { TranspileError } from "../../src/TranspileError"; import * as util from "../src/util"; +import { TSTLErrors } from "../../src/TSTLErrors"; const fs = require("fs"); -export class AssignmentTests { +interface TestFunction { + value: string; + definition?: string; +} - public static readonly funcAssignTestCode = - `let func: {(s: string): string} = function(s) { return s + "+func"; }; - let lambda: (s: string) => string = s => s + "+lambda"; - let thisFunc: {(this: Foo, s: string): string} = function(s) { return s + "+thisFunc"; }; - let thisLambda: (this: Foo, s: string) => string = s => s + "+thisLambda"; - class Foo { - method(s: string): string { return s + "+method"; } - lambdaProp: (s: string) => string = s => s + "+lambdaProp"; - voidMethod(this: void, s: string): string { return s + "+voidMethod"; } - voidLambdaProp: (this: void, s: string) => string = s => s + "+voidLambdaProp"; - static voidStaticMethod(this: void, s: string): string { return s + "+voidStaticMethod"; } - static voidStaticLambdaProp: (this: void, s: string) => string = s => s + "+voidStaticLambdaProp"; - static staticMethod(s: string): string { return s + "+staticMethod"; } - static staticLambdaProp: (s: string) => string = s => s + "+staticLambdaProp"; - } - const foo = new Foo();`; +const selfTestFunctions: TestFunction[] = [ + { + value: "selfFunc", + definition: `let selfFunc: {(this: any, s: string): string} = function(s) { return s; };`, + }, + { + value: "selfLambda", + definition: `let selfLambda: (this: any, s: string) => string = s => s;`, + }, + { + value: "anonFunc", + definition: `let anonFunc: {(s: string): string} = function(s) { return s; };`, + }, + { + value: "anonLambda", + definition: `let anonLambda: (s: string) => string = s => s;`, + }, + { + value: "methodClass.method", + definition: `class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();`, + }, + { + value: "anonMethodClass.anonMethod", + definition: `class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();`, + }, + { + value: "funcPropClass.funcProp", + definition: `class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();`, + }, + { + value: "anonFuncPropClass.anonFuncProp", + definition: `class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();`, + }, + { + value: "StaticMethodClass.staticMethod", + definition: `class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }`, + }, + { + value: "AnonStaticMethodClass.anonStaticMethod", + definition: `class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }`, + }, + { + value: "StaticFuncPropClass.staticFuncProp", + definition: `class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }`, + }, + { + value: "AnonStaticFuncPropClass.anonStaticFuncProp", + definition: `class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }`, + }, + { + value: "FuncNs.nsFunc", + definition: `namespace FuncNs { export function nsFunc(s: string) { return s; } }`, + }, + { + value: "FuncNestedNs.NestedNs.nestedNsFunc", + definition: `namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }`, + }, + { + value: "LambdaNs.nsLambda", + definition: `namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "LambdaNestedNs.NestedNs.nestedNsLambda", + definition: `namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }`, + }, + { + value: "methodInterface.method", + definition: `interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, + }, + { + value: "anonMethodInterface.anonMethod", + definition: `interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };`, + }, + { + value: "funcPropInterface.funcProp", + definition: `interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };`, + }, + { + value: "anonFuncPropInterface.anonFuncProp", + definition: `interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };`, + }, + { + value: "anonMethodClassInNoSelfNs.method", + definition: `/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();`, + }, + { + value: "anonMethodInterfaceInNoSelfNs.method", + definition: `/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };`, + }, + { + value: "anonFunctionNestedInNoSelfClass", + definition: `/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();`, + }, +]; + +const noSelfTestFunctions: TestFunction[] = [ + { + value: "voidFunc", + definition: `let voidFunc: {(this: void, s: string): string} = function(s) { return s; };`, + }, + { + value: "voidLambda", + definition: `let voidLambda: (this: void, s: string) => string = s => s;`, + }, + { + value: "voidMethodClass.voidMethod", + definition: `class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();`, + }, + { + value: "voidFuncPropClass.voidFuncProp", + definition: `class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();`, + }, + { + value: "StaticVoidMethodClass.staticVoidMethod", + definition: `class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }`, + }, + { + value: "StaticVoidFuncPropClass.staticVoidFuncProp", + definition: `class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }`, + }, + { + value: "NoSelfFuncNs.noSelfNsFunc", + definition: `/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }`, + }, + { + value: "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc", + definition: `/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }`, + }, + { + value: "NoSelfLambdaNs.noSelfNsLambda", + definition: `/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda", + definition: `/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }`, + }, + { + value: "noSelfMethodClass.noSelfMethod", + definition: `/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();`, + }, + { + value: "NoSelfStaticMethodClass.noSelfStaticMethod", + definition: `/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }`, + }, + { + value: "noSelfFuncPropClass.noSelfFuncProp", + definition: `/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();`, + }, + { + value: "NoSelfStaticFuncPropClass.noSelfStaticFuncProp", + definition: `/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }`, + }, + { + value: "voidMethodInterface.voidMethod", + definition: `interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };`, + }, + { + value: "voidFuncPropInterface.voidFuncProp", + definition: `interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };`, + }, + { + value: "noSelfMethodInterface.noSelfMethod", + definition: `/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };`, + }, + { + value: "noSelfFuncPropInterface.noSelfFuncProp", + definition: `/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };`, + }, + { + value: "noSelfMethodClassExpression.noSelfMethod", + definition: `/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();`, + }, + { + value: "anonFunctionNestedInClassInNoSelfNs", + definition: `/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();`, + }, +]; + +const noSelfInFileTestFunctions: TestFunction[] = [ + { + value: "noSelfInFileFunc", + definition: `/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };`, + }, + { + value: "noSelfInFileLambda", + definition: `/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;`, + }, + { + value: "NoSelfInFileFuncNs.noSelfInFileNsFunc", + definition: `/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }`, + }, + { + value: "NoSelfInFileLambdaNs.noSelfInFileNsLambda", + definition: `/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "noSelfInFileFuncNestedInClass", + definition: `/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();`, + }, +]; + +const anonTestFunctionExpressions: TestFunction[] = [ + {value: `s => s`}, + {value: `(s => s)`}, + {value: `function(s) { return s; }`}, + {value: `(function(s) { return s; })`}, +]; + +const selfTestFunctionExpressions: TestFunction[] = [ + {value: `function(this: any, s) { return s; }`}, + {value: `(function(this: any, s) { return s; })`}, +]; + +const noSelfTestFunctionExpressions: TestFunction[] = [ + {value: `function(this: void, s) { return s; }`}, + {value: `(function(this: void, s) { return s; })`}, +]; + +const anonTestFunctionType = "(s: string) => string"; +const selfTestFunctionType = "(this: any, s: string) => string"; +const noSelfTestFunctionType = "(this: void, s: string) => string"; + +type TestFunctionCast = [ + /*testFunction: */TestFunction, + /*castedFunction: */string, + /*isSelfConversion?: */boolean? +]; +const validTestFunctionCasts: TestFunctionCast[] = [ + [selfTestFunctions[0], `<${anonTestFunctionType}>(${selfTestFunctions[0].value})`], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${anonTestFunctionType})`], + [selfTestFunctions[0], `<${selfTestFunctionType}>(${selfTestFunctions[0].value})`], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${selfTestFunctionType})`], + [noSelfTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfTestFunctions[0].value})`], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${noSelfTestFunctionType})`], + [noSelfInFileTestFunctions[0], `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`], + [noSelfInFileTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`], +]; +const invalidTestFunctionCasts: TestFunctionCast[] = [ + [noSelfTestFunctions[0], `<${anonTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, false], + [noSelfTestFunctions[0], `<${selfTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${selfTestFunctionType})`, false], + [noSelfInFileTestFunctions[0], `<${selfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, false], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${selfTestFunctionType})`, false], + [selfTestFunctions[0], `<${noSelfTestFunctionType}>(${selfTestFunctions[0].value})`, true], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${noSelfTestFunctionType})`, true], +]; + +type TestFunctionAssignment = [ + /*testFunction: */TestFunction, + /*functionType: */string, + /*isSelfConversion?: */boolean? +]; +const validTestFunctionAssignments: TestFunctionAssignment[] = [ + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), +]; +const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), +]; + +export class AssignmentTests { @TestCase(`"abc"`, `"abc"`) @TestCase("3", "3") @@ -101,7 +459,7 @@ export class AssignmentTests { @Test("TupleReturn assignment") public tupleReturnFunction(): void { const code = `/** @tupleReturn */\n` - + `declare function abc(): number[]\n` + + `declare function abc(this: void): number[]\n` + `let [a,b] = abc();`; const lua = util.transpileString(code); @@ -111,7 +469,7 @@ export class AssignmentTests { @Test("TupleReturn Single assignment") public tupleReturnSingleAssignment(): void { const code = `/** @tupleReturn */\n` - + `declare function abc(): [number, string];\n` + + `declare function abc(this: void): [number, string];\n` + `let a = abc();` + `a = abc();`; @@ -135,7 +493,7 @@ export class AssignmentTests { public tupleReturnNameSpace(): void { const code = `declare namespace def {\n` + `/** @tupleReturn */\n` - + `function abc() {}\n` + + `function abc(this: void) {}\n` + `}\n` + `let [a,b] = def.abc();`; @@ -204,518 +562,239 @@ export class AssignmentTests { .toThrowError(TranspileError, `Cannot use Lua keyword ${identifier} as identifier.`); } - @TestCase("func", "lambda", "foo+lambda") - @TestCase("func", "s => s", "foo") - @TestCase("func", "(s => s)", "foo") - @TestCase("func", "function(s) { return s; }", "foo") - @TestCase("func", "(function(s) { return s; })", "foo") - @TestCase("func", "function(this: void, s: string) { return s; }", "foo") - @TestCase("func", "s => foo.method(s)", "foo+method") - @TestCase("func", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("func", "Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("func", "Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("func", "foo.voidMethod", "foo+voidMethod") - @TestCase("func", "foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("lambda", "func", "foo+func") - @TestCase("lambda", "s => s", "foo") - @TestCase("lambda", "(s => s)", "foo") - @TestCase("lambda", "function(s) { return s; }", "foo") - @TestCase("lambda", "(function(s) { return s; })", "foo") - @TestCase("lambda", "function(this: void, s: string) { return s; }", "foo") - @TestCase("lambda", "s => foo.method(s)", "foo+method") - @TestCase("lambda", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("lambda", "Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("lambda", "Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("lambda", "foo.voidMethod", "foo+voidMethod") - @TestCase("lambda", "foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("Foo.voidStaticMethod", "func", "foo+func") - @TestCase("Foo.voidStaticMethod", "lambda", "foo+lambda") - @TestCase("Foo.voidStaticMethod", "s => s", "foo") - @TestCase("Foo.voidStaticMethod", "(s => s)", "foo") - @TestCase("Foo.voidStaticMethod", "function(s) { return s; }", "foo") - @TestCase("Foo.voidStaticMethod", "(function(s) { return s; })", "foo") - @TestCase("Foo.voidStaticMethod", "function(this: void, s: string) { return s; }", "foo") - @TestCase("Foo.voidStaticMethod", "s => foo.method(s)", "foo+method") - @TestCase("Foo.voidStaticMethod", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("Foo.voidStaticMethod", "Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("Foo.voidStaticMethod", "foo.voidMethod", "foo+voidMethod") - @TestCase("Foo.voidStaticMethod", "foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("Foo.voidStaticLambdaProp", "func", "foo+func") - @TestCase("Foo.voidStaticLambdaProp", "lambda", "foo+lambda") - @TestCase("Foo.voidStaticLambdaProp", "s => s", "foo") - @TestCase("Foo.voidStaticLambdaProp", "(s => s)", "foo") - @TestCase("Foo.voidStaticLambdaProp", "function(s) { return s; }", "foo") - @TestCase("Foo.voidStaticLambdaProp", "(function(s) { return s; })", "foo") - @TestCase("Foo.voidStaticLambdaProp", "function(this: void, s: string) { return s; }", "foo") - @TestCase("Foo.voidStaticLambdaProp", "s => foo.method(s)", "foo+method") - @TestCase("Foo.voidStaticLambdaProp", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("Foo.voidStaticLambdaProp", "Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("Foo.voidStaticLambdaProp", "foo.voidMethod", "foo+voidMethod") - @TestCase("Foo.voidStaticLambdaProp", "foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("foo.voidMethod", "func", "foo+func") - @TestCase("foo.voidMethod", "lambda", "foo+lambda") - @TestCase("foo.voidMethod", "s => s", "foo") - @TestCase("foo.voidMethod", "(s => s)", "foo") - @TestCase("foo.voidMethod", "function(s) { return s; }", "foo") - @TestCase("foo.voidMethod", "(function(s) { return s; })", "foo") - @TestCase("foo.voidMethod", "function(this: void, s: string) { return s; }", "foo") - @TestCase("foo.voidMethod", "s => foo.method(s)", "foo+method") - @TestCase("foo.voidMethod", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("foo.voidMethod", "Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("foo.voidMethod", "Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("foo.voidMethod", "foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("foo.voidLambdaProp", "func", "foo+func") - @TestCase("foo.voidLambdaProp", "lambda", "foo+lambda") - @TestCase("foo.voidLambdaProp", "s => s", "foo") - @TestCase("foo.voidLambdaProp", "(s => s)", "foo") - @TestCase("foo.voidLambdaProp", "function(s) { return s; }", "foo") - @TestCase("foo.voidLambdaProp", "(function(s) { return s; })", "foo") - @TestCase("foo.voidLambdaProp", "function(this: void, s: string) { return s; }", "foo") - @TestCase("foo.voidLambdaProp", "s => foo.method(s)", "foo+method") - @TestCase("foo.voidLambdaProp", "s => foo.lambdaProp(s)", "foo+lambdaProp") - @TestCase("foo.voidLambdaProp", "Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("foo.voidLambdaProp", "Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("foo.voidLambdaProp", "foo.voidMethod", "foo+voidMethod") - @TestCase("func", "<(s: string) => string>lambda", "foo+lambda") - @TestCase("func", "lambda as ((s: string) => string)", "foo+lambda") + @TestCases(validTestFunctionAssignments) + @Test("Valid function variable declaration") + public validFunctionDeclaration(testFunction: TestFunction, functionType: string): void { + const code = + `const fn: ${functionType} = ${testFunction.value}; + return fn("foobar");`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + } + + @TestCases(validTestFunctionAssignments) @Test("Valid function assignment") - public validFunctionAssignment(func: string, assignTo: string, expectResult: string): void { - const code = `${AssignmentTests.funcAssignTestCode} ${func} = ${assignTo}; return ${func}("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + public validFunctionAssignment(testFunction: TestFunction, functionType: string): void { + const code = + `let fn: ${functionType}; + fn = ${testFunction.value}; + return fn("foobar");`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("func", "foo+func") - @TestCase("lambda", "foo+lambda") - @TestCase("Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("foo.voidMethod", "foo+voidMethod") - @TestCase("foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("s => s", "foo") - @TestCase("(s => s)", "foo") - @TestCase("function(s) { return s; }", "foo") - @TestCase("(function(s) { return s; })", "foo") - @TestCase("function(this: void, s: string) { return s; }", "foo") - @TestCase("func", "foo+func", "string | ((s: string) => string)") - @TestCase("func", "foo+func", "T") - @TestCase("<(s: string) => string>func", "foo+func") - @TestCase("func as ((s: string) => string)", "foo+func") - @Test("Valid function argument") - public validFunctionArgument(func: string, expectResult: string, funcType?: string): void { - if (!funcType) { - funcType = "(s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function takesFunc string)>(fn: ${funcType}) { - return (fn as any)("foo"); - } - return takesFunc(${func});`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(invalidTestFunctionAssignments) + @Test("Invalid function variable declaration") + public invalidFunctionDeclaration(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) + : void + { + const code = + `${testFunction.definition || ""} + const fn: ${functionType} = ${testFunction.value};`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("s => s", "foo") - @TestCase("(s => s)", "foo") - @TestCase("function(s) { return s; }", "foo") - @TestCase("(function(s) { return s; })", "foo") - @TestCase("function(this: void, s: string) { return s; }", "foo") - @Test("Valid function expression argument with no signature") - public validFunctionExpressionArgumentNoSignature(func: string, expectResult: string): void { - const code = `${AssignmentTests.funcAssignTestCode} - const takesFunc: any = (fn: (s: string) => string) => { - return (fn as any)("foo"); - } - return takesFunc(${func});`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(invalidTestFunctionAssignments) + @Test("Invalid function assignment") + public invalidFunctionAssignment(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) + : void + { + const code = + `${testFunction.definition || ""} + let fn: ${functionType}; + fn = ${testFunction.value};`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("func", "foo+func") - @TestCase("lambda", "foo+lambda") - @TestCase("Foo.voidStaticMethod", "foo+voidStaticMethod") - @TestCase("Foo.voidStaticLambdaProp", "foo+voidStaticLambdaProp") - @TestCase("foo.voidMethod", "foo+voidMethod") - @TestCase("foo.voidLambdaProp", "foo+voidLambdaProp") - @TestCase("s => s", "foo") - @TestCase("(s => s)", "foo") - @TestCase("function(s) { return s; }", "foo") - @TestCase("(function(s) { return s; })", "foo") - @TestCase("function(this: void, s: string) { return s; }", "foo") - @TestCase("func", "foo+func", "string | ((s: string) => string)") - @TestCase("<(s: string) => string>func", "foo+func") - @TestCase("func as ((s: string) => string)", "foo+func") - @Test("Valid function return") - public validFunctionReturn(func: string, expectResult: string, funcType?: string): void { - if (!funcType) { - funcType = "(s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function returnsFunc(): ${funcType} { - return ${func}; - } - const fn = returnsFunc(); - return (fn as any)("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(validTestFunctionCasts) + @Test("Valid function assignment with cast") + public validFunctionAssignmentWithCast(testFunction: TestFunction, castedFunction: string): void { + const code = + `let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + return fn("foobar");`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("foo.method", "foo.lambdaProp", "foo+lambdaProp") - @TestCase("foo.method", "s => s", "foo") - @TestCase("foo.method", "function(s) { return s; }", "foo") - @TestCase("foo.method", "(function(s) { return s; })", "foo") - @TestCase("foo.method", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("foo.method", "s => func(s)", "foo+func") - @TestCase("foo.method", "s => lambda(s)", "foo+lambda") - @TestCase("foo.method", "Foo.staticMethod", "foo+staticMethod") - @TestCase("foo.method", "Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("foo.method", "thisFunc", "foo+thisFunc") - @TestCase("foo.method", "thisLambda", "foo+thisLambda") - @TestCase("foo.lambdaProp", "foo.method", "foo+method") - @TestCase("foo.lambdaProp", "s => s", "foo") - @TestCase("foo.lambdaProp", "(s => s)", "foo") - @TestCase("foo.lambdaProp", "function(s) { return s; }", "foo") - @TestCase("foo.lambdaProp", "(function(s) { return s; })", "foo") - @TestCase("foo.lambdaProp", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("foo.lambdaProp", "s => func(s)", "foo+func") - @TestCase("foo.lambdaProp", "s => lambda(s)", "foo+lambda") - @TestCase("foo.lambdaProp", "Foo.staticMethod", "foo+staticMethod") - @TestCase("foo.lambdaProp", "Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("foo.lambdaProp", "thisFunc", "foo+thisFunc") - @TestCase("foo.lambdaProp", "thisLambda", "foo+thisLambda") - @TestCase("Foo.staticMethod", "foo.method", "foo+method") - @TestCase("Foo.staticMethod", "foo.lambdaProp", "foo+lambdaProp") - @TestCase("Foo.staticMethod", "s => s", "foo") - @TestCase("Foo.staticMethod", "(s => s)", "foo") - @TestCase("Foo.staticMethod", "function(s) { return s; }", "foo") - @TestCase("Foo.staticMethod", "(function(s) { return s; })", "foo") - @TestCase("Foo.staticMethod", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("Foo.staticMethod", "s => func(s)", "foo+func") - @TestCase("Foo.staticMethod", "s => lambda(s)", "foo+lambda") - @TestCase("Foo.staticMethod", "Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("Foo.staticMethod", "thisFunc", "foo+thisFunc") - @TestCase("Foo.staticMethod", "thisLambda", "foo+thisLambda") - @TestCase("Foo.staticLambdaProp", "foo.method", "foo+method") - @TestCase("Foo.staticLambdaProp", "foo.lambdaProp", "foo+lambdaProp") - @TestCase("Foo.staticLambdaProp", "s => s", "foo") - @TestCase("Foo.staticLambdaProp", "(s => s)", "foo") - @TestCase("Foo.staticLambdaProp", "function(s) { return s; }", "foo") - @TestCase("Foo.staticLambdaProp", "(function(s) { return s; })", "foo") - @TestCase("Foo.staticLambdaProp", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("Foo.staticLambdaProp", "s => func(s)", "foo+func") - @TestCase("Foo.staticLambdaProp", "s => lambda(s)", "foo+lambda") - @TestCase("Foo.staticLambdaProp", "Foo.staticMethod", "foo+staticMethod") - @TestCase("Foo.staticLambdaProp", "thisFunc", "foo+thisFunc") - @TestCase("Foo.staticLambdaProp", "thisLambda", "foo+thisLambda") - @TestCase("thisFunc", "foo.method", "foo+method") - @TestCase("thisFunc", "foo.lambdaProp", "foo+lambdaProp") - @TestCase("thisFunc", "s => s", "foo") - @TestCase("thisFunc", "(s => s)", "foo") - @TestCase("thisFunc", "function(s) { return s; }", "foo") - @TestCase("thisFunc", "(function(s) { return s; })", "foo") - @TestCase("thisFunc", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("thisFunc", "s => func(s)", "foo+func") - @TestCase("thisFunc", "s => lambda(s)", "foo+lambda") - @TestCase("thisFunc", "Foo.staticMethod", "foo+staticMethod") - @TestCase("thisFunc", "Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("thisFunc", "thisLambda", "foo+thisLambda") - @TestCase("thisLambda", "foo.method", "foo+method") - @TestCase("thisLambda", "foo.lambdaProp", "foo+lambdaProp") - @TestCase("thisLambda", "s => s", "foo") - @TestCase("thisLambda", "(s => s)", "foo") - @TestCase("thisLambda", "function(s) { return s; }", "foo") - @TestCase("thisLambda", "(function(s) { return s; })", "foo") - @TestCase("thisLambda", "function(this: Foo, s: string) { return s; }", "foo") - @TestCase("thisLambda", "s => func(s)", "foo+func") - @TestCase("thisLambda", "s => lambda(s)", "foo+lambda") - @TestCase("thisLambda", "Foo.staticMethod", "foo+staticMethod") - @TestCase("thisLambda", "Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("thisLambda", "thisFunc", "foo+thisFunc") - @TestCase("foo.method", "<(this: Foo, s: string) => string>foo.lambdaProp", "foo+lambdaProp") - @TestCase("foo.method", "foo.lambdaProp as ((this: Foo, s: string) => string)", "foo+lambdaProp") - @Test("Valid method assignment") - public validMethodAssignment(func: string, assignTo: string, expectResult: string): void { - const code = `${AssignmentTests.funcAssignTestCode} - ${func} = ${assignTo}; - foo.method = ${func}; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(invalidTestFunctionCasts) + @Test("Invalid function assignment with cast") + public invalidFunctionAssignmentWithCast( + testFunction: TestFunction, + castedFunction: string, + isSelfConversion: boolean + ): void { + const code = + `${testFunction.definition || ""} + let fn: typeof ${testFunction.value}; + fn = ${castedFunction};`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("foo.method", "foo+method") - @TestCase("foo.lambdaProp", "foo+lambdaProp") - @TestCase("Foo.staticMethod", "foo+staticMethod") - @TestCase("Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("thisFunc", "foo+thisFunc") - @TestCase("thisLambda", "foo+thisLambda") - @TestCase("s => s", "foo") - @TestCase("(s => s)", "foo") - @TestCase("function(s) { return s; }", "foo") - @TestCase("(function(s) { return s; })", "foo") - @TestCase("function(this: Foo, s: string) { return s; }", "foo") - @TestCase("foo.method", "foo+method", "string | ((this: Foo, s: string) => string)") - @TestCase("foo.method", "foo+method", "T") - @TestCase("<(this: Foo, s: string) => string>foo.method", "foo+method") - @TestCase("foo.method as ((this: Foo, s: string) => string)", "foo+method") - @Test("Valid method argument") - public validMethodArgument(func: string, expectResult: string, funcType?: string): void { - if (!funcType) { - funcType = "(this: Foo, s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function takesMethod string)>(meth: ${funcType}) { - foo.method = meth as any; - } - takesMethod(${func}); - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(validTestFunctionAssignments) + @Test("Valid function argument") + public validFunctionArgument(testFunction: TestFunction, functionType: string): void { + const code = + `function takesFunction(fn: ${functionType}) { + return fn("foobar"); + } + return takesFunction(${testFunction.value});`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("foo.method", "foo+method") - @TestCase("foo.lambdaProp", "foo+lambdaProp") - @TestCase("Foo.staticMethod", "foo+staticMethod") - @TestCase("Foo.staticLambdaProp", "foo+staticLambdaProp") - @TestCase("thisFunc", "foo+thisFunc") - @TestCase("thisLambda", "foo+thisLambda") - @TestCase("s => s", "foo") - @TestCase("(s => s)", "foo") - @TestCase("function(s) { return s; }", "foo") - @TestCase("(function(s) { return s; })", "foo") - @TestCase("function(this: Foo, s: string) { return s; }", "foo") - @TestCase("foo.method", "foo+method", "string | ((this: Foo, s: string) => string)") - @TestCase("<(this: Foo, s: string) => string>foo.method", "foo+method") - @TestCase("foo.method as ((this: Foo, s: string) => string)", "foo+method") - @Test("Valid method return") - public validMethodReturn(func: string, expectResult: string, funcType?: string): void { - if (!funcType) { - funcType = "(this: Foo, s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function returnMethod(): ${funcType} { - return ${func}; - } - foo.method = returnMethod() as any; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); + @TestCases(invalidTestFunctionAssignments) + @Test("Invalid function argument") + public invalidFunctionArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) + : void + { + const code = + `${testFunction.definition || ""} + declare function takesFunction(fn: ${functionType}); + takesFunction(${testFunction.value});`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("func", "foo.method") - @TestCase("func", "foo.lambdaProp") - @TestCase("func", "Foo.staticMethod") - @TestCase("func", "Foo.staticLambdaProp") - @TestCase("func", "function(this: Foo, s: string) { return s; }") - @TestCase("lambda", "foo.method") - @TestCase("lambda", "foo.lambdaProp") - @TestCase("lambda", "Foo.staticMethod") - @TestCase("lambda", "Foo.staticLambdaProp") - @TestCase("lambda", "function(this: Foo, s: string) { return s; }") - @TestCase("foo.voidMethod", "foo.method") - @TestCase("foo.voidMethod", "foo.lambdaProp") - @TestCase("foo.voidMethod", "Foo.staticMethod") - @TestCase("foo.voidMethod", "Foo.staticLambdaProp") - @TestCase("foo.voidMethod", "function(this: Foo, s: string) { return s; }") - @TestCase("foo.voidLambdaProp", "foo.method") - @TestCase("foo.voidLambdaProp", "foo.lambdaProp") - @TestCase("foo.voidLambdaProp", "Foo.staticMethod") - @TestCase("foo.voidLambdaProp", "Foo.staticLambdaProp") - @TestCase("foo.voidLambdaProp", "function(this: Foo, s: string) { return s; }") - @TestCase("Foo.voidStaticMethod", "foo.method") - @TestCase("Foo.voidStaticMethod", "foo.lambdaProp") - @TestCase("Foo.voidStaticMethod", "Foo.staticMethod") - @TestCase("Foo.voidStaticMethod", "Foo.staticLambdaProp") - @TestCase("Foo.voidStaticMethod", "function(this: Foo, s: string) { return s; }") - @TestCase("Foo.voidStaticLambdaProp", "foo.method") - @TestCase("Foo.voidStaticLambdaProp", "foo.lambdaProp") - @TestCase("Foo.voidStaticLambdaProp", "Foo.staticMethod") - @TestCase("Foo.voidStaticLambdaProp", "Foo.staticLambdaProp") - @TestCase("Foo.voidStaticLambdaProp", "function(this: Foo, s: string) { return s; }") - @TestCase("func", "(foo.method as (string | ((this: Foo, s: string) => string)))") - @TestCase("func", "<(s: string) => string>foo.method") - @TestCase("func", "foo.method as ((s: string) => string)") - @Test("Invalid function assignment") - public invalidFunctionAssignment(func: string, assignTo: string): void { - const code = `${AssignmentTests.funcAssignTestCode} ${func} = ${assignTo};`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from method to function. To fix, wrap the method in an arrow function."); + @TestCases(validTestFunctionCasts) + @Test("Valid function argument with cast") + public validFunctionArgumentWithCast(testFunction: TestFunction, castedFunction: string): void { + const code = + `function takesFunction(fn: typeof ${testFunction.value}) { + return fn("foobar"); + } + return takesFunction(${castedFunction});`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("foo.method") - @TestCase("foo.lambdaProp") - @TestCase("Foo.staticMethod") - @TestCase("Foo.staticLambdaProp") - @TestCase("thisFunc") - @TestCase("thisLambda") - @TestCase("function(this: Foo, s: string) { return s; }") - @TestCase("foo.method", "string | ((s: string) => string)") - @TestCase("foo.method", "T") - @Test("Invalid function argument") - public invalidFunctionArgument(func: string, funcType?: string): void { - if (!funcType) { - funcType = "(s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - declare function takesFunc string)>(fn: ${funcType}); - takesFunc(${func});`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from method to function \"fn\". To fix, wrap the method in an arrow function."); + @TestCases(invalidTestFunctionCasts) + @Test("Invalid function argument with cast") + public invalidFunctionArgumentWithCast( + testFunction: TestFunction, + castedFunction: string, + isSelfConversion: boolean + ): void + { + const code = + `${testFunction.definition || ""} + declare function takesFunction(fn: typeof ${testFunction.value}); + takesFunction(${castedFunction});`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("<(s: string) => string>foo.method") - @TestCase("foo.method as ((s: string) => string)") - @Test("Invalid function argument cast") - public invalidFunctionArgumentCast(func: string): void { - const code = `${AssignmentTests.funcAssignTestCode} - declare function takesFunc string)>(fn: (s: string) => string); - takesFunc(${func});`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from method to function. To fix, wrap the method in an arrow function."); + // TODO: Fix function expression inference with generic types. The following should work, but doesn't: + // function takesFunction string>(fn: T) { ... } + // takesFunction(s => s); // Error: cannot convert method to function + // @TestCases(validTestFunctionAssignments) // Use this instead of other TestCases when fixed + @TestCases(selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType])) + @TestCases(selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType])) + @TestCases(noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType])) + @TestCases(selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType])) + @TestCases(selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType])) + @TestCases(noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType])) + @Test("Valid function generic argument") + public validFunctionGenericArgument(testFunction: TestFunction, functionType: string): void { + const code = + `function takesFunction(fn: T) { + return fn("foobar"); + } + return takesFunction(${testFunction.value});`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("foo.method") - @TestCase("foo.lambdaProp") - @TestCase("Foo.staticMethod") - @TestCase("Foo.staticLambdaProp") - @TestCase("thisFunc") - @TestCase("thisLambda") - @TestCase("function(this: Foo, s: string) { return s; }") - @TestCase("foo.method", "string | ((s: string) => string)") - @TestCase("foo.method", "T") - @TestCase("<(s: string) => string>foo.method") - @TestCase("foo.method as ((s: string) => string)") - @Test("Invalid function return") - public invalidFunctionReturn(func: string, funcType?: string): void { - if (!funcType) { - funcType = "(s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function returnsFunc string)>(): ${funcType} { - return ${func}; - }`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from method to function. To fix, wrap the method in an arrow function."); + @TestCases(invalidTestFunctionAssignments) + @Test("Invalid function generic argument") + public invalidFunctionGenericArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) + : void + { + const code = + `${testFunction.definition || ""} + declare function takesFunction(fn: T); + takesFunction(${testFunction.value});`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("foo.method", "func") - @TestCase("foo.method", "lambda") - @TestCase("foo.method", "Foo.voidStaticMethod") - @TestCase("foo.method", "Foo.voidStaticLambdaProp") - @TestCase("foo.method", "foo.voidMethod") - @TestCase("foo.method", "foo.voidLambdaProp") - @TestCase("foo.method", "function(this: void, s: string) { return s; }") - @TestCase("foo.lambdaProp", "func") - @TestCase("foo.lambdaProp", "lambda") - @TestCase("foo.lambdaProp", "Foo.voidStaticMethod") - @TestCase("foo.lambdaProp", "Foo.voidStaticLambdaProp") - @TestCase("foo.lambdaProp", "foo.voidMethod") - @TestCase("foo.lambdaProp", "foo.voidLambdaProp") - @TestCase("foo.lambdaProp", "function(this: void, s: string) { return s; }") - @TestCase("Foo.staticMethod", "func") - @TestCase("Foo.staticMethod", "lambda") - @TestCase("Foo.staticMethod", "Foo.voidStaticMethod") - @TestCase("Foo.staticMethod", "Foo.voidStaticLambdaProp") - @TestCase("Foo.staticMethod", "foo.voidMethod") - @TestCase("Foo.staticMethod", "foo.voidLambdaProp") - @TestCase("Foo.staticMethod", "function(this: void, s: string) { return s; }") - @TestCase("Foo.staticLambdaProp", "func") - @TestCase("Foo.staticLambdaProp", "lambda") - @TestCase("Foo.staticLambdaProp", "Foo.voidStaticMethod") - @TestCase("Foo.staticLambdaProp", "Foo.voidStaticLambdaProp") - @TestCase("Foo.staticLambdaProp", "foo.voidMethod") - @TestCase("Foo.staticLambdaProp", "foo.voidLambdaProp") - @TestCase("Foo.staticLambdaProp", "function(this: void, s: string) { return s; }") - @TestCase("thisFunc", "func") - @TestCase("thisFunc", "lambda") - @TestCase("thisFunc", "Foo.voidStaticMethod") - @TestCase("thisFunc", "Foo.voidStaticLambdaProp") - @TestCase("thisFunc", "foo.voidMethod") - @TestCase("thisFunc", "foo.voidLambdaProp") - @TestCase("thisFunc", "function(this: void, s: string) { return s; }") - @TestCase("thisLambda", "func") - @TestCase("thisLambda", "lambda") - @TestCase("thisLambda", "Foo.voidStaticMethod") - @TestCase("thisLambda", "Foo.voidStaticLambdaProp") - @TestCase("thisLambda", "foo.voidMethod") - @TestCase("thisLambda", "foo.voidLambdaProp") - @TestCase("thisLambda", "function(this: void, s: string) { return s; }") - @TestCase("foo.method", "(func as string | ((s: string) => string))") - @TestCase("foo.method", "<(this: Foo, s: string) => string>func") - @TestCase("foo.method", "func as ((this: Foo, s: string) => string)") - @Test("Invalid method assignment") - public invalidMethodAssignment(func: string, assignTo: string): void { - const code = `${AssignmentTests.funcAssignTestCode} ${func} = ${assignTo};`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from function to method. To fix, wrap the function in an arrow function or declare" - + " the function with an explicit 'this' parameter."); + @TestCases(anonTestFunctionExpressions.map(f => [f, "0", "'foobar'"])) + @TestCases(selfTestFunctionExpressions.map(f => [f, "0", "'foobar'"])) + @TestCases(noSelfTestFunctionExpressions.map(f => [f, "'foobar'"])) + @Test("Valid function expression argument with no signature") + public validFunctionExpressionArgumentNoSignature(testFunction: TestFunction, ...args: string[]): void { + const code = + `const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { + return fn(...args); + } + return takesFunction(${testFunction.value}, ${args.join(", ")});`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("func") - @TestCase("lambda") - @TestCase("Foo.voidStaticMethod") - @TestCase("Foo.voidStaticLambdaProp") - @TestCase("foo.voidMethod") - @TestCase("foo.voidLambdaProp") - @TestCase("function(this: void, s: string) { return s; }") - @TestCase("func", "string | ((this: Foo, s: string) => string)") - @TestCase("func", "T") - @Test("Invalid method argument") - public invalidMethodArgument(func: string, funcType?: string): void { - if (!funcType) { - funcType = "(this: Foo, s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - declare function takesMethod string)>(meth: ${funcType}); - takesMethod(${func});`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from function to method \"meth\". To fix, wrap the function in an arrow function " - + "or declare the function with an explicit 'this' parameter."); + @TestCases(validTestFunctionAssignments) + @Test("Valid function return") + public validFunctionReturn(testFunction: TestFunction, functionType: string): void { + const code = + `function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + const fn = returnsFunction(); + return fn("foobar");`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); } - @TestCase("<(this: Foo, s: string) => string>func") - @TestCase("func as ((this: Foo, s: string) => string)") - @Test("Invalid method argument cast") - public invalidMethodArgumentCast(func: string): void { - const code = `${AssignmentTests.funcAssignTestCode} - declare function takesMethod string)>( - meth: (this: Foo, s: string) => string); - takesMethod(${func});`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from function to method. To fix, wrap the function in an arrow function " - + "or declare the function with an explicit 'this' parameter."); + @TestCases(invalidTestFunctionAssignments) + @Test("Invalid function return") + public invalidFunctionReturn(testFunction: TestFunction, functionType: string, isSelfConversion: boolean): void { + const code = + `${testFunction.definition || ""} + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + }`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } - @TestCase("func") - @TestCase("lambda") - @TestCase("Foo.voidStaticMethod") - @TestCase("Foo.voidStaticLambdaProp") - @TestCase("foo.voidMethod") - @TestCase("foo.voidLambdaProp") - @TestCase("function(this: void, s: string) { return s; }") - @TestCase("func", "string | ((this: Foo, s: string) => string)") - @TestCase("func", "T") - @TestCase("<(this: Foo, s: string) => string>func") - @TestCase("func as ((this: Foo, s: string) => string)") - @Test("Invalid method return") - public invalidMethodReturn(func: string, funcType?: string): void { - if (!funcType) { - funcType = "(this: Foo, s: string) => string"; - } - const code = `${AssignmentTests.funcAssignTestCode} - function returnsMethod string)>(): ${funcType} { - return ${func}; - }`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Unsupported conversion from function to method. To fix, wrap the function in an arrow function " - + "or declare the function with an explicit 'this' parameter."); + @TestCases(validTestFunctionCasts) + @Test("Valid function return with cast") + public validFunctionReturnWithCast(testFunction: TestFunction, castedFunction: string): void { + const code = + `function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + const fn = returnsFunction(); + return fn("foobar");`; + Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + } + + @TestCases(invalidTestFunctionCasts) + @Test("Invalid function return with cast") + public invalidFunctionReturnWithCast( + testFunction: TestFunction, + castedFunction: string, + isSelfConversion: boolean + ): void + { + const code = + `${testFunction.definition || ""} + function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + }`; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } @Test("Interface method assignment") @@ -736,7 +815,7 @@ export class AssignmentTests { @Test("Valid function tuple assignment") public validFunctionTupleAssignment(): void { - const code = `interface Func { (s: string): string; } + const code = `interface Func { (this: void, s: string): string; } function getTuple(): [number, Func] { return [1, s => s]; } let [i, f]: [number, Func] = getTuple(); return f("foo");`; @@ -746,13 +825,14 @@ export class AssignmentTests { @Test("Invalid function tuple assignment") public invalidFunctionTupleAssignment(): void { - const code = `interface Func { (s: string): string; } + const code = `interface Func { (this: void, s: string): string; } interface Meth { (this: {}, s: string): string; } declare function getTuple(): [number, Meth]; let [i, f]: [number, Func] = getTuple();`; Expect(() => util.transpileString(code)).toThrowError( TranspileError, - "Unsupported conversion from method to function. To fix, wrap the method in an arrow function."); + TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined).message + ); } @Test("Valid method tuple assignment") @@ -770,14 +850,14 @@ export class AssignmentTests { @Test("Invalid method tuple assignment") public invalidMethodTupleAssignment(): void { - const code = `interface Func { (s: string): string; } + const code = `interface Func { (this: void, s: string): string; } interface Meth { (this: {}, s: string): string; } declare function getTuple(): [number, Func]; let [i, f]: [number, Meth] = getTuple();`; Expect(() => util.transpileString(code)).toThrowError( TranspileError, - "Unsupported conversion from function to method. To fix, wrap the function in an arrow function or declare" - + " the function with an explicit 'this' parameter."); + TSTLErrors.UnsupportedSelfFunctionConversion(undefined).message + ); } @Test("Valid interface method assignment") @@ -799,13 +879,14 @@ export class AssignmentTests { const b: B = a;`; Expect(() => util.transpileString(code)).toThrowError( TranspileError, - "Unsupported conversion from method to function \"fn\". To fix, wrap the method in an arrow function."); + TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn").message + ); } - @TestCase("(s: string) => string", ["foo"], "foobar") - @TestCase("{(s: string): string}", ["foo"], "foobar") - @TestCase("(s1: string, s2: string) => string", ["foo", "baz"], "foobaz") - @TestCase("{(s1: string, s2: string): string}", ["foo", "baz"], "foobaz") + @TestCase("(this: any, s: string) => string", ["foo"], "foobar") + @TestCase("{(this: any, s: string): string}", ["foo"], "foobar") + @TestCase("(this: any, s1: string, s2: string) => string", ["foo", "baz"], "foobaz") + @TestCase("{(this: any, s1: string, s2: string): string}", ["foo", "baz"], "foobaz") @Test("Valid function overload assignment") public validFunctionOverloadAssignment(assignType: string, args: string[], expectResult: string): void { const code = `interface O { @@ -819,22 +900,39 @@ export class AssignmentTests { Expect(result).toBe(expectResult); } - @TestCase("(s: string) => string") - @TestCase("(s1: string, s2: string) => string") - @TestCase("{(s: string): string}") - @TestCase("{(this: {}, s1: string, s2: string): string}") + @TestCase("(this: void, s: string) => string") + @TestCase("(this: void, s1: string, s2: string) => string") + @TestCase("{(this: void, s: string): string}") + @TestCase("{(this: any, s1: string, s2: string): string}") @Test("Invalid function overload assignment") public invalidFunctionOverloadAssignment(assignType: string): void { const code = `interface O { - (this: {}, s1: string, s2: string): string; - (s: string): string; + (this: any, s1: string, s2: string): string; + (this: void, s: string): string; } declare const o: O; let f: ${assignType} = o;`; Expect(() => util.transpileString(code)).toThrowError( TranspileError, - "Unsupported assignment of mixed function/method overload. " - + "Overloads should either be all functions or all methods, but not both."); + TSTLErrors.UnsupportedOverloadAssignment(undefined).message + ); + } + + @TestCase("noSelf") + @TestCase("noSelfInFile") + @Test("noSelf function method argument") + public noSelfFunctionMethodArgument(noSelfTag: string): void { + const header = + `/** @${noSelfTag} */ namespace NS { + export class C { + method(fn: (s: string) => string) { return fn("foo"); } + } + } + function foo(this: void, s: string) { return s; }`; + const code = + `const c = new NS.C(); + return c.method(foo);`; + Expect(util.transpileAndExecute(code, undefined, undefined, header, false)).toBe("foo"); } @TestCase("(this: void, s: string) => string") diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts index ae7531aba..12bb8d8d6 100644 --- a/test/unit/declarations.spec.ts +++ b/test/unit/declarations.spec.ts @@ -8,7 +8,7 @@ export class DeclarationTests // Arrange const libLua = `function declaredFunction(x) return 3*x end`; - const tsHeader = `declare function declaredFunction(x: number): number;`; + const tsHeader = `declare function declaredFunction(this: void, x: number): number;`; const source = `return declaredFunction(2) + 4;`; @@ -26,7 +26,7 @@ export class DeclarationTests const tsHeader = ` /** @tupleReturn */ - declare function declaredFunction(x: number): [number, number];`; + declare function declaredFunction(this: void, x: number): [number, number];`; const source = ` const tuple = declaredFunction(3); @@ -48,7 +48,7 @@ export class DeclarationTests function myNameSpace.declaredFunction(x) return 3*x end `; - const tsHeader = `declare namespace myNameSpace { function declaredFunction(x: number): number; }`; + const tsHeader = `declare namespace myNameSpace { function declaredFunction(this: void, x: number): number; }`; const source = `return myNameSpace.declaredFunction(2) + 4;`; @@ -87,7 +87,8 @@ export class DeclarationTests public declarationFunctionCallback(): void { // Arrange const libLua = `function declaredFunction(callback) return callback(4) end`; - const tsHeader = `declare function declaredFunction(callback: (x: number) => number): number;`; + const tsHeader = + `declare function declaredFunction(this: void, callback: (this: void, x: number) => number): number;`; const source = `return declaredFunction(x => 2 * x);`; @@ -108,7 +109,7 @@ export class DeclarationTests const tsHeader = `declare interface MyInterface { - declaredFunction(callback: (x: number) => number): number; + declaredFunction(callback: (this: void, x: number) => number): number; } declare var myInstance: MyInterface;`; diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index bb5c7f51e..59b4f4418 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -401,7 +401,7 @@ export class LuaLibTests return JSONStringify(testArray)`, undefined, undefined, - `declare function tonumber(e: any): number` + `declare function tonumber(this: void, e: any): number` ); // Assert diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index f5a6ad416..606e39985 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -64,4 +64,15 @@ export class LuaModuleTests { }`; Expect(util.transpileAndExecute("return a.b.foo;", undefined, undefined, code)).toBe("foo"); } + + @Test("Access this in module") + public accessThisInModule(): void { + const header = + `module M { + export const foo = "foo"; + export function bar() { return this.foo + "bar"; } + }`; + const code = `return M.bar();`; + Expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); + } } diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 2d50879ba..e3858fae6 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -9,7 +9,7 @@ export class ObjectLiteralTests { @TestCase(`{"a":3,b:"4"}`, `{a = 3, b = "4"};`) @TestCase(`{["a"]:3,b:"4"}`, `{a = 3, b = "4"};`) @TestCase(`{["a"+123]:3,b:"4"}`, `{["a" .. 123] = 3, b = "4"};`) - @TestCase(`{[myFunc()]:3,b:"4"}`, `{[myFunc()] = 3, b = "4"};`) + @TestCase(`{[myFunc()]:3,b:"4"}`, `{[myFunc(_G)] = 3, b = "4"};`) @TestCase(`{x}`, `{x = x};`) @Test("Object Literal") public objectLiteral(inp: string, out: string): void { From a0af198058b015cd17dc55e7758bc02fa47732a3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 15 Mar 2019 23:42:52 +0100 Subject: [PATCH 027/764] 0.16.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 420d71821..5f75bfb94 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.15.2", + "version": "0.16.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 200f4f278..d899895d5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typescript-to-lua", "license": "MIT", - "version": "0.15.2", + "version": "0.16.0", "repository": "https://github.com/Perryvw/TypescriptToLua", "keywords": [ "typescript", From 0c1e17aab343c02b4a5ba812dbcb01dbb0397e21 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 15 Mar 2019 23:53:58 +0100 Subject: [PATCH 028/764] Update CHANGELOG.md --- CHANGELOG.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f4e33325..acae64ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,54 @@ # Changelog +## 0.16.0 +* **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument. + * To remove the self parameter from a single function add `this: void` to its declaration: + ```declare function foo(this: void, ...)``` + * To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`: + ```/** @noSelf */ interface Foo {``` + * To remove the self parameter from all functions in a file, add `/** @noSelfInFile */` at the top. +* Fixed a bug breaking named class expressions. +* Fixed inconsistency between the meaning of `>>` and `>>>` in JS vs. Lua. +* Added `/** @noResolution */` directive to prevent path resolution on declared modules. +* It is now possible to put `/** @luaIterator */` on types extending `Array`. +* Fixed issue with the moment static fields were initialized. +* Fixed issue where `undefined` as property name was not transpiled correctly. +* Various improvements to function/method self parameter inference. +* Tstl options can now be defined in their own `tstl` block in tsconfig.json. For example: +``` +{ + "compilerOptions" : {} + "tstl": { + "luaTarget": "JIT" + } +} +``` +* Fixed issue when redeclaring TypeScript libraries/globals. +* Fixed exception resolving function signatures. +* Added support for automatically transpiling several `console` calls to their Lua equivalent: + * `console.log(...)` -> `print(...)` + * `console.assert(...)` -> `assert(...)` + * `console.trace(...)` -> `print(debug.traceback(...))` +* Added support for `array.findIndex()`. +* Fixed `array.sort()` not working with a compare function. +* Added support for several common `Math.` functions and constants. +* Added support for several common string instance functions such as `upper()`. + +## 0.15.2 +* Several improvements to module path resolution. +* Removed header comment appearing in lualib. +* Several package config improvements. +* Static get/set accessors. + +## 0.15.1 +* Fixed array detection for unit and intersection types. +* Support for import without `from`. +* Added support for `WeakMap` and `WeakSet`. +* Added support for `Object.keys` and `Object.assign`. +* Added support for importing JSON files. +* Fixed bug with where loop variables were not properly scoped. +* Added support for ExportDeclarations + ## 0.15.0 * Now written for TypeScript 3.3.x! * Removed external CLI parser dependency and wrote our own `CommandLineParser.ts` to read CLI and tsconfig input. From 478f0054641ad89a78d98f06e4116e1ea92dc634 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 15 Mar 2019 23:58:42 +0100 Subject: [PATCH 029/764] Updated codecov --- package-lock.json | 423 +++++++++------------------------------------- package.json | 2 +- 2 files changed, 80 insertions(+), 345 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5f75bfb94..0c0f148f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -185,16 +185,13 @@ "integrity": "sha512-d2SJJpwkiPudEQ3+9ysANN2Nvz4QJKUPoe/WL5zyQzI0RaEeZWH5K5xjvUIGszTItHQpFPdH+u51f6G/LkS8Cg==", "dev": true }, - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "es6-promisify": "^5.0.0" } }, "alsatian": { @@ -243,36 +240,6 @@ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", - "dev": true - }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", @@ -290,16 +257,6 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -322,12 +279,6 @@ "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -341,21 +292,29 @@ "supports-color": "^2.0.0" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, "codecov": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.0.2.tgz", - "integrity": "sha512-9ljtIROIjPIUmMRqO+XuDITDoV8xRrZmA0jcEq6p2hg2+wY9wGmLfreAZGIL72IzUfdEDZaU8+Vjidg1fBQ8GQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.2.0.tgz", + "integrity": "sha512-3NJvNARXxilqnqVfgzDHyVrF4oeVgaYW1c1O6Oi5mn93exE7HTSSFNiYdwojWW6IwrCZABJ8crpNbKoo9aUHQw==", "dev": true, "requires": { - "argv": "0.0.2", - "request": "^2.81.0", - "urlgrey": "0.4.4" + "argv": "^0.0.2", + "ignore-walk": "^3.0.1", + "js-yaml": "^3.12.0", + "teeny-request": "^3.7.0", + "urlgrey": "^0.4.4" + }, + "dependencies": { + "js-yaml": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } } }, "color-convert": { @@ -373,15 +332,6 @@ "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", "dev": true }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "commander": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", @@ -400,15 +350,6 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -424,12 +365,6 @@ "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", "dev": true }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, "diff": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", @@ -442,14 +377,19 @@ "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", "dev": true }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "es6-promise": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", + "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, - "optional": true, "requires": { - "jsbn": "~0.1.0" + "es6-promise": "^4.0.3" } }, "escape-string-regexp": { @@ -482,36 +422,12 @@ "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, "extendo-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/extendo-error/-/extendo-error-1.0.1.tgz", "integrity": "sha1-MDJeDPbC+l+RAj0hAO0CGCbmMX0=", "dev": true }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, "fengari": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.2.tgz", @@ -537,38 +453,12 @@ "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", "dev": true }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "1.0.6", - "mime-types": "^2.1.12" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", @@ -589,22 +479,6 @@ "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", "dev": true }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", - "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", - "dev": true, - "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -620,15 +494,34 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "https-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "agent-base": "^4.1.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" } }, "inflight": { @@ -647,24 +540,12 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", @@ -702,49 +583,12 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", @@ -757,21 +601,6 @@ "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", "dev": true }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "~1.33.0" - } - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -816,6 +645,12 @@ "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", "dev": true }, + "node-fetch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", + "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==", + "dev": true + }, "nyc": { "version": "13.3.0", "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", @@ -1850,12 +1685,6 @@ } } }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1883,30 +1712,12 @@ "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true - }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -1935,34 +1746,6 @@ "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", "dev": true }, - "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - } - }, "resolve": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", @@ -2003,12 +1786,6 @@ "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", @@ -2037,23 +1814,6 @@ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "string_decoder": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2102,6 +1862,17 @@ "readable-stream": "^2" } }, + "teeny-request": { + "version": "3.11.3", + "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", + "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "dev": true, + "requires": { + "https-proxy-agent": "^2.2.1", + "node-fetch": "^2.2.0", + "uuid": "^3.3.2" + } + }, "threads": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/threads/-/threads-0.12.0.tgz", @@ -2154,15 +1925,6 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", - "dev": true, - "requires": { - "punycode": "^1.4.1" - } - }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", @@ -2251,22 +2013,6 @@ "tslib": "^1.8.1" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, "typescript": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", @@ -2290,17 +2036,6 @@ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index d899895d5..3212ca994 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@types/glob": "^5.0.35", "@types/node": "^9.6.23", "alsatian": "^2.3.0", - "codecov": "3.0.2", + "codecov": "^3.2.0", "deep-equal": "^1.0.1", "fengari": "^0.1.2", "flatted": "^2.0.0", From d577493d5776643f53c67f1de40046c61438fe5d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 16 Mar 2019 00:04:19 +0100 Subject: [PATCH 030/764] Update CHANGELOG.md --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index acae64ff0..dd4f0783f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ * To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`: ```/** @noSelf */ interface Foo {``` * To remove the self parameter from all functions in a file, add `/** @noSelfInFile */` at the top. + +--- + +* **BREAKING CHANGE:** Directive `/** @luaIterator */` should now be put on types instead of on the functions returning them. + +--- + * Fixed a bug breaking named class expressions. * Fixed inconsistency between the meaning of `>>` and `>>>` in JS vs. Lua. * Added `/** @noResolution */` directive to prevent path resolution on declared modules. From 8b421310e8d511d8ed0d8afe8fd3c7198c35c8ec Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 17 Mar 2019 05:58:37 -0600 Subject: [PATCH 031/764] Array detection fixes (#483) * fixed array access when mixed in a union with an empty tuple * reworked array detection to catch ReadonlyArray * ReadonlyArray test --- src/LuaTransformer.ts | 43 ++++++++++++++++------------ src/TSHelper.ts | 62 ++++++++++++++++++++++++----------------- test/unit/array.spec.ts | 19 +++++++++++++ 3 files changed, 80 insertions(+), 44 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index b367495e0..ab7587e97 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1088,7 +1088,7 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(node); - const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + const context = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void ? this.createSelfIdentifier() : undefined; const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); @@ -1594,7 +1594,7 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(functionDeclaration); - const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + const context = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void ? this.createSelfIdentifier() : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); @@ -1794,7 +1794,7 @@ export class LuaTransformer { const expressionType = this.checker.getTypeAtLocation(statement.expression); this.validateFunctionAssignment(statement, expressionType, returnType); } - if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { + if (tsHelper.isInTupleReturnFunction(statement, this.checker, this.program)) { // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(statement.expression)) { // If return expression is an array literal, leave out brackets. @@ -2080,7 +2080,11 @@ export class LuaTransformer { // LuaIterators return this.transformForOfLuaIteratorStatement(statement, body); - } else if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker)) { + } else if (tsHelper.isArrayType( + this.checker.getTypeAtLocation(statement.expression), + this.checker, + this.program) + ) { // Arrays return this.transformForOfArrayStatement(statement, body); @@ -2099,7 +2103,7 @@ export class LuaTransformer { const pairsIdentifier = tstl.createIdentifier("pairs"); const expression = tstl.createCallExpression(pairsIdentifier, [this.transformExpression(statement.expression)]); - if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker)) { + if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program)) { throw TSTLErrors.ForbiddenForIn(statement); } @@ -2514,7 +2518,7 @@ export class LuaTransformer { // Element access indexExpression = this.transformExpression(expression.left.argumentExpression); const argType = this.checker.getTypeAtLocation(expression.left.expression); - if (tsHelper.isArrayType(argType, this.checker)) { + if (tsHelper.isArrayType(argType, this.checker, this.program)) { // Array access needs a +1 indexExpression = this.expressionPlusOne(indexExpression); } @@ -2548,7 +2552,8 @@ export class LuaTransformer { const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, - this.checker + this.checker, + this.program ); if (hasEffects) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects @@ -2709,7 +2714,8 @@ export class LuaTransformer { const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, - this.checker + this.checker, + this.program ); if (hasEffects) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects @@ -2999,7 +3005,7 @@ export class LuaTransformer { ): ExpressionVisitResult { const type = this.checker.getTypeAtLocation(node); - const hasContext = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void; + const hasContext = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void; // Build parameter string const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters( node.parameters, @@ -3091,8 +3097,9 @@ export class LuaTransformer { let parameters: tstl.Expression[] = []; const isTupleReturn = tsHelper.isTupleReturnCall(node, this.checker); - const isTupleReturnForward = - node.parent && ts.isReturnStatement(node.parent) && tsHelper.isInTupleReturnFunction(node, this.checker); + const isTupleReturnForward = node.parent + && ts.isReturnStatement(node.parent) + && tsHelper.isInTupleReturnFunction(node, this.checker, this.program); const isInDestructingAssignment = tsHelper.isInDestructingAssignment(node); const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); @@ -3186,12 +3193,12 @@ export class LuaTransformer { } // if ownerType is a array, use only supported functions - if (tsHelper.isExplicitArrayType(ownerType, this.checker)) { + if (tsHelper.isExplicitArrayType(ownerType, this.checker, this.program)) { return this.transformArrayCallExpression(node); } // if ownerType inherits from an array, use array calls where appropriate - if (tsHelper.isArrayType(ownerType, this.checker) && + if (tsHelper.isArrayType(ownerType, this.checker, this.program) && tsHelper.isDefaultArrayCallMethodName(node.expression.name.escapedText as string)) { return this.transformArrayCallExpression(node); } @@ -3320,7 +3327,7 @@ export class LuaTransformer { if (tsHelper.isStringType(type)) { return this.transformStringProperty(node); - } else if (tsHelper.isArrayType(type, this.checker)) { + } else if (tsHelper.isArrayType(type, this.checker, this.program)) { const arrayPropertyAccess = this.transformArrayProperty(node); if (arrayPropertyAccess) { return arrayPropertyAccess; @@ -3485,7 +3492,7 @@ export class LuaTransformer { return this.transformConstEnumValue(type, node.argumentExpression.text, node); } - if (tsHelper.isArrayType(type, this.checker)) { + if (tsHelper.isArrayType(type, this.checker, this.program)) { return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), node); } else if (tsHelper.isStringType(type)) { return tstl.createCallExpression( @@ -3878,7 +3885,7 @@ export class LuaTransformer { public transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { + if (tsHelper.getFunctionContextType(callerType, this.checker, this.program) === ContextType.Void) { throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } const params = this.transformArguments(node.arguments); @@ -4313,8 +4320,8 @@ export class LuaTransformer { fromTypeCache.add(toType); // Check function assignments - const fromContext = tsHelper.getFunctionContextType(fromType, this.checker); - const toContext = tsHelper.getFunctionContextType(toType, this.checker); + const fromContext = tsHelper.getFunctionContextType(fromType, this.checker, this.program); + const toContext = tsHelper.getFunctionContextType(toType, this.checker, this.program); if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 2de95d570..154a5efc9 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -140,15 +140,18 @@ export class TSHelper { (type.flags & ts.TypeFlags.StringLiteral) !== 0; } - public static isArrayTypeNode(typeNode: ts.TypeNode): boolean { - return typeNode.kind === ts.SyntaxKind.ArrayType || typeNode.kind === ts.SyntaxKind.TupleType || - ((typeNode.kind === ts.SyntaxKind.UnionType || typeNode.kind === ts.SyntaxKind.IntersectionType) && - (typeNode as ts.UnionOrIntersectionTypeNode).types.some(TSHelper.isArrayTypeNode)); - } + public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + if (type.isUnionOrIntersection()) { + return type.types.some(t => TSHelper.isExplicitArrayType(t, checker, program)); + } - public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker): boolean { - const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode && TSHelper.isArrayTypeNode(typeNode); + if (TSHelper.isStandardLibraryType(type, "ReadonlyArray", program)) { + return true; + } + + const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; + const typeNode = checker.typeToTypeNode(type, undefined, flags); + return typeNode && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); } public static isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { @@ -161,8 +164,8 @@ export class TSHelper { return TSHelper.isFunctionType(type, checker); } - public static isArrayType(type: ts.Type, checker: ts.TypeChecker): boolean { - return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker)); + public static isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker, program)); } public static isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean { @@ -180,12 +183,12 @@ export class TSHelper { } } - public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { + public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker, program: ts.Program): boolean { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { let functionType: ts.Type; if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = TSHelper.inferAssignedType(declaration, checker); + functionType = TSHelper.inferAssignedType(declaration, checker, program); } else { functionType = checker.getTypeAtLocation(declaration); } @@ -330,13 +333,17 @@ export class TSHelper { // If expression is property/element access with possible effects from being evaluated, returns true along with the // separated object and index expressions. - public static isAccessExpressionWithEvaluationEffects(node: ts.Expression, checker: ts.TypeChecker): - [boolean, ts.Expression, ts.Expression] { + public static isAccessExpressionWithEvaluationEffects( + node: ts.Expression, + checker: ts.TypeChecker, + program: ts.Program + ): [boolean, ts.Expression, ts.Expression] + { if (ts.isElementAccessExpression(node) && (TSHelper.isExpressionWithEvaluationEffect(node.expression) || TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression))) { const type = checker.getTypeAtLocation(node.expression); - if (TSHelper.isArrayType(type, checker)) { + if (TSHelper.isArrayType(type, checker, program)) { // Offset arrays by one const oneLit = ts.createNumericLiteral("1"); const exp = ts.createParen(node.argumentExpression); @@ -446,10 +453,10 @@ export class TSHelper { ) !== undefined; } - public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { + public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker, program: ts.Program): ts.Type { if (ts.isParenthesizedExpression(expression.parent)) { // Ignore expressions wrapped in parenthesis - return this.inferAssignedType(expression.parent, checker); + return this.inferAssignedType(expression.parent, checker, program); } else if (ts.isCallOrNewExpression(expression.parent)) { // Expression being passed as argument to a function @@ -462,7 +469,7 @@ export class TSHelper { parentSignature.parameters[signatureIndex], expression ); - if (TSHelper.isArrayType(parameterType, checker)) { + if (TSHelper.isArrayType(parameterType, checker, program)) { // Check for elipses argument const parentSignatureDeclaration = parentSignature.getDeclaration(); if (parentSignatureDeclaration) { @@ -496,7 +503,7 @@ export class TSHelper { } else if (ts.isPropertyAssignment(expression.parent)) { // Expression being assigned to an object literal property - const objType = this.inferAssignedType(expression.parent.parent, checker); + const objType = this.inferAssignedType(expression.parent.parent, checker, program); const property = objType.getProperty(expression.parent.name.getText()); if (!property) { const stringPropertyType = objType.getStringIndexType(); @@ -509,7 +516,7 @@ export class TSHelper { } else if (ts.isArrayLiteralExpression(expression.parent)) { // Expression in an array literal - const arrayType = this.inferAssignedType(expression.parent, checker); + const arrayType = this.inferAssignedType(expression.parent, checker, program); if (ts.isTupleTypeNode(checker.typeToTypeNode(arrayType))) { // Tuples const i = expression.parent.elements.indexOf(expression); @@ -530,7 +537,7 @@ export class TSHelper { return checker.getTypeAtLocation(expression.parent.left); } else { // Other binary expressions - return TSHelper.inferAssignedType(expression.parent, checker); + return TSHelper.inferAssignedType(expression.parent, checker, program); } } else if (ts.isAssertionExpression(expression.parent)) { @@ -550,7 +557,8 @@ export class TSHelper { public static getSignatureDeclarations( signatures: ReadonlyArray, - checker: ts.TypeChecker + checker: ts.TypeChecker, + program: ts.Program ): ts.SignatureDeclaration[] { const signatureDeclarations: ts.SignatureDeclaration[] = []; @@ -560,7 +568,7 @@ export class TSHelper { && !TSHelper.getExplicitThisParameter(signatureDeclaration)) { // Infer type of function expressions/arrow functions - const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); + const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker, program); if (inferredType) { const inferredSignatures = TSHelper.getAllCallSignatures(inferredType); if (inferredSignatures.length > 0) { @@ -650,20 +658,22 @@ export class TSHelper { return contexts.reduce(reducer, ContextType.None); } - public static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType { + public static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): ContextType { if (type.isTypeParameter()) { type = type.getConstraint() || type; } if (type.isUnion()) { - return TSHelper.reduceContextTypes(type.types.map(t => TSHelper.getFunctionContextType(t, checker))); + return TSHelper.reduceContextTypes( + type.types.map(t => TSHelper.getFunctionContextType(t, checker, program)) + ); } const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); if (signatures.length === 0) { return ContextType.None; } - const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker); + const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker, program); return TSHelper.reduceContextTypes( signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker))); } diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index eecdf4cd1..4ddb7b8fd 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -11,6 +11,15 @@ export class ArrayTests { Expect(result).toBe(5); } + @Test("Readonly Array access") + public readonlyArrayAccess(): void { + const result = util.transpileAndExecute( + `const arr: ReadonlyArray = [3,5,1]; + return arr[1];` + ); + Expect(result).toBe(5); + } + @Test("Array union access") public arrayUnionAccess(): void { const result = util.transpileAndExecute( @@ -21,6 +30,16 @@ export class ArrayTests { Expect(result).toBe(5); } + @Test("Array union access with empty tuple") + public arrayUnionAccessWithEmptyTuple(): void { + const result = util.transpileAndExecute( + `function makeArray(): number[] | [] { return [3,5,1]; } + const arr = makeArray(); + return arr[1];` + ); + Expect(result).toBe(5); + } + @Test("Array union length") public arrayUnionLength(): void { const result = util.transpileAndExecute( From fbdb6047123d469ef5749b7ac0c29402fc7c4df9 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 17 Mar 2019 06:43:09 -0600 Subject: [PATCH 032/764] removed escape from backtick (#482) * removed escape from backtick * tweaked test to make more sense --- src/TSHelper.ts | 1 - test/translation/lua/characterEscapeSequence.lua | 9 ++++++--- test/translation/ts/characterEscapeSequence.ts | 6 +++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 154a5efc9..15b02402a 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -687,7 +687,6 @@ export class TSHelper { const escapeSequences: Array<[RegExp, string]> = [ [/[\\]/g, "\\\\"], [/[\']/g, "\\\'"], - [/[\`]/g, "\\\`"], [/[\"]/g, "\\\""], [/[\n]/g, "\\n"], [/[\r]/g, "\\r"], diff --git a/test/translation/lua/characterEscapeSequence.lua b/test/translation/lua/characterEscapeSequence.lua index 36abfe9d0..82f43bbaa 100644 --- a/test/translation/lua/characterEscapeSequence.lua +++ b/test/translation/lua/characterEscapeSequence.lua @@ -3,7 +3,10 @@ local quoteInTemplateString = "\' \' \'"; local doubleQuoteInQuotes = "\" \" \""; local doubleQuoteInDoubleQuotes = "\" \" \""; local doubleQuoteInTemplateString = "\" \" \""; -local escapedCharsInQuotes = "\\ \0 \b \t \n \v \f \" \' \`"; -local escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \' \`"; -local escapedCharsInTemplateString = "\\ \0 \b \t \n \v \f \" \' \`"; +local backQuoteInQuotes = "` ` `"; +local backQuoteInDoubleQuotes = "` ` `"; +local backQuoteInTemplateString = "` ` `"; +local escapedCharsInQuotes = "\\ \0 \b \t \n \v \f \" \' `"; +local escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \'"; +local escapedCharsInTemplateString = "\\ \0 \b \t \n \v \f \" \' `"; local nonEmptyTemplateString = "Level 0: \n\t " .. (tostring("Level 1: \n\t\t " .. (tostring("Level 3: \n\t\t\t " .. (tostring("Last level \n --") .. " \n --")) .. " \n --")) .. " \n --"); diff --git a/test/translation/ts/characterEscapeSequence.ts b/test/translation/ts/characterEscapeSequence.ts index f99683c32..e3ec0b741 100644 --- a/test/translation/ts/characterEscapeSequence.ts +++ b/test/translation/ts/characterEscapeSequence.ts @@ -5,8 +5,12 @@ let doubleQuoteInQuotes = '" " "'; let doubleQuoteInDoubleQuotes = "\" \" \""; let doubleQuoteInTemplateString = `" " "`; +let backQuoteInQuotes = '` ` `'; +let backQuoteInDoubleQuotes = "` ` `"; +let backQuoteInTemplateString = `\` \` \``; + let escapedCharsInQuotes = '\\ \0 \b \t \n \v \f \" \' \`'; -let escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \' \`"; +let escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \'"; let escapedCharsInTemplateString = `\\ \0 \b \t \n \v \f \" \' \``; let nonEmptyTemplateString = `Level 0: \n\t ${`Level 1: \n\t\t ${`Level 3: \n\t\t\t ${'Last level \n --'} \n --`} \n --`} \n --`; From 02b96424f2bf5ba512ef1b6bea68244ed1027655 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 18 Mar 2019 08:11:00 -0600 Subject: [PATCH 033/764] validating arguments passed to lua lib functions (#484) * validating arguments passed to lua lib functions * resolving signature in lualib transform functions instead of passing it in * formatting fixes --- src/LuaTransformer.ts | 36 +++++++++++++++++++++-------------- test/unit/assignments.spec.ts | 23 ++++++++++++++++++++++ test/unit/expressions.spec.ts | 1 + 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ab7587e97..66bb194d5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3162,6 +3162,8 @@ export class LuaTransformer { // If the function being called is of type owner.func, get the type of owner const ownerType = this.checker.getTypeAtLocation(node.expression.expression); + const signature = this.checker.getResolvedSignature(node); + if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { return this.transformMathCallExpression(node); } @@ -3173,7 +3175,7 @@ export class LuaTransformer { if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) { return tstl.createCallExpression( this.transformStringExpression(node.expression.name), - this.transformArguments(node.arguments), + this.transformArguments(node.arguments, signature), node ); } @@ -3207,8 +3209,6 @@ export class LuaTransformer { return this.transformFunctionCallExpression(node); } - const signature = this.checker.getResolvedSignature(node); - // Get the type of the function if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) @@ -3292,7 +3292,8 @@ export class LuaTransformer { public transformArguments( params: ts.NodeArray, - sig?: ts.Signature, context?: T + sig?: ts.Signature, + context?: T ): tstl.Expression[] { const parameters: tstl.Expression[] = []; @@ -3387,7 +3388,8 @@ export class LuaTransformer { // Transpile a Math._ property public transformMathCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; - const params = this.transformArguments(node.arguments); + const signature = this.checker.getResolvedSignature(node); + const params = this.transformArguments(node.arguments, signature); const expressionName = expression.name.escapedText as string; switch (expressionName) { // math.tan(x / y) @@ -3546,7 +3548,8 @@ export class LuaTransformer { public transformStringCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; - const params = this.transformArguments(node.arguments); + const signature = this.checker.getResolvedSignature(node); + const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText as string; @@ -3690,6 +3693,7 @@ export class LuaTransformer { // Transpile an Object._ property public transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; + const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments); const caller = this.transformExpression(expression.expression); const methodName = method.name.escapedText; @@ -3715,6 +3719,7 @@ export class LuaTransformer { public transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const methodName = method.name.escapedText; + const signature = this.checker.getResolvedSignature(expression); switch (methodName) { case "log": @@ -3725,7 +3730,7 @@ export class LuaTransformer { tstl.createTableIndexExpression( tstl.createIdentifier("string"), tstl.createStringLiteral("format")), - this.transformArguments(expression.arguments) + this.transformArguments(expression.arguments, signature) ); return tstl.createCallExpression( tstl.createIdentifier("print"), @@ -3735,10 +3740,10 @@ export class LuaTransformer { // print([arguments]) return tstl.createCallExpression( tstl.createIdentifier("print"), - this.transformArguments(expression.arguments) + this.transformArguments(expression.arguments, signature) ); case "assert": - const args = this.transformArguments(expression.arguments); + const args = this.transformArguments(expression.arguments, signature); if (expression.arguments.length > 1 && this.isStringFormatTemplate(expression.arguments[1])) { // assert([condition], string.format([arguments])) @@ -3766,7 +3771,7 @@ export class LuaTransformer { tstl.createTableIndexExpression( tstl.createIdentifier("string"), tstl.createStringLiteral("format")), - this.transformArguments(expression.arguments) + this.transformArguments(expression.arguments, signature) ); const debugTracebackCall = tstl.createCallExpression( tstl.createTableIndexExpression( @@ -3784,7 +3789,7 @@ export class LuaTransformer { tstl.createTableIndexExpression( tstl.createIdentifier("debug"), tstl.createStringLiteral("traceback")), - this.transformArguments(expression.arguments) + this.transformArguments(expression.arguments, signature) ); return tstl.createCallExpression( tstl.createIdentifier("print"), @@ -3806,7 +3811,8 @@ export class LuaTransformer { // Transpile a Symbol._ property public transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; - const parameters = this.transformArguments(expression.arguments); + const signature = this.checker.getResolvedSignature(expression); + const parameters = this.transformArguments(expression.arguments, signature); const methodName = method.name.escapedText; switch (methodName) { @@ -3827,7 +3833,8 @@ export class LuaTransformer { public transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; - const params = this.transformArguments(node.arguments); + const signature = this.checker.getResolvedSignature(node); + const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText; switch (expressionName) { @@ -3888,7 +3895,8 @@ export class LuaTransformer { if (tsHelper.getFunctionContextType(callerType, this.checker, this.program) === ContextType.Void) { throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } - const params = this.transformArguments(node.arguments); + const signature = this.checker.getResolvedSignature(node); + const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText; switch (expressionName) { diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 257dc2b2d..5b27f33d1 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -663,6 +663,29 @@ export class AssignmentTests { Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); } + @Test("Valid lua lib function argument") + public validLuaLibFunctionArgument(): void { + const code = + `let result = ""; + function foo(this: any, value: string) { result += value; } + const a = ['foo', 'bar']; + a.forEach(foo); + return result;`; + Expect(util.transpileAndExecute(code)).toBe("foobar"); + } + + @Test("Invalid lua lib function argument") + public invalidLuaLibFunctionArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) + : void + { + const code = + `declare function foo(this: void, value: string): void; + declare const a: string[]; + a.forEach(foo);`; + const err = TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "callbackfn"); + Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); + } + @TestCases(validTestFunctionCasts) @Test("Valid function argument with cast") public validFunctionArgumentWithCast(testFunction: TestFunction, castedFunction: string): void { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index e0d2df5b0..aa14e0404 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -493,6 +493,7 @@ export class ExpressionTests { const transformer = util.makeTestTransformer(); const mockNode: any = { + kind: ts.SyntaxKind.CallExpression, arguments: [], caller: ts.createLiteral(false), expression: {name: ts.createIdentifier("unknownFunction"), expression: ts.createLiteral(false)}, From 8515a038a20b97a1ddc1385df17392994d565b2f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 18 Mar 2019 19:27:49 +0100 Subject: [PATCH 034/764] Changed position of spread operator declaration in function body (#485) --- src/LuaTransformer.ts | 12 ++++++------ test/unit/functions.spec.ts | 12 ++++++++++++ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 66bb194d5..b5d65c313 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1169,6 +1169,12 @@ export class LuaTransformer { headerStatements.push(...defaultValueDeclarations); + // Push spread operator here + if (spreadIdentifier) { + const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); + headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); + } + // Add object binding patterns let identifierIndex = 0; const bindingPatternDeclarations: tstl.Statement[] = []; @@ -1181,12 +1187,6 @@ export class LuaTransformer { headerStatements.push(...bindingPatternDeclarations); - // Push spread operator here - if (spreadIdentifier) { - const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); - headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); - } - const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); const scope = this.popScope(); diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 71b1b96b7..55161623b 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -511,4 +511,16 @@ export class FunctionTests { }`; Expect(util.transpileAndExecute("return foo;", undefined, undefined, code)).toBe("foo"); } + + @Test("Function rest binding pattern") + public functionRestBindingPattern(): void { + const result = util.transpileAndExecute( + `function bar(foo: string, ...[bar, baz]: [string, string]) { + return bar + baz + foo; + } + return bar("abc", "def", "xyz"); + `); + + Expect(result).toBe("defxyzabc"); + } } From d0c4f72473be2edc6c4fe255ab613f242a73a347 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 20 Mar 2019 06:36:22 -0700 Subject: [PATCH 035/764] Using getContextualType in inferAssignedType (#487) * using getContextualType for inferAssignedType * test for new inference bug --- src/LuaTransformer.ts | 16 ++--- src/TSHelper.ts | 110 +++------------------------------- test/unit/assignments.spec.ts | 15 +++++ 3 files changed, 32 insertions(+), 109 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index b5d65c313..08ef605a4 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1088,7 +1088,7 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(node); - const context = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void + const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void ? this.createSelfIdentifier() : undefined; const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); @@ -1594,7 +1594,7 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(functionDeclaration); - const context = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void + const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void ? this.createSelfIdentifier() : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); @@ -1794,7 +1794,7 @@ export class LuaTransformer { const expressionType = this.checker.getTypeAtLocation(statement.expression); this.validateFunctionAssignment(statement, expressionType, returnType); } - if (tsHelper.isInTupleReturnFunction(statement, this.checker, this.program)) { + if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(statement.expression)) { // If return expression is an array literal, leave out brackets. @@ -3005,7 +3005,7 @@ export class LuaTransformer { ): ExpressionVisitResult { const type = this.checker.getTypeAtLocation(node); - const hasContext = tsHelper.getFunctionContextType(type, this.checker, this.program) !== ContextType.Void; + const hasContext = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void; // Build parameter string const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters( node.parameters, @@ -3099,7 +3099,7 @@ export class LuaTransformer { const isTupleReturn = tsHelper.isTupleReturnCall(node, this.checker); const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) - && tsHelper.isInTupleReturnFunction(node, this.checker, this.program); + && tsHelper.isInTupleReturnFunction(node, this.checker); const isInDestructingAssignment = tsHelper.isInDestructingAssignment(node); const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); @@ -3892,7 +3892,7 @@ export class LuaTransformer { public transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.getFunctionContextType(callerType, this.checker, this.program) === ContextType.Void) { + if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } const signature = this.checker.getResolvedSignature(node); @@ -4328,8 +4328,8 @@ export class LuaTransformer { fromTypeCache.add(toType); // Check function assignments - const fromContext = tsHelper.getFunctionContextType(fromType, this.checker, this.program); - const toContext = tsHelper.getFunctionContextType(toType, this.checker, this.program); + const fromContext = tsHelper.getFunctionContextType(fromType, this.checker); + const toContext = tsHelper.getFunctionContextType(toType, this.checker); if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 15b02402a..62719cc34 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -183,12 +183,12 @@ export class TSHelper { } } - public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker, program: ts.Program): boolean { + public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { let functionType: ts.Type; if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = TSHelper.inferAssignedType(declaration, checker, program); + functionType = TSHelper.inferAssignedType(declaration, checker); } else { functionType = checker.getTypeAtLocation(declaration); } @@ -453,99 +453,8 @@ export class TSHelper { ) !== undefined; } - public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker, program: ts.Program): ts.Type { - if (ts.isParenthesizedExpression(expression.parent)) { - // Ignore expressions wrapped in parenthesis - return this.inferAssignedType(expression.parent, checker, program); - - } else if (ts.isCallOrNewExpression(expression.parent)) { - // Expression being passed as argument to a function - const argumentIndex = expression.parent.arguments.indexOf(expression); - if (argumentIndex >= 0) { - const parentSignature = checker.getResolvedSignature(expression.parent); - if (parentSignature.parameters.length > 0) { // In case function type is 'any' - const signatureIndex = Math.min(argumentIndex, parentSignature.parameters.length - 1); - let parameterType = checker.getTypeOfSymbolAtLocation( - parentSignature.parameters[signatureIndex], - expression - ); - if (TSHelper.isArrayType(parameterType, checker, program)) { - // Check for elipses argument - const parentSignatureDeclaration = parentSignature.getDeclaration(); - if (parentSignatureDeclaration) { - let declarationIndex = signatureIndex; - if (this.getExplicitThisParameter(parentSignatureDeclaration)) { - // Ignore 'this' parameter - ++declarationIndex; - } - const parameterDeclaration = parentSignatureDeclaration.parameters[declarationIndex]; - if ((parameterType.flags & ts.TypeFlags.Object) !== 0 - && ((parameterType as ts.ObjectType).objectFlags & ts.ObjectFlags.Reference) !== 0 - && parameterDeclaration.dotDotDotToken) - { - // Determine type from elipsis array/tuple type - const parameterTypeReference = (parameterType as ts.TypeReference); - parameterType = parameterTypeReference.typeArguments[argumentIndex - declarationIndex]; - } - } - } - return parameterType; - } - } - - } else if (ts.isReturnStatement(expression.parent)) { - // Expression being returned from a function - return this.getContainingFunctionReturnType(expression.parent, checker); - - } else if (ts.isPropertyDeclaration(expression.parent)) { - // Expression being assigned to a class property - return checker.getTypeAtLocation(expression.parent); - - } else if (ts.isPropertyAssignment(expression.parent)) { - // Expression being assigned to an object literal property - const objType = this.inferAssignedType(expression.parent.parent, checker, program); - const property = objType.getProperty(expression.parent.name.getText()); - if (!property) { - const stringPropertyType = objType.getStringIndexType(); - if (stringPropertyType) { - return stringPropertyType; - } - } else { - return checker.getTypeAtLocation(property.valueDeclaration); - } - - } else if (ts.isArrayLiteralExpression(expression.parent)) { - // Expression in an array literal - const arrayType = this.inferAssignedType(expression.parent, checker, program); - if (ts.isTupleTypeNode(checker.typeToTypeNode(arrayType))) { - // Tuples - const i = expression.parent.elements.indexOf(expression); - const elementType = (arrayType as ts.TypeReference).typeArguments[i]; - return elementType; - } else { - // Standard arrays - return arrayType.getNumberIndexType(); - } - - } else if (ts.isVariableDeclaration(expression.parent)) { - // Expression assigned to declaration - return checker.getTypeAtLocation(expression.parent.name); - - } else if (ts.isBinaryExpression(expression.parent)) { - if (expression.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { - // Expression assigned to variable - return checker.getTypeAtLocation(expression.parent.left); - } else { - // Other binary expressions - return TSHelper.inferAssignedType(expression.parent, checker, program); - } - - } else if (ts.isAssertionExpression(expression.parent)) { - // Expression being cast - return checker.getTypeFromTypeNode(expression.parent.type); - } - - return checker.getTypeAtLocation(expression); + public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { + return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); } public static getAllCallSignatures(type: ts.Type): ReadonlyArray { @@ -557,8 +466,7 @@ export class TSHelper { public static getSignatureDeclarations( signatures: ReadonlyArray, - checker: ts.TypeChecker, - program: ts.Program + checker: ts.TypeChecker ): ts.SignatureDeclaration[] { const signatureDeclarations: ts.SignatureDeclaration[] = []; @@ -568,7 +476,7 @@ export class TSHelper { && !TSHelper.getExplicitThisParameter(signatureDeclaration)) { // Infer type of function expressions/arrow functions - const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker, program); + const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); if (inferredType) { const inferredSignatures = TSHelper.getAllCallSignatures(inferredType); if (inferredSignatures.length > 0) { @@ -658,14 +566,14 @@ export class TSHelper { return contexts.reduce(reducer, ContextType.None); } - public static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): ContextType { + public static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType { if (type.isTypeParameter()) { type = type.getConstraint() || type; } if (type.isUnion()) { return TSHelper.reduceContextTypes( - type.types.map(t => TSHelper.getFunctionContextType(t, checker, program)) + type.types.map(t => TSHelper.getFunctionContextType(t, checker)) ); } @@ -673,7 +581,7 @@ export class TSHelper { if (signatures.length === 0) { return ContextType.None; } - const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker, program); + const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker); return TSHelper.reduceContextTypes( signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker))); } diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 5b27f33d1..f5d5e0ddb 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1122,6 +1122,21 @@ export class AssignmentTests { Expect(util.transpileAndExecute(code)).toBe("foo"); } + @TestCase("(this: void, s: string) => string", "s => s") + @TestCase("(this: any, s: string) => string", "s => s") + @TestCase("(s: string) => string", "s => s") + @TestCase("(this: void, s: string) => string", "function(s) { return s; }") + @TestCase("(this: any, s: string) => string", "function(s) { return s; }") + @TestCase("(s: string) => string", "function(s) { return s; }") + @Test("Function expression type inference in union tuple") + public functionExpressionTypeInferenceInUnionTuple(funcType: string, funcExp: string): void { + const code = + `interface I { callback: ${funcType}; } + let a: I[] | number = [{ callback: ${funcExp} }]; + return a[0].callback("foo");`; + Expect(util.transpileAndExecute(code)).toBe("foo"); + } + @TestCase("(this: void, s: string) => string", "s => s") @TestCase("(this: any, s: string) => string", "s => s") @TestCase("(s: string) => string", "s => s") From c4a387a928d19421355c038aeeee9bcecdc0eebc Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Thu, 21 Mar 2019 23:32:14 +0100 Subject: [PATCH 036/764] Incremental compilation in watch mode (#488) * emit only affected files * track transpiler errors * return 0 for success * return 0 for declarations * do a full recompile after transpiler error * forgot about lazy evaluation * test if affected file is a SourceFile --- src/Compiler.ts | 26 +++++++++++++++++++++++++- src/LuaTranspiler.ts | 18 +++++++++++------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/Compiler.ts b/src/Compiler.ts index 6b382d200..0659ea527 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -43,10 +43,34 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions): host = ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram); } + let fullRecompile = true; host.afterProgramCreate = program => { const transpiler = new LuaTranspiler(program.getProgram()); + let status = transpiler.reportErrors(); + + if (status === 0) { + if (fullRecompile) { + status = transpiler.emitFilesAndReportErrors(); + } else { + while (true) { + const currentFile = program.getSemanticDiagnosticsOfNextAffectedFile(); + if (!currentFile) { break; } + + if ("fileName" in currentFile.affected) { // test if currentFile.affected is `ts.SourceFile` + const fileStatus = transpiler.emitSourceFile(currentFile.affected); + status |= fileStatus; + } else { + for (const sourceFile of currentFile.affected.getSourceFiles()) { + const fileStatus = transpiler.emitSourceFile(sourceFile); + status |= fileStatus; + } + } + } + } + // do a full recompile after transpiler error. + fullRecompile = status !== 0; + } - const status = transpiler.emitFilesAndReportErrors(); const errorDiagnostic: ts.Diagnostic = { category: undefined, code: 6194, diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts index a4a4416a2..dc96e9801 100644 --- a/src/LuaTranspiler.ts +++ b/src/LuaTranspiler.ts @@ -38,7 +38,7 @@ export class LuaTranspiler { return options; } - private reportErrors(): number { + public reportErrors(): number { // Get all diagnostics, ignore unsupported extension const diagnostics = ts.getPreEmitDiagnostics(this.program).filter(diag => diag.code !== 6054); diagnostics.forEach(diag => this.reportDiagnostic(diag)); @@ -65,13 +65,15 @@ export class LuaTranspiler { } public emitFilesAndReportErrors(): number { - const error = this.reportErrors(); - if (error > 0) { - return error; + let status = this.reportErrors(); + + if (status > 0) { + return status; } this.program.getSourceFiles().forEach(sourceFile => { - this.emitSourceFile(sourceFile); + const sourceStatus = this.emitSourceFile(sourceFile); + status |= sourceStatus; }); // Copy lualib to target dir @@ -81,10 +83,10 @@ export class LuaTranspiler { this.emitLuaLib(); } - return 0; + return status; } - public emitSourceFile(sourceFile: ts.SourceFile): void { + public emitSourceFile(sourceFile: ts.SourceFile): number { if (!sourceFile.isDeclarationFile) { try { const rootDir = this.options.rootDir; @@ -119,11 +121,13 @@ export class LuaTranspiler { // Graciously handle transpilation errors console.error("Encountered error parsing file: " + exception.message); console.error(`${sourceFile.fileName} (${1 + pos.line},${pos.character})\n${exception.stack}`); + return 1; } else { throw exception; } } } + return 0; } public transpileSourceFile(sourceFile: ts.SourceFile): string { From 512e7d0aeb4c8969f5cb81241aafe1666ac4cd9c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 21 Mar 2019 23:55:32 +0100 Subject: [PATCH 037/764] 0.16.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c0f148f7..0d029c704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.16.0", + "version": "0.16.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3212ca994..0ae952e43 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "typescript-to-lua", "license": "MIT", - "version": "0.16.0", + "version": "0.16.1", "repository": "https://github.com/Perryvw/TypescriptToLua", "keywords": [ "typescript", From 225c7c1f2a2424c3361b27d15eb66eeb0bd494a4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 26 Mar 2019 06:11:09 -0600 Subject: [PATCH 038/764] support for @tupleReturn per overloaded function signature (#495) * support for @tupleReturn per overloaded function signature * fixed edge-case with interface methods --- src/LuaTransformer.ts | 9 ++- src/TSHelper.ts | 42 +++++++++++-- test/unit/tuples.spec.ts | 131 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 176 insertions(+), 6 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 08ef605a4..4eee5cde8 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1800,8 +1800,13 @@ export class LuaTransformer { // If return expression is an array literal, leave out brackets. return tstl.createReturnStatement(statement.expression.elements .map(elem => this.transformExpression(elem))); - } else if (!tsHelper.isTupleReturnCall(statement.expression, this.checker)) { - // If return expression is not another TupleReturn call, unpack it + } + + const expressionType = this.checker.getTypeAtLocation(statement.expression); + if (!tsHelper.isTupleReturnCall(statement.expression, this.checker) + && tsHelper.isArrayType(expressionType, this.checker, this.program)) + { + // If return expression is an array-type and not another TupleReturn call, unpack it const expression = this.createUnpackCall( this.transformExpression(statement.expression), statement.expression diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 62719cc34..c9ef6dd3a 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -175,9 +175,25 @@ export class TSHelper { public static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { if (ts.isCallExpression(node)) { - const type = checker.getTypeAtLocation(node.expression); + const signature = checker.getResolvedSignature(node); + if (signature) { + if (TSHelper.getCustomSignatureDirectives(signature, checker).has(DecoratorKind.TupleReturn)) { + return true; + } + + // Only check function type for directive if it is declared as an interface or type alias + const declaration = signature.getDeclaration(); + const isInterfaceOrAlias = declaration && declaration.parent + && ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) + || ts.isTypeAliasDeclaration(declaration.parent)); + if (!isInterfaceOrAlias) { + return false; + } + } + const type = checker.getTypeAtLocation(node.expression); return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); + } else { return false; } @@ -192,8 +208,18 @@ export class TSHelper { } else { functionType = checker.getTypeAtLocation(declaration); } + + // Check all overloads for directive + const signatures = functionType.getCallSignatures(); + if (signatures && signatures.some( + s => TSHelper.getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn))) + { + return true; + } + const decorators = TSHelper.getCustomDecorators(functionType, checker); return decorators.has(DecoratorKind.TupleReturn); + } else { return false; } @@ -209,12 +235,12 @@ export class TSHelper { } public static collectCustomDecorators( - symbol: ts.Symbol, + source: ts.Symbol | ts.Signature, checker: ts.TypeChecker, decMap: Map ): void { - const comments = symbol.getDocumentationComment(checker); + const comments = source.getDocumentationComment(checker); const decorators = comments.filter(comment => comment.kind === "text") .map(comment => comment.text.split("\n")) .reduce((a, b) => a.concat(b), []) @@ -233,7 +259,7 @@ export class TSHelper { console.warn(`Encountered unknown decorator ${decStr}.`); } }); - symbol.getJsDocTags().forEach(tag => { + source.getJsDocTags().forEach(tag => { if (Decorator.isValid(tag.name)) { const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []); decMap.set(dec.kind, dec); @@ -267,6 +293,14 @@ export class TSHelper { return decMap; } + public static getCustomSignatureDirectives(signature: ts.Signature, checker: ts.TypeChecker) + : Map + { + const directivesMap = new Map(); + TSHelper.collectCustomDecorators(signature, checker, directivesMap); + return directivesMap; + } + // Search up until finding a node satisfying the callback public static findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T { let current = node; diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 796836c29..5de08527b 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -254,4 +254,135 @@ export class TupleTests { const result = util.executeLua(lua); Expect(result).toBe("foobar"); } + + @Test("Tuple Return on Type Alias") + public tupleReturnOnTypeAlias(): void { + const code = + `/** @tupleReturn */ type Fn = () => [number, number]; + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b;`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe(3); + } + + @Test("Tuple Return on Interface") + public tupleReturnOnInterface(): void { + const code = + `/** @tupleReturn */ interface Fn { (): [number, number]; } + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b;`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe(3); + } + + @Test("Tuple Return on Interface Signature") + public tupleReturnOnInterfaceSignature(): void { + const code = + `interface Fn { + /** @tupleReturn */ (): [number, number]; + } + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b;`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe(3); + } + + @Test("Tuple Return on Overload") + public tupleReturnOnOverload(): void { + const code = + `function fn(a: number): number; + /** @tupleReturn */ function fn(a: string, b: string): [string, string]; + function fn(a: number | string, b?: string): number | [string, string] { + if (typeof a === "number") { + return a; + } else { + return [a, b as string]; + } + } + const a = fn(3); + const [b, c] = fn("foo", "bar"); + return a + b + c`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("3foobar"); + } + + @Test("Tuple Return on Interface Overload") + public tupleReturnOnInterfaceOverload(): void { + const code = + `interface Fn { + (a: number): number; + /** @tupleReturn */ (a: string, b: string): [string, string]; + } + const fn = ((a: number | string, b?: string): number | [string, string] => { + if (typeof a === "number") { + return a; + } else { + return [a, b as string]; + } + }) as Fn; + const a = fn(3); + const [b, c] = fn("foo", "bar"); + return a + b + c`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("3foobar"); + } + + @Test("Tuple Return on Interface Method Overload") + public tupleReturnOnInterfaceMethodOverload(): void { + const code = + `interface Foo { + foo(a: number): number; + /** @tupleReturn */ foo(a: string, b: string): [string, string]; + } + const bar = ({ + foo: (a: number | string, b?: string): number | [string, string] => { + if (typeof a === "number") { + return a; + } else { + return [a, b as string]; + } + } + }) as Foo; + const a = bar.foo(3); + const [b, c] = bar.foo("foo", "bar"); + return a + b + c`; + const lua = util.transpileString(code); + Expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + Expect(result).toBe("3foobar"); + } + + @Test("Tuple Return vs Non-Tuple Return Overload") + public tupleReturnVsNonTupleReturnOverload(): void { + const luaHeader = + `function fn(a, b) + if type(a) == "number" then + return {a, a + 1} + else + return a, b + end + end`; + const tsHeader = + `declare function fn(this: void, a: number): [number, number]; + /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string];`; + const code = + `const [a, b] = fn(3); + const [c, d] = fn("foo", "bar"); + return (a + b) + c + d;`; + const result = util.transpileAndExecute(code, undefined, luaHeader, tsHeader); + Expect(result).toBe("7foobar"); + } } From a200793778df43069a3a082c7f5e942c6239f320 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 27 Mar 2019 02:14:50 +0500 Subject: [PATCH 039/764] Migrate tests to Jest (#491) * Migrate tests to Jest * Fix formatting of some code literals * Update contributing docs * Load ts-node in the fork call in watchmode test * Change test directory in configs * Revisit toThrowExactError matcher * Use toThrowExactError on TSTLErrors in tests * Increase timeout for watchmode test since it may fail sometimes * Execute TypeScript's Opganize Imports command * Split assignments tests to improve parallel testing performance * Add skipLibCheck flag to tests * Inline lualib by default in tests * Remove test-fast script * Remove ignoreDiagnostics option from transpileAndExecute * Remove @ts-check from jest config file * Add (%p) to set size test name * Format some code literals * Revert formatting changes in characterEscapeSequence translation test * Add pretest script to build lualib * Improve performance of build_lualib script * Re-enable type checking for build-lualib script * Use jest's snapshot testing for translation tests * Use regular --watch flag instead of --watchAll in contributing docs * Sort transformation test fixture names --- .editorconfig | 2 +- .gitignore | 22 +- .prettierignore | 7 + .travis.yml | 14 +- CONTRIBUTING.md | 55 +- appveyor.yml | 2 +- build_lualib.ts | 7 +- jest.config.js | 18 + package-lock.json | 6114 +++++++++++++---- package.json | 58 +- src/CommandLineParser.ts | 3 +- src/Compiler.ts | 31 +- src/LuaPrinter.ts | 6 +- src/LuaTransformer.ts | 13 +- src/LuaTranspiler.ts | 8 +- src/TSHelper.ts | 4 +- src/TSTLErrors.ts | 5 +- src/TranspileError.ts | 5 +- src/index.ts | 10 +- src/tstl.ts | 2 +- test/compiler/errorreport.spec.ts | 64 +- test/compiler/outfile.spec.ts | 86 +- test/compiler/project.spec.ts | 160 +- test/compiler/projects/baseurl/tsconfig.json | 2 + .../projects/basic/test_src/test_lib/file.ts | 2 +- .../basic/tsconfig.bothDirOptions.json | 0 test/compiler/projects/basic/tsconfig.json | 6 +- .../projects/basic/tsconfig.outDir.json | 0 .../projects/basic/tsconfig.rootDir.json | 0 .../compiler/projects/watchmode/tsconfig.json | 6 +- test/compiler/projects/watchmode/watch.ts | 2 +- test/compiler/testfiles/out_file.ts | 4 +- test/compiler/testfiles/watch.ts | 2 +- test/compiler/watchmode.spec.ts | 110 +- test/{src => }/json.lua | 0 test/runner.ts | 63 - test/test_thread.ts | 36 - test/threaded_runner.ts | 83 - .../__snapshots__/transformation.spec.ts.snap | 638 ++ test/translation/builder.spec.ts | 49 - test/translation/lua/callNamespace.lua | 1 - .../lua/characterEscapeSequence.lua | 12 - test/translation/lua/classExtension1.lua | 2 - test/translation/lua/classExtension2.lua | 2 - test/translation/lua/classExtension3.lua | 4 - test/translation/lua/classExtension4.lua | 4 - test/translation/lua/classPureAbstract.lua | 12 - test/translation/lua/continue.lua | 12 - test/translation/lua/continueConcurrent.lua | 15 - test/translation/lua/continueNested.lua | 24 - .../lua/continueNestedConcurrent.lua | 27 - test/translation/lua/do.lua | 7 - test/translation/lua/enum.lua | 7 - test/translation/lua/enumHeterogeneous.lua | 7 - test/translation/lua/enumMembersOnly.lua | 5 - test/translation/lua/enumString.lua | 7 - test/translation/lua/exportStatement.lua | 23 - test/translation/lua/for.lua | 9 - test/translation/lua/forIn.lua | 5 - test/translation/lua/forOf.lua | 7 - .../translation/lua/functionRestArguments.lua | 3 - test/translation/lua/getSetAccessors.lua | 26 - test/translation/lua/interfaceIndex.lua | 2 - test/translation/lua/methodRestArguments.lua | 15 - .../lua/modulesChangedVariableExport.lua | 3 - test/translation/lua/modulesClassExport.lua | 14 - .../lua/modulesClassWithMemberExport.lua | 16 - .../translation/lua/modulesFunctionExport.lua | 4 - .../lua/modulesFunctionNoExport.lua | 2 - test/translation/lua/modulesImportAll.lua | 1 - test/translation/lua/modulesImportNamed.lua | 2 - .../lua/modulesImportNamedSpecialChars.lua | 10 - test/translation/lua/modulesImportRenamed.lua | 2 - .../lua/modulesImportRenamedSpecialChars.lua | 10 - .../lua/modulesImportWithoutFromClause.lua | 1 - .../lua/modulesNamespaceExport.lua | 6 - .../lua/modulesNamespaceExportEnum.lua | 11 - ...modulesNamespaceNestedWithMemberExport.lua | 12 - .../lua/modulesNamespaceNoExport.lua | 3 - .../lua/modulesNamespaceWithMemberExport.lua | 8 - .../modulesNamespaceWithMemberNoExport.lua | 9 - .../translation/lua/modulesVariableExport.lua | 3 - .../lua/modulesVariableNoExport.lua | 1 - test/translation/lua/namespace.lua | 6 - test/translation/lua/namespaceMerge.lua | 35 - test/translation/lua/namespaceNested.lua | 10 - test/translation/lua/namespacePhantom.lua | 2 - test/translation/lua/returnDefault.lua | 3 - .../lua/shorthandPropertyAssignment.lua | 4 - test/translation/lua/tryCatch.lua | 8 - test/translation/lua/tryCatchFinally.lua | 11 - test/translation/lua/tryFinally.lua | 8 - test/translation/lua/tupleReturn.lua | 28 - test/translation/lua/typeAssert.lua | 2 - test/translation/lua/while.lua | 7 - test/translation/transformation.spec.ts | 16 + .../{ts => transformation}/callNamespace.ts | 2 +- .../characterEscapeSequence.ts | 4 +- .../{ts => transformation}/classExtension1.ts | 0 .../{ts => transformation}/classExtension2.ts | 3 +- .../{ts => transformation}/classExtension3.ts | 0 .../{ts => transformation}/classExtension4.ts | 0 .../classPureAbstract.ts | 2 +- .../{ts => transformation}/continue.ts | 0 .../continueConcurrent.ts | 0 .../{ts => transformation}/continueNested.ts | 0 .../continueNestedConcurrent.ts | 0 test/translation/transformation/do.ts | 4 + .../{ts => transformation}/enum.ts | 4 +- .../transformation/enumHeterogeneous.ts | 5 + .../{ts => transformation}/enumMembersOnly.ts | 0 test/translation/transformation/enumString.ts | 5 + .../transformation/exportStatement.ts | 6 + test/translation/transformation/for.ts | 1 + test/translation/transformation/forIn.ts | 7 + .../{ts => transformation}/forOf.ts | 0 .../functionRestArguments.ts | 0 .../{ts => transformation}/getSetAccessors.ts | 4 +- .../{ts => transformation}/interfaceIndex.ts | 0 .../methodRestArguments.ts | 0 .../modulesChangedVariableExport.ts | 2 + .../modulesClassExport.ts | 0 .../modulesClassWithMemberExport.ts | 0 .../modulesFunctionExport.ts | 0 .../modulesFunctionNoExport.ts | 0 .../transformation/modulesImportAll.ts | 1 + .../transformation/modulesImportNamed.ts | 1 + .../modulesImportNamedSpecialChars.ts | 5 + .../transformation/modulesImportRenamed.ts | 1 + .../modulesImportRenamedSpecialChars.ts | 5 + .../modulesImportWithoutFromClause.ts | 0 .../modulesNamespaceExport.ts | 0 .../modulesNamespaceExportEnum.ts | 6 + .../modulesNamespaceNestedWithMemberExport.ts | 0 .../modulesNamespaceNoExport.ts | 0 .../modulesNamespaceWithMemberExport.ts | 0 .../modulesNamespaceWithMemberNoExport.ts | 0 .../transformation/modulesVariableExport.ts | 1 + .../transformation/modulesVariableNoExport.ts | 1 + .../{ts => transformation}/namespace.ts | 2 +- .../{ts => transformation}/namespaceMerge.ts | 0 .../{ts => transformation}/namespaceNested.ts | 0 .../namespacePhantom.ts | 2 +- .../{ts => transformation}/returnDefault.ts | 0 .../shorthandPropertyAssignment.ts | 0 .../{ts => transformation}/tryCatch.ts | 0 .../{ts => transformation}/tryCatchFinally.ts | 0 .../{ts => transformation}/tryFinally.ts | 0 .../{ts => transformation}/tupleReturn.ts | 68 +- .../{ts => transformation}/typeAssert.ts | 2 +- .../{ts => transformation}/while.ts | 2 +- test/translation/ts/do.ts | 4 - test/translation/ts/enumHeterogeneous.ts | 5 - test/translation/ts/enumString.ts | 5 - test/translation/ts/exportStatement.ts | 6 - test/translation/ts/for.ts | 2 - test/translation/ts/forIn.ts | 7 - .../ts/modulesChangedVariableExport.ts | 2 - test/translation/ts/modulesImportAll.ts | 1 - test/translation/ts/modulesImportNamed.ts | 1 - .../ts/modulesImportNamedSpecialChars.ts | 5 - test/translation/ts/modulesImportRenamed.ts | 1 - .../ts/modulesImportRenamedSpecialChars.ts | 5 - .../ts/modulesNamespaceExportEnum.ts | 6 - test/translation/ts/modulesVariableExport.ts | 1 - .../translation/ts/modulesVariableNoExport.ts | 1 - test/tsconfig.json | 11 +- test/tslint.json | 59 + test/unit/accessors.spec.ts | 765 +-- test/unit/array.spec.ts | 288 +- test/unit/assignmentDestructuring.spec.ts | 104 +- test/unit/assignments.spec.ts | 1196 ---- test/unit/assignments/assignments.spec.ts | 196 + .../functionExpressionTypeInference.spec.ts | 344 + test/unit/assignments/functionPermutations.ts | 411 ++ .../invalidFunctionAssignments.spec.ts | 206 + .../validFunctionAssignments.spec.ts | 233 + test/unit/bindingpatterns.spec.ts | 135 +- test/unit/class.spec.ts | 1573 ++--- test/unit/commandLineParser.spec.ts | 478 +- .../configuration/mixed/index.spec.ts | 69 +- .../compiler/configuration/options.spec.ts | 38 +- test/unit/conditionals.spec.ts | 706 +- test/unit/console.spec.ts | 130 +- test/unit/curry.spec.ts | 25 +- test/unit/declarations.spec.ts | 216 +- test/unit/decoratorCustomConstructor.spec.ts | 89 +- test/unit/decoratorMetaExtension.spec.ts | 98 +- test/unit/enum.spec.ts | 363 +- test/unit/error.spec.ts | 86 +- test/unit/expressions.spec.ts | 1060 +-- test/unit/functions.spec.ts | 785 +-- test/unit/hoisting.spec.ts | 488 +- test/unit/importexport.spec.ts | 25 +- test/unit/json.spec.ts | 41 +- test/unit/loops.spec.ts | 1275 ++-- test/unit/lualib/inlining.spec.ts | 92 +- test/unit/lualib/lualib.spec.ts | 917 ++- test/unit/lualib/map.spec.ts | 318 +- test/unit/lualib/set.spec.ts | 282 +- test/unit/lualib/symbol.spec.ts | 119 +- test/unit/lualib/weakMap.spec.ts | 256 +- test/unit/lualib/weakSet.spec.ts | 140 +- test/unit/math.spec.ts | 485 +- test/unit/modules.spec.ts | 117 +- test/unit/objectLiteral.spec.ts | 52 +- test/unit/overloads.spec.ts | 194 +- test/unit/require.spec.ts | 145 +- test/unit/spreadElement.spec.ts | 76 +- test/unit/string.spec.ts | 596 +- test/unit/tshelper.spec.ts | 303 +- test/unit/tuples.spec.ts | 723 +- test/unit/typechecking.spec.ts | 261 +- test/{src => }/util.ts | 146 +- tsconfig.json | 9 +- tslint.json | 68 +- 216 files changed, 14186 insertions(+), 10999 deletions(-) create mode 100644 .prettierignore create mode 100644 jest.config.js mode change 100755 => 100644 test/compiler/projects/basic/test_src/test_lib/file.ts mode change 100755 => 100644 test/compiler/projects/basic/tsconfig.bothDirOptions.json mode change 100755 => 100644 test/compiler/projects/basic/tsconfig.json mode change 100755 => 100644 test/compiler/projects/basic/tsconfig.outDir.json mode change 100755 => 100644 test/compiler/projects/basic/tsconfig.rootDir.json rename test/{src => }/json.lua (100%) delete mode 100644 test/runner.ts delete mode 100644 test/test_thread.ts delete mode 100644 test/threaded_runner.ts create mode 100644 test/translation/__snapshots__/transformation.spec.ts.snap delete mode 100644 test/translation/builder.spec.ts delete mode 100644 test/translation/lua/callNamespace.lua delete mode 100644 test/translation/lua/characterEscapeSequence.lua delete mode 100644 test/translation/lua/classExtension1.lua delete mode 100644 test/translation/lua/classExtension2.lua delete mode 100644 test/translation/lua/classExtension3.lua delete mode 100644 test/translation/lua/classExtension4.lua delete mode 100644 test/translation/lua/classPureAbstract.lua delete mode 100644 test/translation/lua/continue.lua delete mode 100644 test/translation/lua/continueConcurrent.lua delete mode 100644 test/translation/lua/continueNested.lua delete mode 100644 test/translation/lua/continueNestedConcurrent.lua delete mode 100644 test/translation/lua/do.lua delete mode 100644 test/translation/lua/enum.lua delete mode 100644 test/translation/lua/enumHeterogeneous.lua delete mode 100644 test/translation/lua/enumMembersOnly.lua delete mode 100644 test/translation/lua/enumString.lua delete mode 100644 test/translation/lua/exportStatement.lua delete mode 100644 test/translation/lua/for.lua delete mode 100644 test/translation/lua/forIn.lua delete mode 100644 test/translation/lua/forOf.lua delete mode 100644 test/translation/lua/functionRestArguments.lua delete mode 100644 test/translation/lua/getSetAccessors.lua delete mode 100644 test/translation/lua/interfaceIndex.lua delete mode 100644 test/translation/lua/methodRestArguments.lua delete mode 100644 test/translation/lua/modulesChangedVariableExport.lua delete mode 100644 test/translation/lua/modulesClassExport.lua delete mode 100644 test/translation/lua/modulesClassWithMemberExport.lua delete mode 100644 test/translation/lua/modulesFunctionExport.lua delete mode 100644 test/translation/lua/modulesFunctionNoExport.lua delete mode 100644 test/translation/lua/modulesImportAll.lua delete mode 100644 test/translation/lua/modulesImportNamed.lua delete mode 100644 test/translation/lua/modulesImportNamedSpecialChars.lua delete mode 100644 test/translation/lua/modulesImportRenamed.lua delete mode 100644 test/translation/lua/modulesImportRenamedSpecialChars.lua delete mode 100644 test/translation/lua/modulesImportWithoutFromClause.lua delete mode 100644 test/translation/lua/modulesNamespaceExport.lua delete mode 100644 test/translation/lua/modulesNamespaceExportEnum.lua delete mode 100644 test/translation/lua/modulesNamespaceNestedWithMemberExport.lua delete mode 100644 test/translation/lua/modulesNamespaceNoExport.lua delete mode 100644 test/translation/lua/modulesNamespaceWithMemberExport.lua delete mode 100644 test/translation/lua/modulesNamespaceWithMemberNoExport.lua delete mode 100644 test/translation/lua/modulesVariableExport.lua delete mode 100644 test/translation/lua/modulesVariableNoExport.lua delete mode 100644 test/translation/lua/namespace.lua delete mode 100644 test/translation/lua/namespaceMerge.lua delete mode 100644 test/translation/lua/namespaceNested.lua delete mode 100644 test/translation/lua/namespacePhantom.lua delete mode 100644 test/translation/lua/returnDefault.lua delete mode 100644 test/translation/lua/shorthandPropertyAssignment.lua delete mode 100644 test/translation/lua/tryCatch.lua delete mode 100644 test/translation/lua/tryCatchFinally.lua delete mode 100644 test/translation/lua/tryFinally.lua delete mode 100644 test/translation/lua/tupleReturn.lua delete mode 100644 test/translation/lua/typeAssert.lua delete mode 100644 test/translation/lua/while.lua create mode 100644 test/translation/transformation.spec.ts rename test/translation/{ts => transformation}/callNamespace.ts (71%) rename test/translation/{ts => transformation}/characterEscapeSequence.ts (84%) rename test/translation/{ts => transformation}/classExtension1.ts (100%) rename test/translation/{ts => transformation}/classExtension2.ts (83%) rename test/translation/{ts => transformation}/classExtension3.ts (100%) rename test/translation/{ts => transformation}/classExtension4.ts (100%) rename test/translation/{ts => transformation}/classPureAbstract.ts (59%) rename test/translation/{ts => transformation}/continue.ts (100%) rename test/translation/{ts => transformation}/continueConcurrent.ts (100%) rename test/translation/{ts => transformation}/continueNested.ts (100%) rename test/translation/{ts => transformation}/continueNestedConcurrent.ts (100%) create mode 100644 test/translation/transformation/do.ts rename test/translation/{ts => transformation}/enum.ts (78%) create mode 100644 test/translation/transformation/enumHeterogeneous.ts rename test/translation/{ts => transformation}/enumMembersOnly.ts (100%) create mode 100644 test/translation/transformation/enumString.ts create mode 100644 test/translation/transformation/exportStatement.ts create mode 100644 test/translation/transformation/for.ts create mode 100644 test/translation/transformation/forIn.ts rename test/translation/{ts => transformation}/forOf.ts (100%) rename test/translation/{ts => transformation}/functionRestArguments.ts (100%) rename test/translation/{ts => transformation}/getSetAccessors.ts (78%) rename test/translation/{ts => transformation}/interfaceIndex.ts (100%) rename test/translation/{ts => transformation}/methodRestArguments.ts (100%) create mode 100644 test/translation/transformation/modulesChangedVariableExport.ts rename test/translation/{ts => transformation}/modulesClassExport.ts (100%) rename test/translation/{ts => transformation}/modulesClassWithMemberExport.ts (100%) rename test/translation/{ts => transformation}/modulesFunctionExport.ts (100%) rename test/translation/{ts => transformation}/modulesFunctionNoExport.ts (100%) create mode 100644 test/translation/transformation/modulesImportAll.ts create mode 100644 test/translation/transformation/modulesImportNamed.ts create mode 100644 test/translation/transformation/modulesImportNamedSpecialChars.ts create mode 100644 test/translation/transformation/modulesImportRenamed.ts create mode 100644 test/translation/transformation/modulesImportRenamedSpecialChars.ts rename test/translation/{ts => transformation}/modulesImportWithoutFromClause.ts (100%) rename test/translation/{ts => transformation}/modulesNamespaceExport.ts (100%) create mode 100644 test/translation/transformation/modulesNamespaceExportEnum.ts rename test/translation/{ts => transformation}/modulesNamespaceNestedWithMemberExport.ts (100%) rename test/translation/{ts => transformation}/modulesNamespaceNoExport.ts (100%) rename test/translation/{ts => transformation}/modulesNamespaceWithMemberExport.ts (100%) rename test/translation/{ts => transformation}/modulesNamespaceWithMemberNoExport.ts (100%) create mode 100644 test/translation/transformation/modulesVariableExport.ts create mode 100644 test/translation/transformation/modulesVariableNoExport.ts rename test/translation/{ts => transformation}/namespace.ts (96%) rename test/translation/{ts => transformation}/namespaceMerge.ts (100%) rename test/translation/{ts => transformation}/namespaceNested.ts (100%) rename test/translation/{ts => transformation}/namespacePhantom.ts (97%) rename test/translation/{ts => transformation}/returnDefault.ts (100%) rename test/translation/{ts => transformation}/shorthandPropertyAssignment.ts (100%) rename test/translation/{ts => transformation}/tryCatch.ts (100%) rename test/translation/{ts => transformation}/tryCatchFinally.ts (100%) rename test/translation/{ts => transformation}/tryFinally.ts (100%) rename test/translation/{ts => transformation}/tupleReturn.ts (96%) rename test/translation/{ts => transformation}/typeAssert.ts (50%) rename test/translation/{ts => transformation}/while.ts (76%) delete mode 100644 test/translation/ts/do.ts delete mode 100644 test/translation/ts/enumHeterogeneous.ts delete mode 100644 test/translation/ts/enumString.ts delete mode 100644 test/translation/ts/exportStatement.ts delete mode 100644 test/translation/ts/for.ts delete mode 100644 test/translation/ts/forIn.ts delete mode 100644 test/translation/ts/modulesChangedVariableExport.ts delete mode 100644 test/translation/ts/modulesImportAll.ts delete mode 100644 test/translation/ts/modulesImportNamed.ts delete mode 100644 test/translation/ts/modulesImportNamedSpecialChars.ts delete mode 100644 test/translation/ts/modulesImportRenamed.ts delete mode 100644 test/translation/ts/modulesImportRenamedSpecialChars.ts delete mode 100644 test/translation/ts/modulesNamespaceExportEnum.ts delete mode 100644 test/translation/ts/modulesVariableExport.ts delete mode 100644 test/translation/ts/modulesVariableNoExport.ts create mode 100644 test/tslint.json delete mode 100644 test/unit/assignments.spec.ts create mode 100644 test/unit/assignments/assignments.spec.ts create mode 100644 test/unit/assignments/functionExpressionTypeInference.spec.ts create mode 100644 test/unit/assignments/functionPermutations.ts create mode 100644 test/unit/assignments/invalidFunctionAssignments.spec.ts create mode 100644 test/unit/assignments/validFunctionAssignments.spec.ts rename test/{src => }/util.ts (51%) diff --git a/.editorconfig b/.editorconfig index 69fbfa8bc..ceeeb10cd 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,5 +8,5 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[*.yml] +[*.{yml,md}] indent_size = 2 diff --git a/.gitignore b/.gitignore index 987b45888..0878aa261 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,10 @@ -*.js -node_modules/ -yarn.lock - -.vscode/ +/node_modules +/dist +/coverage -coverage/ -.nyc* -*.js.map +yarn.lock +.vscode +.idea # Release *.tgz @@ -14,11 +12,3 @@ coverage/ # OSX .DS_Store *.lcov - -# IDEA IDEs -.idea/ - -typescript_lualib.lua -lualib_bundle.lua - -dist/* diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000..a9b94c668 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,7 @@ +/dist +/coverage +/test/compiler/testfiles/invalid_syntax.ts +/test/translation/transformation/characterEscapeSequence.ts + +/src +*.md diff --git a/.travis.yml b/.travis.yml index 14b56e048..79fcbeed8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ language: node_js node_js: -- stable -install: -- npm install + - stable + script: -- npm run build -- npm run coverage -after_success: -- codecov + - npm run lint + - npm run build + - npm test -- --coverage +after_success: npx codecov + deploy: provider: npm email: lorenz.junglas@student.kit.edu diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 13f2db018..d298d2374 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,59 +14,36 @@ To get familiar with the project structure, here is a short overview of each dir * `src/targets/` - Version-specific transpiler overrides for the different Lua targets. The main transpiler transpiles Lua 5.0, each target-specific transpiler extends the transpiler of the version before it, so the 5.3 inherits 5.2 which inherits 5.1 which inherits 5.0. LuaJIT is based on 5.2 so inherits from the 5.2 transpiler. * *Compiler.ts* - Main entry point of the transpiler, this is what interfaces with the TypeScript compiler API. - * *Transpiler.ts* - Main transpiler code, transforms a TypeScript AST to a Lua string. + * *LuaTransformer.ts* - Main transpiler code, transforms a TypeScript AST to a Lua AST. + * *LuaPrinter.ts* - Transforms a Lua AST to a string. * *TSHelper.ts* - Helper methods used during the transpilation process. - `test/` * This directory contains all testing code for the transpiler. - * `test/src/` - - Contains all extra source and utility used to run tests. * `test/unit/` - Unit/Functional tests for the transpiler. Tests in here are grouped by functionality they are testing. Generally each of these tests uses the transpiler to transpile some TypeScript to Lua, then executes it using the Fengari Lua VM. Assertion is done on the result of the lua code. * `test/translation/` - **[Obsolete]** Contains tests that only check the transpiled Lua String. We prefer adding unit/functional tests over translation tests. This directory will probably be removed at some point. ## Running Tests -The tests for this project can be executed using the standard `npm test`. This runs all tests (can take a while!). +The tests for this project can be executed using the standard `npm test`. This runs all tests. -### Testing while developing -Due to the time required to run all tests, it is impractical to run every test while developing part of the transpiler. To speed up the test run you can import `FocusTest` or `FocusTests` from Alsatian. If a class is decorated with `@FocusTests`, all other test classes will be ignored. Similarly, if any test method is decorated with `@FocusTest`, only `@FocusTest` methods will be run during `npm test`. +Due to the time required to run all tests, it is impractical to run every test while developing part of the transpiler. To speed up the test run you can: -For example: -```ts -import { Expect, FocusTests, Test, TestCase } from "alsatian"; +- Use `npm test name` to run tests that match a file name pattern -@FocusTests -export class FunctionTests { - // All tests in here will be executed. -} +- Use `npm test -- --watch [name]` to start tests and rerun them on change -// All other tests will be ignored. -``` +- Check out `Watch Usage` in the watching interface to get information about filtering tests without restarting CLI -Or +- Use `.only` and `.skip` to filter executed tests in the file -```ts -import { Expect, FocusTest, Test, TestCase } from "alsatian"; - -export class FunctionTests { - @FocusTest - @Test("Example test 1") - public test1(): void { // Will be executed - } - - @FocusTest - @Test("Example test 2") - public test2(): void { // Will also be executed - } - - @Test("Example test 3") - public test3(): void { // Will be ignored - } -} - -// All other tests will be ignored. -``` + ```ts + // Skipped + test("test", () => {}); + // Executed + test.only("test", () => {}); + ``` ## Testing Guidelines When submitting a pull request with new functionality, we require some functional (transpile and execute Lua) to be added, to ensure the new functionality works as expected, and will continue to work that way. @@ -74,7 +51,9 @@ When submitting a pull request with new functionality, we require some functiona Translation tests are discouraged as in most cases as we do not really care about the exact Lua output, as long as executing it results in the correct result (which is tested by functional tests). ## Coding Conventions -Most coding conventions are enforced by the ts-lint configuration. The test process will fail if code does not pass the linter. Some extra conventions worth mentioning: +Most coding conventions are enforced by the TSLint and Prettier. You can check your code locally by running `npm run lint`. The CI build will fail if your code does not pass the linter. For better experience, you can install extensions for your code editor for [TSLint](https://palantir.github.io/tslint/usage/third-party-tools/) and [Prettier](https://prettier.io/docs/en/editors.html). + +Some extra conventions worth mentioning: * Do not abbreviate variable names. The exception here are inline lambda arguments, if it is obvious what the argument is you can abbreviate to the first letter, e.g: `statements.filter(s => ts.VariableStatement(s))` * Readability of code is more important than the amount of space it takes. If extra line breaks make your code more readable, add them. * Functional style is encouraged! diff --git a/appveyor.yml b/appveyor.yml index 513dd7593..6ae337099 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -11,7 +11,7 @@ install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version # install modules - - npm install + - npm ci # Post-install test scripts. test_script: diff --git a/build_lualib.ts b/build_lualib.ts index 7ca05f26f..f968f5968 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -1,11 +1,14 @@ import * as fs from "fs"; import * as glob from "glob"; -import {compile} from "./src/Compiler"; -import {LuaLib as luaLib, LuaLibFeature} from "./src/LuaLib"; +import { compile } from "./src/Compiler"; +import { LuaLib as luaLib, LuaLibFeature } from "./src/LuaLib"; const bundlePath = "./dist/lualib/lualib_bundle.lua"; compile([ + "--skipLibCheck", + "--types", + "node", "--luaLibImport", "none", "--luaTarget", diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..8afb70bd0 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,18 @@ +const isCI = require("is-ci"); + +/** @type {Partial} */ +module.exports = { + testMatch: ["**/test/**/*.spec.ts"], + collectCoverageFrom: ["/src/**/*", "!/src/lualib/**/*"], + watchPathIgnorePatterns: ["/watch\\.ts$"], + + testEnvironment: "node", + testRunner: "jest-circus/runner", + preset: "ts-jest", + globals: { + "ts-jest": { + tsConfig: "/test/tsconfig.json", + diagnostics: { warnOnly: !isCI }, + }, + }, +}; diff --git a/package-lock.json b/package-lock.json index 0d029c704..861f7a478 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,103 @@ "@babel/highlight": "^7.0.0" } }, + "@babel/core": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.0.tgz", + "integrity": "sha512-Dzl7U0/T69DFOTwqz/FJdnOSWS57NpjNfCwMKHABr589Lg8uX1RrlBIJ7L5Dubt/xkLsx0xH5EBFzlBVes1ayA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helpers": "^7.4.0", + "@babel/parser": "^7.4.0", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.0", + "@babel/types": "^7.4.0", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", + "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", + "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0" + } + }, + "@babel/parser": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.2.tgz", + "integrity": "sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==", + "dev": true + }, + "@babel/template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", + "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/traverse": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.0.tgz", + "integrity": "sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", + "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, "@babel/generator": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", @@ -54,6 +151,12 @@ "@babel/types": "^7.0.0" } }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, "@babel/helper-split-export-declaration": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", @@ -63,6 +166,92 @@ "@babel/types": "^7.0.0" } }, + "@babel/helpers": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.2.tgz", + "integrity": "sha512-gQR1eQeroDzFBikhrCccm5Gs2xBjZ57DNjGbqTaHo911IpmSxflOQWMAHPw/TXk8L3isv7s9lYzUkexOeTQUYg==", + "dev": true, + "requires": { + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.0", + "@babel/types": "^7.4.0" + }, + "dependencies": { + "@babel/generator": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", + "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", + "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", + "dev": true, + "requires": { + "@babel/types": "^7.4.0" + } + }, + "@babel/parser": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.2.tgz", + "integrity": "sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==", + "dev": true + }, + "@babel/template": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", + "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0" + } + }, + "@babel/traverse": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.0.tgz", + "integrity": "sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.0", + "@babel/parser": "^7.4.0", + "@babel/types": "^7.4.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + } + }, + "@babel/types": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", + "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", @@ -117,6 +306,15 @@ "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", "dev": true }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/template": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", @@ -156,1535 +354,3690 @@ "to-fast-properties": "^2.0.0" } }, - "@types/events": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", - "dev": true - }, - "@types/glob": { - "version": "5.0.35", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.35.tgz", - "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", - "dev": true, - "requires": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true - }, - "@types/node": { - "version": "9.6.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.23.tgz", - "integrity": "sha512-d2SJJpwkiPudEQ3+9ysANN2Nvz4QJKUPoe/WL5zyQzI0RaEeZWH5K5xjvUIGszTItHQpFPdH+u51f6G/LkS8Cg==", - "dev": true - }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "alsatian": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/alsatian/-/alsatian-2.3.0.tgz", - "integrity": "sha512-e83K7JpH9Hj1+TUYyZialNKDln5gW56C82CVcd0AMt2whLFtKzYiddE5Dz2biUWjT8KzF11lkwonzf9wOCQyAA==", + "@cnakazawa/watch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", + "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", "dev": true, "requires": { - "@types/node": ">=4.0.0", - "extendo-error": "^1.0.1", - "glob": "^7.0.3", - "reflect-metadata": "^0.1.3", - "tap-bark": "1.0.0" + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "@jest/console": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.3.0.tgz", + "integrity": "sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "@jest/source-map": "^24.3.0", + "@types/node": "*", + "chalk": "^2.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "argv": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/argv/-/argv-0.0.2.tgz", - "integrity": "sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "@jest/core": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.5.0.tgz", + "integrity": "sha512-RDZArRzAs51YS7dXG1pbXbWGxK53rvUu8mCDYsgqqqQ6uSOaTjcVyBl2Jce0exT2rSLk38ca7az7t2f3b0/oYQ==", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "@jest/console": "^24.3.0", + "@jest/reporters": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/transform": "^24.5.0", + "@jest/types": "^24.5.0", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-changed-files": "^24.5.0", + "jest-config": "^24.5.0", + "jest-haste-map": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-regex-util": "^24.3.0", + "jest-resolve-dependencies": "^24.5.0", + "jest-runner": "^24.5.0", + "jest-runtime": "^24.5.0", + "jest-snapshot": "^24.5.0", + "jest-util": "^24.5.0", + "jest-validate": "^24.5.0", + "jest-watcher": "^24.5.0", + "micromatch": "^3.1.10", + "p-each-series": "^1.0.0", + "pirates": "^4.0.1", + "realpath-native": "^1.1.0", + "rimraf": "^2.5.4", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "@jest/environment": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.5.0.tgz", + "integrity": "sha512-tzUHR9SHjMXwM8QmfHb/EJNbF0fjbH4ieefJBvtwO8YErLTrecc1ROj0uo2VnIT6SlpEGZnvdCK6VgKYBo8LsA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@jest/fake-timers": "^24.5.0", + "@jest/transform": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/node": "*", + "jest-mock": "^24.5.0" } }, - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "@jest/fake-timers": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.5.0.tgz", + "integrity": "sha512-i59KVt3QBz9d+4Qr4QxsKgsIg+NjfuCjSOWj3RQhjF5JNy+eVJDhANQ4WzulzNCHd72srMAykwtRn5NYDGVraw==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "@jest/types": "^24.5.0", + "@types/node": "*", + "jest-message-util": "^24.5.0", + "jest-mock": "^24.5.0" } }, - "codecov": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/codecov/-/codecov-3.2.0.tgz", - "integrity": "sha512-3NJvNARXxilqnqVfgzDHyVrF4oeVgaYW1c1O6Oi5mn93exE7HTSSFNiYdwojWW6IwrCZABJ8crpNbKoo9aUHQw==", + "@jest/reporters": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.5.0.tgz", + "integrity": "sha512-vfpceiaKtGgnuC3ss5czWOihKOUSyjJA4M4udm6nH8xgqsuQYcyDCi4nMMcBKsHXWgz9/V5G7iisnZGfOh1w6Q==", "dev": true, "requires": { - "argv": "^0.0.2", - "ignore-walk": "^3.0.1", - "js-yaml": "^3.12.0", - "teeny-request": "^3.7.0", - "urlgrey": "^0.4.4" + "@jest/environment": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/transform": "^24.5.0", + "@jest/types": "^24.5.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "istanbul-api": "^2.1.1", + "istanbul-lib-coverage": "^2.0.2", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-source-maps": "^3.0.1", + "jest-haste-map": "^24.5.0", + "jest-resolve": "^24.5.0", + "jest-runtime": "^24.5.0", + "jest-util": "^24.5.0", + "jest-worker": "^24.4.0", + "node-notifier": "^5.2.1", + "slash": "^2.0.0", + "source-map": "^0.6.0", + "string-length": "^2.0.0" }, "dependencies": { - "js-yaml": { - "version": "3.12.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", - "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", - "dev": true, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" } } } }, - "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "@jest/source-map": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", + "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", "dev": true, "requires": { - "color-name": "1.1.1" + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" } }, - "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", - "dev": true + "@jest/test-result": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.5.0.tgz", + "integrity": "sha512-u66j2vBfa8Bli1+o3rCaVnVYa9O8CAFZeqiqLVhnarXtreSXG33YQ6vNYBogT7+nYiFNOohTU21BKiHlgmxD5A==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/types": "^24.5.0", + "@types/istanbul-lib-coverage": "^1.1.0" + } }, - "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", - "dev": true + "@jest/transform": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.5.0.tgz", + "integrity": "sha512-XSsDz1gdR/QMmB8UCKlweAReQsZrD/DK7FuDlNo/pE8EcKMrfi2kqLRk8h8Gy/PDzgqJj64jNEzOce9pR8oj1w==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.5.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.5.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.5.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "@jest/types": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.5.0.tgz", + "integrity": "sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^1.1.0", + "@types/yargs": "^12.0.9" + } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true + "@types/babel__core": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz", + "integrity": "sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "@types/babel__generator": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz", + "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "@babel/types": "^7.0.0" } }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true + "@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } }, - "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", - "dev": true + "@types/babel__traverse": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", + "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } }, - "duplexer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", - "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", "dev": true }, - "es6-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz", - "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==", + "@types/glob": { + "version": "5.0.35", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.35.tgz", + "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", + "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==", "dev": true }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "@types/jest": { + "version": "24.0.11", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.11.tgz", + "integrity": "sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ==", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "@types/jest-diff": "*" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "@types/jest-diff": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", + "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", "dev": true }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "@types/node": { + "version": "9.6.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.23.tgz", + "integrity": "sha512-d2SJJpwkiPudEQ3+9ysANN2Nvz4QJKUPoe/WL5zyQzI0RaEeZWH5K5xjvUIGszTItHQpFPdH+u51f6G/LkS8Cg==", "dev": true }, - "eventemitter3": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", - "integrity": "sha1-teEHm1n7XhuidxwKmTvgYKWMmbo=", + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "events-to-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", - "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", + "@types/yargs": { + "version": "12.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.10.tgz", + "integrity": "sha512-WsVzTPshvCSbHThUduGGxbmnwcpkgSctHGHTqzWyFg4lYAuV5qXlyFPOsP3OWqCINfmg/8VXP+zJaa4OxEsBQQ==", "dev": true }, - "extendo-error": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/extendo-error/-/extendo-error-1.0.1.tgz", - "integrity": "sha1-MDJeDPbC+l+RAj0hAO0CGCbmMX0=", + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", "dev": true }, - "fengari": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.2.tgz", - "integrity": "sha512-NleQtQymPtbjBPnGOQiXfZfKpP3R7si+Sbkke631PWNnZt86eZSlymRJ0qv/KUTcz0fSsWO1iltZYz5/JV1uYQ==", + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", + "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", "dev": true, "requires": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" }, "dependencies": { - "sprintf-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", - "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true } } }, - "flatted": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", - "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", "dev": true }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, - "https-proxy-agent": { + "ansi-styles": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, - "ignore-walk": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "append-transform": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", + "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { - "minimatch": "^3.0.4" + "default-require-extensions": "^2.0.0" } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "sprintf-js": "~1.0.2" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true }, - "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "istanbul-lib-instrument": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", - "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", - "dev": true, - "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.3", - "semver": "^5.5.0" - } + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "safer-buffer": "~2.1.0" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "lodash": "^4.17.11" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", "dev": true }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, - "native-promise-only": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/native-promise-only/-/native-promise-only-0.8.1.tgz", - "integrity": "sha1-IKMYwwy0X3H+et+/eyHJnBRy7xE=", + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, - "node-fetch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.3.0.tgz", - "integrity": "sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA==", + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "nyc": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.3.0.tgz", - "integrity": "sha512-P+FwIuro2aFG6B0Esd9ZDWUd51uZrAEoGutqZxzrVmYl3qSfkLgcQpBPBjtDFsUQLFY1dvTQJPOyeqr8S9GF8w==", + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "archy": "^1.0.0", - "arrify": "^1.0.1", - "caching-transform": "^3.0.1", - "convert-source-map": "^1.6.0", - "find-cache-dir": "^2.0.0", - "find-up": "^3.0.0", - "foreground-child": "^1.5.6", - "glob": "^7.1.3", - "istanbul-lib-coverage": "^2.0.3", - "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.1.0", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.1", - "make-dir": "^1.3.0", - "merge-source-map": "^1.1.0", - "resolve-from": "^4.0.0", - "rimraf": "^2.6.3", - "signal-exit": "^3.0.2", - "spawn-wrap": "^1.4.2", - "test-exclude": "^5.1.0", - "uuid": "^3.3.2", - "yargs": "^12.0.5", - "yargs-parser": "^11.1.1" + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "babel-jest": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.5.0.tgz", + "integrity": "sha512-0fKCXyRwxFTJL0UXDJiT2xYxO9Lu2vBd9n+cC+eDjESzcVG3s2DRGAxbzJX21fceB1WYoBjAh8pQ83dKcl003g==", + "dev": true, + "requires": { + "@jest/transform": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/babel__core": "^7.1.0", + "babel-plugin-istanbul": "^5.1.0", + "babel-preset-jest": "^24.3.0", + "chalk": "^2.4.2", + "slash": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "append-transform": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, - "archy": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "arrify": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "async": { - "version": "2.6.2", - "bundled": true, - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "caching-transform": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "hasha": "^3.0.0", - "make-dir": "^1.3.0", - "package-hash": "^3.0.0", - "write-file-atomic": "^2.3.0" - } - }, - "camelcase": { - "version": "5.0.0", - "bundled": true, - "dev": true - }, - "cliui": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - } - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "commander": { - "version": "2.17.1", - "bundled": true, - "dev": true, - "optional": true - }, - "commondir": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cross-spawn": { - "version": "4.0.2", - "bundled": true, - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "which": "^1.2.9" - } - }, - "debug": { - "version": "4.1.1", - "bundled": true, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "ms": "^2.1.1" + "color-convert": "^1.9.0" } }, - "decamelize": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "default-require-extensions": { - "version": "2.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "strip-bom": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "end-of-stream": { - "version": "1.4.1", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "once": "^1.4.0" + "has-flag": "^3.0.0" } - }, - "error-ex": { - "version": "1.3.2", - "bundled": true, + } + } + }, + "babel-plugin-istanbul": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz", + "integrity": "sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "istanbul-lib-instrument": "^3.0.0", + "test-exclude": "^5.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz", + "integrity": "sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w==", + "dev": true, + "requires": { + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-jest": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz", + "integrity": "sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw==", + "dev": true, + "requires": { + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "babel-plugin-jest-hoist": "^24.3.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-descriptor": "^1.0.0" } }, - "es6-error": { - "version": "4.1.1", - "bundled": true, - "dev": true - }, - "execa": { + "is-accessor-descriptor": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "6.0.5", - "bundled": true, - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - } + "kind-of": "^6.0.0" } }, - "find-cache-dir": { - "version": "2.0.0", - "bundled": true, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^3.0.0" + "kind-of": "^6.0.0" } }, - "find-up": { - "version": "3.0.0", - "bundled": true, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } - }, - "foreground-child": { - "version": "1.5.6", - "bundled": true, + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "cross-spawn": "^4", - "signal-exit": "^3.0.0" + "is-extendable": "^0.1.0" } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, + } + } + }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "bundled": true, + } + } + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", + "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "dev": true + }, + "camelcase": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", + "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", + "dev": true + }, + "capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "requires": { + "rsvp": "^4.8.4" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, - "get-stream": { - "version": "4.1.0", - "bundled": true, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", + "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "dev": true, + "requires": { + "color-name": "1.1.1" + } + }, + "color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", + "dev": true + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", + "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", + "dev": true + }, + "compare-versions": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.4.0.tgz", + "integrity": "sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg==", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "cssom": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "dev": true + }, + "cssstyle": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.1.tgz", + "integrity": "sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", + "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "pump": "^3.0.0" + "kind-of": "^6.0.0" } }, - "glob": { - "version": "7.1.3", - "bundled": true, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "diff": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", + "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "dev": true + }, + "diff-sequences": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.3.0.tgz", + "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", + "dev": true + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "exec-sh": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz", + "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expect": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.5.0.tgz", + "integrity": "sha512-p2Gmc0CLxOgkyA93ySWmHFYHUPFIHG6XZ06l7WArWAsrqYVaVEkOU5NtT5i68KUyGKbkQgDCkiT65bWmdoL6Bw==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.3.0", + "jest-matcher-utils": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-regex-util": "^24.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "requires": { + "bser": "^2.0.0" + } + }, + "fengari": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.2.tgz", + "integrity": "sha512-NleQtQymPtbjBPnGOQiXfZfKpP3R7si+Sbkke631PWNnZt86eZSlymRJ0qv/KUTcz0fSsWO1iltZYz5/JV1uYQ==", + "dev": true, + "requires": { + "readline-sync": "^1.4.9", + "sprintf-js": "^1.1.1", + "tmp": "^0.0.33" + }, + "dependencies": { + "sprintf-js": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", + "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", + "dev": true + } + } + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "handlebars": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.1.tgz", + "integrity": "sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-generator-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.0.0.tgz", + "integrity": "sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-api": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz", + "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==", + "dev": true, + "requires": { + "async": "^2.6.1", + "compare-versions": "^3.2.1", + "fileset": "^2.0.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.1.0", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.1", + "js-yaml": "^3.12.0", + "make-dir": "^1.3.0", + "minimatch": "^3.0.4", + "once": "^1.4.0" + }, + "dependencies": { + "js-yaml": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", + "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + } + } + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", + "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", + "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", + "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", + "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", + "dev": true, + "requires": { + "handlebars": "^4.1.0" + } + }, + "jest": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.5.0.tgz", + "integrity": "sha512-lxL+Fq5/RH7inxxmfS2aZLCf8MsS+YCUBfeiNO6BWz/MmjhDGaIEA/2bzEf9q4Q0X+mtFHiinHFvQ0u+RvW/qQ==", + "dev": true, + "requires": { + "import-local": "^2.0.0", + "jest-cli": "^24.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "graceful-fs": { - "version": "4.1.15", - "bundled": true, - "dev": true - }, - "handlebars": { - "version": "4.1.0", - "bundled": true, + "jest-cli": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.5.0.tgz", + "integrity": "sha512-P+Jp0SLO4KWN0cGlNtC7JV0dW1eSFR7eRpoOucP2UM0sqlzp/bVHeo71Omonvigrj9AvCKy7NtQANtqJ7FXz8g==", "dev": true, "requires": { - "async": "^2.5.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } + "@jest/core": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "import-local": "^2.0.0", + "is-ci": "^2.0.0", + "jest-config": "^24.5.0", + "jest-util": "^24.5.0", + "jest-validate": "^24.5.0", + "prompts": "^2.0.1", + "realpath-native": "^1.1.0", + "yargs": "^12.0.2" } }, - "has-flag": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "hasha": { - "version": "3.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "is-stream": "^1.0.1" + "has-flag": "^3.0.0" } - }, - "hosted-git-info": { - "version": "2.7.1", - "bundled": true, - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "bundled": true, - "dev": true - }, - "inflight": { - "version": "1.0.6", - "bundled": true, + } + } + }, + "jest-changed-files": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.5.0.tgz", + "integrity": "sha512-Ikl29dosYnTsH9pYa1Tv9POkILBhN/TLZ37xbzgNsZ1D2+2n+8oEZS2yP1BrHn/T4Rs4Ggwwbp/x8CKOS5YJOg==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "execa": "^1.0.0", + "throat": "^4.0.0" + } + }, + "jest-circus": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.5.0.tgz", + "integrity": "sha512-meGSoAA5rMv+93Wz8KY3FZcJ7aEbXqrgI2F/emPRCVzGXOvR8oQl8GvYBrIbpJW7G0vwnVSjLQMeTMHs1geu5g==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/node": "*", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.5.0", + "jest-matcher-utils": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-snapshot": "^24.5.0", + "jest-util": "^24.5.0", + "pretty-format": "^24.5.0", + "stack-utils": "^1.0.1", + "throat": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "color-convert": "^1.9.0" } }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "invert-kv": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "isexe": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "istanbul-lib-coverage": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "istanbul-lib-hook": { - "version": "2.0.3", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "append-transform": "^1.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "istanbul-lib-report": { - "version": "2.0.4", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "supports-color": "^6.0.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "bundled": true, - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "has-flag": "^3.0.0" } - }, - "istanbul-lib-source-maps": { - "version": "3.0.2", - "bundled": true, + } + } + }, + "jest-config": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.5.0.tgz", + "integrity": "sha512-t2UTh0Z2uZhGBNVseF8wA2DS2SuBiLOL6qpLq18+OZGfFUxTM7BzUVKyHFN/vuN+s/aslY1COW95j1Rw81huOQ==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.5.0", + "babel-jest": "^24.5.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.5.0", + "jest-environment-node": "^24.5.0", + "jest-get-type": "^24.3.0", + "jest-jasmine2": "^24.5.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.5.0", + "jest-util": "^24.5.0", + "jest-validate": "^24.5.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.5.0", + "realpath-native": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } + "color-convert": "^1.9.0" } }, - "istanbul-reports": { - "version": "2.1.1", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "handlebars": "^4.1.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "json-parse-better-errors": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "lcid": { - "version": "2.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "invert-kv": "^2.0.0" + "has-flag": "^3.0.0" } - }, - "load-json-file": { - "version": "4.0.0", - "bundled": true, + } + } + }, + "jest-diff": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.5.0.tgz", + "integrity": "sha512-mCILZd9r7zqL9Uh6yNoXjwGQx0/J43OD2vvWVKwOEOLZliQOsojXwqboubAQ+Tszrb6DHGmNU7m4whGeB9YOqw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.3.0", + "pretty-format": "^24.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "color-convert": "^1.9.0" } }, - "locate-path": { - "version": "3.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "lodash": { - "version": "4.17.11", - "bundled": true, - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "bundled": true, - "dev": true - }, - "lru-cache": { - "version": "4.1.5", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "has-flag": "^3.0.0" } - }, - "make-dir": { - "version": "1.3.0", - "bundled": true, + } + } + }, + "jest-docblock": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", + "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-each": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.5.0.tgz", + "integrity": "sha512-6gy3Kh37PwIT5sNvNY2VchtIFOOBh8UCYnBlxXMb5sr5wpJUDPTUATX2Axq1Vfk+HWTMpsYPeVYp4TXx5uqUBw==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.3.0", + "jest-util": "^24.5.0", + "pretty-format": "^24.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "pify": "^3.0.0" + "color-convert": "^1.9.0" } }, - "map-age-cleaner": { - "version": "0.1.3", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "p-defer": "^1.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "mem": { - "version": "4.1.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^1.0.0", - "p-is-promise": "^2.0.0" + "has-flag": "^3.0.0" } - }, - "merge-source-map": { - "version": "1.1.0", - "bundled": true, + } + } + }, + "jest-environment-jsdom": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.5.0.tgz", + "integrity": "sha512-62Ih5HbdAWcsqBx2ktUnor/mABBo1U111AvZWcLKeWN/n/gc5ZvDBKe4Og44fQdHKiXClrNGC6G0mBo6wrPeGQ==", + "dev": true, + "requires": { + "@jest/environment": "^24.5.0", + "@jest/fake-timers": "^24.5.0", + "@jest/types": "^24.5.0", + "jest-mock": "^24.5.0", + "jest-util": "^24.5.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.5.0.tgz", + "integrity": "sha512-du6FuyWr/GbKLsmAbzNF9mpr2Iu2zWSaq/BNHzX+vgOcts9f2ayXBweS7RAhr+6bLp6qRpMB6utAMF5Ygktxnw==", + "dev": true, + "requires": { + "@jest/environment": "^24.5.0", + "@jest/fake-timers": "^24.5.0", + "@jest/types": "^24.5.0", + "jest-mock": "^24.5.0", + "jest-util": "^24.5.0" + } + }, + "jest-get-type": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.3.0.tgz", + "integrity": "sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow==", + "dev": true + }, + "jest-haste-map": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.5.0.tgz", + "integrity": "sha512-mb4Yrcjw9vBgSvobDwH8QUovxApdimGcOkp+V1ucGGw4Uvr3VzZQBJhNm1UY3dXYm4XXyTW2G7IBEZ9pM2ggRQ==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.5.0", + "jest-worker": "^24.4.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3" + } + }, + "jest-jasmine2": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.5.0.tgz", + "integrity": "sha512-sfVrxVcx1rNUbBeyIyhkqZ4q+seNKyAG6iM0S2TYBdQsXjoFDdqWFfsUxb6uXSsbimbXX/NMkJIwUZ1uT9+/Aw==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^24.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^24.5.0", + "jest-matcher-utils": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-runtime": "^24.5.0", + "jest-snapshot": "^24.5.0", + "jest-util": "^24.5.0", + "pretty-format": "^24.5.0", + "throat": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true - } + "color-convert": "^1.9.0" } }, - "mimic-fn": { - "version": "1.2.0", - "bundled": true, - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "minimist": { - "version": "0.0.10", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - } + "has-flag": "^3.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.5.0.tgz", + "integrity": "sha512-LZKBjGovFRx3cRBkqmIg+BZnxbrLqhQl09IziMk3oeh1OV81Hg30RUIx885mq8qBv1PA0comB9bjKcuyNO1bCQ==", + "dev": true, + "requires": { + "pretty-format": "^24.5.0" + } + }, + "jest-matcher-utils": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.5.0.tgz", + "integrity": "sha512-QM1nmLROjLj8GMGzg5VBra3I9hLpjMPtF1YqzQS3rvWn2ltGZLrGAO1KQ9zUCVi5aCvrkbS5Ndm2evIP9yZg1Q==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.5.0", + "jest-get-type": "^24.3.0", + "pretty-format": "^24.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" } }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "bundled": true, - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "npm-run-path": { - "version": "2.0.2", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "path-key": "^2.0.0" + "has-flag": "^3.0.0" } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "once": { - "version": "1.4.0", - "bundled": true, + } + } + }, + "jest-message-util": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.5.0.tgz", + "integrity": "sha512-6ZYgdOojowCGiV0D8WdgctZEAe+EcFU+KrVds+0ZjvpZurUW2/oKJGltJ6FWY2joZwYXN5VL36GPV6pNVRqRnQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "wrappy": "1" + "color-convert": "^1.9.0" } }, - "optimist": { - "version": "0.6.1", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "os-locale": { - "version": "3.1.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "has-flag": "^3.0.0" } - }, - "p-defer": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "p-is-promise": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "p-limit": { - "version": "2.1.0", - "bundled": true, + } + } + }, + "jest-mock": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.5.0.tgz", + "integrity": "sha512-ZnAtkWrKf48eERgAOiUxVoFavVBziO2pAi2MfZ1+bGXVkDfxWLxU0//oJBkgwbsv6OAmuLBz4XFFqvCFMqnGUw==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "dev": true + }, + "jest-regex-util": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.3.0.tgz", + "integrity": "sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==", + "dev": true + }, + "jest-resolve": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.5.0.tgz", + "integrity": "sha512-ZIfGqLX1Rg8xJpQqNjdoO8MuxHV1q/i2OO1hLXjgCWFWs5bsedS8UrOdgjUqqNae6DXA+pCyRmdcB7lQEEbXew==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "p-try": "^2.0.0" + "color-convert": "^1.9.0" } }, - "p-locate": { - "version": "3.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "p-try": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "package-hash": { - "version": "3.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^3.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" + "has-flag": "^3.0.0" } - }, - "parse-json": { - "version": "4.0.0", - "bundled": true, + } + } + }, + "jest-resolve-dependencies": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.5.0.tgz", + "integrity": "sha512-dRVM1D+gWrFfrq2vlL5P9P/i8kB4BOYqYf3S7xczZ+A6PC3SgXYSErX/ScW/469pWMboM1uAhgLF+39nXlirCQ==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.5.0" + } + }, + "jest-runner": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.5.0.tgz", + "integrity": "sha512-oqsiS9TkIZV5dVkD+GmbNfWBRPIvxqmlTQ+AQUJUQ07n+4xTSDc40r+aKBynHw9/tLzafC00DIbJjB2cOZdvMA==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/environment": "^24.5.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "chalk": "^2.4.2", + "exit": "^0.1.2", + "graceful-fs": "^4.1.15", + "jest-config": "^24.5.0", + "jest-docblock": "^24.3.0", + "jest-haste-map": "^24.5.0", + "jest-jasmine2": "^24.5.0", + "jest-leak-detector": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-resolve": "^24.5.0", + "jest-runtime": "^24.5.0", + "jest-util": "^24.5.0", + "jest-worker": "^24.4.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "color-convert": "^1.9.0" } }, - "path-exists": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "path-key": { - "version": "2.0.1", - "bundled": true, - "dev": true - }, - "path-parse": { - "version": "1.0.6", - "bundled": true, - "dev": true - }, - "path-type": { - "version": "3.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "pify": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "pify": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "find-up": "^3.0.0" + "has-flag": "^3.0.0" } - }, - "pseudomap": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "pump": { - "version": "3.0.0", - "bundled": true, + } + } + }, + "jest-runtime": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.5.0.tgz", + "integrity": "sha512-GTFHzfLdwpaeoDPilNpBrorlPoNZuZrwKKzKJs09vWwHo+9TOsIIuszK8cWOuKC7ss07aN1922Ge8fsGdsqCuw==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/environment": "^24.5.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/yargs": "^12.0.2", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.5.0", + "jest-haste-map": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-mock": "^24.5.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.5.0", + "jest-snapshot": "^24.5.0", + "jest-util": "^24.5.0", + "jest-validate": "^24.5.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^12.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "color-convert": "^1.9.0" } }, - "read-pkg": { - "version": "3.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "read-pkg-up": { - "version": "4.0.0", - "bundled": true, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "release-zalgo": { - "version": "1.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "es6-error": "^4.0.1" + "has-flag": "^3.0.0" } - }, - "require-directory": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "resolve": { - "version": "1.10.0", - "bundled": true, + } + } + }, + "jest-serializer": { + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.4.0.tgz", + "integrity": "sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q==", + "dev": true + }, + "jest-snapshot": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.5.0.tgz", + "integrity": "sha512-eBEeJb5ROk0NcpodmSKnCVgMOo+Qsu5z9EDl3tGffwPzK1yV37mjGWF2YeIz1NkntgTzP+fUL4s09a0+0dpVWA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.5.0", + "chalk": "^2.0.1", + "expect": "^24.5.0", + "jest-diff": "^24.5.0", + "jest-matcher-utils": "^24.5.0", + "jest-message-util": "^24.5.0", + "jest-resolve": "^24.5.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.5.0", + "semver": "^5.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "color-convert": "^1.9.0" } }, - "resolve-from": { - "version": "4.0.0", - "bundled": true, - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "glob": "^7.1.3" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.6.0", - "bundled": true, - "dev": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "has-flag": "^3.0.0" } - }, - "shebang-regex": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true - }, - "spawn-wrap": { - "version": "1.4.2", - "bundled": true, + } + } + }, + "jest-util": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.5.0.tgz", + "integrity": "sha512-Xy8JsD0jvBz85K7VsTIQDuY44s+hYJyppAhcsHsOsGisVtdhar6fajf2UOf2mEVEgh15ZSdA0zkCuheN8cbr1Q==", + "dev": true, + "requires": { + "@jest/console": "^24.3.0", + "@jest/fake-timers": "^24.5.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/node": "*", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "foreground-child": "^1.5.6", - "mkdirp": "^0.5.0", - "os-homedir": "^1.0.1", - "rimraf": "^2.6.2", - "signal-exit": "^3.0.2", - "which": "^1.3.0" + "color-convert": "^1.9.0" } }, - "spdx-correct": { - "version": "3.1.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "spdx-exceptions": { - "version": "2.2.0", - "bundled": true, - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "has-flag": "^3.0.0" } - }, - "spdx-license-ids": { - "version": "3.0.3", - "bundled": true, - "dev": true - }, - "string-width": { - "version": "2.1.1", - "bundled": true, + } + } + }, + "jest-validate": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.5.0.tgz", + "integrity": "sha512-gg0dYszxjgK2o11unSIJhkOFZqNRQbWOAB2/LOUdsd2LfD9oXiMeuee8XsT0iRy5EvSccBgB4h/9HRbIo3MHgQ==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "camelcase": "^5.0.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.3.0", + "leven": "^2.1.0", + "pretty-format": "^24.5.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" + "color-convert": "^1.9.0" } }, - "strip-ansi": { - "version": "4.0.0", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "strip-bom": { - "version": "3.0.0", - "bundled": true, - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "test-exclude": { - "version": "5.1.0", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "arrify": "^1.0.1", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" + "has-flag": "^3.0.0" } - }, - "uglify-js": { - "version": "3.4.9", - "bundled": true, + } + } + }, + "jest-watcher": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.5.0.tgz", + "integrity": "sha512-/hCpgR6bg0nKvD3nv4KasdTxuhwfViVMHUATJlnGCD0r1QrmIssimPbmc5KfAQblAVxkD8xrzuij9vfPUk1/rA==", + "dev": true, + "requires": { + "@jest/test-result": "^24.5.0", + "@jest/types": "^24.5.0", + "@types/node": "*", + "@types/yargs": "^12.0.9", + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "jest-util": "^24.5.0", + "string-length": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "optional": true, "requires": { - "commander": "~2.17.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - } + "color-convert": "^1.9.0" } }, - "uuid": { - "version": "3.3.2", - "bundled": true, - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.4", - "bundled": true, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, - "which": { - "version": "1.3.1", - "bundled": true, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { - "isexe": "^2.0.0" + "has-flag": "^3.0.0" } - }, - "which-module": { - "version": "2.0.0", - "bundled": true, - "dev": true - }, - "wordwrap": { - "version": "0.0.3", - "bundled": true, - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "bundled": true, + } + } + }, + "jest-worker": { + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.4.0.tgz", + "integrity": "sha512-BH9X/klG9vxwoO99ZBUbZFfV8qO0XNZ5SIiCyYK2zOuJBl6YJVAeNIQjcoOVNu4HGEHeYEKsUWws8kSlSbZ9YQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "has-flag": "^3.0.0" } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "write-file-atomic": { - "version": "2.4.2", - "bundled": true, + } + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", + "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "jsdom": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "kleur": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.2.tgz", + "integrity": "sha512-3h7B2WRT5LNXOtQiAaWonilegHcPSf9nLVXlSTci8lu1dZUuui61+EsPEZqSVxY7rXYmB2DVKMQILxaO5WL61Q==", + "dev": true + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "make-error": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", + "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "dev": true + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "mem": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", + "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "~1.38.0" + } + }, + "mimic-fn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", + "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-plain-object": "^2.0.4" } - }, - "y18n": { - "version": "4.0.0", - "bundled": true, + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true - }, - "yallist": { - "version": "2.1.2", - "bundled": true, + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", + "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true + }, + "node-notifier": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", + "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, - "yargs": { - "version": "12.0.5", - "bundled": true, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.1.tgz", + "integrity": "sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "is-descriptor": "^0.1.0" } }, - "yargs-parser": { - "version": "11.1.1", - "bundled": true, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "is-buffer": "^1.1.5" } } } }, + "object-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", + "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1694,36 +4047,334 @@ "wrappy": "1" } }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "dependencies": { + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + } + } + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-each-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", + "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-reduce": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", + "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", + "dev": true + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", "dev": true }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "dev": true + }, + "pretty-format": { + "version": "24.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.5.0.tgz", + "integrity": "sha512-/3RuSghukCf8Riu5Ncve0iI+BzVkbRU5EeUoArKARZobREycuH5O4waxvaNIloEXdb0qwgmEAed5vTpX1HNROQ==", + "dev": true, + "requires": { + "@jest/types": "^24.5.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + } + } + }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "prompts": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.4.tgz", + "integrity": "sha512-HTzM3UWp/99A0gk51gAegwo1QRYA7xjcZufMNe33rCclFszUYAuHe1fIN/3ZmiHeGPkUsNaRyQm1hHOfM0PKxA==", + "dev": true, + "requires": { + "kleur": "^3.0.2", + "sisteransi": "^1.0.0" + } + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "react-is": { + "version": "16.8.4", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", + "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", + "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, - "optional": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1740,10 +4391,125 @@ "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", "dev": true }, - "reflect-metadata": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz", - "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", + "realpath-native": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", + "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "request-promise-native": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, + "requires": { + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "resolve": { @@ -1755,6 +4521,33 @@ "path-parse": "^1.0.5" } }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", @@ -1780,40 +4573,444 @@ } } }, + "rsvp": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", + "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==", + "dev": true + }, "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "requires": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "sisteransi": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", + "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true + }, + "string-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "string_decoder": { "version": "1.1.1", "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -1832,98 +5029,129 @@ "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, - "tap-bark": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/tap-bark/-/tap-bark-1.0.0.tgz", - "integrity": "sha1-bAPcUWh/7Xh3+COtSx3dHvXrVnQ=", - "dev": true, - "requires": { - "@types/node": ">=0.0.2", - "chalk": "^1.1.3", - "duplexer": "^0.1.1", - "tap-parser": "^3.0.3", - "through2": "^2.0.1" - } + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true }, - "tap-parser": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-3.0.5.tgz", - "integrity": "sha1-uUf2ngs+U9S5IBH2zFUuFtrcfsk=", + "test-exclude": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz", + "integrity": "sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==", "dev": true, "requires": { - "events-to-array": "^1.0.1", - "js-yaml": "^3.2.7", - "readable-stream": "^2" + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" } }, - "teeny-request": { - "version": "3.11.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", - "dev": true, - "requires": { - "https-proxy-agent": "^2.2.1", - "node-fetch": "^2.2.0", - "uuid": "^3.3.2" - } + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true }, - "threads": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/threads/-/threads-0.12.0.tgz", - "integrity": "sha512-4B7hd61lDsVW1Z/+FAVX7D9QbiQYUbtGMHVkkwWT/nKPKas8u4FEc+Rg8E8h2erhNTQGNqNJ0TsholmhpKNPRg==", + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "eventemitter3": "^2.0.2", - "native-promise-only": "^0.8.1" + "os-tmpdir": "~1.0.2" } }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" + "kind-of": "^3.0.2" }, "dependencies": { - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "is-buffer": "^1.1.5" } } } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } }, "trim-right": { "version": "1.0.1", @@ -1931,6 +5159,40 @@ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, + "ts-jest": { + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.0.0.tgz", + "integrity": "sha512-o8BO3TkMREpAATaFTrXkovMsCpBl2z4NDBoLJuWZcJJj1ijI49UnvDMfVpj+iogn/Jl8Pbhuei5nc/Ti+frEHw==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "json5": "2.x", + "make-error": "1.x", + "mkdirp": "0.x", + "resolve": "1.x", + "semver": "^5.5", + "yargs-parser": "10.x" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, "ts-node": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.0.tgz", @@ -2013,15 +5275,149 @@ "tslib": "^1.8.1" } }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "typescript": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==" }, - "urlgrey": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/urlgrey/-/urlgrey-0.4.4.tgz", - "integrity": "sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8=", + "uglify-js": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.1.tgz", + "integrity": "sha512-kI+3c+KphOAKIikQsZoT2oDsVYH5qvhpTtFObfMCdhPAYnjSvmW4oTWMhvDD4jtAGHJwztlBXQgozGcq3Xw9oQ==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true, + "optional": true + } + } + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, "util-deprecate": { @@ -2030,24 +5426,214 @@ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "write-file-atomic": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", + "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", "dev": true }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "yn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", diff --git a/package.json b/package.json index 0ae952e43..c99850749 100644 --- a/package.json +++ b/package.json @@ -19,34 +19,37 @@ "scripts": { "build": "tsc -p tsconfig.json && npm run build-lualib", "build-lualib": "ts-node ./build_lualib.ts", - "pretest": "npm run clean && npm run style-check && npm run build && tsc -p ./test/tsconfig.json", - "test": "node ./test/runner.js", - "posttest": "npm run clean", - "coverage": "nyc --source-map=true npm test && nyc report --reporter=text-lcov > coverage.lcov", - "coverage-html": "nyc --source-map=true npm test && nyc report --reporter=html", - "test-threaded": "npm run pretest && node ./test/threaded_runner.js && npm run posttest", - "test-fast": "npm run pretest && node ./test/runner.js --ignoreDiagnostics && npm run posttest", - "clean": "rimraf \"src/**/*.js\" \"src/**/*.js.map\" \"test/**/*.js\" \"test/**/*.js.map\" \"test/compiler/testfiles/*.lua\"", - "release-patch": "npm version patch", - "release-minor": "npm version minor", + "pretest": "ts-node --transpile-only ./build_lualib.ts", + "test": "jest", + "lint": "npm run lint:tslint && npm run lint:prettier", + "lint:prettier": "prettier --check **/*.{js,ts,yml,json}", + "lint:tslint": "tslint -p . && tslint -p test && tslint src/lualib/*.ts", "release-major": "npm version major", + "release-minor": "npm version minor", + "release-patch": "npm version patch", "preversion": "npm run build && npm test", - "postversion": "git push && git push --tags", - "style-check": "tslint -p . && tslint -c ./tslint.json src/lualib/*.ts" + "postversion": "git push && git push --tags" }, "bin": { "tstl": "./dist/tstl.js" }, - "nyc": { - "all": true, - "extension": [ - ".ts" - ], - "include": [ - "src/**/*" - ], - "exclude": [ - "src/lualib/*" + "prettier": { + "endOfLine": "lf", + "printWidth": 100, + "proseWrap": "always", + "tabWidth": 4, + "trailingComma": "all", + "overrides": [ + { + "files": [ + "**/*.md", + "**/*.yml", + "**/.*.yml" + ], + "options": { + "tabWidth": 2 + } + } ] }, "engines": { @@ -57,16 +60,15 @@ }, "devDependencies": { "@types/glob": "^5.0.35", + "@types/jest": "^24.0.11", "@types/node": "^9.6.23", - "alsatian": "^2.3.0", - "codecov": "^3.2.0", - "deep-equal": "^1.0.1", "fengari": "^0.1.2", - "flatted": "^2.0.0", "glob": "^7.1.2", - "nyc": "^13.3.0", + "jest": "^24.5.0", + "jest-circus": "^24.5.0", + "prettier": "^1.16.4", "rimraf": "^2.6.3", - "threads": "^0.12.0", + "ts-jest": "^24.0.0", "ts-node": "^7.0.0", "tslint": "^5.10.0" } diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index 2286bfae8..d2fdc9f0d 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -1,8 +1,7 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; - -import {CompilerOptions, LuaTarget, LuaLibImportKind} from "./CompilerOptions"; +import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; export type CLIParseResult = ParseResult; diff --git a/src/Compiler.ts b/src/Compiler.ts index 0659ea527..642624347 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -1,10 +1,9 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; - import * as CommandLineParser from "./CommandLineParser"; -import {CompilerOptions, LuaLibImportKind, LuaTarget} from "./CompilerOptions"; -import {LuaTranspiler} from "./LuaTranspiler"; +import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; +import { LuaTranspiler } from "./LuaTranspiler"; export function compile(argv: string[]): void { const parseResult = CommandLineParser.parseCommandLine(argv); @@ -105,7 +104,7 @@ export function compileFilesWithOptions(fileNames: string[], options: CompilerOp transpiler.emitFilesAndReportErrors(); } -const libCache: {[key: string]: string} = {}; +const libCache: {[key: string]: ts.SourceFile} = {}; const defaultCompilerOptions: CompilerOptions = { luaLibImport: LuaLibImportKind.Require, @@ -122,7 +121,7 @@ export function createStringCompilerProgram( fileExists: (fileName): boolean => true, getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", - getDefaultLibFileName: () => "lib.es6.d.ts", + getDefaultLibFileName: ts.getDefaultLibFileName, getDirectories: () => [], getNewLine: () => "\n", @@ -139,19 +138,17 @@ export function createStringCompilerProgram( } break; } - if (filename.indexOf(".d.ts") !== -1) { - if (!libCache[filename]) { - const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, filename); - if (fs.existsSync(filePath)) { - libCache[filename] = fs.readFileSync(filePath).toString(); - } else { - const pathWithLibPrefix = path.join(typeScriptDir, "lib." + filename); - libCache[filename] = fs.readFileSync(pathWithLibPrefix).toString(); - } - } - return ts.createSourceFile(filename, libCache[filename], ts.ScriptTarget.Latest, false); + + if (filename.startsWith('lib.')) { + if (libCache[filename]) return libCache[filename]; + const typeScriptDir = path.dirname(require.resolve("typescript")); + const filePath = path.join(typeScriptDir, filename); + const content = fs.readFileSync(filePath, 'utf8'); + + libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); + return libCache[filename]; } + return undefined; }, diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index d4d1beefb..dca5d7eb2 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,9 +1,7 @@ +import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import * as tstl from "./LuaAST"; - +import { LuaLib, LuaLibFeature } from "./LuaLib"; import { TSHelper as tsHelper } from "./TSHelper"; -import { LuaLibFeature, LuaLib } from "./LuaLib"; -import { CompilerOptions } from "./CompilerOptions"; -import { LuaLibImportKind } from "./CompilerOptions"; export class LuaPrinter { /* tslint:disable:object-literal-sort-keys */ diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4eee5cde8..97b789989 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1,12 +1,11 @@ import * as path from "path"; import * as ts from "typescript"; - -import {CompilerOptions, LuaLibImportKind, LuaTarget} from "./CompilerOptions"; -import {DecoratorKind} from "./Decorator"; +import { CompilerOptions, LuaTarget } from "./CompilerOptions"; +import { DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; -import {LuaLib, LuaLibFeature} from "./LuaLib"; -import {ContextType, TSHelper as tsHelper} from "./TSHelper"; -import {TSTLErrors} from "./TSTLErrors"; +import { LuaLibFeature } from "./LuaLib"; +import { ContextType, TSHelper as tsHelper } from "./TSHelper"; +import { TSTLErrors } from "./TSTLErrors"; export type StatementVisitResult = tstl.Statement | tstl.Statement[] | undefined; export type ExpressionVisitResult = tstl.Expression | undefined; @@ -3056,7 +3055,7 @@ export class LuaTransformer { if (classDecorators.has(DecoratorKind.CustomConstructor)) { const customDecorator = classDecorators.get(DecoratorKind.CustomConstructor); if (!customDecorator.args[0]) { - throw TSTLErrors.InvalidDecoratorArgumentNumber("!CustomConstructor", 0, 1, node); + throw TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, node); } return tstl.createCallExpression( tstl.createIdentifier(customDecorator.args[0]), diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts index dc96e9801..cd991f511 100644 --- a/src/LuaTranspiler.ts +++ b/src/LuaTranspiler.ts @@ -1,12 +1,10 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; - +import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; import * as tstl from "./LuaAST"; - -import {CompilerOptions, LuaLibImportKind, LuaTarget} from "./CompilerOptions"; -import {LuaPrinter} from "./LuaPrinter"; -import {LuaTransformer} from "./LuaTransformer"; +import { LuaPrinter } from "./LuaPrinter"; +import { LuaTransformer } from "./LuaTransformer"; export class LuaTranspiler { private program: ts.Program; diff --git a/src/TSHelper.ts b/src/TSHelper.ts index c9ef6dd3a..b0326fe3d 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -1,7 +1,5 @@ import * as ts from "typescript"; - -import {Decorator, DecoratorKind} from "./Decorator"; -import * as tstl from "./LuaAST"; +import { Decorator, DecoratorKind } from "./Decorator"; export enum ContextType { None, diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index f666c3abe..56ee4e73b 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -1,7 +1,6 @@ import * as ts from "typescript"; - -import {TranspileError} from "./TranspileError"; -import {TSHelper as tsHelper} from "./TSHelper"; +import { TranspileError } from "./TranspileError"; +import { TSHelper as tsHelper } from "./TSHelper"; export class TSTLErrors { public static CouldNotFindEnumMember = (enumDeclaration: ts.EnumDeclaration, enumMember: string, node: ts.Node) => diff --git a/src/TranspileError.ts b/src/TranspileError.ts index c05b7a703..dc64f3da6 100644 --- a/src/TranspileError.ts +++ b/src/TranspileError.ts @@ -1,9 +1,8 @@ import * as ts from "typescript"; export class TranspileError extends Error { - public node: ts.Node; - constructor(message: string, node: ts.Node) { + public name = 'TranspileError'; + constructor(message: string, public node: ts.Node) { super(message); - this.node = node; } } diff --git a/src/index.ts b/src/index.ts index 7c9dec9ea..eb153d7bc 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,5 @@ -export {parseCommandLine} from "./CommandLineParser"; -export {compile, compileFilesWithOptions, transpileString, watchWithOptions} from "./Compiler"; -export {CompilerOptions, LuaLibImportKind, LuaTarget,} from "./CompilerOptions"; -export {LuaLibFeature,} from "./LuaLib"; -export {LuaTranspiler,} from "./LuaTranspiler"; +export { parseCommandLine } from "./CommandLineParser"; +export { compile, compileFilesWithOptions, transpileString, watchWithOptions } from "./Compiler"; +export { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; +export { LuaLibFeature } from "./LuaLib"; +export { LuaTranspiler } from "./LuaTranspiler"; diff --git a/src/tstl.ts b/src/tstl.ts index c4dd2be38..5055ec8aa 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -1,5 +1,5 @@ #!/usr/bin/env node -import {compile} from "./Compiler"; +import { compile } from "./Compiler"; compile(process.argv.slice(2)); diff --git a/test/compiler/errorreport.spec.ts b/test/compiler/errorreport.spec.ts index f5f9c8782..1c588ee04 100644 --- a/test/compiler/errorreport.spec.ts +++ b/test/compiler/errorreport.spec.ts @@ -1,42 +1,24 @@ -import { Any, Expect, Setup, SpyOn, Teardown, Test, TestCase } from "alsatian"; -import * as fs from "fs"; import * as path from "path"; -import * as ts from "typescript"; -import { compile, compileFilesWithOptions } from "../../src/Compiler"; - -export class CompilerErrorReportTests { - private originalStdErr: any; - private originalStdOut: any; - private originalProcessExit: any; - - @TestCase("Encountered error parsing file: Default Imports are not supported, please use named imports instead!\n", - "default_import.ts") - @Test("Compile project") - public compileProject(errorMsg: string, ...fileNames: string[]) { - fileNames = fileNames.map((file) => path.resolve(__dirname, "testfiles", file)); - compileFilesWithOptions(fileNames, {outDir: ".", rootDir: "."}); - - Expect(process.stderr.write).toHaveBeenCalledWith(errorMsg, Any); - - Expect(process.exit).toHaveBeenCalledWith(1); - } - - @Setup - private _spyProcess() { - this.originalProcessExit = process.exit; - this.originalStdOut = process.stdout.write; - this.originalStdErr = process.stderr.write; - - SpyOn(process, "exit").andStub(); - SpyOn(process.stderr, "write").andStub(); - SpyOn(process.stdout, "write").andStub(); - } - - @Teardown - private _resetProcess() { - process.exit = this.originalProcessExit; - process.stdout.write = this.originalStdOut; - process.stderr.write = this.originalStdErr; - } - -} +import { compileFilesWithOptions } from "../../src/Compiler"; + +test.each([ + { + errorMsg: + "Encountered error parsing file: Default Imports are not supported, please use named imports instead!", + fileName: "default_import.ts", + }, +])("Compile project (%p)", ({ errorMsg, fileName }) => { + jest.spyOn(console, "log").mockReturnValue(undefined); + const errorMock = jest.spyOn(console, "error").mockReturnValue(undefined); + const exitMock = jest.spyOn(process, "exit").mockReturnValue(undefined as never); + + fileName = path.resolve(__dirname, "testfiles", fileName); + compileFilesWithOptions([fileName], { outDir: ".", rootDir: ".", types: [] }); + + jest.restoreAllMocks(); + + expect(exitMock).toHaveBeenCalledWith(1); + expect(errorMock).toHaveBeenCalledTimes(2); + expect(errorMock).toHaveBeenNthCalledWith(1, errorMsg); + expect(errorMock).toHaveBeenNthCalledWith(2, expect.any(String)); +}); diff --git a/test/compiler/outfile.spec.ts b/test/compiler/outfile.spec.ts index 1b0fa7a44..e82e7341b 100644 --- a/test/compiler/outfile.spec.ts +++ b/test/compiler/outfile.spec.ts @@ -1,47 +1,47 @@ -import { Expect, SetupFixture, Teardown, Test, TestCase } from "alsatian"; import * as fs from "fs"; import * as path from "path"; import { compile } from "../../src/Compiler"; -export class CompilerOutFileTests { - - private outFileRelPath: string; - private outFileAbsPath: string; - - @SetupFixture - public setupFixture() { - this.outFileRelPath = "./testfiles/out_file.script"; - this.outFileAbsPath = path.join(__dirname, this.outFileRelPath); - } - - @Test("Outfile absoulte path") - public outFileAbsTest() { - // Compile project - compile(["--outFile", this.outFileAbsPath, path.join(__dirname, "./testfiles/out_file.ts")]); - - Expect(fs.existsSync(this.outFileAbsPath)).toBe(true); - } - - @Test("Outfile relative path") - public outFileRelTest() { - // Compile project - compile([ - "--outDir", - __dirname, - "--outFile", - this.outFileRelPath, - path.join(__dirname, "./testfiles/out_file.ts"), - ]); - - Expect(fs.existsSync(this.outFileAbsPath)).toBe(true); - } - - @Teardown - public teardown() { - fs.unlink(this.outFileAbsPath, (err) => { - if (err) { - throw err; - } - }); - } -} +let outFileRelPath: string; +let outFileAbsPath: string; + +beforeAll(() => { + outFileRelPath = "./testfiles/out_file.script"; + outFileAbsPath = path.join(__dirname, outFileRelPath); +}); + +afterEach(() => { + fs.unlink(outFileAbsPath, err => { + if (err) { + throw err; + } + }); +}); + +test("Outfile absoulte path", () => { + compile([ + "--types", + "node", + "--skipLibCheck", + "--outFile", + outFileAbsPath, + path.join(__dirname, "./testfiles/out_file.ts"), + ]); + + expect(fs.existsSync(outFileAbsPath)).toBe(true); +}); + +test("Outfile relative path", () => { + compile([ + "--types", + "node", + "--skipLibCheck", + "--outDir", + __dirname, + "--outFile", + outFileRelPath, + path.join(__dirname, "./testfiles/out_file.ts"), + ]); + + expect(fs.existsSync(outFileAbsPath)).toBe(true); +}); diff --git a/test/compiler/project.spec.ts b/test/compiler/project.spec.ts index 329fa4083..c72c0041e 100644 --- a/test/compiler/project.spec.ts +++ b/test/compiler/project.spec.ts @@ -1,4 +1,3 @@ -import { Expect, Setup, Teardown, Test, TestCase } from "alsatian"; import * as fs from "fs"; import * as path from "path"; import { compile } from "../../src/Compiler"; @@ -7,88 +6,97 @@ import { compile } from "../../src/Compiler"; * Find all files inside a dir, recursively. */ function getAllFiles(dir: string): string[] { - return fs.readdirSync(dir).reduce( - (files, file) => { - const name = path.join(dir, file); - const isDirectory = fs.statSync(name).isDirectory(); - return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; - }, - [] - ); + return fs.readdirSync(dir).reduce((files, file) => { + const name = path.join(dir, file); + const isDirectory = fs.statSync(name).isDirectory(); + return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; + }, []); } -export class CompilerProjectTests { - - private existingFiles: string[]; - private filesAfterCompile: string[]; +let existingFiles: string[]; +let filesAfterCompile: string[]; - @TestCase("basic", - "tsconfig.json", - "lualib_bundle.lua", - "test_src/test_lib/file.lua", - "test_src/main.lua") - @TestCase("basic", - ".", - "lualib_bundle.lua", - "test_src/test_lib/file.lua", - "test_src/main.lua") - @TestCase("basic", - "test_src/main.ts", - "lualib_bundle.lua", - "test_src/test_lib/file.lua", - "test_src/main.lua") - @TestCase("basic", - "tsconfig.outDir.json", - "out_dir/lualib_bundle.lua", - "out_dir/test_src/test_lib/file.lua", - "out_dir/test_src/main.lua") - @TestCase("basic", - "tsconfig.rootDir.json", - "test_src/lualib_bundle.lua", - "test_src/test_lib/file.lua", - "test_src/main.lua") - @TestCase("basic", - "tsconfig.bothDirOptions.json", - "out_dir/lualib_bundle.lua", - "out_dir/test_lib/file.lua", - "out_dir/main.lua") - @TestCase("baseurl", - "tsconfig.json", - "out_dir/lualib_bundle.lua", - "out_dir/test_src/test_lib/nested/lib_file.lua", - "out_dir/test_src/main.lua") - @Test("Compile project") - public compileProject(projectName: string, tsconfig: string, ...expectedFiles: string[]) { - const relPathToProject = path.join("projects", projectName); +afterEach(() => { + // Remove files that were created by the test + const createdFiles = filesAfterCompile.filter(v => existingFiles.indexOf(v) < 0); + for (const file of createdFiles) { + fs.unlinkSync(file); + } + existingFiles = []; + filesAfterCompile = []; +}); - // Setup we cant do this in @setup because we need the projectname - this.existingFiles = getAllFiles(path.resolve(__dirname, relPathToProject)); - this.filesAfterCompile = []; - // Setup End +test.each([ + { + projectName: "basic", + tsconfig: "tsconfig.json", + expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], + }, + { + projectName: "basic", + tsconfig: ".", + expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], + }, + { + projectName: "basic", + tsconfig: "test_src/main.ts", + expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], + }, + { + projectName: "basic", + tsconfig: "tsconfig.outDir.json", + expectedFiles: [ + "out_dir/lualib_bundle.lua", + "out_dir/test_src/test_lib/file.lua", + "out_dir/test_src/main.lua", + ], + }, + { + projectName: "basic", + tsconfig: "tsconfig.rootDir.json", + expectedFiles: [ + "test_src/lualib_bundle.lua", + "test_src/test_lib/file.lua", + "test_src/main.lua", + ], + }, + { + projectName: "basic", + tsconfig: "tsconfig.bothDirOptions.json", + expectedFiles: [ + "out_dir/lualib_bundle.lua", + "out_dir/test_lib/file.lua", + "out_dir/main.lua", + ], + }, + { + projectName: "baseurl", + tsconfig: "tsconfig.json", + expectedFiles: [ + "out_dir/lualib_bundle.lua", + "out_dir/test_src/test_lib/nested/lib_file.lua", + "out_dir/test_src/main.lua", + ], + }, +])("Compile project (%p)", ({ projectName, tsconfig, expectedFiles }) => { + const relPathToProject = path.join("projects", projectName); - const tsconfigPath = path.resolve(__dirname, relPathToProject, tsconfig); + // Setup we cant do this in beforeEach because we need the projectname + existingFiles = getAllFiles(path.resolve(__dirname, relPathToProject)); + filesAfterCompile = []; + // Setup End - // Compile project - compile(["-p", tsconfigPath]); + const tsconfigPath = path.resolve(__dirname, relPathToProject, tsconfig); - this.filesAfterCompile = getAllFiles(path.resolve(__dirname, relPathToProject)); - expectedFiles = expectedFiles.map(relPath => path.resolve(__dirname, relPathToProject, relPath)); - expectedFiles.push(...this.existingFiles); + compile(["-p", tsconfigPath]); - for (const existingFile of this.filesAfterCompile) { - Expect(expectedFiles).toContain(existingFile); - } - } + filesAfterCompile = getAllFiles(path.resolve(__dirname, relPathToProject)); + expectedFiles = expectedFiles.map(relPath => + path.resolve(__dirname, relPathToProject, relPath), + ); + expectedFiles.push(...existingFiles); - @Teardown - public teardown() { - // Remove files that were created by the test - const createdFiles = this.filesAfterCompile.filter(v => this.existingFiles.indexOf(v) < 0); - for (const file of createdFiles) { - fs.unlinkSync(file); - } - this.existingFiles = []; - this.filesAfterCompile = []; + for (const existingFile of filesAfterCompile) { + expect(expectedFiles).toContain(existingFile); } - -} +}); diff --git a/test/compiler/projects/baseurl/tsconfig.json b/test/compiler/projects/baseurl/tsconfig.json index 69a82043b..299ae7cf8 100644 --- a/test/compiler/projects/baseurl/tsconfig.json +++ b/test/compiler/projects/baseurl/tsconfig.json @@ -4,5 +4,7 @@ "outDir": "./out_dir", "rootDir": ".", "baseUrl": "./test_src/test_lib", + "types": [], + "skipLibCheck": true } } diff --git a/test/compiler/projects/basic/test_src/test_lib/file.ts b/test/compiler/projects/basic/test_src/test_lib/file.ts old mode 100755 new mode 100644 index d764cbd99..4ac2b8fe0 --- a/test/compiler/projects/basic/test_src/test_lib/file.ts +++ b/test/compiler/projects/basic/test_src/test_lib/file.ts @@ -1 +1 @@ -const test = true; +const foo = true; diff --git a/test/compiler/projects/basic/tsconfig.bothDirOptions.json b/test/compiler/projects/basic/tsconfig.bothDirOptions.json old mode 100755 new mode 100644 diff --git a/test/compiler/projects/basic/tsconfig.json b/test/compiler/projects/basic/tsconfig.json old mode 100755 new mode 100644 index e5a835e99..ec7262ddf --- a/test/compiler/projects/basic/tsconfig.json +++ b/test/compiler/projects/basic/tsconfig.json @@ -1,3 +1,7 @@ { - "luaTarget": "JIT" + "luaTarget": "JIT", + "compilerOptions": { + "types": [], + "skipLibCheck": true + } } diff --git a/test/compiler/projects/basic/tsconfig.outDir.json b/test/compiler/projects/basic/tsconfig.outDir.json old mode 100755 new mode 100644 diff --git a/test/compiler/projects/basic/tsconfig.rootDir.json b/test/compiler/projects/basic/tsconfig.rootDir.json old mode 100755 new mode 100644 diff --git a/test/compiler/projects/watchmode/tsconfig.json b/test/compiler/projects/watchmode/tsconfig.json index e5a835e99..ec7262ddf 100644 --- a/test/compiler/projects/watchmode/tsconfig.json +++ b/test/compiler/projects/watchmode/tsconfig.json @@ -1,3 +1,7 @@ { - "luaTarget": "JIT" + "luaTarget": "JIT", + "compilerOptions": { + "types": [], + "skipLibCheck": true + } } diff --git a/test/compiler/projects/watchmode/watch.ts b/test/compiler/projects/watchmode/watch.ts index 4e2a15260..fa2edc21a 100644 --- a/test/compiler/projects/watchmode/watch.ts +++ b/test/compiler/projects/watchmode/watch.ts @@ -1 +1 @@ -class MyTest {} \ No newline at end of file +class MyTest {} diff --git a/test/compiler/testfiles/out_file.ts b/test/compiler/testfiles/out_file.ts index 45842c5e2..ef22a69f1 100644 --- a/test/compiler/testfiles/out_file.ts +++ b/test/compiler/testfiles/out_file.ts @@ -1,3 +1 @@ -class Test { - -} +class Test {} diff --git a/test/compiler/testfiles/watch.ts b/test/compiler/testfiles/watch.ts index 4e2a15260..fa2edc21a 100644 --- a/test/compiler/testfiles/watch.ts +++ b/test/compiler/testfiles/watch.ts @@ -1 +1 @@ -class MyTest {} \ No newline at end of file +class MyTest {} diff --git a/test/compiler/watchmode.spec.ts b/test/compiler/watchmode.spec.ts index 7b838316b..2d695f698 100644 --- a/test/compiler/watchmode.spec.ts +++ b/test/compiler/watchmode.spec.ts @@ -1,68 +1,74 @@ -import { AsyncTest, Expect, Setup, TestCase, Timeout } from "alsatian"; import { fork } from "child_process"; import * as fs from "fs"; import * as path from "path"; -export class CompilerWatchModeTest { +let testsCleanup: Array<() => void> = []; +afterEach(() => { + testsCleanup.forEach(x => x()); + testsCleanup = []; +}); - @TestCase(["-w", path.join(__dirname, "./testfiles/watch.ts")], - path.join(__dirname, "./testfiles/watch.ts")) - @TestCase(["-w", "-p", path.join(__dirname, "./projects/watchmode/")], - path.join(__dirname, "./projects/watchmode/watch.ts")) - @AsyncTest("Watch single File") - @Timeout(16000) - public async testSingle(args: string[], fileToChange: string): Promise { - fileToChange = fileToChange; - const fileToChangeOut = fileToChange.replace(".ts", ".lua"); - - const child = fork(path.join(__dirname, "watcher_proccess.js")); - child.send(args); - - await this.waitForFileExists(fileToChangeOut, 9000) - .catch(err => console.error(err)); +function waitForFileExists(filePath: string): Promise { + return new Promise(resolve => { + const intervalTimerId = setInterval(() => { + if (fs.existsSync(filePath)) { + clearInterval(intervalTimerId); + resolve(); + } + }, 100); - Expect(fs.existsSync(fileToChangeOut)).toBe(true); + testsCleanup.push(() => clearInterval(intervalTimerId)); + }); +} - const initialResultLua = fs.readFileSync(fileToChangeOut); +test.each([ + { + args: [ + "--types", + "node", + "--skipLibCheck", + "-w", + path.join(__dirname, "./testfiles/watch.ts"), + ], + fileToChange: path.join(__dirname, "./testfiles/watch.ts"), + }, + { + args: ["-w", "-p", path.join(__dirname, "./projects/watchmode/")], + fileToChange: path.join(__dirname, "./projects/watchmode/watch.ts"), + }, +])( + "Watch single File (%p)", + async ({ args, fileToChange }) => { + const fileToChangeOut = fileToChange.replace(".ts", ".lua"); const originalTS = fs.readFileSync(fileToChange); - fs.unlinkSync(fileToChangeOut); - - fs.writeFileSync(fileToChange, "class MyTest2 {}"); - - await this.waitForFileExists(fileToChangeOut, 5000) - .catch(err => console.error(err)); + const child = fork(path.join(__dirname, "watcher_proccess.ts"), [], { + silent: true, + execArgv: ["--require", "ts-node/register/transpile-only"], + }); - const updatedResultLua = fs.readFileSync(fileToChangeOut).toString(); + testsCleanup.push(() => { + try { + fs.unlinkSync(fileToChangeOut); + } catch (err) { + if (err.code !== "ENOENT") throw err; + } + fs.writeFileSync(fileToChange, originalTS); + child.kill(); + }); - Expect(initialResultLua).not.toEqual(updatedResultLua); + child.send(args); - fs.writeFileSync(fileToChange, originalTS); + await waitForFileExists(fileToChangeOut); + const initialResultLua = fs.readFileSync(fileToChangeOut, "utf8"); fs.unlinkSync(fileToChangeOut); + fs.writeFileSync(fileToChange, "class MyTest2 {}"); - child.kill(); - } - - private waitForFileExists(filepath: string, timeout: number = 3000): Promise { - const interval = 200; - return new Promise((resolve, reject) => { - const intervalTimerId = setInterval( - () => { - if (fs.existsSync(filepath)) { - clearTimeout(timeoutId); - clearInterval(intervalTimerId); - resolve(); - } - }, - interval); + await waitForFileExists(fileToChangeOut); + const updatedResultLua = fs.readFileSync(fileToChangeOut, "utf8"); - const timeoutId = setTimeout( - () => { - clearInterval(intervalTimerId); - reject(new Error("Wating for file timed out!")); - }, - timeout); - }); - } -} + expect(initialResultLua).not.toEqual(updatedResultLua); + }, + 20000, +); diff --git a/test/src/json.lua b/test/json.lua similarity index 100% rename from test/src/json.lua rename to test/json.lua diff --git a/test/runner.ts b/test/runner.ts deleted file mode 100644 index b2dfbbf2b..000000000 --- a/test/runner.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { TestOutcome, TestRunner, TestSet } from "alsatian"; - -import * as fs from "fs"; -import * as path from "path"; - -// create test set -const testSet = TestSet.create(); - -// add your tests -testSet.addTestsFromFiles("./test/**/*.spec.js"); - -// create a test runner -const testRunner = new TestRunner(); - -// Copy lualib to project root -fs.copyFileSync( - path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), - "lualib_bundle.lua" -); - -// setup the output -testRunner.outputStream - // pipe to the console - .pipe(process.stdout); - -let success = 0; -let ignored = 0; -let run = 0; -testRunner.onTestComplete(test => { - run++; - - if (test.outcome === TestOutcome.Pass) { - success++; - } else if (test.outcome === TestOutcome.Skip) { - ignored++; - } -}); - -// run the test set -testRunner.run(testSet) - // this will be called after all tests have been run - .then(result => { - // Remove lualib bundle again - fs.unlinkSync("lualib_bundle.lua"); - - const nonIgnoredTests = run - ignored; - const failedTests = nonIgnoredTests - success; - console.log(`Ignored ${ignored}/${run} tests.`); - console.log(`Failed ${failedTests}/${nonIgnoredTests} tests.`); - console.log(`Passed ${success}/${nonIgnoredTests} tests.`); - - if (failedTests > 0) { - process.exit(1); - } - }) - // this will be called if there was a problem - .catch(error => { - // Remove lualib bundle again - fs.unlinkSync("lualib_bundle.lua"); - - console.error(error); - process.exit(1); - }); diff --git a/test/test_thread.ts b/test/test_thread.ts deleted file mode 100644 index d9404d609..000000000 --- a/test/test_thread.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { MatchError, TestRunner, TestSet, TestOutcome } from "alsatian"; -import * as flatted from "flatted"; - -module.exports = (input, done) => { - const testSet = TestSet.create(); - testSet.addTestsFromFiles(input.files); - const testRunner = new TestRunner(); - - let testCount = 0; - let failedTestCount = 0; - - testRunner.onTestComplete(result => { - if (result.outcome === TestOutcome.Fail) { - if (result.error instanceof MatchError) { - console.log(`Test ${result.testFixture.description}, ${result.test.key}(${flatted.stringify(result.testCase.caseArguments)}) Failed!`); - console.log(" ---\n" + - ' message: "' + - result.error.message + - '"\n' + - " severity: fail\n" + - " data:\n" + - " got: " + - result.error.actual + - "\n" + - " expect: " + - result.error.expected + - "\n"); - } - failedTestCount++; - } - testCount++; - }); - - testRunner.run(testSet) - .then(() => done(testCount, failedTestCount)); -}; diff --git a/test/threaded_runner.ts b/test/threaded_runner.ts deleted file mode 100644 index ba8f42000..000000000 --- a/test/threaded_runner.ts +++ /dev/null @@ -1,83 +0,0 @@ -import {MatchError} from "alsatian"; -import * as glob from "glob"; -import * as os from "os"; -import * as path from "path"; -import {config, Pool} from "threads"; - -function fileArrToString(fileArr: string[]): string { - return fileArr.map(val => path.basename(val).replace(".spec.js", "")).join(", "); -} - -function printTestStats(testCount: number, failedTestCount: number, header: string, footer: string): void { - console.log("-----------------"); - console.log(header); - console.log(`Total: ${testCount}`); - console.log(`Passed: ${testCount - failedTestCount}`); - console.log(`Failed: ${failedTestCount}`); - console.log(footer); - console.log("-----------------"); -} - -config.set({ - basepath: { - node: __dirname, - } -}); - -let cpuCount = os.cpus().length + 1; -if ("TRAVIS" in process.env && "CI" in process.env) { - // fixed thread count for CI - cpuCount = 8; -} -const testFiles: string[] = glob.sync("./test/**/*.spec.js"); -const pool = new Pool(cpuCount); -let jobCounter = 0; -const testStartTime = new Date(); -const fileCount = testFiles.length; -let exitWithError = false; -let totalTestCount = 0; -let totalFailedTestCount = 0; - -console.log( - `Running tests: ${fileArrToString(testFiles)} with ${cpuCount} threads`); - -testFiles.forEach(file => { - pool.run("./test_thread") - .send({files: [file]}) - .on("done", - (testCount, failedTestCount) => { - if (failedTestCount !== 0) { - exitWithError = true; - } - totalTestCount += testCount; - totalFailedTestCount += failedTestCount; - jobCounter++; - printTestStats( - testCount, - failedTestCount, - `Tests ${file} results:`, - `Thread: ${jobCounter}/${fileCount} done.`); - }) - .on("error", error => { - console.log("Fatal non test related Exception in test file:", file, error); - }); -}); - -pool.on("finished", () => { - let footer = "All tests passed!"; - if (exitWithError) { - footer = "Exiting with Error: One or more tests failed!"; - } - printTestStats(totalTestCount, totalFailedTestCount, "Final Results:", footer); - - console.log("Everything done, shutting down the thread pool."); - const timeInMs = (new Date().valueOf() - testStartTime.valueOf()); - console.log(`Tests took: ${Math.floor(timeInMs / 1000 / 60)}:${Math.floor(timeInMs / 1000) % 60}`); - - pool.killAll(); - - if (exitWithError) { - process.exit(1); - } -}); - diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap new file mode 100644 index 000000000..9c88af876 --- /dev/null +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -0,0 +1,638 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Transformation (callNamespace) 1`] = `"Namespace:myFunction();"`; + +exports[`Transformation (characterEscapeSequence) 1`] = ` +"local quoteInDoubleQuotes = \\"\\\\' \\\\' \\\\'\\"; +local quoteInTemplateString = \\"\\\\' \\\\' \\\\'\\"; +local doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\"; +local doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\"; +local doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\"; +local backQuoteInQuotes = \\"\` \` \`\\"; +local backQuoteInDoubleQuotes = \\"\` \` \`\\"; +local backQuoteInTemplateString = \\"\` \` \`\\"; +local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; +local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\"; +local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; +local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. (tostring(\\"Level 1: \\\\n\\\\t\\\\t \\" .. (tostring(\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. (tostring(\\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\");" +`; + +exports[`Transformation (classExtension1) 1`] = ` +"MyClass.myFunction = function(self) +end;" +`; + +exports[`Transformation (classExtension2) 1`] = ` +"TestClass.myFunction = function(self) +end;" +`; + +exports[`Transformation (classExtension3) 1`] = ` +"RenamedTestClass.myFunction = function(self) +end; +RenamedMyClass.myFunction = function(self) +end;" +`; + +exports[`Transformation (classExtension4) 1`] = ` +"MyClass.test = \\"test\\"; +MyClass.testP = \\"testP\\"; +MyClass.myFunction = function(self) +end;" +`; + +exports[`Transformation (classPureAbstract) 1`] = ` +"ClassB = ClassB or {}; +ClassB.__index = ClassB; +ClassB.prototype = ClassB.prototype or {}; +ClassB.prototype.__index = ClassB.prototype; +ClassB.prototype.constructor = ClassB; +ClassB.new = function(...) + local self = setmetatable({}, ClassB.prototype); + self:____constructor(...); + return self; +end; +ClassB.prototype.____constructor = function(self) +end;" +`; + +exports[`Transformation (continue) 1`] = ` +"do + local i = 0; + while i < 10 do + do + if i < 5 then + goto __continue1; + end + end + ::__continue1:: + i = i + 1; + end +end" +`; + +exports[`Transformation (continueConcurrent) 1`] = ` +"do + local i = 0; + while i < 10 do + do + if i < 5 then + goto __continue1; + end + if i == 7 then + goto __continue1; + end + end + ::__continue1:: + i = i + 1; + end +end" +`; + +exports[`Transformation (continueNested) 1`] = ` +"do + local i = 0; + while i < 5 do + do + if (i % 2) == 0 then + goto __continue1; + end + do + local j = 0; + while j < 2 do + do + if j == 1 then + goto __continue3; + end + end + ::__continue3:: + j = j + 1; + end + end + end + ::__continue1:: + i = i + 1; + end +end" +`; + +exports[`Transformation (continueNestedConcurrent) 1`] = ` +"do + local i = 0; + while i < 5 do + do + if (i % 2) == 0 then + goto __continue1; + end + do + local j = 0; + while j < 2 do + do + if j == 1 then + goto __continue3; + end + end + ::__continue3:: + j = j + 1; + end + end + if i == 4 then + goto __continue1; + end + end + ::__continue1:: + i = i + 1; + end +end" +`; + +exports[`Transformation (do) 1`] = ` +"local e = 10; +repeat + do + e = e - 1; + end + ::__continue1:: +until not (e > 0);" +`; + +exports[`Transformation (enum) 1`] = ` +"TestEnum = {}; +TestEnum.val1 = 0; +TestEnum[0] = \\"val1\\"; +TestEnum.val2 = 2; +TestEnum[2] = \\"val2\\"; +TestEnum.val3 = 3; +TestEnum[3] = \\"val3\\";" +`; + +exports[`Transformation (enumHeterogeneous) 1`] = ` +"TestEnum = {}; +TestEnum.val1 = 0; +TestEnum[0] = \\"val1\\"; +TestEnum.val2 = 3; +TestEnum[3] = \\"val2\\"; +TestEnum.val3 = \\"baz\\"; +TestEnum.baz = \\"val3\\";" +`; + +exports[`Transformation (enumMembersOnly) 1`] = ` +"val1 = 0; +val2 = 2; +val3 = 3; +val4 = \\"bye\\"; +local a = val1;" +`; + +exports[`Transformation (enumString) 1`] = ` +"TestEnum = {}; +TestEnum.val1 = \\"foo\\"; +TestEnum.foo = \\"val1\\"; +TestEnum.val2 = \\"bar\\"; +TestEnum.bar = \\"val2\\"; +TestEnum.val3 = \\"baz\\"; +TestEnum.baz = \\"val3\\";" +`; + +exports[`Transformation (exportStatement) 1`] = ` +"local exports = exports or {}; +local xyz = 4; +exports.xyz = xyz; +exports.uwv = xyz; +do + local __TSTL_export = require(\\"xyz\\"); + for ____exportKey, ____exportValue in pairs(__TSTL_export) do + exports[____exportKey] = ____exportValue; + end +end +do + local __TSTL_xyz = require(\\"xyz\\"); + local abc = __TSTL_xyz.abc; + local def = __TSTL_xyz.def; + exports.abc = abc; + exports.def = def; +end +do + local __TSTL_xyz = require(\\"xyz\\"); + local def = __TSTL_xyz.abc; + exports.def = def; +end +return exports;" +`; + +exports[`Transformation (for) 1`] = ` +"do + local i = 1; + while i <= 100 do + do + end + ::__continue1:: + i = i + 1; + end +end" +`; + +exports[`Transformation (forIn) 1`] = ` +"for i in pairs({a = 1, b = 2, c = 3, d = 4}) do + do + end + ::__continue1:: +end" +`; + +exports[`Transformation (forOf) 1`] = ` +"local ____TS_array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +for ____TS_index = 1, #____TS_array do + local i = ____TS_array[____TS_index]; + do + end + ::__continue1:: +end" +`; + +exports[`Transformation (functionRestArguments) 1`] = ` +"varargsFunction = function(self, a, ...) + local b = ({...}); +end;" +`; + +exports[`Transformation (getSetAccessors) 1`] = ` +"require(\\"lualib_bundle\\"); +MyClass = MyClass or {}; +MyClass.__index = MyClass; +MyClass.prototype = MyClass.prototype or {}; +MyClass.prototype.____getters = {}; +MyClass.prototype.__index = __TS__Index(MyClass.prototype); +MyClass.prototype.____setters = {}; +MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype); +MyClass.prototype.constructor = MyClass; +MyClass.new = function(...) + local self = setmetatable({}, MyClass.prototype); + self:____constructor(...); + return self; +end; +MyClass.prototype.____constructor = function(self) +end; +MyClass.prototype.____getters.field = function(self) + return self._field + 4; +end; +MyClass.prototype.____setters.field = function(self, v) + self._field = v * 2; +end; +local instance = MyClass.new(); +instance.field = 4; +local b = instance.field; +local c = (4 + instance.field) * 3;" +`; + +exports[`Transformation (interfaceIndex) 1`] = ` +"local a = {}; +a.abc = \\"def\\";" +`; + +exports[`Transformation (methodRestArguments) 1`] = ` +"MyClass = MyClass or {}; +MyClass.__index = MyClass; +MyClass.prototype = MyClass.prototype or {}; +MyClass.prototype.__index = MyClass.prototype; +MyClass.prototype.constructor = MyClass; +MyClass.new = function(...) + local self = setmetatable({}, MyClass.prototype); + self:____constructor(...); + return self; +end; +MyClass.prototype.____constructor = function(self) +end; +MyClass.prototype.varargsFunction = function(self, a, ...) + local b = ({...}); +end;" +`; + +exports[`Transformation (modulesChangedVariableExport) 1`] = ` +"local exports = exports or {}; +exports.foo = 1; +return exports;" +`; + +exports[`Transformation (modulesClassExport) 1`] = ` +"local exports = exports or {}; +exports.TestClass = exports.TestClass or {}; +exports.TestClass.__index = exports.TestClass; +exports.TestClass.prototype = exports.TestClass.prototype or {}; +exports.TestClass.prototype.__index = exports.TestClass.prototype; +exports.TestClass.prototype.constructor = exports.TestClass; +exports.TestClass.new = function(...) + local self = setmetatable({}, exports.TestClass.prototype); + self:____constructor(...); + return self; +end; +exports.TestClass.prototype.____constructor = function(self) +end; +return exports;" +`; + +exports[`Transformation (modulesClassWithMemberExport) 1`] = ` +"local exports = exports or {}; +exports.TestClass = exports.TestClass or {}; +exports.TestClass.__index = exports.TestClass; +exports.TestClass.prototype = exports.TestClass.prototype or {}; +exports.TestClass.prototype.__index = exports.TestClass.prototype; +exports.TestClass.prototype.constructor = exports.TestClass; +exports.TestClass.new = function(...) + local self = setmetatable({}, exports.TestClass.prototype); + self:____constructor(...); + return self; +end; +exports.TestClass.prototype.____constructor = function(self) +end; +exports.TestClass.prototype.memberFunc = function(self) +end; +return exports;" +`; + +exports[`Transformation (modulesFunctionExport) 1`] = ` +"local exports = exports or {}; +exports.publicFunc = function(self) +end; +return exports;" +`; + +exports[`Transformation (modulesFunctionNoExport) 1`] = ` +"publicFunc = function(self) +end;" +`; + +exports[`Transformation (modulesImportAll) 1`] = `"local Test = require(\\"test\\");"`; + +exports[`Transformation (modulesImportNamed) 1`] = ` +"local __TSTL_test = require(\\"test\\"); +local TestClass = __TSTL_test.TestClass;" +`; + +exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` +"local __TSTL_kebab_module = require(\\"kebab-module\\"); +local TestClass = __TSTL_kebab_module.TestClass; +local __TSTL_dollar_module = require(\\"dollar$module\\"); +local TestClass = __TSTL_dollar_module.TestClass; +local __TSTL_singlequote_module = require(\\"singlequote'module\\"); +local TestClass = __TSTL_singlequote_module.TestClass; +local __TSTL_hash_module = require(\\"hash#module\\"); +local TestClass = __TSTL_hash_module.TestClass; +local __TSTL_space_module = require(\\"space module\\"); +local TestClass = __TSTL_space_module.TestClass;" +`; + +exports[`Transformation (modulesImportRenamed) 1`] = ` +"local __TSTL_test = require(\\"test\\"); +local RenamedClass = __TSTL_test.TestClass;" +`; + +exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` +"local __TSTL_kebab_module = require(\\"kebab-module\\"); +local RenamedClass = __TSTL_kebab_module.TestClass; +local __TSTL_dollar_module = require(\\"dollar$module\\"); +local RenamedClass = __TSTL_dollar_module.TestClass; +local __TSTL_singlequote_module = require(\\"singlequote'module\\"); +local RenamedClass = __TSTL_singlequote_module.TestClass; +local __TSTL_hash_module = require(\\"hash#module\\"); +local RenamedClass = __TSTL_hash_module.TestClass; +local __TSTL_space_module = require(\\"space module\\"); +local RenamedClass = __TSTL_space_module.TestClass;" +`; + +exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\");"`; + +exports[`Transformation (modulesNamespaceExport) 1`] = ` +"local exports = exports or {}; +exports.TestSpace = exports.TestSpace or {}; +local TestSpace = exports.TestSpace; +do +end +return exports;" +`; + +exports[`Transformation (modulesNamespaceExportEnum) 1`] = ` +"local exports = exports or {}; +exports.test = exports.test or {}; +local test = exports.test; +do + test.TestEnum = {}; + test.TestEnum.foo = \\"foo\\"; + test.TestEnum.foo = \\"foo\\"; + test.TestEnum.bar = \\"bar\\"; + test.TestEnum.bar = \\"bar\\"; +end +return exports;" +`; + +exports[`Transformation (modulesNamespaceNestedWithMemberExport) 1`] = ` +"local exports = exports or {}; +exports.TestSpace = exports.TestSpace or {}; +local TestSpace = exports.TestSpace; +do + TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {}; + local TestNestedSpace = TestSpace.TestNestedSpace; + do + TestNestedSpace.innerFunc = function(self) + end; + end +end +return exports;" +`; + +exports[`Transformation (modulesNamespaceNoExport) 1`] = ` +"TestSpace = TestSpace or {}; +do +end" +`; + +exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` +"local exports = exports or {}; +exports.TestSpace = exports.TestSpace or {}; +local TestSpace = exports.TestSpace; +do + TestSpace.innerFunc = function(self) + end; +end +return exports;" +`; + +exports[`Transformation (modulesNamespaceWithMemberNoExport) 1`] = ` +"local exports = exports or {}; +exports.TestSpace = exports.TestSpace or {}; +local TestSpace = exports.TestSpace; +do + local innerFunc; + innerFunc = function(self) + end; +end +return exports;" +`; + +exports[`Transformation (modulesVariableExport) 1`] = ` +"local exports = exports or {}; +exports.foo = \\"bar\\"; +return exports;" +`; + +exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\";"`; + +exports[`Transformation (namespace) 1`] = ` +"myNamespace = myNamespace or {}; +do + local nsMember; + nsMember = function(self) + end; +end" +`; + +exports[`Transformation (namespaceMerge) 1`] = ` +"MergedClass = MergedClass or {}; +MergedClass.__index = MergedClass; +MergedClass.prototype = MergedClass.prototype or {}; +MergedClass.prototype.__index = MergedClass.prototype; +MergedClass.prototype.constructor = MergedClass; +MergedClass.new = function(...) + local self = setmetatable({}, MergedClass.prototype); + self:____constructor(...); + return self; +end; +MergedClass.prototype.____constructor = function(self) + self.propertyFunc = function(____) + end; +end; +MergedClass.staticMethodA = function(self) +end; +MergedClass.staticMethodB = function(self) + self:staticMethodA(); +end; +MergedClass.prototype.methodA = function(self) +end; +MergedClass.prototype.methodB = function(self) + self:methodA(); + self:propertyFunc(); +end; +MergedClass = MergedClass or {}; +do + MergedClass.namespaceFunc = function(self) + end; +end +local mergedClass = MergedClass.new(); +mergedClass:methodB(); +mergedClass:propertyFunc(); +MergedClass:staticMethodB(); +MergedClass:namespaceFunc();" +`; + +exports[`Transformation (namespaceNested) 1`] = ` +"myNamespace = myNamespace or {}; +do + myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {}; + local myNestedNamespace = myNamespace.myNestedNamespace; + do + local nsMember; + nsMember = function(self) + end; + end +end" +`; + +exports[`Transformation (namespacePhantom) 1`] = ` +"nsMember = function(self) +end;" +`; + +exports[`Transformation (returnDefault) 1`] = ` +"myFunc = function(self) + return; +end;" +`; + +exports[`Transformation (shorthandPropertyAssignment) 1`] = ` +"local f; +f = function(____, x) + return ({x = x}); +end;" +`; + +exports[`Transformation (tryCatch) 1`] = ` +"do + local ____TS_try, er = pcall(function() + local a = 42; + end); + if not ____TS_try then + local b = \\"fail\\"; + end +end" +`; + +exports[`Transformation (tryCatchFinally) 1`] = ` +"do + local ____TS_try, er = pcall(function() + local a = 42; + end); + if not ____TS_try then + local b = \\"fail\\"; + end + do + local c = \\"finally\\"; + end +end" +`; + +exports[`Transformation (tryFinally) 1`] = ` +"do + pcall(function() + local a = 42; + end); + do + local b = \\"finally\\"; + end +end" +`; + +exports[`Transformation (tupleReturn) 1`] = ` +"tupleReturn = function(self) + return 0, \\"foobar\\"; +end; +tupleReturn(_G); +noTupleReturn(_G); +local a, b = tupleReturn(_G); +local c, d = table.unpack(noTupleReturn(_G)); +a, b = tupleReturn(_G); +c, d = table.unpack(noTupleReturn(_G)); +local e = ({tupleReturn(_G)}); +local f = noTupleReturn(_G); +e = ({tupleReturn(_G)}); +f = noTupleReturn(_G); +foo(_G, ({tupleReturn(_G)})); +foo(_G, noTupleReturn(_G)); +tupleReturnFromVar = function(self) + local r = {1, \\"baz\\"}; + return table.unpack(r); +end; +tupleReturnForward = function(self) + return tupleReturn(_G); +end; +tupleNoForward = function(self) + return ({tupleReturn(_G)}); +end; +tupleReturnUnpack = function(self) + return table.unpack(tupleNoForward(_G)); +end;" +`; + +exports[`Transformation (typeAssert) 1`] = ` +"local test1 = 10; +local test2 = 10;" +`; + +exports[`Transformation (while) 1`] = ` +"local d = 10; +while d > 0 do + do + d = d - 1; + end + ::__continue1:: +end" +`; diff --git a/test/translation/builder.spec.ts b/test/translation/builder.spec.ts deleted file mode 100644 index f667a6fd0..000000000 --- a/test/translation/builder.spec.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { Expect, Test, TestCases } from "alsatian"; - -import * as util from "../src/util"; - -import * as fs from "fs"; -import * as path from "path"; - -const files: string[][] = []; -const fileContents: {[key: string]: Buffer} = {}; - -const tsPath = path.join(__dirname, "./ts/"); -const luaPath = path.join(__dirname, "./lua/"); - -const tsFiles = fs.readdirSync(tsPath); -const luaFiles = fs.readdirSync(luaPath); - -tsFiles.forEach( - (tsFile, i) => { - // ignore non ts files - if (path.extname(tsFile) !== ".ts") { - return; - } - const luaPart = luaFiles.indexOf(tsFile.replace(".ts", ".lua")); - if (luaPart === -1) { - throw new Error("Missing lua counter part for test file: " + tsFile); - } - const luaFile = luaFiles[luaPart]; - const luaFileAbsolute = path.join(luaPath, luaFile); - const tsFileAbsolute = path.join(tsPath, tsFile); - files.push([tsFile, luaFile]); - fileContents[tsFile] = fs.readFileSync(tsFileAbsolute); - fileContents[luaFile] = fs.readFileSync(luaFileAbsolute); - } -); - -function BufferToTestString(b: Buffer): string { - return b.toString().trim().split("\r\n").join("\n"); -} - -export class FileTests { - - @TestCases(files) - @Test("Transformation Tests") - public transformationTests(tsFile: string, luaFile: string) { - Expect(util.transpileString(BufferToTestString(fileContents[tsFile]))) - .toEqual(BufferToTestString(fileContents[luaFile])); - } - -} diff --git a/test/translation/lua/callNamespace.lua b/test/translation/lua/callNamespace.lua deleted file mode 100644 index 40b907163..000000000 --- a/test/translation/lua/callNamespace.lua +++ /dev/null @@ -1 +0,0 @@ -Namespace:myFunction(); diff --git a/test/translation/lua/characterEscapeSequence.lua b/test/translation/lua/characterEscapeSequence.lua deleted file mode 100644 index 82f43bbaa..000000000 --- a/test/translation/lua/characterEscapeSequence.lua +++ /dev/null @@ -1,12 +0,0 @@ -local quoteInDoubleQuotes = "\' \' \'"; -local quoteInTemplateString = "\' \' \'"; -local doubleQuoteInQuotes = "\" \" \""; -local doubleQuoteInDoubleQuotes = "\" \" \""; -local doubleQuoteInTemplateString = "\" \" \""; -local backQuoteInQuotes = "` ` `"; -local backQuoteInDoubleQuotes = "` ` `"; -local backQuoteInTemplateString = "` ` `"; -local escapedCharsInQuotes = "\\ \0 \b \t \n \v \f \" \' `"; -local escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \'"; -local escapedCharsInTemplateString = "\\ \0 \b \t \n \v \f \" \' `"; -local nonEmptyTemplateString = "Level 0: \n\t " .. (tostring("Level 1: \n\t\t " .. (tostring("Level 3: \n\t\t\t " .. (tostring("Last level \n --") .. " \n --")) .. " \n --")) .. " \n --"); diff --git a/test/translation/lua/classExtension1.lua b/test/translation/lua/classExtension1.lua deleted file mode 100644 index ff9e5bb5d..000000000 --- a/test/translation/lua/classExtension1.lua +++ /dev/null @@ -1,2 +0,0 @@ -MyClass.myFunction = function(self) -end; diff --git a/test/translation/lua/classExtension2.lua b/test/translation/lua/classExtension2.lua deleted file mode 100644 index 94e8f655f..000000000 --- a/test/translation/lua/classExtension2.lua +++ /dev/null @@ -1,2 +0,0 @@ -TestClass.myFunction = function(self) -end; diff --git a/test/translation/lua/classExtension3.lua b/test/translation/lua/classExtension3.lua deleted file mode 100644 index 008d45956..000000000 --- a/test/translation/lua/classExtension3.lua +++ /dev/null @@ -1,4 +0,0 @@ -RenamedTestClass.myFunction = function(self) -end; -RenamedMyClass.myFunction = function(self) -end; diff --git a/test/translation/lua/classExtension4.lua b/test/translation/lua/classExtension4.lua deleted file mode 100644 index 8fcb73124..000000000 --- a/test/translation/lua/classExtension4.lua +++ /dev/null @@ -1,4 +0,0 @@ -MyClass.test = "test"; -MyClass.testP = "testP"; -MyClass.myFunction = function(self) -end; diff --git a/test/translation/lua/classPureAbstract.lua b/test/translation/lua/classPureAbstract.lua deleted file mode 100644 index 70ba4efb3..000000000 --- a/test/translation/lua/classPureAbstract.lua +++ /dev/null @@ -1,12 +0,0 @@ -ClassB = ClassB or {}; -ClassB.__index = ClassB; -ClassB.prototype = ClassB.prototype or {}; -ClassB.prototype.__index = ClassB.prototype; -ClassB.prototype.constructor = ClassB; -ClassB.new = function(...) - local self = setmetatable({}, ClassB.prototype); - self:____constructor(...); - return self; -end; -ClassB.prototype.____constructor = function(self) -end; diff --git a/test/translation/lua/continue.lua b/test/translation/lua/continue.lua deleted file mode 100644 index 25ccd79f1..000000000 --- a/test/translation/lua/continue.lua +++ /dev/null @@ -1,12 +0,0 @@ -do - local i = 0; - while i < 10 do - do - if i < 5 then - goto __continue1; - end - end - ::__continue1:: - i = i + 1; - end -end diff --git a/test/translation/lua/continueConcurrent.lua b/test/translation/lua/continueConcurrent.lua deleted file mode 100644 index 6dbd5c31c..000000000 --- a/test/translation/lua/continueConcurrent.lua +++ /dev/null @@ -1,15 +0,0 @@ -do - local i = 0; - while i < 10 do - do - if i < 5 then - goto __continue1; - end - if i == 7 then - goto __continue1; - end - end - ::__continue1:: - i = i + 1; - end -end diff --git a/test/translation/lua/continueNested.lua b/test/translation/lua/continueNested.lua deleted file mode 100644 index 18da6fbf7..000000000 --- a/test/translation/lua/continueNested.lua +++ /dev/null @@ -1,24 +0,0 @@ -do - local i = 0; - while i < 5 do - do - if (i % 2) == 0 then - goto __continue1; - end - do - local j = 0; - while j < 2 do - do - if j == 1 then - goto __continue3; - end - end - ::__continue3:: - j = j + 1; - end - end - end - ::__continue1:: - i = i + 1; - end -end diff --git a/test/translation/lua/continueNestedConcurrent.lua b/test/translation/lua/continueNestedConcurrent.lua deleted file mode 100644 index 55a1b7f2a..000000000 --- a/test/translation/lua/continueNestedConcurrent.lua +++ /dev/null @@ -1,27 +0,0 @@ -do - local i = 0; - while i < 5 do - do - if (i % 2) == 0 then - goto __continue1; - end - do - local j = 0; - while j < 2 do - do - if j == 1 then - goto __continue3; - end - end - ::__continue3:: - j = j + 1; - end - end - if i == 4 then - goto __continue1; - end - end - ::__continue1:: - i = i + 1; - end -end diff --git a/test/translation/lua/do.lua b/test/translation/lua/do.lua deleted file mode 100644 index 14639278d..000000000 --- a/test/translation/lua/do.lua +++ /dev/null @@ -1,7 +0,0 @@ -local e = 10; -repeat - do - e = e - 1; - end - ::__continue1:: -until not (e > 0); diff --git a/test/translation/lua/enum.lua b/test/translation/lua/enum.lua deleted file mode 100644 index ab48266d7..000000000 --- a/test/translation/lua/enum.lua +++ /dev/null @@ -1,7 +0,0 @@ -TestEnum = {}; -TestEnum.val1 = 0; -TestEnum[0] = "val1"; -TestEnum.val2 = 2; -TestEnum[2] = "val2"; -TestEnum.val3 = 3; -TestEnum[3] = "val3"; diff --git a/test/translation/lua/enumHeterogeneous.lua b/test/translation/lua/enumHeterogeneous.lua deleted file mode 100644 index fec3ab147..000000000 --- a/test/translation/lua/enumHeterogeneous.lua +++ /dev/null @@ -1,7 +0,0 @@ -TestEnum = {}; -TestEnum.val1 = 0; -TestEnum[0] = "val1"; -TestEnum.val2 = 3; -TestEnum[3] = "val2"; -TestEnum.val3 = "baz"; -TestEnum.baz = "val3"; diff --git a/test/translation/lua/enumMembersOnly.lua b/test/translation/lua/enumMembersOnly.lua deleted file mode 100644 index 06bdb5f70..000000000 --- a/test/translation/lua/enumMembersOnly.lua +++ /dev/null @@ -1,5 +0,0 @@ -val1 = 0; -val2 = 2; -val3 = 3; -val4 = "bye"; -local a = val1; diff --git a/test/translation/lua/enumString.lua b/test/translation/lua/enumString.lua deleted file mode 100644 index f35f146a6..000000000 --- a/test/translation/lua/enumString.lua +++ /dev/null @@ -1,7 +0,0 @@ -TestEnum = {}; -TestEnum.val1 = "foo"; -TestEnum.foo = "val1"; -TestEnum.val2 = "bar"; -TestEnum.bar = "val2"; -TestEnum.val3 = "baz"; -TestEnum.baz = "val3"; diff --git a/test/translation/lua/exportStatement.lua b/test/translation/lua/exportStatement.lua deleted file mode 100644 index 2369b004b..000000000 --- a/test/translation/lua/exportStatement.lua +++ /dev/null @@ -1,23 +0,0 @@ -local exports = exports or {}; -local xyz = 4; -exports.xyz = xyz; -exports.uwv = xyz; -do - local __TSTL_export = require("xyz"); - for ____exportKey, ____exportValue in pairs(__TSTL_export) do - exports[____exportKey] = ____exportValue; - end -end -do - local __TSTL_xyz = require("xyz"); - local abc = __TSTL_xyz.abc; - local def = __TSTL_xyz.def; - exports.abc = abc; - exports.def = def; -end -do - local __TSTL_xyz = require("xyz"); - local def = __TSTL_xyz.abc; - exports.def = def; -end -return exports; \ No newline at end of file diff --git a/test/translation/lua/for.lua b/test/translation/lua/for.lua deleted file mode 100644 index 9f0dfb360..000000000 --- a/test/translation/lua/for.lua +++ /dev/null @@ -1,9 +0,0 @@ -do - local i = 1; - while i <= 100 do - do - end - ::__continue1:: - i = i + 1; - end -end diff --git a/test/translation/lua/forIn.lua b/test/translation/lua/forIn.lua deleted file mode 100644 index 5882e705d..000000000 --- a/test/translation/lua/forIn.lua +++ /dev/null @@ -1,5 +0,0 @@ -for i in pairs({a = 1, b = 2, c = 3, d = 4}) do - do - end - ::__continue1:: -end diff --git a/test/translation/lua/forOf.lua b/test/translation/lua/forOf.lua deleted file mode 100644 index ce8676017..000000000 --- a/test/translation/lua/forOf.lua +++ /dev/null @@ -1,7 +0,0 @@ -local ____TS_array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; -for ____TS_index = 1, #____TS_array do - local i = ____TS_array[____TS_index]; - do - end - ::__continue1:: -end diff --git a/test/translation/lua/functionRestArguments.lua b/test/translation/lua/functionRestArguments.lua deleted file mode 100644 index b440062ed..000000000 --- a/test/translation/lua/functionRestArguments.lua +++ /dev/null @@ -1,3 +0,0 @@ -varargsFunction = function(self, a, ...) - local b = ({...}); -end; diff --git a/test/translation/lua/getSetAccessors.lua b/test/translation/lua/getSetAccessors.lua deleted file mode 100644 index a4188e9c7..000000000 --- a/test/translation/lua/getSetAccessors.lua +++ /dev/null @@ -1,26 +0,0 @@ -require("lualib_bundle"); -MyClass = MyClass or {}; -MyClass.__index = MyClass; -MyClass.prototype = MyClass.prototype or {}; -MyClass.prototype.____getters = {}; -MyClass.prototype.__index = __TS__Index(MyClass.prototype); -MyClass.prototype.____setters = {}; -MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype); -MyClass.prototype.constructor = MyClass; -MyClass.new = function(...) - local self = setmetatable({}, MyClass.prototype); - self:____constructor(...); - return self; -end; -MyClass.prototype.____constructor = function(self) -end; -MyClass.prototype.____getters.field = function(self) - return self._field + 4; -end; -MyClass.prototype.____setters.field = function(self, v) - self._field = v * 2; -end; -local instance = MyClass.new(); -instance.field = 4; -local b = instance.field; -local c = (4 + instance.field) * 3; diff --git a/test/translation/lua/interfaceIndex.lua b/test/translation/lua/interfaceIndex.lua deleted file mode 100644 index a29d6d09d..000000000 --- a/test/translation/lua/interfaceIndex.lua +++ /dev/null @@ -1,2 +0,0 @@ -local a = {}; -a.abc = "def"; diff --git a/test/translation/lua/methodRestArguments.lua b/test/translation/lua/methodRestArguments.lua deleted file mode 100644 index 0f2ba1555..000000000 --- a/test/translation/lua/methodRestArguments.lua +++ /dev/null @@ -1,15 +0,0 @@ -MyClass = MyClass or {}; -MyClass.__index = MyClass; -MyClass.prototype = MyClass.prototype or {}; -MyClass.prototype.__index = MyClass.prototype; -MyClass.prototype.constructor = MyClass; -MyClass.new = function(...) - local self = setmetatable({}, MyClass.prototype); - self:____constructor(...); - return self; -end; -MyClass.prototype.____constructor = function(self) -end; -MyClass.prototype.varargsFunction = function(self, a, ...) - local b = ({...}); -end; diff --git a/test/translation/lua/modulesChangedVariableExport.lua b/test/translation/lua/modulesChangedVariableExport.lua deleted file mode 100644 index aa02323b6..000000000 --- a/test/translation/lua/modulesChangedVariableExport.lua +++ /dev/null @@ -1,3 +0,0 @@ -local exports = exports or {}; -exports.test = 1; -return exports; diff --git a/test/translation/lua/modulesClassExport.lua b/test/translation/lua/modulesClassExport.lua deleted file mode 100644 index 48dd160d5..000000000 --- a/test/translation/lua/modulesClassExport.lua +++ /dev/null @@ -1,14 +0,0 @@ -local exports = exports or {}; -exports.TestClass = exports.TestClass or {}; -exports.TestClass.__index = exports.TestClass; -exports.TestClass.prototype = exports.TestClass.prototype or {}; -exports.TestClass.prototype.__index = exports.TestClass.prototype; -exports.TestClass.prototype.constructor = exports.TestClass; -exports.TestClass.new = function(...) - local self = setmetatable({}, exports.TestClass.prototype); - self:____constructor(...); - return self; -end; -exports.TestClass.prototype.____constructor = function(self) -end; -return exports; diff --git a/test/translation/lua/modulesClassWithMemberExport.lua b/test/translation/lua/modulesClassWithMemberExport.lua deleted file mode 100644 index f4f63ab0b..000000000 --- a/test/translation/lua/modulesClassWithMemberExport.lua +++ /dev/null @@ -1,16 +0,0 @@ -local exports = exports or {}; -exports.TestClass = exports.TestClass or {}; -exports.TestClass.__index = exports.TestClass; -exports.TestClass.prototype = exports.TestClass.prototype or {}; -exports.TestClass.prototype.__index = exports.TestClass.prototype; -exports.TestClass.prototype.constructor = exports.TestClass; -exports.TestClass.new = function(...) - local self = setmetatable({}, exports.TestClass.prototype); - self:____constructor(...); - return self; -end; -exports.TestClass.prototype.____constructor = function(self) -end; -exports.TestClass.prototype.memberFunc = function(self) -end; -return exports; diff --git a/test/translation/lua/modulesFunctionExport.lua b/test/translation/lua/modulesFunctionExport.lua deleted file mode 100644 index 7b8d3dd58..000000000 --- a/test/translation/lua/modulesFunctionExport.lua +++ /dev/null @@ -1,4 +0,0 @@ -local exports = exports or {}; -exports.publicFunc = function(self) -end; -return exports; diff --git a/test/translation/lua/modulesFunctionNoExport.lua b/test/translation/lua/modulesFunctionNoExport.lua deleted file mode 100644 index 59eb73913..000000000 --- a/test/translation/lua/modulesFunctionNoExport.lua +++ /dev/null @@ -1,2 +0,0 @@ -publicFunc = function(self) -end; diff --git a/test/translation/lua/modulesImportAll.lua b/test/translation/lua/modulesImportAll.lua deleted file mode 100644 index 334fc07a7..000000000 --- a/test/translation/lua/modulesImportAll.lua +++ /dev/null @@ -1 +0,0 @@ -local Test = require("test"); diff --git a/test/translation/lua/modulesImportNamed.lua b/test/translation/lua/modulesImportNamed.lua deleted file mode 100644 index 27cbae8c9..000000000 --- a/test/translation/lua/modulesImportNamed.lua +++ /dev/null @@ -1,2 +0,0 @@ -local __TSTL_test = require("test"); -local TestClass = __TSTL_test.TestClass; diff --git a/test/translation/lua/modulesImportNamedSpecialChars.lua b/test/translation/lua/modulesImportNamedSpecialChars.lua deleted file mode 100644 index 837c6ae21..000000000 --- a/test/translation/lua/modulesImportNamedSpecialChars.lua +++ /dev/null @@ -1,10 +0,0 @@ -local __TSTL_kebab_module = require("kebab-module"); -local TestClass = __TSTL_kebab_module.TestClass; -local __TSTL_dollar_module = require("dollar$module"); -local TestClass = __TSTL_dollar_module.TestClass; -local __TSTL_singlequote_module = require("singlequote'module"); -local TestClass = __TSTL_singlequote_module.TestClass; -local __TSTL_hash_module = require("hash#module"); -local TestClass = __TSTL_hash_module.TestClass; -local __TSTL_space_module = require("space module"); -local TestClass = __TSTL_space_module.TestClass; diff --git a/test/translation/lua/modulesImportRenamed.lua b/test/translation/lua/modulesImportRenamed.lua deleted file mode 100644 index 84c484b5d..000000000 --- a/test/translation/lua/modulesImportRenamed.lua +++ /dev/null @@ -1,2 +0,0 @@ -local __TSTL_test = require("test"); -local RenamedClass = __TSTL_test.TestClass; diff --git a/test/translation/lua/modulesImportRenamedSpecialChars.lua b/test/translation/lua/modulesImportRenamedSpecialChars.lua deleted file mode 100644 index 000113c65..000000000 --- a/test/translation/lua/modulesImportRenamedSpecialChars.lua +++ /dev/null @@ -1,10 +0,0 @@ -local __TSTL_kebab_module = require("kebab-module"); -local RenamedClass = __TSTL_kebab_module.TestClass; -local __TSTL_dollar_module = require("dollar$module"); -local RenamedClass = __TSTL_dollar_module.TestClass; -local __TSTL_singlequote_module = require("singlequote'module"); -local RenamedClass = __TSTL_singlequote_module.TestClass; -local __TSTL_hash_module = require("hash#module"); -local RenamedClass = __TSTL_hash_module.TestClass; -local __TSTL_space_module = require("space module"); -local RenamedClass = __TSTL_space_module.TestClass; diff --git a/test/translation/lua/modulesImportWithoutFromClause.lua b/test/translation/lua/modulesImportWithoutFromClause.lua deleted file mode 100644 index e7b7d56c8..000000000 --- a/test/translation/lua/modulesImportWithoutFromClause.lua +++ /dev/null @@ -1 +0,0 @@ -require("test"); diff --git a/test/translation/lua/modulesNamespaceExport.lua b/test/translation/lua/modulesNamespaceExport.lua deleted file mode 100644 index 122f64cf0..000000000 --- a/test/translation/lua/modulesNamespaceExport.lua +++ /dev/null @@ -1,6 +0,0 @@ -local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; -do -end -return exports; diff --git a/test/translation/lua/modulesNamespaceExportEnum.lua b/test/translation/lua/modulesNamespaceExportEnum.lua deleted file mode 100644 index 5e3997f00..000000000 --- a/test/translation/lua/modulesNamespaceExportEnum.lua +++ /dev/null @@ -1,11 +0,0 @@ -local exports = exports or {}; -exports.test = exports.test or {}; -local test = exports.test; -do - test.TestEnum = {}; - test.TestEnum.foo = "foo"; - test.TestEnum.foo = "foo"; - test.TestEnum.bar = "bar"; - test.TestEnum.bar = "bar"; -end -return exports; diff --git a/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua b/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua deleted file mode 100644 index bde538a11..000000000 --- a/test/translation/lua/modulesNamespaceNestedWithMemberExport.lua +++ /dev/null @@ -1,12 +0,0 @@ -local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; -do - TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {}; - local TestNestedSpace = TestSpace.TestNestedSpace; - do - TestNestedSpace.innerFunc = function(self) - end; - end -end -return exports; diff --git a/test/translation/lua/modulesNamespaceNoExport.lua b/test/translation/lua/modulesNamespaceNoExport.lua deleted file mode 100644 index 9f4892365..000000000 --- a/test/translation/lua/modulesNamespaceNoExport.lua +++ /dev/null @@ -1,3 +0,0 @@ -TestSpace = TestSpace or {}; -do -end diff --git a/test/translation/lua/modulesNamespaceWithMemberExport.lua b/test/translation/lua/modulesNamespaceWithMemberExport.lua deleted file mode 100644 index 1e267f322..000000000 --- a/test/translation/lua/modulesNamespaceWithMemberExport.lua +++ /dev/null @@ -1,8 +0,0 @@ -local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; -do - TestSpace.innerFunc = function(self) - end; -end -return exports; diff --git a/test/translation/lua/modulesNamespaceWithMemberNoExport.lua b/test/translation/lua/modulesNamespaceWithMemberNoExport.lua deleted file mode 100644 index bdbade0fe..000000000 --- a/test/translation/lua/modulesNamespaceWithMemberNoExport.lua +++ /dev/null @@ -1,9 +0,0 @@ -local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; -do - local innerFunc; - innerFunc = function(self) - end; -end -return exports; diff --git a/test/translation/lua/modulesVariableExport.lua b/test/translation/lua/modulesVariableExport.lua deleted file mode 100644 index 76c98810f..000000000 --- a/test/translation/lua/modulesVariableExport.lua +++ /dev/null @@ -1,3 +0,0 @@ -local exports = exports or {}; -exports.test = "test"; -return exports; diff --git a/test/translation/lua/modulesVariableNoExport.lua b/test/translation/lua/modulesVariableNoExport.lua deleted file mode 100644 index f20c4efeb..000000000 --- a/test/translation/lua/modulesVariableNoExport.lua +++ /dev/null @@ -1 +0,0 @@ -local test = "test"; diff --git a/test/translation/lua/namespace.lua b/test/translation/lua/namespace.lua deleted file mode 100644 index f59170157..000000000 --- a/test/translation/lua/namespace.lua +++ /dev/null @@ -1,6 +0,0 @@ -myNamespace = myNamespace or {}; -do - local nsMember; - nsMember = function(self) - end; -end diff --git a/test/translation/lua/namespaceMerge.lua b/test/translation/lua/namespaceMerge.lua deleted file mode 100644 index 7bac3efb6..000000000 --- a/test/translation/lua/namespaceMerge.lua +++ /dev/null @@ -1,35 +0,0 @@ -MergedClass = MergedClass or {}; -MergedClass.__index = MergedClass; -MergedClass.prototype = MergedClass.prototype or {}; -MergedClass.prototype.__index = MergedClass.prototype; -MergedClass.prototype.constructor = MergedClass; -MergedClass.new = function(...) - local self = setmetatable({}, MergedClass.prototype); - self:____constructor(...); - return self; -end; -MergedClass.prototype.____constructor = function(self) - self.propertyFunc = function(____) - end; -end; -MergedClass.staticMethodA = function(self) -end; -MergedClass.staticMethodB = function(self) - self:staticMethodA(); -end; -MergedClass.prototype.methodA = function(self) -end; -MergedClass.prototype.methodB = function(self) - self:methodA(); - self:propertyFunc(); -end; -MergedClass = MergedClass or {}; -do - MergedClass.namespaceFunc = function(self) - end; -end -local mergedClass = MergedClass.new(); -mergedClass:methodB(); -mergedClass:propertyFunc(); -MergedClass:staticMethodB(); -MergedClass:namespaceFunc(); diff --git a/test/translation/lua/namespaceNested.lua b/test/translation/lua/namespaceNested.lua deleted file mode 100644 index e409f968e..000000000 --- a/test/translation/lua/namespaceNested.lua +++ /dev/null @@ -1,10 +0,0 @@ -myNamespace = myNamespace or {}; -do - myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {}; - local myNestedNamespace = myNamespace.myNestedNamespace; - do - local nsMember; - nsMember = function(self) - end; - end -end diff --git a/test/translation/lua/namespacePhantom.lua b/test/translation/lua/namespacePhantom.lua deleted file mode 100644 index 63de0e172..000000000 --- a/test/translation/lua/namespacePhantom.lua +++ /dev/null @@ -1,2 +0,0 @@ -nsMember = function(self) -end; diff --git a/test/translation/lua/returnDefault.lua b/test/translation/lua/returnDefault.lua deleted file mode 100644 index 7b013615d..000000000 --- a/test/translation/lua/returnDefault.lua +++ /dev/null @@ -1,3 +0,0 @@ -myFunc = function(self) - return; -end; diff --git a/test/translation/lua/shorthandPropertyAssignment.lua b/test/translation/lua/shorthandPropertyAssignment.lua deleted file mode 100644 index 96a5da700..000000000 --- a/test/translation/lua/shorthandPropertyAssignment.lua +++ /dev/null @@ -1,4 +0,0 @@ -local f; -f = function(____, x) - return ({x = x}); -end; diff --git a/test/translation/lua/tryCatch.lua b/test/translation/lua/tryCatch.lua deleted file mode 100644 index f3194765e..000000000 --- a/test/translation/lua/tryCatch.lua +++ /dev/null @@ -1,8 +0,0 @@ -do - local ____TS_try, er = pcall(function() - local a = 42; - end); - if not ____TS_try then - local b = "fail"; - end -end diff --git a/test/translation/lua/tryCatchFinally.lua b/test/translation/lua/tryCatchFinally.lua deleted file mode 100644 index 4b5caf9a6..000000000 --- a/test/translation/lua/tryCatchFinally.lua +++ /dev/null @@ -1,11 +0,0 @@ -do - local ____TS_try, er = pcall(function() - local a = 42; - end); - if not ____TS_try then - local b = "fail"; - end - do - local c = "finally"; - end -end diff --git a/test/translation/lua/tryFinally.lua b/test/translation/lua/tryFinally.lua deleted file mode 100644 index a117b8bb2..000000000 --- a/test/translation/lua/tryFinally.lua +++ /dev/null @@ -1,8 +0,0 @@ -do - pcall(function() - local a = 42; - end); - do - local b = "finally"; - end -end diff --git a/test/translation/lua/tupleReturn.lua b/test/translation/lua/tupleReturn.lua deleted file mode 100644 index bc81abc3f..000000000 --- a/test/translation/lua/tupleReturn.lua +++ /dev/null @@ -1,28 +0,0 @@ -tupleReturn = function(self) - return 0, "foobar"; -end; -tupleReturn(_G); -noTupleReturn(_G); -local a, b = tupleReturn(_G); -local c, d = table.unpack(noTupleReturn(_G)); -a, b = tupleReturn(_G); -c, d = table.unpack(noTupleReturn(_G)); -local e = ({tupleReturn(_G)}); -local f = noTupleReturn(_G); -e = ({tupleReturn(_G)}); -f = noTupleReturn(_G); -foo(_G, ({tupleReturn(_G)})); -foo(_G, noTupleReturn(_G)); -tupleReturnFromVar = function(self) - local r = {1, "baz"}; - return table.unpack(r); -end; -tupleReturnForward = function(self) - return tupleReturn(_G); -end; -tupleNoForward = function(self) - return ({tupleReturn(_G)}); -end; -tupleReturnUnpack = function(self) - return table.unpack(tupleNoForward(_G)); -end; diff --git a/test/translation/lua/typeAssert.lua b/test/translation/lua/typeAssert.lua deleted file mode 100644 index 1c7069d36..000000000 --- a/test/translation/lua/typeAssert.lua +++ /dev/null @@ -1,2 +0,0 @@ -local test1 = 10; -local test2 = 10; diff --git a/test/translation/lua/while.lua b/test/translation/lua/while.lua deleted file mode 100644 index a779e9ded..000000000 --- a/test/translation/lua/while.lua +++ /dev/null @@ -1,7 +0,0 @@ -local d = 10; -while d > 0 do - do - d = d - 1; - end - ::__continue1:: -end diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts new file mode 100644 index 000000000..bd246dddf --- /dev/null +++ b/test/translation/transformation.spec.ts @@ -0,0 +1,16 @@ +import * as fs from "fs"; +import * as path from "path"; +import * as util from "../util"; +import { LuaLibImportKind } from "../../src/CompilerOptions"; + +const fixturesPath = path.join(__dirname, "./transformation"); +const fixtures = fs + .readdirSync(fixturesPath) + .filter(f => path.extname(f) === ".ts") + .sort() + .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); + +test.each(fixtures)("Transformation (%s)", (_name, content) => { + const result = util.transpileString(content, { luaLibImport: LuaLibImportKind.Require }); + expect(result).toMatchSnapshot(); +}); diff --git a/test/translation/ts/callNamespace.ts b/test/translation/transformation/callNamespace.ts similarity index 71% rename from test/translation/ts/callNamespace.ts rename to test/translation/transformation/callNamespace.ts index e87b7b751..43ed32d6d 100644 --- a/test/translation/ts/callNamespace.ts +++ b/test/translation/transformation/callNamespace.ts @@ -1,4 +1,4 @@ declare namespace Namespace { function myFunction(); } -Namespace.myFunction(); \ No newline at end of file +Namespace.myFunction(); diff --git a/test/translation/ts/characterEscapeSequence.ts b/test/translation/transformation/characterEscapeSequence.ts similarity index 84% rename from test/translation/ts/characterEscapeSequence.ts rename to test/translation/transformation/characterEscapeSequence.ts index e3ec0b741..8a7fec33e 100644 --- a/test/translation/ts/characterEscapeSequence.ts +++ b/test/translation/transformation/characterEscapeSequence.ts @@ -5,7 +5,7 @@ let doubleQuoteInQuotes = '" " "'; let doubleQuoteInDoubleQuotes = "\" \" \""; let doubleQuoteInTemplateString = `" " "`; -let backQuoteInQuotes = '` ` `'; +let backQuoteInQuotes = "` ` `"; let backQuoteInDoubleQuotes = "` ` `"; let backQuoteInTemplateString = `\` \` \``; @@ -13,4 +13,4 @@ let escapedCharsInQuotes = '\\ \0 \b \t \n \v \f \" \' \`'; let escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \'"; let escapedCharsInTemplateString = `\\ \0 \b \t \n \v \f \" \' \``; -let nonEmptyTemplateString = `Level 0: \n\t ${`Level 1: \n\t\t ${`Level 3: \n\t\t\t ${'Last level \n --'} \n --`} \n --`} \n --`; +let nonEmptyTemplateString = `Level 0: \n\t ${`Level 1: \n\t\t ${`Level 3: \n\t\t\t ${"Last level \n --"} \n --`} \n --`} \n --`; diff --git a/test/translation/ts/classExtension1.ts b/test/translation/transformation/classExtension1.ts similarity index 100% rename from test/translation/ts/classExtension1.ts rename to test/translation/transformation/classExtension1.ts diff --git a/test/translation/ts/classExtension2.ts b/test/translation/transformation/classExtension2.ts similarity index 83% rename from test/translation/ts/classExtension2.ts rename to test/translation/transformation/classExtension2.ts index 158f16422..11145e9d5 100644 --- a/test/translation/ts/classExtension2.ts +++ b/test/translation/transformation/classExtension2.ts @@ -1,6 +1,5 @@ /** @extension */ -class TestClass { -} +class TestClass {} /** @extension */ class MyClass extends TestClass { diff --git a/test/translation/ts/classExtension3.ts b/test/translation/transformation/classExtension3.ts similarity index 100% rename from test/translation/ts/classExtension3.ts rename to test/translation/transformation/classExtension3.ts diff --git a/test/translation/ts/classExtension4.ts b/test/translation/transformation/classExtension4.ts similarity index 100% rename from test/translation/ts/classExtension4.ts rename to test/translation/transformation/classExtension4.ts diff --git a/test/translation/ts/classPureAbstract.ts b/test/translation/transformation/classPureAbstract.ts similarity index 59% rename from test/translation/ts/classPureAbstract.ts rename to test/translation/transformation/classPureAbstract.ts index 178c23b59..d9a661160 100644 --- a/test/translation/ts/classPureAbstract.ts +++ b/test/translation/transformation/classPureAbstract.ts @@ -1,3 +1,3 @@ /** @pureAbstract */ declare class ClassA {} -class ClassB extends ClassA {} \ No newline at end of file +class ClassB extends ClassA {} diff --git a/test/translation/ts/continue.ts b/test/translation/transformation/continue.ts similarity index 100% rename from test/translation/ts/continue.ts rename to test/translation/transformation/continue.ts diff --git a/test/translation/ts/continueConcurrent.ts b/test/translation/transformation/continueConcurrent.ts similarity index 100% rename from test/translation/ts/continueConcurrent.ts rename to test/translation/transformation/continueConcurrent.ts diff --git a/test/translation/ts/continueNested.ts b/test/translation/transformation/continueNested.ts similarity index 100% rename from test/translation/ts/continueNested.ts rename to test/translation/transformation/continueNested.ts diff --git a/test/translation/ts/continueNestedConcurrent.ts b/test/translation/transformation/continueNestedConcurrent.ts similarity index 100% rename from test/translation/ts/continueNestedConcurrent.ts rename to test/translation/transformation/continueNestedConcurrent.ts diff --git a/test/translation/transformation/do.ts b/test/translation/transformation/do.ts new file mode 100644 index 000000000..c17e3d1aa --- /dev/null +++ b/test/translation/transformation/do.ts @@ -0,0 +1,4 @@ +let e = 10; +do { + e--; +} while (e > 0); diff --git a/test/translation/ts/enum.ts b/test/translation/transformation/enum.ts similarity index 78% rename from test/translation/ts/enum.ts rename to test/translation/transformation/enum.ts index a59f7ac76..3d48fbcfb 100644 --- a/test/translation/ts/enum.ts +++ b/test/translation/transformation/enum.ts @@ -1,5 +1,5 @@ enum TestEnum { val1 = 0, val2 = 2, - val3 -} \ No newline at end of file + val3, +} diff --git a/test/translation/transformation/enumHeterogeneous.ts b/test/translation/transformation/enumHeterogeneous.ts new file mode 100644 index 000000000..d4e69f10b --- /dev/null +++ b/test/translation/transformation/enumHeterogeneous.ts @@ -0,0 +1,5 @@ +enum TestEnum { + val1, + val2 = 3, + val3 = "baz", +} diff --git a/test/translation/ts/enumMembersOnly.ts b/test/translation/transformation/enumMembersOnly.ts similarity index 100% rename from test/translation/ts/enumMembersOnly.ts rename to test/translation/transformation/enumMembersOnly.ts diff --git a/test/translation/transformation/enumString.ts b/test/translation/transformation/enumString.ts new file mode 100644 index 000000000..3d7d29747 --- /dev/null +++ b/test/translation/transformation/enumString.ts @@ -0,0 +1,5 @@ +enum TestEnum { + val1 = "foo", + val2 = "bar", + val3 = "baz", +} diff --git a/test/translation/transformation/exportStatement.ts b/test/translation/transformation/exportStatement.ts new file mode 100644 index 000000000..7aa965422 --- /dev/null +++ b/test/translation/transformation/exportStatement.ts @@ -0,0 +1,6 @@ +const xyz = 4; +export { xyz }; +export { xyz as uwv }; +export * from "xyz"; +export { abc, def } from "xyz"; +export { abc as def } from "xyz"; diff --git a/test/translation/transformation/for.ts b/test/translation/transformation/for.ts new file mode 100644 index 000000000..a9dd48620 --- /dev/null +++ b/test/translation/transformation/for.ts @@ -0,0 +1 @@ +for (let i = 1; i <= 100; i++) {} diff --git a/test/translation/transformation/forIn.ts b/test/translation/transformation/forIn.ts new file mode 100644 index 000000000..8d1bff356 --- /dev/null +++ b/test/translation/transformation/forIn.ts @@ -0,0 +1,7 @@ +for (let i in { + a: 1, + b: 2, + c: 3, + d: 4, +}) { +} diff --git a/test/translation/ts/forOf.ts b/test/translation/transformation/forOf.ts similarity index 100% rename from test/translation/ts/forOf.ts rename to test/translation/transformation/forOf.ts diff --git a/test/translation/ts/functionRestArguments.ts b/test/translation/transformation/functionRestArguments.ts similarity index 100% rename from test/translation/ts/functionRestArguments.ts rename to test/translation/transformation/functionRestArguments.ts diff --git a/test/translation/ts/getSetAccessors.ts b/test/translation/transformation/getSetAccessors.ts similarity index 78% rename from test/translation/ts/getSetAccessors.ts rename to test/translation/transformation/getSetAccessors.ts index b721f0f0b..d61f592a2 100644 --- a/test/translation/ts/getSetAccessors.ts +++ b/test/translation/transformation/getSetAccessors.ts @@ -4,11 +4,11 @@ class MyClass { return this._field + 4; } public set field(v: number) { - this._field = v*2; + this._field = v * 2; } } let instance = new MyClass(); instance.field = 4; const b = instance.field; -const c = (4 + instance.field)*3; +const c = (4 + instance.field) * 3; diff --git a/test/translation/ts/interfaceIndex.ts b/test/translation/transformation/interfaceIndex.ts similarity index 100% rename from test/translation/ts/interfaceIndex.ts rename to test/translation/transformation/interfaceIndex.ts diff --git a/test/translation/ts/methodRestArguments.ts b/test/translation/transformation/methodRestArguments.ts similarity index 100% rename from test/translation/ts/methodRestArguments.ts rename to test/translation/transformation/methodRestArguments.ts diff --git a/test/translation/transformation/modulesChangedVariableExport.ts b/test/translation/transformation/modulesChangedVariableExport.ts new file mode 100644 index 000000000..009c4cd06 --- /dev/null +++ b/test/translation/transformation/modulesChangedVariableExport.ts @@ -0,0 +1,2 @@ +export let foo; +foo = 1; diff --git a/test/translation/ts/modulesClassExport.ts b/test/translation/transformation/modulesClassExport.ts similarity index 100% rename from test/translation/ts/modulesClassExport.ts rename to test/translation/transformation/modulesClassExport.ts diff --git a/test/translation/ts/modulesClassWithMemberExport.ts b/test/translation/transformation/modulesClassWithMemberExport.ts similarity index 100% rename from test/translation/ts/modulesClassWithMemberExport.ts rename to test/translation/transformation/modulesClassWithMemberExport.ts diff --git a/test/translation/ts/modulesFunctionExport.ts b/test/translation/transformation/modulesFunctionExport.ts similarity index 100% rename from test/translation/ts/modulesFunctionExport.ts rename to test/translation/transformation/modulesFunctionExport.ts diff --git a/test/translation/ts/modulesFunctionNoExport.ts b/test/translation/transformation/modulesFunctionNoExport.ts similarity index 100% rename from test/translation/ts/modulesFunctionNoExport.ts rename to test/translation/transformation/modulesFunctionNoExport.ts diff --git a/test/translation/transformation/modulesImportAll.ts b/test/translation/transformation/modulesImportAll.ts new file mode 100644 index 000000000..b452afb73 --- /dev/null +++ b/test/translation/transformation/modulesImportAll.ts @@ -0,0 +1 @@ +import * as Test from "test"; diff --git a/test/translation/transformation/modulesImportNamed.ts b/test/translation/transformation/modulesImportNamed.ts new file mode 100644 index 000000000..b4c16e54b --- /dev/null +++ b/test/translation/transformation/modulesImportNamed.ts @@ -0,0 +1 @@ +import { TestClass } from "test"; diff --git a/test/translation/transformation/modulesImportNamedSpecialChars.ts b/test/translation/transformation/modulesImportNamedSpecialChars.ts new file mode 100644 index 000000000..7237d70a2 --- /dev/null +++ b/test/translation/transformation/modulesImportNamedSpecialChars.ts @@ -0,0 +1,5 @@ +import { TestClass } from "kebab-module"; +import { TestClass } from "dollar$module"; +import { TestClass } from "singlequote'module"; +import { TestClass } from "hash#module"; +import { TestClass } from "space module"; diff --git a/test/translation/transformation/modulesImportRenamed.ts b/test/translation/transformation/modulesImportRenamed.ts new file mode 100644 index 000000000..42129a291 --- /dev/null +++ b/test/translation/transformation/modulesImportRenamed.ts @@ -0,0 +1 @@ +import { TestClass as RenamedClass } from "test"; diff --git a/test/translation/transformation/modulesImportRenamedSpecialChars.ts b/test/translation/transformation/modulesImportRenamedSpecialChars.ts new file mode 100644 index 000000000..59e7ed862 --- /dev/null +++ b/test/translation/transformation/modulesImportRenamedSpecialChars.ts @@ -0,0 +1,5 @@ +import { TestClass as RenamedClass } from "kebab-module"; +import { TestClass as RenamedClass } from "dollar$module"; +import { TestClass as RenamedClass } from "singlequote'module"; +import { TestClass as RenamedClass } from "hash#module"; +import { TestClass as RenamedClass } from "space module"; diff --git a/test/translation/ts/modulesImportWithoutFromClause.ts b/test/translation/transformation/modulesImportWithoutFromClause.ts similarity index 100% rename from test/translation/ts/modulesImportWithoutFromClause.ts rename to test/translation/transformation/modulesImportWithoutFromClause.ts diff --git a/test/translation/ts/modulesNamespaceExport.ts b/test/translation/transformation/modulesNamespaceExport.ts similarity index 100% rename from test/translation/ts/modulesNamespaceExport.ts rename to test/translation/transformation/modulesNamespaceExport.ts diff --git a/test/translation/transformation/modulesNamespaceExportEnum.ts b/test/translation/transformation/modulesNamespaceExportEnum.ts new file mode 100644 index 000000000..0c85b6872 --- /dev/null +++ b/test/translation/transformation/modulesNamespaceExportEnum.ts @@ -0,0 +1,6 @@ +export namespace test { + export enum TestEnum { + foo = "foo", + bar = "bar", + } +} diff --git a/test/translation/ts/modulesNamespaceNestedWithMemberExport.ts b/test/translation/transformation/modulesNamespaceNestedWithMemberExport.ts similarity index 100% rename from test/translation/ts/modulesNamespaceNestedWithMemberExport.ts rename to test/translation/transformation/modulesNamespaceNestedWithMemberExport.ts diff --git a/test/translation/ts/modulesNamespaceNoExport.ts b/test/translation/transformation/modulesNamespaceNoExport.ts similarity index 100% rename from test/translation/ts/modulesNamespaceNoExport.ts rename to test/translation/transformation/modulesNamespaceNoExport.ts diff --git a/test/translation/ts/modulesNamespaceWithMemberExport.ts b/test/translation/transformation/modulesNamespaceWithMemberExport.ts similarity index 100% rename from test/translation/ts/modulesNamespaceWithMemberExport.ts rename to test/translation/transformation/modulesNamespaceWithMemberExport.ts diff --git a/test/translation/ts/modulesNamespaceWithMemberNoExport.ts b/test/translation/transformation/modulesNamespaceWithMemberNoExport.ts similarity index 100% rename from test/translation/ts/modulesNamespaceWithMemberNoExport.ts rename to test/translation/transformation/modulesNamespaceWithMemberNoExport.ts diff --git a/test/translation/transformation/modulesVariableExport.ts b/test/translation/transformation/modulesVariableExport.ts new file mode 100644 index 000000000..d407b0602 --- /dev/null +++ b/test/translation/transformation/modulesVariableExport.ts @@ -0,0 +1 @@ +export const foo = "bar"; diff --git a/test/translation/transformation/modulesVariableNoExport.ts b/test/translation/transformation/modulesVariableNoExport.ts new file mode 100644 index 000000000..4f4b4c843 --- /dev/null +++ b/test/translation/transformation/modulesVariableNoExport.ts @@ -0,0 +1 @@ +const foo = "bar"; diff --git a/test/translation/ts/namespace.ts b/test/translation/transformation/namespace.ts similarity index 96% rename from test/translation/ts/namespace.ts rename to test/translation/transformation/namespace.ts index d9ae73274..24f4a78e0 100644 --- a/test/translation/ts/namespace.ts +++ b/test/translation/transformation/namespace.ts @@ -1,3 +1,3 @@ namespace myNamespace { function nsMember() {} -} \ No newline at end of file +} diff --git a/test/translation/ts/namespaceMerge.ts b/test/translation/transformation/namespaceMerge.ts similarity index 100% rename from test/translation/ts/namespaceMerge.ts rename to test/translation/transformation/namespaceMerge.ts diff --git a/test/translation/ts/namespaceNested.ts b/test/translation/transformation/namespaceNested.ts similarity index 100% rename from test/translation/ts/namespaceNested.ts rename to test/translation/transformation/namespaceNested.ts diff --git a/test/translation/ts/namespacePhantom.ts b/test/translation/transformation/namespacePhantom.ts similarity index 97% rename from test/translation/ts/namespacePhantom.ts rename to test/translation/transformation/namespacePhantom.ts index c99b88e8d..2f003c28e 100644 --- a/test/translation/ts/namespacePhantom.ts +++ b/test/translation/transformation/namespacePhantom.ts @@ -1,4 +1,4 @@ /** @phantom */ namespace myNamespace { function nsMember() {} -} \ No newline at end of file +} diff --git a/test/translation/ts/returnDefault.ts b/test/translation/transformation/returnDefault.ts similarity index 100% rename from test/translation/ts/returnDefault.ts rename to test/translation/transformation/returnDefault.ts diff --git a/test/translation/ts/shorthandPropertyAssignment.ts b/test/translation/transformation/shorthandPropertyAssignment.ts similarity index 100% rename from test/translation/ts/shorthandPropertyAssignment.ts rename to test/translation/transformation/shorthandPropertyAssignment.ts diff --git a/test/translation/ts/tryCatch.ts b/test/translation/transformation/tryCatch.ts similarity index 100% rename from test/translation/ts/tryCatch.ts rename to test/translation/transformation/tryCatch.ts diff --git a/test/translation/ts/tryCatchFinally.ts b/test/translation/transformation/tryCatchFinally.ts similarity index 100% rename from test/translation/ts/tryCatchFinally.ts rename to test/translation/transformation/tryCatchFinally.ts diff --git a/test/translation/ts/tryFinally.ts b/test/translation/transformation/tryFinally.ts similarity index 100% rename from test/translation/ts/tryFinally.ts rename to test/translation/transformation/tryFinally.ts diff --git a/test/translation/ts/tupleReturn.ts b/test/translation/transformation/tupleReturn.ts similarity index 96% rename from test/translation/ts/tupleReturn.ts rename to test/translation/transformation/tupleReturn.ts index 0d2936071..75b7fbf01 100644 --- a/test/translation/ts/tupleReturn.ts +++ b/test/translation/transformation/tupleReturn.ts @@ -1,34 +1,34 @@ -/** @tupleReturn */ -function tupleReturn(): [number, string] { - return [0, "foobar"]; -} -declare function noTupleReturn(): [number, string]; -declare function foo(a: [number, string]): void; -tupleReturn(); -noTupleReturn(); -let [a, b] = tupleReturn(); -let [c, d] = noTupleReturn(); -[a, b] = tupleReturn(); -[c, d] = noTupleReturn(); -let e = tupleReturn(); -let f = noTupleReturn(); -e = tupleReturn(); -f = noTupleReturn(); -foo(tupleReturn()); -foo(noTupleReturn()); -/** @tupleReturn */ -function tupleReturnFromVar(): [number, string] { - const r: [number, string] = [1, "baz"]; - return r; -} -/** @tupleReturn */ -function tupleReturnForward(): [number, string] { - return tupleReturn(); -} -function tupleNoForward(): [number, string] { - return tupleReturn(); -} -/** @tupleReturn */ -function tupleReturnUnpack(): [number, string] { - return tupleNoForward(); -} +/** @tupleReturn */ +function tupleReturn(): [number, string] { + return [0, "foobar"]; +} +declare function noTupleReturn(): [number, string]; +declare function foo(a: [number, string]): void; +tupleReturn(); +noTupleReturn(); +let [a, b] = tupleReturn(); +let [c, d] = noTupleReturn(); +[a, b] = tupleReturn(); +[c, d] = noTupleReturn(); +let e = tupleReturn(); +let f = noTupleReturn(); +e = tupleReturn(); +f = noTupleReturn(); +foo(tupleReturn()); +foo(noTupleReturn()); +/** @tupleReturn */ +function tupleReturnFromVar(): [number, string] { + const r: [number, string] = [1, "baz"]; + return r; +} +/** @tupleReturn */ +function tupleReturnForward(): [number, string] { + return tupleReturn(); +} +function tupleNoForward(): [number, string] { + return tupleReturn(); +} +/** @tupleReturn */ +function tupleReturnUnpack(): [number, string] { + return tupleNoForward(); +} diff --git a/test/translation/ts/typeAssert.ts b/test/translation/transformation/typeAssert.ts similarity index 50% rename from test/translation/ts/typeAssert.ts rename to test/translation/transformation/typeAssert.ts index 95c751a36..4b654d851 100644 --- a/test/translation/ts/typeAssert.ts +++ b/test/translation/transformation/typeAssert.ts @@ -1,2 +1,2 @@ -const test1 = 10; +const test1 = 10; const test2 = 10 as number; diff --git a/test/translation/ts/while.ts b/test/translation/transformation/while.ts similarity index 76% rename from test/translation/ts/while.ts rename to test/translation/transformation/while.ts index 6101bd4f2..4014a4add 100644 --- a/test/translation/ts/while.ts +++ b/test/translation/transformation/while.ts @@ -1,4 +1,4 @@ let d = 10; while (d > 0) { - d--; + d--; } diff --git a/test/translation/ts/do.ts b/test/translation/ts/do.ts deleted file mode 100644 index 62b1c0a65..000000000 --- a/test/translation/ts/do.ts +++ /dev/null @@ -1,4 +0,0 @@ -let e = 10 -do { - e--; -} while (e > 0) diff --git a/test/translation/ts/enumHeterogeneous.ts b/test/translation/ts/enumHeterogeneous.ts deleted file mode 100644 index a047d66fe..000000000 --- a/test/translation/ts/enumHeterogeneous.ts +++ /dev/null @@ -1,5 +0,0 @@ -enum TestEnum { - val1, - val2 = 3, - val3 = "baz", -} diff --git a/test/translation/ts/enumString.ts b/test/translation/ts/enumString.ts deleted file mode 100644 index 8ab7e30d1..000000000 --- a/test/translation/ts/enumString.ts +++ /dev/null @@ -1,5 +0,0 @@ -enum TestEnum { - val1 = "foo", - val2 = "bar", - val3 = "baz", -} diff --git a/test/translation/ts/exportStatement.ts b/test/translation/ts/exportStatement.ts deleted file mode 100644 index 524be0bd9..000000000 --- a/test/translation/ts/exportStatement.ts +++ /dev/null @@ -1,6 +0,0 @@ -const xyz = 4; -export {xyz}; -export {xyz as uwv}; -export * from "xyz"; -export {abc, def} from "xyz"; -export {abc as def} from "xyz"; diff --git a/test/translation/ts/for.ts b/test/translation/ts/for.ts deleted file mode 100644 index 02d8156e2..000000000 --- a/test/translation/ts/for.ts +++ /dev/null @@ -1,2 +0,0 @@ -for (let i = 1; i <= 100; i++) { -} diff --git a/test/translation/ts/forIn.ts b/test/translation/ts/forIn.ts deleted file mode 100644 index 55e50cce7..000000000 --- a/test/translation/ts/forIn.ts +++ /dev/null @@ -1,7 +0,0 @@ -for (let i in { - a: 1, - b: 2, - c: 3, - d: 4 -}) { -} diff --git a/test/translation/ts/modulesChangedVariableExport.ts b/test/translation/ts/modulesChangedVariableExport.ts deleted file mode 100644 index 6386d1b78..000000000 --- a/test/translation/ts/modulesChangedVariableExport.ts +++ /dev/null @@ -1,2 +0,0 @@ -export let test; -test = 1; diff --git a/test/translation/ts/modulesImportAll.ts b/test/translation/ts/modulesImportAll.ts deleted file mode 100644 index 1ffb29e95..000000000 --- a/test/translation/ts/modulesImportAll.ts +++ /dev/null @@ -1 +0,0 @@ -import * as Test from "test" diff --git a/test/translation/ts/modulesImportNamed.ts b/test/translation/ts/modulesImportNamed.ts deleted file mode 100644 index 14ba1ec8d..000000000 --- a/test/translation/ts/modulesImportNamed.ts +++ /dev/null @@ -1 +0,0 @@ -import {TestClass} from "test" diff --git a/test/translation/ts/modulesImportNamedSpecialChars.ts b/test/translation/ts/modulesImportNamedSpecialChars.ts deleted file mode 100644 index cff06e7c0..000000000 --- a/test/translation/ts/modulesImportNamedSpecialChars.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {TestClass} from "kebab-module" -import {TestClass} from "dollar$module" -import {TestClass} from "singlequote'module" -import {TestClass} from "hash#module" -import {TestClass} from "space module" diff --git a/test/translation/ts/modulesImportRenamed.ts b/test/translation/ts/modulesImportRenamed.ts deleted file mode 100644 index bc19b6b8b..000000000 --- a/test/translation/ts/modulesImportRenamed.ts +++ /dev/null @@ -1 +0,0 @@ -import {TestClass as RenamedClass} from "test" diff --git a/test/translation/ts/modulesImportRenamedSpecialChars.ts b/test/translation/ts/modulesImportRenamedSpecialChars.ts deleted file mode 100644 index 10cc4b0cc..000000000 --- a/test/translation/ts/modulesImportRenamedSpecialChars.ts +++ /dev/null @@ -1,5 +0,0 @@ -import {TestClass as RenamedClass} from "kebab-module" -import {TestClass as RenamedClass} from "dollar$module" -import {TestClass as RenamedClass} from "singlequote'module" -import {TestClass as RenamedClass} from "hash#module" -import {TestClass as RenamedClass} from "space module" diff --git a/test/translation/ts/modulesNamespaceExportEnum.ts b/test/translation/ts/modulesNamespaceExportEnum.ts deleted file mode 100644 index dd40d81cb..000000000 --- a/test/translation/ts/modulesNamespaceExportEnum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export namespace test { - export enum TestEnum { - foo = "foo", - bar = "bar", - } -} diff --git a/test/translation/ts/modulesVariableExport.ts b/test/translation/ts/modulesVariableExport.ts deleted file mode 100644 index 13f4d5b45..000000000 --- a/test/translation/ts/modulesVariableExport.ts +++ /dev/null @@ -1 +0,0 @@ -export const test = "test" diff --git a/test/translation/ts/modulesVariableNoExport.ts b/test/translation/ts/modulesVariableNoExport.ts deleted file mode 100644 index 858f3dd7c..000000000 --- a/test/translation/ts/modulesVariableNoExport.ts +++ /dev/null @@ -1 +0,0 @@ -const test = "test" diff --git a/test/tsconfig.json b/test/tsconfig.json index 7eb5d7f53..786d64a68 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,13 +1,10 @@ { "compilerOptions": { - "experimentalDecorators": true, - "sourceMap": true, "target": "es2017", + "types": ["node", "jest"], + + "noEmit": true, "module": "commonjs" }, - "exclude": [ - "translation/ts/*", - "compiler/projects/*", - "compiler/testfiles/*" - ] + "exclude": ["translation/transformation", "compiler/projects", "compiler/testfiles"] } diff --git a/test/tslint.json b/test/tslint.json new file mode 100644 index 000000000..e8bb9a2cf --- /dev/null +++ b/test/tslint.json @@ -0,0 +1,59 @@ +{ + "rules": { + "array-type": [true, "array-simple"], + "arrow-return-shorthand": true, + "ban": [ + true, + { "name": "parseInt", "message": "tsstyle#type-coercion" }, + { "name": "parseFloat", "message": "tsstyle#type-coercion" }, + { "name": "Array", "message": "tsstyle#array-constructor" } + ], + "ban-types": [ + true, + ["Object", "Use {} instead."], + ["String", "Use 'string' instead."], + ["Number", "Use 'number' instead."], + ["Boolean", "Use 'boolean' instead."] + ], + "class-name": true, + "curly": [true, "ignore-same-line"], + "deprecation": true, + "forin": false, + "interface-name": [true, "never-prefix"], + "jsdoc-format": true, + "label-position": true, + "max-classes-per-file": [true, 1], + "member-access": true, + "no-angle-bracket-type-assertion": true, + "no-any": false, + "no-arg": true, + "no-conditional-assignment": true, + "no-construct": true, + "no-debugger": true, + "no-default-export": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-inferrable-types": true, + "no-namespace": [true, "allow-declarations"], + "no-null-keyword": true, + "no-reference": true, + "no-string-throw": true, + "no-unused-expression": true, + "no-var-keyword": true, + "object-literal-shorthand": true, + "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], + "prefer-const": true, + "radix": true, + "switch-default": false, + "triple-equals": [true, "allow-null-check"], + "typedef": [true, "call-signature", "property-declaration"], + "use-isnan": true, + "variable-name": [ + true, + "check-format", + "ban-keywords", + "allow-leading-underscore", + "allow-pascal-case" + ] + } +} diff --git a/test/unit/accessors.spec.ts b/test/unit/accessors.spec.ts index 608d28851..fd63233df 100644 --- a/test/unit/accessors.spec.ts +++ b/test/unit/accessors.spec.ts @@ -1,412 +1,409 @@ -import { Expect, Test } from "alsatian"; -import * as util from "../src/util"; +import * as util from "../util"; -export class AccessorTests { - @Test("get accessor") - public getAccessor(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - const f = new Foo(); - return f.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("get accessor", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + const f = new Foo(); + return f.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("get accessor in base class") - public getAccessorInBaseClass(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo {} - const b = new Bar(); - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("get accessor in base class", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + class Bar extends Foo {} + const b = new Bar(); + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("get accessor override") - public getAccessorOverride(): void { - const code = - `class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - get foo() { return this._foo + "bar"; } - } - const b = new Bar(); - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("get accessor override", () => { + const code = ` + class Foo { + _foo = "foo"; + foo = "foo"; + } + class Bar extends Foo { + get foo() { return this._foo + "bar"; } + } + const b = new Bar(); + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("get accessor overridden") - public getAccessorOverridden(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo { - foo = "bar"; - } - const b = new Bar(); - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("get accessor overridden", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + class Bar extends Foo { + foo = "bar"; + } + const b = new Bar(); + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("get accessor override accessor") - public getAccessorOverrideAccessor(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo { - _bar = "bar"; - get foo() { return this._bar; } - } - const b = new Bar(); - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("get accessor override accessor", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + class Bar extends Foo { + _bar = "bar"; + get foo() { return this._bar; } + } + const b = new Bar(); + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("get accessor from interface") - public getAccessorFromINterface(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - interface Bar { - readonly foo: string; - } - const b: Bar = new Foo(); - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("get accessor from interface", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + interface Bar { + readonly foo: string; + } + const b: Bar = new Foo(); + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("set accessor") - public setAccessor(): void { - const code = - `class Foo { - _foo = "foo"; - set foo(val: string) { this._foo = val; } - } - const f = new Foo(); - f.foo = "bar" - return f._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("set accessor", () => { + const code = ` + class Foo { + _foo = "foo"; + set foo(val: string) { this._foo = val; } + } + const f = new Foo(); + f.foo = "bar" + return f._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("set accessor in base class") - public setAccessorInBaseClass(): void { - const code = - `class Foo { - _foo = "foo"; - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo {} - const b = new Bar(); - b.foo = "bar" - return b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("set accessor in base class", () => { + const code = ` + class Foo { + _foo = "foo"; + set foo(val: string) { this._foo = val; } + } + class Bar extends Foo {} + const b = new Bar(); + b.foo = "bar" + return b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("set accessor override") - public setAccessorOverride(): void { - const code = - `class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - set foo(val: string) { this._foo = val; } - } - const b = new Bar(); - b.foo = "bar" - return b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("set accessor override", () => { + const code = ` + class Foo { + _foo = "foo"; + foo = "foo"; + } + class Bar extends Foo { + set foo(val: string) { this._foo = val; } + } + const b = new Bar(); + b.foo = "bar" + return b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("set accessor overridden") - public setAccessorOverridden(): void { - const code = - `class Foo { - _foo = "baz"; - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo { - foo = "foo"; // triggers base class setter - } - const b = new Bar(); - const fooOriginal = b._foo; - b.foo = "bar" - return fooOriginal + b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("set accessor overridden", () => { + const code = ` + class Foo { + _foo = "baz"; + set foo(val: string) { this._foo = val; } + } + class Bar extends Foo { + foo = "foo"; // triggers base class setter + } + const b = new Bar(); + const fooOriginal = b._foo; + b.foo = "bar" + return fooOriginal + b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("set accessor override accessor") - public setAccessorOverrideAccessor(): void { - const code = - `class Foo { - _foo = "foo"; - set foo(val: string) { this._foo = "foo"; } - } - class Bar extends Foo { - set foo(val: string) { this._foo = val; } - } - const b = new Bar(); - b.foo = "bar" - return b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("set accessor override accessor", () => { + const code = ` + class Foo { + _foo = "foo"; + set foo(val: string) { this._foo = "foo"; } + } + class Bar extends Foo { + set foo(val: string) { this._foo = val; } + } + const b = new Bar(); + b.foo = "bar" + return b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("set accessor from interface") - public setAccessorFromInterface(): void { - const code = - `class Foo { - _foo = "foo"; - set foo(val: string) { this._foo = val; } - } - interface Bar { - _foo: string; - foo: string; - } - const b: Bar = new Foo(); - b.foo = "bar" - return b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("set accessor from interface", () => { + const code = ` + class Foo { + _foo = "foo"; + set foo(val: string) { this._foo = val; } + } + interface Bar { + _foo: string; + foo: string; + } + const b: Bar = new Foo(); + b.foo = "bar" + return b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("get/set accessors") - public getSetAccessor(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - set foo(val: string) { this._foo = val; } - } - const f = new Foo(); - const fooOriginal = f.foo; - f.foo = "bar"; - return fooOriginal + f.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("get/set accessors", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + set foo(val: string) { this._foo = val; } + } + const f = new Foo(); + const fooOriginal = f.foo; + f.foo = "bar"; + return fooOriginal + f.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("get/set accessors in base class") - public getSetAccessorInBaseClass(): void { - const code = - `class Foo { - _foo = "foo"; - get foo() { return this._foo; } - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo {} - const b = new Bar(); - const fooOriginal = b.foo; - b.foo = "bar" - return fooOriginal + b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("get/set accessors in base class", () => { + const code = ` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + set foo(val: string) { this._foo = val; } + } + class Bar extends Foo {} + const b = new Bar(); + const fooOriginal = b.foo; + b.foo = "bar" + return fooOriginal + b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("static get accessor") - public staticGetAccessor(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - return Foo.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("static get accessor", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + } + return Foo.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("static get accessor in base class") - public staticGetAccessorInBaseClass(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo {} - return Bar.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("static get accessor in base class", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + } + class Bar extends Foo {} + return Bar.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("static get accessor override") - public staticGetAccessorOverride(): void { - const code = - `class Foo { - static _foo = "foo"; - static foo = "foo"; - } - class Bar extends Foo { - static get foo() { return this._foo + "bar"; } - } - return Bar.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("static get accessor override", () => { + const code = ` + class Foo { + static _foo = "foo"; + static foo = "foo"; + } + class Bar extends Foo { + static get foo() { return this._foo + "bar"; } + } + return Bar.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("static get accessor overridden") - public staticGetAccessorOverridden(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo { - static foo = "bar"; - } - return Bar.foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static get accessor overridden", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + } + class Bar extends Foo { + static foo = "bar"; + } + return Bar.foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static get accessor override accessor") - public staticGetAccessorOverrideAccessor(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo { - static _bar = "bar"; - static get foo() { return this._bar; } - } - return Bar.foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static get accessor override accessor", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + } + class Bar extends Foo { + static _bar = "bar"; + static get foo() { return this._bar; } + } + return Bar.foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static get accessor from interface") - public staticGetAccessorFromINterface(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - interface Bar { - readonly foo: string; - } - const b: Bar = Foo; - return b.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } +test("static get accessor from interface", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + } + interface Bar { + readonly foo: string; + } + const b: Bar = Foo; + return b.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); - @Test("static set accessor") - public staticSetAccessor(): void { - const code = - `class Foo { - static _foo = "foo"; - static set foo(val: string) { this._foo = val; } - } - Foo.foo = "bar" - return Foo._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static set accessor", () => { + const code = ` + class Foo { + static _foo = "foo"; + static set foo(val: string) { this._foo = val; } + } + Foo.foo = "bar" + return Foo._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static set accessor in base class") - public staticSetAccessorInBaseClass(): void { - const code = - `class Foo { - static _foo = "foo"; - static set foo(val: string) { this._foo = val; } - } - class Bar extends Foo {} - Bar.foo = "bar" - return Bar._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static set accessor in base class", () => { + const code = ` + class Foo { + static _foo = "foo"; + static set foo(val: string) { this._foo = val; } + } + class Bar extends Foo {} + Bar.foo = "bar" + return Bar._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static set accessor override") - public staticSetAccessorOverride(): void { - const code = - `class Foo { - static _foo = "foo"; - static foo = "foo"; - } - class Bar extends Foo { - static set foo(val: string) { this._foo = val; } - } - Bar.foo = "bar" - return Bar._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static set accessor override", () => { + const code = ` + class Foo { + static _foo = "foo"; + static foo = "foo"; + } + class Bar extends Foo { + static set foo(val: string) { this._foo = val; } + } + Bar.foo = "bar" + return Bar._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static set accessor overridden") - public staticSetAccessorOverridden(): void { - const code = - `class Foo { - static _foo = "baz"; - static set foo(val: string) { this._foo = val; } - } - class Bar extends Foo { - static foo = "foo"; // triggers base class setter - } - const fooOriginal = Bar._foo; - Bar.foo = "bar" - return fooOriginal + Bar._foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("static set accessor overridden", () => { + const code = ` + class Foo { + static _foo = "baz"; + static set foo(val: string) { this._foo = val; } + } + class Bar extends Foo { + static foo = "foo"; // triggers base class setter + } + const fooOriginal = Bar._foo; + Bar.foo = "bar" + return fooOriginal + Bar._foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("static set accessor override accessor") - public staticSetAccessorOverrideAccessor(): void { - const code = - `class Foo { - static _foo = "foo"; - static set foo(val: string) { this._foo = "foo"; } - } - class Bar extends Foo { - static set foo(val: string) { this._foo = val; } - } - Bar.foo = "bar" - return Bar._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static set accessor override accessor", () => { + const code = ` + class Foo { + static _foo = "foo"; + static set foo(val: string) { this._foo = "foo"; } + } + class Bar extends Foo { + static set foo(val: string) { this._foo = val; } + } + Bar.foo = "bar" + return Bar._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static set accessor from interface") - public staticSetAccessorFromInterface(): void { - const code = - `class Foo { - static _foo = "foo"; - static set foo(val: string) { this._foo = val; } - } - interface Bar { - _foo: string; - foo: string; - } - const b: Bar = Foo; - b.foo = "bar" - return b._foo;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } +test("static set accessor from interface", () => { + const code = ` + class Foo { + static _foo = "foo"; + static set foo(val: string) { this._foo = val; } + } + interface Bar { + _foo: string; + foo: string; + } + const b: Bar = Foo; + b.foo = "bar" + return b._foo; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); - @Test("static get/set accessors") - public staticGetSetAccessor(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - static set foo(val: string) { this._foo = val; } - } - const fooOriginal = Foo.foo; - Foo.foo = "bar"; - return fooOriginal + Foo.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } +test("static get/set accessors", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + static set foo(val: string) { this._foo = val; } + } + const fooOriginal = Foo.foo; + Foo.foo = "bar"; + return fooOriginal + Foo.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); - @Test("static get/set accessors in base class") - public staticGetSetAccessorInBaseClass(): void { - const code = - `class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - static set foo(val: string) { this._foo = val; } - } - class Bar extends Foo {} - const fooOriginal = Bar.foo; - Bar.foo = "bar" - return fooOriginal + Bar.foo;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } -} +test("static get/set accessors in base class", () => { + const code = ` + class Foo { + static _foo = "foo"; + static get foo() { return this._foo; } + static set foo(val: string) { this._foo = val; } + } + class Bar extends Foo {} + const fooOriginal = Bar.foo; + Bar.foo = "bar" + return fooOriginal + Bar.foo; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index 4ddb7b8fd..85dcb5dcb 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -1,150 +1,138 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; - -export class ArrayTests { - @Test("Array access") - public arrayAccess(): void { - const result = util.transpileAndExecute( - `const arr: number[] = [3,5,1]; - return arr[1];` - ); - Expect(result).toBe(5); - } - - @Test("Readonly Array access") - public readonlyArrayAccess(): void { - const result = util.transpileAndExecute( - `const arr: ReadonlyArray = [3,5,1]; - return arr[1];` - ); - Expect(result).toBe(5); - } - - @Test("Array union access") - public arrayUnionAccess(): void { - const result = util.transpileAndExecute( - `function makeArray(): number[] | string[] { return [3,5,1]; } - const arr = makeArray(); - return arr[1];` - ); - Expect(result).toBe(5); - } - - @Test("Array union access with empty tuple") - public arrayUnionAccessWithEmptyTuple(): void { - const result = util.transpileAndExecute( - `function makeArray(): number[] | [] { return [3,5,1]; } - const arr = makeArray(); - return arr[1];` - ); - Expect(result).toBe(5); - } - - @Test("Array union length") - public arrayUnionLength(): void { - const result = util.transpileAndExecute( - `function makeArray(): number[] | string[] { return [3,5,1]; } - const arr = makeArray(); - return arr.length;` - ); - Expect(result).toBe(3); - } - - @Test("Array intersection access") - public arrayIntersectionAccess(): void { - const result = util.transpileAndExecute( - `type I = number[] & {foo: string}; - function makeArray(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const arr = makeArray(); - return arr[1];` - ); - Expect(result).toBe(5); - } - - @Test("Array intersection length") - public arrayIntersectionLength(): void { - const result = util.transpileAndExecute( - `type I = number[] & {foo: string}; - function makeArray(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const arr = makeArray(); - return arr.length;` - ); - Expect(result).toBe(3); - } - - @TestCase("firstElement()", 3) - @TestCase("name", "array") - @TestCase("length", 1) - @Test("Derived array access") - public derivedArrayAccess(member: string, expected: any): void { - const luaHeader = `local arr = {name="array", firstElement=function(self) return self[1]; end};`; - const typeScriptHeader = - `interface CustomArray extends Array{ - name:string, - firstElement():number; - }; - declare const arr: CustomArray;`; - - const result = util.transpileAndExecute( - ` - arr[0] = 3; - return arr.${member};`, - undefined, - luaHeader, - typeScriptHeader - ); - - Expect(result).toBe(expected); - } - - @Test("Array delete") - public arrayDelete(): void { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - delete myarray[2]; - return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - Expect(result).toBe("1,2,nil,4"); - } - - @Test("Array delete return true") - public arrayDeleteReturnTrue(): void { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - const exists = delete myarray[2]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - Expect(result).toBe("true:1,2,nil,4"); - } - - @Test("Array delete return false") - public arrayDeleteReturnFalse(): void { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - const exists = delete myarray[4]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - Expect(result).toBe("true:1,2,3,4"); - } - - @Test("Array property access") - public arrayPropertyAccess(): void { - const code = - `type A = number[] & {foo?: string}; - const a: A = [1,2,3]; - a.foo = "bar"; - return \`\${a.foo}\${a[0]}\${a[1]}\${a[2]}\`;`; - Expect(util.transpileAndExecute(code)).toBe("bar123"); - } -} +import * as util from "../util"; + +test("Array access", () => { + const result = util.transpileAndExecute( + `const arr: number[] = [3,5,1]; + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Readonly Array access", () => { + const result = util.transpileAndExecute( + `const arr: ReadonlyArray = [3,5,1]; + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Array union access", () => { + const result = util.transpileAndExecute( + `function makeArray(): number[] | string[] { return [3,5,1]; } + const arr = makeArray(); + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Array union access with empty tuple", () => { + const result = util.transpileAndExecute( + `function makeArray(): number[] | [] { return [3,5,1]; } + const arr = makeArray(); + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Array union length", () => { + const result = util.transpileAndExecute( + `function makeArray(): number[] | string[] { return [3,5,1]; } + const arr = makeArray(); + return arr.length;`, + ); + expect(result).toBe(3); +}); + +test("Array intersection access", () => { + const result = util.transpileAndExecute( + `type I = number[] & {foo: string}; + function makeArray(): I { + let t = [3,5,1]; + (t as I).foo = "bar"; + return (t as I); + } + const arr = makeArray(); + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Array intersection length", () => { + const result = util.transpileAndExecute( + `type I = number[] & {foo: string}; + function makeArray(): I { + let t = [3,5,1]; + (t as I).foo = "bar"; + return (t as I); + } + const arr = makeArray(); + return arr.length;`, + ); + expect(result).toBe(3); +}); + +test.each([ + { member: "firstElement()", expected: 3 }, + { member: "name", expected: "array" }, + { member: "length", expected: 1 }, +])("Derived array access (%p)", ({ member, expected }) => { + const luaHeader = `local arr = {name="array", firstElement=function(self) return self[1]; end};`; + const typeScriptHeader = ` + interface CustomArray extends Array{ + name:string, + firstElement():number; + }; + declare const arr: CustomArray; + `; + + const result = util.transpileAndExecute( + ` + arr[0] = 3; + return arr.${member};`, + undefined, + luaHeader, + typeScriptHeader, + ); + + expect(result).toBe(expected); +}); + +test("Array delete", () => { + const result = util.transpileAndExecute( + `const myarray = [1,2,3,4]; + delete myarray[2]; + return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + ); + + expect(result).toBe("1,2,nil,4"); +}); + +test("Array delete return true", () => { + const result = util.transpileAndExecute( + `const myarray = [1,2,3,4]; + const exists = delete myarray[2]; + return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + ); + + expect(result).toBe("true:1,2,nil,4"); +}); + +test("Array delete return false", () => { + const result = util.transpileAndExecute( + `const myarray = [1,2,3,4]; + const exists = delete myarray[4]; + return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + ); + + expect(result).toBe("true:1,2,3,4"); +}); + +test("Array property access", () => { + const code = ` + type A = number[] & {foo?: string}; + const a: A = [1,2,3]; + a.foo = "bar"; + return \`\${a.foo}\${a[0]}\${a[1]}\${a[2]}\`; + `; + expect(util.transpileAndExecute(code)).toBe("bar123"); +}); diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 985ee4472..41fb9899b 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -1,63 +1,53 @@ -import { Expect, Test, TestCase } from "alsatian"; -import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; -import * as util from "../src/util"; +import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as util from "../util"; -export class AssignmentDestructuringTests { +const assignmentDestruturingTs = ` + declare function myFunc(this: void): [number, string]; + let [a, b] = myFunc();`; - private readonly assignmentDestruturingTs = ` - declare function myFunc(this: void): [number, string]; - let [a, b] = myFunc();`; +test("Assignment destructuring [5.1]", () => { + const lua = util.transpileString(assignmentDestruturingTs, { + luaTarget: LuaTarget.Lua51, + luaLibImport: LuaLibImportKind.None, + }); + expect(lua).toBe(`local a, b = unpack(myFunc());`); +}); - @Test("Assignment destructuring [5.1]") - public assignmentDestructuring51(): void { - // Transpile - const lua = util.transpileString( - this.assignmentDestruturingTs, {luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None} - ); - // Assert - Expect(lua).toBe(`local a, b = unpack(myFunc());`); - } +test("Assignment destructuring [5.2]", () => { + const lua = util.transpileString(assignmentDestruturingTs, { + luaTarget: LuaTarget.Lua52, + luaLibImport: LuaLibImportKind.None, + }); + expect(lua).toBe(`local a, b = table.unpack(myFunc());`); +}); - @Test("Assignment destructuring [5.2]") - public tupleDestructing52(): void { - // Transpile - const lua = util.transpileString( - this.assignmentDestruturingTs, {luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None} - ); - // Assert - Expect(lua).toBe(`local a, b = table.unpack(myFunc());`); - } +test("Assignment destructuring [JIT]", () => { + const lua = util.transpileString(assignmentDestruturingTs, { + luaTarget: LuaTarget.LuaJIT, + luaLibImport: LuaLibImportKind.None, + }); + expect(lua).toBe(`local a, b = unpack(myFunc());`); +}); - @Test("Assignment destructuring [JIT]") - public assignmentDestructuringJIT(): void { - // Transpile - const lua = util.transpileString( - this.assignmentDestruturingTs, {luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None} - ); - // Assert - Expect(lua).toBe(`local a, b = unpack(myFunc());`); - } +test.each([ + "function foo(): [] { return []; }; let [] = foo();", + "let [] = ['a', 'b', 'c'];", + "let [] = [];", + "let [] = [] = [];", + "function foo(): [] { return []; }; [] = foo();", + "[] = ['a', 'b', 'c'];", + "[] = [];", + "[] = [] = [];", +])("Empty destructuring (%p)", code => { + expect(() => util.transpileAndExecute(code)).not.toThrow(); +}); - @TestCase("function foo(): [] { return []; }; let [] = foo();") - @TestCase("let [] = ['a', 'b', 'c'];") - @TestCase("let [] = [];") - @TestCase("let [] = [] = [];") - @TestCase("function foo(): [] { return []; }; [] = foo();") - @TestCase("[] = ['a', 'b', 'c'];") - @TestCase("[] = [];") - @TestCase("[] = [] = [];") - @Test("Empty destructuring") - public emptyDestructuring(code: string): void { - Expect(() => util.transpileAndExecute(code)).not.toThrow(); - } - - @Test("Union destructuring") - public unionDestructuring(): void { - const code = - `function foo(): [string] | [] { return ["bar"]; } - let x: string; - [x] = foo(); - return x;`; - Expect(util.transpileAndExecute(code)).toBe("bar"); - } -} +test("Union destructuring", () => { + const code = ` + function foo(): [string] | [] { return ["bar"]; } + let x: string; + [x] = foo(); + return x; + `; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts deleted file mode 100644 index f5d5e0ddb..000000000 --- a/test/unit/assignments.spec.ts +++ /dev/null @@ -1,1196 +0,0 @@ -import { Expect, Test, TestCase, TestCases } from "alsatian"; -import { TranspileError } from "../../src/TranspileError"; - -import * as util from "../src/util"; -import { TSTLErrors } from "../../src/TSTLErrors"; -const fs = require("fs"); - -interface TestFunction { - value: string; - definition?: string; -} - -const selfTestFunctions: TestFunction[] = [ - { - value: "selfFunc", - definition: `let selfFunc: {(this: any, s: string): string} = function(s) { return s; };`, - }, - { - value: "selfLambda", - definition: `let selfLambda: (this: any, s: string) => string = s => s;`, - }, - { - value: "anonFunc", - definition: `let anonFunc: {(s: string): string} = function(s) { return s; };`, - }, - { - value: "anonLambda", - definition: `let anonLambda: (s: string) => string = s => s;`, - }, - { - value: "methodClass.method", - definition: `class MethodClass { method(this: any, s: string): string { return s; } } - const methodClass = new MethodClass();`, - }, - { - value: "anonMethodClass.anonMethod", - definition: `class AnonMethodClass { anonMethod(s: string): string { return s; } } - const anonMethodClass = new AnonMethodClass();`, - }, - { - value: "funcPropClass.funcProp", - definition: `class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } - const funcPropClass = new FuncPropClass();`, - }, - { - value: "anonFuncPropClass.anonFuncProp", - definition: `class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } - const anonFuncPropClass = new AnonFuncPropClass();`, - }, - { - value: "StaticMethodClass.staticMethod", - definition: `class StaticMethodClass { - static staticMethod(this: any, s: string): string { return s; } - }`, - }, - { - value: "AnonStaticMethodClass.anonStaticMethod", - definition: `class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }`, - }, - { - value: "StaticFuncPropClass.staticFuncProp", - definition: `class StaticFuncPropClass { - static staticFuncProp: (this: any, s: string) => string = s => s; - }`, - }, - { - value: "AnonStaticFuncPropClass.anonStaticFuncProp", - definition: `class AnonStaticFuncPropClass { - static anonStaticFuncProp: (s: string) => string = s => s; - }`, - }, - { - value: "FuncNs.nsFunc", - definition: `namespace FuncNs { export function nsFunc(s: string) { return s; } }`, - }, - { - value: "FuncNestedNs.NestedNs.nestedNsFunc", - definition: `namespace FuncNestedNs { - export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } - }`, - }, - { - value: "LambdaNs.nsLambda", - definition: `namespace LambdaNs { - export let nsLambda: (s: string) => string = s => s; - }`, - }, - { - value: "LambdaNestedNs.NestedNs.nestedNsLambda", - definition: `namespace LambdaNestedNs { - export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } - }`, - }, - { - value: "methodInterface.method", - definition: `interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, - }, - { - value: "anonMethodInterface.anonMethod", - definition: `interface AnonMethodInterface { anonMethod(s: string): string; } - const anonMethodInterface: AnonMethodInterface = { - anonMethod: function(this: any, s: string): string { return s; } - };`, - }, - { - value: "funcPropInterface.funcProp", - definition: `interface FuncPropInterface { funcProp: (this: any, s: string) => string; } - const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };`, - }, - { - value: "anonFuncPropInterface.anonFuncProp", - definition: `interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } - const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };`, - }, - { - value: "anonMethodClassInNoSelfNs.method", - definition: `/** @noSelf */ namespace AnonMethodClassInNoSelfNs { - export class MethodClass { - method(s: string): string { return s; } - } - } - const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();`, - }, - { - value: "anonMethodInterfaceInNoSelfNs.method", - definition: `/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { - export interface MethodInterface { - method(s: string): string; - } - } - const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { - method: function(s: string): string { return s; } - };`, - }, - { - value: "anonFunctionNestedInNoSelfClass", - definition: `/** @noSelf */ class AnonFunctionNestedInNoSelfClass { - method() { return function(s: string) { return s; } } - } - const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();`, - }, -]; - -const noSelfTestFunctions: TestFunction[] = [ - { - value: "voidFunc", - definition: `let voidFunc: {(this: void, s: string): string} = function(s) { return s; };`, - }, - { - value: "voidLambda", - definition: `let voidLambda: (this: void, s: string) => string = s => s;`, - }, - { - value: "voidMethodClass.voidMethod", - definition: `class VoidMethodClass { - voidMethod(this: void, s: string): string { return s; } - } - const voidMethodClass = new VoidMethodClass();`, - }, - { - value: "voidFuncPropClass.voidFuncProp", - definition: `class VoidFuncPropClass { - voidFuncProp: (this: void, s: string) => string = s => s; - } - const voidFuncPropClass = new VoidFuncPropClass();`, - }, - { - value: "StaticVoidMethodClass.staticVoidMethod", - definition: `class StaticVoidMethodClass { - static staticVoidMethod(this: void, s: string): string { return s; } - }`, - }, - { - value: "StaticVoidFuncPropClass.staticVoidFuncProp", - definition: `class StaticVoidFuncPropClass { - static staticVoidFuncProp: (this: void, s: string) => string = s => s; - }`, - }, - { - value: "NoSelfFuncNs.noSelfNsFunc", - definition: `/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }`, - }, - { - value: "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc", - definition: `/** @noSelf */ namespace NoSelfFuncNestedNs { - export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } - }`, - }, - { - value: "NoSelfLambdaNs.noSelfNsLambda", - definition: `/** @noSelf */ namespace NoSelfLambdaNs { - export let noSelfNsLambda: (s: string) => string = s => s; - }`, - }, - { - value: "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda", - definition: `/** @noSelf */ namespace NoSelfLambdaNestedNs { - export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } - }`, - }, - { - value: "noSelfMethodClass.noSelfMethod", - definition: `/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } - const noSelfMethodClass = new NoSelfMethodClass();`, - }, - { - value: "NoSelfStaticMethodClass.noSelfStaticMethod", - definition: `/** @noSelf */ class NoSelfStaticMethodClass { - static noSelfStaticMethod(s: string): string { return s; } - }`, - }, - { - value: "noSelfFuncPropClass.noSelfFuncProp", - definition: `/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } - const noSelfFuncPropClass = new NoSelfFuncPropClass();`, - }, - { - value: "NoSelfStaticFuncPropClass.noSelfStaticFuncProp", - definition: `/** @noSelf */ class NoSelfStaticFuncPropClass { - static noSelfStaticFuncProp: (s: string) => string = s => s; - }`, - }, - { - value: "voidMethodInterface.voidMethod", - definition: `interface VoidMethodInterface { - voidMethod(this: void, s: string): string; - } - const voidMethodInterface: VoidMethodInterface = { - voidMethod(this: void, s: string): string { return s; } - };`, - }, - { - value: "voidFuncPropInterface.voidFuncProp", - definition: `interface VoidFuncPropInterface { - voidFuncProp: (this: void, s: string) => string; - } - const voidFuncPropInterface: VoidFuncPropInterface = { - voidFuncProp: function(this: void, s: string): string { return s; } - };`, - }, - { - value: "noSelfMethodInterface.noSelfMethod", - definition: `/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } - const noSelfMethodInterface: NoSelfMethodInterface = { - noSelfMethod: function(s: string): string { return s; } - };`, - }, - { - value: "noSelfFuncPropInterface.noSelfFuncProp", - definition: `/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } - const noSelfFuncPropInterface: NoSelfFuncPropInterface = { - noSelfFuncProp: (s: string): string => s - };`, - }, - { - value: "noSelfMethodClassExpression.noSelfMethod", - definition: `/** @noSelf */ const NoSelfMethodClassExpression = class { - noSelfMethod(s: string): string { return s; } - } - const noSelfMethodClassExpression = new NoSelfMethodClassExpression();`, - }, - { - value: "anonFunctionNestedInClassInNoSelfNs", - definition: `/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { - export class AnonFunctionNestedInClass { - method() { return function(s: string) { return s; } } - } - } - const anonFunctionNestedInClassInNoSelfNs = - (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();`, - }, -]; - -const noSelfInFileTestFunctions: TestFunction[] = [ - { - value: "noSelfInFileFunc", - definition: `/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };`, - }, - { - value: "noSelfInFileLambda", - definition: `/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;`, - }, - { - value: "NoSelfInFileFuncNs.noSelfInFileNsFunc", - definition: `/** @noSelfInFile */ namespace NoSelfInFileFuncNs { - export function noSelfInFileNsFunc(s: string) { return s; } - }`, - }, - { - value: "NoSelfInFileLambdaNs.noSelfInFileNsLambda", - definition: `/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { - export let noSelfInFileNsLambda: (s: string) => string = s => s; - }`, - }, - { - value: "noSelfInFileFuncNestedInClass", - definition: `/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { - method() { return function(s: string) { return s; } } - } - const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();`, - }, -]; - -const anonTestFunctionExpressions: TestFunction[] = [ - {value: `s => s`}, - {value: `(s => s)`}, - {value: `function(s) { return s; }`}, - {value: `(function(s) { return s; })`}, -]; - -const selfTestFunctionExpressions: TestFunction[] = [ - {value: `function(this: any, s) { return s; }`}, - {value: `(function(this: any, s) { return s; })`}, -]; - -const noSelfTestFunctionExpressions: TestFunction[] = [ - {value: `function(this: void, s) { return s; }`}, - {value: `(function(this: void, s) { return s; })`}, -]; - -const anonTestFunctionType = "(s: string) => string"; -const selfTestFunctionType = "(this: any, s: string) => string"; -const noSelfTestFunctionType = "(this: void, s: string) => string"; - -type TestFunctionCast = [ - /*testFunction: */TestFunction, - /*castedFunction: */string, - /*isSelfConversion?: */boolean? -]; -const validTestFunctionCasts: TestFunctionCast[] = [ - [selfTestFunctions[0], `<${anonTestFunctionType}>(${selfTestFunctions[0].value})`], - [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${anonTestFunctionType})`], - [selfTestFunctions[0], `<${selfTestFunctionType}>(${selfTestFunctions[0].value})`], - [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${selfTestFunctionType})`], - [noSelfTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfTestFunctions[0].value})`], - [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${noSelfTestFunctionType})`], - [noSelfInFileTestFunctions[0], `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], - [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`], - [noSelfInFileTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], - [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`], -]; -const invalidTestFunctionCasts: TestFunctionCast[] = [ - [noSelfTestFunctions[0], `<${anonTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], - [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, false], - [noSelfTestFunctions[0], `<${selfTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], - [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${selfTestFunctionType})`, false], - [noSelfInFileTestFunctions[0], `<${selfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, false], - [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${selfTestFunctionType})`, false], - [selfTestFunctions[0], `<${noSelfTestFunctionType}>(${selfTestFunctions[0].value})`, true], - [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${noSelfTestFunctionType})`, true], -]; - -type TestFunctionAssignment = [ - /*testFunction: */TestFunction, - /*functionType: */string, - /*isSelfConversion?: */boolean? -]; -const validTestFunctionAssignments: TestFunctionAssignment[] = [ - ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), - ...selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), - ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), - ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), - ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), - ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), - ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), - ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), - ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), - ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), - ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), -]; -const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ - ...selfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), - ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), - ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), - ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), - ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), - ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), - ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), -]; - -export class AssignmentTests { - - @TestCase(`"abc"`, `"abc"`) - @TestCase("3", "3") - @TestCase("[1,2,3]", "{1, 2, 3}") - @TestCase("true", "true") - @TestCase("false", "false") - @TestCase(`{a:3,b:"4"}`, `{a = 3, b = "4"}`) - @Test("Const assignment") - public constAssignment(inp: string, out: string): void { - const lua = util.transpileString(`const myvar = ${inp};`); - Expect(lua).toBe(`local myvar = ${out};`); - } - - @TestCase(`"abc"`, `"abc"`) - @TestCase("3", "3") - @TestCase("[1,2,3]", "{1, 2, 3}") - @TestCase("true", "true") - @TestCase("false", "false") - @TestCase(`{a:3,b:"4"}`, `{a = 3, b = "4"}`) - @Test("Let assignment") - public letAssignment(inp: string, out: string): void { - const lua = util.transpileString(`let myvar = ${inp};`); - Expect(lua).toBe(`local myvar = ${out};`); - } - - @TestCase(`"abc"`, `"abc"`) - @TestCase("3", "3") - @TestCase("[1,2,3]", "{1, 2, 3}") - @TestCase("true", "true") - @TestCase("false", "false") - @TestCase(`{a:3,b:"4"}`, `{a = 3, b = "4"}`) - @Test("Var assignment") - public varAssignment(inp: string, out: string): void { - const lua = util.transpileString(`var myvar = ${inp};`); - Expect(lua).toBe(`myvar = ${out};`); - } - - @TestCase("var myvar;") - @TestCase("let myvar;") - @TestCase("const myvar = null;") - @TestCase("const myvar = undefined;") - @Test("Null assignments") - public nullAssignment(declaration: string): void { - const result = util.transpileAndExecute(declaration + " return myvar;"); - Expect(result).toBe(undefined); - } - - @TestCase(["a", "b"], ["e", "f"]) - @TestCase(["a", "b"], ["e", "f", "g"]) - @TestCase(["a", "b", "c"], ["e", "f", "g"]) - @Test("Binding pattern assignment") - public bindingPattern(input: string[], values: string[]): void { - const pattern = input.join(","); - const initializer = values.map(v => `"${v}"`).join(","); - - const tsCode = `const [${pattern}] = [${initializer}]; return [${pattern}].join("-");`; - const result = util.transpileAndExecute(tsCode); - - Expect(result).toBe(values.slice(0, input.length).join("-")); - } - - @Test("Ellipsis binding pattern") - public ellipsisBindingPattern(): void { - Expect(() => util.transpileString("let [a,b,...c] = [1,2,3];")) - .toThrowError(Error, "Ellipsis destruction is not allowed."); - } - - @Test("Tuple Assignment") - public tupleAssignment(): void { - const code = `function abc(): [number, number] { return [1, 2]; }; - let t: [number, number] = abc(); - return t[0] + t[1];`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(3); - } - - @Test("TupleReturn assignment") - public tupleReturnFunction(): void { - const code = `/** @tupleReturn */\n` - + `declare function abc(this: void): number[]\n` - + `let [a,b] = abc();`; - - const lua = util.transpileString(code); - Expect(lua).toBe("local a, b = abc();"); - } - - @Test("TupleReturn Single assignment") - public tupleReturnSingleAssignment(): void { - const code = `/** @tupleReturn */\n` - + `declare function abc(this: void): [number, string];\n` - + `let a = abc();` - + `a = abc();`; - - const lua = util.transpileString(code); - Expect(lua).toBe("local a = ({abc()});\na = ({abc()});"); - } - - @Test("TupleReturn interface assignment") - public tupleReturnInterface(): void { - const code = `interface def {\n` - + `/** @tupleReturn */\n` - + `abc();\n` - + `} declare const jkl : def;\n` - + `let [a,b] = jkl.abc();`; - - const lua = util.transpileString(code); - Expect(lua).toBe("local a, b = jkl:abc();"); - } - - @Test("TupleReturn namespace assignment") - public tupleReturnNameSpace(): void { - const code = `declare namespace def {\n` - + `/** @tupleReturn */\n` - + `function abc(this: void) {}\n` - + `}\n` - + `let [a,b] = def.abc();`; - - const lua = util.transpileString(code); - Expect(lua).toBe("local a, b = def.abc();"); - } - - @Test("TupleReturn method assignment") - public tupleReturnMethod(): void { - const code = `declare class def {\n` - + `/** @tupleReturn */\n` - + `abc() { return [1,2,3]; }\n` - + `} const jkl = new def();\n` - + `let [a,b] = jkl.abc();`; - - const lua = util.transpileString(code); - Expect(lua).toBe("local jkl = def.new();\nlocal a, b = jkl:abc();"); - } - - @Test("TupleReturn functional") - public tupleReturnFunctional(): void { - const code = `/** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const [a, b] = abc(); - return b + a;`; - - const result = util.transpileAndExecute(code); - - Expect(result).toBe("a3"); - } - - @Test("TupleReturn single") - public tupleReturnSingle(): void { - const code = `/** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const res = abc(); - return res.length`; - - const result = util.transpileAndExecute(code); - - Expect(result).toBe(2); - } - - @Test("TupleReturn in expression") - public tupleReturnInExpression(): void { - const code = `/** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - return abc()[1] + abc()[0];`; - - const result = util.transpileAndExecute(code); - - Expect(result).toBe("a3"); - } - - @TestCase("and") - @TestCase("local") - @TestCase("nil") - @TestCase("not") - @TestCase("or") - @TestCase("repeat") - @TestCase("then") - @TestCase("until") - @Test("Keyword identifier error") - public keywordIdentifierError(identifier: string): void { - Expect(() => util.transpileString(`const ${identifier} = 3;`)) - .toThrowError(TranspileError, `Cannot use Lua keyword ${identifier} as identifier.`); - } - - @TestCases(validTestFunctionAssignments) - @Test("Valid function variable declaration") - public validFunctionDeclaration(testFunction: TestFunction, functionType: string): void { - const code = - `const fn: ${functionType} = ${testFunction.value}; - return fn("foobar");`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(validTestFunctionAssignments) - @Test("Valid function assignment") - public validFunctionAssignment(testFunction: TestFunction, functionType: string): void { - const code = - `let fn: ${functionType}; - fn = ${testFunction.value}; - return fn("foobar");`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionAssignments) - @Test("Invalid function variable declaration") - public invalidFunctionDeclaration(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) - : void - { - const code = - `${testFunction.definition || ""} - const fn: ${functionType} = ${testFunction.value};`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(invalidTestFunctionAssignments) - @Test("Invalid function assignment") - public invalidFunctionAssignment(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) - : void - { - const code = - `${testFunction.definition || ""} - let fn: ${functionType}; - fn = ${testFunction.value};`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(validTestFunctionCasts) - @Test("Valid function assignment with cast") - public validFunctionAssignmentWithCast(testFunction: TestFunction, castedFunction: string): void { - const code = - `let fn: typeof ${testFunction.value}; - fn = ${castedFunction}; - return fn("foobar");`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionCasts) - @Test("Invalid function assignment with cast") - public invalidFunctionAssignmentWithCast( - testFunction: TestFunction, - castedFunction: string, - isSelfConversion: boolean - ): void { - const code = - `${testFunction.definition || ""} - let fn: typeof ${testFunction.value}; - fn = ${castedFunction};`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(validTestFunctionAssignments) - @Test("Valid function argument") - public validFunctionArgument(testFunction: TestFunction, functionType: string): void { - const code = - `function takesFunction(fn: ${functionType}) { - return fn("foobar"); - } - return takesFunction(${testFunction.value});`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionAssignments) - @Test("Invalid function argument") - public invalidFunctionArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) - : void - { - const code = - `${testFunction.definition || ""} - declare function takesFunction(fn: ${functionType}); - takesFunction(${testFunction.value});`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @Test("Valid lua lib function argument") - public validLuaLibFunctionArgument(): void { - const code = - `let result = ""; - function foo(this: any, value: string) { result += value; } - const a = ['foo', 'bar']; - a.forEach(foo); - return result;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } - - @Test("Invalid lua lib function argument") - public invalidLuaLibFunctionArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) - : void - { - const code = - `declare function foo(this: void, value: string): void; - declare const a: string[]; - a.forEach(foo);`; - const err = TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "callbackfn"); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(validTestFunctionCasts) - @Test("Valid function argument with cast") - public validFunctionArgumentWithCast(testFunction: TestFunction, castedFunction: string): void { - const code = - `function takesFunction(fn: typeof ${testFunction.value}) { - return fn("foobar"); - } - return takesFunction(${castedFunction});`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionCasts) - @Test("Invalid function argument with cast") - public invalidFunctionArgumentWithCast( - testFunction: TestFunction, - castedFunction: string, - isSelfConversion: boolean - ): void - { - const code = - `${testFunction.definition || ""} - declare function takesFunction(fn: typeof ${testFunction.value}); - takesFunction(${castedFunction});`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - // TODO: Fix function expression inference with generic types. The following should work, but doesn't: - // function takesFunction string>(fn: T) { ... } - // takesFunction(s => s); // Error: cannot convert method to function - // @TestCases(validTestFunctionAssignments) // Use this instead of other TestCases when fixed - @TestCases(selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType])) - @TestCases(selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType])) - @TestCases(noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType])) - @TestCases(selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType])) - @TestCases(selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType])) - @TestCases(noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType])) - @Test("Valid function generic argument") - public validFunctionGenericArgument(testFunction: TestFunction, functionType: string): void { - const code = - `function takesFunction(fn: T) { - return fn("foobar"); - } - return takesFunction(${testFunction.value});`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionAssignments) - @Test("Invalid function generic argument") - public invalidFunctionGenericArgument(testFunction: TestFunction, functionType: string, isSelfConversion: boolean) - : void - { - const code = - `${testFunction.definition || ""} - declare function takesFunction(fn: T); - takesFunction(${testFunction.value});`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn"); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(anonTestFunctionExpressions.map(f => [f, "0", "'foobar'"])) - @TestCases(selfTestFunctionExpressions.map(f => [f, "0", "'foobar'"])) - @TestCases(noSelfTestFunctionExpressions.map(f => [f, "'foobar'"])) - @Test("Valid function expression argument with no signature") - public validFunctionExpressionArgumentNoSignature(testFunction: TestFunction, ...args: string[]): void { - const code = - `const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { - return fn(...args); - } - return takesFunction(${testFunction.value}, ${args.join(", ")});`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(validTestFunctionAssignments) - @Test("Valid function return") - public validFunctionReturn(testFunction: TestFunction, functionType: string): void { - const code = - `function returnsFunction(): ${functionType} { - return ${testFunction.value}; - } - const fn = returnsFunction(); - return fn("foobar");`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionAssignments) - @Test("Invalid function return") - public invalidFunctionReturn(testFunction: TestFunction, functionType: string, isSelfConversion: boolean): void { - const code = - `${testFunction.definition || ""} - function returnsFunction(): ${functionType} { - return ${testFunction.value}; - }`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @TestCases(validTestFunctionCasts) - @Test("Valid function return with cast") - public validFunctionReturnWithCast(testFunction: TestFunction, castedFunction: string): void { - const code = - `function returnsFunction(): typeof ${testFunction.value} { - return ${castedFunction}; - } - const fn = returnsFunction(); - return fn("foobar");`; - Expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); - } - - @TestCases(invalidTestFunctionCasts) - @Test("Invalid function return with cast") - public invalidFunctionReturnWithCast( - testFunction: TestFunction, - castedFunction: string, - isSelfConversion: boolean - ): void - { - const code = - `${testFunction.definition || ""} - function returnsFunction(): typeof ${testFunction.value} { - return ${castedFunction}; - }`; - const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(undefined) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined); - Expect(() => util.transpileString(code, undefined, false)).toThrowError(TranspileError, err.message); - } - - @Test("Interface method assignment") - public interfaceMethodAssignment(): void { - const code = `class Foo { - method(s: string): string { return s + "+method"; } - lambdaProp: (s: string) => string = s => s + "+lambdaProp"; - } - interface IFoo { - method: (s: string) => string; - lambdaProp(s: string): string; - } - const foo: IFoo = new Foo(); - return foo.method("foo") + "|" + foo.lambdaProp("bar");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo+method|bar+lambdaProp"); - } - - @Test("Valid function tuple assignment") - public validFunctionTupleAssignment(): void { - const code = `interface Func { (this: void, s: string): string; } - function getTuple(): [number, Func] { return [1, s => s]; } - let [i, f]: [number, Func] = getTuple(); - return f("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Invalid function tuple assignment") - public invalidFunctionTupleAssignment(): void { - const code = `interface Func { (this: void, s: string): string; } - interface Meth { (this: {}, s: string): string; } - declare function getTuple(): [number, Meth]; - let [i, f]: [number, Func] = getTuple();`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined).message - ); - } - - @Test("Valid method tuple assignment") - public validMethodTupleAssignment(): void { - const code = `interface Foo { method(s: string): string; } - interface Meth { (this: Foo, s: string): string; } - let meth: Meth = s => s; - function getTuple(): [number, Meth] { return [1, meth]; } - let [i, f]: [number, Meth] = getTuple(); - let foo: Foo = {method: f}; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Invalid method tuple assignment") - public invalidMethodTupleAssignment(): void { - const code = `interface Func { (this: void, s: string): string; } - interface Meth { (this: {}, s: string): string; } - declare function getTuple(): [number, Func]; - let [i, f]: [number, Meth] = getTuple();`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - TSTLErrors.UnsupportedSelfFunctionConversion(undefined).message - ); - } - - @Test("Valid interface method assignment") - public validInterfaceMethodAssignment(): void { - const code = `interface A { fn(this: void, s: string): string; } - interface B { fn(this: void, s: string): string; } - const a: A = { fn(this: void, s) { return s; } }; - const b: B = a; - return b.fn("foo");`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Invalid interface method assignment") - public invalidInterfaceMethodAssignment(): void { - const code = `interface A { fn(s: string): string; } - interface B { fn(this: void, s: string): string; } - declare const a: A; - const b: B = a;`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - TSTLErrors.UnsupportedNoSelfFunctionConversion(undefined, "fn").message - ); - } - - @TestCase("(this: any, s: string) => string", ["foo"], "foobar") - @TestCase("{(this: any, s: string): string}", ["foo"], "foobar") - @TestCase("(this: any, s1: string, s2: string) => string", ["foo", "baz"], "foobaz") - @TestCase("{(this: any, s1: string, s2: string): string}", ["foo", "baz"], "foobaz") - @Test("Valid function overload assignment") - public validFunctionOverloadAssignment(assignType: string, args: string[], expectResult: string): void { - const code = `interface O { - (s1: string, s2: string): string; - (s: string): string; - } - const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); - let f: ${assignType} = o; - return f(${args.map(a => "\"" + a + "\"").join(", ")});`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); - } - - @TestCase("(this: void, s: string) => string") - @TestCase("(this: void, s1: string, s2: string) => string") - @TestCase("{(this: void, s: string): string}") - @TestCase("{(this: any, s1: string, s2: string): string}") - @Test("Invalid function overload assignment") - public invalidFunctionOverloadAssignment(assignType: string): void { - const code = `interface O { - (this: any, s1: string, s2: string): string; - (this: void, s: string): string; - } - declare const o: O; - let f: ${assignType} = o;`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - TSTLErrors.UnsupportedOverloadAssignment(undefined).message - ); - } - - @TestCase("noSelf") - @TestCase("noSelfInFile") - @Test("noSelf function method argument") - public noSelfFunctionMethodArgument(noSelfTag: string): void { - const header = - `/** @${noSelfTag} */ namespace NS { - export class C { - method(fn: (s: string) => string) { return fn("foo"); } - } - } - function foo(this: void, s: string) { return s; }`; - const code = - `const c = new NS.C(); - return c.method(foo);`; - Expect(util.transpileAndExecute(code, undefined, undefined, header, false)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string") - @TestCase("(this: any, s: string) => string") - @TestCase("(s: string) => string") - @Test("Function expression type inference in binary operator") - public functionExpressionTypeInferenceInBinaryOp(funcType: string): void { - const header = `declare const undefinedFunc: ${funcType};`; - const code = - `let func: ${funcType} = s => s; - func = undefinedFunc || (s => s); - return func("foo");`; - Expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); - } - - @TestCase("s => s") - @TestCase("(s => s)") - @TestCase("function(s) { return s; }") - @TestCase("(function(s) { return s; })") - @Test("Function expression type inference in class") - public functionExpressionTypeInferenceInClass(funcExp: string): void { - const code = - `class Foo { - func: (this: void, s: string) => string = ${funcExp}; - method: (s: string) => string = ${funcExp}; - static staticFunc: (this: void, s: string) => string = ${funcExp}; - static staticMethod: (s: string) => string = ${funcExp}; - } - const foo = new Foo(); - return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d");`; - Expect(util.transpileAndExecute(code)).toBe("abcd"); - } - - @TestCase("const foo: Foo", "s => s") - @TestCase("const foo: Foo", "(s => s)") - @TestCase("const foo: Foo", "function(s) { return s; }") - @TestCase("const foo: Foo", "(function(s) { return s; })") - @TestCase("let foo: Foo; foo", "s => s") - @TestCase("let foo: Foo; foo", "(s => s)") - @TestCase("let foo: Foo; foo", "function(s) { return s; }") - @TestCase("let foo: Foo; foo", "(function(s) { return s; })") - @Test("Function expression type inference in object literal") - public functionExpressionTypeInferenceInObjectLiteral(assignTo: string, funcExp: string): void { - const code = - `interface Foo { - func(this: void, s: string): string; - method(this: this, s: string): string; - } - ${assignTo} = {func: ${funcExp}, method: ${funcExp}}; - return foo.method("foo") + foo.func("bar");`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } - - @Test("Function expression type inference in object literal assigned to narrower type") - public functionEXpressionTypeInferenceInObjectLiteralAssignedToNarrowerType(): void { - const code = - `let foo: {} = {bar: s => s}; - return (foo as {bar: (a: any) => any}).bar("foobar");`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } - - @TestCase("const foo: Foo", "s => s") - @TestCase("const foo: Foo", "(s => s)") - @TestCase("const foo: Foo", "function(s) { return s; }") - @TestCase("const foo: Foo", "(function(s) { return s; })") - @TestCase("let foo: Foo; foo", "s => s") - @TestCase("let foo: Foo; foo", "(s => s)") - @TestCase("let foo: Foo; foo", "function(s) { return s; }") - @TestCase("let foo: Foo; foo", "(function(s) { return s; })") - @Test("Function expression type inference in object literal (generic key)") - public functionExpressionTypeInferenceInObjectLiteralGenericKey(assignTo: string, funcExp: string): void { - const code = - `interface Foo { - [f: string]: (this: void, s: string) => string; - } - ${assignTo} = {func: ${funcExp}}; - return foo.func("foo");`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("const funcs: [Func, Method]", "funcs[0]", "funcs[1]", "s => s") - @TestCase("const funcs: [Func, Method]", "funcs[0]", "funcs[1]", "(s => s)") - @TestCase("const funcs: [Func, Method]", "funcs[0]", "funcs[1]", "function(s) { return s; }") - @TestCase("const funcs: [Func, Method]", "funcs[0]", "funcs[1]", "(function(s) { return s; })") - @TestCase("let funcs: [Func, Method]; funcs", "funcs[0]", "funcs[1]", "s => s") - @TestCase("let funcs: [Func, Method]; funcs", "funcs[0]", "funcs[1]", "(s => s)") - @TestCase("let funcs: [Func, Method]; funcs", "funcs[0]", "funcs[1]", "function(s) { return s; }") - @TestCase("let funcs: [Func, Method]; funcs", "funcs[0]", "funcs[1]", "(function(s) { return s; })") - @TestCase("const [func, meth]: [Func, Method]", "func", "meth", "s => s") - @TestCase("const [func, meth]: [Func, Method]", "func", "meth", "(s => s)") - @TestCase("const [func, meth]: [Func, Method]", "func", "meth", "function(s) { return s; }") - @TestCase("const [func, meth]: [Func, Method]", "func", "meth", "(function(s) { return s; })") - @TestCase("let func: Func; let meth: Method; [func, meth]", "func", "meth", "s => s") - @TestCase("let func: Func; let meth: Method; [func, meth]", "func", "meth", "(s => s)") - @TestCase("let func: Func; let meth: Method; [func, meth]", "func", "meth", "function(s) { return s; }") - @TestCase("let func: Func; let meth: Method; [func, meth]", "func", "meth", "(function(s) { return s; })") - @Test("Function expression type inference in tuple") - public functionExpressionTypeInferenceInTuple( - assignTo: string, - func: string, - method: string, - funcExp: string - ): void - { - const code = - `interface Foo { - method(s: string): string; - } - interface Func { - (this: void, s: string): string; - } - interface Method { - (this: Foo, s: string): string; - } - ${assignTo} = [${funcExp}, ${funcExp}]; - const foo: Foo = {method: ${method}}; - return foo.method("foo") + ${func}("bar");`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } - - @TestCase("const meths: Method[]", "meths[0]", "s => s") - @TestCase("const meths: Method[]", "meths[0]", "(s => s)") - @TestCase("const meths: Method[]", "meths[0]", "function(s) { return s; }") - @TestCase("const meths: Method[]", "meths[0]", "(function(s) { return s; })") - @TestCase("let meths: Method[]; meths", "meths[0]", "s => s") - @TestCase("let meths: Method[]; meths", "meths[0]", "(s => s)") - @TestCase("let meths: Method[]; meths", "meths[0]", "function(s) { return s; }") - @TestCase("let meths: Method[]; meths", "meths[0]", "(function(s) { return s; })") - @TestCase("const [meth]: Method[]", "meth", "s => s") - @TestCase("const [meth]: Method[]", "meth", "(s => s)") - @TestCase("const [meth]: Method[]", "meth", "function(s) { return s; }") - @TestCase("const [meth]: Method[]", "meth", "(function(s) { return s; })") - @TestCase("let meth: Method; [meth]", "meth", "s => s") - @TestCase("let meth: Method; [meth]", "meth", "(s => s)") - @TestCase("let meth: Method; [meth]", "meth", "function(s) { return s; }") - @TestCase("let meth: Method; [meth]", "meth", "(function(s) { return s; })") - @Test("Function expression type inference in array") - public functionExpressionTypeInferenceInArray(assignTo: string, method: string, funcExp: string): void { - const code = - `interface Foo { - method(s: string): string; - } - interface Method { - (this: Foo, s: string): string; - } - ${assignTo} = [${funcExp}]; - const foo: Foo = {method: ${method}}; - return foo.method("foo");`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string", "s => s") - @TestCase("(this: any, s: string) => string", "s => s") - @TestCase("(s: string) => string", "s => s") - @TestCase("(this: void, s: string) => string", "function(s) { return s; }") - @TestCase("(this: any, s: string) => string", "function(s) { return s; }") - @TestCase("(s: string) => string", "function(s) { return s; }") - @Test("Function expression type inference in union") - public functionExpressionTypeInferenceInUnion(funcType: string, funcExp: string): void { - const code = - `type U = string | number | (${funcType}); - const u: U = ${funcExp}; - return (u as ${funcType})("foo");`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string", "s => s") - @TestCase("(this: any, s: string) => string", "s => s") - @TestCase("(s: string) => string", "s => s") - @TestCase("(this: void, s: string) => string", "function(s) { return s; }") - @TestCase("(this: any, s: string) => string", "function(s) { return s; }") - @TestCase("(s: string) => string", "function(s) { return s; }") - @Test("Function expression type inference in union tuple") - public functionExpressionTypeInferenceInUnionTuple(funcType: string, funcExp: string): void { - const code = - `interface I { callback: ${funcType}; } - let a: I[] | number = [{ callback: ${funcExp} }]; - return a[0].callback("foo");`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string", "s => s") - @TestCase("(this: any, s: string) => string", "s => s") - @TestCase("(s: string) => string", "s => s") - @TestCase("(this: void, s: string) => string", "function(s) { return s; }") - @TestCase("(this: any, s: string) => string", "function(s) { return s; }") - @TestCase("(s: string) => string", "function(s) { return s; }") - @Test("Function expression type inference in as cast") - public functionExpressionTypeInferenceInAsCast(funcType: string, funcExp: string): void { - const code = - `const fn: ${funcType} = (${funcExp}) as (${funcType}); - return fn("foo");`; - console.log(code); - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string", "s => s") - @TestCase("(this: any, s: string) => string", "s => s") - @TestCase("(s: string) => string", "s => s") - @TestCase("(this: void, s: string) => string", "function(s) { return s; }") - @TestCase("(this: any, s: string) => string", "function(s) { return s; }") - @TestCase("(s: string) => string", "function(s) { return s; }") - @Test("Function expression type inference in type assertion") - public functionExpressionTypeInferenceInTypeAssert(funcType: string, funcExp: string): void { - const code = - `const fn: ${funcType} = <${funcType}>(${funcExp}); - return fn("foo");`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @TestCase("(this: void, s: string) => string", "s => s") - @TestCase("(this: any, s: string) => string", "s => s") - @TestCase("(s: string) => string", "s => s") - @TestCase("(this: void, s: string) => string", "function(s) { return s; }") - @TestCase("(this: any, s: string) => string", "function(s) { return s; }") - @TestCase("(s: string) => string", "function(s) { return s; }") - @Test("Function expression type inference in constructor") - public functionExpresssionTypeInferenceInConstructor(funcType: string, funcExp: string): void { - const code = - `class C { - result: string; - constructor(fn: (s: string) => string) { this.result = fn("foo"); } - } - const c = new C(s => s); - return c.result;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } - - @Test("String table access") - public stringTableAccess(assignType: string): void { - const code = `const dict : {[key:string]:any} = {}; - dict["a b"] = 3; - return dict["a b"];`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(3); - } - -} diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts new file mode 100644 index 000000000..4102b6d26 --- /dev/null +++ b/test/unit/assignments/assignments.spec.ts @@ -0,0 +1,196 @@ +import * as ts from "typescript"; +import { TSTLErrors } from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test.each([ + { inp: `"abc"`, out: `"abc"` }, + { inp: "3", out: "3" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "true", out: "true" }, + { inp: "false", out: "false" }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, +])("Const assignment (%p)", ({ inp, out }) => { + const lua = util.transpileString(`const myvar = ${inp};`); + expect(lua).toBe(`local myvar = ${out};`); +}); + +test.each([ + { inp: `"abc"`, out: `"abc"` }, + { inp: "3", out: "3" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "true", out: "true" }, + { inp: "false", out: "false" }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, +])("Let assignment (%p)", ({ inp, out }) => { + const lua = util.transpileString(`let myvar = ${inp};`); + expect(lua).toBe(`local myvar = ${out};`); +}); + +test.each([ + { inp: `"abc"`, out: `"abc"` }, + { inp: "3", out: "3" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "true", out: "true" }, + { inp: "false", out: "false" }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, +])("Var assignment (%p)", ({ inp, out }) => { + const lua = util.transpileString(`var myvar = ${inp};`); + expect(lua).toBe(`myvar = ${out};`); +}); + +test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = undefined;"])( + "Null assignments (%p)", + declaration => { + const result = util.transpileAndExecute(declaration + " return myvar;"); + expect(result).toBe(undefined); + }, +); + +test.each([ + { input: ["a", "b"], values: ["e", "f"] }, + { input: ["a", "b"], values: ["e", "f", "g"] }, + { input: ["a", "b", "c"], values: ["e", "f", "g"] }, +])("Binding pattern assignment (%p)", ({ input, values }) => { + const pattern = input.join(","); + const initializer = values.map(v => `"${v}"`).join(","); + + const tsCode = `const [${pattern}] = [${initializer}]; return [${pattern}].join("-");`; + const result = util.transpileAndExecute(tsCode); + + expect(result).toBe(values.slice(0, input.length).join("-")); +}); + +test("Ellipsis binding pattern", () => { + expect(() => util.transpileString("let [a,b,...c] = [1,2,3];")).toThrowExactError( + TSTLErrors.ForbiddenEllipsisDestruction(util.nodeStub), + ); +}); + +test("Tuple Assignment", () => { + const code = ` + function abc(): [number, number] { return [1, 2]; }; + let t: [number, number] = abc(); + return t[0] + t[1]; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(3); +}); + +test("TupleReturn assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): number[] + let [a,b] = abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = abc();"); +}); + +test("TupleReturn Single assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): [number, string]; + let a = abc(); + a = abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a = ({abc()});\na = ({abc()});"); +}); + +test("TupleReturn interface assignment", () => { + const code = ` + interface def { + /** @tupleReturn */ + abc(); + } declare const jkl : def; + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = jkl:abc();"); +}); + +test("TupleReturn namespace assignment", () => { + const code = ` + declare namespace def { + /** @tupleReturn */ + function abc(this: void) {} + } + let [a,b] = def.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = def.abc();"); +}); + +test("TupleReturn method assignment", () => { + const code = ` + declare class def { + /** @tupleReturn */ + abc() { return [1,2,3]; } + } const jkl = new def(); + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local jkl = def.new();\nlocal a, b = jkl:abc();"); +}); + +test("TupleReturn functional", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const [a, b] = abc(); + return b + a; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); +}); + +test("TupleReturn single", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const res = abc(); + return res.length + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe(2); +}); + +test("TupleReturn in expression", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + return abc()[1] + abc()[0]; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); +}); + +test.each(["and", "local", "nil", "not", "or", "repeat", "then", "until"])( + "Keyword identifier error (%p)", + identifier => { + expect(() => util.transpileString(`const ${identifier} = 3;`)).toThrowExactError( + TSTLErrors.KeywordIdentifier(ts.createIdentifier(identifier)), + ); + }, +); + +test("String table access", () => { + const code = ` + const dict : {[key:string]:any} = {}; + dict["a b"] = 3; + return dict["a b"]; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(3); +}); diff --git a/test/unit/assignments/functionExpressionTypeInference.spec.ts b/test/unit/assignments/functionExpressionTypeInference.spec.ts new file mode 100644 index 000000000..e393d477c --- /dev/null +++ b/test/unit/assignments/functionExpressionTypeInference.spec.ts @@ -0,0 +1,344 @@ +import * as util from "../../util"; + +test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", noSelfTag => { + const header = ` + /** @${noSelfTag} */ namespace NS { + export class C { + method(fn: (s: string) => string) { return fn("foo"); } + } + } + function foo(this: void, s: string) { return s; } + `; + const code = ` + const c = new NS.C(); + return c.method(foo); + `; + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); +}); + +test.each([ + "(this: void, s: string) => string", + "(this: any, s: string) => string", + "(s: string) => string", +])("Function expression type inference in binary operator (%p)", funcType => { + const header = `declare const undefinedFunc: ${funcType};`; + const code = ` + let func: ${funcType} = s => s; + func = undefinedFunc || (s => s); + return func("foo"); + `; + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); +}); + +test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { return s; })"])( + "Function expression type inference in class (%p)", + funcExp => { + const code = ` + class Foo { + func: (this: void, s: string) => string = ${funcExp}; + method: (s: string) => string = ${funcExp}; + static staticFunc: (this: void, s: string) => string = ${funcExp}; + static staticMethod: (s: string) => string = ${funcExp}; + } + const foo = new Foo(); + return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d"); + `; + expect(util.transpileAndExecute(code)).toBe("abcd"); + }, +); + +test.each([ + { assignTo: "const foo: Foo", funcExp: "s => s" }, + { assignTo: "const foo: Foo", funcExp: "(s => s)" }, + { assignTo: "const foo: Foo", funcExp: "function(s) { return s; }" }, + { assignTo: "const foo: Foo", funcExp: "(function(s) { return s; })" }, + { assignTo: "let foo: Foo; foo", funcExp: "s => s" }, + { assignTo: "let foo: Foo; foo", funcExp: "(s => s)" }, + { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, + { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, +])("Function expression type inference in object literal (%p)", ({ assignTo, funcExp }) => { + const code = ` + interface Foo { + func(this: void, s: string): string; + method(this: this, s: string): string; + } + ${assignTo} = {func: ${funcExp}, method: ${funcExp}}; + return foo.method("foo") + foo.func("bar"); + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("Function expression type inference in object literal assigned to narrower type", () => { + const code = ` + let foo: {} = {bar: s => s}; + return (foo as {bar: (a: any) => any}).bar("foobar"); + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test.each([ + { assignTo: "const foo: Foo", funcExp: "s => s" }, + { assignTo: "const foo: Foo", funcExp: "(s => s)" }, + { assignTo: "const foo: Foo", funcExp: "function(s) { return s; }" }, + { assignTo: "const foo: Foo", funcExp: "(function(s) { return s; })" }, + { assignTo: "let foo: Foo; foo", funcExp: "s => s" }, + { assignTo: "let foo: Foo; foo", funcExp: "(s => s)" }, + { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, + { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, +])( + "Function expression type inference in object literal (generic key) (%p)", + ({ assignTo, funcExp }) => { + const code = ` + interface Foo { + [f: string]: (this: void, s: string) => string; + } + ${assignTo} = {func: ${funcExp}}; + return foo.func("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); + }, +); + +test.each([ + { + assignTo: "const funcs: [Func, Method]", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "s => s", + }, + { + assignTo: "const funcs: [Func, Method]", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "(s => s)", + }, + { + assignTo: "const funcs: [Func, Method]", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "function(s) { return s; }", + }, + { + assignTo: "const funcs: [Func, Method]", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "(function(s) { return s; })", + }, + { + assignTo: "let funcs: [Func, Method]; funcs", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "s => s", + }, + { + assignTo: "let funcs: [Func, Method]; funcs", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "(s => s)", + }, + { + assignTo: "let funcs: [Func, Method]; funcs", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "function(s) { return s; }", + }, + { + assignTo: "let funcs: [Func, Method]; funcs", + func: "funcs[0]", + method: "funcs[1]", + funcExp: "(function(s) { return s; })", + }, + { + assignTo: "const [func, meth]: [Func, Method]", + func: "func", + method: "meth", + funcExp: "s => s", + }, + { + assignTo: "const [func, meth]: [Func, Method]", + func: "func", + method: "meth", + funcExp: "(s => s)", + }, + { + assignTo: "const [func, meth]: [Func, Method]", + func: "func", + method: "meth", + funcExp: "function(s) { return s; }", + }, + { + assignTo: "const [func, meth]: [Func, Method]", + func: "func", + method: "meth", + funcExp: "(function(s) { return s; })", + }, + { + assignTo: "let func: Func; let meth: Method; [func, meth]", + func: "func", + method: "meth", + funcExp: "s => s", + }, + { + assignTo: "let func: Func; let meth: Method; [func, meth]", + func: "func", + method: "meth", + funcExp: "(s => s)", + }, + { + assignTo: "let func: Func; let meth: Method; [func, meth]", + func: "func", + method: "meth", + funcExp: "function(s) { return s; }", + }, + { + assignTo: "let func: Func; let meth: Method; [func, meth]", + func: "func", + method: "meth", + funcExp: "(function(s) { return s; })", + }, +])("Function expression type inference in tuple (%p)", ({ assignTo, func, method, funcExp }) => { + const code = ` + interface Foo { + method(s: string): string; + } + interface Func { + (this: void, s: string): string; + } + interface Method { + (this: Foo, s: string): string; + } + ${assignTo} = [${funcExp}, ${funcExp}]; + const foo: Foo = {method: ${method}}; + return foo.method("foo") + ${func}("bar"); + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test.each([ + { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "s => s" }, + { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "(s => s)" }, + { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "function(s) { return s; }" }, + { + assignTo: "const meths: Method[]", + method: "meths[0]", + funcExp: "(function(s) { return s; })", + }, + { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "s => s" }, + { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "(s => s)" }, + { + assignTo: "let meths: Method[]; meths", + method: "meths[0]", + funcExp: "function(s) { return s; }", + }, + { + assignTo: "let meths: Method[]; meths", + method: "meths[0]", + funcExp: "(function(s) { return s; })", + }, + { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "s => s" }, + { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "(s => s)" }, + { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "function(s) { return s; }" }, + { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "(function(s) { return s; })" }, + { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "s => s" }, + { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(s => s)" }, + { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "function(s) { return s; }" }, + { + assignTo: "let meth: Method; [meth]", + method: "meth", + funcExp: "(function(s) { return s; })", + }, +])("Function expression type inference in array (%p)", ({ assignTo, method, funcExp }) => { + const code = ` + interface Foo { + method(s: string): string; + } + interface Method { + (this: Foo, s: string): string; + } + ${assignTo} = [${funcExp}]; + const foo: Foo = {method: ${method}}; + return foo.method("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); + +test.each([ + { funcType: "(this: void, s: string) => string", funcExp: "s => s" }, + { funcType: "(this: any, s: string) => string", funcExp: "s => s" }, + { funcType: "(s: string) => string", funcExp: "s => s" }, + { funcType: "(this: void, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, +])("Function expression type inference in union (%p)", ({ funcType, funcExp }) => { + const code = ` + type U = string | number | (${funcType}); + const u: U = ${funcExp}; + return (u as ${funcType})("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); + +test.each([ + { funcType: "(this: void, s: string) => string", funcExp: "s => s" }, + { funcType: "(this: any, s: string) => string", funcExp: "s => s" }, + { funcType: "(s: string) => string", funcExp: "s => s" }, + { funcType: "(this: void, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, +])("Function expression type inference in union tuple (%p)", ({ funcType, funcExp }) => { + const code = ` + interface I { callback: ${funcType}; } + let a: I[] | number = [{ callback: ${funcExp} }]; + return a[0].callback("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); + +test.each([ + { funcType: "(this: void, s: string) => string", funcExp: "s => s" }, + { funcType: "(this: any, s: string) => string", funcExp: "s => s" }, + { funcType: "(s: string) => string", funcExp: "s => s" }, + { funcType: "(this: void, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, +])("Function expression type inference in as cast (%p)", ({ funcType, funcExp }) => { + const code = ` + const fn: ${funcType} = (${funcExp}) as (${funcType}); + return fn("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); + +test.each([ + { funcType: "(this: void, s: string) => string", funcExp: "s => s" }, + { funcType: "(this: any, s: string) => string", funcExp: "s => s" }, + { funcType: "(s: string) => string", funcExp: "s => s" }, + { funcType: "(this: void, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, +])("Function expression type inference in type assertion (%p)", ({ funcType, funcExp }) => { + const code = ` + const fn: ${funcType} = <${funcType}>(${funcExp}); + return fn("foo"); + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); + +test.each([ + { funcType: "(this: void, s: string) => string", funcExp: "s => s" }, + { funcType: "(this: any, s: string) => string", funcExp: "s => s" }, + { funcType: "(s: string) => string", funcExp: "s => s" }, + { funcType: "(this: void, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, + { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, +])("Function expression type inference in constructor (%p)", ({ funcType, funcExp }) => { + const code = ` + class C { + result: string; + constructor(fn: (s: string) => string) { this.result = fn("foo"); } + } + const c = new C(s => s); + return c.result; + `; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); diff --git a/test/unit/assignments/functionPermutations.ts b/test/unit/assignments/functionPermutations.ts new file mode 100644 index 000000000..45fbd52f1 --- /dev/null +++ b/test/unit/assignments/functionPermutations.ts @@ -0,0 +1,411 @@ +export interface TestFunction { + value: string; + definition?: string; +} + +export const selfTestFunctions: TestFunction[] = [ + { + value: "selfFunc", + definition: `let selfFunc: {(this: any, s: string): string} = function(s) { return s; };`, + }, + { + value: "selfLambda", + definition: `let selfLambda: (this: any, s: string) => string = s => s;`, + }, + { + value: "anonFunc", + definition: `let anonFunc: {(s: string): string} = function(s) { return s; };`, + }, + { + value: "anonLambda", + definition: `let anonLambda: (s: string) => string = s => s;`, + }, + { + value: "methodClass.method", + definition: `class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();`, + }, + { + value: "anonMethodClass.anonMethod", + definition: `class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();`, + }, + { + value: "funcPropClass.funcProp", + definition: `class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();`, + }, + { + value: "anonFuncPropClass.anonFuncProp", + definition: `class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();`, + }, + { + value: "StaticMethodClass.staticMethod", + definition: `class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }`, + }, + { + value: "AnonStaticMethodClass.anonStaticMethod", + definition: `class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }`, + }, + { + value: "StaticFuncPropClass.staticFuncProp", + definition: `class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }`, + }, + { + value: "AnonStaticFuncPropClass.anonStaticFuncProp", + definition: `class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }`, + }, + { + value: "FuncNs.nsFunc", + definition: `namespace FuncNs { export function nsFunc(s: string) { return s; } }`, + }, + { + value: "FuncNestedNs.NestedNs.nestedNsFunc", + definition: `namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }`, + }, + { + value: "LambdaNs.nsLambda", + definition: `namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "LambdaNestedNs.NestedNs.nestedNsLambda", + definition: `namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }`, + }, + { + value: "methodInterface.method", + definition: `interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, + }, + { + value: "anonMethodInterface.anonMethod", + definition: `interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };`, + }, + { + value: "funcPropInterface.funcProp", + definition: `interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };`, + }, + { + value: "anonFuncPropInterface.anonFuncProp", + definition: `interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };`, + }, + { + value: "anonMethodClassInNoSelfNs.method", + definition: `/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();`, + }, + { + value: "anonMethodInterfaceInNoSelfNs.method", + definition: `/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };`, + }, + { + value: "anonFunctionNestedInNoSelfClass", + definition: `/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();`, + }, +]; + +export const noSelfTestFunctions: TestFunction[] = [ + { + value: "voidFunc", + definition: `let voidFunc: {(this: void, s: string): string} = function(s) { return s; };`, + }, + { + value: "voidLambda", + definition: `let voidLambda: (this: void, s: string) => string = s => s;`, + }, + { + value: "voidMethodClass.voidMethod", + definition: `class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();`, + }, + { + value: "voidFuncPropClass.voidFuncProp", + definition: `class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();`, + }, + { + value: "StaticVoidMethodClass.staticVoidMethod", + definition: `class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }`, + }, + { + value: "StaticVoidFuncPropClass.staticVoidFuncProp", + definition: `class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }`, + }, + { + value: "NoSelfFuncNs.noSelfNsFunc", + definition: `/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }`, + }, + { + value: "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc", + definition: `/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }`, + }, + { + value: "NoSelfLambdaNs.noSelfNsLambda", + definition: `/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda", + definition: `/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }`, + }, + { + value: "noSelfMethodClass.noSelfMethod", + definition: `/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();`, + }, + { + value: "NoSelfStaticMethodClass.noSelfStaticMethod", + definition: `/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }`, + }, + { + value: "noSelfFuncPropClass.noSelfFuncProp", + definition: `/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();`, + }, + { + value: "NoSelfStaticFuncPropClass.noSelfStaticFuncProp", + definition: `/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }`, + }, + { + value: "voidMethodInterface.voidMethod", + definition: `interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };`, + }, + { + value: "voidFuncPropInterface.voidFuncProp", + definition: `interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };`, + }, + { + value: "noSelfMethodInterface.noSelfMethod", + definition: `/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };`, + }, + { + value: "noSelfFuncPropInterface.noSelfFuncProp", + definition: `/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };`, + }, + { + value: "noSelfMethodClassExpression.noSelfMethod", + definition: `/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();`, + }, + { + value: "anonFunctionNestedInClassInNoSelfNs", + definition: `/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();`, + }, +]; + +const noSelfInFileTestFunctions: TestFunction[] = [ + { + value: "noSelfInFileFunc", + definition: `/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };`, + }, + { + value: "noSelfInFileLambda", + definition: `/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;`, + }, + { + value: "NoSelfInFileFuncNs.noSelfInFileNsFunc", + definition: `/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }`, + }, + { + value: "NoSelfInFileLambdaNs.noSelfInFileNsLambda", + definition: `/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }`, + }, + { + value: "noSelfInFileFuncNestedInClass", + definition: `/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();`, + }, +]; + +export const anonTestFunctionExpressions: TestFunction[] = [ + { value: `s => s` }, + { value: `(s => s)` }, + { value: `function(s) { return s; }` }, + { value: `(function(s) { return s; })` }, +]; + +export const selfTestFunctionExpressions: TestFunction[] = [ + { value: `function(this: any, s) { return s; }` }, + { value: `(function(this: any, s) { return s; })` }, +]; + +export const noSelfTestFunctionExpressions: TestFunction[] = [ + { value: `function(this: void, s) { return s; }` }, + { value: `(function(this: void, s) { return s; })` }, +]; + +export const anonTestFunctionType = "(s: string) => string"; +export const selfTestFunctionType = "(this: any, s: string) => string"; +export const noSelfTestFunctionType = "(this: void, s: string) => string"; + +type TestFunctionCast = [ + /*testFunction: */ TestFunction, + /*castedFunction: */ string, + /*isSelfConversion?: */ boolean? +]; +export const validTestFunctionCasts: TestFunctionCast[] = [ + [selfTestFunctions[0], `<${anonTestFunctionType}>(${selfTestFunctions[0].value})`], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${anonTestFunctionType})`], + [selfTestFunctions[0], `<${selfTestFunctionType}>(${selfTestFunctions[0].value})`], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${selfTestFunctionType})`], + [noSelfTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfTestFunctions[0].value})`], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${noSelfTestFunctionType})`], + [ + noSelfInFileTestFunctions[0], + `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, + ], + [ + noSelfInFileTestFunctions[0], + `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`, + ], + [ + noSelfInFileTestFunctions[0], + `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, + ], + [ + noSelfInFileTestFunctions[0], + `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`, + ], +]; +export const invalidTestFunctionCasts: TestFunctionCast[] = [ + [noSelfTestFunctions[0], `<${anonTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], + [ + noSelfTestFunctions[0], + `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, + false, + ], + [noSelfTestFunctions[0], `<${selfTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], + [ + noSelfTestFunctions[0], + `(${noSelfTestFunctions[0].value}) as (${selfTestFunctionType})`, + false, + ], + [ + noSelfInFileTestFunctions[0], + `<${selfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, + false, + ], + [ + noSelfInFileTestFunctions[0], + `(${noSelfInFileTestFunctions[0].value}) as (${selfTestFunctionType})`, + false, + ], + [selfTestFunctions[0], `<${noSelfTestFunctionType}>(${selfTestFunctions[0].value})`, true], + [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${noSelfTestFunctionType})`, true], +]; + +export type TestFunctionAssignment = [ + /*testFunction: */ TestFunction, + /*functionType: */ string, + /*isSelfConversion?: */ boolean? +]; +export const validTestFunctionAssignments: TestFunctionAssignment[] = [ + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctionExpressions.map( + (f): TestFunctionAssignment => [f, noSelfTestFunctionType], + ), +]; +export const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), + ...noSelfInFileTestFunctions.map( + (f): TestFunctionAssignment => [f, selfTestFunctionType, true], + ), + ...selfTestFunctionExpressions.map( + (f): TestFunctionAssignment => [f, noSelfTestFunctionType, false], + ), + ...noSelfTestFunctionExpressions.map( + (f): TestFunctionAssignment => [f, anonTestFunctionType, true], + ), + ...noSelfTestFunctionExpressions.map( + (f): TestFunctionAssignment => [f, selfTestFunctionType, true], + ), +]; diff --git a/test/unit/assignments/invalidFunctionAssignments.spec.ts b/test/unit/assignments/invalidFunctionAssignments.spec.ts new file mode 100644 index 000000000..3c8108c18 --- /dev/null +++ b/test/unit/assignments/invalidFunctionAssignments.spec.ts @@ -0,0 +1,206 @@ +import { TSTLErrors } from "../../../src/TSTLErrors"; +import * as util from "../../util"; +import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; + +test.each(invalidTestFunctionAssignments)( + "Invalid function variable declaration (%p)", + (testFunction, functionType, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + const fn: ${functionType} = ${testFunction.value}; + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionAssignments)( + "Invalid function assignment (%p)", + (testFunction, functionType, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + let fn: ${functionType}; + fn = ${testFunction.value}; + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionCasts)( + "Invalid function assignment with cast (%p)", + (testFunction, castedFunction, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionAssignments)( + "Invalid function argument (%p)", + (testFunction, functionType, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + declare function takesFunction(fn: ${functionType}); + takesFunction(${testFunction.value}); + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test("Invalid lua lib function argument", () => { + const code = ` + declare function foo(this: void, value: string): void; + declare const a: string[]; + a.forEach(foo); + `; + const err = TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "callbackfn"); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); +}); + +test.each(invalidTestFunctionCasts)( + "Invalid function argument with cast (%p)", + (testFunction, castedFunction, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + declare function takesFunction(fn: typeof ${testFunction.value}); + takesFunction(${castedFunction}); + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionAssignments)( + "Invalid function generic argument (%p)", + (testFunction, functionType, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + declare function takesFunction(fn: T); + takesFunction(${testFunction.value}); + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionAssignments)( + "Invalid function return (%p)", + (testFunction, functionType, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test.each(invalidTestFunctionCasts)( + "Invalid function return with cast (%p)", + (testFunction, castedFunction, isSelfConversion) => { + const code = ` + ${testFunction.definition || ""} + function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + `; + const err = isSelfConversion + ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) + : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + }, +); + +test("Interface method assignment", () => { + const code = ` + class Foo { + method(s: string): string { return s + "+method"; } + lambdaProp: (s: string) => string = s => s + "+lambdaProp"; + } + interface IFoo { + method: (s: string) => string; + lambdaProp(s: string): string; + } + const foo: IFoo = new Foo(); + return foo.method("foo") + "|" + foo.lambdaProp("bar"); + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo+method|bar+lambdaProp"); +}); + +test("Invalid function tuple assignment", () => { + const code = ` + interface Func { (this: void, s: string): string; } + interface Meth { (this: {}, s: string): string; } + declare function getTuple(): [number, Meth]; + let [i, f]: [number, Func] = getTuple(); + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub), + ); +}); + +test("Invalid method tuple assignment", () => { + const code = ` + interface Func { (this: void, s: string): string; } + interface Meth { (this: {}, s: string): string; } + declare function getTuple(): [number, Func]; + let [i, f]: [number, Meth] = getTuple(); + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub), + ); +}); + +test("Invalid interface method assignment", () => { + const code = ` + interface A { fn(s: string): string; } + interface B { fn(this: void, s: string): string; } + declare const a: A; + const b: B = a; + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"), + ); +}); + +test.each([ + "(this: void, s: string) => string", + "(this: void, s1: string, s2: string) => string", + "{(this: void, s: string): string}", + "{(this: any, s1: string, s2: string): string}", +])("Invalid function overload assignment (%p)", assignType => { + const code = ` + interface O { + (this: any, s1: string, s2: string): string; + (this: void, s: string): string; + } + declare const o: O; + let f: ${assignType} = o; + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.UnsupportedOverloadAssignment(util.nodeStub), + ); +}); diff --git a/test/unit/assignments/validFunctionAssignments.spec.ts b/test/unit/assignments/validFunctionAssignments.spec.ts new file mode 100644 index 000000000..86b4ce230 --- /dev/null +++ b/test/unit/assignments/validFunctionAssignments.spec.ts @@ -0,0 +1,233 @@ +import * as util from "../../util"; +import { + validTestFunctionAssignments, + validTestFunctionCasts, + selfTestFunctions, + noSelfTestFunctions, + TestFunctionAssignment, + selfTestFunctionExpressions, + noSelfTestFunctionExpressions, + selfTestFunctionType, + anonTestFunctionType, + noSelfTestFunctionType, + anonTestFunctionExpressions, + TestFunction, +} from "./functionPermutations"; + +test.each(validTestFunctionAssignments)( + "Valid function variable declaration (%p)", + (testFunction, functionType) => { + const code = `const fn: ${functionType} = ${testFunction.value}; + return fn("foobar");`; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test.each(validTestFunctionAssignments)( + "Valid function assignment (%p)", + (testFunction, functionType) => { + const code = `let fn: ${functionType}; + fn = ${testFunction.value}; + return fn("foobar");`; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test.each(validTestFunctionCasts)( + "Valid function assignment with cast (%p)", + (testFunction, castedFunction) => { + const code = ` + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + return fn("foobar"); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test.each(validTestFunctionAssignments)( + "Valid function argument (%p)", + (testFunction, functionType) => { + const code = ` + function takesFunction(fn: ${functionType}) { + return fn("foobar"); + } + return takesFunction(${testFunction.value}); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test("Valid lua lib function argument", () => { + const code = `let result = ""; + function foo(this: any, value: string) { result += value; } + const a = ['foo', 'bar']; + a.forEach(foo); + return result;`; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test.each(validTestFunctionCasts)( + "Valid function argument with cast (%p)", + (testFunction, castedFunction) => { + const code = ` + function takesFunction(fn: typeof ${testFunction.value}) { + return fn("foobar"); + } + return takesFunction(${castedFunction}); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test.each([ + // TODO: Fix function expression inference with generic types. The following should work, but doesn't: + // function takesFunction string>(fn: T) { ... } + // takesFunction(s => s); // Error: cannot convert method to function + // ...validTestFunctionAssignments - Use this instead of other cases when fixed + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), + ...noSelfTestFunctionExpressions.map( + (f): TestFunctionAssignment => [f, noSelfTestFunctionType], + ), +])("Valid function generic argument (%p)", (testFunction, functionType) => { + const code = ` + function takesFunction(fn: T) { + return fn("foobar"); + } + return takesFunction(${testFunction.value}); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); +}); + +test.each([ + ...anonTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), + ...selfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), + ...noSelfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["'foobar'"]]), +])("Valid function expression argument with no signature (%p)", (testFunction, args) => { + const code = ` + const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { + return fn(...args); + } + return takesFunction(${testFunction.value}, ${args.join(", ")}); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); +}); + +test.each(validTestFunctionAssignments)( + "Valid function return (%p)", + (testFunction, functionType) => { + const code = ` + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + const fn = returnsFunction(); + return fn("foobar"); + `; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test.each(validTestFunctionCasts)( + "Valid function return with cast (%p)", + (testFunction, castedFunction) => { + const code = `function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + const fn = returnsFunction(); + return fn("foobar");`; + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( + "foobar", + ); + }, +); + +test("Interface method assignment", () => { + const code = `class Foo { + method(s: string): string { return s + "+method"; } + lambdaProp: (s: string) => string = s => s + "+lambdaProp"; + } + interface IFoo { + method: (s: string) => string; + lambdaProp(s: string): string; + } + const foo: IFoo = new Foo(); + return foo.method("foo") + "|" + foo.lambdaProp("bar");`; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo+method|bar+lambdaProp"); +}); + +test("Valid function tuple assignment", () => { + const code = `interface Func { (this: void, s: string): string; } + function getTuple(): [number, Func] { return [1, s => s]; } + let [i, f]: [number, Func] = getTuple(); + return f("foo");`; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test("Valid method tuple assignment", () => { + const code = `interface Foo { method(s: string): string; } + interface Meth { (this: Foo, s: string): string; } + let meth: Meth = s => s; + function getTuple(): [number, Meth] { return [1, meth]; } + let [i, f]: [number, Meth] = getTuple(); + let foo: Foo = {method: f}; + return foo.method("foo");`; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test("Valid interface method assignment", () => { + const code = `interface A { fn(this: void, s: string): string; } + interface B { fn(this: void, s: string): string; } + const a: A = { fn(this: void, s) { return s; } }; + const b: B = a; + return b.fn("foo");`; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test.each([ + { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, + { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, + { + assignType: "(this: any, s1: string, s2: string) => string", + args: ["foo", "baz"], + expectResult: "foobaz", + }, + { + assignType: "{(this: any, s1: string, s2: string): string}", + args: ["foo", "baz"], + expectResult: "foobaz", + }, +])("Valid function overload assignment (%p)", ({ assignType, args, expectResult }) => { + const code = `interface O { + (s1: string, s2: string): string; + (s: string): string; + } + const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); + let f: ${assignType} = o; + return f(${args.map(a => '"' + a + '"').join(", ")});`; + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); +}); diff --git a/test/unit/bindingpatterns.spec.ts b/test/unit/bindingpatterns.spec.ts index ad0e18638..6cc1b5bc3 100644 --- a/test/unit/bindingpatterns.spec.ts +++ b/test/unit/bindingpatterns.spec.ts @@ -1,83 +1,85 @@ -import { Expect, Test, TestCase, TestCases } from "alsatian"; - -import * as util from "../src/util"; +import * as util from "../util"; const testCases = [ - ["{x}", "{x: true}", "x"], - ["[x, y]", "[false, true]", "y"], - ["{x: [y, z]}", "{x: [false, true]}", "z"], - ["{x: [, z]}", "{x: [false, true]}", "z"], - ["{x: [{y}]}", "{x: [{y: true}]}", "y"], - ["[[y, z]]", "[[false, true]]", "z"], - ["{x, y}", "{x: false, y: true}", "y"], - ["{x: foo, y}", "{x: true, y: false}", "foo"], - ["{x: foo, y: bar}", "{x: false, y: true}", "bar"], - ["{x: {x, y}, z}", "{x: {x: true, y: false}, z: false}", "x"], - ["{x: {x, y}, z}", "{x: {x: false, y: true}, z: false}", "y"], - ["{x: {x, y}, z}", "{x: {x: false, y: false}, z: true}", "z"], + { bindingString: "{x}", objectString: "{x: true}", returnVariable: "x" }, + { bindingString: "[x, y]", objectString: "[false, true]", returnVariable: "y" }, + { bindingString: "{x: [y, z]}", objectString: "{x: [false, true]}", returnVariable: "z" }, + { bindingString: "{x: [, z]}", objectString: "{x: [false, true]}", returnVariable: "z" }, + { bindingString: "{x: [{y}]}", objectString: "{x: [{y: true}]}", returnVariable: "y" }, + { bindingString: "[[y, z]]", objectString: "[[false, true]]", returnVariable: "z" }, + { bindingString: "{x, y}", objectString: "{x: false, y: true}", returnVariable: "y" }, + { bindingString: "{x: foo, y}", objectString: "{x: true, y: false}", returnVariable: "foo" }, + { + bindingString: "{x: foo, y: bar}", + objectString: "{x: false, y: true}", + returnVariable: "bar", + }, + { + bindingString: "{x: {x, y}, z}", + objectString: "{x: {x: true, y: false}, z: false}", + returnVariable: "x", + }, + { + bindingString: "{x: {x, y}, z}", + objectString: "{x: {x: false, y: true}, z: false}", + returnVariable: "y", + }, + { + bindingString: "{x: {x, y}, z}", + objectString: "{x: {x: false, y: false}, z: true}", + returnVariable: "z", + }, ]; const testCasesDefault = [ - ["{x = true}", "{}", "x"], - ["{x, y = true}", "{x: false}", "y"], + { bindingString: "{x = true}", objectString: "{}", returnVariable: "x" }, + { bindingString: "{x, y = true}", objectString: "{x: false}", returnVariable: "y" }, ]; -export class BindingPatternTests { - - @TestCase("{x, y}, z", "{x: false, y: false}, true", "z") - @TestCase("{x, y}, {z}", "{x: false, y: false}, {z: true}", "z") - @TestCases(testCases) - @TestCases(testCasesDefault) - @Test("Object bindings in functions") - public tesBindingPatternParameters( - bindingString: string, - objectString: string, - returnVariable: string - ): void { - const result = util.transpileAndExecute(` - function test(${bindingString}) { - return ${returnVariable}; - } - return test(${objectString}); - `); - Expect(result).toBe(true); - } +test.each([ + { bindingString: "{x, y}, z", objectString: "{x: false, y: false}, true", returnVariable: "z" }, + { + bindingString: "{x, y}, {z}", + objectString: "{x: false, y: false}, {z: true}", + returnVariable: "z", + }, + ...testCases, + ...testCasesDefault, +])("Object bindings in functions (%p)", ({ bindingString, objectString, returnVariable }) => { + const result = util.transpileAndExecute(` + function test(${bindingString}) { + return ${returnVariable}; + } + return test(${objectString}); + `); + expect(result).toBe(true); +}); - @TestCases(testCases) - @TestCases(testCasesDefault) - public testBindingPatternDeclarations( - bindingString: string, - objectString: string, - returnVariable: string - ): void { +test.each([...testCases, ...testCasesDefault])( + "testBindingPatternDeclarations (%p)", + ({ bindingString, objectString, returnVariable }) => { const result = util.transpileAndExecute(` let ${bindingString} = ${objectString}; return ${returnVariable}; `); - Expect(result).toBe(true); - } + expect(result).toBe(true); + }, +); - @TestCases(testCases) - @TestCases(testCasesDefault) - public testBindingPatternExportDeclarations( - bindingString: string, - objectString: string, - returnVariable: string - ): void { +test.each([...testCases, ...testCasesDefault])( + "testBindingPatternExportDeclarations (%p)", + ({ bindingString, objectString, returnVariable }) => { const result = util.transpileExecuteAndReturnExport( `export const ${bindingString} = ${objectString};`, - returnVariable + returnVariable, ); - Expect(result).toBe(true); - } + expect(result).toBe(true); + }, +); - @TestCases(testCases) - @Test("Object bindings with call expressions") - public testBindingPatternCallExpressions( - bindingString: string, - objectString: string, - returnVariable: string - ): void { +test.each(testCases)( + "Object bindings with call expressions (%p)", + ({ bindingString, objectString, returnVariable }) => { const result = util.transpileAndExecute(` function call() { return ${objectString}; @@ -85,7 +87,6 @@ export class BindingPatternTests { let ${bindingString} = call(); return ${returnVariable}; `); - Expect(result).toBe(true); - } - -} + expect(result).toBe(true); + }, +); diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 314e91853..f8f305ea0 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -1,835 +1,748 @@ -import { Expect, Test, TestCase } from "alsatian"; - import * as ts from "typescript"; -import * as util from "../src/util"; -import { TranspileError } from "../../src/TranspileError"; - -export class ClassTests { - - @Test("ClassFieldInitializer") - public classFieldInitializer(): void { - const result = util.transpileAndExecute( - `class a { - field: number = 4; - } - return new a().field;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassNumericLiteralFieldInitializer") - public classNumericLiteralFieldInitializer(): void { - const result = util.transpileAndExecute( - `class a { - 1: number = 4; - } - return new a()[1];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStringLiteralFieldInitializer") - public classStringLiteralFieldInitializer(): void { - const result = util.transpileAndExecute( - `class a { - "field": number = 4; - } - return new a()["field"];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassComputedFieldInitializer") - public classComputedFieldInitializer(): void { - const result = util.transpileAndExecute( - `const field: "field" = "field"; - class a { - [field]: number = 4; - } - return new a()[field];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassConstructor") - public classConstructor(): void { - const result = util.transpileAndExecute( - `class a { - field: number = 3; - constructor(n: number) { - this.field = n * 2; - } - } - return new a(4).field;` - ); - - // Assert - Expect(result).toBe(8); - } - - @Test("ClassConstructorAssignment") - public classConstructorAssignment(): void { - const result = util.transpileAndExecute( - `class a { constructor(public field: number) {} } - return new a(4).field;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassConstructorDefaultParameter") - public classConstructorDefaultParameter(): void { - const result = util.transpileAndExecute( - `class a { public field: number; constructor(f: number = 3) { this.field = f; } } - return new a().field;` - ); - - Expect(result).toBe(3); - } - - @Test("ClassConstructorAssignmentDefault") - public classConstructorAssignmentParameterDefault(): void { - const result = util.transpileAndExecute( - `class a { constructor(public field: number = 3) { } } - return new a().field;` - ); - - Expect(result).toBe(3); - } - - @Test("ClassNewNoBrackets") - public classNewNoBrackets(): void { - const result = util.transpileAndExecute( - `class a { - public field: number = 4; +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test("ClassFieldInitializer", () => { + const result = util.transpileAndExecute( + `class a { + field: number = 4; + } + return new a().field;`, + ); + + expect(result).toBe(4); +}); + +test("ClassNumericLiteralFieldInitializer", () => { + const result = util.transpileAndExecute( + `class a { + 1: number = 4; + } + return new a()[1];`, + ); + + expect(result).toBe(4); +}); + +test("ClassStringLiteralFieldInitializer", () => { + const result = util.transpileAndExecute( + `class a { + "field": number = 4; + } + return new a()["field"];`, + ); + + expect(result).toBe(4); +}); + +test("ClassComputedFieldInitializer", () => { + const result = util.transpileAndExecute( + `const field: "field" = "field"; + class a { + [field]: number = 4; + } + return new a()[field];`, + ); + + expect(result).toBe(4); +}); + +test("ClassConstructor", () => { + const result = util.transpileAndExecute( + `class a { + field: number = 3; + constructor(n: number) { + this.field = n * 2; + } + } + return new a(4).field;`, + ); + + expect(result).toBe(8); +}); + +test("ClassConstructorAssignment", () => { + const result = util.transpileAndExecute( + `class a { constructor(public field: number) {} } + return new a(4).field;`, + ); + + expect(result).toBe(4); +}); + +test("ClassConstructorDefaultParameter", () => { + const result = util.transpileAndExecute( + `class a { public field: number; constructor(f: number = 3) { this.field = f; } } + return new a().field;`, + ); + + expect(result).toBe(3); +}); + +test("ClassConstructorAssignmentDefault", () => { + const result = util.transpileAndExecute( + `class a { constructor(public field: number = 3) { } } + return new a().field;`, + ); + + expect(result).toBe(3); +}); + +test("ClassNewNoBrackets", () => { + const result = util.transpileAndExecute( + `class a { + public field: number = 4; + constructor() {} + } + let inst = new a; + return inst.field;`, + ); + + expect(result).toBe(4); +}); + +test("ClassStaticFields", () => { + const result = util.transpileAndExecute( + `class a { static field: number = 4; } + return a.field;`, + ); + + expect(result).toBe(4); +}); + +test("ClassStaticNumericLiteralFields", () => { + const result = util.transpileAndExecute( + `class a { static 1: number = 4; } + return a[1];`, + ); + + expect(result).toBe(4); +}); + +test("ClassStaticStringLiteralFields", () => { + const result = util.transpileAndExecute( + `class a { static "field": number = 4; } + return a["field"];`, + ); + + expect(result).toBe(4); +}); + +test("ClassStaticComputedFields", () => { + const result = util.transpileAndExecute( + `const field: "field" = "field"; + class a { static [field]: number = 4; } + return a[field];`, + ); + + expect(result).toBe(4); +}); + +test("classExtends", () => { + const result = util.transpileAndExecute( + `class a { field: number = 4; } + class b extends a {} + return new b().field;`, + ); + + expect(result).toBe(4); +}); + +test("SubclassDefaultConstructor", () => { + const result = util.transpileAndExecute( + `class a { + field: number; + constructor(field: number) { + this.field = field; + } + } + class b extends a {} + return new b(10).field;`, + ); + + expect(result).toBe(10); +}); + +test("SubsubclassDefaultConstructor", () => { + const result = util.transpileAndExecute( + `class a { + field: number; + constructor(field: number) { + this.field = field; + } + } + class b extends a {} + class c extends b {} + return new c(10).field;`, + ); + + expect(result).toBe(10); +}); + +test("SubclassConstructor", () => { + const result = util.transpileAndExecute( + `class a { + field: number; + constructor(field: number) { + this.field = field; + } + } + class b extends a { + constructor(field: number) { + super(field + 1); + } + } + return new b(10).field;`, + ); + + expect(result).toBe(11); +}); + +test("classSuper", () => { + const result = util.transpileAndExecute( + `class a { + public field: number = 4; + constructor(n: number) { + this.field = n; + } + } + class b extends a { + constructor() { + super(5); + } + } + return new b().field;`, + ); + + expect(result).toBe(5); +}); + +test("classSuperSuper", () => { + const result = util.transpileAndExecute( + `class a { + public field: number = 4; + constructor(n: number) { + this.field = n; + } + } + class b extends a { + constructor(n: number) { + super(n * 2); + } + } + class c extends b { + constructor() { + super(5); + } + } + return new c().field;`, + ); + + expect(result).toBe(10); +}); + +test("classSuperSkip", () => { + const result = util.transpileAndExecute( + `class a { + public field: number = 4; + constructor(n: number) { + this.field = n; + } + } + class b extends a { + } + class c extends b { + constructor() { + super(5); + } + } + return new c().field;`, + ); + + expect(result).toBe(5); +}); + +test("renamedClassExtends", () => { + const result = util.transpileAndExecute( + `const b = new B(); + return b.value;`, + undefined, + undefined, + `namespace Classes { + export class Base { + public value: number; + constructor(){ this.value = 3; } + } + } + + const A = Classes.Base; + class B extends A { + constructor(){ super(); } + };`, + ); + + expect(result).toBe(3); +}); + +test("ClassMethodCall", () => { + const result = util.transpileAndExecute( + `class a { + public method(): number { + return 4; + } + } + let inst = new a(); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("ClassNumericLiteralMethodCall", () => { + const result = util.transpileAndExecute( + `class a { + public 1(): number { + return 4; + } + } + let inst = new a(); + return inst[1]();`, + ); + + expect(result).toBe(4); +}); + +test("ClassStringLiteralMethodCall", () => { + const result = util.transpileAndExecute( + `class a { + public "method"(): number { + return 4; + } + } + let inst = new a(); + return inst["method"]();`, + ); + + expect(result).toBe(4); +}); + +test("ClassComputedMethodCall", () => { + const result = util.transpileAndExecute( + `const method: "method" = "method"; + class a { + public [method](): number { + return 4; + } + } + let inst = new a(); + return inst[method]();`, + ); + + expect(result).toBe(4); +}); + +test("ClassToString", () => { + const result = util.transpileAndExecute( + `class a { + public toString(): string { + return "instance of a"; + } + } + let inst = new a(); + return inst.toString();`, + ); + + expect(result).toBe("instance of a"); +}); + +test("HasOwnProperty true", () => { + const result = util.transpileAndExecute( + `class a { + public test(): void { + } + } + let inst = new a(); + inst["prop"] = 17; + return inst.hasOwnProperty("prop");`, + ); + + expect(result).toBe(true); +}); + +test("HasOwnProperty false", () => { + const result = util.transpileAndExecute( + `class a { + public test(): void { + } + } + let inst = new a(); + inst["prop"] = 17; + return inst.hasOwnProperty("test");`, + ); + + expect(result).toBe(false); +}); + +test("CastClassMethodCall", () => { + const result = util.transpileAndExecute( + `interface result + { + val : number; + } + class a { + public method(out: result) { + out.val += 2; + } + } + let inst:any = new a(); + let result = {val : 0}; + (inst as a).method(result); + (inst as a).method(result); + return result.val;`, + ); + + expect(result).toBe(4); +}); + +test("ClassPropertyFunctionThis", () => { + const result = util.transpileAndExecute( + `class a { + constructor(private n: number) {} + public method: () => number = () => this.n; + } + let inst = new a(4); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("ClassInheritedMethodCall", () => { + const result = util.transpileAndExecute( + `class a { + public method(): number { + return 4; + } + } + class b extends a {} + let inst = new b(); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("ClassDoubleInheritedMethodCall", () => { + const result = util.transpileAndExecute( + `class a { + public method(): number { + return 4; + } + } + class b extends a {} + class c extends b {} + let inst = new c(); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("ClassInheritedMethodCall2", () => { + const result = util.transpileAndExecute( + `class a {} + class b extends a { + public method(): number { + return 4; + } + } + class c extends b {} + let inst = new c(); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("ClassMethodOverride", () => { + const result = util.transpileAndExecute( + `class a { + public method(): number { + return 2; + } + } + class b extends a { + public method(): number { + return 4; + } + } + let inst = new b(); + return inst.method();`, + ); + + expect(result).toBe(4); +}); + +test("methodDefaultParameters", () => { + const result = util.transpileAndExecute( + `class a { + public method(b: number, c: number = 5): number { + return b + c; + } + } + let inst = new a(); + return inst.method(4);`, + ); + + expect(result).toBe(9); +}); + +test("Class without name error", () => { + const transformer = util.makeTestTransformer(); + + expect(() => + transformer.transformClassDeclaration({} as ts.ClassDeclaration), + ).toThrowExactError(TSTLErrors.MissingClassName(util.nodeStub)); +}); + +test("CallSuperMethodNoArgs", () => { + const result = util.transpileAndExecute( + `class a { + a: number + constructor(n: number) { + this.a = n; + } + public method() { + return this.a; + } + } + class b extends a { + constructor(n: number) { + super(n); + } + public method() { + return super.method(); + } + } + let inst = new b(6); + return inst.method();`, + ); + + expect(result).toBe(6); +}); + +test("CallSuperMethodArgs", () => { + const result = util.transpileAndExecute( + `class a { + a: number + constructor(n: number) { + this.a = n; + } + public method(n: number) { + return this.a + n; + } + } + class b extends a { + constructor(n: number) { + super(n); + } + public method(n: number) { + return super.method(n); + } + } + let inst = new b(6); + return inst.method(4);`, + ); + + expect(result).toBe(10); +}); + +test("CallSuperExpressionMethod", () => { + const result = util.transpileAndExecute( + `let i = 0; + function make() { + const j = i++; + return class { constructor() {} - } - let inst = new a; - return inst.field;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStaticFields") - public classStaticFields(): void { - const result = util.transpileAndExecute( - `class a { static field: number = 4; } - return a.field;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStaticNumericLiteralFields") - public classStaticNumericLiteralFields(): void { - const result = util.transpileAndExecute( - `class a { static 1: number = 4; } - return a[1];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStaticStringLiteralFields") - public classStaticStringLiteralFields(): void { - const result = util.transpileAndExecute( - `class a { static "field": number = 4; } - return a["field"];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStaticComputedFields") - public classStaticComputedFields(): void { - const result = util.transpileAndExecute( - `const field: "field" = "field"; - class a { static [field]: number = 4; } - return a[field];` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("classExtends") - public classExtends(): void { - const result = util.transpileAndExecute( - `class a { field: number = 4; } - class b extends a {} - return new b().field;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("SubclassDefaultConstructor") - public subclassDefaultConstructor(): void { - const result = util.transpileAndExecute( - `class a { - field: number; - constructor(field: number) { - this.field = field; - } - } - class b extends a {} - return new b(10).field;` - ); - - Expect(result).toBe(10); - } - - @Test("SubsubclassDefaultConstructor") - public subsubclassDefaultConstructor(): void { - const result = util.transpileAndExecute( - `class a { - field: number; - constructor(field: number) { - this.field = field; - } - } - class b extends a {} - class c extends b {} - return new c(10).field;` - ); - - Expect(result).toBe(10); - } - - @Test("SubclassConstructor") - public subclassConstructor(): void { - const result = util.transpileAndExecute( - `class a { - field: number; - constructor(field: number) { - this.field = field; - } - } - class b extends a { - constructor(field: number) { - super(field + 1); - } - } - return new b(10).field;` - ); - - Expect(result).toBe(11); - } - - @Test("classSuper") - public classSuper(): void { - const result = util.transpileAndExecute( - `class a { - public field: number = 4; - constructor(n: number) { - this.field = n; - } - } - class b extends a { - constructor() { - super(5); - } - } - return new b().field;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("classSuperSuper") - public classSuperSuper(): void { - const result = util.transpileAndExecute( - `class a { - public field: number = 4; - constructor(n: number) { - this.field = n; - } - } - class b extends a { - constructor(n: number) { - super(n * 2); - } - } - class c extends b { - constructor() { - super(5); - } - } - return new c().field;` - ); - - // Assert - Expect(result).toBe(10); - } - - @Test("classSuperSkip") - public classSuperSkip(): void { - const result = util.transpileAndExecute( - `class a { - public field: number = 4; - constructor(n: number) { - this.field = n; - } - } - class b extends a { - } - class c extends b { - constructor() { - super(5); - } - } - return new c().field;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("renamedClassExtends") - public renamedClassExtends(): void - { - const result = util.transpileAndExecute( - `const b = new B(); - return b.value;`, - undefined, undefined, - `namespace Classes { - export class Base { - public value: number; - constructor(){ this.value = 3; } - } - } - - const A = Classes.Base; - class B extends A { - constructor(){ super(); } - };` - ); - - // Assert - Expect(result).toBe(3); - } - - @Test("ClassMethodCall") - public classMethodCall(): void { - const result = util.transpileAndExecute( - `class a { - public method(): number { - return 4; - } - } - let inst = new a(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassNumericLiteralMethodCall") - public classNumericLiteralMethodCall(): void { - const result = util.transpileAndExecute( - `class a { - public 1(): number { - return 4; - } - } - let inst = new a(); - return inst[1]();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassStringLiteralMethodCall") - public classStringLiteralMethodCall(): void { - const result = util.transpileAndExecute( - `class a { - public "method"(): number { - return 4; - } - } - let inst = new a(); - return inst["method"]();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassComputedMethodCall") - public classComputedMethodCall(): void { - const result = util.transpileAndExecute( - `const method: "method" = "method"; - class a { - public [method](): number { - return 4; - } - } - let inst = new a(); - return inst[method]();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassToString") - public classToString(): void { - const result = util.transpileAndExecute( - `class a { - public toString(): string { - return "instance of a"; - } - } - let inst = new a(); - return inst.toString();` - ); - - // Assert - Expect(result).toBe("instance of a"); - } - @Test("HasOwnProperty true") - public hasOwnProperty1(): void { - const result = util.transpileAndExecute( - `class a { - public test(): void { - } - } - let inst = new a(); - inst["prop"] = 17; - return inst.hasOwnProperty("prop");` - ); - - // Assert - Expect(result).toBe(true); - } - @Test("HasOwnProperty false") - public hasOwnProperty2(): void { - const result = util.transpileAndExecute( - `class a { - public test(): void { - } - } - let inst = new a(); - inst["prop"] = 17; - return inst.hasOwnProperty("test");` - ); - - // Assert - Expect(result).toBe(false); - } - @Test("CastClassMethodCall") - public extraParenthesisAssignment(): void { - const result = util.transpileAndExecute( - `interface result - { - val : number; - } - class a { - public method(out: result) { - out.val += 2; - } - } - let inst:any = new a(); - let result = {val : 0}; - (inst as a).method(result); - (inst as a).method(result); - return result.val;` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassPropertyFunctionThis") - public classPropertyFunctionThis(): void { - const result = util.transpileAndExecute( - `class a { - constructor(private n: number) {} - public method: () => number = () => this.n; - } - let inst = new a(4); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassInheritedMethodCall") - public classInheritedMethodCall(): void { - const result = util.transpileAndExecute( - `class a { - public method(): number { - return 4; - } - } - class b extends a {} - let inst = new b(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassDoubleInheritedMethodCall") - public classDoubleInheritedMethodCall(): void { - const result = util.transpileAndExecute( - `class a { - public method(): number { - return 4; - } - } - class b extends a {} - class c extends b {} - let inst = new c(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassInheritedMethodCall2") - public classInheritedMethodCall2(): void { - const result = util.transpileAndExecute( - `class a {} - class b extends a { - public method(): number { - return 4; - } - } - class c extends b {} - let inst = new c(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("ClassMethodOverride") - public classMethodOverride(): void { - const result = util.transpileAndExecute( - `class a { - public method(): number { - return 2; - } - } - class b extends a { - public method(): number { - return 4; - } - } - let inst = new b(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(4); - } - - @Test("methodDefaultParameters") - public methodInheritedParameters(): void { - const result = util.transpileAndExecute( - `class a { - public method(b: number, c: number = 5): number { - return b + c; - } - } - let inst = new a(); - return inst.method(4);` - ); - - // Assert - Expect(result).toBe(9); - } - - @Test("Class without name error") - public classWithoutNameError(): void { - const transformer = util.makeTestTransformer(); - - Expect(() => transformer.transformClassDeclaration({} as ts.ClassDeclaration)) - .toThrowError(Error, "Class declarations must have a name."); - } - - @Test("CallSuperMethodNoArgs") - public callSuperMethodNoArgs(): void { - const result = util.transpileAndExecute( - `class a { - a: number - constructor(n: number) { - this.a = n; - } - public method() { - return this.a; - } - } - class b extends a { - constructor(n: number) { - super(n); - } - public method() { - return super.method(); - } - } - let inst = new b(6); - return inst.method();` - ); - - // Assert - Expect(result).toBe(6); - } - - @Test("CallSuperMethodArgs") - public callSuperMethodArgs(): void { - const result = util.transpileAndExecute( - `class a { - a: number - constructor(n: number) { - this.a = n; - } - public method(n: number) { - return this.a + n; - } - } - class b extends a { - constructor(n: number) { - super(n); - } - public method(n: number) { - return super.method(n); - } - } - let inst = new b(6); - return inst.method(4);` - ); - - // Assert - Expect(result).toBe(10); - } - - @Test("CallSuperExpressionMethod") - public callSuperExpressionMethod(): void { - const result = util.transpileAndExecute( - `let i = 0; - function make() { - const j = i++; - return class { - constructor() {} - method() {} - }; - } - class B extends make() { - constructor() { super(); } - method() { super.method(); } - } - const inst = new B(); - inst.method(); - inst.method(); - inst.method(); - return i;` - ); - - // Assert - Expect(result).toBe(1); - } - - @Test("CallSuperSuperMethod") - public callSuperSuperMethod(): void { - const result = util.transpileAndExecute( - `class a { - a: number - constructor(n: number) { - this.a = n; - } - public method() { - return this.a; - } - } - class b extends a { - constructor(n: number) { - super(n); - } - public method() { - return super.method(); - } - } - class c extends b { - constructor(n: number) { - super(n); - } - public method() { - return super.method(); - } - } - let inst = new c(6); - return inst.method();` - ); - - // Assert - Expect(result).toBe(6); - } - - @Test("classExpression") - public classExpression(): void { - const result = util.transpileAndExecute( - `class a { - public method() { - return "instance of a"; - } - } - const b = class extends a { - public method() { - return "instance of b"; - } - } - let inst = new b(); - return inst.method();` - ); - - // Assert - Expect(result).toBe("instance of b"); - } - - @Test("Named Class Expression") - public namedClassExpression(): void { - const result = util.transpileAndExecute( - `const a = class MyClass { - public method() { - return "foo"; - } - } - let inst = new a(); - return inst.method();` - ); - - // Assert - Expect(result).toBe("foo"); - } - - @Test("classExpressionBaseClassMethod") - public classExpressionBaseClassMethod(): void { - const result = util.transpileAndExecute( - `class a { - public method() { - return 42; - } - } - const b = class extends a { - } - let inst = new b(); - return inst.method();` - ); - - // Assert - Expect(result).toBe(42); - } - - @Test("Class Method Runtime Override") - public classMethodRuntimeOverride(): void { - const result = util.transpileAndExecute( - `class MyClass { - method(): number { - return 4; - } - } - - let inst = new MyClass(); - inst.method = () => { - return 8; - } - return inst.method();` - ); - - Expect(result).toBe(8); - } - - @Test("Exported class super call") - public exportedClassSuperCall(): void { - const code = - `export class Foo { - prop: string; - constructor(prop: string) { this.prop = prop; } - } - export class Bar extends Foo { - constructor() { - super("bar"); - } - } - export const baz = (new Bar()).prop;`; - Expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("bar"); - } - - @TestCase("(new Foo())", "foo") - @TestCase("Foo", "bar") - @Test("Class method name collision") - public classMethodNameCollisiom(input: string, expectResult: string): void { - const code = - `class Foo { + method() {} + }; + } + class B extends make() { + constructor() { super(); } + method() { super.method(); } + } + const inst = new B(); + inst.method(); + inst.method(); + inst.method(); + return i;`, + ); + + expect(result).toBe(1); +}); + +test("CallSuperSuperMethod", () => { + const result = util.transpileAndExecute( + `class a { + a: number + constructor(n: number) { + this.a = n; + } + public method() { + return this.a; + } + } + class b extends a { + constructor(n: number) { + super(n); + } + public method() { + return super.method(); + } + } + class c extends b { + constructor(n: number) { + super(n); + } + public method() { + return super.method(); + } + } + let inst = new c(6); + return inst.method();`, + ); + + expect(result).toBe(6); +}); + +test("classExpression", () => { + const result = util.transpileAndExecute( + `class a { + public method() { + return "instance of a"; + } + } + const b = class extends a { + public method() { + return "instance of b"; + } + } + let inst = new b(); + return inst.method();`, + ); + + expect(result).toBe("instance of b"); +}); + +test("Named Class Expression", () => { + const result = util.transpileAndExecute( + `const a = class MyClass { + public method() { + return "foo"; + } + } + let inst = new a(); + return inst.method();`, + ); + + expect(result).toBe("foo"); +}); + +test("classExpressionBaseClassMethod", () => { + const result = util.transpileAndExecute( + `class a { + public method() { + return 42; + } + } + const b = class extends a { + } + let inst = new b(); + return inst.method();`, + ); + + expect(result).toBe(42); +}); + +test("Class Method Runtime Override", () => { + const result = util.transpileAndExecute( + `class MyClass { + method(): number { + return 4; + } + } + + let inst = new MyClass(); + inst.method = () => { + return 8; + } + return inst.method();`, + ); + + expect(result).toBe(8); +}); + +test("Exported class super call", () => { + const code = ` + export class Foo { + prop: string; + constructor(prop: string) { this.prop = prop; } + } + export class Bar extends Foo { + constructor() { + super("bar"); + } + } + export const baz = (new Bar()).prop; + `; + expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("bar"); +}); + +test.each([{ input: "(new Foo())", expectResult: "foo" }, { input: "Foo", expectResult: "bar" }])( + "Class method name collision (%p)", + ({ input, expectResult }) => { + const code = ` + class Foo { public method() { return "foo"; } public static method() { return "bar"; } } - return ${input}.method();`; - Expect(util.transpileAndExecute(code)).toBe(expectResult); - } - - @TestCase("extension") - @TestCase("metaExtension") - @Test("Class extends extension") - public classExtendsExtension(extensionType: string): void { - const code = - `declare class A {} - /** @${extensionType} **/ - class B extends A {} - class C extends B {}`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Cannot extend classes with decorator '@extension' or '@metaExtension'." - ); - } - - @TestCase("extension") - @TestCase("metaExtension") - @Test("Class construct extension") - public classConstructExtension(extensionType: string): void { - const code = - `declare class A {} - /** @${extensionType} **/ - class B extends A {} - const b = new B();`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Cannot construct classes with decorator '@extension' or '@metaExtension'." - ); - } - - @Test("Class static instance of self") - public classStaticInstanceOfSelf(): void { - const code = - `class Foo { - bar = "foobar"; - static instance = new Foo(); - } - return Foo.instance.bar;`; - Expect(util.transpileAndExecute(code)).toBe("foobar"); - } -} + return ${input}.method(); + `; + expect(util.transpileAndExecute(code)).toBe(expectResult); + }, +); + +test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { + const code = ` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + class C extends B {} + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.InvalidExtendsExtension(util.nodeStub), + ); +}); + +test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { + const code = ` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + const b = new B(); + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub), + ); +}); + +test("Class static instance of self", () => { + const code = ` + class Foo { + bar = "foobar"; + static instance = new Foo(); + } + return Foo.instance.bar; + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts index 000cdd4b3..2e4f8d1d2 100644 --- a/test/unit/commandLineParser.spec.ts +++ b/test/unit/commandLineParser.spec.ts @@ -1,245 +1,235 @@ -import { Expect, Test, TestCase } from "alsatian"; - import { findConfigFile, parseCommandLine, parseTsConfigString } from "../../src/CommandLineParser"; -import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; - -export class CommandLineParserTests -{ - @TestCase([""], LuaLibImportKind.Inline) - @TestCase(["--luaLibImport", "none"], LuaLibImportKind.None) - @TestCase(["--luaLibImport", "always"], LuaLibImportKind.Always) - @TestCase(["--luaLibImport", "inline"], LuaLibImportKind.Inline) - @TestCase(["--luaLibImport", "require"], LuaLibImportKind.Require) - @Test("CLI parser luaLibImportKind") - public cliParserLuaLibImportKind(args: string[], expected: LuaLibImportKind): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.luaLibImport).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @Test("CLI parser invalid luaLibImportKind") - public cliParserInvalidLuaLibImportKind(): void { - const result = parseCommandLine(["--luaLibImport", "invalid"]); - Expect(result.isValid).toBe(false); - } - - @TestCase([""], LuaTarget.LuaJIT) - @TestCase(["--luaTarget", "5.1"], LuaTarget.Lua51) - @TestCase(["--luaTarget", "5.2"], LuaTarget.Lua52) - @TestCase(["--luaTarget", "jit"], LuaTarget.LuaJIT) - @TestCase(["--luaTarget", "JIT"], LuaTarget.LuaJIT) - @TestCase(["--luaTarget", "5.3"], LuaTarget.Lua53) - @Test("CLI parser luaTarget") - public cliParserLuaTarget(args: string[], expected: LuaTarget): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.luaTarget).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @TestCase(["-lt", "5.1"], LuaTarget.Lua51) - @TestCase(["-lt", "5.2"], LuaTarget.Lua52) - @TestCase(["-lt", "jit"], LuaTarget.LuaJIT) - @TestCase(["-lt", "JIT"], LuaTarget.LuaJIT) - @TestCase(["-lt", "5.3"], LuaTarget.Lua53) - @Test("CLI parser luaTarget") - public cliParserLuaTargetAlias(args: string[], expected: LuaTarget): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.luaTarget).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @Test("CLI parser invalid luaTarget") - public cliParserInvalidLuaTarget(): void { - const result = parseCommandLine(["--luatTarget", "invalid"]); - Expect(result.isValid).toBe(false); - } - - @TestCase([""], false) - @TestCase(["--noHeader", "true"], true) - @TestCase(["--noHeader", "false"], false) - @TestCase(["--noHeader"], true) - @TestCase(["--noHeader", "--noHoisting"], true) - @Test("CLI parser noHeader") - public cliParserNoHeader(args: string[], expected: boolean): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.noHeader).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @TestCase([""], false) - @TestCase(["--noHoisting", "true"], true) - @TestCase(["--noHoisting", "false"], false) - @TestCase(["--noHoisting"], true) - @TestCase(["--noHoisting", "--noHeader"], true) - @Test("CLI parser noHoisting") - public cliParserNoHoisting(args: string[], expected: boolean): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.noHoisting).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @TestCase([""], false) - @TestCase(["--project", "tsconfig.json"], true) - @TestCase(["-p", "tsconfig.json"], true) - @Test("CLI parser project") - public cliParserProject(args: string[], expected: boolean): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.project !== undefined).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @Test("CLI Parser Multiple Options") - public cliParserMultipleOptions(): void { - const commandLine = "--project tsconfig.json --noHeader --noHoisting -lt 5.3"; - const result = parseCommandLine(commandLine.split(" ")); - - if (result.isValid === true) { - Expect(result.result.options.project).toBeDefined(); - Expect(result.result.options.noHeader).toBe(true); - Expect(result.result.options.noHoisting).toBe(true); - Expect(result.result.options.luaTarget).toBe(LuaTarget.Lua53); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @TestCase([""], false) - @TestCase(["--help"], true) - @TestCase(["-h"], true) - @Test("CLI parser project") - public cliParserHelp(args: string[], expected: boolean): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.help === true).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @TestCase([""], false) - @TestCase(["--version"], true) - @TestCase(["-v"], true) - @Test("CLI parser project") - public cliParserVersion(args: string[], expected: boolean): void { - const result = parseCommandLine(args); - if (result.isValid === true) { - Expect(result.result.options.version === true).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } - - @Test("defaultOption") - @TestCase("luaTarget", LuaTarget.LuaJIT) - @TestCase("noHeader", false) - @TestCase("luaLibImport", "inline") - @TestCase("rootDir", process.cwd()) - @TestCase("outDir", process.cwd()) - public defaultOptions(option: any, expected: any): void { - const parsedCommandLine = parseCommandLine([]); - if (parsedCommandLine.isValid) { - Expect(expected).toBe(parsedCommandLine.result.options[option]); - } else { - Expect(parsedCommandLine.isValid).toBeTruthy(); - } - } - - @Test("ValidLuaTarget") - public validLuaTarget(): void { - const parsedCommandLine = parseCommandLine(['--luaTarget', '5.3']); - if (parsedCommandLine.isValid) { - Expect(parsedCommandLine.result.options["luaTarget"]).toBe("5.3"); - } else { - Expect(parsedCommandLine.isValid).toBeTruthy(); - } - } - - @Test("InvalidLuaTarget") - public invalidLuaTarget(): void { - // Don't check error message because the yargs library messes the message up. - const result = parseCommandLine(['--luaTarget', '42']); - Expect(result.isValid).toBe(false); - } - - @Test("InvalidArgumentTSTL") - public invalidArgument(): void { - // Don't check error message because the yargs library messes the message up. - const result = parseCommandLine(['--invalidTarget', 'test']); - Expect(result.isValid).toBe(false); - } - - @Test("outDir") - public outDir(): void { - const parsedCommandLine = parseCommandLine(['--outDir', './test']); - - if (parsedCommandLine.isValid) { - Expect(parsedCommandLine.result.options['outDir']).toBe('./test'); - } else { - Expect(parsedCommandLine.isValid).toBeTruthy(); - } - } - - @Test("rootDir") - public rootDir(): void { - const parsedCommandLine = parseCommandLine(['--rootDir', './test']); - - if (parsedCommandLine.isValid) { - Expect(parsedCommandLine.result.options['rootDir']).toBe('./test'); - Expect(parsedCommandLine.result.options['outDir']).toBe('./test'); - } else { - Expect(parsedCommandLine.isValid).toBeTruthy(); - } - } - - @Test("outDirAndRooDir") - public outDirAndRooDir(): void { - const parsedCommandLine = parseCommandLine(['--outDir', './testOut', '--rootDir', './testRoot']); - - if (parsedCommandLine.isValid) { - Expect(parsedCommandLine.result.options['outDir']).toBe('./testOut'); - Expect(parsedCommandLine.result.options['rootDir']).toBe('./testRoot'); - } else { - Expect(parsedCommandLine.isValid).toBeTruthy(); - } - } - - @Test("Find config no path") - public findConfigNoPath(): void { - const result = findConfigFile({ options: {}, fileNames: [], errors: [] }); - Expect(result.isValid).toBe(false); - } - - @TestCase("{}", undefined) - @TestCase(`{ noHeader: true }`, true) - @TestCase(`{ noHeader: "true" }`, true) - @TestCase(`{ tstl: { noHeader: true } }`, true) - @TestCase(`{ tstl: { noHeader: "true" } }`, true) - @Test("TsConfig noHeader") - public tsConfigNoHeader(tsConfig: string, expected: boolean): void { - const result = parseTsConfigString(tsConfig, ""); - - if (result.isValid) { - Expect(result.result.options.noHeader).toBe(expected); - } else { - Expect(result.isValid).toBeTruthy(); - } - } -} +import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; + +test.each([ + { args: [""], expected: LuaLibImportKind.Inline }, + { args: ["--luaLibImport", "none"], expected: LuaLibImportKind.None }, + { args: ["--luaLibImport", "always"], expected: LuaLibImportKind.Always }, + { args: ["--luaLibImport", "inline"], expected: LuaLibImportKind.Inline }, + { args: ["--luaLibImport", "require"], expected: LuaLibImportKind.Require }, +])("CLI parser luaLibImportKind (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.luaLibImport).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test("CLI parser invalid luaLibImportKind", () => { + const result = parseCommandLine(["--luaLibImport", "invalid"]); + expect(result.isValid).toBe(false); +}); + +test.each([ + { args: [""], expected: LuaTarget.LuaJIT }, + { args: ["--luaTarget", "5.1"], expected: LuaTarget.Lua51 }, + { args: ["--luaTarget", "5.2"], expected: LuaTarget.Lua52 }, + { args: ["--luaTarget", "jit"], expected: LuaTarget.LuaJIT }, + { args: ["--luaTarget", "JIT"], expected: LuaTarget.LuaJIT }, + { args: ["--luaTarget", "5.3"], expected: LuaTarget.Lua53 }, +])("CLI parser luaTarget (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.luaTarget).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { args: ["-lt", "5.1"], expected: LuaTarget.Lua51 }, + { args: ["-lt", "5.2"], expected: LuaTarget.Lua52 }, + { args: ["-lt", "jit"], expected: LuaTarget.LuaJIT }, + { args: ["-lt", "JIT"], expected: LuaTarget.LuaJIT }, + { args: ["-lt", "5.3"], expected: LuaTarget.Lua53 }, +])("CLI parser luaTarget (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.luaTarget).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test("CLI parser invalid luaTarget", () => { + const result = parseCommandLine(["--luatTarget", "invalid"]); + expect(result.isValid).toBe(false); +}); + +test.each([ + { args: [""], expected: false }, + { args: ["--noHeader", "true"], expected: true }, + { args: ["--noHeader", "false"], expected: false }, + { args: ["--noHeader"], expected: true }, + { args: ["--noHeader", "--noHoisting"], expected: true }, +])("CLI parser noHeader (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.noHeader).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { args: [""], expected: false }, + { args: ["--noHoisting", "true"], expected: true }, + { args: ["--noHoisting", "false"], expected: false }, + { args: ["--noHoisting"], expected: true }, + { args: ["--noHoisting", "--noHeader"], expected: true }, +])("CLI parser noHoisting (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.noHoisting).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { args: [""], expected: false }, + { args: ["--project", "tsconfig.json"], expected: true }, + { args: ["-p", "tsconfig.json"], expected: true }, +])("CLI parser project (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.project !== undefined).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test("CLI Parser Multiple Options", () => { + const commandLine = "--project tsconfig.json --noHeader --noHoisting -lt 5.3"; + const result = parseCommandLine(commandLine.split(" ")); + + if (result.isValid === true) { + expect(result.result.options.project).toBeDefined(); + expect(result.result.options.noHeader).toBe(true); + expect(result.result.options.noHoisting).toBe(true); + expect(result.result.options.luaTarget).toBe(LuaTarget.Lua53); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { args: [""], expected: false }, + { args: ["--help"], expected: true }, + { args: ["-h"], expected: true }, +])("CLI parser project (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.help === true).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { args: [""], expected: false }, + { args: ["--version"], expected: true }, + { args: ["-v"], expected: true }, +])("CLI parser project (%p)", ({ args, expected }) => { + const result = parseCommandLine(args); + if (result.isValid === true) { + expect(result.result.options.version === true).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); + +test.each([ + { option: "luaTarget", expected: LuaTarget.LuaJIT }, + { option: "noHeader", expected: false }, + { option: "luaLibImport", expected: "inline" }, + { option: "rootDir", expected: process.cwd() }, + { option: "outDir", expected: process.cwd() }, +])("defaultOption (%p)", ({ option, expected }) => { + const parsedCommandLine = parseCommandLine([]); + if (parsedCommandLine.isValid) { + expect(expected).toBe(parsedCommandLine.result.options[option]); + } else { + expect(parsedCommandLine.isValid).toBeTruthy(); + } +}); + +test("ValidLuaTarget", () => { + const parsedCommandLine = parseCommandLine(["--luaTarget", "5.3"]); + if (parsedCommandLine.isValid) { + expect(parsedCommandLine.result.options["luaTarget"]).toBe("5.3"); + } else { + expect(parsedCommandLine.isValid).toBeTruthy(); + } +}); + +test("InvalidLuaTarget", () => { + // Don't check error message because the yargs library messes the message up. + const result = parseCommandLine(["--luaTarget", "42"]); + expect(result.isValid).toBe(false); +}); + +test("InvalidArgumentTSTL", () => { + // Don't check error message because the yargs library messes the message up. + const result = parseCommandLine(["--invalidTarget", "test"]); + expect(result.isValid).toBe(false); +}); + +test("outDir", () => { + const parsedCommandLine = parseCommandLine(["--outDir", "./test"]); + + if (parsedCommandLine.isValid) { + expect(parsedCommandLine.result.options["outDir"]).toBe("./test"); + } else { + expect(parsedCommandLine.isValid).toBeTruthy(); + } +}); + +test("rootDir", () => { + const parsedCommandLine = parseCommandLine(["--rootDir", "./test"]); + + if (parsedCommandLine.isValid) { + expect(parsedCommandLine.result.options["rootDir"]).toBe("./test"); + expect(parsedCommandLine.result.options["outDir"]).toBe("./test"); + } else { + expect(parsedCommandLine.isValid).toBeTruthy(); + } +}); + +test("outDirAndRooDir", () => { + const parsedCommandLine = parseCommandLine([ + "--outDir", + "./testOut", + "--rootDir", + "./testRoot", + ]); + + if (parsedCommandLine.isValid) { + expect(parsedCommandLine.result.options["outDir"]).toBe("./testOut"); + expect(parsedCommandLine.result.options["rootDir"]).toBe("./testRoot"); + } else { + expect(parsedCommandLine.isValid).toBeTruthy(); + } +}); + +test("Find config no path", () => { + const result = findConfigFile({ options: {}, fileNames: [], errors: [] }); + expect(result.isValid).toBe(false); +}); + +test.each([ + { tsConfig: "{}" }, + { tsConfig: `{ noHeader: true }`, expected: true }, + { tsConfig: `{ noHeader: "true" }`, expected: true }, + { tsConfig: `{ tstl: { noHeader: true } }`, expected: true }, + { tsConfig: `{ tstl: { noHeader: "true" } }`, expected: true }, +])("TsConfig noHeader (%p)", ({ tsConfig, expected }) => { + const result = parseTsConfigString(tsConfig, ""); + + if (result.isValid) { + expect(result.result.options.noHeader).toBe(expected); + } else { + expect(result.isValid).toBeTruthy(); + } +}); diff --git a/test/unit/compiler/configuration/mixed/index.spec.ts b/test/unit/compiler/configuration/mixed/index.spec.ts index 179a8ac77..119a91365 100644 --- a/test/unit/compiler/configuration/mixed/index.spec.ts +++ b/test/unit/compiler/configuration/mixed/index.spec.ts @@ -1,46 +1,39 @@ -import { Expect, Test } from "alsatian"; import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; - -import { CompilerOptions, LuaLibImportKind } from "../../../../../src/CompilerOptions"; import { parseCommandLine } from "../../../../../src/CommandLineParser"; +import { CompilerOptions, LuaLibImportKind } from "../../../../../src/CompilerOptions"; -export class MixedConfigurationTests -{ - @Test("tsconfig.json mixed with cmd line args") - public tsconfigMixedWithCmdLineArgs(): void { - const rootPath = __dirname; - const tsConfigPath = path.join(rootPath, "project-tsconfig.json"); - const expectedTsConfig = ts.parseJsonConfigFileContent( - ts.parseConfigFileTextToJson(tsConfigPath, fs.readFileSync(tsConfigPath).toString()).config, - ts.sys, - path.dirname(tsConfigPath) - ); +test("tsconfig.json mixed with cmd line args", () => { + const rootPath = __dirname; + const tsConfigPath = path.join(rootPath, "project-tsconfig.json"); + const expectedTsConfig = ts.parseJsonConfigFileContent( + ts.parseConfigFileTextToJson(tsConfigPath, fs.readFileSync(tsConfigPath).toString()).config, + ts.sys, + path.dirname(tsConfigPath), + ); - const parsedArgs = parseCommandLine([ - "-p", - `"${tsConfigPath}"`, - "--luaLibImport", - LuaLibImportKind.Inline, - `${path.join(rootPath, "test.ts")}`, - ]); + const parsedArgs = parseCommandLine([ + "-p", + `"${tsConfigPath}"`, + "--luaLibImport", + LuaLibImportKind.Inline, + `${path.join(rootPath, "test.ts")}`, + ]); - if (parsedArgs.isValid === true) - { - Expect(parsedArgs.result.options).toEqual({ - ...expectedTsConfig.options, - // Overridden by cmd args (set to "none" in project-tsconfig.json) - luaLibImport: LuaLibImportKind.Inline, - // Only set in tsconfig, TSTL default is "JIT" - luaTarget: "5.1", - // Only present in TSTL dfaults - noHeader: false, - project: tsConfigPath, - noHoisting: false, - } as CompilerOptions); - } else { - Expect(parsedArgs.isValid).toBeTruthy(); - } + if (parsedArgs.isValid === true) { + expect(parsedArgs.result.options).toEqual({ + ...expectedTsConfig.options, + // Overridden by cmd args (set to "none" in project-tsconfig.json) + luaLibImport: LuaLibImportKind.Inline, + // Only set in tsconfig, TSTL default is "JIT" + luaTarget: "5.1", + // Only present in TSTL dfaults + noHeader: false, + project: tsConfigPath, + noHoisting: false, + } as CompilerOptions); + } else { + expect(parsedArgs.isValid).toBeTruthy(); } -} +}); diff --git a/test/unit/compiler/configuration/options.spec.ts b/test/unit/compiler/configuration/options.spec.ts index 28324c10a..47bf9bedf 100644 --- a/test/unit/compiler/configuration/options.spec.ts +++ b/test/unit/compiler/configuration/options.spec.ts @@ -1,29 +1,19 @@ -import { Expect, Test, TestCase } from "alsatian"; +import { LuaLibImportKind, LuaTarget } from "../../../../src/CompilerOptions"; +import * as util from "../../../util"; -import * as util from "../../../src/util"; -import { LuaTarget, LuaLibImportKind } from "../../../../src/CompilerOptions"; +test.each([LuaTarget.LuaJIT, "jit", "JiT"])("Options luaTarget case-insensitive (%p)", target => { + const options = { luaTarget: target as LuaTarget }; + const result = util.transpileString("~a", options); -export class ObjectLiteralTests -{ - @TestCase(LuaTarget.LuaJIT) - @TestCase("jit") - @TestCase("JiT") - @Test("Options LuaTarget case-insensitive") - public luaTargetCaseInsensitive(target: string): void { - const options = {LuaTarget: target}; - const result = util.transpileString("~a", options); + expect(result).toBe("bit.bnot(a);"); +}); - Expect(result).toBe("bit.bnot(a);"); - } - - @TestCase(LuaLibImportKind.None) - @TestCase("none") - @TestCase("NoNe") - @Test("Options LuaLibImport case-insensitive") - public luaLibImportCaseInsensitive(importKind: string): void { - const options = {LuaLibImportKind: importKind}; +test.each([LuaLibImportKind.None, "none", "NoNe"])( + "Options luaLibImport case-insensitive (%p)", + importKind => { + const options = { luaLibImport: importKind as LuaLibImportKind }; const result = util.transpileString("const a = new Map();", options); - Expect(result).toBe("local a = Map.new();"); - } -} + expect(result).toBe("local a = Map.new();"); + }, +); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 6d330100b..6d79a37a8 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,232 +1,216 @@ -import { Expect, Test, TestCase } from "alsatian"; -import { TranspileError } from "../../src/TranspileError"; import { LuaTarget } from "../../src/CompilerOptions"; -import * as util from "../src/util"; - -export class LuaConditionalsTests { - - @TestCase(0, 0) - @TestCase(1, 1) - @Test("if") - public if(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let input: number = ${inp}; - if (input === 0) { - return 0; - } - return 1;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @Test("ifelse") - public ifelse(inp: number, expected: number): void { +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("if (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; + if (input === 0) { + return 0; + } + return 1;`, + ); + + expect(result).toBe(expected); +}); + +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])( + "ifelse (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let input: number = ${inp}; if (input === 0) { return 0; } else { return 1; - }` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, 3) - @Test("ifelseif") - public ifelseif(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let input: number = ${inp}; - if (input === 0) { - return 0; - } else if (input === 1){ - return 1; - } else if (input === 2){ - return 2; - } - return 3;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, 3) - @Test("ifelseifelse") - public ifelseifelse(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let input: number = ${inp}; - if (input === 0) { - return 0; - } else if (input === 1){ - return 1; - } else if (input === 2){ - return 2; - } else { - return 3; - }` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -1) - @Test("switch") - public switch(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -2) - @Test("switchdefault") - public switchdefault(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 1) - @TestCase(0, 1) - @TestCase(2, 4) - @TestCase(3, 4) - @TestCase(4, 4) - @TestCase(5, 15) - @TestCase(7, -2) - @Test("switchfallthrough") - public switchfallthrough(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - case 1: - result = 1; - break; - case 2: - result = 2; - case 3: - case 4: - result = 4; - break; - case 5: - result = 5; - case 6: - result += 10; - break; - case 7: - result = 7; - default: - result = -2; - break; - } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -2) - @Test("nestedSwitch") - public nestedSwitch(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - switch(${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - default: - result = -3; - break; - } - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result;` + }`, ); - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 2) - @TestCase(2, 2) - @Test("switchLocalScope") - public switchLocalScope(inp: number, expected: number): void { + expect(result).toBe(expected); + }, +); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: 3 }, +])("ifelseif (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; + if (input === 0) { + return 0; + } else if (input === 1){ + return 1; + } else if (input === 2){ + return 2; + } + return 3;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: 3 }, +])("ifelseifelse (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; + if (input === 0) { + return 0; + } else if (input === 1){ + return 1; + } else if (input === 2){ + return 2; + } else { + return 3; + }`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -1 }, +])("switch (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -2 }, +])("switchdefault (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 1 }, + { inp: 0, expected: 1 }, + { inp: 2, expected: 4 }, + { inp: 3, expected: 4 }, + { inp: 4, expected: 4 }, + { inp: 5, expected: 15 }, + { inp: 7, expected: -2 }, +])("switchfallthrough (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + case 1: + result = 1; + break; + case 2: + result = 2; + case 3: + case 4: + result = 4; + break; + case 5: + result = 5; + case 6: + result += 10; + break; + case 7: + result = 7; + default: + result = -2; + break; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -2 }, +])("nestedSwitch (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + switch(${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + default: + result = -3; + break; + } + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 2 }, { inp: 2, expected: 2 }])( + "switchLocalScope (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let result: number = -1; @@ -246,157 +230,151 @@ export class LuaConditionalsTests { break; } } - return result;` + return result;`, ); - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -1) - @Test("switchReturn") - public switchReturn(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `const result: number = -1; - - switch (${inp}) { - case 0: - return 0; - break; - case 1: - return 1; - case 2: - return 2; - break; + expect(result).toBe(expected); + }, +); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -1 }, +])("switchReturn (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `const result: number = -1; + + switch (${inp}) { + case 0: + return 0; + break; + case 1: + return 1; + case 2: + return 2; + break; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -1 }, +])("switchWithBrackets (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -1) - @Test("switchWithBrackets") - public switchWithBrackets(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - break; - } - case 2: { - result = 2; - break; - } + case 1: { + result = 1; + break; } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - - @TestCase(0, 0) - @TestCase(1, 1) - @TestCase(2, 2) - @TestCase(3, -1) - @Test("switchWithBracketsBreakInConditional") - public switchWithBracketsBreakInConditional(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - - if (result == 1) break; - } - case 2: { - result = 2; - break; - } + case 2: { + result = 2; + break; } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase(0, 4) - @TestCase(1, 0) - @TestCase(2, 2) - @TestCase(3, -1) - @Test("switchWithBracketsBreakInInternalLoop") - public switchWithBracketsBreakInInternalLoop(inp: number, expected: number): void { - const result = util.transpileAndExecute( - `let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 0 }, + { inp: 1, expected: 1 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -1 }, +])("switchWithBracketsBreakInConditional (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; - for (let i = 0; i < 5; i++) { - result++; + if (result == 1) break; + } + case 2: { + result = 2; + break; + } + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: 0, expected: 4 }, + { inp: 1, expected: 0 }, + { inp: 2, expected: 2 }, + { inp: 3, expected: -1 }, +])("switchWithBracketsBreakInInternalLoop (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + + for (let i = 0; i < 5; i++) { + result++; - if (i >= 2) { - break; - } + if (i >= 2) { + break; } } - case 1: { - result++; - break; - } - case 2: { - result = 2; - break; - } } - return result;` - ); - - // Assert - Expect(result).toBe(expected); - } - - @Test("If dead code after return") - public ifDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `if (true) { return 3; const b = 8; }`); - - Expect(result).toBe(3); - } - - @Test("switch dead code after return") - public whileDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `switch ("abc") { case "def": return 4; let abc = 4; case "abc": return 5; let def = 6; }`); - - Expect(result).toBe(5); - } - - @Test("switch not allowed in 5.1") - public switchThrow51(): void { - Expect( () => util.transpileString(`switch ("abc") {}`, {luaTarget: LuaTarget.Lua51})) - .toThrowError(TranspileError, "Switch statements is/are not supported for target Lua 5.1."); - } -} + case 1: { + result++; + break; + } + case 2: { + result = 2; + break; + } + } + return result;`, + ); + + expect(result).toBe(expected); +}); + +test("If dead code after return", () => { + const result = util.transpileAndExecute(`if (true) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); + +test("switch dead code after return", () => { + const result = util.transpileAndExecute( + `switch ("abc") { case "def": return 4; let abc = 4; case "abc": return 5; let def = 6; }`, + ); + + expect(result).toBe(5); +}); + +test("switch not allowed in 5.1", () => { + expect(() => + util.transpileString(`switch ("abc") {}`, { luaTarget: LuaTarget.Lua51 }), + ).toThrowExactError( + TSTLErrors.UnsupportedForTarget("Switch statements", LuaTarget.Lua51, util.nodeStub), + ); +}); diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts index 2bd1e5fab..5c9319045 100644 --- a/test/unit/console.spec.ts +++ b/test/unit/console.spec.ts @@ -1,67 +1,77 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; +import * as util from "../util"; -export class ConsoleTests { +const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - @TestCase("console.log()", "print();") - @TestCase('console.log("Hello")', 'print("Hello");') - @TestCase('console.log("Hello %s", "there")', 'print(string.format("Hello %s", "there"));') - @TestCase('console.log("Hello %%s", "there")', 'print(string.format("Hello %%s", "there"));') - @TestCase('console.log("Hello", "There")', 'print("Hello", "There");') - @Test("console.log") - public testConsoleLog(inp: string, expected: string): void { - // Transpile - const lua = util.transpileString(inp); +test.each([ + { inp: "console.log()", expected: "print();" }, + { inp: 'console.log("Hello")', expected: 'print("Hello");' }, + { + inp: 'console.log("Hello %s", "there")', + expected: 'print(string.format("Hello %s", "there"));', + }, + { + inp: 'console.log("Hello %%s", "there")', + expected: 'print(string.format("Hello %%s", "there"));', + }, + { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There");' }, +])("console.log (%p)", ({ inp, expected }) => { + expect(util.transpileString(inp, compilerOptions)).toBe(expected); +}); - // Assert - Expect(lua).toBe(expected); - } +test.each([ + { inp: "console.trace()", expected: "print(debug.traceback());" }, + { inp: 'console.trace("message")', expected: 'print(debug.traceback("message"));' }, + { + inp: 'console.trace("Hello %s", "there")', + expected: 'print(debug.traceback(string.format("Hello %s", "there")));', + }, + { + inp: 'console.trace("Hello %%s", "there")', + expected: 'print(debug.traceback(string.format("Hello %%s", "there")));', + }, + { + inp: 'console.trace("Hello", "there")', + expected: 'print(debug.traceback("Hello", "there"));', + }, +])("console.trace (%p)", ({ inp, expected }) => { + expect(util.transpileString(inp, compilerOptions)).toBe(expected); +}); - @TestCase("console.trace()", "print(debug.traceback());") - @TestCase('console.trace("message")', 'print(debug.traceback("message"));') - @TestCase('console.trace("Hello %s", "there")', 'print(debug.traceback(string.format("Hello %s", "there")));') - @TestCase('console.trace("Hello %%s", "there")', 'print(debug.traceback(string.format("Hello %%s", "there")));') - @TestCase('console.trace("Hello", "there")', 'print(debug.traceback("Hello", "there"));') - @Test("console.trace") - public testConsoleTrace(inp: string, expected: string): void { - // Transpile - const lua = util.transpileString(inp); +test.each([ + { inp: "console.assert(false)", expected: "assert(false);" }, + { inp: 'console.assert(false, "message")', expected: 'assert(false, "message");' }, + { + inp: 'console.assert(false, "message %s", "info")', + expected: 'assert(false, string.format("message %s", "info"));', + }, + { + inp: 'console.assert(false, "message %%s", "info")', + expected: 'assert(false, string.format("message %%s", "info"));', + }, + { + inp: 'console.assert(false, "message", "more")', + expected: 'assert(false, "message", "more");', + }, +])("console.assert (%p)", ({ inp, expected }) => { + expect(util.transpileString(inp, compilerOptions)).toBe(expected); +}); - // Assert - Expect(lua).toBe(expected); - } +test("console.differentiation", () => { + const result = util.transpileExecuteAndReturnExport( + ` + export class Console { + test() { return 42; } + } - @TestCase("console.assert(false)", "assert(false);") - @TestCase('console.assert(false, "message")', 'assert(false, "message");') - @TestCase('console.assert(false, "message %s", "info")', 'assert(false, string.format("message %s", "info"));') - @TestCase('console.assert(false, "message %%s", "info")', 'assert(false, string.format("message %%s", "info"));') - @TestCase('console.assert(false, "message", "more")', 'assert(false, "message", "more");') - @Test("console.assert") - public testConsoleAssert(inp: string, expected: string): void { - // Transpile - const lua = util.transpileString(inp); + function test() { + const console = new Console(); + return console.test(); + } - // Assert - Expect(lua).toBe(expected); - } - - @Test("console.differentiation") - public testConsoleDifferentiation(): void { - // Transpile - const result = util.transpileExecuteAndReturnExport(` - export class Console { - test() { return 42; } - } - - function test() { - const console = new Console(); - return console.test(); - } - - export const result = test(); - `, "result"); - Expect(result).toBe(42); - } - - -} \ No newline at end of file + export const result = test(); + `, + "result", + compilerOptions, + ); + expect(result).toBe(42); +}); diff --git a/test/unit/curry.spec.ts b/test/unit/curry.spec.ts index 03bf99000..639336a47 100644 --- a/test/unit/curry.spec.ts +++ b/test/unit/curry.spec.ts @@ -1,19 +1,10 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; +import * as util from "../util"; -export class LuaCurryTests { +test.each([{ x: 2, y: 3 }, { x: 5, y: 4 }])("curryingAdd (%p)", ({ x, y }) => { + const result = util.transpileAndExecute( + `let add = (x: number) => (y: number) => x + y; + return add(${x})(${y})`, + ); - @Test("curryingAdd") - @TestCase(2, 3) - @TestCase(5, 4) - public curryingAdd(x: number, y: number): void - { - const result = util.transpileAndExecute( - `let add = (x: number) => (y: number) => x + y; - return add(${x})(${y})` - ); - - // Assert - Expect(result).toBe(x + y); - } -} + expect(result).toBe(x + y); +}); diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts index 12bb8d8d6..a4181b009 100644 --- a/test/unit/declarations.spec.ts +++ b/test/unit/declarations.spec.ts @@ -1,124 +1,94 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; +import * as util from "../util"; -export class DeclarationTests -{ - @Test("Declaration function call") - public declarationFunctionCall(): void { - // Arrange - const libLua = `function declaredFunction(x) return 3*x end`; - - const tsHeader = `declare function declaredFunction(this: void, x: number): number;`; - - const source = `return declaredFunction(2) + 4;`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe(10); - } - - @Test("Declaration function call tupleReturn") - public declarationFunctionCallTupleReturn(): void { - // Arrange - const libLua = `function declaredFunction(x) return x, 2*x + 1 end`; - - const tsHeader = ` - /** @tupleReturn */ - declare function declaredFunction(this: void, x: number): [number, number];`; - - const source = ` - const tuple = declaredFunction(3); - const [destructedLeft, destructedRight] = declaredFunction(2); - return \`\${tuple[0] + destructedLeft},\${tuple[1] + destructedRight}\`;`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe("5,12"); - } - - @Test("Declaration namespace function call") - public declarationNamespaceFunctionCall(): void { - // Arrange - const libLua = ` - myNameSpace = {} - function myNameSpace.declaredFunction(x) return 3*x end - `; - - const tsHeader = `declare namespace myNameSpace { function declaredFunction(this: void, x: number): number; }`; - - const source = `return myNameSpace.declaredFunction(2) + 4;`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe(10); - } - - @Test("Declaration interface function call") - public declarationInterfaceFunctionCall(): void { - // Arrange - const libLua = ` - myInterfaceInstance = {} - myInterfaceInstance.x = 10 - function myInterfaceInstance:declaredFunction(x) return self.x + 3*x end - `; - - const tsHeader = ` - declare interface MyInterface { - declaredFunction(x: number): number; - } - declare var myInterfaceInstance: MyInterface;`; - - const source = `return myInterfaceInstance.declaredFunction(3);`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe(19); - } - - @Test("Declaration function callback") - public declarationFunctionCallback(): void { - // Arrange - const libLua = `function declaredFunction(callback) return callback(4) end`; - const tsHeader = - `declare function declaredFunction(this: void, callback: (this: void, x: number) => number): number;`; - - const source = `return declaredFunction(x => 2 * x);`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe(8); - } - - @Test("Declaration instance function callback") - public declarationInstanceFunctionCallback(): void { - // Arrange - const libLua = ` - myInstance = {} - myInstance.x = 10 - function myInstance:declaredFunction(callback) return callback(self.x) end`; - - const tsHeader = - `declare interface MyInterface { - declaredFunction(callback: (this: void, x: number) => number): number; - } - declare var myInstance: MyInterface;`; - - const source = `return myInstance.declaredFunction(x => 2 * x);`; - - // Act - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - - // Assert - Expect(result).toBe(20); - } -} +test("Declaration function call", () => { + const libLua = `function declaredFunction(x) return 3*x end`; + + const tsHeader = `declare function declaredFunction(this: void, x: number): number;`; + + const source = `return declaredFunction(2) + 4;`; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe(10); +}); + +test("Declaration function call tupleReturn", () => { + const libLua = `function declaredFunction(x) return x, 2*x + 1 end`; + + const tsHeader = ` + /** @tupleReturn */ + declare function declaredFunction(this: void, x: number): [number, number]; + `; + + const source = ` + const tuple = declaredFunction(3); + const [destructedLeft, destructedRight] = declaredFunction(2); + return \`\${tuple[0] + destructedLeft},\${tuple[1] + destructedRight}\`; + `; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe("5,12"); +}); + +test("Declaration namespace function call", () => { + const libLua = ` + myNameSpace = {} + function myNameSpace.declaredFunction(x) return 3*x end + `; + + const tsHeader = `declare namespace myNameSpace { function declaredFunction(this: void, x: number): number; }`; + + const source = `return myNameSpace.declaredFunction(2) + 4;`; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe(10); +}); + +test("Declaration interface function call", () => { + const libLua = ` + myInterfaceInstance = {} + myInterfaceInstance.x = 10 + function myInterfaceInstance:declaredFunction(x) return self.x + 3*x end + `; + + const tsHeader = ` + declare interface MyInterface { + declaredFunction(x: number): number; + } + declare var myInterfaceInstance: MyInterface; + `; + + const source = `return myInterfaceInstance.declaredFunction(3);`; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe(19); +}); + +test("Declaration function callback", () => { + const libLua = `function declaredFunction(callback) return callback(4) end`; + const tsHeader = `declare function declaredFunction(this: void, callback: (this: void, x: number) => number): number;`; + + const source = `return declaredFunction(x => 2 * x);`; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe(8); +}); + +test("Declaration instance function callback", () => { + const libLua = ` + myInstance = {} + myInstance.x = 10 + function myInstance:declaredFunction(callback) return callback(self.x) end + `; + + const tsHeader = ` + declare interface MyInterface { + declaredFunction(callback: (this: void, x: number) => number): number; + } + declare var myInstance: MyInterface; + `; + + const source = `return myInstance.declaredFunction(x => 2 * x);`; + + const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); + expect(result).toBe(20); +}); diff --git a/test/unit/decoratorCustomConstructor.spec.ts b/test/unit/decoratorCustomConstructor.spec.ts index 69fb6bd2a..9ff43c51d 100644 --- a/test/unit/decoratorCustomConstructor.spec.ts +++ b/test/unit/decoratorCustomConstructor.spec.ts @@ -1,52 +1,47 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; -import { TranspileError } from "../../src/TranspileError"; +test("CustomCreate", () => { + const luaHeader = ` + function Point2DCreate(x, y) + return {x = x, y = y} + end + `; -export class DecoratorCustomConstructor -{ - @Test("CustomCreate") - public customCreate(): void { - const luaHeader = - `function Point2DCreate(x, y) - return {x = x, y = y} - end`; + const tsHeader = ` + /** @customConstructor Point2DCreate */ + class Point2D { + public x: number; + public y: number; + constructor(x: number, y: number) { + // No values assigned + } + } + `; - const tsHeader = - `/** @customConstructor Point2DCreate */ - class Point2D { - public x: number; - public y: number; - constructor(x: number, y: number) { - // No values assigned - } - }`; - - const result = util.transpileAndExecute( - `return new Point2D(1, 2).x;`, - undefined, - luaHeader, - tsHeader - ); + const result = util.transpileAndExecute( + `return new Point2D(1, 2).x;`, + undefined, + luaHeader, + tsHeader, + ); - // Assert - Expect(result).toBe(1); - } + expect(result).toBe(1); +}); - @Test("IncorrectUsage") - public incorrectUsage(): void { - Expect(() => { - util.transpileString( - `/** @customConstructor */ - class Point2D { - constructor( - public x: number, - public y: number - ) {} - } - return new Point2D(1, 2).x; - ` - ); - }).toThrowError(TranspileError, "!CustomConstructor expects 1 argument(s) but got 0."); - } -} +test("IncorrectUsage", () => { + expect(() => { + util.transpileString(` + /** @customConstructor */ + class Point2D { + constructor( + public x: number, + public y: number + ) {} + } + return new Point2D(1, 2).x; + `); + }).toThrowExactError( + TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, util.nodeStub), + ); +}); diff --git a/test/unit/decoratorMetaExtension.spec.ts b/test/unit/decoratorMetaExtension.spec.ts index 6fdedf191..eb574cc62 100644 --- a/test/unit/decoratorMetaExtension.spec.ts +++ b/test/unit/decoratorMetaExtension.spec.ts @@ -1,63 +1,51 @@ -import { Expect, Test } from "alsatian"; -import * as util from "../src/util"; - -import { TranspileError } from "../../src/TranspileError"; import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; -export class DecoratorMetaExtension { - - @Test("MetaExtension") - public metaExtension(): void { - const tsHeader = ` - declare class _LOADED {} - declare namespace debug { - function getregistry(): any; +test("MetaExtension", () => { + const tsHeader = ` + declare class _LOADED {} + declare namespace debug { + function getregistry(): any; + } + /** @metaExtension */ + class LoadedExt extends _LOADED { + public static test() { + return 5; } - /** @metaExtension */ - class LoadedExt extends _LOADED { - public static test() { - return 5; - } - }`; + } + `; - const result = util.transpileAndExecute( - `return debug.getregistry()["_LOADED"].test();`, - undefined, undefined, tsHeader); + const result = util.transpileAndExecute( + `return debug.getregistry()["_LOADED"].test();`, + undefined, + undefined, + tsHeader, + ); - // Assert - Expect(result).toBe(5); - } + expect(result).toBe(5); +}); - @Test("IncorrectUsage") - public incorrectUsage(): void { - const expectedMessage = TSTLErrors.MissingMetaExtension(undefined).message; - Expect(() => { - util.transpileString( - ` - /** @metaExtension */ - class LoadedExt { - public static test() { - return 5; - } +test("IncorrectUsage", () => { + expect(() => { + util.transpileString(` + /** @metaExtension */ + class LoadedExt { + public static test() { + return 5; } - ` - ); - }).toThrowError(TranspileError, expectedMessage); - } + } + `); + }).toThrowExactError(TSTLErrors.MissingMetaExtension(util.nodeStub)); +}); - @Test("DontAllowInstantiation") - public dontAllowInstantiation(): void { - Expect(() => { - util.transpileString( - ` - declare class _LOADED {} - /** @metaExtension */ - class Ext extends _LOADED { - } - const e = new Ext(); - ` - ); - }).toThrowError(TranspileError, - "Cannot construct classes with decorator '@extension' or '@metaExtension'."); - } -} +test("DontAllowInstantiation", () => { + expect(() => { + util.transpileString(` + declare class _LOADED {} + /** @metaExtension */ + class Ext extends _LOADED { + } + const e = new Ext(); + `); + }).toThrowExactError(TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub)); +}); diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index d21b695c4..cbb0fbe15 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -1,191 +1,174 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; - -import { TranspileError } from "../../src/TranspileError"; - -export class EnumTests { - @Test("Declare const enum") - public declareConstEnum(): void { - const testCode = ` - declare const enum TestEnum { - MEMBER_ONE = "test", - MEMBER_TWO = "test2" +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test("Declare const enum", () => { + const testCode = ` + declare const enum TestEnum { + MEMBER_ONE = "test", + MEMBER_TWO = "test2" + } + + const valueOne = TestEnum.MEMBER_ONE; + `; + + expect(util.transpileString(testCode)).toBe(`local valueOne = "test";`); +}); + +test("Const enum", () => { + const testCode = ` + const enum TestEnum { + MEMBER_ONE = "test", + MEMBER_TWO = "test2" + } + + const valueOne = TestEnum.MEMBER_TWO; + `; + + expect(util.transpileString(testCode)).toBe(`local valueOne = "test2";`); +}); + +test("Const enum without initializer", () => { + const testCode = ` + const enum TestEnum { + MEMBER_ONE, + MEMBER_TWO + } + + const valueOne = TestEnum.MEMBER_TWO; + `; + + expect(util.transpileString(testCode)).toBe(`local valueOne = 1;`); +}); + +test("Const enum without initializer in some values", () => { + const testCode = ` + const enum TestEnum { + MEMBER_ONE = 3, + MEMBER_TWO, + MEMBER_THREE = 5 + } + + const valueOne = TestEnum.MEMBER_TWO; + `; + + expect(util.transpileString(testCode)).toBe(`local valueOne = 4;`); +}); + +test("Invalid heterogeneous enum", () => { + expect(() => { + util.transpileString(` + enum TestEnum { + a, + b = "ok", + c, } - - const valueOne = TestEnum.MEMBER_ONE; - `; - - Expect(util.transpileString(testCode)).toBe(`local valueOne = "test";`); - } - - @Test("Const enum") - public constEnum(): void { - const testCode = ` - const enum TestEnum { - MEMBER_ONE = "test", - MEMBER_TWO = "test2" - } - - const valueOne = TestEnum.MEMBER_TWO; - `; - - Expect(util.transpileString(testCode)).toBe(`local valueOne = "test2";`); - } - - @Test("Const enum without initializer") - public constEnumNoInitializer(): void { - const testCode = ` - const enum TestEnum { - MEMBER_ONE, - MEMBER_TWO - } - - const valueOne = TestEnum.MEMBER_TWO; - `; - - Expect(util.transpileString(testCode)).toBe(`local valueOne = 1;`); - } - - @Test("Const enum without initializer in some values") - public constEnumNoInitializerInSomeValues(): void { - const testCode = ` - const enum TestEnum { - MEMBER_ONE = 3, - MEMBER_TWO, - MEMBER_THREE = 5 - } - - const valueOne = TestEnum.MEMBER_TWO; - `; - - Expect(util.transpileString(testCode)).toBe(`local valueOne = 4;`); - } - - @Test("Invalid heterogeneous enum") - public invalidHeterogeneousEnum(): void { - // Transpile & Assert - Expect(() => { - const lua = util.transpileString( - `enum TestEnum { - a, - b = "ok", - c, - }` - ); - }).toThrowError(TranspileError, "Invalid heterogeneous enum. Enums should either specify no " - + "member values, or specify values (of the same type) for all members."); - } - - @Test("String literal name in enum") - public stringLiteralNameEnum(): void { - const code = `enum TestEnum { - ["name"] = "foo" - } - return TestEnum["name"];`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Enum identifier value internal") - public enumIdentifierValueInternal(): void { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi = def, - jkl, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` - ); - - Expect(result).toBe("0,1,1,2"); - } - - @Test("Enum identifier value internal recursive") - public enumIdentifierValueInternalRecursive(): void { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi = def, - jkl = ghi, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` - ); - - Expect(result).toBe("0,1,1,1"); - } - - @Test("Enum identifier value external") - public enumIdentifierValueExternal(): void { - const result = util.transpileAndExecute( - `const ext = 6; - enum testEnum { - abc, - def, - ghi = ext, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi}\`;` - ); - - Expect(result).toBe("0,1,6"); - } - - @Test("Enum reverse mapping") - public enumReverseMapping(): void { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi - } - return testEnum[testEnum.abc] + testEnum[testEnum.ghi]` - ); - - Expect(result).toBe("abcghi"); - } - - @Test("Const enum index") - public constEnumIndex(): void { - const result = util.transpileAndExecute( - `const enum testEnum { - abc, - def, - ghi - } - return testEnum["def"];` - ); - - Expect(result).toBe(1); - } - - @Test("Const enum index identifier value") - public constEnumIndexIdnetifierValue(): void { - const result = util.transpileAndExecute( - `const enum testEnum { - abc, - def = 4, - ghi, - jkl = ghi - } - return testEnum["jkl"];` - ); - - Expect(result).toBe(5); - } - - @Test("Const enum index identifier chain") - public constEnumIndexIdnetifierChain(): void { - const result = util.transpileAndExecute( - `const enum testEnum { - abc = 3, - def, - ghi = def, - jkl = ghi, - } - return testEnum["ghi"];` - ); - - Expect(result).toBe(4); - } -} + `); + }).toThrowExactError(TSTLErrors.HeterogeneousEnum(util.nodeStub)); +}); + +test("String literal name in enum", () => { + const code = ` + enum TestEnum { + ["name"] = "foo" + } + return TestEnum["name"]; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test("Enum identifier value internal", () => { + const result = util.transpileAndExecute( + `enum testEnum { + abc, + def, + ghi = def, + jkl, + } + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;`, + ); + + expect(result).toBe("0,1,1,2"); +}); + +test("Enum identifier value internal recursive", () => { + const result = util.transpileAndExecute( + `enum testEnum { + abc, + def, + ghi = def, + jkl = ghi, + } + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;`, + ); + + expect(result).toBe("0,1,1,1"); +}); + +test("Enum identifier value external", () => { + const result = util.transpileAndExecute( + `const ext = 6; + enum testEnum { + abc, + def, + ghi = ext, + } + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi}\`;`, + ); + + expect(result).toBe("0,1,6"); +}); + +test("Enum reverse mapping", () => { + const result = util.transpileAndExecute( + `enum testEnum { + abc, + def, + ghi + } + return testEnum[testEnum.abc] + testEnum[testEnum.ghi]`, + ); + + expect(result).toBe("abcghi"); +}); + +test("Const enum index", () => { + const result = util.transpileAndExecute( + `const enum testEnum { + abc, + def, + ghi + } + return testEnum["def"];`, + ); + + expect(result).toBe(1); +}); + +test("Const enum index identifier value", () => { + const result = util.transpileAndExecute( + `const enum testEnum { + abc, + def = 4, + ghi, + jkl = ghi + } + return testEnum["jkl"];`, + ); + + expect(result).toBe(5); +}); + +test("Const enum index identifier chain", () => { + const result = util.transpileAndExecute( + `const enum testEnum { + abc = 3, + def, + ghi = def, + jkl = ghi, + } + return testEnum["ghi"];`, + ); + + expect(result).toBe(4); +}); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index a7058bc03..f91a22269 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -1,37 +1,22 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; -import { TranspileError } from "../../src/TranspileError"; +test("throwString", () => { + const lua = util.transpileString(`throw "Some Error"`); + expect(lua).toBe(`error("Some Error");`); +}); -export class LuaErrorTests { +test("throwError", () => { + expect(() => { + const lua = util.transpileString(`throw Error("Some Error")`); + }).toThrowExactError(TSTLErrors.InvalidThrowExpression(util.nodeStub)); +}); - @Test("throwString") - public trowString(): void { - // Transpile - const lua = util.transpileString( - `throw "Some Error"` - ); - // Assert - Expect(lua).toBe(`error("Some Error");`); - } - - @Test("throwError") - public throwError(): void { - // Transpile & Asser - Expect(() => { - const lua = util.transpileString( - `throw Error("Some Error")` - ); - }).toThrowError(TranspileError, "Invalid throw expression, only strings can be thrown."); - } - - @TestCase(0, "A") - @TestCase(1, "B") - @TestCase(2, "C") - @Test("re-throw") - public reThrow(i: number, expected: any): void { - const source = - `const i: number = ${i}; +test.each([{ i: 0, expected: "A" }, { i: 1, expected: "B" }, { i: 2, expected: "C" }])( + "re-throw (%p)", + ({ i, expected }) => { + const source = ` + const i: number = ${i}; function foo() { try { try { @@ -53,26 +38,27 @@ export class LuaErrorTests { } catch (e) { result = (e as string)[(e as string).length - 1]; } - return result;`; + return result; + `; const result = util.transpileAndExecute(source); - Expect(result).toBe(expected); - } + expect(result).toBe(expected); + }, +); - @Test("re-throw (no catch var)") - public reThrowWithoutCatchVar(): void { - const source = - `let result = "x"; +test("re-throw (no catch var)", () => { + const source = ` + let result = "x"; + try { try { - try { - throw "y"; - } catch { - throw "z"; - } - } catch (e) { - result = (e as string)[(e as string).length - 1]; + throw "y"; + } catch { + throw "z"; } - return result;`; - const result = util.transpileAndExecute(source); - Expect(result).toBe("z"); - } -} + } catch (e) { + result = (e as string)[(e as string).length - 1]; + } + return result; + `; + const result = util.transpileAndExecute(source); + expect(result).toBe("z"); +}); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index aa14e0404..e1acbfa18 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -1,528 +1,554 @@ -import { Expect, Test, TestCase } from "alsatian"; -import { TranspileError } from "../../src/TranspileError"; -import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; - import * as ts from "typescript"; -import * as util from "../src/util"; +import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; import { TSTLErrors } from "../../src/TSTLErrors"; - -export class ExpressionTests { - - @TestCase("i++", "i = i + 1;") - @TestCase("++i", "i = i + 1;") - @TestCase("i--", "i = i - 1;") - @TestCase("--i", "i = i - 1;") - @TestCase("!a", "not a;") - @TestCase("-a", "-a;") - @TestCase("+a", "a;") - @TestCase("let a = delete tbl['test']", "local a = (function()\n tbl.test = nil;\n return true;\nend)();") - @TestCase("delete tbl['test']", "tbl.test = nil;") - @TestCase("let a = delete tbl.test", "local a = (function()\n tbl.test = nil;\n return true;\nend)();") - @TestCase("delete tbl.test", "tbl.test = nil;") - @Test("Unary expressions basic") - public unaryBasic(input: string, lua: string): void { - Expect(util.transpileString(input)).toBe(lua); - } - - @TestCase("3+4", 3 + 4) - @TestCase("5-2", 5 - 2) - @TestCase("6*3", 6 * 3) - @TestCase("6**3", 6 ** 3) - @TestCase("20/5", 20 / 5) - @TestCase("15/10", 15 / 10) - @TestCase("15%3", 15 % 3) - @Test("Binary expressions basic numeric") - public binaryNum(input: string, output: number): void { - const result = util.transpileAndExecute(`return ${input}`); - - // Assert - Expect(result).toBe(output); - } - - @TestCase("1==1", true) - @TestCase("1===1", true) - @TestCase("1!=1", false) - @TestCase("1!==1", false) - @TestCase("1>1", false) - @TestCase("1>=1", true) - @TestCase("1<1", false) - @TestCase("1<=1", true) - @TestCase("1&&1", 1) - @TestCase("1||1", 1) - @Test("Binary expressions basic boolean") - public binaryBool(input: string, expected: any): void { - const result = util.transpileAndExecute(`return ${input}`); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase("'key' in obj") - @TestCase("'existingKey' in obj") - @TestCase("0 in obj") - @TestCase("9 in obj") - @Test("Binary expression in") - public binaryIn(input: string): void +import * as util from "../util"; + +test.each([ + { input: "i++", lua: "i = i + 1;" }, + { input: "++i", lua: "i = i + 1;" }, + { input: "i--", lua: "i = i - 1;" }, + { input: "--i", lua: "i = i - 1;" }, + { input: "!a", lua: "not a;" }, + { input: "-a", lua: "-a;" }, + { input: "+a", lua: "a;" }, + { + input: "let a = delete tbl['test']", + lua: "local a = (function()\n tbl.test = nil;\n return true;\nend)();", + }, + { input: "delete tbl['test']", lua: "tbl.test = nil;" }, { + input: "let a = delete tbl.test", + lua: "local a = (function()\n tbl.test = nil;\n return true;\nend)();", + }, + { input: "delete tbl.test", lua: "tbl.test = nil;" }, +])("Unary expressions basic (%p)", ({ input, lua }) => { + expect(util.transpileString(input)).toBe(lua); +}); + +test.each([ + { input: "3+4", output: 3 + 4 }, + { input: "5-2", output: 5 - 2 }, + { input: "6*3", output: 6 * 3 }, + { input: "6**3", output: 6 ** 3 }, + { input: "20/5", output: 20 / 5 }, + { input: "15/10", output: 15 / 10 }, + { input: "15%3", output: 15 % 3 }, +])("Binary expressions basic numeric (%p)", ({ input, output }) => { + const result = util.transpileAndExecute(`return ${input}`); + + expect(result).toBe(output); +}); + +test.each([ + { input: "1==1", expected: true }, + { input: "1===1", expected: true }, + { input: "1!=1", expected: false }, + { input: "1!==1", expected: false }, + { input: "1>1", expected: false }, + { input: "1>=1", expected: true }, + { input: "1<1", expected: false }, + { input: "1<=1", expected: true }, + { input: "1&&1", expected: 1 }, + { input: "1||1", expected: 1 }, +])("Binary expressions basic boolean (%p)", ({ input, expected }) => { + const result = util.transpileAndExecute(`return ${input}`); + + expect(result).toBe(expected); +}); + +test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])( + "Binary expression in (%p)", + input => { const tsHeader = "declare var obj: any;"; const tsSource = `return ${input}`; const luaHeader = "obj = { existingKey = 1 }"; const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); - // Assert - Expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); - } - - @TestCase("a+=b", 5 + 3) - @TestCase("a-=b", 5 - 3) - @TestCase("a*=b", 5 * 3) - @TestCase("a/=b", 5 / 3) - @TestCase("a%=b", 5 % 3) - @TestCase("a**=b", 5 ** 3) - @Test("Binary expressions overridden operators") - public binaryOperatorOverride(input: string, expected: number): void { - const result = util.transpileAndExecute(`let a = 5; let b = 3; ${input}; return a;`); - - Expect(result).toBe(expected); - } - - @TestCase("~b") - @TestCase("a&b") - @TestCase("a&=b") - @TestCase("a|b") - @TestCase("a|=b") - @TestCase("a^b") - @TestCase("a^=b") - @TestCase("a<>b") - @TestCase("a>>=b") - @TestCase("a>>>b") - @TestCase("a>>>=b") - @Test("Bitop [5.1]") - public bitOperatorOverride51(input: string, lua: string): void { - // Bit operations not supported in 5.1, expect an exception - Expect(() => util.transpileString(input, { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None })) - .toThrow(); - } - - @TestCase("~a", "bit.bnot(a);") - @TestCase("a&b", "bit.band(a, b);") - @TestCase("a&=b", "a = bit.band(a, b);") - @TestCase("a|b", "bit.bor(a, b);") - @TestCase("a|=b", "a = bit.bor(a, b);") - @TestCase("a^b", "bit.bxor(a, b);") - @TestCase("a^=b", "a = bit.bxor(a, b);") - @TestCase("a<>b", "bit.arshift(a, b);") - @TestCase("a>>=b", "a = bit.arshift(a, b);") - @TestCase("a>>>b", "bit.rshift(a, b);") - @TestCase("a>>>=b", "a = bit.rshift(a, b);") - @Test("Bitop [JIT]") - public bitOperatorOverrideJIT(input: string, lua: string): void { - const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; - Expect(util.transpileString(input, options)).toBe(lua); - } - - @TestCase("~a", "bit32.bnot(a);") - @TestCase("a&b", "bit32.band(a, b);") - @TestCase("a&=b", "a = bit32.band(a, b);") - @TestCase("a|b", "bit32.bor(a, b);") - @TestCase("a|=b", "a = bit32.bor(a, b);") - @TestCase("a^b", "bit32.bxor(a, b);") - @TestCase("a^=b", "a = bit32.bxor(a, b);") - @TestCase("a<>b", "bit32.arshift(a, b);") - @TestCase("a>>=b", "a = bit32.arshift(a, b);") - @TestCase("a>>>b", "bit32.rshift(a, b);") - @TestCase("a>>>=b", "a = bit32.rshift(a, b);") - @Test("Bitop [5.2]") - public bitOperatorOverride52(input: string, lua: string): void { - const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; - Expect(util.transpileString(input, options)).toBe(lua); - } - - @TestCase("~a", "~a;") - @TestCase("a&b", "a & b;") - @TestCase("a&=b", "a = a & b;") - @TestCase("a|b", "a | b;") - @TestCase("a|=b", "a = a | b;") - @TestCase("a^b", "a ~ b;") - @TestCase("a^=b", "a = a ~ b;") - @TestCase("a<>>b", "a >> b;") - @TestCase("a>>>=b", "a = a >> b;") - @Test("Bitop [5.3]") - public bitOperatorOverride53(input: string, lua: string): void { - const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; - Expect(util.transpileString(input, options)).toBe(lua); - } - - @TestCase("a>>b") - @TestCase("a>>=b") - @Test("Unsupported bitop 5.3") - public bitOperatorOverride53Unsupported(input: string): void { - Expect(() => util.transpileString(input, { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None })) - .toThrowError(TranspileError, TSTLErrors.UnsupportedKind( - "right shift operator (use >>> instead)", - ts.SyntaxKind.GreaterThanGreaterThanToken, - undefined - ).message); - } - - @TestCase("1+1", "1 + 1;") - @TestCase("-1+1", "(-1) + 1;") - @TestCase("1*30+4", "(1 * 30) + 4;") - @TestCase("1*(3+4)", "1 * (3 + 4);") - @TestCase("1*(3+4*2)", "1 * (3 + (4 * 2));") - @Test("Binary expressions ordering parentheses") - public binaryParentheses(input: string, lua: string): void { - Expect(util.transpileString(input)).toBe(lua); - } - - @TestCase("bar(),foo()", 1) - @TestCase("foo(),bar()", 2) - @TestCase("foo(),bar(),baz()", 3) - @Test("Binary Comma") - public binaryComma(input: string, expectResult: number): void { - const code = - `function foo() { return 1; } - function bar() { return 2; }; - function baz() { return 3; }; - return (${input});`; - Expect(util.transpileAndExecute(code)).toBe(expectResult); - } - - @Test("Binary Comma Statement in For Loop") - public binaryCommaStatementInForLoop(): void { - const code = - `let x: number, y: number; - for (x = 0, y = 17; x < 5; ++x, --y) {} - return y;`; - Expect(util.transpileAndExecute(code)).toBe(12); - } - - @Test("Null Expression") - public nullExpression(): void { - Expect(util.transpileString("null")).toBe("nil;"); - } - - @Test("Undefined Expression") - public undefinedExpression(): void { - Expect(util.transpileString("undefined")).toBe("nil;"); - } - - @TestCase("true ? 'a' : 'b'", "a") - @TestCase("false ? 'a' : 'b'", "b") - @TestCase("true ? false : true", false) - @TestCase("false ? false : true", true) - @TestCase("true ? literalValue : true", "literal") - @TestCase("true ? variableValue : true", undefined) - @TestCase("true ? maybeUndefinedValue : true", undefined) - @TestCase("true ? maybeBooleanValue : true", false) - @TestCase("true ? maybeUndefinedValue : true", undefined, { strictNullChecks: true }) - @TestCase("true ? maybeBooleanValue : true", false, { strictNullChecks: true }) - @TestCase("true ? undefined : true", undefined, { strictNullChecks: true }) - @TestCase("true ? null : true", undefined, { strictNullChecks: true }) - @TestCase("true ? false : true", false, { luaTarget: LuaTarget.Lua51 }) - @TestCase("false ? false : true", true, { luaTarget: LuaTarget.Lua51 }) - @TestCase("true ? undefined : true", undefined, { luaTarget: LuaTarget.Lua51 }) - @TestCase("true ? false : true", false, { luaTarget: LuaTarget.LuaJIT }) - @TestCase("false ? false : true", true, { luaTarget: LuaTarget.LuaJIT }) - @TestCase("true ? undefined : true", undefined, { luaTarget: LuaTarget.LuaJIT }) - @Test("Ternary operator") - public ternaryOperator(input: string, expected: any, options?: ts.CompilerOptions): void { - const result = util.transpileAndExecute( - `const literalValue = 'literal'; - let variableValue:string; - let maybeBooleanValue:string|boolean = false; - let maybeUndefinedValue:string|undefined; - return ${input};`, options); - - Expect(result).toBe(expected); - } - - @TestCase("inst.field", 8) - @TestCase("inst.field + 3", 8 + 3) - @TestCase("inst.field * 3", 8 * 3) - @TestCase("inst.field / 2", 8 / 2) - @TestCase("inst.field && 3", 8 && 3) - @TestCase("inst.field || 3", 8 || 3) - @TestCase("(inst.field + 3) & 3", (8 + 3) & 3) - @TestCase("inst.field | 3", 8 | 3) - @TestCase("inst.field << 3", 8 << 3) - @TestCase("inst.field >>> 1", 8 >> 1) - @TestCase("inst.field = 3", 3) - @TestCase(`"abc" + inst.field`, "abc8") - @Test("Get accessor expression") - public getAccessorBinary(expression: string, expected: any): void { - const source = `class MyClass {` - + ` public _field: number;` - + ` public get field(): number { return this._field + 4; }` - + ` public set field(v: number) { this._field = v; }` - + `}` - + `var inst = new MyClass();` - + `inst._field = 4;` - + `return ${expression};`; - - // Transpile/Execute - const result = util.transpileAndExecute(source); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase("= 4", 4 + 4) - @TestCase("-= 3", (4 - 3) + 4) - @TestCase("+= 3", (4 + 3) + 4) - @TestCase("*= 3", (4 * 3) + 4) - @TestCase("/= 2", (4 / 2) + 4) - @TestCase("&= 3", (4 & 3) + 4) - @TestCase("|= 3", (4 | 3) + 4) - @TestCase("<<= 3", (4 << 3) + 4) - @TestCase(">>>= 3", (4 >> 3) + 4) - @Test("Set accessorExpression") - public setAccessorBinary(expression: string, expected: any): void { - const source = `class MyClass {` - + ` public _field: number = 4;` - + ` public get field(): number { return this._field; }` - + ` public set field(v: number) { this._field = v + 4; }` - + `}` - + `var inst = new MyClass();` - + `inst.field ${expression};` - + `return inst._field;`; - - // Transpile/Execute - const result = util.transpileAndExecute(source); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase("inst.baseField", 7) - @TestCase("inst.field", 6) - @TestCase("inst.superField", 5) - @TestCase("inst.superBaseField", 4) - @Test("Inherited accessors") - public inheritedAccessors(expression: string, expected: any): void { - const source = `class MyBaseClass {` - + ` public _baseField: number;` - + ` public get baseField(): number { return this._baseField + 6; }` - + ` public set baseField(v: number) { this._baseField = v; }` - + `}` - + `class MyClass extends MyBaseClass {` - + ` public _field: number;` - + ` public get field(): number { return this._field + 4; }` - + ` public set field(v: number) { this._field = v; }` - + `}` - + `class MySuperClass extends MyClass {` - + ` public _superField: number;` - + ` public get superField(): number { return this._superField + 2; }` - + ` public set superField(v: number) { this._superField = v; }` - + ` public get superBaseField() { return this.baseField - 3; }` - + `}` - + `var inst = new MySuperClass();` - + `inst.baseField = 1;` - + `inst.field = 2;` - + `inst.superField = 3;` - + `return ${expression};`; - - const result = util.transpileAndExecute(source); - Expect(result).toBe(expected); - } - - @TestCase("return x.value;", 1) - @TestCase("x.value = 3; return x.value;", 3) - @Test("Union accessors") - public unionAccessors(expression: string, expected: any): void { - const result = util.transpileAndExecute( - `class A{ get value(){ return this.v || 1; } set value(v){ this.v = v; } v: number; } - class B{ get value(){ return this.v || 2; } set value(v){ this.v = v; } v: number; } - let x: A|B = new A(); - ${expression}` - ); - - Expect(result).toBe(expected); - } - - @TestCase("i++", 10) - @TestCase("i--", 10) - @TestCase("++i", 11) - @TestCase("--i", 9) - @Test("Incrementor value") - public incrementorValue(expression: string, expected: number): void { - const result = util.transpileAndExecute(`let i = 10; return ${expression};`); - - Expect(result).toBe(expected); - } - - @TestCase("a++", "val3") - @TestCase("a--", "val3") - @TestCase("--a", "val2") - @TestCase("++a", "val4") - @Test("Template string expression") - public templateStringExpression(lambda: string, expected: string): void { - const result = util.transpileAndExecute("let a = 3; return `val${" + lambda + "}`;"); - - Expect(result).toEqual(expected); - } - - @TestCase("x = y", "y") - @TestCase("x += y", "xy") - @Test("Assignment expressions") - public assignmentExpression(expression: string, expected: string): void { + expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); + }, +); + +test.each([ + { input: "a+=b", expected: 5 + 3 }, + { input: "a-=b", expected: 5 - 3 }, + { input: "a*=b", expected: 5 * 3 }, + { input: "a/=b", expected: 5 / 3 }, + { input: "a%=b", expected: 5 % 3 }, + { input: "a**=b", expected: 5 ** 3 }, +])("Binary expressions overridden operators (%p)", ({ input, expected }) => { + const result = util.transpileAndExecute(`let a = 5; let b = 3; ${input}; return a;`); + + expect(result).toBe(expected); +}); + +test.each([ + { input: "~b" }, + { input: "a&b" }, + { input: "a&=b" }, + { input: "a|b" }, + { input: "a|=b" }, + { input: "a^b" }, + { input: "a^=b" }, + { input: "a<>b" }, + { input: "a>>=b" }, + { input: "a>>>b" }, + { input: "a>>>=b" }, +])("Bitop [5.1] (%p)", ({ input }) => { + // Bit operations not supported in 5.1, expect an exception + expect(() => + util.transpileString(input, { + luaTarget: LuaTarget.Lua51, + luaLibImport: LuaLibImportKind.None, + }), + ).toThrow(); +}); + +test.each([ + { input: "~a", lua: "bit.bnot(a);" }, + { input: "a&b", lua: "bit.band(a, b);" }, + { input: "a&=b", lua: "a = bit.band(a, b);" }, + { input: "a|b", lua: "bit.bor(a, b);" }, + { input: "a|=b", lua: "a = bit.bor(a, b);" }, + { input: "a^b", lua: "bit.bxor(a, b);" }, + { input: "a^=b", lua: "a = bit.bxor(a, b);" }, + { input: "a<>b", lua: "bit.arshift(a, b);" }, + { input: "a>>=b", lua: "a = bit.arshift(a, b);" }, + { input: "a>>>b", lua: "bit.rshift(a, b);" }, + { input: "a>>>=b", lua: "a = bit.rshift(a, b);" }, +])("Bitop [JIT] (%p)", ({ input, lua }) => { + const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; + expect(util.transpileString(input, options)).toBe(lua); +}); + +test.each([ + { input: "~a", lua: "bit32.bnot(a);" }, + { input: "a&b", lua: "bit32.band(a, b);" }, + { input: "a&=b", lua: "a = bit32.band(a, b);" }, + { input: "a|b", lua: "bit32.bor(a, b);" }, + { input: "a|=b", lua: "a = bit32.bor(a, b);" }, + { input: "a^b", lua: "bit32.bxor(a, b);" }, + { input: "a^=b", lua: "a = bit32.bxor(a, b);" }, + { input: "a<>b", lua: "bit32.arshift(a, b);" }, + { input: "a>>=b", lua: "a = bit32.arshift(a, b);" }, + { input: "a>>>b", lua: "bit32.rshift(a, b);" }, + { input: "a>>>=b", lua: "a = bit32.rshift(a, b);" }, +])("Bitop [5.2] (%p)", ({ input, lua }) => { + const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; + expect(util.transpileString(input, options)).toBe(lua); +}); + +test.each([ + { input: "~a", lua: "~a;" }, + { input: "a&b", lua: "a & b;" }, + { input: "a&=b", lua: "a = a & b;" }, + { input: "a|b", lua: "a | b;" }, + { input: "a|=b", lua: "a = a | b;" }, + { input: "a^b", lua: "a ~ b;" }, + { input: "a^=b", lua: "a = a ~ b;" }, + { input: "a<>>b", lua: "a >> b;" }, + { input: "a>>>=b", lua: "a = a >> b;" }, +])("Bitop [5.3] (%p)", ({ input, lua }) => { + const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; + expect(util.transpileString(input, options)).toBe(lua); +}); + +test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { + expect(() => + util.transpileString(input, { + luaTarget: LuaTarget.Lua53, + luaLibImport: LuaLibImportKind.None, + }), + ).toThrowExactError( + TSTLErrors.UnsupportedKind( + "right shift operator (use >>> instead)", + ts.SyntaxKind.GreaterThanGreaterThanToken, + util.nodeStub, + ), + ); +}); + +test.each([ + { input: "1+1", lua: "1 + 1;" }, + { input: "-1+1", lua: "(-1) + 1;" }, + { input: "1*30+4", lua: "(1 * 30) + 4;" }, + { input: "1*(3+4)", lua: "1 * (3 + 4);" }, + { input: "1*(3+4*2)", lua: "1 * (3 + (4 * 2));" }, +])("Binary expressions ordering parentheses (%p)", ({ input, lua }) => { + expect(util.transpileString(input)).toBe(lua); +}); + +test.each([ + { input: "bar(),foo()", expectResult: 1 }, + { input: "foo(),bar()", expectResult: 2 }, + { input: "foo(),bar(),baz()", expectResult: 3 }, +])("Binary Comma (%p)", ({ input, expectResult }) => { + const code = `function foo() { return 1; } + function bar() { return 2; }; + function baz() { return 3; }; + return (${input});`; + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); + +test("Binary Comma Statement in For Loop", () => { + const code = ` + let x: number, y: number; + for (x = 0, y = 17; x < 5; ++x, --y) {} + return y; + `; + expect(util.transpileAndExecute(code)).toBe(12); +}); + +test("Null Expression", () => { + expect(util.transpileString("null")).toBe("nil;"); +}); + +test("Undefined Expression", () => { + expect(util.transpileString("undefined")).toBe("nil;"); +}); + +test.each([ + { input: "true ? 'a' : 'b'", expected: "a" }, + { input: "false ? 'a' : 'b'", expected: "b" }, + { input: "true ? false : true", expected: false }, + { input: "false ? false : true", expected: true }, + { input: "true ? literalValue : true", expected: "literal" }, + { input: "true ? variableValue : true" }, + { input: "true ? maybeUndefinedValue : true" }, + { input: "true ? maybeBooleanValue : true", expected: false }, + { input: "true ? maybeUndefinedValue : true", options: { strictNullChecks: true } }, + { + input: "true ? maybeBooleanValue : true", + expected: false, + options: { strictNullChecks: true }, + }, + { input: "true ? undefined : true", options: { strictNullChecks: true } }, + { input: "true ? null : true", options: { strictNullChecks: true } }, + { input: "true ? false : true", expected: false, options: { luaTarget: LuaTarget.Lua51 } }, + { input: "false ? false : true", expected: true, options: { luaTarget: LuaTarget.Lua51 } }, + { input: "true ? undefined : true", options: { luaTarget: LuaTarget.Lua51 } }, + { input: "true ? false : true", expected: false, options: { luaTarget: LuaTarget.LuaJIT } }, + { input: "false ? false : true", expected: true, options: { luaTarget: LuaTarget.LuaJIT } }, + { input: "true ? undefined : true", options: { luaTarget: LuaTarget.LuaJIT } }, +])("Ternary operator (%p)", ({ input, expected, options }) => { + const result = util.transpileAndExecute( + `const literalValue = 'literal'; + let variableValue:string; + let maybeBooleanValue:string|boolean = false; + let maybeUndefinedValue:string|undefined; + return ${input};`, + options, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { expression: "inst.field", expected: 8 }, + { expression: "inst.field + 3", expected: 8 + 3 }, + { expression: "inst.field * 3", expected: 8 * 3 }, + { expression: "inst.field / 2", expected: 8 / 2 }, + { expression: "inst.field && 3", expected: 8 && 3 }, + { expression: "inst.field || 3", expected: 8 || 3 }, + { expression: "(inst.field + 3) & 3", expected: (8 + 3) & 3 }, + { expression: "inst.field | 3", expected: 8 | 3 }, + { expression: "inst.field << 3", expected: 8 << 3 }, + { expression: "inst.field >>> 1", expected: 8 >> 1 }, + { expression: "inst.field = 3", expected: 3 }, + { expression: `"abc" + inst.field`, expected: "abc8" }, +])("Get accessor expression (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute(` + class MyClass { + public _field: number; + public get field(): number { return this._field + 4; } + public set field(v: number) { this._field = v; } + } + var inst = new MyClass(); + inst._field = 4; + return ${expression}; + `); + + expect(result).toBe(expected); +}); + +test.each([ + { expression: "= 4", expected: 4 + 4 }, + { expression: "-= 3", expected: 4 - 3 + 4 }, + { expression: "+= 3", expected: 4 + 3 + 4 }, + { expression: "*= 3", expected: 4 * 3 + 4 }, + { expression: "/= 2", expected: 4 / 2 + 4 }, + { expression: "&= 3", expected: (4 & 3) + 4 }, + { expression: "|= 3", expected: (4 | 3) + 4 }, + { expression: "<<= 3", expected: (4 << 3) + 4 }, + { expression: ">>>= 3", expected: (4 >> 3) + 4 }, +])("Set accessorExpression (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute(` + class MyClass { + public _field: number = 4; + public get field(): number { return this._field; } + public set field(v: number) { this._field = v + 4; } + } + var inst = new MyClass(); + inst.field ${expression}; + return inst._field; + `); + + expect(result).toBe(expected); +}); + +test.each([ + { expression: "inst.baseField", expected: 7 }, + { expression: "inst.field", expected: 6 }, + { expression: "inst.superField", expected: 5 }, + { expression: "inst.superBaseField", expected: 4 }, +])("Inherited accessors (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute(` + class MyBaseClass { + public _baseField: number; + public get baseField(): number { return this._baseField + 6; } + public set baseField(v: number) { this._baseField = v; } + } + class MyClass extends MyBaseClass { + public _field: number; + public get field(): number { return this._field + 4; } + public set field(v: number) { this._field = v; } + } + class MySuperClass extends MyClass { + public _superField: number; + public get superField(): number { return this._superField + 2; } + public set superField(v: number) { this._superField = v; } + public get superBaseField() { return this.baseField - 3; } + } + var inst = new MySuperClass(); + inst.baseField = 1; + inst.field = 2; + inst.superField = 3; + return ${expression} + `); + expect(result).toBe(expected); +}); + +test.each([ + { expression: "return x.value;", expected: 1 }, + { expression: "x.value = 3; return x.value;", expected: 3 }, +])("Union accessors (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `class A{ get value(){ return this.v || 1; } set value(v){ this.v = v; } v: number; } + class B{ get value(){ return this.v || 2; } set value(v){ this.v = v; } v: number; } + let x: A|B = new A(); + ${expression}`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { expression: "i++", expected: 10 }, + { expression: "i--", expected: 10 }, + { expression: "++i", expected: 11 }, + { expression: "--i", expected: 9 }, +])("Incrementor value (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute(`let i = 10; return ${expression};`); + + expect(result).toBe(expected); +}); + +test.each([ + { lambda: "a++", expected: "val3" }, + { lambda: "a--", expected: "val3" }, + { lambda: "--a", expected: "val2" }, + { lambda: "++a", expected: "val4" }, +])("Template string expression (%p)", ({ lambda, expected }) => { + const result = util.transpileAndExecute("let a = 3; return `val${" + lambda + "}`;"); + + expect(result).toEqual(expected); +}); + +test.each([{ expression: "x = y", expected: "y" }, { expression: "x += y", expected: "xy" }])( + "Assignment expressions (%p)", + ({ expression, expected }) => { const result = util.transpileAndExecute(`let x = "x"; let y = "y"; return ${expression};`); - Expect(result).toBe(expected); - } - - @TestCase("x = o.p", "o") - @TestCase("x = a[0]", "a") - @TestCase("x = y = o.p", "o") - @TestCase("x = o.p", "o") - @Test("Assignment expressions using temp") - public assignmentWithTempExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let x = "x"; - let y = "y"; - let o = {p: "o"}; - let a = ["a"]; - return ${expression};`); - Expect(result).toBe(expected); - } - - @TestCase("o.p = x", "x") - @TestCase("a[0] = x", "x") - @TestCase("o.p = a[0]", "a") - @TestCase("o.p = a[0] = x", "x") - @Test("Property assignment expressions") - public propertyAssignmentExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let x = "x"; - let o = {p: "o"}; - let a = ["a"]; - return ${expression};`); - Expect(result).toBe(expected); - } - - @TestCase("x = t()", "t0,t1") - @TestCase("x = tr()", "tr0,tr1") - @TestCase("[x[1], x[0]] = t()", "t0,t1") - @TestCase("[x[1], x[0]] = tr()", "tr0,tr1") - @TestCase("x = [y[1], y[0]]", "y1,y0") - @TestCase("[x[0], x[1]] = [y[1], y[0]]", "y1,y0") - @Test("Tuple assignment expressions") - public tupleAssignmentExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let x: [string, string] = ["x0", "x1"]; - let y: [string, string] = ["y0", "y1"]; - function t(): [string, string] { return ["t0", "t1"] }; - /** @tupleReturn */ - function tr(): [string, string] { return ["tr0", "tr1"] }; - const r = ${expression}; - return \`\${r[0]},\${r[1]}\``); - Expect(result).toBe(expected); - } - - @Test("Block expression") - public blockExpresion(): void { - const result = util.transpileAndExecute(`let a = 4; {let a = 42; } return a;`); - Expect(result).toBe(4); - } - - @Test("Non-null expression") - public nonNullExpression(): void { - const result = util.transpileAndExecute(`function abc(): number | undefined { return 3; } - const a: number = abc()!; - return a;`); - Expect(result).toBe(3); - } - // ==================================== - // Test expected errors - // ==================================== - - @Test("Unknown unary postfix error") - public unknownUnaryPostfixError(): void { - const transformer = util.makeTestTransformer(); - - const mockExpression: any = { - operand: ts.createLiteral(false), - operator: ts.SyntaxKind.AsteriskToken, - }; - - Expect(() => transformer.transformPostfixUnaryExpression(mockExpression as ts.PostfixUnaryExpression)) - .toThrowError(TranspileError, "Unsupported unary postfix operator kind: AsteriskToken"); - } - - @Test("Unknown unary postfix error") - public unknownUnaryPrefixError(): void { - const transformer = util.makeTestTransformer(); - - const mockExpression: any = { - operand: ts.createLiteral(false), - operator: ts.SyntaxKind.AsteriskToken, - }; - - Expect(() => transformer.transformPrefixUnaryExpression(mockExpression as ts.PrefixUnaryExpression)) - .toThrowError(TranspileError, "Unsupported unary prefix operator kind: AsteriskToken"); - } - - @Test("Incompatible fromCodePoint expression error") - public incompatibleFromCodePointExpression(): void { - const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); - - const identifier = ts.createIdentifier("fromCodePoint"); - Expect(() => transformer.transformStringExpression(identifier)) - .toThrowError(TranspileError, "string property fromCodePoint is/are not supported " + - "for target Lua jit."); - } - - @Test("Unknown string expression error") - public unknownStringExpression(): void { - const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); - - const identifier = ts.createIdentifier("abcd"); - Expect(() => transformer.transformStringExpression(identifier)) - .toThrowError(TranspileError, "string property abcd is/are not supported for target Lua jit."); - } - - @Test("Unsupported array function error") - public unsupportedArrayFunctionError(): void { - const transformer = util.makeTestTransformer(); - - const mockNode: any = { - kind: ts.SyntaxKind.CallExpression, - arguments: [], - caller: ts.createLiteral(false), - expression: {name: ts.createIdentifier("unknownFunction"), expression: ts.createLiteral(false)}, - }; - - Expect(() => transformer.transformArrayCallExpression(mockNode as ts.CallExpression)) - .toThrowError(TranspileError, "Unsupported property on array: unknownFunction"); - } - - @Test("Unsupported math property error") - public unsupportedMathPropertyError(): void { - const transformer = util.makeTestTransformer(); - - Expect(() => transformer.transformMathExpression(ts.createIdentifier("unknownProperty"))) - .toThrowError(TranspileError, "Unsupported property on math: unknownProperty"); - } - - @Test("Unsupported object literal element error") - public unsupportedObjectLiteralElementError(): void { - const transformer = util.makeTestTransformer(); - - const mockObject: any = { - properties: [{ + expect(result).toBe(expected); + }, +); + +test.each([ + { expression: "x = o.p", expected: "o" }, + { expression: "x = a[0]", expected: "a" }, + { expression: "x = y = o.p", expected: "o" }, + { expression: "x = o.p", expected: "o" }, +])("Assignment expressions using temp (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let x = "x"; + let y = "y"; + let o = {p: "o"}; + let a = ["a"]; + return ${expression};`, + ); + expect(result).toBe(expected); +}); + +test.each([ + { expression: "o.p = x", expected: "x" }, + { expression: "a[0] = x", expected: "x" }, + { expression: "o.p = a[0]", expected: "a" }, + { expression: "o.p = a[0] = x", expected: "x" }, +])("Property assignment expressions (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let x = "x"; + let o = {p: "o"}; + let a = ["a"]; + return ${expression};`, + ); + expect(result).toBe(expected); +}); + +test.each([ + { expression: "x = t()", expected: "t0,t1" }, + { expression: "x = tr()", expected: "tr0,tr1" }, + { expression: "[x[1], x[0]] = t()", expected: "t0,t1" }, + { expression: "[x[1], x[0]] = tr()", expected: "tr0,tr1" }, + { expression: "x = [y[1], y[0]]", expected: "y1,y0" }, + { expression: "[x[0], x[1]] = [y[1], y[0]]", expected: "y1,y0" }, +])("Tuple assignment expressions (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let x: [string, string] = ["x0", "x1"]; + let y: [string, string] = ["y0", "y1"]; + function t(): [string, string] { return ["t0", "t1"] }; + /** @tupleReturn */ + function tr(): [string, string] { return ["tr0", "tr1"] }; + const r = ${expression}; + return \`\${r[0]},\${r[1]}\``, + ); + expect(result).toBe(expected); +}); + +test("Block expression", () => { + const result = util.transpileAndExecute(`let a = 4; {let a = 42; } return a;`); + expect(result).toBe(4); +}); + +test("Non-null expression", () => { + const result = util.transpileAndExecute(` + function abc(): number | undefined { return 3; } + const a: number = abc()!; + return a; + `); + expect(result).toBe(3); +}); + +test("Unknown unary postfix error", () => { + const transformer = util.makeTestTransformer(); + + const mockExpression: any = { + operand: ts.createLiteral(false), + operator: ts.SyntaxKind.AsteriskToken, + }; + + expect(() => + transformer.transformPostfixUnaryExpression(mockExpression as ts.PostfixUnaryExpression), + ).toThrowExactError( + TSTLErrors.UnsupportedKind( + "unary postfix operator", + ts.SyntaxKind.AsteriskToken, + util.nodeStub, + ), + ); +}); + +test("Unknown unary postfix error", () => { + const transformer = util.makeTestTransformer(); + + const mockExpression: any = { + operand: ts.createLiteral(false), + operator: ts.SyntaxKind.AsteriskToken, + }; + + expect(() => + transformer.transformPrefixUnaryExpression(mockExpression as ts.PrefixUnaryExpression), + ).toThrowExactError( + TSTLErrors.UnsupportedKind( + "unary prefix operator", + ts.SyntaxKind.AsteriskToken, + util.nodeStub, + ), + ); +}); + +test("Incompatible fromCodePoint expression error", () => { + const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); + + const identifier = ts.createIdentifier("fromCodePoint"); + expect(() => transformer.transformStringExpression(identifier)).toThrowExactError( + TSTLErrors.UnsupportedForTarget( + "string property fromCodePoint", + LuaTarget.LuaJIT, + util.nodeStub, + ), + ); +}); + +test("Unknown string expression error", () => { + const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); + + const identifier = ts.createIdentifier("abcd"); + expect(() => transformer.transformStringExpression(identifier)).toThrowExactError( + TSTLErrors.UnsupportedForTarget("string property abcd", LuaTarget.LuaJIT, util.nodeStub), + ); +}); + +test("Unsupported array function error", () => { + const transformer = util.makeTestTransformer(); + + const mockNode: any = { + kind: ts.SyntaxKind.CallExpression, + arguments: [], + caller: ts.createLiteral(false), + expression: { + name: ts.createIdentifier("unknownFunction"), + expression: ts.createLiteral(false), + }, + }; + + expect(() => + transformer.transformArrayCallExpression(mockNode as ts.CallExpression), + ).toThrowExactError(TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub)); +}); + +test("Unsupported math property error", () => { + const transformer = util.makeTestTransformer(); + + expect(() => + transformer.transformMathExpression(ts.createIdentifier("unknownProperty")), + ).toThrowExactError(TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub)); +}); + +test("Unsupported object literal element error", () => { + const transformer = util.makeTestTransformer(); + + const mockObject: any = { + properties: [ + { kind: ts.SyntaxKind.FalseKeyword, name: ts.createIdentifier("testProperty"), - }], - }; - - Expect(() => transformer.transformObjectLiteral(mockObject as ts.ObjectLiteralExpression)) - .toThrowError(TranspileError, "Unsupported object literal element kind: FalseKeyword"); - } -} + }, + ], + }; + + expect(() => + transformer.transformObjectLiteral(mockObject as ts.ObjectLiteralExpression), + ).toThrowExactError( + TSTLErrors.UnsupportedKind( + "object literal element", + ts.SyntaxKind.FalseKeyword, + util.nodeStub, + ), + ); +}); diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 55161623b..d36dddcdf 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -1,104 +1,83 @@ -import { Expect, Test, TestCase } from "alsatian"; - import * as ts from "typescript"; -import * as util from "../src/util"; - -export class FunctionTests { - - @Test("Arrow Function Expression") - public arrowFunctionExpression(): void - { - const result = util.transpileAndExecute(`let add = (a, b) => a+b; return add(1,2);`); - - // Assert - Expect(result).toBe(3); - } - - @TestCase("i++", 15) - @TestCase("i--", 5) - @TestCase("++i", 15) - @TestCase("--i", 5) - @Test("Arrow function unary expression") - public arrowFunctionUnary(lambda: string, expected: number): void { - const result = util.transpileAndExecute(`let i = 10; [1,2,3,4,5].forEach(() => ${lambda}); return i;`); - - Expect(result).toBe(expected); - } - - @TestCase("b => a = b", 5) - @TestCase("b => a += b", 15) - @TestCase("b => a -= b", 5) - @TestCase("b => a *= b", 50) - @TestCase("b => a /= b", 2) - @TestCase("b => a **= b", 100000) - @TestCase("b => a %= b", 0) - @Test("Arrow function assignment") - public arrowFunctionAssignment(lambda: string, expected: number): void - { - const result = util.transpileAndExecute(`let a = 10; let lambda = ${lambda}; - lambda(5); return a;`); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase([]) - @TestCase([5]) - @TestCase([1, 2]) - @Test("Arrow Default Values") - public arrowExpressionDefaultValues(inp: number[]): void { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - - const callArgs = inp.join(","); - - // Transpile/Execute - const result = util.transpileAndExecute( - `let add = (a: number = 3, b: number = 4) => a+b; - return add(${callArgs});` - ); - - // Assert - Expect(result).toBe(v1 + v2); - } - - @Test("Function Expression") - public functionExpression(): void - { - const result = util.transpileAndExecute(`let add = function(a, b) {return a+b}; return add(1,2);`); - - // Assert - Expect(result).toBe(3); - } - - @Test("Function definition scope") - public functionDefinitionScope(): void - { - const result = util.transpileAndExecute(`function abc() { function xyz() { return 5; } }\n - function def() { function xyz() { return 3; } abc(); return xyz(); }\n - return def();`); - - // Assert - Expect(result).toBe(3); - } - - @Test("Function default parameter") - public functionDefaultParameter(): void - { - const result = util.transpileAndExecute(`function abc(defaultParam: string = "abc") { return defaultParam; }\n - return abc() + abc("def");`); - - // Assert - Expect(result).toBe("abcdef"); - } - - @TestCase([]) - @TestCase([5]) - @TestCase([1, 2]) - @Test("Function Default Values") - public functionExpressionDefaultValues(inp: number[]): void { +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test("Arrow Function Expression", () => { + const result = util.transpileAndExecute(`let add = (a, b) => a+b; return add(1,2);`); + + expect(result).toBe(3); +}); + +test.each([ + { lambda: "i++", expected: 15 }, + { lambda: "i--", expected: 5 }, + { lambda: "++i", expected: 15 }, + { lambda: "--i", expected: 5 }, +])("Arrow function unary expression (%p)", ({ lambda, expected }) => { + const result = util.transpileAndExecute( + `let i = 10; [1,2,3,4,5].forEach(() => ${lambda}); return i;`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { lambda: "b => a = b", expected: 5 }, + { lambda: "b => a += b", expected: 15 }, + { lambda: "b => a -= b", expected: 5 }, + { lambda: "b => a *= b", expected: 50 }, + { lambda: "b => a /= b", expected: 2 }, + { lambda: "b => a **= b", expected: 100000 }, + { lambda: "b => a %= b", expected: 0 }, +])("Arrow function assignment (%p)", ({ lambda, expected }) => { + const result = util.transpileAndExecute(`let a = 10; let lambda = ${lambda}; + lambda(5); return a;`); + + expect(result).toBe(expected); +}); + +test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Arrow Default Values (%p)", ({ inp }) => { + // Default value is 3 for v1 + const v1 = inp.length > 0 ? inp[0] : 3; + // Default value is 4 for v2 + const v2 = inp.length > 1 ? inp[1] : 4; + + const callArgs = inp.join(","); + + const result = util.transpileAndExecute( + `let add = (a: number = 3, b: number = 4) => a+b; + return add(${callArgs});`, + ); + + expect(result).toBe(v1 + v2); +}); + +test("Function Expression", () => { + const result = util.transpileAndExecute( + `let add = function(a, b) {return a+b}; return add(1,2);`, + ); + + expect(result).toBe(3); +}); + +test("Function definition scope", () => { + const result = util.transpileAndExecute(`function abc() { function xyz() { return 5; } }\n + function def() { function xyz() { return 3; } abc(); return xyz(); }\n + return def();`); + + expect(result).toBe(3); +}); + +test("Function default parameter", () => { + const result = util.transpileAndExecute(`function abc(defaultParam: string = "abc") { return defaultParam; }\n + return abc() + abc("def");`); + + expect(result).toBe("abcdef"); +}); + +test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])( + "Function Default Values (%p)", + ({ inp }) => { // Default value is 3 for v1 const v1 = inp.length > 0 ? inp[0] : 3; // Default value is 4 for v2 @@ -106,253 +85,229 @@ export class FunctionTests { const callArgs = inp.join(","); - // Transpile/Execute const result = util.transpileAndExecute( `let add = function(a: number = 3, b: number = 4) { return a+b; }; - return add(${callArgs});` + return add(${callArgs});`, ); - // Assert - Expect(result).toBe(v1 + v2); - } + expect(result).toBe(v1 + v2); + }, +); - @Test("Class method call") - public classMethod(): void { - const returnValue = 4; - const source = `class TestClass { - public classMethod(): number { return ${returnValue}; } - } +test("Class method call", () => { + const returnValue = 4; + const source = `class TestClass { + public classMethod(): number { return ${returnValue}; } + } - const classInstance = new TestClass(); - return classInstance.classMethod();`; + const classInstance = new TestClass(); + return classInstance.classMethod();`; - // Transpile/Execute - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - // Assert - Expect(result).toBe(returnValue); - } + expect(result).toBe(returnValue); +}); - @Test("Class dot method call void") - public classDotMethod(): void { - const returnValue = 4; - const source = `class TestClass { - public dotMethod: () => number = () => ${returnValue}; - } +test("Class dot method call void", () => { + const returnValue = 4; + const source = `class TestClass { + public dotMethod: () => number = () => ${returnValue}; + } - const classInstance = new TestClass(); - return classInstance.dotMethod();`; + const classInstance = new TestClass(); + return classInstance.dotMethod();`; - // Transpile/Execute - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - // Assert - Expect(result).toBe(returnValue); - } + expect(result).toBe(returnValue); +}); - @Test("Class dot method call with parameter") - public classDotMethod2(): void { - const returnValue = 4; - const source = `class TestClass { - public dotMethod: (x: number) => number = x => 3 * x; - } +test("Class dot method call with parameter", () => { + const returnValue = 4; + const source = `class TestClass { + public dotMethod: (x: number) => number = x => 3 * x; + } - const classInstance = new TestClass(); - return classInstance.dotMethod(${returnValue});`; + const classInstance = new TestClass(); + return classInstance.dotMethod(${returnValue});`; - // Transpile - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - // Assert - Expect(result).toBe(3 * returnValue); - } + expect(result).toBe(3 * returnValue); +}); - @Test("Class static dot method") - public classDotMethodStatic(): void { - const returnValue = 4; - const source = `class TestClass { - public static dotMethod: () => number = () => ${returnValue}; - } +test("Class static dot method", () => { + const returnValue = 4; + const source = `class TestClass { + public static dotMethod: () => number = () => ${returnValue}; + } - return TestClass.dotMethod();`; + return TestClass.dotMethod();`; - // Transpile/Execute - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - // Assert - Expect(result).toBe(returnValue); - } + expect(result).toBe(returnValue); +}); - @Test("Class static dot method with parameter") - public classDotMethodStaticWithParameter(): void { - const returnValue = 4; - const source = `class TestClass { - public static dotMethod: (x: number) => number = x => 3 * x; - } +test("Class static dot method with parameter", () => { + const returnValue = 4; + const source = `class TestClass { + public static dotMethod: (x: number) => number = x => 3 * x; + } - return TestClass.dotMethod(${returnValue});`; + return TestClass.dotMethod(${returnValue});`; - // Transpile - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - // Assert - Expect(result).toBe(3 * returnValue); - } + expect(result).toBe(3 * returnValue); +}); - @Test("Function bind") - public functionBind(): void { - const source = `const abc = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } - return abc.bind({ a: 4 }, "b")("c");`; +test("Function bind", () => { + const source = `const abc = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } + return abc.bind({ a: 4 }, "b")("c");`; - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - Expect(result).toBe("4bc"); - } + expect(result).toBe("4bc"); +}); - @Test("Function apply") - public functionApply(): void { - const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } - return abc.apply({ a: 4 }, ["b"]);`; +test("Function apply", () => { + const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } + return abc.apply({ a: 4 }, ["b"]);`; - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - Expect(result).toBe("4b"); - } + expect(result).toBe("4b"); +}); - @Test("Function call") - public functionCall(): void { - const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } - return abc.call({ a: 4 }, "b");`; +test("Function call", () => { + const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } + return abc.call({ a: 4 }, "b");`; - const result = util.transpileAndExecute(source); + const result = util.transpileAndExecute(source); - Expect(result).toBe("4b"); - } + expect(result).toBe("4b"); +}); - @Test("Invalid property access call transpilation") - public invalidPropertyCall(): void { - const transformer = util.makeTestTransformer(); +test("Invalid property access call transpilation", () => { + const transformer = util.makeTestTransformer(); - const mockObject: any = { - expression: ts.createLiteral("abc"), - }; + const mockObject: any = { + expression: ts.createLiteral("abc"), + }; - Expect(() => transformer.transformPropertyCall(mockObject as ts.CallExpression)) - .toThrowError(Error, "Tried to transpile a non-property call as property call."); - } + expect(() => + transformer.transformPropertyCall(mockObject as ts.CallExpression), + ).toThrowExactError(TSTLErrors.InvalidPropertyCall(util.nodeStub)); +}); - @Test("Function dead code after return") - public functionDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `function abc() { return 3; const a = 5; } return abc();`); +test("Function dead code after return", () => { + const result = util.transpileAndExecute( + `function abc() { return 3; const a = 5; } return abc();`, + ); - Expect(result).toBe(3); - } + expect(result).toBe(3); +}); - @Test("Method dead code after return") - public methodDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `class def { public static abc() { return 3; const a = 5; } } return def.abc();`); +test("Method dead code after return", () => { + const result = util.transpileAndExecute( + `class def { public static abc() { return 3; const a = 5; } } return def.abc();`, + ); - Expect(result).toBe(3); - } + expect(result).toBe(3); +}); - @Test("Recursive function definition") - public recursiveFunctionDefinition(): void { - const result = util.transpileAndExecute( - `function f() { return typeof f; }; return f();`); +test("Recursive function definition", () => { + const result = util.transpileAndExecute(`function f() { return typeof f; }; return f();`); - Expect(result).toBe("function"); - } + expect(result).toBe("function"); +}); - @Test("Recursive function expression") - public recursiveFunctionExpression(): void { - const result = util.transpileAndExecute( - `let f = function() { return typeof f; }; return f();`); +test("Recursive function expression", () => { + const result = util.transpileAndExecute(`let f = function() { return typeof f; }; return f();`); - Expect(result).toBe("function"); - } + expect(result).toBe("function"); +}); - @Test("Wrapped recursive function expression") - public wrappedRecursiveFunctionExpression(): void { - const result = util.transpileAndExecute( - `function wrap(fn: T) { return fn; } - let f = wrap(function() { return typeof f; }); return f();`); +test("Wrapped recursive function expression", () => { + const result = util.transpileAndExecute( + `function wrap(fn: T) { return fn; } + let f = wrap(function() { return typeof f; }); return f();`, + ); - Expect(result).toBe("function"); - } + expect(result).toBe("function"); +}); - @Test("Recursive arrow function") - public recursiveArrowFunction(): void { - const result = util.transpileAndExecute( - `let f = () => typeof f; return f();`); +test("Recursive arrow function", () => { + const result = util.transpileAndExecute(`let f = () => typeof f; return f();`); - Expect(result).toBe("function"); - } + expect(result).toBe("function"); +}); - @Test("Wrapped recursive arrow function") - public wrappedRecursiveArrowFunction(): void { - const result = util.transpileAndExecute( - `function wrap(fn: T) { return fn; } - let f = wrap(() => typeof f); return f();`); +test("Wrapped recursive arrow function", () => { + const result = util.transpileAndExecute( + `function wrap(fn: T) { return fn; } + let f = wrap(() => typeof f); return f();`, + ); - Expect(result).toBe("function"); - } + expect(result).toBe("function"); +}); - @Test("Object method declaration") - public objectMethodDeclaration(): void { - const result = util.transpileAndExecute( - `let o = { v: 4, m(i: number): number { return this.v * i; } }; return o.m(3);`); - Expect(result).toBe(12); - } - - @TestCase(["bar"], "foobar") - @TestCase(["baz", "bar"], "bazbar") - @Test("Function overload") - public functionOverload(args: string[], expectResult: string): void { - const code = `class O { - prop = "foo"; - method(s: string): string; - method(this: void, s1: string, s2: string): string; - method(s1: string) { - if (typeof this === "string") { - return this + s1; - } - return this.prop + s1; - } - }; - const o = new O(); - return o.method(${args.map(a => "\"" + a + "\"").join(", ")});`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); - } - - @Test("Nested Function") - public nestedFunction(): void { - const code = `class C { - private prop = "bar"; - public outer() { - const o = { - prop: "foo", - innerFunc: function() { return this.prop; }, - innerArrow: () => this.prop - }; - return o.innerFunc() + o.innerArrow(); - } - } - let c = new C(); - return c.outer();`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foobar"); - } - - @TestCase("abc", "abc") - @TestCase("abc", "def") - @Test("Dot vs Colon method call") - public dotVColonMethodCall(s1: string, s2: string): void - { - const result = util.transpileAndExecute( - `class MyClass { +test("Object method declaration", () => { + const result = util.transpileAndExecute( + `let o = { v: 4, m(i: number): number { return this.v * i; } }; return o.m(3);`, + ); + expect(result).toBe(12); +}); + +test.each([ + { args: ["bar"], expectResult: "foobar" }, + { args: ["baz", "bar"], expectResult: "bazbar" }, +])("Function overload (%p)", ({ args, expectResult }) => { + const code = ` + class O { + prop = "foo"; + method(s: string): string; + method(this: void, s1: string, s2: string): string; + method(s1: string) { + if (typeof this === "string") { + return this + s1; + } + return this.prop + s1; + } + }; + const o = new O(); + return o.method(${args.map(a => '"' + a + '"').join(", ")}); + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); +}); + +test("Nested Function", () => { + const code = ` + class C { + private prop = "bar"; + public outer() { + const o = { + prop: "foo", + innerFunc: function() { return this.prop; }, + innerArrow: () => this.prop + }; + return o.innerFunc() + o.innerArrow(); + } + } + let c = new C(); + return c.outer(); + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foobar"); +}); + +test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])( + "Dot vs Colon method call (%p)", + ({ s1, s2 }) => { + const result = util.transpileAndExecute(` + class MyClass { dotMethod(this: void, s: string) { return s; } @@ -361,66 +316,67 @@ export class FunctionTests { } } const inst = new MyClass(); - return inst.dotMethod("${s1}") == inst.colonMethod("${s2}");` - ); - Expect(result).toBe(s1 === s2); - } - - @Test("Element access call") - public elementAccessCall(): void { - const code = `class C { + return inst.dotMethod("${s1}") == inst.colonMethod("${s2}"); + `); + expect(result).toBe(s1 === s2); + }, +); + +test("Element access call", () => { + const code = ` + class C { prop = "bar"; method(s: string) { return s + this.prop; } } const c = new C(); return c['method']("foo"); - `; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foobar"); - } - - @Test("Element access call no args") - public elementAccessCallNoArgs(): void { - const code = `class C { + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foobar"); +}); + +test("Element access call no args", () => { + const code = ` + class C { prop = "bar"; method() { return this.prop; } } const c = new C(); return c['method'](); - `; - const result = util.transpileAndExecute(code); - Expect(result).toBe("bar"); - } + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("bar"); +}); - @Test("Complex element access call") - public elementAccessCallComplex(): void { - const code = `class C { +test("Complex element access call", () => { + const code = ` + class C { prop = "bar"; method(s: string) { return s + this.prop; } } function getC() { return new C(); } return getC()['method']("foo"); - `; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foobar"); - } + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foobar"); +}); - @Test("Complex element access call no args") - public elementAccessCallComplexNoArgs(): void { - const code = `class C { +test("Complex element access call no args", () => { + const code = ` + class C { prop = "bar"; method() { return this.prop; } } function getC() { return new C(); } return getC()['method'](); - `; - const result = util.transpileAndExecute(code); - Expect(result).toBe("bar"); - } - - @Test("Complex element access call statement") - public elementAccessCallComplexStatement(): void { - const code = `let foo: string; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("bar"); +}); + +test("Complex element access call statement", () => { + const code = ` + let foo: string; class C { prop = "bar"; method(s: string) { foo = s + this.prop; } @@ -428,54 +384,56 @@ export class FunctionTests { function getC() { return new C(); } getC()['method']("foo"); return foo; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foobar"); +}); + +test.each([{ iterations: 1, expectedResult: 1 }, { iterations: 2, expectedResult: 42 }])( + "Generator functions value (%p)", + ({ iterations, expectedResult }) => { + const code = ` + function* seq(value: number) { + let a = yield value + 1; + return 42; + } + const gen = seq(0); + let ret: number; + for(let i = 0; i < ${iterations}; ++i) + { + ret = gen.next(i).value; + } + return ret; `; const result = util.transpileAndExecute(code); - Expect(result).toBe("foobar"); - } - - @TestCase(1, 1) - @TestCase(2, 42) - @Test("Generator functions value") - public generatorFunctionValue(iterations: number, expectedResult: number): void { - const code = `function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: number; - for(let i = 0; i < ${iterations}; ++i) - { - ret = gen.next(i).value; - } - return ret; - `; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectedResult); - } - - @TestCase(1, false) - @TestCase(2, true) - @Test("Generator functions done") - public generatorFunctionDone(iterations: number, expectedResult: boolean): void { - const code = `function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: boolean; - for(let i = 0; i < ${iterations}; ++i) - { - ret = gen.next(i).done; - } - return ret; + expect(result).toBe(expectedResult); + }, +); + +test.each([{ iterations: 1, expectedResult: false }, { iterations: 2, expectedResult: true }])( + "Generator functions done (%p)", + ({ iterations, expectedResult }) => { + const code = ` + function* seq(value: number) { + let a = yield value + 1; + return 42; + } + const gen = seq(0); + let ret: boolean; + for(let i = 0; i < ${iterations}; ++i) + { + ret = gen.next(i).done; + } + return ret; `; const result = util.transpileAndExecute(code); - Expect(result).toBe(expectedResult); - } + expect(result).toBe(expectedResult); + }, +); - @Test("Generator for..of") - public generatorFunctionForOf(): void { - const code = `function* seq() { +test("Generator for..of", () => { + const code = ` + function* seq() { yield(1); yield(2); yield(3); @@ -486,41 +444,40 @@ export class FunctionTests { { result = result * 10 + i; } - return result`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(123); - } - - @Test("Function local overriding export") - public functionLocalOverridingExport(): void { - const code = - `export const foo = 5; - function bar(foo: number) { - return foo; - } - export const result = bar(7);`; - Expect(util.transpileExecuteAndReturnExport(code, "result")).toBe(7); - } - - @Test("Function using global as this") - public functionUsingGlobalAsThis(): void { - const code = - `var foo = "foo"; - function bar(this: any) { - return this.foo; - }`; - Expect(util.transpileAndExecute("return foo;", undefined, undefined, code)).toBe("foo"); - } - - @Test("Function rest binding pattern") - public functionRestBindingPattern(): void { - const result = util.transpileAndExecute( - `function bar(foo: string, ...[bar, baz]: [string, string]) { - return bar + baz + foo; - } - return bar("abc", "def", "xyz"); - `); + return result + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(123); +}); + +test("Function local overriding export", () => { + const code = ` + export const foo = 5; + function bar(foo: number) { + return foo; + } + export const result = bar(7); + `; + expect(util.transpileExecuteAndReturnExport(code, "result")).toBe(7); +}); + +test("Function using global as this", () => { + const code = ` + var foo = "foo"; + function bar(this: any) { + return this.foo; + } + `; + expect(util.transpileAndExecute("return foo;", undefined, undefined, code)).toBe("foo"); +}); + +test("Function rest binding pattern", () => { + const result = util.transpileAndExecute(` + function bar(foo: string, ...[bar, baz]: [string, string]) { + return bar + baz + foo; + } + return bar("abc", "def", "xyz"); + `); - Expect(result).toBe("defxyzabc"); - } -} + expect(result).toBe("defxyzabc"); +}); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 44ed9d0dd..215d38c49 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -1,257 +1,245 @@ import * as ts from "typescript"; -import { Expect, Test, TestCase } from "alsatian"; - -import * as util from "../src/util"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; -import { TranspileError } from "../../src/TranspileError"; - -export class HoistingTests { - @Test("Var Hoisting") - public varHoisting(): void { - const code = - `foo = "foo"; - var foo; - return foo;`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Exported Var Hoisting") - public exportedVarHoisting(): void { - const code = - `foo = "foo"; - export var foo;`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @TestCase("let") - @TestCase("const") - @Test("Let/Const Hoisting") - public letConstHoisting(varType: string): void { - const code = - `let bar: string; - function setBar() { bar = foo; } - ${varType} foo = "foo"; - setBar(); - return foo;`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @TestCase("let") - @TestCase("const") - @Test("Exported Let/Const Hoisting") - public exportedLetConstHoisting(varType: string): void { - const code = - `let bar: string; - function setBar() { bar = foo; } - export ${varType} foo = "foo"; - setBar();`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @Test("Global Function Hoisting") - public globalFunctionHoisting(): void { - const code = - `const foo = bar(); +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test("Var Hoisting", () => { + const code = ` + foo = "foo"; + var foo; + return foo; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test("Exported Var Hoisting", () => { + const code = ` + foo = "foo"; + export var foo; + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { + const code = ` + let bar: string; + function setBar() { bar = foo; } + ${varType} foo = "foo"; + setBar(); + return foo; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test.each(["let", "const"])("Exported Let/Const Hoisting (%p)", varType => { + const code = ` + let bar: string; + function setBar() { bar = foo; } + export ${varType} foo = "foo"; + setBar(); + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test("Global Function Hoisting", () => { + const code = ` + const foo = bar(); + function bar() { return "bar"; } + return foo; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("bar"); +}); + +test("Local Function Hoisting", () => { + const code = ` + export const foo = bar(); + function bar() { return "bar"; } + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("bar"); +}); + +test("Exported Function Hoisting", () => { + const code = ` + const foo = bar(); + export function bar() { return "bar"; } + export const baz = foo; + `; + const result = util.transpileExecuteAndReturnExport(code, "baz"); + expect(result).toBe("bar"); +}); + +test("Namespace Function Hoisting", () => { + const code = ` + let foo: string; + namespace NS { + foo = bar(); function bar() { return "bar"; } - return foo;`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("bar"); - } - - @Test("Local Function Hoisting") - public localFunctionHoisting(): void { - const code = - `export const foo = bar(); - function bar() { return "bar"; }`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("bar"); - } - - @Test("Exported Function Hoisting") - public exportedFunctionHoisting(): void { - const code = - `const foo = bar(); + } + `; + const result = util.transpileAndExecute("return foo;", undefined, undefined, code); + expect(result).toBe("bar"); +}); + +test("Exported Namespace Function Hoisting", () => { + const code = ` + let foo: string; + namespace NS { + foo = bar(); export function bar() { return "bar"; } - export const baz = foo;`; - const result = util.transpileExecuteAndReturnExport(code, "baz"); - Expect(result).toBe("bar"); - } - - @Test("Namespace Function Hoisting") - public namespaceFunctionHoisting(): void { - const code = - `let foo: string; - namespace NS { - foo = bar(); - function bar() { return "bar"; } - }`; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - Expect(result).toBe("bar"); - } - - @Test("Exported Namespace Function Hoisting") - public exportedNamespaceFunctionHoisting(): void { - const code = - `let foo: string; - namespace NS { - foo = bar(); - export function bar() { return "bar"; } - }`; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - Expect(result).toBe("bar"); - } - - @TestCase("var", "foo") - @TestCase("let", "bar") - @TestCase("const", "bar") - @Test("Hoisting in Non-Function Scope") - public hoistingInNonFunctionScope(varType: string, expectResult: string): void { - const code = - `function foo() { - ${varType} bar = "bar"; - for (let i = 0; i < 1; ++i) { - ${varType} bar = "foo"; - } - return bar; + } + `; + const result = util.transpileAndExecute("return foo;", undefined, undefined, code); + expect(result).toBe("bar"); +}); + +test.each([ + { varType: "var", expectResult: "foo" }, + { varType: "let", expectResult: "bar" }, + { varType: "const", expectResult: "bar" }, +])("Hoisting in Non-Function Scope (%p)", ({ varType, expectResult }) => { + const code = ` + function foo() { + ${varType} bar = "bar"; + for (let i = 0; i < 1; ++i) { + ${varType} bar = "foo"; } - return foo();`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); - } - - @TestCase("", "foofoo") - @TestCase(" = \"bar\"", "barbar") - @Test("Var hoisting from child scope") - public varHoistingFromChildScope(initializer: string, expectResult: string): void { - const code = - `foo = "foo"; - let result: string; - if (true) { - var foo${initializer}; - result = foo; + return bar; + } + return foo(); + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); +}); + +test.each([ + { initializer: "", expectResult: "foofoo" }, + { initializer: ' = "bar"', expectResult: "barbar" }, +])("Var hoisting from child scope (%p)", ({ initializer, expectResult }) => { + const code = ` + foo = "foo"; + let result: string; + if (true) { + var foo${initializer}; + result = foo; + } + return foo + result; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); +}); + +test("Hoisting due to reference from hoisted function", () => { + const code = ` + const foo = "foo"; + const result = bar(); + function bar() { + return foo; + } + return result; + `; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + +test("Namespace Hoisting", () => { + const code = ` + function bar() { + return NS.foo; + } + namespace NS { + export let foo = "foo"; + } + export const foo = bar(); + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test("Exported Namespace Hoisting", () => { + const code = ` + function bar() { + return NS.foo; + } + export namespace NS { + export let foo = "foo"; + } + export const foo = bar(); + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test("Nested Namespace Hoisting", () => { + const code = ` + export namespace Outer { + export function bar() { + return Inner.foo; } - return foo + result;`; - const result = util.transpileAndExecute(code); - Expect(result).toBe(expectResult); - } - - @Test("Hoisting due to reference from hoisted function") - public hoistingDueToReferenceFromHoistedFunction(): void { - const code = - `const foo = "foo"; - const result = bar(); - function bar() { - return foo; - } - return result;`; - const result = util.transpileAndExecute(code); - Expect(result).toBe("foo"); - } - - @Test("Namespace Hoisting") - public namespaceHoisting(): void { - const code = - `function bar() { - return NS.foo; - } - namespace NS { + namespace Inner { export let foo = "foo"; } - export const foo = bar();`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @Test("Exported Namespace Hoisting") - public exportedNamespaceHoisting(): void { - const code = - `function bar() { - return NS.foo; - } - export namespace NS { - export let foo = "foo"; - } - export const foo = bar();`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @Test("Nested Namespace Hoisting") - public nestedNamespaceHoisting(): void { - const code = - `export namespace Outer { - export function bar() { - return Inner.foo; - } - namespace Inner { - export let foo = "foo"; - } - } - export const foo = Outer.bar();`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @Test("Class Hoisting") - public classHoisting(): void { - const code = - `function makeFoo() { - return new Foo(); - } - class Foo { - public bar = "foo"; - } - export const foo = makeFoo().bar;`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @Test("Enum Hoisting") - public enumHoisting(): void { - const code = - `function bar() { - return E.A; - } - enum E { - A = "foo" - } - export const foo = bar();`; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - Expect(result).toBe("foo"); - } - - @TestCase(`foo = "foo"; var foo;`, "foo") - @TestCase(`foo = "foo"; export var foo;`, "foo") - @TestCase(`function setBar() { const bar = foo; } let foo = "foo";`, "foo") - @TestCase(`function setBar() { const bar = foo; } const foo = "foo";`, "foo") - @TestCase(`function setBar() { const bar = foo; } export let foo = "foo";`, "foo") - @TestCase(`function setBar() { const bar = foo; } export const foo = "foo";`, "foo") - @TestCase(`const foo = bar(); function bar() { return "bar"; }`, "bar") - @TestCase(`export const foo = bar(); function bar() { return "bar"; }`, "bar") - @TestCase(`const foo = bar(); export function bar() { return "bar"; }`, "bar") - @TestCase(`function bar() { return NS.foo; } namespace NS { export let foo = "foo"; }`, "NS") - @TestCase( - `export namespace O { export function f() { return I.foo; } namespace I { export let foo = "foo"; } }`, - "I" - ) - @TestCase(`function makeFoo() { return new Foo(); } class Foo {}`, "Foo") - @TestCase(`function bar() { return E.A; } enum E { A = "foo" }`, "E") - @Test("No Hoisting") - public noHoisting(code: string, identifier: string): void { - const compilerOptions: CompilerOptions = { - noHoisting: true, - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - Expect(() => util.transpileString(code, compilerOptions)).toThrowError( - TranspileError, - `Identifier "${identifier}" was referenced before it was declared. The declaration ` + - "must be moved before the identifier's use, or hoisting must be enabled." - ); - } -} + } + export const foo = Outer.bar(); + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test("Class Hoisting", () => { + const code = ` + function makeFoo() { + return new Foo(); + } + class Foo { + public bar = "foo"; + } + export const foo = makeFoo().bar; + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test("Enum Hoisting", () => { + const code = ` + function bar() { + return E.A; + } + enum E { + A = "foo" + } + export const foo = bar(); + `; + const result = util.transpileExecuteAndReturnExport(code, "foo"); + expect(result).toBe("foo"); +}); + +test.each([ + { code: `foo = "foo"; var foo;`, identifier: "foo" }, + { code: `foo = "foo"; export var foo;`, identifier: "foo" }, + { code: `function setBar() { const bar = foo; } let foo = "foo";`, identifier: "foo" }, + { code: `function setBar() { const bar = foo; } const foo = "foo";`, identifier: "foo" }, + { code: `function setBar() { const bar = foo; } export let foo = "foo";`, identifier: "foo" }, + { code: `function setBar() { const bar = foo; } export const foo = "foo";`, identifier: "foo" }, + { code: `const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, + { code: `export const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, + { code: `const foo = bar(); export function bar() { return "bar"; }`, identifier: "bar" }, + { + code: `function bar() { return NS.foo; } namespace NS { export let foo = "foo"; }`, + identifier: "NS", + }, + { + code: `export namespace O { export function f() { return I.foo; } namespace I { export let foo = "foo"; } }`, + identifier: "I", + }, + { code: `function makeFoo() { return new Foo(); } class Foo {}`, identifier: "Foo" }, + { code: `function bar() { return E.A; } enum E { A = "foo" }`, identifier: "E" }, +])("No Hoisting (%p)", ({ code, identifier }) => { + expect(() => util.transpileString(code, { noHoisting: true })).toThrowExactError( + TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)), + ); +}); diff --git a/test/unit/importexport.spec.ts b/test/unit/importexport.spec.ts index 7aca64caf..cd98b0b4f 100644 --- a/test/unit/importexport.spec.ts +++ b/test/unit/importexport.spec.ts @@ -1,17 +1,12 @@ -import { Expect, Test, TestCase } from "alsatian"; - -import * as util from "../src/util"; import { TSTLErrors } from "../../src/TSTLErrors"; -import { TranspileError } from "../../src/TranspileError"; +import * as util from "../util"; -export class ImportExportTests -{ - @TestCase("export { default } from '...'") - @TestCase("export { x as default } from '...';") - @TestCase("export { default as x } from '...';") - @Test("Export default keyword disallowed") - public exportDefaultKeywordError(exportStatement: string): void { - const expectedTest = TSTLErrors.UnsupportedDefaultExport(undefined).message; - Expect(() => util.transpileString(exportStatement)).toThrowError(TranspileError, expectedTest); - } -} +test.each([ + "export { default } from '...'", + "export { x as default } from '...';", + "export { default as x } from '...';", +])("Export default keyword disallowed (%p)", exportStatement => { + expect(() => util.transpileString(exportStatement)).toThrowExactError( + TSTLErrors.UnsupportedDefaultExport(util.nodeStub), + ); +}); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index 7ac15a776..337e5676f 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,27 +1,24 @@ -import { Expect, Test, TestCase } from "alsatian"; import { transpileString } from "../../src/Compiler"; -import { TranspileError } from "../../src/TranspileError"; -import * as util from "../src/util"; +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; -export class JsonTests { - @Test("JSON") - @TestCase("0") - @TestCase('""') - @TestCase("[]") - @TestCase('[1, "2", []]') - @TestCase('{ "a": "b" }') - @TestCase('{ "a": { "b": "c" } }') - public json(json: string): void { - const lua = transpileString(json, { resolveJsonModule: true, noHeader: true }, false, "file.json") - .replace(/^return ([\s\S]+);$/, "return JSONStringify($1);"); +test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } }'])( + "JSON (%p)", + json => { + const lua = transpileString( + json, + { resolveJsonModule: true, noHeader: true }, + false, + "file.json", + ).replace(/^return ([\s\S]+);$/, "return JSONStringify($1);"); const result = util.executeLua(lua); - Expect(JSON.parse(result)).toEqual(JSON.parse(json)); - } + expect(JSON.parse(result)).toEqual(JSON.parse(json)); + }, +); - @Test("Empty JSON") - public emptyJson(): void { - Expect(() => transpileString("", { resolveJsonModule: true, noHeader: true }, false, "file.json")) - .toThrowError(TranspileError, "Invalid JSON file content"); - } -} +test("Empty JSON", () => { + expect(() => + transpileString("", { resolveJsonModule: true, noHeader: true }, false, "file.json"), + ).toThrowExactError(TSTLErrors.InvalidJsonFileContent(util.nodeStub)); +}); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 153e243b2..d87f019fd 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,35 +1,25 @@ -import { Expect, Test, TestCase } from "alsatian"; import * as ts from "typescript"; -import { TranspileError } from "../../src/TranspileError"; import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; -import * as util from "../src/util"; - -const deepEqual = require("deep-equal"); - -export class LuaLoopTests -{ - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("while") - public while(inp: number[], expected: number[]): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; - while (i < arrTest.length) { - arrTest[i] = arrTest[i] + 1; - i++; - } - return JSONStringify(arrTest);` - ); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3, 4], [0, 1, 2, 1, 4]) - @Test("while with continue") - public whileWithContinue(inp: number[], expected: number[]): void - { +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("while (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + let i = 0; + while (i < arrTest.length) { + arrTest[i] = arrTest[i] + 1; + i++; + } + return JSONStringify(arrTest);`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( + "while with continue (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i = 0; @@ -50,17 +40,16 @@ export class LuaLoopTests i++; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3, 4], [0, 1, 2, 1, 4]) - @Test("dowhile with continue") - public dowhileWithContinue(inp: number[], expected: number[]): void - { +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( + "dowhile with continue (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i = 0; @@ -81,49 +70,42 @@ export class LuaLoopTests i++; } while (i < arrTest.length) - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("for") - public for(inp: number[], expected: number[]): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - for (let i = 0; i < arrTest.length; ++i) { - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("for with expression") - public forWithExpression(inp: number[], expected: number[]): void - { + expect(result).toBe(JSON.stringify(expected)); + }, +); + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + for (let i = 0; i < arrTest.length; ++i) { + arrTest[i] = arrTest[i] + 1; + } + return JSONStringify(arrTest);`, + ); + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( + "for with expression (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i: number; for (i = 0 * 1; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3, 4], [0, 0, 2, 0, 4]) - @Test("for with continue") - public forWithContinue(inp: number[], expected: number[]): void - { - // Transpile +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( + "for with continue (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; for (let i = 0; i < arrTest.length; i++) { @@ -138,68 +120,60 @@ export class LuaLoopTests arrTest[i] = j; } } - return JSONStringify(arrTest); - ` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("forMirror") - public forMirror(inp: number[], expected: number[]): void - { +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( + "forMirror (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; for (let i = 0; arrTest.length > i; i++) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3], [0, 1, 2, 3]) - @Test("forBreak") - public forBreak(inp: number[], expected: number[]): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - for (let i = 0; i < arrTest.length; ++i) { - break; - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("forNoDeclarations") - public forNoDeclarations(inp: number[], expected: number[]): void - { + expect(result).toBe(JSON.stringify(expected)); + }, +); + +test.each([{ inp: [0, 1, 2, 3], expected: [0, 1, 2, 3] }])("forBreak (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + for (let i = 0; i < arrTest.length; ++i) { + break; + arrTest[i] = arrTest[i] + 1; + } + return JSONStringify(arrTest);`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( + "forNoDeclarations (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i = 0; for (; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("forNoCondition") - public forNoCondition(inp: number[], expected: number[]): void - { +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( + "forNoCondition (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i = 0; @@ -210,17 +184,16 @@ export class LuaLoopTests arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("forNoPostExpression") - public forNoPostExpression(inp: number[], expected: number[]): void - { +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( + "forNoPostExpression (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; let i = 0; @@ -233,79 +206,94 @@ export class LuaLoopTests i++; } - return JSONStringify(arrTest);` + return JSONStringify(arrTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2, 3], [1, 2, 3, 4], "let i = 0; i < arrTest.length; i++") - @TestCase([0, 1, 2, 3], [1, 2, 3, 4], "let i = 0; i <= arrTest.length - 1; i++") - @TestCase([0, 1, 2, 3], [1, 2, 3, 4], "let i = 0; arrTest.length > i; i++") - @TestCase([0, 1, 2, 3], [1, 2, 3, 4], "let i = 0; arrTest.length - 1 >= i; i++") - @TestCase([0, 1, 2, 3], [1, 1, 3, 3], "let i = 0; i < arrTest.length; i += 2") - @TestCase([0, 1, 2, 3], [1, 2, 3, 4 ], "let i = arrTest.length - 1; i >= 0; i--") - @TestCase([0, 1, 2, 3], [0, 2, 2, 4], "let i = arrTest.length - 1; i >= 0; i -= 2") - @TestCase([0, 1, 2, 3], [0, 2, 2, 4], "let i = arrTest.length - 1; i > 0; i -= 2") - @Test("forheader") - public forheader(inp: number[], expected: number[], header: string): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - for (${header}) { - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); + expect(result).toBe(JSON.stringify(expected)); + }, +); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase("for scope") - public forScope(): void { - const code = - `let i = 42; - for (let i = 0; i < 10; ++i) {} - return i;`; - Expect(util.transpileAndExecute(code)).toBe(42); - } - - @TestCase({ ["test1"]: 0, ["test2"]: 1, ["test3"]: 2 }, { ["test1"]: 1, ["test2"]: 2, ["test3"]: 3 }) - @Test("forin[Object]") - public forinObject(inp: any, expected: any): void +test.each([ + { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; i < arrTest.length; i++" }, { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; - for (let key in objTest) { - objTest[key] = objTest[key] + 1; - } - return JSONStringify(objTest);` - ); - - // Assert - Expect(deepEqual(JSON.parse(result), expected)).toBe(true); - } - - @TestCase([1, 2, 3]) - @Test("forin[Array]") - public forinArray(inp: number[]): void { - // Transpile & Assert - Expect(() => - util.transpileString( - `let arrTest = ${JSON.stringify(inp)}; - for (let key in arrTest) { - arrTest[key]++; - }` - ) - ).toThrowError(TranspileError, "Iterating over arrays with 'for ... in' is not allowed."); - } - - @TestCase({a: 0, b: 1, c: 2, d: 3, e: 4}, {a: 0, b: 0, c: 2, d: 0, e: 4}) - @Test("forin with continue") - public forinWithContinue(inp: number[], expected: number[]): void + inp: [0, 1, 2, 3], + expected: [1, 2, 3, 4], + header: "let i = 0; i <= arrTest.length - 1; i++", + }, + { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; arrTest.length > i; i++" }, + { + inp: [0, 1, 2, 3], + expected: [1, 2, 3, 4], + header: "let i = 0; arrTest.length - 1 >= i; i++", + }, + { inp: [0, 1, 2, 3], expected: [1, 1, 3, 3], header: "let i = 0; i < arrTest.length; i += 2" }, + { + inp: [0, 1, 2, 3], + expected: [1, 2, 3, 4], + header: "let i = arrTest.length - 1; i >= 0; i--", + }, + { + inp: [0, 1, 2, 3], + expected: [0, 2, 2, 4], + header: "let i = arrTest.length - 1; i >= 0; i -= 2", + }, { + inp: [0, 1, 2, 3], + expected: [0, 2, 2, 4], + header: "let i = arrTest.length - 1; i > 0; i -= 2", + }, +])("forheader (%p)", ({ inp, expected, header }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + for (${header}) { + arrTest[i] = arrTest[i] + 1; + } + return JSONStringify(arrTest);`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test("for scope", () => { + const code = ` + let i = 42; + for (let i = 0; i < 10; ++i) {} + return i; + `; + expect(util.transpileAndExecute(code)).toBe(42); +}); + +test.each([ + { + inp: { ["test1"]: 0, ["test2"]: 1, ["test3"]: 2 }, + expected: { ["test1"]: 1, ["test2"]: 2, ["test3"]: 3 }, + }, +])("forin[Object] (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let objTest = ${JSON.stringify(inp)}; + for (let key in objTest) { + objTest[key] = objTest[key] + 1; + } + return JSONStringify(objTest);`, + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([{ inp: [1, 2, 3] }])("forin[Array] (%p)", ({ inp }) => { + expect(() => + util.transpileString( + `let arrTest = ${JSON.stringify(inp)}; + for (let key in arrTest) { + arrTest[key]++; + }`, + ), + ).toThrowExactError(TSTLErrors.ForbiddenForIn(util.nodeStub)); +}); + +test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( + "forin with continue (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let obj = ${JSON.stringify(inp)}; for (let i in obj) { @@ -315,35 +303,29 @@ export class LuaLoopTests obj[i] = 0; } - return JSONStringify(obj); - ` - ); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2], [1, 2, 3]) - @Test("forof") - public forof(inp: any, expected: any): void - { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; - let arrResultTest = []; - for (let value of objTest) { - arrResultTest.push(value + 1) - } - return JSONStringify(arrResultTest);` + return JSONStringify(obj);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([0, 1, 2], [1, 2, 3]) - @Test("forof existing variable") - public forofExistingVar(inp: any, expected: any): void - { + expect(result).toBe(JSON.stringify(expected)); + }, +); + +test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let objTest = ${JSON.stringify(inp)}; + let arrResultTest = []; + for (let value of objTest) { + arrResultTest.push(value + 1) + } + return JSONStringify(arrResultTest);`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])( + "forof existing variable (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; @@ -351,34 +333,32 @@ export class LuaLoopTests for (value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);` + return JSONStringify(arrResultTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([[1, 2], [2, 3], [3, 4]], [3, 5, 7]) - @Test("forof destructing") - public forofDestructing(inp: number[][], expected: any): void - { +test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( + "forof destructing (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; for (let [a,b] of objTest) { arrResultTest.push(a + b) } - return JSONStringify(arrResultTest);` + return JSONStringify(arrResultTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([[1, 2], [2, 3], [3, 4]], [3, 5, 7]) - @Test("forof destructing with existing variables") - public forofDestructingExistingVars(inp: number[][], expected: any): void - { +test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( + "forof destructing with existing variables (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; @@ -387,17 +367,16 @@ export class LuaLoopTests for ([a,b] of objTest) { arrResultTest.push(a + b) } - return JSONStringify(arrResultTest);` + return JSONStringify(arrResultTest);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } + expect(result).toBe(JSON.stringify(expected)); + }, +); - @TestCase([0, 1, 2, 3, 4], [0, 0, 2, 0, 4]) - @Test("forof with continue") - public forofWithContinue(inp: number[], expected: number[]): void - { +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( + "forof with continue (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( `let testArr = ${JSON.stringify(inp)}; let a = 0; @@ -415,414 +394,416 @@ export class LuaLoopTests } a++; } - return JSONStringify(testArr);` + return JSONStringify(testArr);`, ); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @Test("forof with iterator") - public forofWithIterator(): void { - const code = `const arr = ["a", "b", "c"]; - function iter(): IterableIterator { - let i = 0; - return { - [Symbol.iterator]() { return this; }, - next() { return {value: arr[i], done: i++ >= arr.length} }, - } - } - let result = ""; - for (let e of iter()) { - result += e; - } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof with iterator and existing variable") - public forofWithIteratorExistingVar(): void { - const code = `const arr = ["a", "b", "c"]; - function iter(): IterableIterator { - let i = 0; - return { - [Symbol.iterator]() { return this; }, - next() { return {value: arr[i], done: i++ >= arr.length} }, - } - } - let result = ""; - let e: string; - for (e of iter()) { - result += e; - } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof destructuring with iterator") - public forofDestructuringWithIterator(): void { - const code = `const arr = ["a", "b", "c"]; - function iter(): IterableIterator<[string, string]> { - let i = 0; - return { - [Symbol.iterator]() { return this; }, - next() { return {value: [i.toString(), arr[i]], done: i++ >= arr.length} }, - } - } - let result = ""; - for (let [a, b] of iter()) { - result += a + b; - } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof destructuring with iterator and existing variables") - public forofDestructuringWithIteratorExistingVars(): void { - const code = `const arr = ["a", "b", "c"]; - function iter(): IterableIterator<[string, string]> { - let i = 0; - return { - [Symbol.iterator]() { return this; }, - next() { return {value: [i.toString(), arr[i]], done: i++ >= arr.length} }, - } - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of iter()) { - result += a + b; - } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof lua iterator") - public forofLuaIterator(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof array lua iterator") - public forofArrayLuaIterator(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Array {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof lua iterator with existing variable") - public forofLuaIteratorExistingVar(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - let e: string; - for (e of luaIter()) { result += e; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof lua iterator destructuring") - public forofLuaIteratorDestructuring(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof lua iterator destructuring with existing variables") - public forofLuaIteratorDestructuringExistingVar(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof lua iterator tuple-return") - public forofLuaIteratorTupleReturn(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof lua iterator tuple-return with existing variables") - public forofLuaIteratorTupleReturnExistingVars(): void { - const code = `const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @Test("forof lua iterator tuple-return single variable") - public forofLuaIteratorTupleReturnSingleVar(): void { - const code = `/** @luaIterator */ + expect(result).toBe(JSON.stringify(expected)); + }, +); + +test("forof with iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + function iter(): IterableIterator { + let i = 0; + return { + [Symbol.iterator]() { return this; }, + next() { return {value: arr[i], done: i++ >= arr.length} }, + } + } + let result = ""; + for (let e of iter()) { + result += e; + } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof with iterator and existing variable", () => { + const code = ` + const arr = ["a", "b", "c"]; + function iter(): IterableIterator { + let i = 0; + return { + [Symbol.iterator]() { return this; }, + next() { return {value: arr[i], done: i++ >= arr.length} }, + } + } + let result = ""; + let e: string; + for (e of iter()) { + result += e; + } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof destructuring with iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + function iter(): IterableIterator<[string, string]> { + let i = 0; + return { + [Symbol.iterator]() { return this; }, + next() { return {value: [i.toString(), arr[i]], done: i++ >= arr.length} }, + } + } + let result = ""; + for (let [a, b] of iter()) { + result += a + b; + } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof destructuring with iterator and existing variables", () => { + const code = ` + const arr = ["a", "b", "c"]; + function iter(): IterableIterator<[string, string]> { + let i = 0; + return { + [Symbol.iterator]() { return this; }, + next() { return {value: [i.toString(), arr[i]], done: i++ >= arr.length} }, + } + } + let result = ""; + let a: string; + let b: string; + for ([a, b] of iter()) { + result += a + b; + } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof array lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Array {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof lua iterator with existing variable", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + let e: string; + for (e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof lua iterator destructuring", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i] && [i.toString(), arr[i++]]) as any; + } + let result = ""; + for (let [a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator destructuring with existing variables", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i] && [i.toString(), arr[i++]]) as any; + } + let result = ""; + let a: string; + let b: string; + for ([a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - for (let x of luaIter()) {}`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - Expect(() => util.transpileString(code, compilerOptions)).toThrowError( - TranspileError, - "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " - + "You must use a destructuring statement to catch results from a lua iterator with " - + "the TupleReturn decorator."); - } - - @Test("forof lua iterator tuple-return single existing variable") - public forofLuaIteratorTupleReturnSingleExistingVar(): void { - const code = `/** @luaIterator */ + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + let result = ""; + for (let [a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return with existing variables", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - let x: [string, string]; - for (x of luaIter()) {}`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - Expect(() => util.transpileString(code, compilerOptions)).toThrowError( - TranspileError, - "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " - + "You must use a destructuring statement to catch results from a lua iterator with " - + "the TupleReturn decorator."); - } - - @Test("forof forwarded lua iterator") - public forofForwardedLuaIterator(): void { - const code = - `const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - function iter() { return arr[i++]; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let a of forward()) { result += a; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("abc"); - } - - @Test("forof forwarded lua iterator with tupleReturn") - public forofForwardedLuaIteratorWithTupleReturn(): void { - const code = - `const arr = ["a", "b", "c"]; - /** @luaIterator */ + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + let result = ""; + let a: string; + let b: string; + for ([a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return single variable", () => { + const code = ` + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; + for (let x of luaIter()) {} + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub), + ); +}); + +test("forof lua iterator tuple-return single existing variable", () => { + const code = ` + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; + let x: [string, string]; + for (x of luaIter()) {} + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub), + ); +}); + +test("forof forwarded lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + function iter() { return arr[i++]; } + return iter as any; + } + function forward() { + const iter = luaIter(); + return iter; + } + let result = ""; + for (let a of forward()) { result += a; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof forwarded lua iterator with tupleReturn", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let [a, b] of forward()) { result += a + b; } - return result;`; - const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - Expect(result).toBe("0a1b2c"); - } - - @TestCase("while (a < b) { i++; }") - @TestCase("do { i++; } while (a < b)") - @TestCase("for (let i = 0; i < 3; i++) {}") - @TestCase("for (let a in b) {}") - @TestCase("for (let a of b) {}") - @Test("loop versions") - public whileVersions(loop: string): void { - // Transpile - const lua51 = util.transpileString(loop, { luaTarget: LuaTarget.Lua51 }); - const lua52 = util.transpileString(loop, { luaTarget: LuaTarget.Lua52 }); - const lua53 = util.transpileString(loop, { luaTarget: LuaTarget.Lua53 }); - const luajit = util.transpileString(loop, { luaTarget: LuaTarget.LuaJIT }); - - // Assert - Expect(lua51.indexOf("::__continue1::") !== -1).toBe(false); // No labels in 5.1 - Expect(lua52.indexOf("::__continue1::") !== -1).toBe(true); // Labels from 5.2 onwards - Expect(lua53.indexOf("::__continue1::") !== -1).toBe(true); - Expect(luajit.indexOf("::__continue1::") !== -1).toBe(true); - } - - @Test("for dead code after return") - public forDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `for (let i = 0; i < 10; i++) { return 3; const b = 8; }`); - - Expect(result).toBe(3); - } - - @Test("for..in dead code after return") - public forInDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`); - - Expect(result).toBe(3); - } - - @Test("for..of dead code after return") - public forOfDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `for (let a of [1,2,4]) { return 3; const b = 8; }`); - - Expect(result).toBe(3); - } - - @Test("while dead code after return") - public whileDeadCodeAfterReturn(): void { - const result = util.transpileAndExecute( - `while (true) { return 3; const b = 8; }`); - - Expect(result).toBe(3); - } -} + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + function forward() { + const iter = luaIter(); + return iter; + } + let result = ""; + for (let [a, b] of forward()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test.each([ + "while (a < b) { i++; }", + "do { i++; } while (a < b)", + "for (let i = 0; i < 3; i++) {}", + "for (let a in b) {}", + "for (let a of b) {}", +])("loop versions (%p)", loop => { + const lua51 = util.transpileString(loop, { luaTarget: LuaTarget.Lua51 }); + const lua52 = util.transpileString(loop, { luaTarget: LuaTarget.Lua52 }); + const lua53 = util.transpileString(loop, { luaTarget: LuaTarget.Lua53 }); + const luajit = util.transpileString(loop, { luaTarget: LuaTarget.LuaJIT }); + + expect(lua51.indexOf("::__continue1::") !== -1).toBe(false); // No labels in 5.1 + expect(lua52.indexOf("::__continue1::") !== -1).toBe(true); // Labels from 5.2 onwards + expect(lua53.indexOf("::__continue1::") !== -1).toBe(true); + expect(luajit.indexOf("::__continue1::") !== -1).toBe(true); +}); + +test("for dead code after return", () => { + const result = util.transpileAndExecute( + `for (let i = 0; i < 10; i++) { return 3; const b = 8; }`, + ); + + expect(result).toBe(3); +}); + +test("for..in dead code after return", () => { + const result = util.transpileAndExecute( + `for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`, + ); + + expect(result).toBe(3); +}); + +test("for..of dead code after return", () => { + const result = util.transpileAndExecute(`for (let a of [1,2,4]) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); + +test("while dead code after return", () => { + const result = util.transpileAndExecute(`while (true) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); diff --git a/test/unit/lualib/inlining.spec.ts b/test/unit/lualib/inlining.spec.ts index 89aed54a9..f4a6e2b45 100644 --- a/test/unit/lualib/inlining.spec.ts +++ b/test/unit/lualib/inlining.spec.ts @@ -1,50 +1,44 @@ -import { Expect, Test } from "alsatian"; -import * as util from "../../src/util"; - import { LuaLibImportKind, LuaTarget } from "../../../src/CompilerOptions"; - -export class InliningTests { - @Test("map constructor") - public mapConstructor(): void - { - const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`, - { luaLibImport: LuaLibImportKind.Inline, luaTarget: LuaTarget.Lua53 }); - - Expect(result).toBe(0); - } - - @Test("map foreach keys") - public mapForEachKeys(): void { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - mymap.forEach((value, key) => { count += key; }); - return count;`, - { luaLibImport: LuaLibImportKind.Inline, luaTarget: LuaTarget.Lua53 }); - - Expect(result).toBe(18); - } - - @Test("set constructor") - public setConstructor(): void - { - const result = util.transpileAndExecute( - `class abc {} let def = new abc(); let myset = new Set(); return myset.size;`, - { luaLibImport: LuaLibImportKind.Inline, luaTarget: LuaTarget.Lua53 } - ); - - Expect(result).toBe(0); - } - - @Test("set foreach keys") - public setForEachKeys(): void { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach((value, key) => { count += key; }); - return count;`, - { luaLibImport: LuaLibImportKind.Inline, luaTarget: LuaTarget.Lua53 }); - - Expect(result).toBe(9); - } -} +import * as util from "../../util"; + +test("map constructor", () => { + const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`, { + luaLibImport: LuaLibImportKind.Inline, + luaTarget: LuaTarget.Lua53, + }); + + expect(result).toBe(0); +}); + +test("map foreach keys", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + let count = 0; + mymap.forEach((value, key) => { count += key; }); + return count;`, + { luaLibImport: LuaLibImportKind.Inline }, + ); + + expect(result).toBe(18); +}); + +test("set constructor", () => { + const result = util.transpileAndExecute( + `class abc {} let def = new abc(); let myset = new Set(); return myset.size;`, + { luaLibImport: LuaLibImportKind.Inline }, + ); + + expect(result).toBe(0); +}); + +test("set foreach keys", () => { + const result = util.transpileAndExecute( + `let myset = new Set([2, 3, 4]); + let count = 0; + myset.forEach((value, key) => { count += key; }); + return count;`, + { luaLibImport: LuaLibImportKind.Inline }, + ); + + expect(result).toBe(9); +}); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 59b4f4418..8c4052562 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -1,521 +1,486 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as ts from "typescript"; -import * as util from "../../src/util"; -import { LuaLibImportKind } from "../../../src/CompilerOptions"; - -export class LuaLibTests -{ - @TestCase([0, 1, 2, 3], [1, 2, 3, 4]) - @Test("forEach") - public forEach(inp: number[], expected: number[]): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - arrTest.forEach((elem, index) => { - arrTest[index] = arrTest[index] + 1; - }) - return JSONStringify(arrTest);` - ); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase([], 3, -1) - @TestCase([0, 2, 4, 8], 10, -1) - @TestCase([0, 2, 4, 8], 8, 3) - @Test("array.findIndex[value]") - public findIndexByValue(inp: number[], searchEl: number, expected: number): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index) => { - return elem === ${searchEl}; - }));` +import * as util from "../../util"; + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forEach (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + arrTest.forEach((elem, index) => { + arrTest[index] = arrTest[index] + 1; + }) + return JSONStringify(arrTest);`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([ + { inp: [], searchEl: 3, expected: -1 }, + { inp: [0, 2, 4, 8], searchEl: 10, expected: -1 }, + { inp: [0, 2, 4, 8], searchEl: 8, expected: 3 }, +])("array.findIndex[value] (%p)", ({ inp, searchEl, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index) => { + return elem === ${searchEl}; + }));`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: [0, 2, 4, 8], expected: 3, value: 8 }, + { inp: [0, 2, 4, 8], expected: 1, value: 2 }, +])("array.findIndex[index] (%p)", ({ inp, expected, value }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index, arr) => { + return index === ${expected} && arr[${expected}] === ${value}; + }));`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { inp: [], func: "x => x" }, + { inp: [0, 1, 2, 3], func: "x => x" }, + { inp: [0, 1, 2, 3], func: "x => x*2" }, + { inp: [1, 2, 3, 4], func: "x => -x" }, + { inp: [0, 1, 2, 3], func: "x => x+2" }, + { inp: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, +])("array.map (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute( + `return JSONStringify([${inp.toString()}].map(${func}))`, + ); + + expect(result).toBe(JSON.stringify(inp.map(eval(func)))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x < 3" }, + { inp: [0, 1, 2, 3], func: "x => x < 0" }, + { inp: [0, -1, -2, -3], func: "x => x < 0" }, + { inp: [0, 1, 2, 3], func: "() => true" }, + { inp: [0, 1, 2, 3], func: "() => false" }, +])("array.filter (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute( + `return JSONStringify([${inp.toString()}].filter(${func}))`, + ); + + expect(result).toBe(JSON.stringify(inp.filter(eval(func)))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [false, true, false], func: "x => x" }, + { inp: [true, true, true], func: "x => x" }, +])("array.every (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute( + `return JSONStringify([${inp.toString()}].every(${func}))`, + ); + + expect(result).toBe(JSON.stringify(inp.every(eval(func)))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [false, true, false], func: "x => x" }, + { inp: [true, true, true], func: "x => x" }, +])("array.some (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute( + `return JSONStringify([${inp.toString()}].some(${func}))`, + ); + + expect(result).toBe(JSON.stringify(inp.some(eval(func)))); +}); + +test.each([ + { inp: [], start: 1, end: 2 }, + { inp: [0, 1, 2, 3], start: 1, end: 2 }, + { inp: [0, 1, 2, 3], start: 1, end: 1 }, + { inp: [0, 1, 2, 3], start: 1, end: -1 }, + { inp: [0, 1, 2, 3], start: -3, end: -1 }, + { inp: [0, 1, 2, 3, 4, 5], start: 1, end: 3 }, + { inp: [0, 1, 2, 3, 4, 5], start: 3 }, +])("array.slice (%p)", ({ inp, start, end }) => { + const result = util.transpileAndExecute( + `return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`, + ); + + expect(result).toBe(JSON.stringify(inp.slice(start, end))); +}); + +test.each([ + { inp: [], start: 0, deleteCount: 0, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 1, deleteCount: 0, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 2, deleteCount: 2, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 4, deleteCount: 1, newElements: [8, 9] }, + { inp: [0, 1, 2, 3], start: 4, deleteCount: 0, newElements: [8, 9] }, + { inp: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, + { inp: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, +])("array.splice[Insert] (%p)", ({ inp, start, deleteCount, newElements }) => { + const result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); + return JSONStringify(spliceTestTable);`, + ); + + inp.splice(start, deleteCount, ...newElements); + expect(result).toBe(JSON.stringify(inp)); +}); + +test.each([ + { inp: [], start: 1, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 1, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 10, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 4 }, + { inp: [0, 1, 2, 3, 4, 5], start: 3 }, + { inp: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, + { inp: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, +])("array.splice[Remove] (%p)", ({ inp, start, deleteCount, newElements = [] }) => { + let result; + if (deleteCount) { + result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); + return JSONStringify(spliceTestTable);`, ); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase([0, 2, 4, 8], 3, 8) - @TestCase([0, 2, 4, 8], 1, 2) - @Test("array.findIndex[index]") - public findIndexByIndex(inp: number[], expected: number, value: number): void - { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index, arr) => { - return index === ${expected} && arr[${expected}] === ${value}; - }));` + } else { + result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}); + return JSONStringify(spliceTestTable);`, ); - - // Assert - Expect(result).toBe(expected); } - @TestCase([], "x => x") - @TestCase([0, 1, 2, 3], "x => x") - @TestCase([0, 1, 2, 3], "x => x*2") - @TestCase([1, 2, 3, 4], "x => -x") - @TestCase([0, 1, 2, 3], "x => x+2") - @TestCase([0, 1, 2, 3], "x => x%2 == 0 ? x + 1 : x - 1") - @Test("array.map") - public map(inp: T[], func: string): void - { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].map(${func}))`); - - // Assert - Expect(result).toBe(JSON.stringify(inp.map(eval(func)))); + if (deleteCount) { + inp.splice(start, deleteCount, ...newElements); + expect(result).toBe(JSON.stringify(inp)); + } else { + inp.splice(start); + expect(result).toBe(JSON.stringify(inp)); } - - @TestCase([], "x => x > 1") - @TestCase([0, 1, 2, 3], "x => x > 1") - @TestCase([0, 1, 2, 3], "x => x < 3") - @TestCase([0, 1, 2, 3], "x => x < 0") - @TestCase([0, -1, -2, -3], "x => x < 0") - @TestCase([0, 1, 2, 3], "() => true") - @TestCase([0, 1, 2, 3], "() => false") - @Test("array.filter") - public filter(inp: T[], func: string): void - { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].filter(${func}))`); - - // Assert - Expect(result).toBe(JSON.stringify(inp.filter(eval(func)))); +}); + +test.each([ + { arr: [], args: [[]] }, + { arr: [1, 2, 3], args: [[]] }, + { arr: [1, 2, 3], args: [[4]] }, + { arr: [1, 2, 3], args: [[4, 5]] }, + { arr: [1, 2, 3], args: [[4, 5]] }, + { arr: [1, 2, 3], args: [4, [5]] }, + { arr: [1, 2, 3], args: [4, [5, 6]] }, + { arr: [1, 2, 3], args: [4, [5, 6], 7] }, + { arr: [1, 2, 3], args: ["test", [5, 6], 7, ["test1", "test2"]] }, + { arr: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, +])("array.concat (%p)", ({ arr, args }: { arr: any[]; args: any[] }) => { + const argStr = args.map(arg => JSON.stringify(arg)).join(","); + + const result = util.transpileAndExecute( + `let concatTestTable: any[] = ${JSON.stringify(arr)}; + return JSONStringify(concatTestTable.concat(${argStr}));`, + ); + + const concatArr = arr.concat(...args); + expect(result).toBe(JSON.stringify(concatArr)); +}); + +test.each([ + { inp: [], expected: "" }, + { inp: ["test1"], expected: "test1" }, + { inp: ["test1", "test2"], expected: "test1,test2" }, + { inp: ["test1", "test2"], expected: "test1;test2", seperator: ";" }, + { inp: ["test1", "test2"], expected: "test1test2", seperator: "" }, +])("array.join (%p)", ({ inp, expected, seperator }) => { + let seperatorLua; + if (seperator === "") { + seperatorLua = '""'; + } else if (seperator) { + seperatorLua = '"' + seperator + '"'; + } else { + seperatorLua = ""; } - - @TestCase([], "x => x > 1") - @TestCase([0, 1, 2, 3], "x => x > 1") - @TestCase([false, true, false], "x => x") - @TestCase([true, true, true], "x => x") - @Test("array.every") - public every(inp: T[], func: string): void - { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].every(${func}))`); - - // Assert - Expect(result).toBe(JSON.stringify(inp.every(eval(func)))); + const result = util.transpileAndExecute( + `let joinTestTable = ${JSON.stringify(inp)}; + return joinTestTable.join(${seperatorLua});`, + ); + + const joinedInp = inp.join(seperator); + expect(result).toBe(joinedInp); +}); + +test.each([ + { inp: [], element: "test1" }, + { inp: ["test1"], element: "test1" }, + { inp: ["test1", "test2"], element: "test2" }, + { inp: ["test1", "test2", "test3"], element: "test3", fromIndex: 1 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 2 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: -2 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 12 }, +])("array.indexOf (%p)", ({ inp, element, fromIndex }) => { + let str = `return ${JSON.stringify(inp)}.indexOf("${element}");`; + if (fromIndex) { + str = `return ${JSON.stringify(inp)}.indexOf("${element}", ${fromIndex});`; } - @TestCase([], "x => x > 1") - @TestCase([0, 1, 2, 3], "x => x > 1") - @TestCase([false, true, false], "x => x") - @TestCase([true, true, true], "x => x") - @Test("array.some") - public some(inp: T[], func: string): void - { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].some(${func}))`); + const result = util.transpileAndExecute(str); - // Assert - Expect(result).toBe(JSON.stringify(inp.some(eval(func)))); - } + // Account for lua indexing (-1) + expect(result).toBe(inp.indexOf(element, fromIndex)); +}); - @TestCase([], 1, 2) - @TestCase([0, 1, 2, 3], 1, 2) - @TestCase([0, 1, 2, 3], 1, 1) - @TestCase([0, 1, 2, 3], 1, -1) - @TestCase([0, 1, 2, 3], -3, -1) - @TestCase([0, 1, 2, 3, 4, 5], 1, 3) - @TestCase([0, 1, 2, 3, 4, 5], 3) - @Test("array.slice") - public slice(inp: T[], start: number, end?: number): void - { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`); - - // Assert - Expect(result).toBe(JSON.stringify(inp.slice(start, end))); - } - - @TestCase([], 0, 0, 9, 10, 11) - @TestCase([0, 1, 2, 3], 1, 0, 9, 10, 11) - @TestCase([0, 1, 2, 3], 2, 2, 9, 10, 11) - @TestCase([0, 1, 2, 3], 4, 1, 8, 9) - @TestCase([0, 1, 2, 3], 4, 0, 8, 9) - @TestCase([0, 1, 2, 3, 4, 5], 5, 9, 10, 11) - @TestCase([0, 1, 2, 3, 4, 5], 3, 2, 3, 4, 5) - @Test("array.splice[Insert]") - public spliceInsert(inp: T[], start: number, deleteCount: number, ...newElements: any[]): void - { +test.each([{ inp: [1, 2, 3], expected: 3 }, { inp: [1, 2, 3, 4, 5], expected: 3 }])( + "array.destructuring.simple (%p)", + ({ inp, expected }) => { const result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` + `let [x, y, z] = ${JSON.stringify(inp)} + return z;`, ); - // Assert - inp.splice(start, deleteCount, ...newElements); - Expect(result).toBe(JSON.stringify(inp)); - } + expect(result).toBe(expected); + }, +); - @TestCase([], 1, 1) - @TestCase([0, 1, 2, 3], 1, 1) - @TestCase([0, 1, 2, 3], 10, 1) - @TestCase([0, 1, 2, 3], 4) - @TestCase([0, 1, 2, 3, 4, 5], 3) - @TestCase([0, 1, 2, 3, 4, 5], 2, 2) - @TestCase([0, 1, 2, 3, 4, 5, 6, 7, 8], 5, 9, 10, 11) - @Test("array.splice[Remove]") - public spliceRemove(inp: T[], start: number, deleteCount?: number, ...newElements: any[]): void - { - let result; - if (deleteCount) { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` - ); - } else { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}); - return JSONStringify(spliceTestTable);` - ); - } +test.each([{ inp: [1] }, { inp: [1, 2, 3] }])("array.push (%p)", ({ inp }) => { + const result = util.transpileAndExecute( + `let testArray = [0]; + testArray.push(${inp.join(", ")}); + return JSONStringify(testArray);`, + ); - // Assert - if (deleteCount) { - inp.splice(start, deleteCount, ...newElements); - Expect(result).toBe(JSON.stringify(inp)); - } else { - inp.splice(start); - Expect(result).toBe(JSON.stringify(inp)); - } - } + expect(result).toBe(JSON.stringify([0].concat(inp))); +}); - @TestCase([], []) - @TestCase([1, 2, 3], []) - @TestCase([1, 2, 3], [4]) - @TestCase([1, 2, 3], [4, 5]) - @TestCase([1, 2, 3], [4, 5]) - @TestCase([1, 2, 3], 4, [5]) - @TestCase([1, 2, 3], 4, [5, 6]) - @TestCase([1, 2, 3], 4, [5, 6], 7) - @TestCase([1, 2, 3], "test", [5, 6], 7, ["test1", "test2"]) - @TestCase([1, 2, "test"], "test", ["test1", "test2"]) - @Test("array.concat") - public concat(arr: T[], ...args: T[]): void +test.each([ + { array: "[1, 2, 3]", expected: [3, 2] }, + { array: "[1, 2, 3, null]", expected: [3, 2] }, +])("array.pop (%p)", ({ array, expected }) => { { - const argStr = args.map(arg => JSON.stringify(arg)).join(","); - const result = util.transpileAndExecute( - `let concatTestTable: any[] = ${JSON.stringify(arr)}; - return JSONStringify(concatTestTable.concat(${argStr}));` - ); - - // Assert - const concatArr = arr.concat(...args); - Expect(result).toBe(JSON.stringify(concatArr)); - } - - @TestCase([], "") - @TestCase(["test1"], "test1") - @TestCase(["test1", "test2"], "test1,test2") - @TestCase(["test1", "test2"], "test1;test2", ";") - @TestCase(["test1", "test2"], "test1test2", "") - @Test("array.join") - public join(inp: T[], expected: string, seperator?: string): void { - let seperatorLua; - if (seperator === "") { - seperatorLua = "\"\""; - } else if (seperator) { - seperatorLua = "\"" + seperator + "\""; - } else { - seperatorLua = ""; - } - // Transpile/Execute - const result = util.transpileAndExecute( - `let joinTestTable = ${JSON.stringify(inp)}; - return joinTestTable.join(${seperatorLua});` + `let testArray = ${array}; + let val = testArray.pop(); + return val`, ); - // Assert - const joinedInp = inp.join(seperator); - Expect(result).toBe(joinedInp); - } - - @TestCase([], "test1") - @TestCase(["test1"], "test1") - @TestCase(["test1", "test2"], "test2") - @TestCase(["test1", "test2", "test3"], "test3", 1) - @TestCase(["test1", "test2", "test3"], "test1", 2) - @TestCase(["test1", "test2", "test3"], "test1", -2) - @TestCase(["test1", "test2", "test3"], "test1", 12) - @Test("array.indexOf") - public indexOf(inp: string[], element: string, fromIndex?: number): void - { - let str = `return ${JSON.stringify(inp)}.indexOf("${element}");`; - if (fromIndex) { - str = `return ${JSON.stringify(inp)}.indexOf("${element}", ${fromIndex});`; - } - - // Transpile/Execute - const result = util.transpileAndExecute(str); - - // Assert - // Account for lua indexing (-1) - Expect(result).toBe(inp.indexOf(element, fromIndex)); + expect(result).toBe(expected[0]); } - - @TestCase([1, 2, 3], 3) - @TestCase([1, 2, 3, 4, 5], 3) - @Test("array.destructuring.simple") - public arrayDestructuringSimple(inp: number[], expected: number): void { const result = util.transpileAndExecute( - `let [x, y, z] = ${JSON.stringify(inp)} - return z; - `); + `let testArray = ${array}; + testArray.pop(); + return testArray.length`, + ); - // Assert - Expect(result).toBe(expected); + expect(result).toBe(expected[1]); } - - @TestCase([1]) - @TestCase([1, 2, 3]) - @Test("array.push") - public arrayPush(inp: number[]): void +}); + +test.each([ + { array: "[1, 2, 3]", expected: [3, 2, 1] }, + { array: "[1, 2, 3, null]", expected: [3, 2, 1] }, + { array: "[1, 2, 3, 4]", expected: [4, 3, 2, 1] }, + { array: "[1]", expected: [1] }, + { array: "[]", expected: [] }, +])("array.reverse (%p)", ({ array, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + let val = testArray.reverse(); + return JSONStringify(testArray)`, + ); + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([ + { array: "[1, 2, 3]", expectedArray: [2, 3], expectedValue: 1 }, + { array: "[1]", expectedArray: [], expectedValue: 1 }, + { array: "[]", expectedArray: [], expectedValue: undefined }, +])("array.shift (%p)", ({ array, expectedArray, expectedValue }) => { { - const result = util.transpileAndExecute( - `let testArray = [0]; - testArray.push(${inp.join(", ")}); - return JSONStringify(testArray); - ` - ); - - // Assert - Expect(result).toBe(JSON.stringify([0].concat(inp))); - } - - @TestCase("[1, 2, 3]", [3, 2]) - @TestCase("[1, 2, 3, null]", [3, 2]) - @Test("array.pop") - public arrayPop(array: string, expected): void { + // test array mutation { const result = util.transpileAndExecute( `let testArray = ${array}; - let val = testArray.pop(); - return val`); - - // Assert - Expect(result).toBe(expected[0]); + let val = testArray.shift(); + return JSONStringify(testArray)`, + ); + expect(result).toBe(JSON.stringify(expectedArray)); } + // test return value { const result = util.transpileAndExecute( `let testArray = ${array}; - testArray.pop(); - return testArray.length`); + let val = testArray.shift(); + return val`, + ); - // Assert - Expect(result).toBe(expected[1]); + expect(result).toBe(expectedValue); } } - - @TestCase("[1, 2, 3]", [3, 2, 1]) - @TestCase("[1, 2, 3, null]", [3, 2, 1]) - @TestCase("[1, 2, 3, 4]", [4, 3, 2, 1]) - @TestCase("[1]", [1]) - @TestCase("[]", []) - @Test("array.reverse") - public arrayReverse(array: string, expected): void +}); + +test.each([ + { array: "[3, 4, 5]", toUnshift: [1, 2], expected: [1, 2, 3, 4, 5] }, + { array: "[]", toUnshift: [], expected: [] }, + { array: "[1]", toUnshift: [], expected: [1] }, + { array: "[]", toUnshift: [1], expected: [1] }, +])("array.unshift (%p)", ({ array, toUnshift, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + testArray.unshift(${toUnshift}); + return JSONStringify(testArray)`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([ + { array: "[4, 5, 3, 2, 1]", expected: [1, 2, 3, 4, 5] }, + { array: "[1]", expected: [1] }, + { array: "[1, null]", expected: [1] }, + { array: "[]", expected: [] }, +])("array.sort (%p)", ({ array, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + testArray.sort(); + return JSONStringify(testArray)`, + ); + + expect(result).toBe(JSON.stringify(expected)); +}); + +test.each([ + { array: [1, 2, 3, 4, 5], compareStr: "a - b", compareFn: (a: any, b: any) => a - b }, { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.reverse(); - return JSONStringify(testArray)`); - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @TestCase("[1, 2, 3]", [2, 3], 1) - @TestCase("[1]", [], 1) - @TestCase("[]", [], undefined) - @Test("array.shift") - public arrayShift(array: string, expectedArray: number[], expectedValue: number): void { - { - // test array mutation - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return JSONStringify(testArray)`); - // Assert - Expect(result).toBe(JSON.stringify(expectedArray)); - } - // test return value - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return val`); - - // Assert - Expect(result).toBe(expectedValue); - } - } - } - @TestCase("[3, 4, 5]", [1, 2], [1, 2, 3, 4, 5]) - @TestCase("[]", [], []) - @TestCase("[1]", [], [1]) - @TestCase("[]", [1], [1]) - @Test("array.unshift") - public arrayUnshift(array: string, toUnshift, expected): void + array: ["4", "5", "3", "2", "1"], + compareStr: "tonumber(a) - tonumber(b)", + compareFn: (a: any, b: any) => Number(a) - Number(b), + }, { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.unshift(${toUnshift}); - return JSONStringify(testArray)`); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); + array: ["4", "5", "3", "2", "1"], + compareStr: "tonumber(b) - tonumber(a)", + compareFn: (a: any, b: any) => Number(b) - Number(a), + }, +])("array.sort with compare function (%p)", ({ array, compareStr, compareFn }) => { + const result = util.transpileAndExecute( + `let testArray = ${JSON.stringify(array)}; + testArray.sort((a, b) => ${compareStr}); + return JSONStringify(testArray)`, + undefined, + undefined, + `declare function tonumber(this: void, e: any): number`, + ); + + expect(result).toBe(JSON.stringify(array.sort(compareFn))); +}); + +test.each([ + { condition: "true", lhs: "4", rhs: "5", expected: 4 }, + { condition: "false", lhs: "4", rhs: "5", expected: 5 }, + { condition: "3", lhs: "4", rhs: "5", expected: 4 }, +])("Ternary Conditional (%p)", ({ condition, lhs, rhs, expected }) => { + const result = util.transpileAndExecute(`return ${condition} ? ${lhs} : ${rhs};`); + + expect(result).toBe(expected); +}); + +test.each([ + { condition: "true", expected: 11 }, + { condition: "false", expected: 13 }, + { condition: "a < 4", expected: 13 }, + { condition: "a == 8", expected: 11 }, +])("Ternary Conditional Delayed (%p)", ({ condition, expected }) => { + const result = util.transpileAndExecute( + `let a = 3; + let delay = () => ${condition} ? a + 3 : a + 5; + a = 8; + return delay();`, + ); + + expect(result).toBe(expected); +}); + +test.each([ + { initial: "{a: 3}", parameters: "{}", expected: { a: 3 } }, + { initial: "{}", parameters: "{a: 3}", expected: { a: 3 } }, + { initial: "{a: 3}", parameters: "{a: 5}", expected: { a: 5 } }, + { initial: "{a: 3}", parameters: "{b: 5},{c: 7}", expected: { a: 3, b: 5, c: 7 } }, +])("Object.Assign (%p)", ({ initial, parameters, expected }) => { + const jsonResult = util.transpileAndExecute(` + return JSONStringify(Object.assign(${initial},${parameters})); + `); + + const result = JSON.parse(jsonResult); + for (const key in expected) { + expect(result[key]).toBe(expected[key]); } - - @TestCase("[4, 5, 3, 2, 1]", [1, 2, 3, 4, 5]) - @TestCase("[1]", [1]) - @TestCase("[1, null]", [1]) - @TestCase("[]", []) - @Test("array.sort") - public arraySort(array: string, expected): void - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.sort(); - return JSONStringify(testArray)`); - - // Assert - Expect(result).toBe(JSON.stringify(expected)); - } - - @Test("array.sort with compare function") - @TestCase([1, 2, 3, 4, 5], "a - b", (a: number, b: number) => a - b) - @TestCase(["4", "5", "3", "2", "1"], "tonumber(a) - tonumber(b)", (a: string, b: string) => Number(a) - Number(b)) - @TestCase(["4", "5", "3", "2", "1"], "tonumber(b) - tonumber(a)", (a: string, b: string) => Number(b) - Number(a)) - public arraySortWithCompareFunction( - array: any[], - compareStr: string, - compareFn: (a: any, b: any) => number - ): void { - const result = util.transpileAndExecute( - `let testArray = ${JSON.stringify(array)}; - testArray.sort((a, b) => ${compareStr}); - return JSONStringify(testArray)`, - undefined, - undefined, - `declare function tonumber(this: void, e: any): number` - ); - - // Assert - Expect(result).toBe(JSON.stringify(array.sort(compareFn))); - } - - @TestCase("true", "4", "5", 4) - @TestCase("false", "4", "5", 5) - @TestCase("3", "4", "5", 4) - @Test("Ternary Conditional") - public ternaryConditional(condition: string, lhs: string, rhs: string, expected: any): void - { - const result = util.transpileAndExecute(`return ${condition} ? ${lhs} : ${rhs};`); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase("true", 11) - @TestCase("false", 13) - @TestCase("a < 4", 13) - @TestCase("a == 8", 11) - @Test("Ternary Conditional Delayed") - public ternaryConditionalDelayed(condition: string, expected: any): void - { - const result = util.transpileAndExecute( - `let a = 3; - let delay = () => ${condition} ? a + 3 : a + 5; - a = 8; - return delay();`); - - // Assert - Expect(result).toBe(expected); - } - - @TestCase("{a: 3}", "{}", {a : 3}) - @TestCase("{}", "{a: 3}", {a : 3}) - @TestCase("{a: 3}", "{a: 5}", {a : 5}) - @TestCase("{a: 3}", "{b: 5},{c: 7}", {a : 3, b: 5, c: 7}) - @Test("Object.Assign") - public objectAssign(initial: string, parameters: string, expected: object): void { - const jsonResult = util.transpileAndExecute(` - return JSONStringify(Object.assign(${initial},${parameters})); - `); - - const result = JSON.parse(jsonResult); - for (const key in expected) { - Expect(result[key]).toBe(expected[key]); - } - } - - @TestCase("{}", []) - @TestCase("{abc: 3}", ["abc,3"]) - @TestCase("{abc: 3, def: 'xyz'}", ["abc,3", "def,xyz"]) - @Test("Object.entries") - public objectEntries(obj: string, expected: string[]): void { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.entries(obj).map(e => e.join(",")).join(";"); - `, {target: ts.ScriptTarget.ES2018, lib: ["es2018"], luaLibImport: LuaLibImportKind.Require}) as string; - - const foundKeys = result.split(";"); - if (expected.length === 0) { - Expect(foundKeys.length).toBe(1); - Expect(foundKeys[0]).toBe(""); - } else { - Expect(foundKeys.length).toBe(expected.length); - for (const key of expected) { - Expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); - } +}); + +test.each([ + { obj: "{}", expected: [] }, + { obj: "{abc: 3}", expected: ["abc,3"] }, + { obj: "{abc: 3, def: 'xyz'}", expected: ["abc,3", "def,xyz"] }, +])("Object.entries (%p)", ({ obj, expected }) => { + const result = util.transpileAndExecute(` + const obj = ${obj}; + return Object.entries(obj).map(e => e.join(",")).join(";"); + `) as string; + + const foundKeys = result.split(";"); + if (expected.length === 0) { + expect(foundKeys.length).toBe(1); + expect(foundKeys[0]).toBe(""); + } else { + expect(foundKeys.length).toBe(expected.length); + for (const key of expected) { + expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); } } - - @TestCase("{}", []) - @TestCase("{abc: 3}", ["abc"]) - @TestCase("{abc: 3, def: 'xyz'}", ["abc", "def"]) - @Test("Object.keys") - public objectKeys(obj: string, expected: string[]): void { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.keys(obj).join(","); - `) as string; - - const foundKeys = result.split(","); - if (expected.length === 0) { - Expect(foundKeys.length).toBe(1); - Expect(foundKeys[0]).toBe(""); - } else { - Expect(foundKeys.length).toBe(expected.length); - for (const key of expected) { - Expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); - } +}); + +test.each([ + { obj: "{}", expected: [] }, + { obj: "{abc: 3}", expected: ["abc"] }, + { obj: "{abc: 3, def: 'xyz'}", expected: ["abc", "def"] }, +])("Object.keys (%p)", ({ obj, expected }) => { + const result = util.transpileAndExecute(` + const obj = ${obj}; + return Object.keys(obj).join(","); + `) as string; + + const foundKeys = result.split(","); + if (expected.length === 0) { + expect(foundKeys.length).toBe(1); + expect(foundKeys[0]).toBe(""); + } else { + expect(foundKeys.length).toBe(expected.length); + for (const key of expected) { + expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); } } - - @TestCase("{}", []) - @TestCase("{abc: 'def'}", ["def"]) - @TestCase("{abc: 3, def: 'xyz'}", ["3", "xyz"]) - @Test("Object.values") - public objectValues(obj: string, expected: string[]): void { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.values(obj).join(","); - `, {target: ts.ScriptTarget.ES2018, lib: ["es2018"], luaLibImport: LuaLibImportKind.Require}) as string; - - const foundValues = result.split(","); - if (expected.length === 0) { - Expect(foundValues.length).toBe(1); - Expect(foundValues[0]).toBe(""); - } else { - Expect(foundValues.length).toBe(expected.length); - for (const key of expected) { - Expect(foundValues.indexOf(key) >= 0).toBeTruthy(); - } +}); + +test.each([ + { obj: "{}", expected: [] }, + { obj: "{abc: 'def'}", expected: ["def"] }, + { obj: "{abc: 3, def: 'xyz'}", expected: ["3", "xyz"] }, +])("Object.values (%p)", ({ obj, expected }) => { + const result = util.transpileAndExecute(` + const obj = ${obj}; + return Object.values(obj).join(","); + `) as string; + + const foundValues = result.split(","); + if (expected.length === 0) { + expect(foundValues.length).toBe(1); + expect(foundValues[0]).toBe(""); + } else { + expect(foundValues.length).toBe(expected.length); + for (const key of expected) { + expect(foundValues.indexOf(key) >= 0).toBeTruthy(); } } -} +}); diff --git a/test/unit/lualib/map.spec.ts b/test/unit/lualib/map.spec.ts index 20e85c344..149ee258f 100644 --- a/test/unit/lualib/map.spec.ts +++ b/test/unit/lualib/map.spec.ts @@ -1,169 +1,149 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../../src/util"; - -export class MapTests { - @Test("map constructor") - public mapConstructor(): void - { - const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`); - - Expect(result).toBe(0); - } - - @Test("map iterable constructor") - public mapIterableConstructor(): void - { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); - return mymap.has("a") && mymap.has("b");`); - - Expect(result).toBe(true); - } - - @Test("map iterable constructor map") - public mapIterableConstructor2(): void - { - const result = util.transpileAndExecute(`let mymap = new Map(new Map([["a", "c"],["b", "d"]])); - return mymap.has("a") && mymap.has("b");`); - - Expect(result).toBe(true); - } - - @Test("map clear") - public mapClear(): void - { - const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();`; - const size = util.transpileAndExecute(mapTS + `return mymap.size;`); - Expect(size).toBe(0); - - const contains = util.transpileAndExecute(mapTS + `return !mymap.has("a") && !mymap.has("b");`); - Expect(contains).toBe(true); - } - - @Test("map delete") - public mapDelete(): void - { - const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");`; - const contains = util.transpileAndExecute(mapTS + `return mymap.has("b") && !mymap.has("a");`); - Expect(contains).toBe(true); - } - - @Test("map entries") - public mapEntries(): void - { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - for (var [key, value] of mymap.entries()) { count += key + value; } - return count;` - ); - Expect(result).toBe(27); - } - - @Test("map foreach") - public mapForEach(): void - { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); - let count = 0; - mymap.forEach(i => count += i); - return count;` - ); - - Expect(result).toBe(9); - } - - @Test("map foreach keys") - public mapForEachKeys(): void - { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - mymap.forEach((value, key) => { count += key; }); - return count;` - ); - - Expect(result).toBe(18); - } - - @Test("map get") - public mapGet(): void - { - const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");`); - - Expect(result).toBe("c"); - } - - @Test("map get missing") - public mapGetMissing(): void - { - const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");`); - Expect(result).toBe(undefined); - } - - @Test("map has") - public mapHas(): void - { - const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has("a");`); - Expect(contains).toBe(true); - } - - @Test("map has false") - public mapHasFalse(): void - { - const contains = util.transpileAndExecute(`let mymap = new Map(); return mymap.has("a");`); - Expect(contains).toBe(false); - } - - @Test("map has null") - public mapHasNull(): void - { - const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has(null);`); - Expect(contains).toBe(false); - } - - @Test("map keys") - public mapKeys(): void - { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - for (var key of mymap.keys()) { count += key; } - return count;` - ); - - Expect(result).toBe(18); - } - - @Test("map set") - public mapSet(): void - { - const mapTS = `let mymap = new Map(); mymap.set("a", 5);`; - const has = util.transpileAndExecute(mapTS + `return mymap.has("a");`); - Expect(has).toBe(true); - - const value = util.transpileAndExecute(mapTS + `return mymap.get("a")`); - Expect(value).toBe(5); - } - - @Test("map values") - public mapValues(): void { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - for (var value of mymap.values()) { count += value; } - return count;` - ); - - Expect(result).toBe(9); - } - - @Test("map size") - public mapSize(): void { - Expect(util.transpileAndExecute(`let m = new Map(); return m.size;`)).toBe(0); - Expect(util.transpileAndExecute(`let m = new Map(); m.set(1,3); return m.size;`)).toBe(1); - Expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); return m.size;`)).toBe(2); - Expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`)).toBe(0); - Expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`)).toBe(1); - } -} +import * as util from "../../util"; + +test("map constructor", () => { + const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`); + + expect(result).toBe(0); +}); + +test("map iterable constructor", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.has("a") && mymap.has("b");`, + ); + + expect(result).toBe(true); +}); + +test("map iterable constructor map", () => { + const result = util.transpileAndExecute(` + let mymap = new Map(new Map([["a", "c"],["b", "d"]])); + return mymap.has("a") && mymap.has("b"); + `); + + expect(result).toBe(true); +}); + +test("map clear", () => { + const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();`; + const size = util.transpileAndExecute(mapTS + `return mymap.size;`); + expect(size).toBe(0); + + const contains = util.transpileAndExecute(mapTS + `return !mymap.has("a") && !mymap.has("b");`); + expect(contains).toBe(true); +}); + +test("map delete", () => { + const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");`; + const contains = util.transpileAndExecute(mapTS + `return mymap.has("b") && !mymap.has("a");`); + expect(contains).toBe(true); +}); + +test("map entries", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + let count = 0; + for (var [key, value] of mymap.entries()) { count += key + value; } + return count;`, + ); + expect(result).toBe(27); +}); + +test("map foreach", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); + let count = 0; + mymap.forEach(i => count += i); + return count;`, + ); + + expect(result).toBe(9); +}); + +test("map foreach keys", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + let count = 0; + mymap.forEach((value, key) => { count += key; }); + return count;`, + ); + + expect(result).toBe(18); +}); + +test("map get", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");`, + ); + + expect(result).toBe("c"); +}); + +test("map get missing", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");`, + ); + expect(result).toBe(undefined); +}); + +test("map has", () => { + const contains = util.transpileAndExecute( + `let mymap = new Map([["a", "c"]]); return mymap.has("a");`, + ); + expect(contains).toBe(true); +}); + +test("map has false", () => { + const contains = util.transpileAndExecute(`let mymap = new Map(); return mymap.has("a");`); + expect(contains).toBe(false); +}); + +test("map has null", () => { + const contains = util.transpileAndExecute( + `let mymap = new Map([["a", "c"]]); return mymap.has(null);`, + ); + expect(contains).toBe(false); +}); + +test("map keys", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + let count = 0; + for (var key of mymap.keys()) { count += key; } + return count;`, + ); + + expect(result).toBe(18); +}); + +test("map set", () => { + const mapTS = `let mymap = new Map(); mymap.set("a", 5);`; + const has = util.transpileAndExecute(mapTS + `return mymap.has("a");`); + expect(has).toBe(true); + + const value = util.transpileAndExecute(mapTS + `return mymap.get("a")`); + expect(value).toBe(5); +}); + +test("map values", () => { + const result = util.transpileAndExecute( + `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + let count = 0; + for (var value of mymap.values()) { count += value; } + return count;`, + ); + + expect(result).toBe(9); +}); + +test("map size", () => { + expect(util.transpileAndExecute(`let m = new Map(); return m.size;`)).toBe(0); + expect(util.transpileAndExecute(`let m = new Map(); m.set(1,3); return m.size;`)).toBe(1); + expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); return m.size;`)).toBe(2); + expect( + util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`), + ).toBe(0); + expect( + util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`), + ).toBe(1); +}); diff --git a/test/unit/lualib/set.spec.ts b/test/unit/lualib/set.spec.ts index 954ee06b8..1fce6ceb7 100644 --- a/test/unit/lualib/set.spec.ts +++ b/test/unit/lualib/set.spec.ts @@ -1,152 +1,130 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../../src/util"; - -export class SetTests { - @Test("set constructor") - public setConstructor(): void - { - const result = util.transpileAndExecute(`let myset = new Set(); return myset.size;`); - - Expect(result).toBe(0); - } - - @Test("set iterable constructor") - public setIterableConstructor(): void - { - const result = util.transpileAndExecute( - `let myset = new Set(["a", "b"]); - return myset.has("a") || myset.has("b");`); - - Expect(result).toBe(true); - } - - @Test("set iterable constructor set") - public setIterableConstructorSet(): void - { - const result = util.transpileAndExecute( - `let myset = new Set(new Set(["a", "b"])); - return myset.has("a") || myset.has("b");`); - - Expect(result).toBe(true); - } - - @Test("set add") - public setAdd(): void - { - const has = util.transpileAndExecute(`let myset = new Set(); myset.add("a"); return myset.has("a");`); - Expect(has).toBe(true); - } - - @Test("set clear") - public setClear(): void - { - const setTS = `let myset = new Set(["a", "b"]); myset.clear();`; - const size = util.transpileAndExecute(setTS + `return myset.size;`); - Expect(size).toBe(0); - - const contains = util.transpileAndExecute(setTS + `return !myset.has("a") && !myset.has("b");`); - Expect(contains).toBe(true); - } - - @Test("set delete") - public setDelete(): void - { - const setTS = `let myset = new Set(["a", "b"]); myset.delete("a");`; - const contains = util.transpileAndExecute(setTS + `return myset.has("b") && !myset.has("a");`); - Expect(contains).toBe(true); - } - - @Test("set entries") - public setEntries(): void - { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var [key, value] of myset.entries()) { count += key + value; } - return count;` - ); - - Expect(result).toBe(36); - } - - @Test("set foreach") - public setForEach(): void - { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach(i => { count += i; }); - return count;` - ); - Expect(result).toBe(9); - } - - @Test("set foreach keys") - public setForEachKeys(): void - { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach((value, key) => { count += key; }); - return count;` - ); - - Expect(result).toBe(9); - } - - @Test("set has") - public setHas(): void - { - const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has("a");`); - Expect(contains).toBe(true); - } - - @Test("set has false") - public setHasFalse(): void - { - const contains = util.transpileAndExecute(`let myset = new Set(); return myset.has("a");`); - Expect(contains).toBe(false); - } - - @Test("set has null") - public setHasNull(): void - { - const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has(null);`); - Expect(contains).toBe(false); - } - - @Test("set keys") - public setKeys(): void - { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var key of myset.keys()) { count += key; } - return count;` - ); - - Expect(result).toBe(18); - } - - @Test("set values") - public setValues(): void - { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var value of myset.values()) { count += value; } - return count;` - ); - - Expect(result).toBe(18); - } - - @Test("set size") - public setSize(): void { - Expect(util.transpileAndExecute(`let m = new Set(); return m.size;`)).toBe(0); - Expect(util.transpileAndExecute(`let m = new Set(); m.add(1); return m.size;`)).toBe(1); - Expect(util.transpileAndExecute(`let m = new Set([1, 2]); return m.size;`)).toBe(2); - Expect(util.transpileAndExecute(`let m = new Set([1, 2]); m.clear(); return m.size;`)).toBe(0); - Expect(util.transpileAndExecute(`let m = new Set([1, 2]); m.delete(2); return m.size;`)).toBe(1); - } -} +import * as util from "../../util"; + +test("set constructor", () => { + const result = util.transpileAndExecute(`let myset = new Set(); return myset.size;`); + + expect(result).toBe(0); +}); + +test("set iterable constructor", () => { + const result = util.transpileAndExecute( + `let myset = new Set(["a", "b"]); + return myset.has("a") || myset.has("b");`, + ); + + expect(result).toBe(true); +}); + +test("set iterable constructor set", () => { + const result = util.transpileAndExecute( + `let myset = new Set(new Set(["a", "b"])); + return myset.has("a") || myset.has("b");`, + ); + + expect(result).toBe(true); +}); + +test("set add", () => { + const has = util.transpileAndExecute( + `let myset = new Set(); myset.add("a"); return myset.has("a");`, + ); + expect(has).toBe(true); +}); + +test("set clear", () => { + const setTS = `let myset = new Set(["a", "b"]); myset.clear();`; + const size = util.transpileAndExecute(setTS + `return myset.size;`); + expect(size).toBe(0); + + const contains = util.transpileAndExecute(setTS + `return !myset.has("a") && !myset.has("b");`); + expect(contains).toBe(true); +}); + +test("set delete", () => { + const setTS = `let myset = new Set(["a", "b"]); myset.delete("a");`; + const contains = util.transpileAndExecute(setTS + `return myset.has("b") && !myset.has("a");`); + expect(contains).toBe(true); +}); + +test("set entries", () => { + const result = util.transpileAndExecute( + `let myset = new Set([5, 6, 7]); + let count = 0; + for (var [key, value] of myset.entries()) { count += key + value; } + return count;`, + ); + + expect(result).toBe(36); +}); + +test("set foreach", () => { + const result = util.transpileAndExecute( + `let myset = new Set([2, 3, 4]); + let count = 0; + myset.forEach(i => { count += i; }); + return count;`, + ); + expect(result).toBe(9); +}); + +test("set foreach keys", () => { + const result = util.transpileAndExecute( + `let myset = new Set([2, 3, 4]); + let count = 0; + myset.forEach((value, key) => { count += key; }); + return count;`, + ); + + expect(result).toBe(9); +}); + +test("set has", () => { + const contains = util.transpileAndExecute( + `let myset = new Set(["a", "c"]); return myset.has("a");`, + ); + expect(contains).toBe(true); +}); + +test("set has false", () => { + const contains = util.transpileAndExecute(`let myset = new Set(); return myset.has("a");`); + expect(contains).toBe(false); +}); + +test("set has null", () => { + const contains = util.transpileAndExecute( + `let myset = new Set(["a", "c"]); return myset.has(null);`, + ); + expect(contains).toBe(false); +}); + +test("set keys", () => { + const result = util.transpileAndExecute( + `let myset = new Set([5, 6, 7]); + let count = 0; + for (var key of myset.keys()) { count += key; } + return count;`, + ); + + expect(result).toBe(18); +}); + +test("set values", () => { + const result = util.transpileAndExecute( + `let myset = new Set([5, 6, 7]); + let count = 0; + for (var value of myset.values()) { count += value; } + return count;`, + ); + + expect(result).toBe(18); +}); + +test.each([ + { code: `let m = new Set(); return m.size;`, expected: 0 }, + { code: `let m = new Set(); m.add(1); return m.size;`, expected: 1 }, + { code: `let m = new Set([1, 2]); return m.size;`, expected: 2 }, + { code: `let m = new Set([1, 2]); m.clear(); return m.size;`, expected: 0 }, + { code: `let m = new Set([1, 2]); m.delete(2); return m.size;`, expected: 1 }, +])("set size (%p)", ({ code, expected }) => { + expect(util.transpileAndExecute(code)).toBe(expected); +}); diff --git a/test/unit/lualib/symbol.spec.ts b/test/unit/lualib/symbol.spec.ts index a15b79664..51be6c70e 100644 --- a/test/unit/lualib/symbol.spec.ts +++ b/test/unit/lualib/symbol.spec.ts @@ -1,89 +1,66 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../../src/util"; -import { CompilerOptions, LuaLibImportKind } from '../../../src/CompilerOptions'; +import * as util from "../../util"; -export class SymbolTests { - private compilerOptions: CompilerOptions = { - lib: ["esnext"], - luaLibImport: LuaLibImportKind.Require, - }; - - @Test("symbol.toString()") - @TestCase() - @TestCase(1) - @TestCase("name") - public symbolToString(description?: string | number): void - { +test.each([{}, { description: 1 }, { description: "name" }])( + "symbol.toString() (%p)", + ({ description }) => { const result = util.transpileAndExecute(` return Symbol(${JSON.stringify(description)}).toString(); - `, this.compilerOptions); + `); - Expect(result).toBe(`Symbol(${description || ''})`); - } + expect(result).toBe(`Symbol(${description || ""})`); + }, +); - @Test("symbol.description") - @TestCase() - @TestCase(1) - @TestCase("name") - public symbolDescription(description?: string | number): void - { +test.each([{}, { description: 1 }, { description: "name" }])( + "symbol.description (%p)", + ({ description }) => { const result = util.transpileAndExecute(` return Symbol(${JSON.stringify(description)}).description; - `, this.compilerOptions); + `); - Expect(result).toBe(description); - } + expect(result).toBe(description); + }, +); - @Test("symbol uniqueness") - public symbolUniqueness(): void - { - const result = util.transpileAndExecute(` - return Symbol("a") === Symbol("a"); - `); +test("symbol uniqueness", () => { + const result = util.transpileAndExecute(` + return Symbol("a") === Symbol("a"); + `); - Expect(result).toBe(false); - } + expect(result).toBe(false); +}); - @Test("Symbol.for") - public symbolFor(): void - { - const result = util.transpileAndExecute(` - return Symbol.for("name").description; - `, this.compilerOptions); +test("Symbol.for", () => { + const result = util.transpileAndExecute(` + return Symbol.for("name").description; + `); - Expect(result).toBe("name"); - } + expect(result).toBe("name"); +}); - @Test("Symbol.for non-uniqueness") - public symbolForNonUniqueness(): void - { - const result = util.transpileAndExecute(` - return Symbol.for("a") === Symbol.for("a"); - `); +test("Symbol.for non-uniqueness", () => { + const result = util.transpileAndExecute(` + return Symbol.for("a") === Symbol.for("a"); + `); - Expect(result).toBe(true); - } + expect(result).toBe(true); +}); - @Test("Symbol.keyFor") - public symbolKeyFor(): void - { - const result = util.transpileAndExecute(` - const sym = Symbol.for("a"); - Symbol.for("b"); - return Symbol.keyFor(sym); - `); +test("Symbol.keyFor", () => { + const result = util.transpileAndExecute(` + const sym = Symbol.for("a"); + Symbol.for("b"); + return Symbol.keyFor(sym); + `); - Expect(result).toBe("a"); - } + expect(result).toBe("a"); +}); - @Test("Symbol.keyFor empty") - public symbolKeyForEmpty(): void - { - const result = util.transpileAndExecute(` - Symbol.for("a"); - return Symbol.keyFor(Symbol()); - `); +test("Symbol.keyFor empty", () => { + const result = util.transpileAndExecute(` + Symbol.for("a"); + return Symbol.keyFor(Symbol()); + `); - Expect(result).toBe(undefined); - } -} + expect(result).toBe(undefined); +}); diff --git a/test/unit/lualib/weakMap.spec.ts b/test/unit/lualib/weakMap.spec.ts index d9e829778..51b5df8d8 100644 --- a/test/unit/lualib/weakMap.spec.ts +++ b/test/unit/lualib/weakMap.spec.ts @@ -1,134 +1,122 @@ -import { Expect, Test } from "alsatian"; -import * as util from "../../src/util"; - -export class WeakMapTests { - private initRefsTs = `let ref = {}; - let ref2 = () => {};`; - - @Test("weakMap constructor") - public weakMapConstructor(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, 1]]); - return mymap.get(ref); - `); - - Expect(result).toBe(1); - } - - @Test("weakMap iterable constructor") - public weakMapIterableConstructor(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, 1], [ref2, 2]]); - return mymap.has(ref) && mymap.has(ref2); - `); - - Expect(result).toBe(true); - } - - @Test("weakMap iterable constructor map") - public weakMapIterableConstructor2(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap(new Map([[ref, 1], [ref2, 2]])); - return mymap.has(ref) && mymap.has(ref2); - `); - - Expect(result).toBe(true); - } - - @Test("weakMap delete") - public weakMapDelete(): void - { - const contains = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, true], [ref2, true]]); - mymap.delete(ref2); - return mymap.has(ref) && !mymap.has(ref2); - `); - - Expect(contains).toBe(true); - } - - @Test("weakMap get") - public weakMapGet(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, 1], [{}, 2]]); - return mymap.get(ref); - `); - - Expect(result).toBe(1); - } - - @Test("weakMap get missing") - public weakMapGetMissing(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[{}, true]]); - return mymap.get({}); - `); - - Expect(result).toBe(undefined); - } - - @Test("weakMap has") - public weakMapHas(): void - { - const contains = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, true]]); - return mymap.has(ref); - `); - - Expect(contains).toBe(true); - } - - @Test("weakMap has false") - public weakMapHasFalse(): void - { - const contains = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[ref, true]]); - return mymap.has(ref2); - `); - - Expect(contains).toBe(false); - } - - @Test("weakMap has null") - public weakMapHasNull(): void - { - const contains = util.transpileAndExecute(this.initRefsTs + ` - let mymap = new WeakMap([[{}, true]]); - return mymap.has(null); - `); - - Expect(contains).toBe(false); - } - - @Test("weakMap set") - public weakMapSet(): void - { - const init = this.initRefsTs + ` - let mymap = new WeakMap(); - mymap.set(ref, 5); - `; - - const has = util.transpileAndExecute(init + `return mymap.has(ref);`); - Expect(has).toBe(true); - - const value = util.transpileAndExecute(init + `return mymap.get(ref)`); - Expect(value).toBe(5); - } - - @Test("weakMap has no map features") - public weakMapHasNoMapFeatures(): void - { - const transpileAndExecute = (tsStr: string) => util.transpileAndExecute(tsStr, undefined, undefined, undefined, true); - Expect(transpileAndExecute(`return new WeakMap().size`)).toBe(undefined); - Expect(() => transpileAndExecute(`new WeakMap().clear()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakMap().keys()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakMap().values()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakMap().entries()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakMap().forEach(() => {})`)).toThrow(); - } -} +import * as util from "../../util"; + +const initRefsTs = ` + let ref = {}; + let ref2 = () => {}; +`; + +test("weakMap constructor", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, 1]]); + return mymap.get(ref); + `); + + expect(result).toBe(1); +}); + +test("weakMap iterable constructor", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, 1], [ref2, 2]]); + return mymap.has(ref) && mymap.has(ref2); + `); + + expect(result).toBe(true); +}); + +test("weakMap iterable constructor map", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap(new Map([[ref, 1], [ref2, 2]])); + return mymap.has(ref) && mymap.has(ref2); + `); + + expect(result).toBe(true); +}); + +test("weakMap delete", () => { + const contains = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, true], [ref2, true]]); + mymap.delete(ref2); + return mymap.has(ref) && !mymap.has(ref2); + `); + + expect(contains).toBe(true); +}); + +test("weakMap get", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, 1], [{}, 2]]); + return mymap.get(ref); + `); + + expect(result).toBe(1); +}); + +test("weakMap get missing", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[{}, true]]); + return mymap.get({}); + `); + + expect(result).toBe(undefined); +}); + +test("weakMap has", () => { + const contains = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, true]]); + return mymap.has(ref); + `); + + expect(contains).toBe(true); +}); + +test("weakMap has false", () => { + const contains = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[ref, true]]); + return mymap.has(ref2); + `); + + expect(contains).toBe(false); +}); + +test("weakMap has null", () => { + const contains = util.transpileAndExecute(` + ${initRefsTs} + let mymap = new WeakMap([[{}, true]]); + return mymap.has(null); + `); + + expect(contains).toBe(false); +}); + +test("weakMap set", () => { + const init = ` + ${initRefsTs} + let mymap = new WeakMap(); + mymap.set(ref, 5); + `; + + const has = util.transpileAndExecute(init + `return mymap.has(ref);`); + expect(has).toBe(true); + + const value = util.transpileAndExecute(init + `return mymap.get(ref)`); + expect(value).toBe(5); +}); + +test("weakMap has no map features (size)", () => { + expect(util.transpileAndExecute(`return (new WeakMap() as any).size`)).toBe(undefined); +}); + +test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( + "weakMap has no map features (%p)", + call => { + expect(() => util.transpileAndExecute(`(new WeakMap() as any).${call}`)).toThrow(); + }, +); diff --git a/test/unit/lualib/weakSet.spec.ts b/test/unit/lualib/weakSet.spec.ts index e4425618e..1b50a4756 100644 --- a/test/unit/lualib/weakSet.spec.ts +++ b/test/unit/lualib/weakSet.spec.ts @@ -1,87 +1,79 @@ -import { Expect, Test } from "alsatian"; -import * as util from "../../src/util"; +import * as util from "../../util"; -export class WeakSetTests { - private initRefsTs = `let ref = {}; - let ref2 = () => {};`; +const initRefsTs = ` + let ref = {}; + let ref2 = () => {}; +`; - @Test("weakSet constructor") - public weakSetConstructor(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet([ref]); - return myset.has(ref) - `); +test("weakSet constructor", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet([ref]); + return myset.has(ref) + `); - Expect(result).toBe(true); - } + expect(result).toBe(true); +}); - @Test("weakSet iterable constructor") - public weakSetIterableConstructor(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet([ref, ref2]); - return myset.has(ref) && myset.has(ref2); - `); +test("weakSet iterable constructor", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet([ref, ref2]); + return myset.has(ref) && myset.has(ref2); + `); - Expect(result).toBe(true); - } + expect(result).toBe(true); +}); - @Test("weakSet iterable constructor set") - public weakSetIterableConstructorSet(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet(new Set([ref, ref2])); - return myset.has(ref) && myset.has(ref2); - `); +test("weakSet iterable constructor set", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet(new Set([ref, ref2])); + return myset.has(ref) && myset.has(ref2); + `); - Expect(result).toBe(true); - } + expect(result).toBe(true); +}); - @Test("weakSet add") - public weakSetAdd(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet(); - myset.add(ref); - return myset.has(ref); - `); +test("weakSet add", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet(); + myset.add(ref); + return myset.has(ref); + `); - Expect(result).toBe(true); - } + expect(result).toBe(true); +}); - @Test("weakSet add different references") - public weakSetAddDifferentReferences(): void - { - const result = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet(); - myset.add({}); - return myset.has({}); - `); +test("weakSet add different references", () => { + const result = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet(); + myset.add({}); + return myset.has({}); + `); - Expect(result).toBe(false); - } + expect(result).toBe(false); +}); - @Test("weakSet delete") - public weakSetDelete(): void - { - const contains = util.transpileAndExecute(this.initRefsTs + ` - let myset = new WeakSet([ref, ref2]); - myset.delete(ref); - return myset.has(ref2) && !myset.has(ref); - `); - Expect(contains).toBe(true); - } +test("weakSet delete", () => { + const contains = util.transpileAndExecute(` + ${initRefsTs} + let myset = new WeakSet([ref, ref2]); + myset.delete(ref); + return myset.has(ref2) && !myset.has(ref); + `); + expect(contains).toBe(true); +}); - @Test("weakSet has no set features") - public weakSetHasNoSetFeatures(): void - { - const transpileAndExecute = (tsStr: string) => util.transpileAndExecute(tsStr, undefined, undefined, undefined, true); - Expect(transpileAndExecute(`return new WeakSet().size`)).toBe(undefined); - Expect(() => transpileAndExecute(`new WeakSet().clear()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakSet().keys()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakSet().values()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakSet().entries()`)).toThrow(); - Expect(() => transpileAndExecute(`new WeakSet().forEach(() => {})`)).toThrow(); - } -} +test("weakSet has no set features (size)", () => { + expect(util.transpileAndExecute(`return (new WeakSet() as any).size`)).toBe(undefined); +}); + +test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( + "weakSet has no set features (%p)", + call => { + expect(() => util.transpileAndExecute(`(new WeakSet() as any).${call}`)).toThrow(); + }, +); diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index ad9047553..f44429f7f 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -1,258 +1,253 @@ -import { Expect, Test, TestCase, IgnoreTest } from "alsatian"; -import * as util from "../src/util"; +import * as util from "../util"; -export class MathTests { +test.each([ + { inp: "Math.cos()", expected: "math.cos();" }, + { inp: "Math.sin()", expected: "math.sin();" }, + { inp: "Math.min()", expected: "math.min();" }, + { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3);" }, + { inp: "Math.log2(3)", expected: `(math.log(3) / ${Math.LN2});` }, + { inp: "Math.log10(3)", expected: `(math.log(3) / ${Math.LN10});` }, + { inp: "Math.log1p(3)", expected: "math.log(1 + 3);" }, + { inp: "Math.round(3.3)", expected: "math.floor(3.3 + 0.5);" }, + { inp: "Math.PI", expected: "math.pi;" }, +])("Math (%p)", ({ inp, expected }) => { + const lua = util.transpileString(inp); - // Dont test all and dont do functional test - // because math implementations may differ between js and lua - @TestCase("Math.cos()", "math.cos();") - @TestCase("Math.sin()", "math.sin();") - @TestCase("Math.min()", "math.min();") - @TestCase("Math.atan2(2, 3)", "math.atan(2 / 3);") - @TestCase("Math.log2(3)", `(math.log(3) / ${Math.LN2});`) - @TestCase("Math.log10(3)", `(math.log(3) / ${Math.LN10});`) - @TestCase("Math.log1p(3)", "math.log(1 + 3);") - @TestCase("Math.round(3.3)", "math.floor(3.3 + 0.5);") - @TestCase("Math.PI", "math.pi;") - @Test("Math") - public math(inp: string, expected: string): void { - // Transpile - const lua = util.transpileString(inp); + expect(lua).toBe(expected); +}); - // Assert - Expect(lua).toBe(expected); - } - - @TestCase("E") - @TestCase("LN10") - @TestCase("LN2") - @TestCase("LOG10E") - @TestCase("LOG2E") - @TestCase("SQRT1_2") - @TestCase("SQRT2") - @Test("Math constant") - public mathConstant(constant: string): void { +test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])( + "Math constant (%p)", + constant => { const epsilon = 0.000001; const code = `return Math.abs(Math.${constant} - ${Math[constant]}) <= ${epsilon}`; - Expect(util.transpileAndExecute(code)).toBe(true); - } + expect(util.transpileAndExecute(code)).toBe(true); + }, +); - @TestCase("++x", "x=4;y=6") - @TestCase("x++", "x=4;y=6") - @TestCase("--x", "x=2;y=6") - @TestCase("x--", "x=2;y=6") - @TestCase("x += y", "x=9;y=6") - @TestCase("x -= y", "x=-3;y=6") - @TestCase("x *= y", "x=18;y=6") - @TestCase("y /= x", "x=3;y=2.0") - @TestCase("y %= x", "x=3;y=0") - @TestCase("y **= x", "x=3;y=216.0") - @TestCase("x |= y", "x=7;y=6") - @TestCase("x &= y", "x=2;y=6") - @TestCase("x ^= y", "x=5;y=6") - @TestCase("x <<= y", "x=192;y=6") - @TestCase("x >>>= y", "x=0;y=6") - @Test("Operator assignment statements") - public opAssignmentStatement(statement: string, expected: string): void { - const result = util.transpileAndExecute( - `let x = 3; - let y = 6; - ${statement}; - return \`x=\${x};y=\${y}\``); - Expect(result).toBe(expected); - } +test.each([ + { statement: "++x", expected: "x=4;y=6" }, + { statement: "x++", expected: "x=4;y=6" }, + { statement: "--x", expected: "x=2;y=6" }, + { statement: "x--", expected: "x=2;y=6" }, + { statement: "x += y", expected: "x=9;y=6" }, + { statement: "x -= y", expected: "x=-3;y=6" }, + { statement: "x *= y", expected: "x=18;y=6" }, + { statement: "y /= x", expected: "x=3;y=2.0" }, + { statement: "y %= x", expected: "x=3;y=0" }, + { statement: "y **= x", expected: "x=3;y=216.0" }, + { statement: "x |= y", expected: "x=7;y=6" }, + { statement: "x &= y", expected: "x=2;y=6" }, + { statement: "x ^= y", expected: "x=5;y=6" }, + { statement: "x <<= y", expected: "x=192;y=6" }, + { statement: "x >>>= y", expected: "x=0;y=6" }, +])("Operator assignment statements (%p)", ({ statement, expected }) => { + const result = util.transpileAndExecute( + `let x = 3; + let y = 6; + ${statement}; + return \`x=\${x};y=\${y}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++o.p", "o=4;a=6") - @TestCase("o.p++", "o=4;a=6") - @TestCase("--o.p", "o=2;a=6") - @TestCase("o.p--", "o=2;a=6") - @TestCase("o.p += a[0]", "o=9;a=6") - @TestCase("o.p -= a[0]", "o=-3;a=6") - @TestCase("o.p *= a[0]", "o=18;a=6") - @TestCase("a[0] /= o.p", "o=3;a=2.0") - @TestCase("a[0] %= o.p", "o=3;a=0") - @TestCase("a[0] **= o.p", "o=3;a=216.0") - @TestCase("o.p |= a[0]", "o=7;a=6") - @TestCase("o.p &= a[0]", "o=2;a=6") - @TestCase("o.p ^= a[0]", "o=5;a=6") - @TestCase("o.p <<= a[0]", "o=192;a=6") - @TestCase("o.p >>>= a[0]", "o=0;a=6") - @Test("Operator assignment to simple property statements") - public opSimplePropAssignmentStatement(statement: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - ${statement}; - return \`o=\${o.p};a=\${a[0]}\``); - Expect(result).toBe(expected); - } +test.each([ + { statement: "++o.p", expected: "o=4;a=6" }, + { statement: "o.p++", expected: "o=4;a=6" }, + { statement: "--o.p", expected: "o=2;a=6" }, + { statement: "o.p--", expected: "o=2;a=6" }, + { statement: "o.p += a[0]", expected: "o=9;a=6" }, + { statement: "o.p -= a[0]", expected: "o=-3;a=6" }, + { statement: "o.p *= a[0]", expected: "o=18;a=6" }, + { statement: "a[0] /= o.p", expected: "o=3;a=2.0" }, + { statement: "a[0] %= o.p", expected: "o=3;a=0" }, + { statement: "a[0] **= o.p", expected: "o=3;a=216.0" }, + { statement: "o.p |= a[0]", expected: "o=7;a=6" }, + { statement: "o.p &= a[0]", expected: "o=2;a=6" }, + { statement: "o.p ^= a[0]", expected: "o=5;a=6" }, + { statement: "o.p <<= a[0]", expected: "o=192;a=6" }, + { statement: "o.p >>>= a[0]", expected: "o=0;a=6" }, +])("Operator assignment to simple property statements (%p)", ({ statement, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: 3}; + let a = [6]; + ${statement}; + return \`o=\${o.p};a=\${a[0]}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++o.p.d", "o=4;a=[6,11],[7,13]") - @TestCase("o.p.d++", "o=4;a=[6,11],[7,13]") - @TestCase("--o.p.d", "o=2;a=[6,11],[7,13]") - @TestCase("o.p.d--", "o=2;a=[6,11],[7,13]") - @TestCase("o.p.d += a[0][0]", "o=9;a=[6,11],[7,13]") - @TestCase("o.p.d -= a[0][0]", "o=-3;a=[6,11],[7,13]") - @TestCase("o.p.d *= a[0][0]", "o=18;a=[6,11],[7,13]") - @TestCase("a[0][0] /= o.p.d", "o=3;a=[2.0,11],[7,13]") - @TestCase("a[0][0] %= o.p.d", "o=3;a=[0,11],[7,13]") - @TestCase("a[0][0] **= o.p.d", "o=3;a=[216.0,11],[7,13]") - @TestCase("o.p.d |= a[0][0]", "o=7;a=[6,11],[7,13]") - @TestCase("o.p.d &= a[0][0]", "o=2;a=[6,11],[7,13]") - @TestCase("o.p.d ^= a[0][0]", "o=5;a=[6,11],[7,13]") - @TestCase("o.p.d <<= a[0][0]", "o=192;a=[6,11],[7,13]") - @TestCase("o.p.d >>>= a[0][0]", "o=0;a=[6,11],[7,13]") - @Test("Operator assignment to deep property statements") - public opDeepPropAssignmentStatement(statement: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: {d: 3}}; - let a = [[6,11], [7,13]]; - ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}]\``); - Expect(result).toBe(expected); - } +test.each([ + { statement: "++o.p.d", expected: "o=4;a=[6,11],[7,13]" }, + { statement: "o.p.d++", expected: "o=4;a=[6,11],[7,13]" }, + { statement: "--o.p.d", expected: "o=2;a=[6,11],[7,13]" }, + { statement: "o.p.d--", expected: "o=2;a=[6,11],[7,13]" }, + { statement: "o.p.d += a[0][0]", expected: "o=9;a=[6,11],[7,13]" }, + { statement: "o.p.d -= a[0][0]", expected: "o=-3;a=[6,11],[7,13]" }, + { statement: "o.p.d *= a[0][0]", expected: "o=18;a=[6,11],[7,13]" }, + { statement: "a[0][0] /= o.p.d", expected: "o=3;a=[2.0,11],[7,13]" }, + { statement: "a[0][0] %= o.p.d", expected: "o=3;a=[0,11],[7,13]" }, + { statement: "a[0][0] **= o.p.d", expected: "o=3;a=[216.0,11],[7,13]" }, + { statement: "o.p.d |= a[0][0]", expected: "o=7;a=[6,11],[7,13]" }, + { statement: "o.p.d &= a[0][0]", expected: "o=2;a=[6,11],[7,13]" }, + { statement: "o.p.d ^= a[0][0]", expected: "o=5;a=[6,11],[7,13]" }, + { statement: "o.p.d <<= a[0][0]", expected: "o=192;a=[6,11],[7,13]" }, + { statement: "o.p.d >>>= a[0][0]", expected: "o=0;a=[6,11],[7,13]" }, +])("Operator assignment to deep property statements (%p)", ({ statement, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: {d: 3}}; + let a = [[6,11], [7,13]]; + ${statement}; + return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}]\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++of().p", "o=4;a=6") - @TestCase("of().p++", "o=4;a=6") - @TestCase("--of().p", "o=2;a=6") - @TestCase("of().p--", "o=2;a=6") - @TestCase("of().p += af()[i()]", "o=9;a=6") - @TestCase("of().p -= af()[i()]", "o=-3;a=6") - @TestCase("of().p *= af()[i()]", "o=18;a=6") - @TestCase("af()[i()] /= of().p", "o=3;a=2.0") - @TestCase("af()[i()] %= of().p", "o=3;a=0") - @TestCase("af()[i()] **= of().p", "o=3;a=216.0") - @TestCase("of().p |= af()[i()]", "o=7;a=6") - @TestCase("of().p &= af()[i()]", "o=2;a=6") - @TestCase("of().p ^= af()[i()]", "o=5;a=6") - @TestCase("of().p <<= af()[i()]", "o=192;a=6") - @TestCase("of().p >>>= af()[i()]", "o=0;a=6") - @Test("Operator assignment to complex property statements") - public opComplexPropAssignmentStatement(statement: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - function of() { return o; } - function af() { return a; } - function i() { return 0; } - ${statement}; - return \`o=\${o.p};a=\${a[0]}\``); - Expect(result).toBe(expected); - } +test.each([ + { statement: "++of().p", expected: "o=4;a=6" }, + { statement: "of().p++", expected: "o=4;a=6" }, + { statement: "--of().p", expected: "o=2;a=6" }, + { statement: "of().p--", expected: "o=2;a=6" }, + { statement: "of().p += af()[i()]", expected: "o=9;a=6" }, + { statement: "of().p -= af()[i()]", expected: "o=-3;a=6" }, + { statement: "of().p *= af()[i()]", expected: "o=18;a=6" }, + { statement: "af()[i()] /= of().p", expected: "o=3;a=2.0" }, + { statement: "af()[i()] %= of().p", expected: "o=3;a=0" }, + { statement: "af()[i()] **= of().p", expected: "o=3;a=216.0" }, + { statement: "of().p |= af()[i()]", expected: "o=7;a=6" }, + { statement: "of().p &= af()[i()]", expected: "o=2;a=6" }, + { statement: "of().p ^= af()[i()]", expected: "o=5;a=6" }, + { statement: "of().p <<= af()[i()]", expected: "o=192;a=6" }, + { statement: "of().p >>>= af()[i()]", expected: "o=0;a=6" }, +])("Operator assignment to complex property statements (%p)", ({ statement, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: 3}; + let a = [6]; + function of() { return o; } + function af() { return a; } + function i() { return 0; } + ${statement}; + return \`o=\${o.p};a=\${a[0]}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++of().p.d", "o=4;a=[7,6],[11,13];i=0") - @TestCase("of().p.d++", "o=4;a=[7,6],[11,13];i=0") - @TestCase("--of().p.d", "o=2;a=[7,6],[11,13];i=0") - @TestCase("of().p.d--", "o=2;a=[7,6],[11,13];i=0") - @TestCase("of().p.d += af()[i()][i()]", "o=9;a=[7,6],[11,13];i=2") - @TestCase("of().p.d -= af()[i()][i()]", "o=-3;a=[7,6],[11,13];i=2") - @TestCase("of().p.d *= af()[i()][i()]", "o=18;a=[7,6],[11,13];i=2") - @TestCase("af()[i()][i()] /= of().p.d", "o=3;a=[7,2.0],[11,13];i=2") - @TestCase("af()[i()][i()] %= of().p.d", "o=3;a=[7,0],[11,13];i=2") - @TestCase("af()[i()][i()] **= of().p.d", "o=3;a=[7,216.0],[11,13];i=2") - @TestCase("of().p.d |= af()[i()][i()]", "o=7;a=[7,6],[11,13];i=2") - @TestCase("of().p.d &= af()[i()][i()]", "o=2;a=[7,6],[11,13];i=2") - @TestCase("of().p.d ^= af()[i()][i()]", "o=5;a=[7,6],[11,13];i=2") - @TestCase("of().p.d <<= af()[i()][i()]", "o=192;a=[7,6],[11,13];i=2") - @TestCase("of().p.d >>>= af()[i()][i()]", "o=0;a=[7,6],[11,13];i=2") - @Test("Operator assignment to complex deep property statements") - public opComplexDeepPropAssignmentStatement(statement: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: {d: 3}}; - let a = [[7, 6], [11, 13]]; - function of() { return o; } - function af() { return a; } - let _i = 0; - function i() { return _i++; } - ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}];i=\${_i}\``); - Expect(result).toBe(expected); - } +test.each([ + { statement: "++of().p.d", expected: "o=4;a=[7,6],[11,13];i=0" }, + { statement: "of().p.d++", expected: "o=4;a=[7,6],[11,13];i=0" }, + { statement: "--of().p.d", expected: "o=2;a=[7,6],[11,13];i=0" }, + { statement: "of().p.d--", expected: "o=2;a=[7,6],[11,13];i=0" }, + { statement: "of().p.d += af()[i()][i()]", expected: "o=9;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d -= af()[i()][i()]", expected: "o=-3;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d *= af()[i()][i()]", expected: "o=18;a=[7,6],[11,13];i=2" }, + { statement: "af()[i()][i()] /= of().p.d", expected: "o=3;a=[7,2.0],[11,13];i=2" }, + { statement: "af()[i()][i()] %= of().p.d", expected: "o=3;a=[7,0],[11,13];i=2" }, + { statement: "af()[i()][i()] **= of().p.d", expected: "o=3;a=[7,216.0],[11,13];i=2" }, + { statement: "of().p.d |= af()[i()][i()]", expected: "o=7;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d &= af()[i()][i()]", expected: "o=2;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d ^= af()[i()][i()]", expected: "o=5;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d <<= af()[i()][i()]", expected: "o=192;a=[7,6],[11,13];i=2" }, + { statement: "of().p.d >>>= af()[i()][i()]", expected: "o=0;a=[7,6],[11,13];i=2" }, +])("Operator assignment to complex deep property statements (%p)", ({ statement, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: {d: 3}}; + let a = [[7, 6], [11, 13]]; + function of() { return o; } + function af() { return a; } + let _i = 0; + function i() { return _i++; } + ${statement}; + return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}];i=\${_i}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++x", "4;x=4;y=6") - @TestCase("x++", "3;x=4;y=6") - @TestCase("--x", "2;x=2;y=6") - @TestCase("x--", "3;x=2;y=6") - @TestCase("x += y", "9;x=9;y=6") - @TestCase("x -= y", "-3;x=-3;y=6") - @TestCase("x *= y", "18;x=18;y=6") - @TestCase("y /= x", "2.0;x=3;y=2.0") - @TestCase("y %= x", "0;x=3;y=0") - @TestCase("y **= x", "216.0;x=3;y=216.0") - @TestCase("x |= y", "7;x=7;y=6") - @TestCase("x &= y", "2;x=2;y=6") - @TestCase("x ^= y", "5;x=5;y=6") - @TestCase("x <<= y", "192;x=192;y=6") - @TestCase("x >>>= y", "0;x=0;y=6") - @TestCase("x + (y += 7)", "16;x=3;y=13") - @TestCase("x + (y += 7)", "16;x=3;y=13") - @TestCase("x++ + (y += 7)", "16;x=4;y=13") - @Test("Operator assignment expressions") - public opAssignmentExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let x = 3; - let y = 6; - const r = ${expression}; - return \`\${r};x=\${x};y=\${y}\``); - Expect(result).toBe(expected); - } +test.each([ + { expression: "++x", expected: "4;x=4;y=6" }, + { expression: "x++", expected: "3;x=4;y=6" }, + { expression: "--x", expected: "2;x=2;y=6" }, + { expression: "x--", expected: "3;x=2;y=6" }, + { expression: "x += y", expected: "9;x=9;y=6" }, + { expression: "x -= y", expected: "-3;x=-3;y=6" }, + { expression: "x *= y", expected: "18;x=18;y=6" }, + { expression: "y /= x", expected: "2.0;x=3;y=2.0" }, + { expression: "y %= x", expected: "0;x=3;y=0" }, + { expression: "y **= x", expected: "216.0;x=3;y=216.0" }, + { expression: "x |= y", expected: "7;x=7;y=6" }, + { expression: "x &= y", expected: "2;x=2;y=6" }, + { expression: "x ^= y", expected: "5;x=5;y=6" }, + { expression: "x <<= y", expected: "192;x=192;y=6" }, + { expression: "x >>>= y", expected: "0;x=0;y=6" }, + { expression: "x + (y += 7)", expected: "16;x=3;y=13" }, + { expression: "x + (y += 7)", expected: "16;x=3;y=13" }, + { expression: "x++ + (y += 7)", expected: "16;x=4;y=13" }, +])("Operator assignment expressions (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let x = 3; + let y = 6; + const r = ${expression}; + return \`\${r};x=\${x};y=\${y}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++o.p", "4;o=4;a=6") - @TestCase("o.p++", "3;o=4;a=6") - @TestCase("--o.p", "2;o=2;a=6") - @TestCase("o.p--", "3;o=2;a=6") - @TestCase("o.p += a[0]", "9;o=9;a=6") - @TestCase("o.p -= a[0]", "-3;o=-3;a=6") - @TestCase("o.p *= a[0]", "18;o=18;a=6") - @TestCase("a[0] /= o.p", "2.0;o=3;a=2.0") - @TestCase("a[0] %= o.p", "0;o=3;a=0") - @TestCase("a[0] **= o.p", "216.0;o=3;a=216.0") - @TestCase("o.p |= a[0]", "7;o=7;a=6") - @TestCase("o.p &= a[0]", "2;o=2;a=6") - @TestCase("o.p ^= a[0]", "5;o=5;a=6") - @TestCase("o.p <<= a[0]", "192;o=192;a=6") - @TestCase("o.p >>>= a[0]", "0;o=0;a=6") - @TestCase("o.p + (a[0] += 7)", "16;o=3;a=13") - @TestCase("o.p += (a[0] += 7)", "16;o=16;a=13") - @TestCase("o.p++ + (a[0] += 7)", "16;o=4;a=13") - @Test("Operator assignment to simple property expressions") - public opSimplePropAssignmentExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\``); - Expect(result).toBe(expected); - } +test.each([ + { expression: "++o.p", expected: "4;o=4;a=6" }, + { expression: "o.p++", expected: "3;o=4;a=6" }, + { expression: "--o.p", expected: "2;o=2;a=6" }, + { expression: "o.p--", expected: "3;o=2;a=6" }, + { expression: "o.p += a[0]", expected: "9;o=9;a=6" }, + { expression: "o.p -= a[0]", expected: "-3;o=-3;a=6" }, + { expression: "o.p *= a[0]", expected: "18;o=18;a=6" }, + { expression: "a[0] /= o.p", expected: "2.0;o=3;a=2.0" }, + { expression: "a[0] %= o.p", expected: "0;o=3;a=0" }, + { expression: "a[0] **= o.p", expected: "216.0;o=3;a=216.0" }, + { expression: "o.p |= a[0]", expected: "7;o=7;a=6" }, + { expression: "o.p &= a[0]", expected: "2;o=2;a=6" }, + { expression: "o.p ^= a[0]", expected: "5;o=5;a=6" }, + { expression: "o.p <<= a[0]", expected: "192;o=192;a=6" }, + { expression: "o.p >>>= a[0]", expected: "0;o=0;a=6" }, + { expression: "o.p + (a[0] += 7)", expected: "16;o=3;a=13" }, + { expression: "o.p += (a[0] += 7)", expected: "16;o=16;a=13" }, + { expression: "o.p++ + (a[0] += 7)", expected: "16;o=4;a=13" }, +])("Operator assignment to simple property expressions (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: 3}; + let a = [6]; + const r = ${expression}; + return \`\${r};o=\${o.p};a=\${a[0]}\``, + ); + expect(result).toBe(expected); +}); - @TestCase("++of().p", "4;o=4;a=6") - @TestCase("of().p++", "3;o=4;a=6") - @TestCase("--of().p", "2;o=2;a=6") - @TestCase("of().p--", "3;o=2;a=6") - @TestCase("of().p += af()[i()]", "9;o=9;a=6") - @TestCase("of().p -= af()[i()]", "-3;o=-3;a=6") - @TestCase("of().p *= af()[i()]", "18;o=18;a=6") - @TestCase("af()[i()] /= of().p", "2.0;o=3;a=2.0") - @TestCase("af()[i()] %= of().p", "0;o=3;a=0") - @TestCase("af()[i()] **= of().p", "216.0;o=3;a=216.0") - @TestCase("of().p |= af()[i()]", "7;o=7;a=6") - @TestCase("of().p &= af()[i()]", "2;o=2;a=6") - @TestCase("of().p ^= af()[i()]", "5;o=5;a=6") - @TestCase("of().p <<= af()[i()]", "192;o=192;a=6") - @TestCase("of().p >>>= af()[i()]", "0;o=0;a=6") - @TestCase("of().p + (af()[i()] += 7)", "16;o=3;a=13") - @TestCase("of().p += (af()[i()] += 7)", "16;o=16;a=13") - @TestCase("of().p++ + (af()[i()] += 7)", "16;o=4;a=13") - @Test("Operator assignment to complex property expressions") - public opComplexPropAssignmentExpression(expression: string, expected: string): void { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - function of() { return o; } - function af() { return a; } - function i() { return 0; } - const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\``); - Expect(result).toBe(expected); - } -} +test.each([ + { expression: "++of().p", expected: "4;o=4;a=6" }, + { expression: "of().p++", expected: "3;o=4;a=6" }, + { expression: "--of().p", expected: "2;o=2;a=6" }, + { expression: "of().p--", expected: "3;o=2;a=6" }, + { expression: "of().p += af()[i()]", expected: "9;o=9;a=6" }, + { expression: "of().p -= af()[i()]", expected: "-3;o=-3;a=6" }, + { expression: "of().p *= af()[i()]", expected: "18;o=18;a=6" }, + { expression: "af()[i()] /= of().p", expected: "2.0;o=3;a=2.0" }, + { expression: "af()[i()] %= of().p", expected: "0;o=3;a=0" }, + { expression: "af()[i()] **= of().p", expected: "216.0;o=3;a=216.0" }, + { expression: "of().p |= af()[i()]", expected: "7;o=7;a=6" }, + { expression: "of().p &= af()[i()]", expected: "2;o=2;a=6" }, + { expression: "of().p ^= af()[i()]", expected: "5;o=5;a=6" }, + { expression: "of().p <<= af()[i()]", expected: "192;o=192;a=6" }, + { expression: "of().p >>>= af()[i()]", expected: "0;o=0;a=6" }, + { expression: "of().p + (af()[i()] += 7)", expected: "16;o=3;a=13" }, + { expression: "of().p += (af()[i()] += 7)", expected: "16;o=16;a=13" }, + { expression: "of().p++ + (af()[i()] += 7)", expected: "16;o=4;a=13" }, +])("Operator assignment to complex property expressions (%p)", ({ expression, expected }) => { + const result = util.transpileAndExecute( + `let o = {p: 3}; + let a = [6]; + function of() { return o; } + function af() { return a; } + function i() { return 0; } + const r = ${expression}; + return \`\${r};o=\${o.p};a=\${a[0]}\``, + ); + expect(result).toBe(expected); +}); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 606e39985..c02f052de 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -1,78 +1,65 @@ -import { Expect, Test, TestCase } from "alsatian"; import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; -import * as ts from "typescript"; -import * as util from "../src/util"; +test("defaultImport", () => { + expect(() => { + const lua = util.transpileString(`import TestClass from "test"`); + }).toThrowExactError(TSTLErrors.DefaultImportsNotSupported(util.nodeStub)); +}); -export class LuaModuleTests { +test("lualibRequire", () => { + const lua = util.transpileString(`let a = b instanceof c;`, { + luaLibImport: LuaLibImportKind.Require, + luaTarget: LuaTarget.LuaJIT, + }); - @Test("defaultImport") - public defaultImport(): void { - Expect(() => { - const lua = util.transpileString(`import TestClass from "test"`); - }).toThrowError(Error, "Default Imports are not supported, please use named imports instead!"); - } + expect(lua.startsWith(`require("lualib_bundle")`)); +}); - @Test("lualibRequire") - public lualibRequire(): void { - // Transpile - const lua = util.transpileString(`let a = b instanceof c;`, - { luaLibImport: LuaLibImportKind.Require, luaTarget: LuaTarget.LuaJIT }); +test("lualibRequireAlways", () => { + const lua = util.transpileString(``, { + luaLibImport: LuaLibImportKind.Always, + luaTarget: LuaTarget.LuaJIT, + }); - // Assert - Expect(lua.startsWith(`require("lualib_bundle")`)); - } + expect(lua).toBe(`require("lualib_bundle");`); +}); - @Test("lualibRequireAlways") - public lualibRequireAlways(): void { - // Transpile - const lua = util.transpileString(``, { luaLibImport: LuaLibImportKind.Always, luaTarget: LuaTarget.LuaJIT }); +test("Non-exported module", () => { + const result = util.transpileAndExecute( + "return g.test();", + undefined, + undefined, + "module g { export function test() { return 3; } }", + ); - // Assert - Expect(lua).toBe(`require("lualib_bundle");`); - } + expect(result).toBe(3); +}); - @Test("Non-exported module") - public nonExportedModule(): void { - const result = util.transpileAndExecute( - "return g.test();", - undefined, - undefined, - "module g { export function test() { return 3; } }" // Typescript header - ); - - Expect(result).toBe(3); - } - - @TestCase(LuaLibImportKind.Inline) - @TestCase(LuaLibImportKind.None) - @TestCase(LuaLibImportKind.Require) - @Test("LuaLib no uses? No code") - public lualibNoUsesNoCode(impKind: LuaLibImportKind): void { - // Transpile +test.each([LuaLibImportKind.Inline, LuaLibImportKind.None, LuaLibImportKind.Require])( + "LuaLib no uses? No code (%p)", + impKind => { const lua = util.transpileString(``, { luaLibImport: impKind }); - // Assert - Expect(lua).toBe(``); - } + expect(lua).toBe(``); + }, +); - @Test("Nested module with dot in name") - public nestedModuleWithDotInName(): void { - const code = - `module a.b { - export const foo = "foo"; - }`; - Expect(util.transpileAndExecute("return a.b.foo;", undefined, undefined, code)).toBe("foo"); - } +test("Nested module with dot in name", () => { + const code = `module a.b { + export const foo = "foo"; + }`; + expect(util.transpileAndExecute("return a.b.foo;", undefined, undefined, code)).toBe("foo"); +}); - @Test("Access this in module") - public accessThisInModule(): void { - const header = - `module M { - export const foo = "foo"; - export function bar() { return this.foo + "bar"; } - }`; - const code = `return M.bar();`; - Expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); - } -} +test("Access this in module", () => { + const header = ` + module M { + export const foo = "foo"; + export function bar() { return this.foo + "bar"; } + } + `; + const code = `return M.bar();`; + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); +}); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index e3858fae6..21ae4abf0 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -1,34 +1,28 @@ -import { Expect, Test, TestCase } from "alsatian"; - -import * as util from "../src/util"; +import * as util from "../util"; const fs = require("fs"); -export class ObjectLiteralTests { - - @TestCase(`{a:3,b:"4"}`, `{a = 3, b = "4"};`) - @TestCase(`{"a":3,b:"4"}`, `{a = 3, b = "4"};`) - @TestCase(`{["a"]:3,b:"4"}`, `{a = 3, b = "4"};`) - @TestCase(`{["a"+123]:3,b:"4"}`, `{["a" .. 123] = 3, b = "4"};`) - @TestCase(`{[myFunc()]:3,b:"4"}`, `{[myFunc(_G)] = 3, b = "4"};`) - @TestCase(`{x}`, `{x = x};`) - @Test("Object Literal") - public objectLiteral(inp: string, out: string): void { - const lua = util.transpileString(`const myvar = ${inp};`); - Expect(lua).toBe(`local myvar = ${out}`); - } +test.each([ + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"};` }, + { inp: `{"a":3,b:"4"}`, out: `{a = 3, b = "4"};` }, + { inp: `{["a"]:3,b:"4"}`, out: `{a = 3, b = "4"};` }, + { inp: `{["a"+123]:3,b:"4"}`, out: `{["a" .. 123] = 3, b = "4"};` }, + { inp: `{[myFunc()]:3,b:"4"}`, out: `{[myFunc(_G)] = 3, b = "4"};` }, + { inp: `{x}`, out: `{x = x};` }, +])("Object Literal (%p)", ({ inp, out }) => { + const lua = util.transpileString(`const myvar = ${inp};`); + expect(lua).toBe(`local myvar = ${out}`); +}); - @TestCase("3", 3) - @Test("Shorthand Property Assignment") - public ShorthandPropertyAssignment(input: string, expected: number): void { +test.each([{ input: "3", expected: 3 }])( + "Shorthand Property Assignment (%p)", + ({ input, expected }) => { const result = util.transpileAndExecute(`const x = ${input}; const o = {x}; return o.x;`); - Expect(result).toBe(expected); - } + expect(result).toBe(expected); + }, +); - @Test("undefined as object key") - public undefinedAsObjectKey(): void { - const code = - `const foo = {undefined: "foo"}; - return foo.undefined;`; - Expect(util.transpileAndExecute(code)).toBe("foo"); - } -} +test("undefined as object key", () => { + const code = `const foo = {undefined: "foo"}; + return foo.undefined;`; + expect(util.transpileAndExecute(code)).toBe("foo"); +}); diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index 1b6d7e925..482cdd089 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -1,129 +1,119 @@ -import { Expect, Test, TestCase } from "alsatian"; +import * as util from "../util"; -import * as util from "../src/util"; +test("overload function1", () => { + const result = util.transpileAndExecute( + `function abc(def: number): string; + function abc(def: string): string; + function abc(def: number | string): string { + if (typeof def == "number") { + return "jkl" + (def * 3); + } else { + return def; + } + } + return abc(3);`, + ); + + expect(result).toBe("jkl9"); +}); + +test("overload function2", () => { + const result = util.transpileAndExecute( + `function abc(def: number): string; + function abc(def: string): string; + function abc(def: number | string): string { + if (typeof def == "number") { + return "jkl" + (def * 3); + } else { + return def; + } + } + return abc("ghj");`, + ); + + expect(result).toBe("ghj"); +}); -export class OverloadTests { - @Test("overload function1") - public overloadFunction1(): void - { - const result = util.transpileAndExecute( - `function abc(def: number): string; - function abc(def: string): string; - function abc(def: number | string): string { +test("overload method1", () => { + const result = util.transpileAndExecute( + `class myclass { + static abc(def: number): string; + static abc(def: string): string; + static abc(def: number | string): string { if (typeof def == "number") { return "jkl" + (def * 3); } else { return def; } } - return abc(3);`); + } + return myclass.abc(3);`, + ); - Expect(result).toBe("jkl9"); - } + expect(result).toBe("jkl9"); +}); - @Test("overload function2") - public overloadFunction2(): void - { - const result = util.transpileAndExecute( - `function abc(def: number): string; - function abc(def: string): string; - function abc(def: number | string): string { +test("overload method2", () => { + const result = util.transpileAndExecute( + `class myclass { + static abc(def: number): string; + static abc(def: string): string; + static abc(def: number | string): string { if (typeof def == "number") { return "jkl" + (def * 3); } else { return def; } } - return abc("ghj");`); + } + return myclass.abc("ghj");`, + ); - Expect(result).toBe("ghj"); - } + expect(result).toBe("ghj"); +}); - @Test("overload method1") - public overloadMethod1(): void - { - const result = util.transpileAndExecute( - `class myclass { - static abc(def: number): string; - static abc(def: string): string; - static abc(def: number | string): string { - if (typeof def == "number") { - return "jkl" + (def * 3); - } else { - return def; - } - } - } - return myclass.abc(3);`); +test("constructor1", () => { + const result = util.transpileAndExecute( + `class myclass { + num: number; + str: string; - Expect(result).toBe("jkl9"); - } - - @Test("overload method2") - public overloadMethod2(): void - { - const result = util.transpileAndExecute( - `class myclass { - static abc(def: number): string; - static abc(def: string): string; - static abc(def: number | string): string { - if (typeof def == "number") { - return "jkl" + (def * 3); - } else { - return def; - } - } - } - return myclass.abc("ghj");`); - - Expect(result).toBe("ghj"); - } - - @Test("constructor1") - public constructor1(): void - { - const result = util.transpileAndExecute( - `class myclass { - num: number; - str: string; - - constructor(def: number); - constructor(def: string); - constructor(def: number | string) { - if (typeof def == "number") { - this.num = def; - } else { - this.str = def; - } + constructor(def: number); + constructor(def: string); + constructor(def: number | string) { + if (typeof def == "number") { + this.num = def; + } else { + this.str = def; } } - const inst = new myclass(3); - return inst.num`); + } + const inst = new myclass(3); + return inst.num`, + ); - Expect(result).toBe(3); - } + expect(result).toBe(3); +}); - @Test("constructor2") - public constructor2(): void - { - const result = util.transpileAndExecute( - `class myclass { - num: number; - str: string; +test("constructor2", () => { + const result = util.transpileAndExecute( + `class myclass { + num: number; + str: string; - constructor(def: number); - constructor(def: string); - constructor(def: number | string) { - if (typeof def == "number") { - this.num = def; - } else { - this.str = def; - } + constructor(def: number); + constructor(def: string); + constructor(def: number | string) { + if (typeof def == "number") { + this.num = def; + } else { + this.str = def; } } - const inst = new myclass("ghj"); - return inst.str`); + } + const inst = new myclass("ghj"); + return inst.str`, + ); - Expect(result).toBe("ghj"); - } -} + expect(result).toBe("ghj"); +}); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index 27c5a7432..747ce7b7a 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -1,48 +1,113 @@ -import { Expect, FocusTest, Test, TestCase } from "alsatian"; +import * as util from "../util"; -import * as util from "../src/util"; -import * as path from "path"; -import { CompilerOptions } from "../../src/CompilerOptions"; - -export class RequireTests { - - @TestCase("file.ts", "./folder/Module", "folder.Module", { rootDir: "." }, false) - @TestCase("file.ts", "./folder/Module", "folder.Module", { rootDir: "./" }, false) - @TestCase("src/file.ts", "./folder/Module", "src.folder.Module", { rootDir: "." }, false) - @TestCase("file.ts", "folder/Module", "folder.Module", { rootDir: ".", baseUrl: "." }, false) - @TestCase("file.ts", "folder/Module", "folder.Module", { rootDir: "./", baseUrl: "." }, false) - @TestCase("src/file.ts", "./folder/Module", "folder.Module", { rootDir: "src" }, false) - @TestCase("src/file.ts", "./folder/Module", "folder.Module", { rootDir: "./src" }, false) - @TestCase("file.ts", "../Module", "", { rootDir: "./src" }, true) - @TestCase("src/dir/file.ts", "../Module", "Module", { rootDir: "./src" }, false) - @TestCase("src/dir/dir/file.ts", "../../dir/Module", "dir.Module", { rootDir: "./src" }, false) - @Test("require paths root from --baseUrl or --rootDir") - public testRequirePath( - filePath: string, - usedPath: string, - expectedPath: string, - options: CompilerOptions, - throwsError: boolean): void { +test.each([ + { + filePath: "file.ts", + usedPath: "./folder/Module", + expectedPath: "folder.Module", + options: { rootDir: "." }, + throwsError: false, + }, + { + filePath: "file.ts", + usedPath: "./folder/Module", + expectedPath: "folder.Module", + options: { rootDir: "./" }, + throwsError: false, + }, + { + filePath: "src/file.ts", + usedPath: "./folder/Module", + expectedPath: "src.folder.Module", + options: { rootDir: "." }, + throwsError: false, + }, + { + filePath: "file.ts", + usedPath: "folder/Module", + expectedPath: "folder.Module", + options: { rootDir: ".", baseUrl: "." }, + throwsError: false, + }, + { + filePath: "file.ts", + usedPath: "folder/Module", + expectedPath: "folder.Module", + options: { rootDir: "./", baseUrl: "." }, + throwsError: false, + }, + { + filePath: "src/file.ts", + usedPath: "./folder/Module", + expectedPath: "folder.Module", + options: { rootDir: "src" }, + throwsError: false, + }, + { + filePath: "src/file.ts", + usedPath: "./folder/Module", + expectedPath: "folder.Module", + options: { rootDir: "./src" }, + throwsError: false, + }, + { + filePath: "file.ts", + usedPath: "../Module", + expectedPath: "", + options: { rootDir: "./src" }, + throwsError: true, + }, + { + filePath: "src/dir/file.ts", + usedPath: "../Module", + expectedPath: "Module", + options: { rootDir: "./src" }, + throwsError: false, + }, + { + filePath: "src/dir/dir/file.ts", + usedPath: "../../dir/Module", + expectedPath: "dir.Module", + options: { rootDir: "./src" }, + throwsError: false, + }, +])( + "require paths root from --baseUrl or --rootDir (%p)", + ({ filePath, usedPath, expectedPath, options, throwsError }) => { if (throwsError) { - Expect(() => util.transpileString(`import * from "${usedPath}";`, options, true, filePath)).toThrow(); + expect(() => + util.transpileString(`import * from "${usedPath}";`, options, true, filePath), + ).toThrow(); } else { - const lua = util.transpileString(`import * from "${usedPath}";`, options, true, filePath); + const lua = util.transpileString( + `import * from "${usedPath}";`, + options, + true, + filePath, + ); const regex = /require\("(.*?)"\)/; const match = regex.exec(lua); - Expect(match[1]).toBe(expectedPath); + expect(match[1]).toBe(expectedPath); } - } + }, +); - @TestCase("", "src.fake") - @TestCase("/** @noResolution */", "fake") - @Test("noResolution on ambient modules causes no path alterations") - public testRequireModule(comment: string, expectedPath: string): void { - const lua = util.transpileString({ - "src/file.ts": `import * as fake from "fake";`, - "module.d.ts": `${comment} declare module "fake" {}`, - }, undefined, true, "src/file.ts"); +test.each([ + { comment: "", expectedPath: "src.fake" }, + { comment: "/** @noResolution */", expectedPath: "fake" }, +])( + "noResolution on ambient modules causes no path alterations (%p)", + ({ comment, expectedPath }) => { + const lua = util.transpileString( + { + "src/file.ts": `import * as fake from "fake";`, + "module.d.ts": `${comment} declare module "fake" {}`, + }, + undefined, + true, + "src/file.ts", + ); const regex = /require\("(.*?)"\)/; - Expect(regex.exec(lua)[1]).toBe(expectedPath); - } - -} \ No newline at end of file + expect(regex.exec(lua)[1]).toBe(expectedPath); + }, +); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 35249ce15..3bb7ff981 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -1,49 +1,37 @@ -import { Expect, Test, TestCase } from "alsatian"; +import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as util from "../util"; -import { LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; -import * as util from "../src/util"; +test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])( + "Spread Element Push (%p)", + ({ inp }) => { + const result = util.transpileAndExecute( + `return JSONStringify([].push(...${JSON.stringify(inp)}));`, + ); + expect(result).toBe([].push(...inp)); + }, +); -export class SpreadElementTest { +test("Spread Element Lua 5.1", () => { + // Cant test functional because our VM doesn't run on 5.1 + const options = { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None }; + const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); + expect(lua).toBe("__TS__ArrayPush({}, unpack({1, 2, 3}));"); +}); - @TestCase([]) - @TestCase([1, 2, 3]) - @TestCase([1, "test", 3]) - @Test("Spread Element Push") - public spreadElementPush(inp: any[]): void - { - const result = util.transpileAndExecute(`return JSONStringify([].push(...${JSON.stringify(inp)}));`); - Expect(result).toBe([].push(...inp)); - } +test("Spread Element Lua 5.2", () => { + const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; + const lua = util.transpileString(`[...[0, 1, 2]]`, options); + expect(lua).toBe("{table.unpack({0, 1, 2})};"); +}); - @Test("Spread Element Lua 5.1") - public spreadElement51(): void - { - // Cant test functional because our VM doesn't run on 5.1 - const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, {luaTarget: LuaTarget.Lua51}); - Expect(lua).toBe("__TS__ArrayPush({}, unpack({1, 2, 3}));"); - } +test("Spread Element Lua 5.3", () => { + const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; + const lua = util.transpileString(`[...[0, 1, 2]]`, options); + expect(lua).toBe("{table.unpack({0, 1, 2})};"); +}); - @Test("Spread Element Lua 5.2") - public spreadElement52(): void - { - const options = {luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None}; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - Expect(lua).toBe("{table.unpack({0, 1, 2})};"); - } - - @Test("Spread Element Lua 5.3") - public spreadElement53(): void - { - const options = {luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None}; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - Expect(lua).toBe("{table.unpack({0, 1, 2})};"); - } - - @Test("Spread Element Lua JIT") - public spreadElementJIT(): void - { - const options = {luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None}; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - Expect(lua).toBe("{unpack({0, 1, 2})};"); - } -} +test("Spread Element Lua JIT", () => { + const options = { luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None }; + const lua = util.transpileString(`[...[0, 1, 2]]`, options); + expect(lua).toBe("{unpack({0, 1, 2})};"); +}); diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index d82fb0b9c..2b7cd4362 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -1,340 +1,256 @@ -import { Expect, Test, TestCase } from "alsatian"; -import { TranspileError } from "../../src/TranspileError"; -import * as util from "../src/util"; - -export class StringTests -{ - @Test("Unsuported string function") - public stringUnsuportedFunction(): void { - // Assert - Expect(() => { - util.transpileString( - `return "test".testThisIsNoMember()` - ); - }).toThrowError(TranspileError, "Unsupported property on string: testThisIsNoMember"); - } - - @Test("Suported lua string function") - public stringSuportedLuaFunction(): void { - Expect(util.transpileAndExecute( - `return "test".upper()`, - undefined, - undefined, - `interface String { upper(): string; }` - ) - ).toBe("TEST"); - } - - @TestCase([]) - @TestCase([65]) - @TestCase([65, 66]) - @TestCase([65, 66, 67]) - @Test("String.fromCharCode") - public stringFromCharcode(inp: number[]): void - { - const result = util.transpileAndExecute( - `return String.fromCharCode(${inp.toString()})` - ); - - // Assert - Expect(result).toBe(String.fromCharCode(...inp)); - } - - @TestCase(12, 23, 43) - @TestCase("test", "hello", "bye") - @TestCase("test", 42, "bye") - @TestCase("test", 42, 12) - @Test("Template Strings") - public templateStrings(a: any, b: any, c: any): void { - // Transpile - const a1 = typeof(a) === "string" ? "'" + a + "'" : a; - const b1 = typeof(b) === "string" ? "'" + b + "'" : b; - const c1 = typeof(c) === "string" ? "'" + c + "'" : c; - - const result = util.transpileAndExecute( - "let a = " + a1 + "; let b = " + b1 + "; let c = " + c1 + "; return `${a} ${b} test ${c}`;" - ); - - // Assert - Expect(result).toBe(`${a} ${b} test ${c}`); - } - - @TestCase("hello test", "", "") - @TestCase("hello test", " ", "") - @TestCase("hello test", "hello", "") - @TestCase("hello test", "test", "") - @TestCase("hello test", "test", "world") - @Test("string.replace") - public replace(inp: string, searchValue: string, replaceValue: string): void - { - const result = util.transpileAndExecute( - `return "${inp}".replace("${searchValue}", "${replaceValue}");` - ); - - // Assert - Expect(result).toBe(inp.replace(searchValue, replaceValue)); - } - - @TestCase(["", ""], "") - @TestCase(["hello", "test"], "hellotest") - @TestCase(["hello", "test", "bye"], "hellotestbye") - @TestCase(["hello", 42], "hello42") - @TestCase([42, "hello"], "42hello") - @Test("string.concat[+]") - public concat(inp: any[], expected: string): void { - const concatStr = inp.map(elem => typeof(elem) === "string" ? `"${elem}"` : elem).join(" + "); - - // Transpile/Execute - const result = util.transpileAndExecute( - `return ${concatStr}` - ); - - // Assert - Expect(result).toBe(expected); - } - @TestCase("", ["", ""]) - @TestCase("hello", ["test"]) - @TestCase("hello", []) - @TestCase("hello", ["test", "bye"]) - @Test("string.concatFct") - public concatFct(str: string, param: string[]): void { - const paramStr = param.map(elem => `"${elem}"`).join(", "); - const result = util.transpileAndExecute( - `return "${str}".concat(${paramStr})` - ); - // Assert - Expect(result).toBe(str.concat(...param)); - } - @TestCase("hello test", "") - @TestCase("hello test", "t") - @TestCase("hello test", "h") - @TestCase("hello test", "invalid") - @Test("string.indexOf") - public indexOf(inp: string, searchValue: string): void - { - const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}")`); - - // Assert - Expect(result).toBe(inp.indexOf(searchValue)); - } - - @TestCase("hello test", "t", 5) - @TestCase("hello test", "t", 6) - @TestCase("hello test", "t", 7) - @TestCase("hello test", "h", 4) - @Test("string.indexOf with offset") - public indexOfOffset(inp: string, searchValue: string, offset: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".indexOf("${searchValue}", ${offset})` - ); - - // Assert - Expect(result).toBe(inp.indexOf(searchValue, offset)); - } - - @TestCase("hello test", "t", 4, 3) - @TestCase("hello test", "h", 3, 4) - @Test("string.indexOf with offset expression") - public indexOfOffsetWithExpression(inp: string, searchValue: string, x: number, y: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".indexOf("${searchValue}", 2 > 1 && ${x} || ${y})` - ); - - // Assert - Expect(result).toBe(inp.indexOf(searchValue, x)); - } - @TestCase("hello test") - @TestCase("hello test", 0) - @TestCase("hello test", 1) - @TestCase("hello test", 1, 2) - @TestCase("hello test", 1, 5) - @Test("string.slice") - public slice(inp: string, start?: number, end?: number): void - { - // Transpile/Execute - const paramStr = start? (end ? `${start}, ${end}` : `${start}`):''; - const result = util.transpileAndExecute( - `return "${inp}".slice(${paramStr})` - ); - - // Assert - Expect(result).toBe(inp.slice(start, end)); - } - @TestCase("hello test", 0) - @TestCase("hello test", 1) - @TestCase("hello test", 1, 2) - @TestCase("hello test", 1, 5) - @Test("string.substring") - public substring(inp: string, start: number, end?: number): void - { - // Transpile/Execute - const paramStr = end ? `${start}, ${end}` : `${start}`; - const result = util.transpileAndExecute( - `return "${inp}".substring(${paramStr})` - ); - - // Assert - Expect(result).toBe(inp.substring(start, end)); - } - - @TestCase("hello test", 1, 0) - @TestCase("hello test", 3, 0, 5) - @Test("string.substring with expression") - public substringWithExpression(inp: string, start: number, ignored: number, end?: number): void - { - // Transpile/Execute - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute( - `return "${inp}".substring(${paramStr})` - ); - - // Assert - Expect(result).toBe(inp.substring(start, end)); - } - - @TestCase("hello test", 0) - @TestCase("hello test", 1) - @TestCase("hello test", 1, 2) - @TestCase("hello test", 1, 5) - @Test("string.substr") - public substr(inp: string, start: number, end?: number): void - { - // Transpile/Execute - const paramStr = end ? `${start}, ${end}` : `${start}`; - const result = util.transpileAndExecute( - `return "${inp}".substr(${paramStr})` - ); - - // Assert - Expect(result).toBe(inp.substr(start, end)); - } - - @TestCase("hello test", 1, 0) - @TestCase("hello test", 3, 0, 2) - @Test("string.substr with expression") - public substrWithExpression(inp: string, start: number, ignored: number, end?: number): void - { - // Transpile/Execute - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute( - `return "${inp}".substr(${paramStr})` - ); - - // Assert - Expect(result).toBe(inp.substr(start, end)); - } - - @TestCase("", 0) - @TestCase("h", 1) - @TestCase("hello", 5) - @Test("string.length") - public length(inp: string, expected: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".length` - ); - - // Assert - Expect(result).toBe(inp.length); - } - - @TestCase("hello TEST") - @Test("string.toLowerCase") - public toLowerCase(inp: string): void - { - const result = util.transpileAndExecute( - `return "${inp}".toLowerCase()` - ); - - // Assert - Expect(result).toBe(inp.toLowerCase()); - } - - @TestCase("hello test") - @Test("string.toUpperCase") - public toUpperCase(inp: string): void - { - const result = util.transpileAndExecute( - `return "${inp}".toUpperCase()` - ); - - // Assert - Expect(result).toBe(inp.toUpperCase()); - } - - @TestCase("hello test", "") - @TestCase("hello test", " ") - @TestCase("hello test", "h") - @TestCase("hello test", "t") - @TestCase("hello test", "l") - @TestCase("hello test", "invalid") - @TestCase("hello test", "hello test") - @Test("string.split") - public split(inp: string, separator: string): void - { - const result = util.transpileAndExecute( - `return JSONStringify("${inp}".split("${separator}"))` - ); - - // Assert - Expect(result).toBe(JSON.stringify(inp.split(separator))); - } - - @TestCase("hello test", 1) - @TestCase("hello test", 2) - @TestCase("hello test", 3) - @TestCase("hello test", 99) - @Test("string.charAt") - public charAt(inp: string, index: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".charAt(${index})` - ); - - // Assert - Expect(result).toBe(inp.charAt(index)); - } - - @TestCase("hello test", 1) - @TestCase("hello test", 2) - @TestCase("hello test", 3) - @Test("string.charCodeAt") - public charCodeAt(inp: string, index: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".charCodeAt(${index})` - ); - - // Assert - Expect(result).toBe(inp.charCodeAt(index)); - } - - @TestCase("hello test", 1, 0) - @TestCase("hello test", 1, 2) - @TestCase("hello test", 3, 2) - @TestCase("hello test", 3, 99) - @Test("string.charAt with expression") - public charAtWithExpression(inp: string, index: number, ignored: number): void - { - const result = util.transpileAndExecute( - `return "${inp}".charAt(2 > 1 && ${index} || ${ignored})` - ); - - // Assert - Expect(result).toBe(inp.charAt(index)); - } - - @TestCase("abcd", 3) - @TestCase("abcde", 3) - @TestCase("abcde", 0) - @TestCase("a", 0) - @Test("string index") - public index(input: string, index: number): void - { - const result = util.transpileAndExecute(`return "${input}"[${index}];`); - - Expect(result).toBe(input[index]); - } -} +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test("Unsuported string function", () => { + expect(() => { + util.transpileString(`return "test".testThisIsNoMember()`); + }).toThrowExactError( + TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub), + ); +}); + +test("Suported lua string function", () => { + expect( + util.transpileAndExecute( + `return "test".upper()`, + undefined, + undefined, + `interface String { upper(): string; }`, + ), + ).toBe("TEST"); +}); + +test.each([{ inp: [] }, { inp: [65] }, { inp: [65, 66] }, { inp: [65, 66, 67] }])( + "String.fromCharCode (%p)", + ({ inp }) => { + const result = util.transpileAndExecute(`return String.fromCharCode(${inp.toString()})`); + + expect(result).toBe(String.fromCharCode(...inp)); + }, +); + +test.each([ + { a: 12, b: 23, c: 43 }, + { a: "test", b: "hello", c: "bye" }, + { a: "test", b: 42, c: "bye" }, + { a: "test", b: 42, c: 12 }, +])("Template Strings (%p)", ({ a, b, c }) => { + const a1 = typeof a === "string" ? "'" + a + "'" : a; + const b1 = typeof b === "string" ? "'" + b + "'" : b; + const c1 = typeof c === "string" ? "'" + c + "'" : c; + + const result = util.transpileAndExecute( + "let a = " + a1 + "; let b = " + b1 + "; let c = " + c1 + "; return `${a} ${b} test ${c}`;", + ); + + expect(result).toBe(`${a} ${b} test ${c}`); +}); + +test.each([ + { inp: "hello test", searchValue: "", replaceValue: "" }, + { inp: "hello test", searchValue: " ", replaceValue: "" }, + { inp: "hello test", searchValue: "hello", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "world" }, +])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { + const result = util.transpileAndExecute( + `return "${inp}".replace("${searchValue}", "${replaceValue}");`, + ); + + expect(result).toBe(inp.replace(searchValue, replaceValue)); +}); + +test.each([ + { inp: ["", ""], expected: "" }, + { inp: ["hello", "test"], expected: "hellotest" }, + { inp: ["hello", "test", "bye"], expected: "hellotestbye" }, + { inp: ["hello", 42], expected: "hello42" }, + { inp: [42, "hello"], expected: "42hello" }, +])("string.concat[+] (%p)", ({ inp, expected }) => { + const concatStr = inp.map(elem => (typeof elem === "string" ? `"${elem}"` : elem)).join(" + "); + + const result = util.transpileAndExecute(`return ${concatStr}`); + + expect(result).toBe(expected); +}); + +test.each([ + { str: "", param: ["", ""] }, + { str: "hello", param: ["test"] }, + { str: "hello", param: [] }, + { str: "hello", param: ["test", "bye"] }, +])("string.concatFct (%p)", ({ str, param }) => { + const paramStr = param.map(elem => `"${elem}"`).join(", "); + const result = util.transpileAndExecute(`return "${str}".concat(${paramStr})`); + expect(result).toBe(str.concat(...param)); +}); + +test.each([ + { inp: "hello test", searchValue: "" }, + { inp: "hello test", searchValue: "t" }, + { inp: "hello test", searchValue: "h" }, + { inp: "hello test", searchValue: "invalid" }, +])("string.indexOf (%p)", ({ inp, searchValue }) => { + const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}")`); + + expect(result).toBe(inp.indexOf(searchValue)); +}); + +test.each([ + { inp: "hello test", searchValue: "t", offset: 5 }, + { inp: "hello test", searchValue: "t", offset: 6 }, + { inp: "hello test", searchValue: "t", offset: 7 }, + { inp: "hello test", searchValue: "h", offset: 4 }, +])("string.indexOf with offset (%p)", ({ inp, searchValue, offset }) => { + const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}", ${offset})`); + + expect(result).toBe(inp.indexOf(searchValue, offset)); +}); + +test.each([ + { inp: "hello test", searchValue: "t", x: 4, y: 3 }, + { inp: "hello test", searchValue: "h", x: 3, y: 4 }, +])("string.indexOf with offset expression (%p)", ({ inp, searchValue, x, y }) => { + const result = util.transpileAndExecute( + `return "${inp}".indexOf("${searchValue}", 2 > 1 && ${x} || ${y})`, + ); + + expect(result).toBe(inp.indexOf(searchValue, x)); +}); + +test.each([ + { inp: "hello test" }, + { inp: "hello test", start: 0 }, + { inp: "hello test", start: 1 }, + { inp: "hello test", start: 1, end: 2 }, + { inp: "hello test", start: 1, end: 5 }, +])("string.slice (%p)", ({ inp, start, end }) => { + const paramStr = start ? (end ? `${start}, ${end}` : `${start}`) : ""; + const result = util.transpileAndExecute(`return "${inp}".slice(${paramStr})`); + + expect(result).toBe(inp.slice(start, end)); +}); + +test.each([ + { inp: "hello test", start: 0 }, + { inp: "hello test", start: 1 }, + { inp: "hello test", start: 1, end: 2 }, + { inp: "hello test", start: 1, end: 5 }, +])("string.substring (%p)", ({ inp, start, end }) => { + const paramStr = end ? `${start}, ${end}` : `${start}`; + const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); + + expect(result).toBe(inp.substring(start, end)); +}); + +test.each([ + { inp: "hello test", start: 1, ignored: 0 }, + { inp: "hello test", start: 3, ignored: 0, end: 5 }, +])("string.substring with expression (%p)", ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); + + expect(result).toBe(inp.substring(start, end)); +}); + +test.each([ + { inp: "hello test", start: 0 }, + { inp: "hello test", start: 1 }, + { inp: "hello test", start: 1, end: 2 }, + { inp: "hello test", start: 1, end: 5 }, +])("string.substr (%p)", ({ inp, start, end }) => { + const paramStr = end ? `${start}, ${end}` : `${start}`; + const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); + + expect(result).toBe(inp.substr(start, end)); +}); + +test.each([ + { inp: "hello test", start: 1, ignored: 0 }, + { inp: "hello test", start: 3, ignored: 0, end: 2 }, +])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); + + expect(result).toBe(inp.substr(start, end)); +}); + +test.each([{ inp: "", expected: 0 }, { inp: "h", expected: 1 }, { inp: "hello", expected: 5 }])( + "string.length (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute(`return "${inp}".length`); + + expect(result).toBe(inp.length); + }, +); + +test.each(["hello TEST"])("string.toLowerCase (%p)", inp => { + const result = util.transpileAndExecute(`return "${inp}".toLowerCase()`); + + expect(result).toBe(inp.toLowerCase()); +}); + +test.each(["hello test"])("string.toUpperCase (%p)", inp => { + const result = util.transpileAndExecute(`return "${inp}".toUpperCase()`); + + expect(result).toBe(inp.toUpperCase()); +}); + +test.each([ + { inp: "hello test", separator: "" }, + { inp: "hello test", separator: " " }, + { inp: "hello test", separator: "h" }, + { inp: "hello test", separator: "t" }, + { inp: "hello test", separator: "l" }, + { inp: "hello test", separator: "invalid" }, + { inp: "hello test", separator: "hello test" }, +])("string.split (%p)", ({ inp, separator }) => { + const result = util.transpileAndExecute(`return JSONStringify("${inp}".split("${separator}"))`); + + expect(result).toBe(JSON.stringify(inp.split(separator))); +}); + +test.each([ + { inp: "hello test", index: 1 }, + { inp: "hello test", index: 2 }, + { inp: "hello test", index: 3 }, + { inp: "hello test", index: 99 }, +])("string.charAt (%p)", ({ inp, index }) => { + const result = util.transpileAndExecute(`return "${inp}".charAt(${index})`); + + expect(result).toBe(inp.charAt(index)); +}); + +test.each([ + { inp: "hello test", index: 1 }, + { inp: "hello test", index: 2 }, + { inp: "hello test", index: 3 }, +])("string.charCodeAt (%p)", ({ inp, index }) => { + const result = util.transpileAndExecute(`return "${inp}".charCodeAt(${index})`); + + expect(result).toBe(inp.charCodeAt(index)); +}); + +test.each([ + { inp: "hello test", index: 1, ignored: 0 }, + { inp: "hello test", index: 1, ignored: 2 }, + { inp: "hello test", index: 3, ignored: 2 }, + { inp: "hello test", index: 3, ignored: 99 }, +])("string.charAt with expression (%p)", ({ inp, index, ignored }) => { + const result = util.transpileAndExecute( + `return "${inp}".charAt(2 > 1 && ${index} || ${ignored})`, + ); + + expect(result).toBe(inp.charAt(index)); +}); + +test.each([ + { input: "abcd", index: 3 }, + { input: "abcde", index: 3 }, + { input: "abcde", index: 0 }, + { input: "a", index: 0 }, +])("string index (%p)", ({ input, index }) => { + const result = util.transpileAndExecute(`return "${input}"[${index}];`); + + expect(result).toBe(input[index]); +}); diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 408443d8e..6e1b0d9df 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -1,10 +1,7 @@ -import { Expect, Test, TestCase } from "alsatian"; -import { TSHelper as tsHelper } from "../../src/TSHelper"; - import * as ts from "typescript"; -import * as util from "../src/util"; - import { DecoratorKind } from "../../src/Decorator"; +import { TSHelper as tsHelper } from "../../src/TSHelper"; +import * as util from "../util"; enum TestEnum { testA = 1, @@ -12,149 +9,153 @@ enum TestEnum { testC = 4, } -export class TSHelperTests { - - @TestCase(TestEnum.testA, "testA") - @TestCase(-1, "unknown") - @TestCase(TestEnum.testA | TestEnum.testB, "unknown") - @Test("EnumName") - public testEnumName(inp, expected): void { - const result = tsHelper.enumName(inp, TestEnum); - - Expect(result).toEqual(expected); - } - - @TestCase(TestEnum.testA, ["testA"]) - @TestCase(-1, []) - @TestCase(TestEnum.testA | TestEnum.testC, ["testA", "testC"]) - @TestCase(TestEnum.testA | TestEnum.testB | TestEnum.testC, ["testA", "testB", "testC"]) - @Test("EnumNames") - public testEnumNames(inp, expected): void { - const result = tsHelper.enumNames(inp, TestEnum); - - Expect(result).toEqual(expected); - } - - @Test("IsFileModuleNull") - public isFileModuleNull(): void { - Expect(tsHelper.isFileModule(undefined)).toEqual(false); - } - - @Test("GetCustomDecorators single") - public GetCustomDecoratorsSingle(): void { - const source = `/** @compileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1;`; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - Expect(decorators.size).toBe(1); - Expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } - - @Test("GetCustomDecorators multiple") - public GetCustomDecoratorsMultiple(): void { - const source = `/** @compileMembersOnly - * @Phantom */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1;`; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - Expect(decorators.size).toBe(2); - Expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - Expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - } - - @Test("GetCustomDecorators single jsdoc") - public GetCustomDecoratorsSingleJSDoc(): void { - const source = `/** @compileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1;`; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - Expect(decorators.size).toBe(1); - Expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } - - @Test("GetCustomDecorators multiple jsdoc") - public GetCustomDecoratorsMultipleJSDoc(): void { - const source = `/** @phantom - * @CompileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1;`; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - Expect(decorators.size).toBe(2); - Expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - Expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } - - @Test("GetCustomDecorators multiple default jsdoc") - public GetCustomDecoratorsMultipleDefaultJSDoc(): void { - const source = `/** - * @description abc - * @phantom - * @compileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1;`; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - Expect(decorators.size).toBe(2); - Expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - Expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } -} +test.each([ + { inp: TestEnum.testA, expected: "testA" }, + { inp: -1, expected: "unknown" }, + { inp: TestEnum.testA | TestEnum.testB, expected: "unknown" }, +])("EnumName (%p)", ({ inp, expected }) => { + const result = tsHelper.enumName(inp, TestEnum); + + expect(result).toEqual(expected); +}); + +test.each([ + { inp: TestEnum.testA, expected: ["testA"] }, + { inp: -1, expected: [] }, + { inp: TestEnum.testA | TestEnum.testC, expected: ["testA", "testC"] }, + { + inp: TestEnum.testA | TestEnum.testB | TestEnum.testC, + expected: ["testA", "testB", "testC"], + }, +])("EnumNames (%p)", ({ inp, expected }) => { + const result = tsHelper.enumNames(inp, TestEnum); + + expect(result).toEqual(expected); +}); + +test("IsFileModuleNull", () => { + expect(tsHelper.isFileModule(undefined)).toEqual(false); +}); + +test("GetCustomDecorators single", () => { + const source = ` + /** @compileMembersOnly */ + enum TestEnum { + val1 = 0, + val2 = 2, + val3, + val4 = "bye", + } + + const a = TestEnum.val1; + `; + + const [sourceFile, typeChecker] = util.parseTypeScript(source); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(1); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); +}); + +test("GetCustomDecorators multiple", () => { + const source = ` + /** @compileMembersOnly + * @Phantom */ + enum TestEnum { + val1 = 0, + val2 = 2, + val3, + val4 = "bye", + } + + const a = TestEnum.val1; + `; + + const [sourceFile, typeChecker] = util.parseTypeScript(source); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); +}); + +test("GetCustomDecorators single jsdoc", () => { + const source = ` + /** @compileMembersOnly */ + enum TestEnum { + val1 = 0, + val2 = 2, + val3, + val4 = "bye", + } + + const a = TestEnum.val1; + `; + + const [sourceFile, typeChecker] = util.parseTypeScript(source); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(1); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); +}); + +test("GetCustomDecorators multiple jsdoc", () => { + const source = ` + /** @phantom + * @CompileMembersOnly */ + enum TestEnum { + val1 = 0, + val2 = 2, + val3, + val4 = "bye", + } + + const a = TestEnum.val1; + `; + + const [sourceFile, typeChecker] = util.parseTypeScript(source); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); +}); + +test("GetCustomDecorators multiple default jsdoc", () => { + const source = ` + /** + * @description abc + * @phantom + * @compileMembersOnly */ + enum TestEnum { + val1 = 0, + val2 = 2, + val3, + val4 = "bye", + } + + const a = TestEnum.val1; + `; + + const [sourceFile, typeChecker] = util.parseTypeScript(source); + const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); +}); diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 5de08527b..41fa43676 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -1,388 +1,353 @@ -import { Expect, Test, TestCase } from "alsatian"; -import * as util from "../src/util"; - -export class TupleTests { - @Test("Tuple loop") - public tupleLoop(): void - { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - let count = 0; - for (const value of tuple) { count += value; } - return count;` - ); - - // Assert - Expect(result).toBe(9); - } - - @Test("Tuple foreach") - public tupleForEach(): void - { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - let count = 0; - tuple.forEach(v => count += v); - return count;` - ); - - // Assert - Expect(result).toBe(9); - } - - @Test("Tuple access") - public tupleAccess(): void - { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - return tuple[1];` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("Tuple union access") - public tupleUnionAccess(): void - { - const result = util.transpileAndExecute( - `function makeTuple(): [number, number, number] | [string, string, string] { return [3,5,1]; } - const tuple = makeTuple(); - return tuple[1];` - ); - Expect(result).toBe(5); - } - - @Test("Tuple intersection access") - public tupleIntersectionAccess(): void - { - const result = util.transpileAndExecute( - `type I = [number, number, number] & {foo: string}; - function makeTuple(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const tuple = makeTuple(); - return tuple[1];` - ); - Expect(result).toBe(5); - } - - @Test("Tuple Destruct") - public tupleDestruct(): void - { - const result = util.transpileAndExecute( - `function tuple(): [number, number, number] { return [3,5,1]; } - const [a,b,c] = tuple(); - return b;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("Tuple length") - public tupleLength(): void - { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - return tuple.length;` - ); - - // Assert - Expect(result).toBe(3); - } - - @Test("Tuple Return Access") - public tupleReturnAccess(): void - { - const result = util.transpileAndExecute( - `/** @tupleReturn */ - function tuple(): [number, number, number] { return [3,5,1]; } - return tuple()[2];` - ); - - // Assert - Expect(result).toBe(1); - } - - @Test("Tuple Return Destruct Declaration") - public tupleReturnDestructDeclaration(): void - { - const result = util.transpileAndExecute( - `/** @tupleReturn */ - function tuple(): [number, number, number] { return [3,5,1]; } - const [a,b,c] = tuple(); - return b;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("Tuple Return Destruct Assignment") - public tupleReturnDestructAssignment(): void - { - const result = util.transpileAndExecute( - `/** @tupleReturn */ - function tuple(): [number, number] { return [3,6]; } - let [a,b] = [1,2]; - [b,a] = tuple(); - return a - b;` - ); - - // Assert - Expect(result).toBe(3); - } - - @Test("Tuple Static Method Return Destruct") - public tupleStaticMethodReturnDestruct(): void - { - const result = util.transpileAndExecute( - `class Test { - /** @tupleReturn */ - static tuple(): [number, number, number] { return [3,5,1]; } - } - const [a,b,c] = Test.tuple(); - return b;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("Tuple Non-Static Method Return Destruct") - public tupleMethodNonStaticReturnDestruct(): void - { - const result = util.transpileAndExecute( - `class Test { - /** @tupleReturn */ - tuple(): [number, number, number] { return [3,5,1]; } - } - const t = new Test(); - const [a,b,c] = t.tuple(); - return b;` - ); - - // Assert - Expect(result).toBe(5); - } - - @Test("Tuple Return on Arrow Function") - public tupleReturnOnArrowFunction(): void { - const code = - `const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; - const [a, b] = fn("foo"); - return a + b;`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return Inference") - public tupleReturnInference(): void { - const code = - `/** @tupleReturn */ interface Fn { (s: string): [string, string] } - const fn: Fn = s => [s, "bar"]; +import * as util from "../util"; + +test("Tuple loop", () => { + const result = util.transpileAndExecute( + `const tuple: [number, number, number] = [3,5,1]; + let count = 0; + for (const value of tuple) { count += value; } + return count;`, + ); + + expect(result).toBe(9); +}); + +test("Tuple foreach", () => { + const result = util.transpileAndExecute( + `const tuple: [number, number, number] = [3,5,1]; + let count = 0; + tuple.forEach(v => count += v); + return count;`, + ); + + expect(result).toBe(9); +}); + +test("Tuple access", () => { + const result = util.transpileAndExecute( + `const tuple: [number, number, number] = [3,5,1]; + return tuple[1];`, + ); + + expect(result).toBe(5); +}); + +test("Tuple union access", () => { + const result = util.transpileAndExecute( + `function makeTuple(): [number, number, number] | [string, string, string] { return [3,5,1]; } + const tuple = makeTuple(); + return tuple[1];`, + ); + expect(result).toBe(5); +}); + +test("Tuple intersection access", () => { + const result = util.transpileAndExecute( + `type I = [number, number, number] & {foo: string}; + function makeTuple(): I { + let t = [3,5,1]; + (t as I).foo = "bar"; + return (t as I); + } + const tuple = makeTuple(); + return tuple[1];`, + ); + expect(result).toBe(5); +}); + +test("Tuple Destruct", () => { + const result = util.transpileAndExecute( + `function tuple(): [number, number, number] { return [3,5,1]; } + const [a,b,c] = tuple(); + return b;`, + ); + + expect(result).toBe(5); +}); + +test("Tuple length", () => { + const result = util.transpileAndExecute( + `const tuple: [number, number, number] = [3,5,1]; + return tuple.length;`, + ); + + expect(result).toBe(3); +}); + +test("Tuple Return Access", () => { + const result = util.transpileAndExecute( + `/** @tupleReturn */ + function tuple(): [number, number, number] { return [3,5,1]; } + return tuple()[2];`, + ); + + expect(result).toBe(1); +}); + +test("Tuple Return Destruct Declaration", () => { + const result = util.transpileAndExecute( + `/** @tupleReturn */ + function tuple(): [number, number, number] { return [3,5,1]; } + const [a,b,c] = tuple(); + return b;`, + ); + + expect(result).toBe(5); +}); + +test("Tuple Return Destruct Assignment", () => { + const result = util.transpileAndExecute( + `/** @tupleReturn */ + function tuple(): [number, number] { return [3,6]; } + let [a,b] = [1,2]; + [b,a] = tuple(); + return a - b;`, + ); + + expect(result).toBe(3); +}); + +test("Tuple Static Method Return Destruct", () => { + const result = util.transpileAndExecute( + `class Test { + /** @tupleReturn */ + static tuple(): [number, number, number] { return [3,5,1]; } + } + const [a,b,c] = Test.tuple(); + return b;`, + ); + + expect(result).toBe(5); +}); + +test("Tuple Non-Static Method Return Destruct", () => { + const result = util.transpileAndExecute( + `class Test { + /** @tupleReturn */ + tuple(): [number, number, number] { return [3,5,1]; } + } + const t = new Test(); + const [a,b,c] = t.tuple(); + return b;`, + ); + + expect(result).toBe(5); +}); + +test("Tuple Return on Arrow Function", () => { + const code = ` + const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; + const [a, b] = fn("foo"); + return a + b; + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return Inference", () => { + const code = ` + /** @tupleReturn */ interface Fn { (s: string): [string, string] } + const fn: Fn = s => [s, "bar"]; + const [a, b] = fn("foo"); + return a + b; + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return Inference as Argument", () => { + const code = ` + /** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(fn: Fn) { const [a, b] = fn("foo"); - return a + b;`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return Inference as Argument") - public tupleReturnInferenceAsArgument(): void { - const code = - `/** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(fn: Fn) { - const [a, b] = fn("foo"); - return a + b; - } - return foo(s => [s, "bar"]);`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return Inference as Elipsis Argument") - public tupleReturnInferenceAsElipsisArgument(): void { - const code = - `/** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(a: number, ...fn: Fn[]) { - const [a, b] = fn[0]("foo"); - return a + b; - } - return foo(7, s => [s, "bar"]);`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return Inference as Elipsis Tuple Argument") - public tupleReturnInferenceAsElipsisTupleArgument(): void { - const code = - `/** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(a: number, ...fn: [number, Fn]) { - const [a, b] = fn[1]("foo"); - return a + b; - } - return foo(7, 17, s => [s, "bar"]);`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return in Spread") - public tupleReturnInSpread(): void { - const code = - `/** @tupleReturn */ function foo(): [string, string] { - return ["foo", "bar"]; - } - function bar(a: string, b: string) { - return a + b; + return a + b; + } + return foo(s => [s, "bar"]); + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return Inference as Elipsis Argument", () => { + const code = ` + /** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(a: number, ...fn: Fn[]) { + const [a, b] = fn[0]("foo"); + return a + b; + } + return foo(7, s => [s, "bar"]); + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return Inference as Elipsis Tuple Argument", () => { + const code = ` + /** @tupleReturn */ interface Fn { (s: string): [string, string] } + function foo(a: number, ...fn: [number, Fn]) { + const [a, b] = fn[1]("foo"); + return a + b; + } + return foo(7, 17, s => [s, "bar"]); + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return in Spread", () => { + const code = ` + /** @tupleReturn */ function foo(): [string, string] { + return ["foo", "bar"]; + } + function bar(a: string, b: string) { + return a + b; + } + return bar(...foo()); + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + +test("Tuple Return on Type Alias", () => { + const code = ` + /** @tupleReturn */ type Fn = () => [number, number]; + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b; + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(3); +}); + +test("Tuple Return on Interface", () => { + const code = ` + /** @tupleReturn */ interface Fn { (): [number, number]; } + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b; + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(3); +}); + +test("Tuple Return on Interface Signature", () => { + const code = ` + interface Fn { + /** @tupleReturn */ (): [number, number]; + } + const fn: Fn = () => [1, 2]; + const [a, b] = fn(); + return a + b; + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(3); +}); + +test("Tuple Return on Overload", () => { + const code = ` + function fn(a: number): number; + /** @tupleReturn */ function fn(a: string, b: string): [string, string]; + function fn(a: number | string, b?: string): number | [string, string] { + if (typeof a === "number") { + return a; + } else { + return [a, b as string]; } - return bar(...foo());`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("foobar"); - } - - @Test("Tuple Return on Type Alias") - public tupleReturnOnTypeAlias(): void { - const code = - `/** @tupleReturn */ type Fn = () => [number, number]; - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b;`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe(3); - } - - @Test("Tuple Return on Interface") - public tupleReturnOnInterface(): void { - const code = - `/** @tupleReturn */ interface Fn { (): [number, number]; } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b;`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe(3); - } - - @Test("Tuple Return on Interface Signature") - public tupleReturnOnInterfaceSignature(): void { - const code = - `interface Fn { - /** @tupleReturn */ (): [number, number]; + } + const a = fn(3); + const [b, c] = fn("foo", "bar"); + return a + b + c + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("3foobar"); +}); + +test("Tuple Return on Interface Overload", () => { + const code = ` + interface Fn { + (a: number): number; + /** @tupleReturn */ (a: string, b: string): [string, string]; + } + const fn = ((a: number | string, b?: string): number | [string, string] => { + if (typeof a === "number") { + return a; + } else { + return [a, b as string]; } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b;`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe(3); - } - - @Test("Tuple Return on Overload") - public tupleReturnOnOverload(): void { - const code = - `function fn(a: number): number; - /** @tupleReturn */ function fn(a: string, b: string): [string, string]; - function fn(a: number | string, b?: string): number | [string, string] { + }) as Fn; + const a = fn(3); + const [b, c] = fn("foo", "bar"); + return a + b + c + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("3foobar"); +}); + +test("Tuple Return on Interface Method Overload", () => { + const code = ` + interface Foo { + foo(a: number): number; + /** @tupleReturn */ foo(a: string, b: string): [string, string]; + } + const bar = ({ + foo: (a: number | string, b?: string): number | [string, string] => { if (typeof a === "number") { return a; } else { return [a, b as string]; } } - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("3foobar"); - } - - @Test("Tuple Return on Interface Overload") - public tupleReturnOnInterfaceOverload(): void { - const code = - `interface Fn { - (a: number): number; - /** @tupleReturn */ (a: string, b: string): [string, string]; - } - const fn = ((a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - }) as Fn; - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("3foobar"); - } - - @Test("Tuple Return on Interface Method Overload") - public tupleReturnOnInterfaceMethodOverload(): void { - const code = - `interface Foo { - foo(a: number): number; - /** @tupleReturn */ foo(a: string, b: string): [string, string]; - } - const bar = ({ - foo: (a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - } - }) as Foo; - const a = bar.foo(3); - const [b, c] = bar.foo("foo", "bar"); - return a + b + c`; - const lua = util.transpileString(code); - Expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - Expect(result).toBe("3foobar"); - } - - @Test("Tuple Return vs Non-Tuple Return Overload") - public tupleReturnVsNonTupleReturnOverload(): void { - const luaHeader = - `function fn(a, b) - if type(a) == "number" then - return {a, a + 1} - else - return a, b - end - end`; - const tsHeader = - `declare function fn(this: void, a: number): [number, number]; - /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string];`; - const code = - `const [a, b] = fn(3); - const [c, d] = fn("foo", "bar"); - return (a + b) + c + d;`; - const result = util.transpileAndExecute(code, undefined, luaHeader, tsHeader); - Expect(result).toBe("7foobar"); - } -} + }) as Foo; + const a = bar.foo(3); + const [b, c] = bar.foo("foo", "bar"); + return a + b + c + `; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("3foobar"); +}); + +test("Tuple Return vs Non-Tuple Return Overload", () => { + const luaHeader = ` + function fn(a, b) + if type(a) == "number" then + return {a, a + 1} + else + return a, b + end + end + `; + const tsHeader = ` + declare function fn(this: void, a: number): [number, number]; + /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string]; + `; + const code = ` + const [a, b] = fn(3); + const [c, d] = fn("foo", "bar"); + return (a + b) + c + d; + `; + const result = util.transpileAndExecute(code, undefined, luaHeader, tsHeader); + expect(result).toBe("7foobar"); +}); diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index 533c0d3d0..e52337405 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -1,149 +1,112 @@ -import { Expect, Test, TestCase } from "alsatian"; - -import * as util from "../src/util"; -import { TranspileError } from "../../src/TranspileError"; - -export class TypeCheckingTests { - @TestCase("0") - @TestCase("30") - @TestCase("30_000") - @TestCase("30.00") - @Test("typeof number") - public typeofNumberTest(inp: string): void - { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - Expect(result).toBe("number"); - } - - @TestCase("\"abc\"") - @TestCase("`abc`") - @Test("typeof string") - public typeofStringTest(inp: string): void - { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - Expect(result).toBe("string"); - } - - @TestCase("false") - @TestCase("true") - @Test("typeof boolean") - public typeofBooleanTest(inp: string): void - { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - Expect(result).toBe("boolean"); - } - - @TestCase("{}") - @TestCase("[]") - @Test("typeof object literal") - public typeofObjectLiteral(inp: string): void - { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - Expect(result).toBe("object"); - } - - @Test("typeof class instance") - public typeofClassInstance(): void - { - const result = util.transpileAndExecute(`class myClass {} let inst = new myClass(); return typeof inst;`); - - Expect(result).toBe("object"); - } - - @Test("typeof function") - public typeofFunction(): void - { - const result = util.transpileAndExecute(`return typeof (() => 3);`); - - Expect(result).toBe("function"); - } - - @TestCase("null") - @TestCase("undefined") - @Test("typeof undefined") - public typeofUndefinedTest(inp: string): void - { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - Expect(result).toBe("nil"); - } - - @Test("instanceof") - public instanceOf(): void - { - const result = util.transpileAndExecute( - "class myClass {} let inst = new myClass(); return inst instanceof myClass;" - ); - - Expect(result).toBeTruthy(); - } - - @Test("instanceof inheritance") - public instanceOfInheritance(): void - { - const result = util.transpileAndExecute("class myClass {}\n" - + "class childClass extends myClass{}\n" - + "let inst = new childClass(); return inst instanceof myClass;"); - - Expect(result).toBeTruthy(); - } - - @Test("instanceof inheritance false") - public instanceOfInheritanceFalse(): void - { - const result = util.transpileAndExecute("class myClass {}\n" - + "class childClass extends myClass{}\n" - + "let inst = new myClass(); return inst instanceof childClass;"); - - Expect(result).toBe(false); - } - - @Test("null instanceof Object") - public nullInstanceOf(): void - { - const result = util.transpileAndExecute("return (null) instanceof Object;"); - - Expect(result).toBe(false); - } - - @Test("null instanceof Class") - public nullInstanceOfClass(): void - { - const result = util.transpileAndExecute("class myClass {} return (null) instanceof myClass;"); - - Expect(result).toBe(false); - } - - @TestCase("extension") - @TestCase("metaExtension") - @Test("instanceof extension") - public instanceOfExtension(extensionType: string): void { - const code = - `declare class A {} - /** @${extensionType} **/ - class B extends A {} - declare const foo: any; - const result = foo instanceof B;`; - Expect(() => util.transpileString(code)).toThrowError( - TranspileError, - "Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'." - ); - } - - @Test("instanceof export") - public instanceOfExport(): void - { - const result = util.transpileExecuteAndReturnExport( - `export class myClass {} - let inst = new myClass(); - export const result = inst instanceof myClass;`, - "result" - ); - - Expect(result).toBeTruthy(); - } -} +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +test.each(["0", "30", "30_000", "30.00"])("typeof number (%p)", inp => { + const result = util.transpileAndExecute(`return typeof ${inp};`); + + expect(result).toBe("number"); +}); + +test.each(['"abc"', "`abc`"])("typeof string (%p)", inp => { + const result = util.transpileAndExecute(`return typeof ${inp};`); + + expect(result).toBe("string"); +}); + +test.each(["false", "true"])("typeof boolean (%p)", inp => { + const result = util.transpileAndExecute(`return typeof ${inp};`); + + expect(result).toBe("boolean"); +}); + +test.each(["{}", "[]"])("typeof object literal (%p)", inp => { + const result = util.transpileAndExecute(`return typeof ${inp};`); + + expect(result).toBe("object"); +}); + +test("typeof class instance", () => { + const result = util.transpileAndExecute( + `class myClass {} let inst = new myClass(); return typeof inst;`, + ); + + expect(result).toBe("object"); +}); + +test("typeof function", () => { + const result = util.transpileAndExecute(`return typeof (() => 3);`); + + expect(result).toBe("function"); +}); + +test.each(["null", "undefined"])("typeof undefined (%p)", inp => { + const result = util.transpileAndExecute(`return typeof ${inp};`); + + expect(result).toBe("nil"); +}); + +test("instanceof", () => { + const result = util.transpileAndExecute( + "class myClass {} let inst = new myClass(); return inst instanceof myClass;", + ); + + expect(result).toBeTruthy(); +}); + +test("instanceof inheritance", () => { + const result = util.transpileAndExecute(` + class myClass {} + class childClass extends myClass{} + let inst = new childClass(); return inst instanceof myClass; + `); + + expect(result).toBeTruthy(); +}); + +test("instanceof inheritance false", () => { + const result = util.transpileAndExecute(` + class myClass {} + class childClass extends myClass{} + let inst = new myClass(); return inst instanceof childClass; + `); + + expect(result).toBe(false); +}); + +test("null instanceof Object", () => { + const result = util.transpileAndExecute("return (null) instanceof Object;"); + + expect(result).toBe(false); +}); + +test("null instanceof Class", () => { + const result = util.transpileAndExecute( + "class myClass {} return (null) instanceof myClass;", + ); + + expect(result).toBe(false); +}); + +test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { + const code = ` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + declare const foo: any; + const result = foo instanceof B; + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.InvalidInstanceOfExtension(util.nodeStub), + ); +}); + +test("instanceof export", () => { + const result = util.transpileExecuteAndReturnExport( + `export class myClass {} + let inst = new myClass(); + export const result = inst instanceof myClass;`, + "result", + ); + + expect(result).toBeTruthy(); +}); diff --git a/test/src/util.ts b/test/util.ts similarity index 51% rename from test/src/util.ts rename to test/util.ts index ec3f0cf73..73d338434 100644 --- a/test/src/util.ts +++ b/test/util.ts @@ -1,47 +1,86 @@ +import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; +import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; +import { + createStringCompilerProgram, + transpileString as compilerTranspileString, +} from "../src/Compiler"; +import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../src/CompilerOptions"; +import { LuaTransformer } from "../src/LuaTransformer"; + +export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); + +declare global { + namespace jest { + interface Matchers { + toThrowExactError(error: Error): void; + } + } +} -import { Expect } from "alsatian"; +expect.extend({ + toThrowExactError( + callback: () => void, + error: Error, + ): { pass: boolean; message: () => string } { + if (this.isNot) { + return { pass: true, message: () => "Inverted toThrowExactError is not implemented" }; + } -import { transpileString as compilerTranspileString, createStringCompilerProgram } from "../../src/Compiler"; -import { CompilerOptions, LuaTarget, LuaLibImportKind } from "../../src/CompilerOptions"; + let executionError: Error | undefined; + try { + callback(); + } catch (err) { + executionError = err; + } -import {lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; + expect(() => { + if (executionError) throw executionError; + }).toThrowError(error.constructor as any); + expect(() => { + if (executionError) throw executionError; + }).toThrowError(error); -import * as fs from "fs"; -import { LuaTransformer } from "../../src/LuaTransformer"; + return { pass: true, message: () => "" }; + }, +}); export function transpileString( str: string | { [filename: string]: string }, - options?: CompilerOptions, + options: CompilerOptions = {}, ignoreDiagnostics = true, - filePath = "file.ts" -): string -{ - if (ignoreDiagnostics === false) { - ignoreDiagnostics = process.argv[2] === "--ignoreDiagnostics"; - } - if (options) { - if (options.noHeader === undefined) { - options.noHeader = true; - } - return compilerTranspileString(str, options, ignoreDiagnostics, filePath); - } else { - return compilerTranspileString( - str, - { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - noHeader: true, - }, - ignoreDiagnostics, - filePath - ); - } + filePath = "file.ts", +): string { + return compilerTranspileString( + str, + { + luaLibImport: LuaLibImportKind.Inline, + luaTarget: LuaTarget.Lua53, + noHeader: true, + skipLibCheck: true, + target: ts.ScriptTarget.ESNext, + lib: [ + "lib.es2015.d.ts", + "lib.es2016.d.ts", + "lib.es2017.d.ts", + "lib.es2018.d.ts", + "lib.esnext.d.ts", + ], + ...options, + }, + ignoreDiagnostics, + filePath, + ); } +const lualibContent = fs.readFileSync( + path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), + "utf8", +); +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; export function executeLua(luaStr: string, withLib = true): any { + luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); if (withLib) { luaStr = minimalTestLib + luaStr; } @@ -61,7 +100,10 @@ export function executeLua(luaStr: string, withLib = true): any { } else if (lua.lua_isstring(L, -1)) { return lua.lua_tojsstring(L, -1); } else { - throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); + throw new Error( + "Unsupported lua return type: " + + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))), + ); } } else { // If the lua VM did not terminate with status code LUA_OK an error occurred. @@ -72,21 +114,9 @@ export function executeLua(luaStr: string, withLib = true): any { } } -export function expectCodeEqual(code1: string, code2: string): void { - // Trim leading/trailing whitespace - let c1 = code1.trim(); - let c2 = code2.trim(); - - // Unify indentation - c1 = c1.replace(/\s+/g, " "); - c2 = c2.replace(/\s+/g, " "); - - Expect(c1).toBe(c2); -} - // Get a mock transformer to use for testing export function makeTestTransformer(target: LuaTarget = LuaTarget.Lua53): LuaTransformer { - const options = {luaTarget: target}; + const options = { luaTarget: target }; return new LuaTransformer(ts.createProgram([], options), options); } @@ -95,15 +125,13 @@ export function transpileAndExecute( compilerOptions?: CompilerOptions, luaHeader?: string, tsHeader?: string, - ignoreDiagnosticsOverride = process.argv[2] === "--ignoreDiagnostics" -): any -{ +): any { const wrappedTsString = `${tsHeader ? tsHeader : ""} declare function JSONStringify(this: void, p: any): string; function __runTest(this: void): any {${tsStr}}`; const lua = `${luaHeader ? luaHeader : ""} - ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnosticsOverride)} + ${transpileString(wrappedTsString, compilerOptions, false)} return __runTest();`; return executeLua(lua); @@ -113,9 +141,8 @@ export function transpileExecuteAndReturnExport( tsStr: string, returnExport: string, compilerOptions?: CompilerOptions, - luaHeader?: string -): any -{ + luaHeader?: string, +): any { const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; ${tsStr}`; @@ -127,13 +154,18 @@ export function transpileExecuteAndReturnExport( return executeLua(lua); } -export function parseTypeScript(typescript: string, target: LuaTarget = LuaTarget.Lua53) - : [ts.SourceFile, ts.TypeChecker] { +export function parseTypeScript( + typescript: string, + target: LuaTarget = LuaTarget.Lua53, +): [ts.SourceFile, ts.TypeChecker] { const program = createStringCompilerProgram(typescript, { luaTarget: target }); return [program.getSourceFile("file.ts"), program.getTypeChecker()]; } -export function findFirstChild(node: ts.Node, predicate: (node: ts.Node) => boolean): ts.Node | undefined { +export function findFirstChild( + node: ts.Node, + predicate: (node: ts.Node) => boolean, +): ts.Node | undefined { for (const child of node.getChildren()) { if (predicate(child)) { return child; @@ -146,7 +178,3 @@ export function findFirstChild(node: ts.Node, predicate: (node: ts.Node) => bool } return undefined; } - -const jsonlib = fs.readFileSync("test/src/json.lua") + "\n"; - -export const minimalTestLib = jsonlib; diff --git a/tsconfig.json b/tsconfig.json index f214f1bed..84d667105 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,12 +1,11 @@ { "compilerOptions": { - "noImplicitThis" : true, - "alwaysStrict" : true, - "outDir": "./dist/", - "rootDir": "./src/", + "noImplicitThis": true, + "alwaysStrict": true, + "rootDir": "./src", + "outDir": "./dist", "declaration": true, "sourceMap": true, - "experimentalDecorators": true, "target": "es2017", "module": "commonjs" }, diff --git a/tslint.json b/tslint.json index b230c4203..178f3066d 100644 --- a/tslint.json +++ b/tslint.json @@ -1,55 +1,12 @@ { - "defaultSeverity": "error", + "extends": "./test/tslint.json", "rules": { - "array-type": [true, "array-simple"], "arrow-parens": [true, "ban-single-arg-parens"], - "arrow-return-shorthand": true, - "ban": [true, - {"name": "parseInt", "message": "tsstyle#type-coercion"}, - {"name": "parseFloat", "message": "tsstyle#type-coercion"}, - {"name": "Array", "message": "tsstyle#array-constructor"} - ], - "ban-types": [true, - ["Object", "Use {} instead."], - ["String", "Use 'string' instead."], - ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] - ], - "class-name": true, - "curly": [true, "ignore-same-line"], - "deprecation": true, - "forin": false, "import-spacing": true, - "interface-name": [true, "never-prefix"], - "jsdoc-format": true, - "label-position": true, - "max-classes-per-file": [true, 1], "max-line-length": [true, 120], - "member-access": true, "new-parens": true, - "no-angle-bracket-type-assertion": true, - "no-any": false, - "no-arg": true, - "no-conditional-assignment": true, - "no-construct": true, - "no-debugger": true, - "no-default-export": true, - "no-duplicate-switch-case": true, - "no-duplicate-variable": true, - "no-inferrable-types": true, - "no-namespace": [true, "allow-declarations"], - "no-null-keyword": true, - "no-reference": true, - "no-string-throw": true, "no-trailing-whitespace": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-shorthand": true, - "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], - "prefer-const": true, - "radix": true, "semicolon": [true, "always", "ignore-bound-class-methods"], - "switch-default": false, "trailing-comma": [ true, { @@ -62,21 +19,12 @@ "esSpecCompliant": true } ], - "triple-equals": [true, "allow-null-check"], - "typedef": [ + "whitespace": [ true, - "call-signature", - "property-declaration" - ], - "use-isnan": true, - "variable-name": [ - true, - "check-format", - "ban-keywords", - "allow-leading-underscore", - "allow-pascal-case" - ], - "whitespace": [true, "check-type-operator", "check-decl", "check-rest-spread", "check-typecast"] - }, - "rulesDirectory": [] + "check-type-operator", + "check-decl", + "check-rest-spread", + "check-typecast" + ] + } } From 8fb72f4f03a92e0c8693cc42a2dc2ea66e62b0ff Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 27 Mar 2019 23:35:16 +0500 Subject: [PATCH 040/764] Add array.flat and array.flatMap (#496) --- src/LuaLib.ts | 4 ++++ src/LuaTransformer.ts | 4 ++++ src/TSHelper.ts | 2 ++ src/lualib/ArrayFlat.ts | 12 ++++++++++++ src/lualib/ArrayFlatMap.ts | 17 +++++++++++++++++ test/unit/lualib/lualib.spec.ts | 33 +++++++++++++++++++++++++++++++++ 6 files changed, 72 insertions(+) create mode 100644 src/lualib/ArrayFlat.ts create mode 100644 src/lualib/ArrayFlatMap.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 3db60196c..4dc023de0 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -17,6 +17,8 @@ export enum LuaLibFeature { ArraySlice = "ArraySlice", ArraySome = "ArraySome", ArraySplice = "ArraySplice", + ArrayFlat = "ArrayFlat", + ArrayFlatMap = "ArrayFlatMap", ClassIndex = "ClassIndex", ClassNewIndex = "ClassNewIndex", FunctionApply = "FunctionApply", @@ -42,6 +44,8 @@ export enum LuaLibFeature { } const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { + ArrayFlat: [LuaLibFeature.ArrayConcat], + ArrayFlatMap: [LuaLibFeature.ArrayConcat], Iterator: [LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 97b789989..2e5b04d51 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3888,6 +3888,10 @@ export class LuaTransformer { parameters, node ); + case "flat": + return this.transformLuaLibFunction(LuaLibFeature.ArrayFlat, node, caller, ...params); + case "flatMap": + return this.transformLuaLibFunction(LuaLibFeature.ArrayFlatMap, node, caller, ...params); default: throw TSTLErrors.UnsupportedProperty("array", expressionName as string, node); } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index b0326fe3d..717ba023c 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -25,6 +25,8 @@ const defaultArrayCallMethodNames = new Set([ "slice", "splice", "join", + "flat", + "flatMap", ]); const defaultArrayPropertyNames = new Set([ diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts new file mode 100644 index 000000000..4006b51d5 --- /dev/null +++ b/src/lualib/ArrayFlat.ts @@ -0,0 +1,12 @@ +function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { + let result: any[] = []; + for (const value of array) { + if (depth > 0 && type(value) === "table" && 1 in value) { + result = result.concat(__TS__ArrayFlat(value, depth - 1)); + } else { + result[result.length] = value; + } + } + + return result; +} diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts new file mode 100644 index 000000000..9c73db579 --- /dev/null +++ b/src/lualib/ArrayFlatMap.ts @@ -0,0 +1,17 @@ +function __TS__ArrayFlatMap( + this: void, + array: T[], + callback: (value: T, index: number, array: T[]) => U | ReadonlyArray +): U[] { + let result: U[] = []; + for (let i = 0; i < array.length; i++) { + const value = callback(array[i], i, array); + if (type(value) === "table" && 1 in value) { + result = result.concat(value); + } else { + result[result.length] = value as U; + } + } + + return result; +} diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 8c4052562..803ed4858 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -377,6 +377,39 @@ test.each([ expect(result).toBe(JSON.stringify(array.sort(compareFn))); }); +test.each([ + { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, + { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, + { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, + { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, +])("array.flat (%p)", ({ array, depth, expected }) => { + // TODO: Remove once `Infinity` would be implemented + const luaDepth = depth === Infinity ? "1 / 0" : depth; + const result = util.transpileAndExecute(` + return JSONStringify(${JSON.stringify(array)}.flat(${luaDepth})) + `); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { array: [1, [2, 3], [4]], map: (value: T) => value }, + { array: [1, 2, 3], map: (v: number) => v * 2 }, + { array: [1, 2, 3], map: (v: number) => [v, v * 2] }, + { array: [1, 2, 3], map: (v: number) => [v, [v]] }, + { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i] }, +])("array.flatMap (%p)", ({ array, map }) => { + const result = util.transpileAndExecute(` + const array = ${JSON.stringify(array)}; + const result = array.flatMap(${map.toString()}); + return JSONStringify(result); + `); + + // TODO(node 12): array.flatMap(map) + const expected = [].concat(...(array as any[]).map(map)); + expect(JSON.parse(result)).toEqual(expected); +}); + test.each([ { condition: "true", lhs: "4", rhs: "5", expected: 4 }, { condition: "false", lhs: "4", rhs: "5", expected: 5 }, From 02749290b0017bb108d0cf75636db8b1b5bb09ec Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 28 Mar 2019 00:00:03 +0500 Subject: [PATCH 041/764] Add Object.fromEntries (#497) --- src/LuaLib.ts | 2 ++ src/LuaTransformer.ts | 2 ++ src/lualib/ObjectFromEntries.ts | 24 ++++++++++++++++++++ test/unit/lualib/lualib.spec.ts | 39 ++++++++++++++++++++++++++++++++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 src/lualib/ObjectFromEntries.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 4dc023de0..6bf97c411 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -31,6 +31,7 @@ export enum LuaLibFeature { NewIndex = "NewIndex", ObjectAssign = "ObjectAssign", ObjectEntries = "ObjectEntries", + ObjectFromEntries = "ObjectFromEntries", ObjectKeys = "ObjectKeys", ObjectValues = "ObjectValues", Set = "Set", @@ -47,6 +48,7 @@ const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], Iterator: [LuaLibFeature.Symbol], + ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2e5b04d51..3a7d8dcad 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3707,6 +3707,8 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...parameters); case "entries": return this.transformLuaLibFunction(LuaLibFeature.ObjectEntries, expression, ...parameters); + case "fromEntries": + return this.transformLuaLibFunction(LuaLibFeature.ObjectFromEntries, expression, ...parameters); case "keys": return this.transformLuaLibFunction(LuaLibFeature.ObjectKeys, expression, ...parameters); case "values": diff --git a/src/lualib/ObjectFromEntries.ts b/src/lualib/ObjectFromEntries.ts new file mode 100644 index 000000000..efdf7dd90 --- /dev/null +++ b/src/lualib/ObjectFromEntries.ts @@ -0,0 +1,24 @@ +function __TS__ObjectFromEntries( + this: void, + entries: ReadonlyArray<[string, T]> | Iterable<[string, T]> +): Record { + const obj: Record = {}; + + const iterable = entries as Iterable<[string, T]>; + if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) break; + + const value: [string, T] = result.value; + obj[value[0]] = value[1]; + } + } else { + for (const entry of entries as ReadonlyArray<[string, T]>) { + obj[entry[0]] = entry[1]; + } + } + + return obj; +} diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 803ed4858..87913fd84 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -441,7 +441,7 @@ test.each([ { initial: "{}", parameters: "{a: 3}", expected: { a: 3 } }, { initial: "{a: 3}", parameters: "{a: 5}", expected: { a: 5 } }, { initial: "{a: 3}", parameters: "{b: 5},{c: 7}", expected: { a: 3, b: 5, c: 7 } }, -])("Object.Assign (%p)", ({ initial, parameters, expected }) => { +])("Object.assign (%p)", ({ initial, parameters, expected }) => { const jsonResult = util.transpileAndExecute(` return JSONStringify(Object.assign(${initial},${parameters})); `); @@ -517,3 +517,40 @@ test.each([ } } }); + +// https://github.com/Microsoft/TypeScript/pull/26149 +const objectFromEntriesDeclaration = ` + interface ObjectConstructor { + fromEntries(entries: ReadonlyArray<[string, T]> | Iterable<[string, T]>): Record; + fromEntries(entries: ReadonlyArray<[string, any]> | Iterable<[string, any]>): Record; + } +`; + +test.each([ + { entries: [], expected: [] }, + { entries: [["a", 1], ["b", 2]], expected: { a: 1, b: 2 } }, + { entries: [["a", 1], ["a", 2]], expected: { a: 2 } }, +])("Object.fromEntries (%p)", ({ entries, expected }) => { + const result = util.transpileAndExecute( + `const obj = Object.fromEntries(${JSON.stringify(entries)}); + return JSONStringify(obj);`, + undefined, + undefined, + objectFromEntriesDeclaration, + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test("Object.fromEntries (Map)", () => { + const result = util.transpileAndExecute( + `const map = new Map([["foo", "bar"]]); + const obj = Object.fromEntries(map); + return JSONStringify(obj);`, + undefined, + undefined, + objectFromEntriesDeclaration, + ); + + expect(JSON.parse(result)).toEqual({ foo: "bar" }); +}); From 85dbd9538905f31e5cd7ea590100015e9d325708 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 28 Mar 2019 22:23:49 +0500 Subject: [PATCH 042/764] Update outdated repo urls and add description to package.json (#499) * Update outdated repo urls * Add description to package.json --- CHANGELOG.md | 8 ++++---- package.json | 5 +++-- src/LuaPrinter.ts | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd4f0783f..ae6096eb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,14 @@ ## 0.16.0 * **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument. - * To remove the self parameter from a single function add `this: void` to its declaration: + * To remove the self parameter from a single function add `this: void` to its declaration: ```declare function foo(this: void, ...)``` * To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`: ```/** @noSelf */ interface Foo {``` * To remove the self parameter from all functions in a file, add `/** @noSelfInFile */` at the top. --- - + * **BREAKING CHANGE:** Directive `/** @luaIterator */` should now be put on types instead of on the functions returning them. --- @@ -82,14 +82,14 @@ * Fixed several bugs with functions and context parameters. ## 0.13.0 -* Reworked how functions are transpiled, see https://github.com/Perryvw/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods +* Reworked how functions are transpiled, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods * Improved handling of types extending Array. * Fixed several bugs with classes. * Fixed issues with inherited accessors. ## 0.12.0 * Added detection of types extending Array. -* Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/Perryvw/TypescriptToLua/wiki/Compiler-Directives +* Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Compiler-Directives * Fixed bug with constructor default values. * The Lualib is no longer included when not used. * Fixed bug with unpack in LuaJIT. diff --git a/package.json b/package.json index c99850749..13ccaa59a 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "typescript-to-lua", - "license": "MIT", "version": "0.16.1", - "repository": "https://github.com/Perryvw/TypescriptToLua", + "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", + "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "license": "MIT", "keywords": [ "typescript", "lua", diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index dca5d7eb2..b178a306a 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -46,7 +46,7 @@ export class LuaPrinter { let header = ""; if (this.options.noHeader === undefined || this.options.noHeader === false) { - header += `--[[ Generated with https://github.com/Perryvw/TypescriptToLua ]]\n`; + header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`; } if (luaLibFeatures) { From d806e10b7ef644f074c047d212092b3ef89d9db1 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 28 Mar 2019 22:24:21 +0500 Subject: [PATCH 043/764] Update tsconfig example (#498) * Add shared tsconfig * Remove shared tsconfig and change example instead --- README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 61009e43a..6051d5be8 100644 --- a/README.md +++ b/README.md @@ -38,15 +38,16 @@ Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/Type `tstl -p path/to/tsconfig.json --watch` **Example tsconfig.json** -``` +```json { "compilerOptions": { - "noImplicitAny" : true, - "noImplicitThis" : true, - "alwaysStrict" : true, - "strictNullChecks": true + "target": "esnext", + "lib": ["es2015", "es2016", "es2017", "es2018", "esnext"], + "strict": true }, - "luaTarget": "JIT" + "tstl": { + "luaTarget": "JIT" + } } ``` From 1dd715c32e7ae4cec59f5c2550bf5651410edaee Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 30 Mar 2019 16:22:02 +0500 Subject: [PATCH 044/764] Improve Prettier DX (#500) * Add fix instructions on Prettier check failure * Enforce LF EOL only on CI * Fix quotes in jest config --- .prettierrc.js | 11 +++++++++++ jest.config.js | 2 +- package.json | 21 +-------------------- 3 files changed, 13 insertions(+), 21 deletions(-) create mode 100644 .prettierrc.js diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..1e032a0bf --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,11 @@ +const isCI = require("is-ci"); + +/** @type {import("prettier").Options} */ +module.exports = { + printWidth: 100, + tabWidth: 4, + trailingComma: "all", + proseWrap: "always", + endOfLine: isCI ? "lf" : "auto", + overrides: [{ files: ["**/*.md", "**/*.yml", "**/.*.yml"], options: { tabWidth: 2 } }], +}; diff --git a/jest.config.js b/jest.config.js index 8afb70bd0..adedec88f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,6 @@ const isCI = require("is-ci"); -/** @type {Partial} */ +/** @type {Partial} */ module.exports = { testMatch: ["**/test/**/*.spec.ts"], collectCoverageFrom: ["/src/**/*", "!/src/lualib/**/*"], diff --git a/package.json b/package.json index 13ccaa59a..7c7d6bd1e 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "pretest": "ts-node --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", - "lint:prettier": "prettier --check **/*.{js,ts,yml,json}", + "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run lint:prettier -- --write` or `yarn lint:prettier --write` to fix it.' && exit 1)", "lint:tslint": "tslint -p . && tslint -p test && tslint src/lualib/*.ts", "release-major": "npm version major", "release-minor": "npm version minor", @@ -34,25 +34,6 @@ "bin": { "tstl": "./dist/tstl.js" }, - "prettier": { - "endOfLine": "lf", - "printWidth": 100, - "proseWrap": "always", - "tabWidth": 4, - "trailingComma": "all", - "overrides": [ - { - "files": [ - "**/*.md", - "**/*.yml", - "**/.*.yml" - ], - "options": { - "tabWidth": 2 - } - } - ] - }, "engines": { "node": ">=8.5.0" }, From 8fb498a2c5f8a18d08b9b13e3b4b60c7e7a5635f Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 2 Apr 2019 23:46:28 +0500 Subject: [PATCH 045/764] Add fix:prettier npm script (#502) --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c7d6bd1e..a8635b178 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,9 @@ "pretest": "ts-node --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", - "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run lint:prettier -- --write` or `yarn lint:prettier --write` to fix it.' && exit 1)", + "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:tslint": "tslint -p . && tslint -p test && tslint src/lualib/*.ts", + "fix:prettier": "prettier --check --write **/*.{js,ts,yml,json}", "release-major": "npm version major", "release-minor": "npm version minor", "release-patch": "npm version patch", From ed5bcd756d727f87b4aaf0abe6bd511801f45d83 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Tue, 2 Apr 2019 22:28:58 +0200 Subject: [PATCH 046/764] Added initial support for sourcemaps (#452) * Added initial support for sourcemaps * Made some adjustments to source maps (#466) * Made some adjustments to source maps * Fixed tests * Removed tsOriginal field from AST nodes * Fixed package issues * Inline source maps * Added sourcemap lualib function * Added override for traceback (#490) * Added override for traceback * Improved sourcemap override * Removed obsolete argument * put traceback override at start of the file after headers * changed 2 underscore identifiers * Added test for sourceMapTraceback * don't enforce prettier linting * use debug.getinfo for file names * Trying to diagnose test issue * No longer check filename in sourcemap test * Another stab at fixing tests * Added sourcemap test, simplified API * Added back dependency that got lost in the merge * Fix prettier complaining * Made appveyor lint * Fixed bug in setNodeOriginal and added test to detect it --- appveyor.yml | 1 + build_lualib.ts | 2 +- package-lock.json | 77 ++- package.json | 1 + src/CommandLineParser.ts | 5 + src/Compiler.ts | 8 +- src/CompilerOptions.ts | 1 + src/LuaAST.ts | 56 ++- src/LuaLib.ts | 1 + src/LuaPrinter.ts | 443 +++++++++++++----- src/LuaTransformer.ts | 117 +++-- src/LuaTranspiler.ts | 22 +- src/lualib/SourceMapTraceBack.ts | 33 ++ src/lualib/StringReplace.ts | 5 - src/lualib/declarations/string.d.ts | 12 + test/compiler/watchmode.spec.ts | 6 +- .../configuration/mixed/index.spec.ts | 1 + test/unit/json.spec.ts | 23 +- test/unit/sourcemaps.spec.ts | 134 ++++++ test/util.ts | 39 ++ 20 files changed, 758 insertions(+), 229 deletions(-) create mode 100644 src/lualib/SourceMapTraceBack.ts create mode 100644 src/lualib/declarations/string.d.ts create mode 100644 test/unit/sourcemaps.spec.ts diff --git a/appveyor.yml b/appveyor.yml index 6ae337099..078fad304 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -19,6 +19,7 @@ test_script: - node --version - npm --version # run tests + - npm run lint - npm run build - npm test diff --git a/build_lualib.ts b/build_lualib.ts index f968f5968..be376fef6 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -20,7 +20,7 @@ compile([ "./src/lualib", "--noHeader", "true", - ...glob.sync("./src/lualib/*.ts"), + ...glob.sync("./src/lualib/**/*.ts"), ]); if (fs.existsSync(bundlePath)) { diff --git a/package-lock.json b/package-lock.json index 861f7a478..e7b030bb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -561,6 +561,12 @@ "supports-color": "^5.3.0" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -581,6 +587,14 @@ "callsites": "^3.0.0", "graceful-fs": "^4.1.15", "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "@jest/test-result": { @@ -637,6 +651,12 @@ "supports-color": "^5.3.0" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1668,6 +1688,13 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true } } }, @@ -2093,6 +2120,14 @@ "optimist": "^0.6.1", "source-map": "^0.6.1", "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "har-schema": { @@ -2556,6 +2591,14 @@ "make-dir": "^1.3.0", "rimraf": "^2.6.2", "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "istanbul-reports": { @@ -3359,6 +3402,12 @@ "supports-color": "^5.3.0" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3491,9 +3540,9 @@ "dev": true }, "js-yaml": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", - "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", + "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -4826,10 +4875,9 @@ } }, "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, "source-map-resolve": { "version": "0.5.2", @@ -4852,6 +4900,14 @@ "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, "source-map-url": { @@ -5321,6 +5377,13 @@ "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", "dev": true, "optional": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true } } }, diff --git a/package.json b/package.json index a8635b178..361da018a 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "node": ">=8.5.0" }, "dependencies": { + "source-map": "^0.7.3", "typescript": "^3.3.1" }, "devDependencies": { diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index d2fdc9f0d..50a1fa738 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -52,6 +52,11 @@ const optionDeclarations: {[key: string]: CLIOption} = { describe: "Disables hoisting.", type: "boolean", } as CLIOption, + sourceMapTraceback: { + default: false, + describe: "Applies the source map to show source TS files and lines in error tracebacks.", + type: "boolean", + } as CLIOption, }; export const { version } = require("../package.json"); diff --git a/src/Compiler.ts b/src/Compiler.ts index 642624347..306182f34 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -3,7 +3,7 @@ import * as path from "path"; import * as ts from "typescript"; import * as CommandLineParser from "./CommandLineParser"; import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; -import { LuaTranspiler } from "./LuaTranspiler"; +import { LuaTranspiler, TranspileResult } from "./LuaTranspiler"; export function compile(argv: string[]): void { const parseResult = CommandLineParser.parseCommandLine(argv); @@ -167,7 +167,7 @@ export function transpileString( options: CompilerOptions = defaultCompilerOptions, ignoreDiagnostics = false, filePath = "file.ts" -): string { +): TranspileResult { const program = createStringCompilerProgram(input, options, filePath); if (!ignoreDiagnostics) { @@ -182,7 +182,5 @@ export function transpileString( const transpiler = new LuaTranspiler(program); - const result = transpiler.transpileSourceFile(program.getSourceFile(filePath)); - - return result.trim(); + return transpiler.transpileSourceFile(program.getSourceFile(filePath)); } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 24fae4374..49ad4eabf 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -5,6 +5,7 @@ export interface CompilerOptions extends ts.CompilerOptions { luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; noHoisting?: boolean; + sourceMapTraceback?: boolean; } export enum LuaLibImportKind { diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 58534b996..277f4fdf7 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -98,10 +98,9 @@ export type Operator = UnaryOperator | BinaryOperator; export type SymbolId = number; -// TODO For future sourcemap support? export interface TextRange { - pos: number; - end: number; + line?: number; + column?: number; } export interface Node extends TextRange { @@ -110,13 +109,12 @@ export interface Node extends TextRange { } export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node { - let pos = -1; - let end = -1; - if (tsOriginal) { - pos = tsOriginal.pos; - end = tsOriginal.end; + const sourcePosition = getSourcePosition(tsOriginal); + if (sourcePosition) { + return {kind, parent, line: sourcePosition.line, column: sourcePosition.column}; + } else { + return {kind, parent}; } - return {kind, parent, pos, end}; } export function cloneNode(node: T): T { @@ -124,8 +122,12 @@ export function cloneNode(node: T): T { } export function setNodeOriginal(node: T, tsOriginal: ts.Node): T { - node.pos = tsOriginal.pos; - node.end = tsOriginal.end; + const sourcePosition = getSourcePosition(tsOriginal); + if (sourcePosition) { + node.line = sourcePosition.line; + node.column = sourcePosition.column; + } + return node; } @@ -136,20 +138,32 @@ export function setParent(node: Node | Node[] | undefined, parent: Node): void if (Array.isArray(node)) { node.forEach(n => { n.parent = parent; - if (n.pos === -1 || n.end === -1) { - n.pos = parent.pos; - n.end = parent.end; - } }); } else { node.parent = parent; - if (node.pos === -1 || node.end === -1) { - node.pos = parent.pos; - node.end = parent.end; - } } } +function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { + if (sourceNode !== undefined && sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { + + const { line, character } = ts.getLineAndCharacterOfPosition( + sourceNode.getSourceFile(), + sourceNode.pos + sourceNode.getLeadingTriviaWidth() + ); + + return { line, column: character }; + } +} + +export function getOriginalPos(node: Node): TextRange { + while (node.line === undefined && node.parent !== undefined) { + node = node.parent; + } + + return { line: node.line, column: node.column }; +} + export interface Block extends Node { kind: SyntaxKind.Block; statements?: Statement[]; @@ -812,8 +826,8 @@ export function createIdentifier( return expression; } -export function cloneIdentifier(identifier: Identifier): Identifier { - return createIdentifier(identifier.text, undefined, identifier.symbolId); +export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): Identifier { + return createIdentifier(identifier.text, tsOriginal, identifier.symbolId); } export function createAnnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 6bf97c411..7515d8d4b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -37,6 +37,7 @@ export enum LuaLibFeature { Set = "Set", WeakMap = "WeakMap", WeakSet = "WeakSet", + SourceMapTraceBack = "SourceMapTraceBack", StringReplace = "StringReplace", StringSplit = "StringSplit", StringConcat = "StringConcat", diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index b178a306a..23ac3e753 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,8 +1,14 @@ -import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; +import * as path from "path"; + +import {SourceNode, SourceMapGenerator, RawSourceMap, SourceMapConsumer} from "source-map"; + import * as tstl from "./LuaAST"; +import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import { LuaLib, LuaLibFeature } from "./LuaLib"; import { TSHelper as tsHelper } from "./TSHelper"; +type SourceChunk = string | SourceNode; + export class LuaPrinter { /* tslint:disable:object-literal-sort-keys */ private static operatorMap: {[key in tstl.Operator]: string} = { @@ -37,12 +43,78 @@ export class LuaPrinter { private options: CompilerOptions; private currentIndent: string; + private sourceFile: string; + public constructor(options: CompilerOptions) { this.options = options; this.currentIndent = ""; } - public print(block: tstl.Block, luaLibFeatures?: Set): string { + public print(block: tstl.Block, luaLibFeatures?: Set, sourceFile?: string): [string, string] { + // Add traceback lualib if sourcemap traceback option is enabled + if (this.options.sourceMapTraceback) { + if (luaLibFeatures === undefined) { + luaLibFeatures = new Set(); + } + luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); + } + + const rootSourceNode = this.printImplementation(block, luaLibFeatures, sourceFile); + + const codeWithSourceMap = rootSourceNode + // TODO is the file: part really required? and should this be handled in the printer? + .toStringWithSourceMap({file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua"}); + + let codeResult = codeWithSourceMap.code; + + if (this.options.inlineSourceMap) { + codeResult += "\n" + this.printInlineSourceMap(codeWithSourceMap.map); + } + + if (this.options.sourceMapTraceback) { + const stackTraceOverride = this.printStackTraceOverride(rootSourceNode); + codeResult = codeResult.replace("{#SourceMapTraceback}", stackTraceOverride); + } + + return [codeResult, codeWithSourceMap.map.toString()]; + } + + private printInlineSourceMap(sourceMap: SourceMapGenerator): string { + const map = sourceMap.toString(); + const base64Map = Buffer.from(map).toString('base64'); + + return `//# sourceMappingURL=data:application/json;base64,${base64Map}\n`; + } + + private printStackTraceOverride(rootNode: SourceNode): string { + let line = 1; + const map: {[line: number]: number} = {}; + rootNode.walk((chunk, mappedPosition) => { + if (mappedPosition.line !== undefined && mappedPosition.line > 0) { + if (map[line] === undefined) { + map[line] = mappedPosition.line; + } else { + map[line] = Math.min(map[line], mappedPosition.line); + } + } + line += chunk.split("\n").length - 1; + }); + + const mapItems = []; + for (const lineNr in map) { + mapItems.push(`["${lineNr}"] = ${map[lineNr]}`); + } + + const mapString = "{" + mapItems.join(",") + "}"; + + return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; + } + + private printImplementation( + block: tstl.Block, + luaLibFeatures?: Set, + sourceFile?: string): SourceNode { + let header = ""; if (this.options.noHeader === undefined || this.options.noHeader === false) { @@ -64,7 +136,15 @@ export class LuaPrinter { } } - return header + this.printBlock(block); + this.sourceFile = path.basename(sourceFile); + + if (this.options.sourceMapTraceback) { + header += "{#SourceMapTraceback}\n"; + } + + const fileBlockNode = this.createSourceNode(block, this.printBlock(block)); + + return this.concatNodes(header, fileBlockNode); } private pushIndent(): void { @@ -75,15 +155,30 @@ export class LuaPrinter { this.currentIndent = this.currentIndent.slice(4); } - private indent(input: string): string { - return this.currentIndent + input; + private indent(input: SourceChunk = ""): SourceChunk { + return this.concatNodes(this.currentIndent, input); } - private printBlock(block: tstl.Block): string { - return this.ignoreDeadStatements(block.statements).map(s => this.printStatement(s)).join(""); + private createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { + const originalPos = tstl.getOriginalPos(node); + + return originalPos !== undefined + ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks) + : new SourceNode(undefined, undefined, this.sourceFile, chunks); + } + + private concatNodes(...chunks: SourceChunk[]): SourceNode { + return new SourceNode(undefined, undefined, this.sourceFile, chunks); } - private printStatement(statement: tstl.Statement): string { + private printBlock(block: tstl.Block): SourceNode { + return this.createSourceNode( + block, + this.ignoreDeadStatements(block.statements).map(s => this.printStatement(s)) + ); + } + + private printStatement(statement: tstl.Statement): SourceNode { switch (statement.kind) { case tstl.SyntaxKind.DoStatement: return this.printDoStatement(statement as tstl.DoStatement); @@ -111,135 +206,175 @@ export class LuaPrinter { return this.printBreakStatement(statement as tstl.BreakStatement); case tstl.SyntaxKind.ExpressionStatement: return this.printExpressionStatement(statement as tstl.ExpressionStatement); + default: + throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[statement.kind]}`); } } - private printDoStatement(statement: tstl.DoStatement): string { - let result = this.indent("do\n"); + private printDoStatement(statement: tstl.DoStatement): SourceNode { + const chunks: SourceChunk[] = []; + chunks.push(this.indent("do\n")); this.pushIndent(); - result += this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s)).join(""); + chunks.push(...this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s))); this.popIndent(); - result += this.indent("end\n"); + chunks.push(this.indent("end\n")); - return result; + return this.concatNodes(...chunks); } - private printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): string { - const left = this.indent(`local ${statement.left.map(e => this.printExpression(e)).join(", ")}`); + private printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { + const chunks: SourceChunk[] = []; + chunks.push(this.indent("local ")); + chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); + if (statement.right) { - return left + ` = ${statement.right.map(e => this.printExpression(e)).join(", ")};\n`; - } else { - return left + ";\n"; + chunks.push(" = "); + chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); } + chunks.push(";\n"); + + return this.concatNodes(...chunks); } - private printVariableAssignmentStatement(statement: tstl.AssignmentStatement): string { - return this.indent( - `${statement.left.map(e => this.printExpression(e)).join(", ")} = ` + - `${statement.right.map(e => this.printExpression(e)).join(", ")};\n`); + private printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push(this.indent()); + chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); + chunks.push(" = "); + chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); + chunks.push(";\n"); + + return this.createSourceNode(statement, chunks); } - private printIfStatement(statement: tstl.IfStatement, isElseIf?: boolean): string { + private printIfStatement(statement: tstl.IfStatement, isElseIf?: boolean): SourceNode { + const chunks: SourceChunk[] = []; + const prefix = isElseIf ? "elseif" : "if"; - let result = this.indent(`${prefix} ${this.printExpression(statement.condtion)} then\n`); + + chunks.push(this.indent(prefix + " "), this.printExpression(statement.condtion), " then\n"); + this.pushIndent(); - result += this.printBlock(statement.ifBlock); + chunks.push(this.printBlock(statement.ifBlock)); this.popIndent(); + if (statement.elseBlock) { if (tstl.isIfStatement(statement.elseBlock)) { - result += this.printIfStatement(statement.elseBlock, true); + chunks.push(this.printIfStatement(statement.elseBlock, true)); } else { - result += this.indent("else\n"); + chunks.push(this.indent("else\n")); this.pushIndent(); - result += this.printBlock(statement.elseBlock); + chunks.push(this.printBlock(statement.elseBlock)); this.popIndent(); - result += this.indent("end\n"); + chunks.push(this.indent("end\n")); } } else { - result += this.indent("end\n"); + chunks.push(this.indent("end\n")); } - return result; + return this.concatNodes(...chunks); } - private printWhileStatement(statement: tstl.WhileStatement): string { - let result = this.indent(`while ${this.printExpression(statement.condtion)} do\n`); + private printWhileStatement(statement: tstl.WhileStatement): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push(this.indent("while "), this.printExpression(statement.condtion), " do\n"); + this.pushIndent(); - result += this.printBlock(statement.body); + chunks.push(this.printBlock(statement.body)); this.popIndent(); - result += this.indent("end\n"); - return result; + chunks.push(this.indent("end\n")); + + return this.concatNodes(...chunks); } - private printRepeatStatement(statement: tstl.RepeatStatement): string { - let result = this.indent(`repeat\n`); + private printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push(this.indent(`repeat\n`)); + this.pushIndent(); - result += this.printBlock(statement.body); + chunks.push(this.printBlock(statement.body)); this.popIndent(); - result += this.indent(`until ${this.printExpression(statement.condtion)};\n`); - return result; + chunks.push(this.indent("until "), this.printExpression(statement.condtion), ";\n"); + + return this.concatNodes(...chunks); } - private printForStatement(statement: tstl.ForStatement): string { + private printForStatement(statement: tstl.ForStatement): SourceNode { const ctrlVar = this.printExpression(statement.controlVariable); const ctrlVarInit = this.printExpression(statement.controlVariableInitializer); const limit = this.printExpression(statement.limitExpression); - let result = this.indent(`for ${ctrlVar} = ${ctrlVarInit}, ${limit}`); + const chunks: SourceChunk[] = []; + + chunks.push(this.indent("for "), ctrlVar, " = ", ctrlVarInit, ", ", limit); + if (statement.stepExpression) { - const step = this.printExpression(statement.stepExpression); - result += `, ${step}`; + chunks.push(", ", this.printExpression(statement.stepExpression)); } - result += ` do\n`; + chunks.push(" do\n"); this.pushIndent(); - result += this.printBlock(statement.body); + chunks.push(this.printBlock(statement.body)); this.popIndent(); - result += this.indent("end\n"); - return result; + chunks.push(this.indent("end\n")); + + return this.concatNodes(...chunks); } - private printForInStatement(statement: tstl.ForInStatement): string { + private printForInStatement(statement: tstl.ForInStatement): SourceNode { const names = statement.names.map(i => this.printIdentifier(i)).join(", "); const expressions = statement.expressions.map(e => this.printExpression(e)).join(", "); - let result = this.indent(`for ${names} in ${expressions} do\n`); + const chunks: SourceChunk[] = []; + + chunks.push(this.indent("for "), names, " in ", expressions, " do\n"); + this.pushIndent(); - result += this.printBlock(statement.body); + chunks.push(this.printBlock(statement.body)); this.popIndent(); - result += this.indent("end\n"); + chunks.push(this.indent("end\n")); - return result; + return this.createSourceNode(statement, chunks); } - private printGotoStatement(statement: tstl.GotoStatement): string { - return this.indent(`goto ${statement.label};\n`); + private printGotoStatement(statement: tstl.GotoStatement): SourceNode { + return this.createSourceNode(statement, [this.indent("goto "), statement.label, ";\n"]); } - private printLabelStatement(statement: tstl.LabelStatement): string { - return this.indent(`::${statement.name}::\n`); + private printLabelStatement(statement: tstl.LabelStatement): SourceNode { + return this.createSourceNode(statement, [this.indent("::"), statement.name, "::\n"]); } - private printReturnStatement(statement: tstl.ReturnStatement): string { - if (!statement.expressions) { - return this.indent(`return;\n`); + private printReturnStatement(statement: tstl.ReturnStatement): SourceNode { + if (!statement.expressions || statement.expressions.length === 0) { + return this.createSourceNode(statement, this.indent("return;\n")); } - return this.indent(`return ${statement.expressions.map(e => this.printExpression(e)).join(", ")};\n`); + + const chunks: SourceChunk[] = []; + + chunks.push(...this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e)))); + + chunks.push(";\n"); + + return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } - private printBreakStatement(statement: tstl.BreakStatement): string { - return this.indent("break;\n"); + private printBreakStatement(statement: tstl.BreakStatement): SourceNode { + return this.createSourceNode(statement, this.indent("break;\n")); } - private printExpressionStatement(statement: tstl.ExpressionStatement): string { - return this.indent(`${this.printExpression(statement.expression)};\n`); + private printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { + return this.concatNodes(this.indent(), this.printExpression(statement.expression), ";\n"); } // Expressions - private printExpression(expression: tstl.Expression): string { + private printExpression(expression: tstl.Expression): SourceNode { switch (expression.kind) { case tstl.SyntaxKind.StringLiteral: return this.printStringLiteral(expression as tstl.StringLiteral); @@ -272,88 +407,128 @@ export class LuaPrinter { return this.printIdentifier(expression as tstl.Identifier); case tstl.SyntaxKind.TableIndexExpression: return this.printTableIndexExpression(expression as tstl.TableIndexExpression); + default: + throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[expression.kind]}`); } } - private printStringLiteral(expression: tstl.StringLiteral): string { - return `"${expression.value}"`; + private printStringLiteral(expression: tstl.StringLiteral): SourceNode { + return this.createSourceNode(expression, `"${expression.value}"`); } - private printNumericLiteral(expression: tstl.NumericLiteral): string { - return `${expression.value}`; + private printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { + return this.createSourceNode(expression, String(expression.value)); } - private printNilLiteral(expression: tstl.NilLiteral): string { - return "nil"; + private printNilLiteral(expression: tstl.NilLiteral): SourceNode { + return this.createSourceNode(expression, "nil"); } - private printDotsLiteral(expression: tstl.DotsLiteral): string { - return "..."; + private printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { + return this.createSourceNode(expression, "..."); } - private printBooleanLiteral(expression: tstl.BooleanLiteral): string { + private printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { if (expression.kind === tstl.SyntaxKind.TrueKeyword) { - return "true"; + return this.createSourceNode(expression, "true"); } else { - return "false"; + return this.createSourceNode(expression, "false"); } } - private printFunctionExpression(expression: tstl.FunctionExpression): string { - const paramterArr: string[] = expression.params ? expression.params.map(i => this.printIdentifier(i)) : []; + private printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { + const parameterChunks: SourceNode[] = expression.params + ? expression.params.map(i => this.printIdentifier(i)) + : []; + if (expression.dots) { - paramterArr.push(this.printDotsLiteral(expression.dots)); + parameterChunks.push(this.printDotsLiteral(expression.dots)); } - let result = `function(${paramterArr.join(", ")})\n`; + const chunks: SourceChunk[] = []; + + chunks.push("function("); + chunks.push(...this.joinChunks(", ", parameterChunks)); + chunks.push(")\n"); + this.pushIndent(); - result += this.printBlock(expression.body); + chunks.push(this.printBlock(expression.body)); this.popIndent(); - result += this.indent("end"); + chunks.push(this.indent("end")); - return result; + return this.createSourceNode(expression, chunks); } - private printTableFieldExpression(expression: tstl.TableFieldExpression): string { + private printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { + const chunks: SourceChunk[] = []; + const value = this.printExpression(expression.value); if (expression.key) { if (tstl.isStringLiteral(expression.key) && tsHelper.isValidLuaIdentifier(expression.key.value)) { - return `${expression.key.value} = ${value}`; + chunks.push(expression.key.value, " = ", value); } else { - return `[${this.printExpression(expression.key)}] = ${value}`; + chunks.push("[", this.printExpression(expression.key), "] = ", value); } } else { - return value; + chunks.push(value); } + + return this.createSourceNode(expression, chunks); } - private printTableExpression(expression: tstl.TableExpression): string { - let fields = ""; + private printTableExpression(expression: tstl.TableExpression): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push("{"); + if (expression.fields) { - fields = expression.fields.map(f => this.printTableFieldExpression(f)).join(", "); + expression.fields.forEach((f, i) => { + if (i < expression.fields.length - 1) { + chunks.push(this.printTableFieldExpression(f), ", "); + } else { + chunks.push(this.printTableFieldExpression(f)); + } + }); } - return `{${fields}}`; + + chunks.push("}"); + + return this.createSourceNode(expression, chunks); } - private printUnaryExpression(expression: tstl.UnaryExpression): string { - const operand = this.needsParentheses(expression.operand) - ? `(${this.printExpression(expression.operand)})` - : this.printExpression(expression.operand); - return `${this.printOperator(expression.operator)}${operand}`; + private printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push(this.printOperator(expression.operator)); + + if (this.needsParentheses(expression.operand)) { + chunks.push("(", this.printExpression(expression.operand), ")"); + } else { + chunks.push(this.printExpression(expression.operand)); + } + + return this.createSourceNode(expression, chunks); } - private printBinaryExpression(expression: tstl.BinaryExpression): string { - const left = this.needsParentheses(expression.left) - ? `(${this.printExpression(expression.left)})` - : this.printExpression(expression.left); + private printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { + const chunks: SourceChunk[] = []; - const right = this.needsParentheses(expression.right) - ? `(${this.printExpression(expression.right)})` - : this.printExpression(expression.right); + if (this.needsParentheses(expression.left)) { + chunks.push("(", this.printExpression(expression.left), ")"); + } else { + chunks.push(this.printExpression(expression.left)); + } + + chunks.push(" ", this.printOperator(expression.operator), " "); + + if (this.needsParentheses(expression.right)) { + chunks.push("(", this.printExpression(expression.right), ")"); + } else { + chunks.push(this.printExpression(expression.right)); + } - const operator = this.printOperator(expression.operator); - return `${left} ${operator} ${right}`; + return this.createSourceNode(expression, chunks); } private needsParentheses(expression: tstl.Expression): boolean { @@ -361,34 +536,45 @@ export class LuaPrinter { || tstl.isFunctionExpression(expression); } - private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): string { - return `(${this.printExpression(expression.innerEpxression)})`; + private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { + return this.createSourceNode(expression, ["(", this.printExpression(expression.innerEpxression), ")"]); } - private printCallExpression(expression: tstl.CallExpression): string { - const params = expression.params ? expression.params.map(e => this.printExpression(e)).join(", ") : ""; - return this.needsParentheses(expression.expression) - ? `(${this.printExpression(expression.expression)})(${params})` - : `${this.printExpression(expression.expression)}(${params})`; + private printCallExpression(expression: tstl.CallExpression): SourceNode { + const chunks = []; + const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e))); + + if (this.needsParentheses(expression.expression)) { + chunks.push("(", this.printExpression(expression.expression), ")(", ...parameterChunks, ")"); + } else { + chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")"); + } + + return this.concatNodes(...chunks); } - private printMethodCallExpression(expression: tstl.MethodCallExpression): string { - const params = expression.params.map(e => this.printExpression(e)).join(", "); + private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { const prefix = this.printExpression(expression.prefixExpression); + const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e))); const name = this.printIdentifier(expression.name); - return `${prefix}:${name}(${params})`; + + return this.concatNodes(prefix, ":", name, "(", ...parameterChunks, ")"); } - private printIdentifier(expression: tstl.Identifier): string { - return expression.text; + private printIdentifier(expression: tstl.Identifier): SourceNode { + return this.createSourceNode(expression, expression.text); } - private printTableIndexExpression(expression: tstl.TableIndexExpression): string { - const table = this.printExpression(expression.table); + private printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { + const chunks: SourceChunk[] = []; + + chunks.push(this.printExpression(expression.table)); if (tstl.isStringLiteral(expression.index) && tsHelper.isValidLuaIdentifier(expression.index.value)) { - return `${table}.${expression.index.value}`; + chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); + } else { + chunks.push("[", this.printExpression(expression.index), "]"); } - return `${table}[${this.printExpression(expression.index)}]`; + return this.createSourceNode(expression, chunks); } private printOperator(kind: tstl.Operator): string { @@ -405,4 +591,15 @@ export class LuaPrinter { } return aliveStatements; } + + private joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { + const result = []; + for (let i = 0; i < chunks.length; i++) { + result.push(chunks[i]); + if (i < chunks.length - 1) { + result.push(separator); + } + } + return result; + } } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 3a7d8dcad..40d2b8eed 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -599,12 +599,13 @@ export class LuaTransformer { const result: tstl.Statement[] = []; // className = className or {} - let classTable: tstl.Expression = tstl.createTableExpression(); + let classTable: tstl.Expression = tstl.createTableExpression([], statement); if (!noClassOr) { classTable = tstl.createBinaryExpression( this.addExportToIdentifier(className), // Use original identifier node in declaration classTable, - tstl.SyntaxKind.OrOperator + tstl.SyntaxKind.OrOperator, + statement ); } @@ -617,7 +618,8 @@ export class LuaTransformer { if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { const classGetters = tstl.createTableIndexExpression( createClassNameWithExport(), - tstl.createStringLiteral("____getters") + tstl.createStringLiteral("____getters"), + statement ); const assignClassGetters = tstl.createAssignmentStatement( classGetters, @@ -632,7 +634,8 @@ export class LuaTransformer { // className.__index = className const classIndex = tstl.createTableIndexExpression( createClassNameWithExport(), - tstl.createStringLiteral("__index") + tstl.createStringLiteral("__index"), + statement ); const assignClassIndex = tstl.createAssignmentStatement(classIndex, createClassNameWithExport(), statement); result.push(assignClassIndex); @@ -656,14 +659,16 @@ export class LuaTransformer { // className.prototype = className.prototype or {} const createClassPrototype = () => tstl.createTableIndexExpression( createClassNameWithExport(), - tstl.createStringLiteral("prototype") + tstl.createStringLiteral("prototype"), + statement ); const classPrototypeTable = noClassOr - ? tstl.createTableExpression() + ? tstl.createTableExpression([], statement) : tstl.createBinaryExpression( createClassPrototype(), tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator + tstl.SyntaxKind.OrOperator, + statement ); const assignClassPrototype = tstl.createAssignmentStatement(createClassPrototype(), classPrototypeTable); result.push(assignClassPrototype); @@ -672,11 +677,13 @@ export class LuaTransformer { if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStatic(m))) { const classPrototypeGetters = tstl.createTableIndexExpression( createClassPrototype(), - tstl.createStringLiteral("____getters") + tstl.createStringLiteral("____getters"), + statement ); const assignClassPrototypeGetters = tstl.createAssignmentStatement( classPrototypeGetters, - tstl.createTableExpression() + tstl.createTableExpression(), + statement ); result.push(assignClassPrototypeGetters); } @@ -689,7 +696,8 @@ export class LuaTransformer { // className.prototype.__index = __TS_Index(className.prototype) const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeIndex, - this.transformLuaLibFunction(LuaLibFeature.Index, undefined, createClassPrototype()) + this.transformLuaLibFunction(LuaLibFeature.Index, undefined, createClassPrototype()), + statement ); result.push(assignClassPrototypeIndex); @@ -697,7 +705,8 @@ export class LuaTransformer { // className.prototype.__index = className.prototype const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeIndex, - createClassPrototype() + createClassPrototype(), + statement ); result.push(assignClassPrototypeIndex); } @@ -706,11 +715,13 @@ export class LuaTransformer { // className.prototype.____setters = {} const classPrototypeSetters = tstl.createTableIndexExpression( createClassPrototype(), - tstl.createStringLiteral("____setters") + tstl.createStringLiteral("____setters"), + statement ); const assignClassPrototypeSetters = tstl.createAssignmentStatement( classPrototypeSetters, - tstl.createTableExpression() + tstl.createTableExpression(), + statement ); result.push(assignClassPrototypeSetters); } @@ -750,7 +761,8 @@ export class LuaTransformer { // className.____super = baseName const createClassBase = () => tstl.createTableIndexExpression( createClassNameWithExport(), - tstl.createStringLiteral("____super") + tstl.createStringLiteral("____super"), + statement ); const assignClassBase = tstl.createAssignmentStatement(createClassBase(), baseName, statement); result.push(assignClassBase); @@ -804,13 +816,15 @@ export class LuaTransformer { // setmetatable(className.prototype, className.____super.prototype) const basePrototype = tstl.createTableIndexExpression( createClassBase(), - tstl.createStringLiteral("prototype") + tstl.createStringLiteral("prototype"), + statement ); const setClassPrototypeMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), [createClassPrototype(), basePrototype] - ) + ), + statement ); result.push(setClassPrototypeMetatable); @@ -853,7 +867,8 @@ export class LuaTransformer { tstl.createCallExpression( tstl.createIdentifier("setmetatable"), [tstl.createTableExpression(), createClassPrototype()] - ) + ), + statement ); newFuncStatements.push(assignSelf); @@ -863,12 +878,13 @@ export class LuaTransformer { this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [tstl.createDotsLiteral()] - ) + ), + statement ); newFuncStatements.push(callConstructor); // return self - const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()]); + const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()], statement); newFuncStatements.push(returnSelf); // function className.new(construct, ...) ... end @@ -883,7 +899,8 @@ export class LuaTransformer { tstl.createDotsLiteral(), undefined, statement - ) + ), + statement ); result.push(newFunc); @@ -907,7 +924,7 @@ export class LuaTransformer { const selfIndex = tstl.createTableIndexExpression(this.createSelfIdentifier(), fieldName); // self[fieldName] = value - const assignClassField = tstl.createAssignmentStatement(selfIndex, value); + const assignClassField = tstl.createAssignmentStatement(selfIndex, value, f); statements.push(assignClassField); } @@ -1097,7 +1114,8 @@ export class LuaTransformer { tstl.createBlock(body), paramNames, dots, - restParamName + restParamName, + node.body ); const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); @@ -1494,20 +1512,6 @@ export class LuaTransformer { resumeCall) ); - //coroutine.status(____co) ~= "dead"; - const coStatus = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("coroutine"), - tstl.createStringLiteral("status") - ), - [coroutineIdentifier] - ); - const status = tstl.createBinaryExpression( - coStatus, - tstl.createStringLiteral("dead"), - tstl.SyntaxKind.EqualityOperator - ); - nextBody.push(status); //if(not ____err){error(____value)} const errorCheck = tstl.createIfStatement( tstl.createUnaryExpression( @@ -1524,7 +1528,22 @@ export class LuaTransformer { ]) ); nextBody.push(errorCheck); - //{done = coroutine.status(____co) ~= "dead"; value = ____value} + + //coroutine.status(____co) == "dead"; + const coStatus = tstl.createCallExpression( + tstl.createTableIndexExpression( + tstl.createIdentifier("coroutine"), + tstl.createStringLiteral("status") + ), + [coroutineIdentifier] + ); + const status = tstl.createBinaryExpression( + coStatus, + tstl.createStringLiteral("dead"), + tstl.SyntaxKind.EqualityOperator + ); + + //{done = coroutine.status(____co) == "dead"; value = ____value} const iteratorResult = tstl.createTableExpression([ tstl.createTableFieldExpression( status, @@ -1813,10 +1832,10 @@ export class LuaTransformer { return tstl.createReturnStatement([expression]); } } - return tstl.createReturnStatement([this.transformExpression(statement.expression)]); + return tstl.createReturnStatement([this.transformExpression(statement.expression)], statement); } else { // Empty return - return tstl.createReturnStatement(); + return tstl.createReturnStatement([], statement); } } @@ -3151,7 +3170,7 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); } - const callExpression = tstl.createCallExpression(callPath, parameters); + const callExpression = tstl.createCallExpression(callPath, parameters, node); return wrapResult ? this.wrapInTable(callExpression) : callExpression; } @@ -3242,13 +3261,17 @@ export class LuaTransformer { // table:name() return tstl.createMethodCallExpression( table, - tstl.createIdentifier(name), + this.transformIdentifier(node.expression.name), parameters, node ); } else { // table.name() - const callPath = tstl.createTableIndexExpression(table, tstl.createStringLiteral(name)); + const callPath = tstl.createTableIndexExpression( + table, + tstl.createStringLiteral(name), + node.expression + ); return tstl.createCallExpression(callPath, parameters, node); } } @@ -3970,7 +3993,7 @@ export class LuaTransformer { public transformStringLiteral(literal: ts.StringLiteralLike): tstl.StringLiteral { const text = tsHelper.escapeString(literal.text); - return tstl.createStringLiteral(text); + return tstl.createStringLiteral(text, literal); } public transformNumericLiteral(literal: ts.NumericLiteral): tstl.NumericLiteral { @@ -4239,7 +4262,6 @@ export class LuaTransformer { // exported if (!rhs) { return []; - } else if (Array.isArray(lhs)) { assignment = tstl.createAssignmentStatement( lhs.map(i => this.createExportedIdentifier(i)), @@ -4469,8 +4491,13 @@ export class LuaTransformer { if (scope.functionDefinitions) { for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { + const { line, column } = tstl.getOriginalPos(functionDefinition.assignment); + const assignmentPos = ts.getPositionOfLineAndCharacter( + this.currentSourceFile, + line, + column); if (functionSymbolId !== symbolId // Don't recurse into self - && declaration.pos < functionDefinition.assignment.pos // Ignore functions before symbol declaration + && declaration.pos < assignmentPos // Ignore functions before symbol declaration && functionDefinition.referencedSymbols.has(symbolId) && this.shouldHoist(functionSymbolId, scope)) { diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts index cd991f511..771a32642 100644 --- a/src/LuaTranspiler.ts +++ b/src/LuaTranspiler.ts @@ -6,6 +6,12 @@ import * as tstl from "./LuaAST"; import { LuaPrinter } from "./LuaPrinter"; import { LuaTransformer } from "./LuaTransformer"; +export interface TranspileResult { + lua: string; + luaAST: tstl.Node; + sourceMap: string; +} + export class LuaTranspiler { private program: ts.Program; @@ -89,7 +95,7 @@ export class LuaTranspiler { try { const rootDir = this.options.rootDir; - const lua = this.transpileSourceFile(sourceFile); + const { lua, luaAST, sourceMap } = this.transpileSourceFile(sourceFile); let outPath = sourceFile.fileName; if (this.options.outDir !== this.options.rootDir) { @@ -112,6 +118,9 @@ export class LuaTranspiler { // Write output ts.sys.writeFile(outPath, lua); + if (this.options.sourceMap) { + ts.sys.writeFile(outPath + ".map", sourceMap); + } } catch (exception) { /* istanbul ignore else: Testing else part would require to add a bug/exception to our code */ if (exception.node) { @@ -128,18 +137,13 @@ export class LuaTranspiler { return 0; } - public transpileSourceFile(sourceFile: ts.SourceFile): string { + public transpileSourceFile(sourceFile: ts.SourceFile): TranspileResult { // Transform AST const [luaAST, lualibFeatureSet] = this.luaTransformer.transformSourceFile(sourceFile); // Print AST - return this.luaPrinter.print(luaAST, lualibFeatureSet); - } + const [lua, sourceMap] = this.luaPrinter.print(luaAST, lualibFeatureSet, sourceFile.fileName); - public transpileSourceFileKeepAST(sourceFile: ts.SourceFile): [tstl.Block, string] { - // Transform AST - const [luaAST, lualibFeatureSet] = this.luaTransformer.transformSourceFile(sourceFile); - // Print AST - return [luaAST, this.luaPrinter.print(luaAST, lualibFeatureSet)]; + return { lua, luaAST, sourceMap }; } public reportDiagnostic(diagnostic: ts.Diagnostic): void { diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts new file mode 100644 index 000000000..eb5215d64 --- /dev/null +++ b/src/lualib/SourceMapTraceBack.ts @@ -0,0 +1,33 @@ +declare const debug: { + traceback: (this: void, ...args: any[]) => string; +}; + +type TraceBackFunction = (this: void, thread?: any, message?: string, level?: number) => string; + +declare const _G: {[key: string]: any} & {__TS__originalTraceback: TraceBackFunction}; + +// TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to +// get some metadata about transpilation. +function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: {[line: number]: number}): void { + _G["__TS__sourcemap"] = _G["__TS__sourcemap"] || {}; + _G["__TS__sourcemap"][fileName] = sourceMap; + + if (_G.__TS__originalTraceback === undefined) { + _G.__TS__originalTraceback = debug.traceback; + debug.traceback = (thread, message, level) => { + const trace = _G["__TS__originalTraceback"](thread, message, level); + const [result, occurrences] = string.gsub( + trace, + "(%S+).lua:(%d+)", + (file, line) => { + if (_G["__TS__sourcemap"][file + ".lua"] && _G["__TS__sourcemap"][file + ".lua"][line]) { + return `${file}.ts:${_G["__TS__sourcemap"][file + ".lua"][line]}`; + } + return `${file}.lua:${line}`; + } + ); + + return result; + }; + } +} diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index 3f51b8b43..6ba303451 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -1,8 +1,3 @@ -declare namespace string { - /** @tupleReturn */ - function gsub(this: void, source: string, searchValue: string, replaceValue: string): [string, number]; -} - function __TS__StringReplace(this: void, source: string, searchValue: string, replaceValue: string): string { return string.gsub(source, searchValue, replaceValue)[0]; } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts new file mode 100644 index 000000000..6e387692b --- /dev/null +++ b/src/lualib/declarations/string.d.ts @@ -0,0 +1,12 @@ +/** @luaIterator */ +interface GMatchResult extends Array { } + +/** @noSelf */ +declare namespace string { + /** @tupleReturn */ + function gsub(source: string, searchValue: string, replaceValue: string): [string, number]; + /** @tupleReturn */ + function gsub(source: string, searchValue: string, replaceValue: (...groups: string[]) => string): [string, number]; + + function gmatch(haystack: string, pattern: string): GMatchResult; +} diff --git a/test/compiler/watchmode.spec.ts b/test/compiler/watchmode.spec.ts index 2d695f698..f4115dcc3 100644 --- a/test/compiler/watchmode.spec.ts +++ b/test/compiler/watchmode.spec.ts @@ -40,7 +40,7 @@ test.each([ "Watch single File (%p)", async ({ args, fileToChange }) => { const fileToChangeOut = fileToChange.replace(".ts", ".lua"); - const originalTS = fs.readFileSync(fileToChange); + const originalTS = fs.readFileSync(fileToChange, "utf-8"); const child = fork(path.join(__dirname, "watcher_proccess.ts"), [], { silent: true, @@ -60,13 +60,13 @@ test.each([ child.send(args); await waitForFileExists(fileToChangeOut); - const initialResultLua = fs.readFileSync(fileToChangeOut, "utf8"); + const initialResultLua = fs.readFileSync(fileToChangeOut, "utf-8"); fs.unlinkSync(fileToChangeOut); fs.writeFileSync(fileToChange, "class MyTest2 {}"); await waitForFileExists(fileToChangeOut); - const updatedResultLua = fs.readFileSync(fileToChangeOut, "utf8"); + const updatedResultLua = fs.readFileSync(fileToChangeOut, "utf-8"); expect(initialResultLua).not.toEqual(updatedResultLua); }, diff --git a/test/unit/compiler/configuration/mixed/index.spec.ts b/test/unit/compiler/configuration/mixed/index.spec.ts index 119a91365..cb98a7d45 100644 --- a/test/unit/compiler/configuration/mixed/index.spec.ts +++ b/test/unit/compiler/configuration/mixed/index.spec.ts @@ -32,6 +32,7 @@ test("tsconfig.json mixed with cmd line args", () => { noHeader: false, project: tsConfigPath, noHoisting: false, + sourceMapTraceback: false, } as CompilerOptions); } else { expect(parsedArgs.isValid).toBeTruthy(); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index 337e5676f..db16d75ae 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,16 +1,19 @@ -import { transpileString } from "../../src/Compiler"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; +import * as ts from "typescript"; + +const jsonOptions = { + resolveJsonModule: true, + noHeader: true, + moduleResolution: ts.ModuleResolutionKind.NodeJs, +}; test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } }'])( "JSON (%p)", json => { - const lua = transpileString( - json, - { resolveJsonModule: true, noHeader: true }, - false, - "file.json", - ).replace(/^return ([\s\S]+);$/, "return JSONStringify($1);"); + const lua = util + .transpileString(json, jsonOptions, false, "file.json") + .replace(/^return ([\s\S]+);$/, "return JSONStringify($1);"); const result = util.executeLua(lua); expect(JSON.parse(result)).toEqual(JSON.parse(json)); @@ -18,7 +21,7 @@ test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } ); test("Empty JSON", () => { - expect(() => - transpileString("", { resolveJsonModule: true, noHeader: true }, false, "file.json"), - ).toThrowExactError(TSTLErrors.InvalidJsonFileContent(util.nodeStub)); + expect(() => util.transpileString("", jsonOptions, false, "file.json")).toThrowExactError( + TSTLErrors.InvalidJsonFileContent(util.nodeStub), + ); }); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts new file mode 100644 index 000000000..b6873787b --- /dev/null +++ b/test/unit/sourcemaps.spec.ts @@ -0,0 +1,134 @@ +import * as util from "../util"; +import { LuaLibImportKind } from "../../src/CompilerOptions"; +import { SourceMapConsumer, Position } from "source-map"; + +test.each([ + { + typeScriptSource: ` + const abc = "foo"; + const def = "bar"; + + const xyz = "baz";`, + + assertPatterns: [ + { luaPattern: "abc", typeScriptPattern: "abc" }, + { luaPattern: "def", typeScriptPattern: "def" }, + { luaPattern: "xyz", typeScriptPattern: "xyz" }, + { luaPattern: `"foo"`, typeScriptPattern: `"foo"` }, + { luaPattern: `"bar"`, typeScriptPattern: `"bar"` }, + { luaPattern: `"baz"`, typeScriptPattern: `"baz"` }, + ], + }, + { + typeScriptSource: ` + function abc() { + return def(); + } + function def() { + return "foo"; + } + return abc();`, + + assertPatterns: [ + { luaPattern: "abc = function(", typeScriptPattern: "abc() {" }, + { luaPattern: "def = function(", typeScriptPattern: "def() {" }, + { luaPattern: "return abc(", typeScriptPattern: "return abc(" }, + ], + }, + { + typeScriptSource: ` + const enum abc { foo = 2, bar = 4 }; + const xyz = abc.foo;`, + + assertPatterns: [ + { luaPattern: "xyz", typeScriptPattern: "xyz" }, + { luaPattern: "2", typeScriptPattern: "abc.foo" }, + ], + }, +])("Source map has correct mapping (%p)", async ({ typeScriptSource, assertPatterns }) => { + // Act + const { lua, sourceMap } = util.transpileStringResult(typeScriptSource); + + // Assert + const consumer = await new SourceMapConsumer(sourceMap); + + for (const { luaPattern, typeScriptPattern } of assertPatterns) { + const luaPosition = lineAndColumnOf(lua, luaPattern); + const mappedPosition = consumer.originalPositionFor(luaPosition); + + const typescriptPosition = lineAndColumnOf(typeScriptSource, typeScriptPattern); + + const mappedLineColumn = { line: mappedPosition.line, column: mappedPosition.column }; + expect(mappedLineColumn).toEqual(typescriptPosition); + } +}); + +test("sourceMapTraceback saves sourcemap in _G", () => { + // Arrange + const typeScriptSource = ` + function abc() { + return "foo"; + } + return JSONStringify(_G.__TS__sourcemap);`; + + const options = { sourceMapTraceback: true, luaLibImport: LuaLibImportKind.Inline }; + + // Act + const transpiledLua = util.transpileString(typeScriptSource, options); + + const sourceMapJson = util.transpileAndExecute( + typeScriptSource, + options, + undefined, + "declare const _G: {__TS__sourcemap: any};", + ); + + // Assert + expect(sourceMapJson).toBeDefined(); + + const sourceMap = JSON.parse(sourceMapJson); + + const sourceMapFiles = Object.keys(sourceMap); + + expect(sourceMapFiles.length).toBe(1); + expect(sourceMap[sourceMapFiles[0]]).toBeDefined(); + + const assertPatterns = [ + { luaPattern: "abc = function(", typeScriptPattern: "abc() {" }, + { luaPattern: `return "foo"`, typeScriptPattern: `return "foo"` }, + ]; + + for (const { luaPattern, typeScriptPattern } of assertPatterns) { + const luaPosition = lineAndColumnOf(transpiledLua, luaPattern); + const mappedLine = sourceMap[sourceMapFiles[0]][luaPosition.line.toString()]; + + const typescriptPosition = lineAndColumnOf(typeScriptSource, typeScriptPattern); + + // Add 1 to account for transpiledAndExecute-added function header + expect(mappedLine).toEqual(typescriptPosition.line + 1); + } +}); + +// Helper functions + +function lineAndColumnOf(text: string, pattern: string): Position { + const pos = text.indexOf(pattern); + if (pos === -1) { + return { line: -1, column: -1 }; + } + + const lineLengths = text.split("\n").map(s => s.length); + + let totalPos = 0; + for (let line = 1; line <= lineLengths.length; line++) { + // Add + 1 for the removed \n + const lineLength = lineLengths[line - 1] + 1; + if (pos < totalPos + lineLength) { + return { line, column: pos - totalPos }; + } + + totalPos += lineLengths[line - 1] + 1; + } + + return { line: -1, column: -1 }; +} diff --git a/test/util.ts b/test/util.ts index 73d338434..d09cd7824 100644 --- a/test/util.ts +++ b/test/util.ts @@ -8,6 +8,7 @@ import { } from "../src/Compiler"; import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../src/CompilerOptions"; import { LuaTransformer } from "../src/LuaTransformer"; +import { TranspileResult } from "../src/LuaTranspiler"; export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); @@ -46,12 +47,50 @@ expect.extend({ }, }); +function compilerTranspile( + str: string | { [filename: string]: string }, + options: CompilerOptions = {}, + ignoreDiagnostics = true, + filePath = "file.ts", +): TranspileResult { + return compilerTranspileString( + str, + { + luaLibImport: LuaLibImportKind.Inline, + luaTarget: LuaTarget.Lua53, + noHeader: true, + skipLibCheck: true, + target: ts.ScriptTarget.ESNext, + lib: [ + "lib.es2015.d.ts", + "lib.es2016.d.ts", + "lib.es2017.d.ts", + "lib.es2018.d.ts", + "lib.esnext.d.ts", + ], + ...options, + }, + ignoreDiagnostics, + filePath, + ); +} + export function transpileString( str: string | { [filename: string]: string }, options: CompilerOptions = {}, ignoreDiagnostics = true, filePath = "file.ts", ): string { + const { lua } = transpileStringResult(str, options, ignoreDiagnostics, filePath); + return lua.trim(); +} + +export function transpileStringResult( + str: string | { [filename: string]: string }, + options: CompilerOptions = {}, + ignoreDiagnostics = true, + filePath = "file.ts", +): TranspileResult { return compilerTranspileString( str, { From 1e260e60f1f4b590d108042e487544f750a7ad51 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 2 Apr 2019 22:32:45 +0200 Subject: [PATCH 047/764] 0.17.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7b030bb9..dda947979 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.16.1", + "version": "0.17.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 361da018a..1f15d68ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.16.1", + "version": "0.17.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 0bf1ea04d971cb2c4410896e4b1ea6c57df16a28 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Apr 2019 22:45:58 +0200 Subject: [PATCH 048/764] Update CHANGELOG.md --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae6096eb9..dd6c83c67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.17.0 +* We now support source maps in the [standard JS v3 format](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1). You can generate source maps with the `--sourceMap` CLI argument, or by adding `sourceMap: true` to your tsconfig. Inline source maps are also supported with `--inlineSourceMap` CLI/tsconfig parameter. +* Also added support for `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). + +* Made watch mode incremental. + +* Added support for `Object.fromEntries`, `array.flat` and `array.flatMap`. + +* **BREAKING CHANGE:** Directive `@tupleReturn` should now be specified **per overload**. + +* Fixed a bug where rest parameters would not transpile correctly. +* Fixed an issue with escaped backticks. +* Various small fixes function inference and array detection. + +* Changed testing framework to [jest](https://github.com/facebook/jest). + + ## 0.16.0 * **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument. * To remove the self parameter from a single function add `this: void` to its declaration: From b34142ae73e657e880b014870f86f3347975f6c0 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Wed, 3 Apr 2019 10:02:29 +0200 Subject: [PATCH 049/764] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd6c83c67..6650811d9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.17.0 * We now support source maps in the [standard JS v3 format](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1). You can generate source maps with the `--sourceMap` CLI argument, or by adding `sourceMap: true` to your tsconfig. Inline source maps are also supported with `--inlineSourceMap` CLI/tsconfig parameter. -* Also added support for `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). +* Also added [tstl option](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options) `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). * Made watch mode incremental. From 422a36ad8a053ba3b8efc24b9c30f7a3a368111b Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 3 Apr 2019 15:34:54 -0600 Subject: [PATCH 050/764] output cleanup (#501) * removed empty string literals from template strings and unneeded parenthesis from expressions * stripping parenthesis from casts * fixed indenting * additional binary expression test * function cleanup - using `function foo()` syntax instead of `foo = function()` - Exception made for assigned function expressions - inlining arrow functions with no body - also stripping empty do...end statements * removing continue tags from loops with no continue statements * fixed lint error * addressed feedback and did some cleanup * formatting table literals and added some comments * updates based on feedback * added comment to isValidFunctionDeclarationName * refactored function expression stuff to avoid needing inline parameter on printReturnStatement * moved parens out of printFunctionParameters --- src/LuaAST.ts | 51 +++- src/LuaPrinter.ts | 138 ++++++---- src/LuaTransformer.ts | 208 ++++++++++------ src/TSHelper.ts | 8 + .../__snapshots__/transformation.spec.ts.snap | 235 +++++++++--------- test/unit/assignments/assignments.spec.ts | 12 +- test/unit/expressions.spec.ts | 7 +- test/unit/loops.spec.ts | 32 +-- test/unit/objectLiteral.spec.ts | 10 +- test/unit/sourcemaps.spec.ts | 8 +- test/unit/spreadElement.spec.ts | 8 +- 11 files changed, 427 insertions(+), 290 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 277f4fdf7..3ef1f8612 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -121,11 +121,17 @@ export function cloneNode(node: T): T { return Object.assign({}, node); } +export function setNodePosition(node: T, position: TextRange): T { + node.line = position.line; + node.column = position.column; + + return node; +} + export function setNodeOriginal(node: T, tsOriginal: ts.Node): T { const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { - node.line = sourcePosition.line; - node.column = sourcePosition.column; + setNodePosition(node, sourcePosition); } return node; @@ -589,20 +595,19 @@ export function createStringLiteral(value: string | ts.__String, tsOriginal?: ts return expression; } -// There is no export function statement/declaration because those are just syntax sugar -// -// `function f () body end` becomes `f = function () body` end -// `function t.a.b.c.f () body end` becomes `t.a.b.c.f = function () body end` -// `local function f () body end` becomes `local f; f = function () body end` NOT `local f = function () body end` -// See https://www.lua.org/manual/5.3/manual.html 3.4.11 -// -// We should probably create helper functions to create the different export function declarations +export enum FunctionExpressionFlags { + None = 0x0, + Inline = 0x1, // Keep function on same line + Declaration = 0x2, // Prefer declaration syntax `function foo()` over assignment syntax `foo = function()` +} + export interface FunctionExpression extends Expression { kind: SyntaxKind.FunctionExpression; params?: Identifier[]; dots?: DotsLiteral; restParamName?: Identifier; body: Block; + flags: FunctionExpressionFlags; } export function isFunctionExpression(node: Node): node is FunctionExpression { @@ -614,6 +619,7 @@ export function createFunctionExpression( params?: Identifier[], dots?: DotsLiteral, restParamName?: Identifier, + flags = FunctionExpressionFlags.None, tsOriginal?: ts.Node, parent?: Node ): FunctionExpression @@ -627,6 +633,7 @@ export function createFunctionExpression( expression.dots = dots; setParent(restParamName, expression); expression.restParamName = restParamName; + expression.flags = flags; return expression; } @@ -862,3 +869,27 @@ export function createTableIndexExpression( } export type IdentifierOrTableIndexExpression = Identifier | TableIndexExpression; + +export type FunctionDefinition = (VariableDeclarationStatement | AssignmentStatement) & { + right: [FunctionExpression]; +}; + +export function isFunctionDefinition(statement: VariableDeclarationStatement | AssignmentStatement) + : statement is FunctionDefinition +{ + return statement.left.length === 1 + && statement.right + && statement.right.length === 1 + && isFunctionExpression(statement.right[0]); +} + +export type InlineFunctionExpression = FunctionExpression & { + body: { statements: [ReturnStatement]; }; +}; + +export function isInlineFunctionExpression(expression: FunctionExpression) : expression is InlineFunctionExpression { + return expression.body.statements + && expression.body.statements.length === 1 + && isReturnStatement(expression.body.statements[0]) + && (expression.flags & FunctionExpressionFlags.Inline) !== 0; +} diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 23ac3e753..5538cca89 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -213,25 +213,37 @@ export class LuaPrinter { private printDoStatement(statement: tstl.DoStatement): SourceNode { const chunks: SourceChunk[] = []; - chunks.push(this.indent("do\n")); - this.pushIndent(); - chunks.push(...this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s))); - this.popIndent(); - chunks.push(this.indent("end\n")); + + if (statement.statements && statement.statements.length > 0) { + chunks.push(this.indent("do\n")); + this.pushIndent(); + chunks.push(...this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s))); + this.popIndent(); + chunks.push(this.indent("end\n")); + } return this.concatNodes(...chunks); } private printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { const chunks: SourceChunk[] = []; + chunks.push(this.indent("local ")); - chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); - if (statement.right) { - chunks.push(" = "); - chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); + if (tstl.isFunctionDefinition(statement)) { + // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion + chunks.push(this.printFunctionDefinition(statement)); + chunks.push("\n"); + + } else { + chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); + + if (statement.right) { + chunks.push(" = "); + chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); + } + chunks.push(";\n"); } - chunks.push(";\n"); return this.concatNodes(...chunks); } @@ -240,6 +252,19 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.indent()); + + if (tstl.isFunctionDefinition(statement) + && (statement.right[0].flags & tstl.FunctionExpressionFlags.Declaration) !== 0) + { + // Use `function foo()` instead of `foo = function()` + const name = this.printExpression(statement.left[0]); + if (tsHelper.isValidLuaFunctionDeclarationName(name.toString())) { + chunks.push(this.printFunctionDefinition(statement)); + chunks.push("\n"); + return this.createSourceNode(statement, chunks); + } + } + chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); chunks.push(" = "); chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); @@ -359,7 +384,6 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(...this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e)))); - chunks.push(";\n"); return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); @@ -436,7 +460,7 @@ export class LuaPrinter { } } - private printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { + private printFunctionParameters(expression: tstl.FunctionExpression): SourceChunk[] { const parameterChunks: SourceNode[] = expression.params ? expression.params.map(i => this.printIdentifier(i)) : []; @@ -445,10 +469,46 @@ export class LuaPrinter { parameterChunks.push(this.printDotsLiteral(expression.dots)); } + return this.joinChunks(", ", parameterChunks); + } + + private printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("function("); - chunks.push(...this.joinChunks(", ", parameterChunks)); + chunks.push(...this.printFunctionParameters(expression)); + chunks.push(")"); + + if (tstl.isInlineFunctionExpression(expression)) { + const returnStatement = expression.body.statements[0]; + chunks.push(" "); + const returnNode: SourceChunk[] = [ + "return ", + ...this.joinChunks(", ", returnStatement.expressions.map(e => this.printExpression(e))), + ";", + ]; + chunks.push(this.createSourceNode(returnStatement, returnNode)); + chunks.push(" end"); + + } else { + chunks.push("\n"); + this.pushIndent(); + chunks.push(this.printBlock(expression.body)); + this.popIndent(); + chunks.push(this.indent("end")); + } + + return this.createSourceNode(expression, chunks); + } + + private printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { + const expression = statement.right[0]; + const chunks: SourceChunk[] = []; + + chunks.push("function "); + chunks.push(this.printExpression(statement.left[0])); + chunks.push("("); + chunks.push(...this.printFunctionParameters(expression)); chunks.push(")\n"); this.pushIndent(); @@ -482,14 +542,18 @@ export class LuaPrinter { chunks.push("{"); - if (expression.fields) { - expression.fields.forEach((f, i) => { - if (i < expression.fields.length - 1) { - chunks.push(this.printTableFieldExpression(f), ", "); - } else { - chunks.push(this.printTableFieldExpression(f)); - } - }); + if (expression.fields && expression.fields.length > 0) { + if (expression.fields.length === 1) { + // Inline tables with only one entry + chunks.push(this.printTableFieldExpression(expression.fields[0])); + + } else { + chunks.push("\n"); + this.pushIndent(); + expression.fields.forEach(f => chunks.push(this.indent(), this.printTableFieldExpression(f), ",\n")); + this.popIndent(); + chunks.push(this.indent()); + } } chunks.push("}"); @@ -501,12 +565,7 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); - - if (this.needsParentheses(expression.operand)) { - chunks.push("(", this.printExpression(expression.operand), ")"); - } else { - chunks.push(this.printExpression(expression.operand)); - } + chunks.push(this.printExpression(expression.operand)); return this.createSourceNode(expression, chunks); } @@ -514,28 +573,13 @@ export class LuaPrinter { private printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; - if (this.needsParentheses(expression.left)) { - chunks.push("(", this.printExpression(expression.left), ")"); - } else { - chunks.push(this.printExpression(expression.left)); - } - + chunks.push(this.printExpression(expression.left)); chunks.push(" ", this.printOperator(expression.operator), " "); - - if (this.needsParentheses(expression.right)) { - chunks.push("(", this.printExpression(expression.right), ")"); - } else { - chunks.push(this.printExpression(expression.right)); - } + chunks.push(this.printExpression(expression.right)); return this.createSourceNode(expression, chunks); } - private needsParentheses(expression: tstl.Expression): boolean { - return tstl.isBinaryExpression(expression) || tstl.isUnaryExpression(expression) - || tstl.isFunctionExpression(expression); - } - private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { return this.createSourceNode(expression, ["(", this.printExpression(expression.innerEpxression), ")"]); } @@ -544,11 +588,7 @@ export class LuaPrinter { const chunks = []; const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e))); - if (this.needsParentheses(expression.expression)) { - chunks.push("(", this.printExpression(expression.expression), ")(", ...parameterChunks, ")"); - } else { - chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")"); - } + chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")"); return this.concatNodes(...chunks); } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 40d2b8eed..9fc558448 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -25,7 +25,7 @@ interface SymbolInfo { interface FunctionDefinitionInfo { referencedSymbols: Set; - assignment?: tstl.AssignmentStatement; + definition?: tstl.VariableDeclarationStatement | tstl.AssignmentStatement; } interface Scope { @@ -34,6 +34,7 @@ interface Scope { referencedSymbols?: Set; variableDeclarations?: tstl.VariableDeclarationStatement[]; functionDefinitions?: Map; + loopContinued?: boolean; } export class LuaTransformer { @@ -536,7 +537,9 @@ export class LuaTransformer { const constructorFunction = tstl.createFunctionExpression( tstl.createBlock(constructorBody), [this.createSelfIdentifier()], - tstl.createDotsLiteral() + tstl.createDotsLiteral(), + undefined, + tstl.FunctionExpressionFlags.Declaration ); result.push(tstl.createAssignmentStatement( this.createConstructorName(className), @@ -898,6 +901,7 @@ export class LuaTransformer { undefined, tstl.createDotsLiteral(), undefined, + tstl.FunctionExpressionFlags.Declaration, statement ), statement @@ -1014,7 +1018,13 @@ export class LuaTransformer { const result = tstl.createAssignmentStatement( this.createConstructorName(className), - tstl.createFunctionExpression(block, params, dotsLiteral, restParamName, undefined, undefined), + tstl.createFunctionExpression( + block, + params, + dotsLiteral, + restParamName, + tstl.FunctionExpressionFlags.Declaration + ), statement ); @@ -1032,7 +1042,10 @@ export class LuaTransformer { const [body] = this.transformFunctionBody(getAccessor.parameters, getAccessor.body); const accessorFunction = tstl.createFunctionExpression( tstl.createBlock(body), - [this.createSelfIdentifier()] + [this.createSelfIdentifier()], + undefined, + undefined, + tstl.FunctionExpressionFlags.Declaration ); const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); @@ -1067,7 +1080,8 @@ export class LuaTransformer { tstl.createBlock(body), params, dot, - restParam + restParam, + tstl.FunctionExpressionFlags.Declaration ); const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); @@ -1115,6 +1129,7 @@ export class LuaTransformer { paramNames, dots, restParamName, + tstl.FunctionExpressionFlags.Declaration, node.body ); @@ -1630,7 +1645,13 @@ export class LuaTransformer { restParamName ); const block = tstl.createBlock(body); - const functionExpression = tstl.createFunctionExpression(block, params, dotsLiteral, restParamName); + const functionExpression = tstl.createFunctionExpression( + block, + params, + dotsLiteral, + restParamName, + tstl.FunctionExpressionFlags.Declaration + ); // Remember symbols referenced in this function for hoisting later if (!this.options.noHoisting && name.symbolId !== undefined) { const scope = this.peekScope(); @@ -1684,7 +1705,7 @@ export class LuaTransformer { table = this.transformIdentifier(statement.initializer); } else { // Contain the expression in a temporary variable - table = tstl.createIdentifier("____"); + table = tstl.createAnnonymousIdentifier(); statements.push(tstl.createVariableDeclarationStatement( table, this.transformExpression(statement.initializer))); } @@ -1870,7 +1891,10 @@ export class LuaTransformer { public transformDoStatement(statement: ts.DoStatement): tstl.RepeatStatement { return tstl.createRepeatStatement( tstl.createBlock(this.transformLoopBody(statement)), - tstl.createUnaryExpression(this.transformExpression(statement.expression), tstl.SyntaxKind.NotOperator), + tstl.createUnaryExpression( + tstl.createParenthesizedExpression(this.transformExpression(statement.expression)), + tstl.SyntaxKind.NotOperator + ), statement ); } @@ -1940,7 +1964,7 @@ export class LuaTransformer { const scope = this.popScope(); const scopeId = scope.id; - if (this.options.luaTarget === LuaTarget.Lua51) { + if (!scope.loopContinued) { return body; } @@ -2223,7 +2247,10 @@ export class LuaTransformer { result.push(catchAssignment); - const notTryResult = tstl.createUnaryExpression(tryResult, tstl.SyntaxKind.NotOperator); + const notTryResult = tstl.createUnaryExpression( + tstl.createParenthesizedExpression(tryResult), + tstl.SyntaxKind.NotOperator + ); result.push(tstl.createIfStatement(notTryResult, this.transformBlock(statement.catchClause.block))); } else { @@ -2258,8 +2285,10 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedForTarget("Continue statement", this.options.luaTarget, statement); } + const scope = this.findScope(ScopeType.Loop); + scope.loopContinued = true; return tstl.createGotoStatement( - `__continue${this.findScope(ScopeType.Loop).id}`, + `__continue${scope.id}`, statement ); } @@ -2310,9 +2339,8 @@ export class LuaTransformer { case ts.SyntaxKind.DeleteExpression: return this.transformDeleteExpression(expression as ts.DeleteExpression); case ts.SyntaxKind.FunctionExpression: - return this.transformFunctionExpression(expression as ts.ArrowFunction, this.createSelfIdentifier()); case ts.SyntaxKind.ArrowFunction: - return this.transformFunctionExpression(expression as ts.ArrowFunction, tstl.createIdentifier("____")); + return this.transformFunctionExpression(expression as ts.ArrowFunction); case ts.SyntaxKind.NewExpression: return this.transformNewExpression(expression as ts.NewExpression); case ts.SyntaxKind.ParenthesizedExpression: @@ -2878,10 +2906,10 @@ export class LuaTransformer { const val1Function = this.wrapInFunctionCall(val1); const val2Function = this.wrapInFunctionCall(val2); - // ((condition and (() => v1)) or (() => v2))() + // (condition and (() => v1) or (() => v2))() const conditionAnd = tstl.createBinaryExpression(condition, val1Function, tstl.SyntaxKind.AndOperator); const orExpression = tstl.createBinaryExpression(conditionAnd, val2Function, tstl.SyntaxKind.OrOperator); - return tstl.createCallExpression(orExpression, [], expression); + return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression); } public transformConditionalExpression(expression: ts.ConditionalExpression): tstl.Expression { @@ -2893,7 +2921,7 @@ export class LuaTransformer { const val1 = this.transformExpression(expression.whenTrue); const val2 = this.transformExpression(expression.whenFalse); - // (condition and v1) or v2 + // condition and v1 or v2 const conditionAnd = tstl.createBinaryExpression(condition, val1, tstl.SyntaxKind.AndOperator); return tstl.createBinaryExpression( conditionAnd, @@ -2997,7 +3025,7 @@ export class LuaTransformer { const identifier = this.transformIdentifier(element.name); properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { - const expression = this.transformFunctionExpression(element, this.createSelfIdentifier()); + const expression = this.transformFunctionExpression(element); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, node); @@ -3022,19 +3050,26 @@ export class LuaTransformer { ); } - public transformFunctionExpression( - node: ts.FunctionLikeDeclaration, - context: tstl.Identifier | undefined - ): ExpressionVisitResult - { + public transformFunctionExpression(node: ts.FunctionLikeDeclaration): ExpressionVisitResult { const type = this.checker.getTypeAtLocation(node); - const hasContext = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void; + + let context: tstl.Identifier | undefined; + if (tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void) { + if (ts.isArrowFunction(node)) { + // dummy context for arrow functions with parameters + if (node.parameters.length > 0) { + context = tstl.createAnnonymousIdentifier(); + } + } else { + // self context + context = this.createSelfIdentifier(); + } + } + // Build parameter string - const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters( - node.parameters, - hasContext ? context : undefined - ); + const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters(node.parameters, context); + let flags = tstl.FunctionExpressionFlags.None; let body: ts.Block; if (ts.isBlock(node.body)) { body = node.body; @@ -3043,6 +3078,7 @@ export class LuaTransformer { body = ts.createBlock([returnExpression]); returnExpression.parent = body; body.parent = node.body.parent; + flags |= tstl.FunctionExpressionFlags.Inline; } const [transformedBody] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); @@ -3051,6 +3087,7 @@ export class LuaTransformer { paramNames, dotsLiteral, spreadIdentifier, + flags, node ); } @@ -3091,6 +3128,11 @@ export class LuaTransformer { } public transformParenthesizedExpression(expression: ts.ParenthesizedExpression): tstl.Expression { + if (ts.isAssertionExpression(expression.expression)) { + // Strip parenthesis from casts + return this.transformExpression(expression.expression); + } + return tstl.createParenthesizedExpression( this.transformExpression(expression.expression), expression @@ -3249,8 +3291,10 @@ export class LuaTransformer { parameters = this.transformArguments(node.arguments, signature); const rawGetIdentifier = tstl.createIdentifier("rawget"); const rawGetCall = tstl.createCallExpression(rawGetIdentifier, [expr, ...parameters]); - return tstl.createBinaryExpression( - rawGetCall, tstl.createNilLiteral(), tstl.SyntaxKind.InequalityOperator, node); + return tstl.createParenthesizedExpression( + tstl.createBinaryExpression( + rawGetCall, tstl.createNilLiteral(), tstl.SyntaxKind.InequalityOperator, node) + ); } else { const parameters = this.transformArguments(node.arguments, signature); const table = this.transformExpression(node.expression.expression); @@ -3590,20 +3634,24 @@ export class LuaTransformer { node.arguments.length === 1 ? this.createStringCall("find", node, caller, params[0]) : this.createStringCall( - "find", node, caller, params[0], - this.expressionPlusOne(params[1]), - tstl.createBooleanLiteral(true) - ); + "find", node, caller, params[0], + this.expressionPlusOne(params[1]), + tstl.createBooleanLiteral(true) + ); - return tstl.createBinaryExpression( + return tstl.createParenthesizedExpression( tstl.createBinaryExpression( - stringExpression, - tstl.createNumericLiteral(0), - tstl.SyntaxKind.OrOperator - ), - tstl.createNumericLiteral(1), - tstl.SyntaxKind.SubractionOperator, - node + tstl.createParenthesizedExpression( + tstl.createBinaryExpression( + stringExpression, + tstl.createNumericLiteral(0), + tstl.SyntaxKind.OrOperator + ) + ), + tstl.createNumericLiteral(1), + tstl.SyntaxKind.SubractionOperator, + node + ) ); case "substr": if (node.arguments.length === 1) { @@ -3612,7 +3660,11 @@ export class LuaTransformer { } else { const arg1 = params[0]; const arg2 = params[1]; - const sumArg = tstl.createBinaryExpression(arg1, arg2, tstl.SyntaxKind.AdditionOperator); + const sumArg = tstl.createBinaryExpression( + tstl.createParenthesizedExpression(arg1), + tstl.createParenthesizedExpression(arg2), + tstl.SyntaxKind.AdditionOperator + ); return this.createStringCall("sub", node, caller, this.expressionPlusOne(arg1), sumArg); } case "substring": @@ -3974,11 +4026,13 @@ export class LuaTransformer { const condition = tstl.createBinaryExpression(typeCall, tableString, tstl.SyntaxKind.EqualityOperator); const andClause = tstl.createBinaryExpression(condition, objectString, tstl.SyntaxKind.AndOperator); - return tstl.createBinaryExpression( - andClause, - tstl.cloneNode(typeCall), - tstl.SyntaxKind.OrOperator, - node + return tstl.createParenthesizedExpression( + tstl.createBinaryExpression( + andClause, + tstl.cloneNode(typeCall), + tstl.SyntaxKind.OrOperator, + node + ) ); } @@ -4017,24 +4071,29 @@ export class LuaTransformer { return this.createSelfIdentifier(thisKeyword); } - public transformTemplateExpression(expression: ts.TemplateExpression): tstl.BinaryExpression { - const parts: tstl.Expression[] = [tstl.createStringLiteral(tsHelper.escapeString(expression.head.text))]; + public transformTemplateExpression(expression: ts.TemplateExpression): tstl.Expression { + const parts: tstl.Expression[] = []; + + const head = tsHelper.escapeString(expression.head.text); + if (head.length > 0) { + parts.push(tstl.createStringLiteral(head, expression.head)); + } + expression.templateSpans.forEach(span => { const expr = this.transformExpression(span.expression); - const text = tstl.createStringLiteral(tsHelper.escapeString(span.literal.text)); + parts.push(tstl.createCallExpression(tstl.createIdentifier("tostring"), [expr])); - // tostring(expr).."text" - parts.push(tstl.createBinaryExpression( - tstl.createCallExpression(tstl.createIdentifier("tostring"), [expr]), - text, - tstl.SyntaxKind.ConcatOperator) - ); + const text = tsHelper.escapeString(span.literal.text); + if (text.length > 0) { + parts.push(tstl.createStringLiteral(text, span.literal)); + } }); + return parts.reduce((prev, current) => tstl.createBinaryExpression( prev, current, tstl.SyntaxKind.ConcatOperator) - ) as tstl.BinaryExpression; + ); } public transformPropertyName(propertyName: ts.PropertyName): tstl.Expression { @@ -4289,11 +4348,13 @@ export class LuaTransformer { } if ((this.isModule || this.currentNamespace || insideFunction || isLetOrConst) && isFirstDeclaration) { // local - const isFunctionType = functionDeclaration - || (tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.initializer - && tsHelper.isFunctionTypeAtLocation(tsOriginal.initializer, this.checker)); - if (isFunctionType) { - // Split declaration and assignment for cuntions to allow recursion + const isPossibleWrappedFunction = !functionDeclaration + && tsOriginal + && ts.isVariableDeclaration(tsOriginal) + && tsOriginal.initializer + && tsHelper.isFunctionTypeAtLocation(tsOriginal.initializer, this.checker); + if (isPossibleWrappedFunction) { + // Split declaration and assignment for wrapped function types to allow recursion declaration = tstl.createVariableDeclarationStatement(lhs, undefined, tsOriginal, parent); assignment = tstl.createAssignmentStatement(lhs, rhs, tsOriginal, parent); @@ -4324,7 +4385,7 @@ export class LuaTransformer { // Remember function definitions for hoisting later const functionSymbolId = (lhs as tstl.Identifier).symbolId; if (functionSymbolId !== undefined) { - this.peekScope().functionDefinitions.get(functionSymbolId).assignment = assignment; + this.peekScope().functionDefinitions.get(functionSymbolId).definition = declaration || assignment; } } @@ -4423,6 +4484,9 @@ export class LuaTransformer { } private expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { + if (tstl.isBinaryExpression(expression)) { + expression = tstl.createParenthesizedExpression(expression); + } return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } @@ -4491,13 +4555,13 @@ export class LuaTransformer { if (scope.functionDefinitions) { for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { - const { line, column } = tstl.getOriginalPos(functionDefinition.assignment); - const assignmentPos = ts.getPositionOfLineAndCharacter( + const { line, column } = tstl.getOriginalPos(functionDefinition.definition); + const definitionPos = ts.getPositionOfLineAndCharacter( this.currentSourceFile, line, column); if (functionSymbolId !== symbolId // Don't recurse into self - && declaration.pos < assignmentPos // Ignore functions before symbol declaration + && declaration.pos < definitionPos // Ignore functions before symbol declaration && functionDefinition.referencedSymbols.has(symbolId) && this.shouldHoist(functionSymbolId, scope)) { @@ -4531,12 +4595,12 @@ export class LuaTransformer { } const result = statements.slice(); - const hoistedFunctions: tstl.AssignmentStatement[] = []; + const hoistedFunctions: Array = []; for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { if (this.shouldHoist(functionSymbolId, scope)) { - const i = result.indexOf(functionDefinition.assignment); + const i = result.indexOf(functionDefinition.definition); result.splice(i, 1); - hoistedFunctions.push(functionDefinition.assignment); + hoistedFunctions.push(functionDefinition.definition); } } if (hoistedFunctions.length > 0) { @@ -4557,10 +4621,8 @@ export class LuaTransformer { if (symbols.some(s => this.shouldHoist(s, scope))) { let assignment: tstl.AssignmentStatement | undefined; if (declaration.right) { - assignment = tstl.createAssignmentStatement( - declaration.left, - declaration.right - ); + assignment = tstl.createAssignmentStatement(declaration.left, declaration.right); + tstl.setNodePosition(assignment, declaration); // Preserve position info for sourcemap } const i = result.indexOf(declaration); if (i >= 0) { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 717ba023c..d9ec50f2e 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -652,6 +652,14 @@ export class TSHelper { return match && match[0] === str; } + // Checks that a name is valid for use in lua function declaration syntax: + // 'foo.bar' => passes ('function foo.bar()' is valid) + // 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) + public static isValidLuaFunctionDeclarationName(str: string): boolean { + const match = str.match(/[a-zA-Z0-9_\.]+/); + return match && match[0] === str; + } + public static isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { const falsibleFlags = ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 9c88af876..b0baaa3dd 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -14,31 +14,31 @@ local backQuoteInTemplateString = \\"\` \` \`\\"; local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\"; local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; -local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. (tostring(\\"Level 1: \\\\n\\\\t\\\\t \\" .. (tostring(\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. (tostring(\\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\");" +local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. tostring(\\"Level 1: \\\\n\\\\t\\\\t \\" .. tostring(\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. tostring(\\"Last level \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\";" `; exports[`Transformation (classExtension1) 1`] = ` -"MyClass.myFunction = function(self) -end;" +"function MyClass.myFunction(self) +end" `; exports[`Transformation (classExtension2) 1`] = ` -"TestClass.myFunction = function(self) -end;" +"function TestClass.myFunction(self) +end" `; exports[`Transformation (classExtension3) 1`] = ` -"RenamedTestClass.myFunction = function(self) -end; -RenamedMyClass.myFunction = function(self) -end;" +"function RenamedTestClass.myFunction(self) +end +function RenamedMyClass.myFunction(self) +end" `; exports[`Transformation (classExtension4) 1`] = ` "MyClass.test = \\"test\\"; MyClass.testP = \\"testP\\"; -MyClass.myFunction = function(self) -end;" +function MyClass.myFunction(self) +end" `; exports[`Transformation (classPureAbstract) 1`] = ` @@ -47,13 +47,13 @@ ClassB.__index = ClassB; ClassB.prototype = ClassB.prototype or {}; ClassB.prototype.__index = ClassB.prototype; ClassB.prototype.constructor = ClassB; -ClassB.new = function(...) +function ClassB.new(...) local self = setmetatable({}, ClassB.prototype); self:____constructor(...); return self; -end; -ClassB.prototype.____constructor = function(self) -end;" +end +function ClassB.prototype.____constructor(self) +end" `; exports[`Transformation (continue) 1`] = ` @@ -94,7 +94,7 @@ exports[`Transformation (continueNested) 1`] = ` local i = 0; while i < 5 do do - if (i % 2) == 0 then + if i % 2 == 0 then goto __continue1; end do @@ -121,7 +121,7 @@ exports[`Transformation (continueNestedConcurrent) 1`] = ` local i = 0; while i < 5 do do - if (i % 2) == 0 then + if i % 2 == 0 then goto __continue1; end do @@ -149,10 +149,7 @@ end" exports[`Transformation (do) 1`] = ` "local e = 10; repeat - do - e = e - 1; - end - ::__continue1:: + e = e - 1; until not (e > 0);" `; @@ -224,36 +221,43 @@ exports[`Transformation (for) 1`] = ` "do local i = 1; while i <= 100 do - do - end - ::__continue1:: i = i + 1; end end" `; exports[`Transformation (forIn) 1`] = ` -"for i in pairs({a = 1, b = 2, c = 3, d = 4}) do - do - end - ::__continue1:: +"for i in pairs({ + a = 1, + b = 2, + c = 3, + d = 4, +}) do end" `; exports[`Transformation (forOf) 1`] = ` -"local ____TS_array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +"local ____TS_array = { + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, +}; for ____TS_index = 1, #____TS_array do local i = ____TS_array[____TS_index]; - do - end - ::__continue1:: end" `; exports[`Transformation (functionRestArguments) 1`] = ` -"varargsFunction = function(self, a, ...) +"function varargsFunction(self, a, ...) local b = ({...}); -end;" +end" `; exports[`Transformation (getSetAccessors) 1`] = ` @@ -266,19 +270,19 @@ MyClass.prototype.__index = __TS__Index(MyClass.prototype); MyClass.prototype.____setters = {}; MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype); MyClass.prototype.constructor = MyClass; -MyClass.new = function(...) +function MyClass.new(...) local self = setmetatable({}, MyClass.prototype); self:____constructor(...); return self; -end; -MyClass.prototype.____constructor = function(self) -end; -MyClass.prototype.____getters.field = function(self) +end +function MyClass.prototype.____constructor(self) +end +function MyClass.prototype.____getters.field(self) return self._field + 4; -end; -MyClass.prototype.____setters.field = function(self, v) +end +function MyClass.prototype.____setters.field(self, v) self._field = v * 2; -end; +end local instance = MyClass.new(); instance.field = 4; local b = instance.field; @@ -296,16 +300,16 @@ MyClass.__index = MyClass; MyClass.prototype = MyClass.prototype or {}; MyClass.prototype.__index = MyClass.prototype; MyClass.prototype.constructor = MyClass; -MyClass.new = function(...) +function MyClass.new(...) local self = setmetatable({}, MyClass.prototype); self:____constructor(...); return self; -end; -MyClass.prototype.____constructor = function(self) -end; -MyClass.prototype.varargsFunction = function(self, a, ...) +end +function MyClass.prototype.____constructor(self) +end +function MyClass.prototype.varargsFunction(self, a, ...) local b = ({...}); -end;" +end" `; exports[`Transformation (modulesChangedVariableExport) 1`] = ` @@ -321,13 +325,13 @@ exports.TestClass.__index = exports.TestClass; exports.TestClass.prototype = exports.TestClass.prototype or {}; exports.TestClass.prototype.__index = exports.TestClass.prototype; exports.TestClass.prototype.constructor = exports.TestClass; -exports.TestClass.new = function(...) +function exports.TestClass.new(...) local self = setmetatable({}, exports.TestClass.prototype); self:____constructor(...); return self; -end; -exports.TestClass.prototype.____constructor = function(self) -end; +end +function exports.TestClass.prototype.____constructor(self) +end return exports;" `; @@ -338,28 +342,28 @@ exports.TestClass.__index = exports.TestClass; exports.TestClass.prototype = exports.TestClass.prototype or {}; exports.TestClass.prototype.__index = exports.TestClass.prototype; exports.TestClass.prototype.constructor = exports.TestClass; -exports.TestClass.new = function(...) +function exports.TestClass.new(...) local self = setmetatable({}, exports.TestClass.prototype); self:____constructor(...); return self; -end; -exports.TestClass.prototype.____constructor = function(self) -end; -exports.TestClass.prototype.memberFunc = function(self) -end; +end +function exports.TestClass.prototype.____constructor(self) +end +function exports.TestClass.prototype.memberFunc(self) +end return exports;" `; exports[`Transformation (modulesFunctionExport) 1`] = ` "local exports = exports or {}; -exports.publicFunc = function(self) -end; +function exports.publicFunc(self) +end return exports;" `; exports[`Transformation (modulesFunctionNoExport) 1`] = ` -"publicFunc = function(self) -end;" +"function publicFunc(self) +end" `; exports[`Transformation (modulesImportAll) 1`] = `"local Test = require(\\"test\\");"`; @@ -406,8 +410,6 @@ exports[`Transformation (modulesNamespaceExport) 1`] = ` "local exports = exports or {}; exports.TestSpace = exports.TestSpace or {}; local TestSpace = exports.TestSpace; -do -end return exports;" `; @@ -433,26 +435,22 @@ do TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {}; local TestNestedSpace = TestSpace.TestNestedSpace; do - TestNestedSpace.innerFunc = function(self) - end; + function TestNestedSpace.innerFunc(self) + end end end return exports;" `; -exports[`Transformation (modulesNamespaceNoExport) 1`] = ` -"TestSpace = TestSpace or {}; -do -end" -`; +exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {};"`; exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` "local exports = exports or {}; exports.TestSpace = exports.TestSpace or {}; local TestSpace = exports.TestSpace; do - TestSpace.innerFunc = function(self) - end; + function TestSpace.innerFunc(self) + end end return exports;" `; @@ -462,9 +460,8 @@ exports[`Transformation (modulesNamespaceWithMemberNoExport) 1`] = ` exports.TestSpace = exports.TestSpace or {}; local TestSpace = exports.TestSpace; do - local innerFunc; - innerFunc = function(self) - end; + local function innerFunc(self) + end end return exports;" `; @@ -480,9 +477,8 @@ exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\"; exports[`Transformation (namespace) 1`] = ` "myNamespace = myNamespace or {}; do - local nsMember; - nsMember = function(self) - end; + local function nsMember(self) + end end" `; @@ -492,30 +488,30 @@ MergedClass.__index = MergedClass; MergedClass.prototype = MergedClass.prototype or {}; MergedClass.prototype.__index = MergedClass.prototype; MergedClass.prototype.constructor = MergedClass; -MergedClass.new = function(...) +function MergedClass.new(...) local self = setmetatable({}, MergedClass.prototype); self:____constructor(...); return self; -end; -MergedClass.prototype.____constructor = function(self) - self.propertyFunc = function(____) +end +function MergedClass.prototype.____constructor(self) + self.propertyFunc = function() end; -end; -MergedClass.staticMethodA = function(self) -end; -MergedClass.staticMethodB = function(self) +end +function MergedClass.staticMethodA(self) +end +function MergedClass.staticMethodB(self) self:staticMethodA(); -end; -MergedClass.prototype.methodA = function(self) -end; -MergedClass.prototype.methodB = function(self) +end +function MergedClass.prototype.methodA(self) +end +function MergedClass.prototype.methodB(self) self:methodA(); self:propertyFunc(); -end; +end MergedClass = MergedClass or {}; do - MergedClass.namespaceFunc = function(self) - end; + function MergedClass.namespaceFunc(self) + end end local mergedClass = MergedClass.new(); mergedClass:methodB(); @@ -530,29 +526,26 @@ do myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {}; local myNestedNamespace = myNamespace.myNestedNamespace; do - local nsMember; - nsMember = function(self) - end; + local function nsMember(self) + end end end" `; exports[`Transformation (namespacePhantom) 1`] = ` -"nsMember = function(self) -end;" +"function nsMember(self) +end" `; exports[`Transformation (returnDefault) 1`] = ` -"myFunc = function(self) +"function myFunc(self) return; -end;" +end" `; exports[`Transformation (shorthandPropertyAssignment) 1`] = ` "local f; -f = function(____, x) - return ({x = x}); -end;" +f = function(____, x) return ({x = x}); end;" `; exports[`Transformation (tryCatch) 1`] = ` @@ -560,7 +553,7 @@ exports[`Transformation (tryCatch) 1`] = ` local ____TS_try, er = pcall(function() local a = 42; end); - if not ____TS_try then + if not (____TS_try) then local b = \\"fail\\"; end end" @@ -571,7 +564,7 @@ exports[`Transformation (tryCatchFinally) 1`] = ` local ____TS_try, er = pcall(function() local a = 42; end); - if not ____TS_try then + if not (____TS_try) then local b = \\"fail\\"; end do @@ -592,9 +585,9 @@ end" `; exports[`Transformation (tupleReturn) 1`] = ` -"tupleReturn = function(self) +"function tupleReturn(self) return 0, \\"foobar\\"; -end; +end tupleReturn(_G); noTupleReturn(_G); local a, b = tupleReturn(_G); @@ -607,19 +600,22 @@ e = ({tupleReturn(_G)}); f = noTupleReturn(_G); foo(_G, ({tupleReturn(_G)})); foo(_G, noTupleReturn(_G)); -tupleReturnFromVar = function(self) - local r = {1, \\"baz\\"}; +function tupleReturnFromVar(self) + local r = { + 1, + \\"baz\\", + }; return table.unpack(r); -end; -tupleReturnForward = function(self) +end +function tupleReturnForward(self) return tupleReturn(_G); -end; -tupleNoForward = function(self) +end +function tupleNoForward(self) return ({tupleReturn(_G)}); -end; -tupleReturnUnpack = function(self) +end +function tupleReturnUnpack(self) return table.unpack(tupleNoForward(_G)); -end;" +end" `; exports[`Transformation (typeAssert) 1`] = ` @@ -630,9 +626,6 @@ local test2 = 10;" exports[`Transformation (while) 1`] = ` "local d = 10; while d > 0 do - do - d = d - 1; - end - ::__continue1:: + d = d - 1; end" `; diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index 4102b6d26..54f925d41 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -5,10 +5,10 @@ import * as util from "../../util"; test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, + { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Const assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`const myvar = ${inp};`); expect(lua).toBe(`local myvar = ${out};`); @@ -17,10 +17,10 @@ test.each([ test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, + { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Let assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`let myvar = ${inp};`); expect(lua).toBe(`local myvar = ${out};`); @@ -29,10 +29,10 @@ test.each([ test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, + { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, + { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Var assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`var myvar = ${inp};`); expect(lua).toBe(`myvar = ${out};`); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index e1acbfa18..072accf9b 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -177,10 +177,11 @@ test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { test.each([ { input: "1+1", lua: "1 + 1;" }, - { input: "-1+1", lua: "(-1) + 1;" }, - { input: "1*30+4", lua: "(1 * 30) + 4;" }, + { input: "-1+1", lua: "-1 + 1;" }, + { input: "1*30+4", lua: "1 * 30 + 4;" }, { input: "1*(3+4)", lua: "1 * (3 + 4);" }, - { input: "1*(3+4*2)", lua: "1 * (3 + (4 * 2));" }, + { input: "1*(3+4*2)", lua: "1 * (3 + 4 * 2);" }, + { input: "10-(4+5)", lua: "10 - (4 + 5);" }, ])("Binary expressions ordering parentheses (%p)", ({ input, lua }) => { expect(util.transpileString(input)).toBe(lua); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index d87f019fd..1b78813d8 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -763,21 +763,23 @@ test("forof forwarded lua iterator with tupleReturn", () => { }); test.each([ - "while (a < b) { i++; }", - "do { i++; } while (a < b)", - "for (let i = 0; i < 3; i++) {}", - "for (let a in b) {}", - "for (let a of b) {}", -])("loop versions (%p)", loop => { - const lua51 = util.transpileString(loop, { luaTarget: LuaTarget.Lua51 }); - const lua52 = util.transpileString(loop, { luaTarget: LuaTarget.Lua52 }); - const lua53 = util.transpileString(loop, { luaTarget: LuaTarget.Lua53 }); - const luajit = util.transpileString(loop, { luaTarget: LuaTarget.LuaJIT }); - - expect(lua51.indexOf("::__continue1::") !== -1).toBe(false); // No labels in 5.1 - expect(lua52.indexOf("::__continue1::") !== -1).toBe(true); // Labels from 5.2 onwards - expect(lua53.indexOf("::__continue1::") !== -1).toBe(true); - expect(luajit.indexOf("::__continue1::") !== -1).toBe(true); + "while (a < b) { i++; continue; }", + "do { i++; continue; } while (a < b)", + "for (let i = 0; i < 3; i++) { continue; }", + "for (let a in b) { continue; }", + "for (let a of b) { continue; }", +])("loop continue in different lua versions (%p)", loop => { + const lua51 = { luaTarget: LuaTarget.Lua51 }; + const lua52 = { luaTarget: LuaTarget.Lua52 }; + const lua53 = { luaTarget: LuaTarget.Lua53 }; + const luajit = { luaTarget: LuaTarget.LuaJIT }; + + expect(() => util.transpileString(loop, lua51)).toThrowError( + TSTLErrors.UnsupportedForTarget("Continue statement", LuaTarget.Lua51, undefined), + ); + expect(util.transpileString(loop, lua52).indexOf("::__continue1::") !== -1).toBe(true); + expect(util.transpileString(loop, lua53).indexOf("::__continue1::") !== -1).toBe(true); + expect(util.transpileString(loop, luajit).indexOf("::__continue1::") !== -1).toBe(true); }); test("for dead code after return", () => { diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 21ae4abf0..3cc8ad2c2 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -2,11 +2,11 @@ import * as util from "../util"; const fs = require("fs"); test.each([ - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"};` }, - { inp: `{"a":3,b:"4"}`, out: `{a = 3, b = "4"};` }, - { inp: `{["a"]:3,b:"4"}`, out: `{a = 3, b = "4"};` }, - { inp: `{["a"+123]:3,b:"4"}`, out: `{["a" .. 123] = 3, b = "4"};` }, - { inp: `{[myFunc()]:3,b:"4"}`, out: `{[myFunc(_G)] = 3, b = "4"};` }, + { inp: `{a:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, + { inp: `{"a":3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, + { inp: `{["a"]:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, + { inp: `{["a"+123]:3,b:"4"}`, out: '{\n ["a" .. 123] = 3,\n b = "4",\n};' }, + { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4",\n};' }, { inp: `{x}`, out: `{x = x};` }, ])("Object Literal (%p)", ({ inp, out }) => { const lua = util.transpileString(`const myvar = ${inp};`); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index b6873787b..e8a374780 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -7,7 +7,7 @@ test.each([ typeScriptSource: ` const abc = "foo"; const def = "bar"; - + const xyz = "baz";`, assertPatterns: [ @@ -30,8 +30,8 @@ test.each([ return abc();`, assertPatterns: [ - { luaPattern: "abc = function(", typeScriptPattern: "abc() {" }, - { luaPattern: "def = function(", typeScriptPattern: "def() {" }, + { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, + { luaPattern: "function def(", typeScriptPattern: "function def() {" }, { luaPattern: "return abc(", typeScriptPattern: "return abc(" }, ], }, @@ -94,7 +94,7 @@ test("sourceMapTraceback saves sourcemap in _G", () => { expect(sourceMap[sourceMapFiles[0]]).toBeDefined(); const assertPatterns = [ - { luaPattern: "abc = function(", typeScriptPattern: "abc() {" }, + { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, { luaPattern: `return "foo"`, typeScriptPattern: `return "foo"` }, ]; diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 3bb7ff981..42559ec2a 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -15,23 +15,23 @@ test("Spread Element Lua 5.1", () => { // Cant test functional because our VM doesn't run on 5.1 const options = { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); - expect(lua).toBe("__TS__ArrayPush({}, unpack({1, 2, 3}));"); + expect(lua).toBe("__TS__ArrayPush({}, unpack({\n 1,\n 2,\n 3,\n}));"); }); test("Spread Element Lua 5.2", () => { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{table.unpack({0, 1, 2})};"); + expect(lua).toBe("{table.unpack({\n 0,\n 1,\n 2,\n})};"); }); test("Spread Element Lua 5.3", () => { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{table.unpack({0, 1, 2})};"); + expect(lua).toBe("{table.unpack({\n 0,\n 1,\n 2,\n})};"); }); test("Spread Element Lua JIT", () => { const options = { luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{unpack({0, 1, 2})};"); + expect(lua).toBe("{unpack({\n 0,\n 1,\n 2,\n})};"); }); From dccea87d40eb3ef650cb9ff4f4f57a39e79dca3e Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 4 Apr 2019 15:04:46 -0600 Subject: [PATCH 051/764] ensuring statement expressions are transpiled to valid lua (#506) * ensuring statement expressions are transpiled to valid lua * test format fix * fixed test to actually run the lua --- src/LuaTransformer.ts | 16 +++- .../compiler/configuration/options.spec.ts | 2 +- test/unit/expressions.spec.ts | 77 ++++++++++++------- test/unit/math.spec.ts | 8 +- test/unit/spreadElement.spec.ts | 6 +- 5 files changed, 74 insertions(+), 35 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9fc558448..0df3f10ed 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1817,6 +1817,14 @@ export class LuaTransformer { ); } + if (!ts.isCallLikeExpression(expression)) { + // Assign expression statements to dummy to make sure they're legal lua + return tstl.createVariableDeclarationStatement( + tstl.createAnnonymousIdentifier(), + this.transformExpression(expression) + ); + } + return tstl.createExpressionStatement(this.transformExpression(expression)); } @@ -3481,7 +3489,10 @@ export class LuaTransformer { const logCall1 = tstl.createCallExpression(log1, params); const e = tstl.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); const div = tstl.createBinaryExpression(logCall1, e, tstl.SyntaxKind.DivisionOperator); - return tstl.createParenthesizedExpression(div, node); + return ts.isExpressionStatement(node.parent) + // if used as a stand-alone statement, needs to be a call expression to be valid lua + ? this.createImmediatelyInvokedFunctionExpression([], div, node) + : tstl.createParenthesizedExpression(div, node); } // math.log(1 + x) @@ -4235,7 +4246,8 @@ export class LuaTransformer { { const body = statements ? statements.slice(0) : []; body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result])); - const iife = tstl.createFunctionExpression(tstl.createBlock(body)); + const flags = statements.length === 0 ? tstl.FunctionExpressionFlags.Inline : tstl.FunctionExpressionFlags.None; + const iife = tstl.createFunctionExpression(tstl.createBlock(body), undefined, undefined, undefined, flags); return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); } diff --git a/test/unit/compiler/configuration/options.spec.ts b/test/unit/compiler/configuration/options.spec.ts index 47bf9bedf..a26532c7c 100644 --- a/test/unit/compiler/configuration/options.spec.ts +++ b/test/unit/compiler/configuration/options.spec.ts @@ -5,7 +5,7 @@ test.each([LuaTarget.LuaJIT, "jit", "JiT"])("Options luaTarget case-insensitive const options = { luaTarget: target as LuaTarget }; const result = util.transpileString("~a", options); - expect(result).toBe("bit.bnot(a);"); + expect(result).toBe("local ____ = bit.bnot(a);"); }); test.each([LuaLibImportKind.None, "none", "NoNe"])( diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 072accf9b..f2f820328 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -8,9 +8,9 @@ test.each([ { input: "++i", lua: "i = i + 1;" }, { input: "i--", lua: "i = i - 1;" }, { input: "--i", lua: "i = i - 1;" }, - { input: "!a", lua: "not a;" }, - { input: "-a", lua: "-a;" }, - { input: "+a", lua: "a;" }, + { input: "!a", lua: "local ____ = not a;" }, + { input: "-a", lua: "local ____ = -a;" }, + { input: "+a", lua: "local ____ = a;" }, { input: "let a = delete tbl['test']", lua: "local a = (function()\n tbl.test = nil;\n return true;\nend)();", @@ -106,18 +106,18 @@ test.each([ }); test.each([ - { input: "~a", lua: "bit.bnot(a);" }, - { input: "a&b", lua: "bit.band(a, b);" }, + { input: "~a", lua: "local ____ = bit.bnot(a);" }, + { input: "a&b", lua: "local ____ = bit.band(a, b);" }, { input: "a&=b", lua: "a = bit.band(a, b);" }, - { input: "a|b", lua: "bit.bor(a, b);" }, + { input: "a|b", lua: "local ____ = bit.bor(a, b);" }, { input: "a|=b", lua: "a = bit.bor(a, b);" }, - { input: "a^b", lua: "bit.bxor(a, b);" }, + { input: "a^b", lua: "local ____ = bit.bxor(a, b);" }, { input: "a^=b", lua: "a = bit.bxor(a, b);" }, - { input: "a<>b", lua: "bit.arshift(a, b);" }, + { input: "a>>b", lua: "local ____ = bit.arshift(a, b);" }, { input: "a>>=b", lua: "a = bit.arshift(a, b);" }, - { input: "a>>>b", lua: "bit.rshift(a, b);" }, + { input: "a>>>b", lua: "local ____ = bit.rshift(a, b);" }, { input: "a>>>=b", lua: "a = bit.rshift(a, b);" }, ])("Bitop [JIT] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; @@ -125,18 +125,18 @@ test.each([ }); test.each([ - { input: "~a", lua: "bit32.bnot(a);" }, - { input: "a&b", lua: "bit32.band(a, b);" }, + { input: "~a", lua: "local ____ = bit32.bnot(a);" }, + { input: "a&b", lua: "local ____ = bit32.band(a, b);" }, { input: "a&=b", lua: "a = bit32.band(a, b);" }, - { input: "a|b", lua: "bit32.bor(a, b);" }, + { input: "a|b", lua: "local ____ = bit32.bor(a, b);" }, { input: "a|=b", lua: "a = bit32.bor(a, b);" }, - { input: "a^b", lua: "bit32.bxor(a, b);" }, + { input: "a^b", lua: "local ____ = bit32.bxor(a, b);" }, { input: "a^=b", lua: "a = bit32.bxor(a, b);" }, - { input: "a<>b", lua: "bit32.arshift(a, b);" }, + { input: "a>>b", lua: "local ____ = bit32.arshift(a, b);" }, { input: "a>>=b", lua: "a = bit32.arshift(a, b);" }, - { input: "a>>>b", lua: "bit32.rshift(a, b);" }, + { input: "a>>>b", lua: "local ____ = bit32.rshift(a, b);" }, { input: "a>>>=b", lua: "a = bit32.rshift(a, b);" }, ])("Bitop [5.2] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; @@ -144,16 +144,16 @@ test.each([ }); test.each([ - { input: "~a", lua: "~a;" }, - { input: "a&b", lua: "a & b;" }, + { input: "~a", lua: "local ____ = ~a;" }, + { input: "a&b", lua: "local ____ = a & b;" }, { input: "a&=b", lua: "a = a & b;" }, - { input: "a|b", lua: "a | b;" }, + { input: "a|b", lua: "local ____ = a | b;" }, { input: "a|=b", lua: "a = a | b;" }, - { input: "a^b", lua: "a ~ b;" }, + { input: "a^b", lua: "local ____ = a ~ b;" }, { input: "a^=b", lua: "a = a ~ b;" }, - { input: "a<>>b", lua: "a >> b;" }, + { input: "a>>>b", lua: "local ____ = a >> b;" }, { input: "a>>>=b", lua: "a = a >> b;" }, ])("Bitop [5.3] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; @@ -183,7 +183,7 @@ test.each([ { input: "1*(3+4*2)", lua: "1 * (3 + 4 * 2);" }, { input: "10-(4+5)", lua: "10 - (4 + 5);" }, ])("Binary expressions ordering parentheses (%p)", ({ input, lua }) => { - expect(util.transpileString(input)).toBe(lua); + expect(util.transpileString(input)).toBe("local ____ = " + lua); }); test.each([ @@ -208,11 +208,11 @@ test("Binary Comma Statement in For Loop", () => { }); test("Null Expression", () => { - expect(util.transpileString("null")).toBe("nil;"); + expect(util.transpileString("null")).toBe("local ____ = nil;"); }); test("Undefined Expression", () => { - expect(util.transpileString("undefined")).toBe("nil;"); + expect(util.transpileString("undefined")).toBe("local ____ = nil;"); }); test.each([ @@ -553,3 +553,28 @@ test("Unsupported object literal element error", () => { ), ); }); + +test.each([ + '"foobar"', + "17", + "true", + "{}", + "[]", + "[].length", + "foo() + foo()", + "!foo()", + "foo()", + "typeof foo", + '"bar" in bar', + "foo as Function", + "Math.log2(2)", + "Math.log10(2)", +])("Expression statements (%p)", input => { + const code = ` + function foo() { return 17; } + const bar = {}; + ${input}; + return 1; + `; + expect(util.transpileAndExecute(code)).toBe(1); +}); diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index f44429f7f..fefd4f310 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -5,11 +5,13 @@ test.each([ { inp: "Math.sin()", expected: "math.sin();" }, { inp: "Math.min()", expected: "math.min();" }, { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3);" }, - { inp: "Math.log2(3)", expected: `(math.log(3) / ${Math.LN2});` }, - { inp: "Math.log10(3)", expected: `(math.log(3) / ${Math.LN10});` }, + { inp: "Math.log2(3)", expected: `(function() return math.log(3) / ${Math.LN2}; end)();` }, + { inp: "Math.log10(3)", expected: `(function() return math.log(3) / ${Math.LN10}; end)();` }, + { inp: "const x = Math.log2(3)", expected: `local x = (math.log(3) / ${Math.LN2});` }, + { inp: "const x = Math.log10(3)", expected: `local x = (math.log(3) / ${Math.LN10});` }, { inp: "Math.log1p(3)", expected: "math.log(1 + 3);" }, { inp: "Math.round(3.3)", expected: "math.floor(3.3 + 0.5);" }, - { inp: "Math.PI", expected: "math.pi;" }, + { inp: "Math.PI", expected: "local ____ = math.pi;" }, ])("Math (%p)", ({ inp, expected }) => { const lua = util.transpileString(inp); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 42559ec2a..dcdc84c5f 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -21,17 +21,17 @@ test("Spread Element Lua 5.1", () => { test("Spread Element Lua 5.2", () => { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{table.unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})};"); }); test("Spread Element Lua 5.3", () => { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{table.unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})};"); }); test("Spread Element Lua JIT", () => { const options = { luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("{unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})};"); }); From 1cec44346c1200142558692a0ab3f2c21d33c626 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 5 Apr 2019 06:22:05 -0600 Subject: [PATCH 052/764] String concat fix (#508) * wrapping values in concat ops in tostring, when needed * test format fix * removed accidental import and changed strings in test --- src/LuaTransformer.ts | 25 ++++++++++-- .../__snapshots__/transformation.spec.ts.snap | 2 +- test/unit/string.spec.ts | 39 ++++++++++++++++--- 3 files changed, 56 insertions(+), 10 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 0df3f10ed..86f680583 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2396,6 +2396,10 @@ export class LuaTransformer { return this.transformBinaryBitOperation(tsOriginal, left, right, operator); default: const luaOperator = this.transformBinaryOperator(operator, tsOriginal); + if (luaOperator === tstl.SyntaxKind.ConcatOperator) { + left = this.wrapInToStringForConcat(left); + right = this.wrapInToStringForConcat(right); + } return tstl.createBinaryExpression(left, right, luaOperator, tsOriginal); } } @@ -4091,8 +4095,7 @@ export class LuaTransformer { } expression.templateSpans.forEach(span => { - const expr = this.transformExpression(span.expression); - parts.push(tstl.createCallExpression(tstl.createIdentifier("tostring"), [expr])); + parts.push(this.wrapInToStringForConcat(this.transformExpression(span.expression))); const text = tsHelper.escapeString(span.literal.text); if (text.length > 0) { @@ -4487,7 +4490,13 @@ export class LuaTransformer { private wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { const returnStatement = tstl.createReturnStatement([expression]); - return tstl.createFunctionExpression(tstl.createBlock([returnStatement])); + return tstl.createFunctionExpression( + tstl.createBlock([returnStatement]), + undefined, + undefined, + undefined, + tstl.FunctionExpressionFlags.Inline + ); } private wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { @@ -4495,6 +4504,16 @@ export class LuaTransformer { return tstl.createParenthesizedExpression(tstl.createTableExpression(fields)); } + private wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { + if (tstl.isStringLiteral(expression) + || tstl.isNumericLiteral(expression) + || (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator)) + { + return expression; + } + return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); + } + private expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { if (tstl.isBinaryExpression(expression)) { expression = tstl.createParenthesizedExpression(expression); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index b0baaa3dd..2a8c00c78 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -14,7 +14,7 @@ local backQuoteInTemplateString = \\"\` \` \`\\"; local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\"; local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; -local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. tostring(\\"Level 1: \\\\n\\\\t\\\\t \\" .. tostring(\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. tostring(\\"Last level \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\";" +local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\";" `; exports[`Transformation (classExtension1) 1`] = ` diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 2b7cd4362..dfb494c62 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -34,14 +34,41 @@ test.each([ { a: "test", b: "hello", c: "bye" }, { a: "test", b: 42, c: "bye" }, { a: "test", b: 42, c: 12 }, + { a: "test", b: 42, c: true }, + { a: false, b: 42, c: 12 }, ])("Template Strings (%p)", ({ a, b, c }) => { - const a1 = typeof a === "string" ? "'" + a + "'" : a; - const b1 = typeof b === "string" ? "'" + b + "'" : b; - const c1 = typeof c === "string" ? "'" + c + "'" : c; + const a1 = typeof a === "string" ? `'${a}'` : a; + const b1 = typeof b === "string" ? `'${b}'` : b; + const c1 = typeof c === "string" ? `'${c}'` : c; - const result = util.transpileAndExecute( - "let a = " + a1 + "; let b = " + b1 + "; let c = " + c1 + "; return `${a} ${b} test ${c}`;", - ); + const result = util.transpileAndExecute(` + let a = ${a1}; + let b = ${b1}; + let c = ${c1}; + return \`${a} ${b} test ${c}\`; + `); + + expect(result).toBe(`${a} ${b} test ${c}`); +}); + +test.each([ + { a: 12, b: 23, c: 43 }, + { a: "test", b: "hello", c: "bye" }, + { a: "test", b: 42, c: "bye" }, + { a: "test", b: 42, c: 12 }, + { a: "test", b: 42, c: true }, + { a: false, b: 42, c: 12 }, +])("String Concat Operator (%p)", ({ a, b, c }) => { + const a1 = typeof a === "string" ? `'${a}'` : a; + const b1 = typeof b === "string" ? `'${b}'` : b; + const c1 = typeof c === "string" ? `'${c}'` : c; + + const result = util.transpileAndExecute(` + let a = ${a1}; + let b = ${b1}; + let c = ${c1}; + return a + " " + b + " test " + c; + `); expect(result).toBe(`${a} ${b} test ${c}`); }); From 683e43a4c4acc5357b0fcfe7711432c4ebf27cec Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 5 Apr 2019 06:38:44 -0600 Subject: [PATCH 053/764] removing semi-colons, except where needed for disambiguation (#505) * removing semi-colons, except where needed for disambiguation * fixed formatting in new test * added semicolons to manually printed statements which could be followed by parenthesis --- src/LuaPrinter.ts | 94 +++- .../__snapshots__/transformation.spec.ts.snap | 522 +++++++++--------- test/unit/assignmentDestructuring.spec.ts | 6 +- test/unit/assignments/assignments.spec.ts | 22 +- .../compiler/configuration/options.spec.ts | 4 +- test/unit/console.spec.ts | 30 +- test/unit/enum.spec.ts | 8 +- test/unit/error.spec.ts | 2 +- test/unit/expressions.spec.ts | 112 ++-- test/unit/json.spec.ts | 2 +- test/unit/math.spec.ts | 22 +- test/unit/objectLiteral.spec.ts | 12 +- test/unit/semicolons.spec.ts | 17 + test/unit/spreadElement.spec.ts | 8 +- 14 files changed, 457 insertions(+), 404 deletions(-) create mode 100644 test/unit/semicolons.spec.ts diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 5538cca89..f4a68dcdc 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -172,10 +172,48 @@ export class LuaPrinter { } private printBlock(block: tstl.Block): SourceNode { - return this.createSourceNode( - block, - this.ignoreDeadStatements(block.statements).map(s => this.printStatement(s)) + return this.createSourceNode(block, this.printStatementArray(block.statements)); + } + + private statementMayRequireSemiColon(statement: tstl.Statement): boolean { + // Types of statements that could create ambiguous syntax if followed by parenthesis + return tstl.isVariableDeclarationStatement(statement) + || tstl.isAssignmentStatement(statement) + || tstl.isExpressionStatement(statement); + } + + private nodeStartsWithParenthesis(sourceNode: SourceNode): boolean { + let result: boolean | undefined; + sourceNode.walk(chunk => { + if (result === undefined) { + chunk = chunk.trimLeft(); // Ignore leading whitespace + + if (chunk.length > 0) { + result = chunk.startsWith("("); + } + } + }); + return result || false; + } + + private printStatementArray(statements: tstl.Statement[]): SourceChunk[] { + const statementNodes: SourceNode[] = []; + statements = this.removeDeadAndEmptyStatements(statements); + statements.forEach( + (s, i) => { + const node = this.printStatement(s); + + if (i > 0 + && this.statementMayRequireSemiColon(statements[i - 1]) + && this.nodeStartsWithParenthesis(node)) + { + statementNodes[i - 1].add(";"); + } + + statementNodes.push(node); + } ); + return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } private printStatement(statement: tstl.Statement): SourceNode { @@ -214,13 +252,11 @@ export class LuaPrinter { private printDoStatement(statement: tstl.DoStatement): SourceNode { const chunks: SourceChunk[] = []; - if (statement.statements && statement.statements.length > 0) { - chunks.push(this.indent("do\n")); - this.pushIndent(); - chunks.push(...this.ignoreDeadStatements(statement.statements).map(s => this.printStatement(s))); - this.popIndent(); - chunks.push(this.indent("end\n")); - } + chunks.push(this.indent("do\n")); + this.pushIndent(); + chunks.push(...this.printStatementArray(statement.statements)); + this.popIndent(); + chunks.push(this.indent("end")); return this.concatNodes(...chunks); } @@ -233,7 +269,6 @@ export class LuaPrinter { if (tstl.isFunctionDefinition(statement)) { // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion chunks.push(this.printFunctionDefinition(statement)); - chunks.push("\n"); } else { chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); @@ -242,7 +277,6 @@ export class LuaPrinter { chunks.push(" = "); chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); } - chunks.push(";\n"); } return this.concatNodes(...chunks); @@ -260,7 +294,6 @@ export class LuaPrinter { const name = this.printExpression(statement.left[0]); if (tsHelper.isValidLuaFunctionDeclarationName(name.toString())) { chunks.push(this.printFunctionDefinition(statement)); - chunks.push("\n"); return this.createSourceNode(statement, chunks); } } @@ -268,7 +301,6 @@ export class LuaPrinter { chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); chunks.push(" = "); chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); - chunks.push(";\n"); return this.createSourceNode(statement, chunks); } @@ -292,10 +324,10 @@ export class LuaPrinter { this.pushIndent(); chunks.push(this.printBlock(statement.elseBlock)); this.popIndent(); - chunks.push(this.indent("end\n")); + chunks.push(this.indent("end")); } } else { - chunks.push(this.indent("end\n")); + chunks.push(this.indent("end")); } return this.concatNodes(...chunks); @@ -310,7 +342,7 @@ export class LuaPrinter { chunks.push(this.printBlock(statement.body)); this.popIndent(); - chunks.push(this.indent("end\n")); + chunks.push(this.indent("end")); return this.concatNodes(...chunks); } @@ -324,7 +356,7 @@ export class LuaPrinter { chunks.push(this.printBlock(statement.body)); this.popIndent(); - chunks.push(this.indent("until "), this.printExpression(statement.condtion), ";\n"); + chunks.push(this.indent("until "), this.printExpression(statement.condtion)); return this.concatNodes(...chunks); } @@ -347,7 +379,7 @@ export class LuaPrinter { chunks.push(this.printBlock(statement.body)); this.popIndent(); - chunks.push(this.indent("end\n")); + chunks.push(this.indent("end")); return this.concatNodes(...chunks); } @@ -363,38 +395,37 @@ export class LuaPrinter { this.pushIndent(); chunks.push(this.printBlock(statement.body)); this.popIndent(); - chunks.push(this.indent("end\n")); + chunks.push(this.indent("end")); return this.createSourceNode(statement, chunks); } private printGotoStatement(statement: tstl.GotoStatement): SourceNode { - return this.createSourceNode(statement, [this.indent("goto "), statement.label, ";\n"]); + return this.createSourceNode(statement, [this.indent("goto "), statement.label]); } private printLabelStatement(statement: tstl.LabelStatement): SourceNode { - return this.createSourceNode(statement, [this.indent("::"), statement.name, "::\n"]); + return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]); } private printReturnStatement(statement: tstl.ReturnStatement): SourceNode { if (!statement.expressions || statement.expressions.length === 0) { - return this.createSourceNode(statement, this.indent("return;\n")); + return this.createSourceNode(statement, this.indent("return")); } const chunks: SourceChunk[] = []; chunks.push(...this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e)))); - chunks.push(";\n"); return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } private printBreakStatement(statement: tstl.BreakStatement): SourceNode { - return this.createSourceNode(statement, this.indent("break;\n")); + return this.createSourceNode(statement, this.indent("break")); } private printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { - return this.concatNodes(this.indent(), this.printExpression(statement.expression), ";\n"); + return this.concatNodes(this.indent(), this.printExpression(statement.expression)); } // Expressions @@ -485,7 +516,6 @@ export class LuaPrinter { const returnNode: SourceChunk[] = [ "return ", ...this.joinChunks(", ", returnStatement.expressions.map(e => this.printExpression(e))), - ";", ]; chunks.push(this.createSourceNode(returnStatement, returnNode)); chunks.push(" end"); @@ -621,10 +651,16 @@ export class LuaPrinter { return LuaPrinter.operatorMap[kind]; } - private ignoreDeadStatements(statements: tstl.Statement[]): tstl.Statement[] { + private isEmptyStatement(statement: tstl.Statement): boolean { + return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + } + + private removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { const aliveStatements = []; for (const statement of statements) { - aliveStatements.push(statement); + if (!this.isEmptyStatement(statement)) { + aliveStatements.push(statement); + } if (tstl.isReturnStatement(statement)) { break; } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 2a8c00c78..346836118 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,20 +1,20 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Transformation (callNamespace) 1`] = `"Namespace:myFunction();"`; +exports[`Transformation (callNamespace) 1`] = `"Namespace:myFunction()"`; exports[`Transformation (characterEscapeSequence) 1`] = ` -"local quoteInDoubleQuotes = \\"\\\\' \\\\' \\\\'\\"; -local quoteInTemplateString = \\"\\\\' \\\\' \\\\'\\"; -local doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\"; -local doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\"; -local doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\"; -local backQuoteInQuotes = \\"\` \` \`\\"; -local backQuoteInDoubleQuotes = \\"\` \` \`\\"; -local backQuoteInTemplateString = \\"\` \` \`\\"; -local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; -local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\"; -local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\"; -local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\";" +"local quoteInDoubleQuotes = \\"\\\\' \\\\' \\\\'\\" +local quoteInTemplateString = \\"\\\\' \\\\' \\\\'\\" +local doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" +local doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" +local doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" +local backQuoteInQuotes = \\"\` \` \`\\" +local backQuoteInDoubleQuotes = \\"\` \` \`\\" +local backQuoteInTemplateString = \\"\` \` \`\\" +local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\" +local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\" +local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\" +local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\"" `; exports[`Transformation (classExtension1) 1`] = ` @@ -35,22 +35,22 @@ end" `; exports[`Transformation (classExtension4) 1`] = ` -"MyClass.test = \\"test\\"; -MyClass.testP = \\"testP\\"; +"MyClass.test = \\"test\\" +MyClass.testP = \\"testP\\" function MyClass.myFunction(self) end" `; exports[`Transformation (classPureAbstract) 1`] = ` -"ClassB = ClassB or {}; -ClassB.__index = ClassB; -ClassB.prototype = ClassB.prototype or {}; -ClassB.prototype.__index = ClassB.prototype; -ClassB.prototype.constructor = ClassB; +"ClassB = ClassB or {} +ClassB.__index = ClassB +ClassB.prototype = ClassB.prototype or {} +ClassB.prototype.__index = ClassB.prototype +ClassB.prototype.constructor = ClassB function ClassB.new(...) - local self = setmetatable({}, ClassB.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, ClassB.prototype) + self:____constructor(...) + return self end function ClassB.prototype.____constructor(self) end" @@ -58,170 +58,170 @@ end" exports[`Transformation (continue) 1`] = ` "do - local i = 0; + local i = 0 while i < 10 do do if i < 5 then - goto __continue1; + goto __continue1 end end ::__continue1:: - i = i + 1; + i = i + 1 end end" `; exports[`Transformation (continueConcurrent) 1`] = ` "do - local i = 0; + local i = 0 while i < 10 do do if i < 5 then - goto __continue1; + goto __continue1 end if i == 7 then - goto __continue1; + goto __continue1 end end ::__continue1:: - i = i + 1; + i = i + 1 end end" `; exports[`Transformation (continueNested) 1`] = ` "do - local i = 0; + local i = 0 while i < 5 do do if i % 2 == 0 then - goto __continue1; + goto __continue1 end do - local j = 0; + local j = 0 while j < 2 do do if j == 1 then - goto __continue3; + goto __continue3 end end ::__continue3:: - j = j + 1; + j = j + 1 end end end ::__continue1:: - i = i + 1; + i = i + 1 end end" `; exports[`Transformation (continueNestedConcurrent) 1`] = ` "do - local i = 0; + local i = 0 while i < 5 do do if i % 2 == 0 then - goto __continue1; + goto __continue1 end do - local j = 0; + local j = 0 while j < 2 do do if j == 1 then - goto __continue3; + goto __continue3 end end ::__continue3:: - j = j + 1; + j = j + 1 end end if i == 4 then - goto __continue1; + goto __continue1 end end ::__continue1:: - i = i + 1; + i = i + 1 end end" `; exports[`Transformation (do) 1`] = ` -"local e = 10; +"local e = 10 repeat - e = e - 1; -until not (e > 0);" + e = e - 1 +until not (e > 0)" `; exports[`Transformation (enum) 1`] = ` -"TestEnum = {}; -TestEnum.val1 = 0; -TestEnum[0] = \\"val1\\"; -TestEnum.val2 = 2; -TestEnum[2] = \\"val2\\"; -TestEnum.val3 = 3; -TestEnum[3] = \\"val3\\";" +"TestEnum = {} +TestEnum.val1 = 0 +TestEnum[0] = \\"val1\\" +TestEnum.val2 = 2 +TestEnum[2] = \\"val2\\" +TestEnum.val3 = 3 +TestEnum[3] = \\"val3\\"" `; exports[`Transformation (enumHeterogeneous) 1`] = ` -"TestEnum = {}; -TestEnum.val1 = 0; -TestEnum[0] = \\"val1\\"; -TestEnum.val2 = 3; -TestEnum[3] = \\"val2\\"; -TestEnum.val3 = \\"baz\\"; -TestEnum.baz = \\"val3\\";" +"TestEnum = {} +TestEnum.val1 = 0 +TestEnum[0] = \\"val1\\" +TestEnum.val2 = 3 +TestEnum[3] = \\"val2\\" +TestEnum.val3 = \\"baz\\" +TestEnum.baz = \\"val3\\"" `; exports[`Transformation (enumMembersOnly) 1`] = ` -"val1 = 0; -val2 = 2; -val3 = 3; -val4 = \\"bye\\"; -local a = val1;" +"val1 = 0 +val2 = 2 +val3 = 3 +val4 = \\"bye\\" +local a = val1" `; exports[`Transformation (enumString) 1`] = ` -"TestEnum = {}; -TestEnum.val1 = \\"foo\\"; -TestEnum.foo = \\"val1\\"; -TestEnum.val2 = \\"bar\\"; -TestEnum.bar = \\"val2\\"; -TestEnum.val3 = \\"baz\\"; -TestEnum.baz = \\"val3\\";" +"TestEnum = {} +TestEnum.val1 = \\"foo\\" +TestEnum.foo = \\"val1\\" +TestEnum.val2 = \\"bar\\" +TestEnum.bar = \\"val2\\" +TestEnum.val3 = \\"baz\\" +TestEnum.baz = \\"val3\\"" `; exports[`Transformation (exportStatement) 1`] = ` -"local exports = exports or {}; -local xyz = 4; -exports.xyz = xyz; -exports.uwv = xyz; +"local exports = exports or {} +local xyz = 4 +exports.xyz = xyz +exports.uwv = xyz do - local __TSTL_export = require(\\"xyz\\"); + local __TSTL_export = require(\\"xyz\\") for ____exportKey, ____exportValue in pairs(__TSTL_export) do - exports[____exportKey] = ____exportValue; + exports[____exportKey] = ____exportValue end end do - local __TSTL_xyz = require(\\"xyz\\"); - local abc = __TSTL_xyz.abc; - local def = __TSTL_xyz.def; - exports.abc = abc; - exports.def = def; + local __TSTL_xyz = require(\\"xyz\\") + local abc = __TSTL_xyz.abc + local def = __TSTL_xyz.def + exports.abc = abc + exports.def = def end do - local __TSTL_xyz = require(\\"xyz\\"); - local def = __TSTL_xyz.abc; - exports.def = def; + local __TSTL_xyz = require(\\"xyz\\") + local def = __TSTL_xyz.abc + exports.def = def end -return exports;" +return exports" `; exports[`Transformation (for) 1`] = ` "do - local i = 1; + local i = 1 while i <= 100 do - i = i + 1; + i = i + 1 end end" `; @@ -248,117 +248,117 @@ exports[`Transformation (forOf) 1`] = ` 8, 9, 10, -}; +} for ____TS_index = 1, #____TS_array do - local i = ____TS_array[____TS_index]; + local i = ____TS_array[____TS_index] end" `; exports[`Transformation (functionRestArguments) 1`] = ` "function varargsFunction(self, a, ...) - local b = ({...}); + local b = ({...}) end" `; exports[`Transformation (getSetAccessors) 1`] = ` "require(\\"lualib_bundle\\"); -MyClass = MyClass or {}; -MyClass.__index = MyClass; -MyClass.prototype = MyClass.prototype or {}; -MyClass.prototype.____getters = {}; -MyClass.prototype.__index = __TS__Index(MyClass.prototype); -MyClass.prototype.____setters = {}; -MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype); -MyClass.prototype.constructor = MyClass; +MyClass = MyClass or {} +MyClass.__index = MyClass +MyClass.prototype = MyClass.prototype or {} +MyClass.prototype.____getters = {} +MyClass.prototype.__index = __TS__Index(MyClass.prototype) +MyClass.prototype.____setters = {} +MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype) +MyClass.prototype.constructor = MyClass function MyClass.new(...) - local self = setmetatable({}, MyClass.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, MyClass.prototype) + self:____constructor(...) + return self end function MyClass.prototype.____constructor(self) end function MyClass.prototype.____getters.field(self) - return self._field + 4; + return self._field + 4 end function MyClass.prototype.____setters.field(self, v) - self._field = v * 2; + self._field = v * 2 end -local instance = MyClass.new(); -instance.field = 4; -local b = instance.field; -local c = (4 + instance.field) * 3;" +local instance = MyClass.new() +instance.field = 4 +local b = instance.field +local c = (4 + instance.field) * 3" `; exports[`Transformation (interfaceIndex) 1`] = ` -"local a = {}; -a.abc = \\"def\\";" +"local a = {} +a.abc = \\"def\\"" `; exports[`Transformation (methodRestArguments) 1`] = ` -"MyClass = MyClass or {}; -MyClass.__index = MyClass; -MyClass.prototype = MyClass.prototype or {}; -MyClass.prototype.__index = MyClass.prototype; -MyClass.prototype.constructor = MyClass; +"MyClass = MyClass or {} +MyClass.__index = MyClass +MyClass.prototype = MyClass.prototype or {} +MyClass.prototype.__index = MyClass.prototype +MyClass.prototype.constructor = MyClass function MyClass.new(...) - local self = setmetatable({}, MyClass.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, MyClass.prototype) + self:____constructor(...) + return self end function MyClass.prototype.____constructor(self) end function MyClass.prototype.varargsFunction(self, a, ...) - local b = ({...}); + local b = ({...}) end" `; exports[`Transformation (modulesChangedVariableExport) 1`] = ` -"local exports = exports or {}; -exports.foo = 1; -return exports;" +"local exports = exports or {} +exports.foo = 1 +return exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"local exports = exports or {}; -exports.TestClass = exports.TestClass or {}; -exports.TestClass.__index = exports.TestClass; -exports.TestClass.prototype = exports.TestClass.prototype or {}; -exports.TestClass.prototype.__index = exports.TestClass.prototype; -exports.TestClass.prototype.constructor = exports.TestClass; +"local exports = exports or {} +exports.TestClass = exports.TestClass or {} +exports.TestClass.__index = exports.TestClass +exports.TestClass.prototype = exports.TestClass.prototype or {} +exports.TestClass.prototype.__index = exports.TestClass.prototype +exports.TestClass.prototype.constructor = exports.TestClass function exports.TestClass.new(...) - local self = setmetatable({}, exports.TestClass.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, exports.TestClass.prototype) + self:____constructor(...) + return self end function exports.TestClass.prototype.____constructor(self) end -return exports;" +return exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"local exports = exports or {}; -exports.TestClass = exports.TestClass or {}; -exports.TestClass.__index = exports.TestClass; -exports.TestClass.prototype = exports.TestClass.prototype or {}; -exports.TestClass.prototype.__index = exports.TestClass.prototype; -exports.TestClass.prototype.constructor = exports.TestClass; +"local exports = exports or {} +exports.TestClass = exports.TestClass or {} +exports.TestClass.__index = exports.TestClass +exports.TestClass.prototype = exports.TestClass.prototype or {} +exports.TestClass.prototype.__index = exports.TestClass.prototype +exports.TestClass.prototype.constructor = exports.TestClass function exports.TestClass.new(...) - local self = setmetatable({}, exports.TestClass.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, exports.TestClass.prototype) + self:____constructor(...) + return self end function exports.TestClass.prototype.____constructor(self) end function exports.TestClass.prototype.memberFunc(self) end -return exports;" +return exports" `; exports[`Transformation (modulesFunctionExport) 1`] = ` -"local exports = exports or {}; +"local exports = exports or {} function exports.publicFunc(self) end -return exports;" +return exports" `; exports[`Transformation (modulesFunctionNoExport) 1`] = ` @@ -366,116 +366,116 @@ exports[`Transformation (modulesFunctionNoExport) 1`] = ` end" `; -exports[`Transformation (modulesImportAll) 1`] = `"local Test = require(\\"test\\");"`; +exports[`Transformation (modulesImportAll) 1`] = `"local Test = require(\\"test\\")"`; exports[`Transformation (modulesImportNamed) 1`] = ` -"local __TSTL_test = require(\\"test\\"); -local TestClass = __TSTL_test.TestClass;" +"local __TSTL_test = require(\\"test\\") +local TestClass = __TSTL_test.TestClass" `; exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` -"local __TSTL_kebab_module = require(\\"kebab-module\\"); -local TestClass = __TSTL_kebab_module.TestClass; -local __TSTL_dollar_module = require(\\"dollar$module\\"); -local TestClass = __TSTL_dollar_module.TestClass; -local __TSTL_singlequote_module = require(\\"singlequote'module\\"); -local TestClass = __TSTL_singlequote_module.TestClass; -local __TSTL_hash_module = require(\\"hash#module\\"); -local TestClass = __TSTL_hash_module.TestClass; -local __TSTL_space_module = require(\\"space module\\"); -local TestClass = __TSTL_space_module.TestClass;" +"local __TSTL_kebab_module = require(\\"kebab-module\\") +local TestClass = __TSTL_kebab_module.TestClass +local __TSTL_dollar_module = require(\\"dollar$module\\") +local TestClass = __TSTL_dollar_module.TestClass +local __TSTL_singlequote_module = require(\\"singlequote'module\\") +local TestClass = __TSTL_singlequote_module.TestClass +local __TSTL_hash_module = require(\\"hash#module\\") +local TestClass = __TSTL_hash_module.TestClass +local __TSTL_space_module = require(\\"space module\\") +local TestClass = __TSTL_space_module.TestClass" `; exports[`Transformation (modulesImportRenamed) 1`] = ` -"local __TSTL_test = require(\\"test\\"); -local RenamedClass = __TSTL_test.TestClass;" +"local __TSTL_test = require(\\"test\\") +local RenamedClass = __TSTL_test.TestClass" `; exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` -"local __TSTL_kebab_module = require(\\"kebab-module\\"); -local RenamedClass = __TSTL_kebab_module.TestClass; -local __TSTL_dollar_module = require(\\"dollar$module\\"); -local RenamedClass = __TSTL_dollar_module.TestClass; -local __TSTL_singlequote_module = require(\\"singlequote'module\\"); -local RenamedClass = __TSTL_singlequote_module.TestClass; -local __TSTL_hash_module = require(\\"hash#module\\"); -local RenamedClass = __TSTL_hash_module.TestClass; -local __TSTL_space_module = require(\\"space module\\"); -local RenamedClass = __TSTL_space_module.TestClass;" +"local __TSTL_kebab_module = require(\\"kebab-module\\") +local RenamedClass = __TSTL_kebab_module.TestClass +local __TSTL_dollar_module = require(\\"dollar$module\\") +local RenamedClass = __TSTL_dollar_module.TestClass +local __TSTL_singlequote_module = require(\\"singlequote'module\\") +local RenamedClass = __TSTL_singlequote_module.TestClass +local __TSTL_hash_module = require(\\"hash#module\\") +local RenamedClass = __TSTL_hash_module.TestClass +local __TSTL_space_module = require(\\"space module\\") +local RenamedClass = __TSTL_space_module.TestClass" `; -exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\");"`; +exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\")"`; exports[`Transformation (modulesNamespaceExport) 1`] = ` -"local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; -return exports;" +"local exports = exports or {} +exports.TestSpace = exports.TestSpace or {} +local TestSpace = exports.TestSpace +return exports" `; exports[`Transformation (modulesNamespaceExportEnum) 1`] = ` -"local exports = exports or {}; -exports.test = exports.test or {}; -local test = exports.test; +"local exports = exports or {} +exports.test = exports.test or {} +local test = exports.test do - test.TestEnum = {}; - test.TestEnum.foo = \\"foo\\"; - test.TestEnum.foo = \\"foo\\"; - test.TestEnum.bar = \\"bar\\"; - test.TestEnum.bar = \\"bar\\"; + test.TestEnum = {} + test.TestEnum.foo = \\"foo\\" + test.TestEnum.foo = \\"foo\\" + test.TestEnum.bar = \\"bar\\" + test.TestEnum.bar = \\"bar\\" end -return exports;" +return exports" `; exports[`Transformation (modulesNamespaceNestedWithMemberExport) 1`] = ` -"local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; +"local exports = exports or {} +exports.TestSpace = exports.TestSpace or {} +local TestSpace = exports.TestSpace do - TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {}; - local TestNestedSpace = TestSpace.TestNestedSpace; + TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {} + local TestNestedSpace = TestSpace.TestNestedSpace do function TestNestedSpace.innerFunc(self) end end end -return exports;" +return exports" `; -exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {};"`; +exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {}"`; exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` -"local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; +"local exports = exports or {} +exports.TestSpace = exports.TestSpace or {} +local TestSpace = exports.TestSpace do function TestSpace.innerFunc(self) end end -return exports;" +return exports" `; exports[`Transformation (modulesNamespaceWithMemberNoExport) 1`] = ` -"local exports = exports or {}; -exports.TestSpace = exports.TestSpace or {}; -local TestSpace = exports.TestSpace; +"local exports = exports or {} +exports.TestSpace = exports.TestSpace or {} +local TestSpace = exports.TestSpace do local function innerFunc(self) end end -return exports;" +return exports" `; exports[`Transformation (modulesVariableExport) 1`] = ` -"local exports = exports or {}; -exports.foo = \\"bar\\"; -return exports;" +"local exports = exports or {} +exports.foo = \\"bar\\" +return exports" `; -exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\";"`; +exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\""`; exports[`Transformation (namespace) 1`] = ` -"myNamespace = myNamespace or {}; +"myNamespace = myNamespace or {} do local function nsMember(self) end @@ -483,48 +483,48 @@ end" `; exports[`Transformation (namespaceMerge) 1`] = ` -"MergedClass = MergedClass or {}; -MergedClass.__index = MergedClass; -MergedClass.prototype = MergedClass.prototype or {}; -MergedClass.prototype.__index = MergedClass.prototype; -MergedClass.prototype.constructor = MergedClass; +"MergedClass = MergedClass or {} +MergedClass.__index = MergedClass +MergedClass.prototype = MergedClass.prototype or {} +MergedClass.prototype.__index = MergedClass.prototype +MergedClass.prototype.constructor = MergedClass function MergedClass.new(...) - local self = setmetatable({}, MergedClass.prototype); - self:____constructor(...); - return self; + local self = setmetatable({}, MergedClass.prototype) + self:____constructor(...) + return self end function MergedClass.prototype.____constructor(self) self.propertyFunc = function() - end; + end end function MergedClass.staticMethodA(self) end function MergedClass.staticMethodB(self) - self:staticMethodA(); + self:staticMethodA() end function MergedClass.prototype.methodA(self) end function MergedClass.prototype.methodB(self) - self:methodA(); - self:propertyFunc(); + self:methodA() + self:propertyFunc() end -MergedClass = MergedClass or {}; +MergedClass = MergedClass or {} do function MergedClass.namespaceFunc(self) end end -local mergedClass = MergedClass.new(); -mergedClass:methodB(); -mergedClass:propertyFunc(); -MergedClass:staticMethodB(); -MergedClass:namespaceFunc();" +local mergedClass = MergedClass.new() +mergedClass:methodB() +mergedClass:propertyFunc() +MergedClass:staticMethodB() +MergedClass:namespaceFunc()" `; exports[`Transformation (namespaceNested) 1`] = ` -"myNamespace = myNamespace or {}; +"myNamespace = myNamespace or {} do - myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {}; - local myNestedNamespace = myNamespace.myNestedNamespace; + myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {} + local myNestedNamespace = myNamespace.myNestedNamespace do local function nsMember(self) end @@ -539,22 +539,22 @@ end" exports[`Transformation (returnDefault) 1`] = ` "function myFunc(self) - return; + return end" `; exports[`Transformation (shorthandPropertyAssignment) 1`] = ` -"local f; -f = function(____, x) return ({x = x}); end;" +"local f +f = function(____, x) return ({x = x}) end" `; exports[`Transformation (tryCatch) 1`] = ` "do local ____TS_try, er = pcall(function() - local a = 42; - end); + local a = 42 + end) if not (____TS_try) then - local b = \\"fail\\"; + local b = \\"fail\\" end end" `; @@ -562,13 +562,13 @@ end" exports[`Transformation (tryCatchFinally) 1`] = ` "do local ____TS_try, er = pcall(function() - local a = 42; - end); + local a = 42 + end) if not (____TS_try) then - local b = \\"fail\\"; + local b = \\"fail\\" end do - local c = \\"finally\\"; + local c = \\"finally\\" end end" `; @@ -576,56 +576,56 @@ end" exports[`Transformation (tryFinally) 1`] = ` "do pcall(function() - local a = 42; - end); + local a = 42 + end) do - local b = \\"finally\\"; + local b = \\"finally\\" end end" `; exports[`Transformation (tupleReturn) 1`] = ` "function tupleReturn(self) - return 0, \\"foobar\\"; -end -tupleReturn(_G); -noTupleReturn(_G); -local a, b = tupleReturn(_G); -local c, d = table.unpack(noTupleReturn(_G)); -a, b = tupleReturn(_G); -c, d = table.unpack(noTupleReturn(_G)); -local e = ({tupleReturn(_G)}); -local f = noTupleReturn(_G); -e = ({tupleReturn(_G)}); -f = noTupleReturn(_G); -foo(_G, ({tupleReturn(_G)})); -foo(_G, noTupleReturn(_G)); + return 0, \\"foobar\\" +end +tupleReturn(_G) +noTupleReturn(_G) +local a, b = tupleReturn(_G) +local c, d = table.unpack(noTupleReturn(_G)) +a, b = tupleReturn(_G) +c, d = table.unpack(noTupleReturn(_G)) +local e = ({tupleReturn(_G)}) +local f = noTupleReturn(_G) +e = ({tupleReturn(_G)}) +f = noTupleReturn(_G) +foo(_G, ({tupleReturn(_G)})) +foo(_G, noTupleReturn(_G)) function tupleReturnFromVar(self) local r = { 1, \\"baz\\", - }; - return table.unpack(r); + } + return table.unpack(r) end function tupleReturnForward(self) - return tupleReturn(_G); + return tupleReturn(_G) end function tupleNoForward(self) - return ({tupleReturn(_G)}); + return ({tupleReturn(_G)}) end function tupleReturnUnpack(self) - return table.unpack(tupleNoForward(_G)); + return table.unpack(tupleNoForward(_G)) end" `; exports[`Transformation (typeAssert) 1`] = ` -"local test1 = 10; -local test2 = 10;" +"local test1 = 10 +local test2 = 10" `; exports[`Transformation (while) 1`] = ` -"local d = 10; +"local d = 10 while d > 0 do - d = d - 1; + d = d - 1 end" `; diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 41fb9899b..34ccacee5 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -10,7 +10,7 @@ test("Assignment destructuring [5.1]", () => { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = unpack(myFunc());`); + expect(lua).toBe(`local a, b = unpack(myFunc())`); }); test("Assignment destructuring [5.2]", () => { @@ -18,7 +18,7 @@ test("Assignment destructuring [5.2]", () => { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = table.unpack(myFunc());`); + expect(lua).toBe(`local a, b = table.unpack(myFunc())`); }); test("Assignment destructuring [JIT]", () => { @@ -26,7 +26,7 @@ test("Assignment destructuring [JIT]", () => { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = unpack(myFunc());`); + expect(lua).toBe(`local a, b = unpack(myFunc())`); }); test.each([ diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index 54f925d41..4e47bd849 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -10,8 +10,8 @@ test.each([ { inp: "false", out: "false" }, { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Const assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`const myvar = ${inp};`); - expect(lua).toBe(`local myvar = ${out};`); + const lua = util.transpileString(`const myvar = ${inp}`); + expect(lua).toBe(`local myvar = ${out}`); }); test.each([ @@ -22,8 +22,8 @@ test.each([ { inp: "false", out: "false" }, { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Let assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`let myvar = ${inp};`); - expect(lua).toBe(`local myvar = ${out};`); + const lua = util.transpileString(`let myvar = ${inp}`); + expect(lua).toBe(`local myvar = ${out}`); }); test.each([ @@ -34,8 +34,8 @@ test.each([ { inp: "false", out: "false" }, { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, ])("Var assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`var myvar = ${inp};`); - expect(lua).toBe(`myvar = ${out};`); + const lua = util.transpileString(`var myvar = ${inp}`); + expect(lua).toBe(`myvar = ${out}`); }); test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = undefined;"])( @@ -84,7 +84,7 @@ test("TupleReturn assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local a, b = abc();"); + expect(lua).toBe("local a, b = abc()"); }); test("TupleReturn Single assignment", () => { @@ -96,7 +96,7 @@ test("TupleReturn Single assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local a = ({abc()});\na = ({abc()});"); + expect(lua).toBe("local a = ({abc()})\na = ({abc()})"); }); test("TupleReturn interface assignment", () => { @@ -109,7 +109,7 @@ test("TupleReturn interface assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local a, b = jkl:abc();"); + expect(lua).toBe("local a, b = jkl:abc()"); }); test("TupleReturn namespace assignment", () => { @@ -122,7 +122,7 @@ test("TupleReturn namespace assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local a, b = def.abc();"); + expect(lua).toBe("local a, b = def.abc()"); }); test("TupleReturn method assignment", () => { @@ -135,7 +135,7 @@ test("TupleReturn method assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local jkl = def.new();\nlocal a, b = jkl:abc();"); + expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); }); test("TupleReturn functional", () => { diff --git a/test/unit/compiler/configuration/options.spec.ts b/test/unit/compiler/configuration/options.spec.ts index a26532c7c..31b9a6fe1 100644 --- a/test/unit/compiler/configuration/options.spec.ts +++ b/test/unit/compiler/configuration/options.spec.ts @@ -5,7 +5,7 @@ test.each([LuaTarget.LuaJIT, "jit", "JiT"])("Options luaTarget case-insensitive const options = { luaTarget: target as LuaTarget }; const result = util.transpileString("~a", options); - expect(result).toBe("local ____ = bit.bnot(a);"); + expect(result).toBe("local ____ = bit.bnot(a)"); }); test.each([LuaLibImportKind.None, "none", "NoNe"])( @@ -14,6 +14,6 @@ test.each([LuaLibImportKind.None, "none", "NoNe"])( const options = { luaLibImport: importKind as LuaLibImportKind }; const result = util.transpileString("const a = new Map();", options); - expect(result).toBe("local a = Map.new();"); + expect(result).toBe("local a = Map.new()"); }, ); diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts index 5c9319045..5734b6440 100644 --- a/test/unit/console.spec.ts +++ b/test/unit/console.spec.ts @@ -3,54 +3,54 @@ import * as util from "../util"; const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; test.each([ - { inp: "console.log()", expected: "print();" }, - { inp: 'console.log("Hello")', expected: 'print("Hello");' }, + { inp: "console.log()", expected: "print()" }, + { inp: 'console.log("Hello")', expected: 'print("Hello")' }, { inp: 'console.log("Hello %s", "there")', - expected: 'print(string.format("Hello %s", "there"));', + expected: 'print(string.format("Hello %s", "there"))', }, { inp: 'console.log("Hello %%s", "there")', - expected: 'print(string.format("Hello %%s", "there"));', + expected: 'print(string.format("Hello %%s", "there"))', }, - { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There");' }, + { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There")' }, ])("console.log (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); }); test.each([ - { inp: "console.trace()", expected: "print(debug.traceback());" }, - { inp: 'console.trace("message")', expected: 'print(debug.traceback("message"));' }, + { inp: "console.trace()", expected: "print(debug.traceback())" }, + { inp: 'console.trace("message")', expected: 'print(debug.traceback("message"))' }, { inp: 'console.trace("Hello %s", "there")', - expected: 'print(debug.traceback(string.format("Hello %s", "there")));', + expected: 'print(debug.traceback(string.format("Hello %s", "there")))', }, { inp: 'console.trace("Hello %%s", "there")', - expected: 'print(debug.traceback(string.format("Hello %%s", "there")));', + expected: 'print(debug.traceback(string.format("Hello %%s", "there")))', }, { inp: 'console.trace("Hello", "there")', - expected: 'print(debug.traceback("Hello", "there"));', + expected: 'print(debug.traceback("Hello", "there"))', }, ])("console.trace (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); }); test.each([ - { inp: "console.assert(false)", expected: "assert(false);" }, - { inp: 'console.assert(false, "message")', expected: 'assert(false, "message");' }, + { inp: "console.assert(false)", expected: "assert(false)" }, + { inp: 'console.assert(false, "message")', expected: 'assert(false, "message")' }, { inp: 'console.assert(false, "message %s", "info")', - expected: 'assert(false, string.format("message %s", "info"));', + expected: 'assert(false, string.format("message %s", "info"))', }, { inp: 'console.assert(false, "message %%s", "info")', - expected: 'assert(false, string.format("message %%s", "info"));', + expected: 'assert(false, string.format("message %%s", "info"))', }, { inp: 'console.assert(false, "message", "more")', - expected: 'assert(false, "message", "more");', + expected: 'assert(false, "message", "more")', }, ])("console.assert (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index cbb0fbe15..c067d04fb 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -11,7 +11,7 @@ test("Declare const enum", () => { const valueOne = TestEnum.MEMBER_ONE; `; - expect(util.transpileString(testCode)).toBe(`local valueOne = "test";`); + expect(util.transpileString(testCode)).toBe(`local valueOne = "test"`); }); test("Const enum", () => { @@ -24,7 +24,7 @@ test("Const enum", () => { const valueOne = TestEnum.MEMBER_TWO; `; - expect(util.transpileString(testCode)).toBe(`local valueOne = "test2";`); + expect(util.transpileString(testCode)).toBe(`local valueOne = "test2"`); }); test("Const enum without initializer", () => { @@ -37,7 +37,7 @@ test("Const enum without initializer", () => { const valueOne = TestEnum.MEMBER_TWO; `; - expect(util.transpileString(testCode)).toBe(`local valueOne = 1;`); + expect(util.transpileString(testCode)).toBe(`local valueOne = 1`); }); test("Const enum without initializer in some values", () => { @@ -51,7 +51,7 @@ test("Const enum without initializer in some values", () => { const valueOne = TestEnum.MEMBER_TWO; `; - expect(util.transpileString(testCode)).toBe(`local valueOne = 4;`); + expect(util.transpileString(testCode)).toBe(`local valueOne = 4`); }); test("Invalid heterogeneous enum", () => { diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index f91a22269..7adc5a29a 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -3,7 +3,7 @@ import * as util from "../util"; test("throwString", () => { const lua = util.transpileString(`throw "Some Error"`); - expect(lua).toBe(`error("Some Error");`); + expect(lua).toBe(`error("Some Error")`); }); test("throwError", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index f2f820328..0fd43b914 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -4,23 +4,23 @@ import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; test.each([ - { input: "i++", lua: "i = i + 1;" }, - { input: "++i", lua: "i = i + 1;" }, - { input: "i--", lua: "i = i - 1;" }, - { input: "--i", lua: "i = i - 1;" }, - { input: "!a", lua: "local ____ = not a;" }, - { input: "-a", lua: "local ____ = -a;" }, - { input: "+a", lua: "local ____ = a;" }, + { input: "i++", lua: "i = i + 1" }, + { input: "++i", lua: "i = i + 1" }, + { input: "i--", lua: "i = i - 1" }, + { input: "--i", lua: "i = i - 1" }, + { input: "!a", lua: "local ____ = not a" }, + { input: "-a", lua: "local ____ = -a" }, + { input: "+a", lua: "local ____ = a" }, { input: "let a = delete tbl['test']", - lua: "local a = (function()\n tbl.test = nil;\n return true;\nend)();", + lua: "local a = (function()\n tbl.test = nil\n return true\nend)()", }, - { input: "delete tbl['test']", lua: "tbl.test = nil;" }, + { input: "delete tbl['test']", lua: "tbl.test = nil" }, { input: "let a = delete tbl.test", - lua: "local a = (function()\n tbl.test = nil;\n return true;\nend)();", + lua: "local a = (function()\n tbl.test = nil\n return true\nend)()", }, - { input: "delete tbl.test", lua: "tbl.test = nil;" }, + { input: "delete tbl.test", lua: "tbl.test = nil" }, ])("Unary expressions basic (%p)", ({ input, lua }) => { expect(util.transpileString(input)).toBe(lua); }); @@ -106,55 +106,55 @@ test.each([ }); test.each([ - { input: "~a", lua: "local ____ = bit.bnot(a);" }, - { input: "a&b", lua: "local ____ = bit.band(a, b);" }, - { input: "a&=b", lua: "a = bit.band(a, b);" }, - { input: "a|b", lua: "local ____ = bit.bor(a, b);" }, - { input: "a|=b", lua: "a = bit.bor(a, b);" }, - { input: "a^b", lua: "local ____ = bit.bxor(a, b);" }, - { input: "a^=b", lua: "a = bit.bxor(a, b);" }, - { input: "a<>b", lua: "local ____ = bit.arshift(a, b);" }, - { input: "a>>=b", lua: "a = bit.arshift(a, b);" }, - { input: "a>>>b", lua: "local ____ = bit.rshift(a, b);" }, - { input: "a>>>=b", lua: "a = bit.rshift(a, b);" }, + { input: "~a", lua: "local ____ = bit.bnot(a)" }, + { input: "a&b", lua: "local ____ = bit.band(a, b)" }, + { input: "a&=b", lua: "a = bit.band(a, b)" }, + { input: "a|b", lua: "local ____ = bit.bor(a, b)" }, + { input: "a|=b", lua: "a = bit.bor(a, b)" }, + { input: "a^b", lua: "local ____ = bit.bxor(a, b)" }, + { input: "a^=b", lua: "a = bit.bxor(a, b)" }, + { input: "a<>b", lua: "local ____ = bit.arshift(a, b)" }, + { input: "a>>=b", lua: "a = bit.arshift(a, b)" }, + { input: "a>>>b", lua: "local ____ = bit.rshift(a, b)" }, + { input: "a>>>=b", lua: "a = bit.rshift(a, b)" }, ])("Bitop [JIT] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); }); test.each([ - { input: "~a", lua: "local ____ = bit32.bnot(a);" }, - { input: "a&b", lua: "local ____ = bit32.band(a, b);" }, - { input: "a&=b", lua: "a = bit32.band(a, b);" }, - { input: "a|b", lua: "local ____ = bit32.bor(a, b);" }, - { input: "a|=b", lua: "a = bit32.bor(a, b);" }, - { input: "a^b", lua: "local ____ = bit32.bxor(a, b);" }, - { input: "a^=b", lua: "a = bit32.bxor(a, b);" }, - { input: "a<>b", lua: "local ____ = bit32.arshift(a, b);" }, - { input: "a>>=b", lua: "a = bit32.arshift(a, b);" }, - { input: "a>>>b", lua: "local ____ = bit32.rshift(a, b);" }, - { input: "a>>>=b", lua: "a = bit32.rshift(a, b);" }, + { input: "~a", lua: "local ____ = bit32.bnot(a)" }, + { input: "a&b", lua: "local ____ = bit32.band(a, b)" }, + { input: "a&=b", lua: "a = bit32.band(a, b)" }, + { input: "a|b", lua: "local ____ = bit32.bor(a, b)" }, + { input: "a|=b", lua: "a = bit32.bor(a, b)" }, + { input: "a^b", lua: "local ____ = bit32.bxor(a, b)" }, + { input: "a^=b", lua: "a = bit32.bxor(a, b)" }, + { input: "a<>b", lua: "local ____ = bit32.arshift(a, b)" }, + { input: "a>>=b", lua: "a = bit32.arshift(a, b)" }, + { input: "a>>>b", lua: "local ____ = bit32.rshift(a, b)" }, + { input: "a>>>=b", lua: "a = bit32.rshift(a, b)" }, ])("Bitop [5.2] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); }); test.each([ - { input: "~a", lua: "local ____ = ~a;" }, - { input: "a&b", lua: "local ____ = a & b;" }, - { input: "a&=b", lua: "a = a & b;" }, - { input: "a|b", lua: "local ____ = a | b;" }, - { input: "a|=b", lua: "a = a | b;" }, - { input: "a^b", lua: "local ____ = a ~ b;" }, - { input: "a^=b", lua: "a = a ~ b;" }, - { input: "a<>>b", lua: "local ____ = a >> b;" }, - { input: "a>>>=b", lua: "a = a >> b;" }, + { input: "~a", lua: "local ____ = ~a" }, + { input: "a&b", lua: "local ____ = a & b" }, + { input: "a&=b", lua: "a = a & b" }, + { input: "a|b", lua: "local ____ = a | b" }, + { input: "a|=b", lua: "a = a | b" }, + { input: "a^b", lua: "local ____ = a ~ b" }, + { input: "a^=b", lua: "a = a ~ b" }, + { input: "a<>>b", lua: "local ____ = a >> b" }, + { input: "a>>>=b", lua: "a = a >> b" }, ])("Bitop [5.3] (%p)", ({ input, lua }) => { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); @@ -176,12 +176,12 @@ test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { }); test.each([ - { input: "1+1", lua: "1 + 1;" }, - { input: "-1+1", lua: "-1 + 1;" }, - { input: "1*30+4", lua: "1 * 30 + 4;" }, - { input: "1*(3+4)", lua: "1 * (3 + 4);" }, - { input: "1*(3+4*2)", lua: "1 * (3 + 4 * 2);" }, - { input: "10-(4+5)", lua: "10 - (4 + 5);" }, + { input: "1+1", lua: "1 + 1" }, + { input: "-1+1", lua: "-1 + 1" }, + { input: "1*30+4", lua: "1 * 30 + 4" }, + { input: "1*(3+4)", lua: "1 * (3 + 4)" }, + { input: "1*(3+4*2)", lua: "1 * (3 + 4 * 2)" }, + { input: "10-(4+5)", lua: "10 - (4 + 5)" }, ])("Binary expressions ordering parentheses (%p)", ({ input, lua }) => { expect(util.transpileString(input)).toBe("local ____ = " + lua); }); @@ -208,11 +208,11 @@ test("Binary Comma Statement in For Loop", () => { }); test("Null Expression", () => { - expect(util.transpileString("null")).toBe("local ____ = nil;"); + expect(util.transpileString("null")).toBe("local ____ = nil"); }); test("Undefined Expression", () => { - expect(util.transpileString("undefined")).toBe("local ____ = nil;"); + expect(util.transpileString("undefined")).toBe("local ____ = nil"); }); test.each([ diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index db16d75ae..079188cba 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -13,7 +13,7 @@ test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } json => { const lua = util .transpileString(json, jsonOptions, false, "file.json") - .replace(/^return ([\s\S]+);$/, "return JSONStringify($1);"); + .replace(/^return ([\s\S]+)$/, "return JSONStringify($1)"); const result = util.executeLua(lua); expect(JSON.parse(result)).toEqual(JSON.parse(json)); diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index fefd4f310..c518c69a3 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -1,17 +1,17 @@ import * as util from "../util"; test.each([ - { inp: "Math.cos()", expected: "math.cos();" }, - { inp: "Math.sin()", expected: "math.sin();" }, - { inp: "Math.min()", expected: "math.min();" }, - { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3);" }, - { inp: "Math.log2(3)", expected: `(function() return math.log(3) / ${Math.LN2}; end)();` }, - { inp: "Math.log10(3)", expected: `(function() return math.log(3) / ${Math.LN10}; end)();` }, - { inp: "const x = Math.log2(3)", expected: `local x = (math.log(3) / ${Math.LN2});` }, - { inp: "const x = Math.log10(3)", expected: `local x = (math.log(3) / ${Math.LN10});` }, - { inp: "Math.log1p(3)", expected: "math.log(1 + 3);" }, - { inp: "Math.round(3.3)", expected: "math.floor(3.3 + 0.5);" }, - { inp: "Math.PI", expected: "local ____ = math.pi;" }, + { inp: "Math.cos()", expected: "math.cos()" }, + { inp: "Math.sin()", expected: "math.sin()" }, + { inp: "Math.min()", expected: "math.min()" }, + { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3)" }, + { inp: "Math.log2(3)", expected: `(function() return math.log(3) / ${Math.LN2} end)()` }, + { inp: "Math.log10(3)", expected: `(function() return math.log(3) / ${Math.LN10} end)()` }, + { inp: "const x = Math.log2(3)", expected: `local x = (math.log(3) / ${Math.LN2})` }, + { inp: "const x = Math.log10(3)", expected: `local x = (math.log(3) / ${Math.LN10})` }, + { inp: "Math.log1p(3)", expected: "math.log(1 + 3)" }, + { inp: "Math.round(3.3)", expected: "math.floor(3.3 + 0.5)" }, + { inp: "Math.PI", expected: "local ____ = math.pi" }, ])("Math (%p)", ({ inp, expected }) => { const lua = util.transpileString(inp); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 3cc8ad2c2..a37ab815d 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -2,12 +2,12 @@ import * as util from "../util"; const fs = require("fs"); test.each([ - { inp: `{a:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, - { inp: `{"a":3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, - { inp: `{["a"]:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n};' }, - { inp: `{["a"+123]:3,b:"4"}`, out: '{\n ["a" .. 123] = 3,\n b = "4",\n};' }, - { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4",\n};' }, - { inp: `{x}`, out: `{x = x};` }, + { inp: `{a:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, + { inp: `{"a":3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, + { inp: `{["a"]:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, + { inp: `{["a"+123]:3,b:"4"}`, out: '{\n ["a" .. 123] = 3,\n b = "4",\n}' }, + { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4",\n}' }, + { inp: `{x}`, out: `{x = x}` }, ])("Object Literal (%p)", ({ inp, out }) => { const lua = util.transpileString(`const myvar = ${inp};`); expect(lua).toBe(`local myvar = ${out}`); diff --git a/test/unit/semicolons.spec.ts b/test/unit/semicolons.spec.ts new file mode 100644 index 000000000..7142fe548 --- /dev/null +++ b/test/unit/semicolons.spec.ts @@ -0,0 +1,17 @@ +import * as util from "../util"; + +test.each([ + "const a = 1; const b = a;", + "const a = 1; let b: number; b = a;", + "{}", + "function bar() {} bar();", +])("semicolon insertion (%p)", leadingStatement => { + const code = ` + let result = ""; + function foo() { result = "foo"; } + ${leadingStatement} + (foo)(); + return result; + `; + expect(util.transpileAndExecute(code)).toEqual("foo"); +}); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index dcdc84c5f..00acb8d05 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -15,23 +15,23 @@ test("Spread Element Lua 5.1", () => { // Cant test functional because our VM doesn't run on 5.1 const options = { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); - expect(lua).toBe("__TS__ArrayPush({}, unpack({\n 1,\n 2,\n 3,\n}));"); + expect(lua).toBe("__TS__ArrayPush({}, unpack({\n 1,\n 2,\n 3,\n}))"); }); test("Spread Element Lua 5.2", () => { const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); }); test("Spread Element Lua 5.3", () => { const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); }); test("Spread Element Lua JIT", () => { const options = { luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})};"); + expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})}"); }); From 4fbf086274a764f5d52642d825248f993b0645f1 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 10 Apr 2019 10:26:39 -0600 Subject: [PATCH 054/764] Removing "or" assignment from exports, class and namespace declarations (#512) * exports, classes and modules no longer use X = X or {} * fixed translation tests * changed 'exports' to '____exports' * caching classes in local when exported --- src/Decorator.ts | 3 - src/LuaTransformer.ts | 199 +++++++++--------- src/TSHelper.ts | 16 ++ .../__snapshots__/transformation.spec.ts.snap | 144 +++++++------ 4 files changed, 184 insertions(+), 178 deletions(-) diff --git a/src/Decorator.ts b/src/Decorator.ts index c18ab4dc3..73ac39ea7 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -21,8 +21,6 @@ export class Decorator { return DecoratorKind.Phantom; case "tuplereturn": return DecoratorKind.TupleReturn; - case "noclassor": - return DecoratorKind.NoClassOr; case "luaiterator": return DecoratorKind.LuaIterator; case "noself": @@ -52,7 +50,6 @@ export enum DecoratorKind { PureAbstract = "PureAbstract", Phantom = "Phantom", TupleReturn = "TupleReturn", - NoClassOr = "NoClassOr", LuaIterator = "LuaIterator", NoSelf = "NoSelf", NoSelfInFile = "NoSelfInFile", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 86f680583..4357414fa 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -118,18 +118,20 @@ export class LuaTransformer { this.popScope(); if (this.isModule) { + // local exports = {} statements.unshift( tstl.createVariableDeclarationStatement( - tstl.createIdentifier("exports"), - tstl.createBinaryExpression( - tstl.createIdentifier("exports"), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator - ))); + this.createExportsIdentifier(), + tstl.createTableExpression() + ) + ); + + // return exports statements.push( tstl.createReturnStatement( - [tstl.createIdentifier("exports")] - )); + [this.createExportsIdentifier()] + ) + ); } } @@ -289,7 +291,7 @@ export class LuaTransformer { const body = tstl.createBlock( [tstl.createAssignmentStatement( tstl.createTableIndexExpression( - tstl.createIdentifier("exports"), + this.createExportsIdentifier(), forKey ), forValue @@ -570,7 +572,7 @@ export class LuaTransformer { const value = this.transformExpression(field.initializer); const classField = tstl.createTableIndexExpression( - this.addExportToIdentifier(tstl.cloneIdentifier(className)), + tstl.cloneIdentifier(className), fieldName ); @@ -593,34 +595,28 @@ export class LuaTransformer { extendsType: ts.Type ): tstl.Statement[] { - let noClassOr = false; - if (extendsType) { - const decorators = tsHelper.getCustomDecorators(extendsType, this.checker); - noClassOr = decorators.has(DecoratorKind.NoClassOr); - } - const result: tstl.Statement[] = []; - // className = className or {} - let classTable: tstl.Expression = tstl.createTableExpression([], statement); - if (!noClassOr) { - classTable = tstl.createBinaryExpression( - this.addExportToIdentifier(className), // Use original identifier node in declaration - classTable, - tstl.SyntaxKind.OrOperator, - statement - ); - } + // [____exports.]className = {} + const classTable: tstl.Expression = tstl.createTableExpression([], statement); const classVar = this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); result.push(...classVar); - const createClassNameWithExport = () => this.addExportToIdentifier(tstl.cloneIdentifier(className)); + if (this.isIdentifierExported(className)) { + // local className = ____exports.className + result.push( + tstl.createVariableDeclarationStatement( + tstl.cloneIdentifier(className), + this.addExportToIdentifier(tstl.cloneIdentifier(className)) + ) + ); + } // className.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { const classGetters = tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("____getters"), statement ); @@ -636,17 +632,17 @@ export class LuaTransformer { // className.__index = className const classIndex = tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("__index"), statement ); - const assignClassIndex = tstl.createAssignmentStatement(classIndex, createClassNameWithExport(), statement); + const assignClassIndex = tstl.createAssignmentStatement(classIndex, tstl.cloneIdentifier(className), statement); result.push(assignClassIndex); // className.____setters = {} if (statement.members.some(m => ts.isSetAccessor(m) && tsHelper.isStatic(m))) { const classSetters = tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("____setters") ); const assignClassSetters = tstl.createAssignmentStatement( @@ -659,20 +655,13 @@ export class LuaTransformer { this.importLuaLibFeature(LuaLibFeature.ClassNewIndex); } - // className.prototype = className.prototype or {} + // className.prototype = {} const createClassPrototype = () => tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype"), statement ); - const classPrototypeTable = noClassOr - ? tstl.createTableExpression([], statement) - : tstl.createBinaryExpression( - createClassPrototype(), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator, - statement - ); + const classPrototypeTable = tstl.createTableExpression(); const assignClassPrototype = tstl.createAssignmentStatement(createClassPrototype(), classPrototypeTable); result.push(assignClassPrototype); @@ -749,7 +738,7 @@ export class LuaTransformer { ); const assignClassPrototypeConstructor = tstl.createAssignmentStatement( classPrototypeConstructor, - createClassNameWithExport(), + tstl.cloneIdentifier(className), statement ); result.push(assignClassPrototypeConstructor); @@ -759,11 +748,13 @@ export class LuaTransformer { if (extendsType) { const extendedTypeNode = tsHelper.getExtendedTypeNode(statement, this.checker); - const baseName = this.transformExpression(extendedTypeNode.expression); + const baseName = ts.isIdentifier(extendedTypeNode.expression) + ? this.transformIdentifier(extendedTypeNode.expression) // Skip adding '____exports' + : this.transformExpression(extendedTypeNode.expression); // className.____super = baseName const createClassBase = () => tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("____super"), statement ); @@ -800,7 +791,7 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [createClassNameWithExport(), tstl.createTableExpression(metatableFields)] + [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)] ) ); result.push(setClassMetatable); @@ -810,7 +801,7 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [createClassNameWithExport(), createClassBase()] + [tstl.cloneIdentifier(className), createClassBase()] ) ); result.push(setClassMetatable); @@ -856,7 +847,7 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [createClassNameWithExport(), tstl.createTableExpression(metatableFields)] + [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)] ) ); result.push(setClassMetatable); @@ -894,7 +885,7 @@ export class LuaTransformer { // or function export.className.new(construct, ...) ... end const newFunc = tstl.createAssignmentStatement( tstl.createTableIndexExpression( - createClassNameWithExport(), + tstl.cloneIdentifier(className), tstl.createStringLiteral("new")), tstl.createFunctionExpression( tstl.createBlock(newFuncStatements), @@ -952,7 +943,7 @@ export class LuaTransformer { public createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { return tstl.createTableIndexExpression( tstl.createTableIndexExpression( - this.addExportToIdentifier(tstl.cloneIdentifier(className)), + tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype") ), tstl.createStringLiteral("____constructor") @@ -1048,10 +1039,9 @@ export class LuaTransformer { tstl.FunctionExpressionFlags.Declaration ); - const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); const methodTable = tsHelper.isStatic(getAccessor) - ? classNameWithExport - : tstl.createTableIndexExpression(classNameWithExport, tstl.createStringLiteral("prototype")); + ? tstl.cloneIdentifier(className) + : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); const classGetters = tstl.createTableIndexExpression( methodTable, @@ -1084,10 +1074,9 @@ export class LuaTransformer { tstl.FunctionExpressionFlags.Declaration ); - const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); const methodTable = tsHelper.isStatic(setAccessor) - ? classNameWithExport - : tstl.createTableIndexExpression(classNameWithExport, tstl.createStringLiteral("prototype")); + ? tstl.cloneIdentifier(className) + : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); const classSetters = tstl.createTableIndexExpression( methodTable, @@ -1133,10 +1122,9 @@ export class LuaTransformer { node.body ); - const classNameWithExport = this.addExportToIdentifier(tstl.cloneIdentifier(className)); const methodTable = tsHelper.isStatic(node) || noPrototype - ? classNameWithExport - : tstl.createTableIndexExpression(classNameWithExport, tstl.createStringLiteral("prototype")); + ? tstl.cloneIdentifier(className) + : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); return tstl.createAssignmentStatement( tstl.createTableIndexExpression( @@ -1302,60 +1290,63 @@ export class LuaTransformer { const result: tstl.Statement[] = []; - if (this.currentNamespace) { - // outerNS.innerNS = outerNS.innerNS or {} - const namespaceDeclaration = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.transformIdentifier(this.currentNamespace.name as ts.Identifier), - tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text)), - tstl.createBinaryExpression( + const symbol = this.checker.getSymbolAtLocation(statement.name); + const hasExports = symbol !== undefined && this.checker.getExportsOfModule(symbol).length > 0; + const isFirstDeclaration = symbol !== undefined + && symbol.declarations[0] === statement + // TS allows an empty namespace before a class of the same name + && symbol.declarations.findIndex(d => ts.isClassLike(d)) === -1; + if (isFirstDeclaration) { + const isExported = (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; + if (isExported && this.currentNamespace) { + // outerNS.innerNS = {} + const namespaceDeclaration = tstl.createAssignmentStatement( tstl.createTableIndexExpression( this.transformIdentifier(this.currentNamespace.name as ts.Identifier), tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text)), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator)); + tstl.createTableExpression() + ); - result.push(namespaceDeclaration); + result.push(namespaceDeclaration); - // local innerNS = outerNS.innerNS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - statement.name as ts.Identifier, - tstl.createTableIndexExpression( - this.transformIdentifier(this.currentNamespace.name as ts.Identifier), - tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text))); + if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { + // local innerNS = outerNS.innerNS + const localDeclaration = this.createHoistableVariableDeclarationStatement( + statement.name as ts.Identifier, + tstl.createTableIndexExpression( + this.transformIdentifier(this.currentNamespace.name as ts.Identifier), + tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text))); - result.push(localDeclaration); + result.push(localDeclaration); + } - } else if (this.isModule && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export)) { - // exports.NS = exports.NS or {} - const namespaceDeclaration = tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier)), - tstl.createBinaryExpression( + } else if (isExported && !this.currentNamespace && this.isModule) { + // exports.NS = {} + const namespaceDeclaration = tstl.createAssignmentStatement( this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier)), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator)); + tstl.createTableExpression() + ); - result.push(namespaceDeclaration); + result.push(namespaceDeclaration); - // local NS = exports.NS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - statement.name as ts.Identifier, - this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier))); + if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { + // local NS = exports.NS + const localDeclaration = this.createHoistableVariableDeclarationStatement( + statement.name as ts.Identifier, + this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier))); - result.push(localDeclaration); + result.push(localDeclaration); + } - } else { - // local NS = NS or {} - const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( - this.transformIdentifier(statement.name as ts.Identifier), - tstl.createBinaryExpression( + } else { + // local NS = {} + const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( this.transformIdentifier(statement.name as ts.Identifier), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator - ) - ); + tstl.createTableExpression() + ); - result.push(...localDeclaration); + result.push(...localDeclaration); + } } // Set current namespace for nested NS @@ -1364,7 +1355,7 @@ export class LuaTransformer { this.currentNamespace = statement; // Transform moduleblock to block and visit it - if (statement.body && (ts.isModuleBlock(statement.body) || ts.isModuleDeclaration(statement.body))) { + if (tsHelper.moduleHasEmittedBody(statement)) { this.pushScope(ScopeType.Block, statement); let statements = ts.isModuleBlock(statement.body) ? this.transformStatements(statement.body.statements) @@ -3157,11 +3148,11 @@ export class LuaTransformer { let baseClassName: tstl.IdentifierOrTableIndexExpression; if (ts.isIdentifier(extendsExpression)) { // Use "baseClassName" if base is a simple identifier - baseClassName = this.addExportToIdentifier(this.transformIdentifier(extendsExpression)); + baseClassName = this.transformIdentifier(extendsExpression); } else { // Use "className.____super" if the base is not a simple identifier baseClassName = tstl.createTableIndexExpression( - this.addExportToIdentifier(this.transformIdentifier(classDeclaration.name)), + this.transformIdentifier(classDeclaration.name), tstl.createStringLiteral("____super"), expression ); @@ -4195,7 +4186,7 @@ export class LuaTransformer { public createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { const exportTable = this.currentNamespace ? this.transformIdentifier(this.currentNamespace.name as ts.Identifier) - : tstl.createIdentifier("exports"); + : this.createExportsIdentifier(); return tstl.createTableIndexExpression( exportTable, @@ -4320,6 +4311,10 @@ export class LuaTransformer { return tstl.createIdentifier("self", tsOriginal); } + private createExportsIdentifier(): tstl.Identifier { + return tstl.createIdentifier("____exports"); + } + private createLocalOrExportedOrGlobalDeclaration( lhs: tstl.Identifier | tstl.Identifier[], rhs?: tstl.Expression, diff --git a/src/TSHelper.ts b/src/TSHelper.ts index d9ec50f2e..521b06f22 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -736,4 +736,20 @@ export class TSHelper { return [false, undefined]; } } + + public static moduleHasEmittedBody(statement: ts.ModuleDeclaration) + : statement is ts.ModuleDeclaration & {body: ts.ModuleBlock | ts.ModuleDeclaration} + { + if (statement.body) { + if (ts.isModuleBlock(statement.body)) { + // Ignore if body has no emitted statements + return statement.body.statements.findIndex( + s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) + ) !== -1; + } else if (ts.isModuleDeclaration(statement.body)) { + return true; + } + } + return false; + } } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 346836118..d6c1a3abb 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -42,9 +42,9 @@ end" `; exports[`Transformation (classPureAbstract) 1`] = ` -"ClassB = ClassB or {} +"ClassB = {} ClassB.__index = ClassB -ClassB.prototype = ClassB.prototype or {} +ClassB.prototype = {} ClassB.prototype.__index = ClassB.prototype ClassB.prototype.constructor = ClassB function ClassB.new(...) @@ -192,29 +192,29 @@ TestEnum.baz = \\"val3\\"" `; exports[`Transformation (exportStatement) 1`] = ` -"local exports = exports or {} +"local ____exports = {} local xyz = 4 -exports.xyz = xyz -exports.uwv = xyz +____exports.xyz = xyz +____exports.uwv = xyz do local __TSTL_export = require(\\"xyz\\") for ____exportKey, ____exportValue in pairs(__TSTL_export) do - exports[____exportKey] = ____exportValue + ____exports[____exportKey] = ____exportValue end end do local __TSTL_xyz = require(\\"xyz\\") local abc = __TSTL_xyz.abc local def = __TSTL_xyz.def - exports.abc = abc - exports.def = def + ____exports.abc = abc + ____exports.def = def end do local __TSTL_xyz = require(\\"xyz\\") local def = __TSTL_xyz.abc - exports.def = def + ____exports.def = def end -return exports" +return ____exports" `; exports[`Transformation (for) 1`] = ` @@ -262,9 +262,9 @@ end" exports[`Transformation (getSetAccessors) 1`] = ` "require(\\"lualib_bundle\\"); -MyClass = MyClass or {} +MyClass = {} MyClass.__index = MyClass -MyClass.prototype = MyClass.prototype or {} +MyClass.prototype = {} MyClass.prototype.____getters = {} MyClass.prototype.__index = __TS__Index(MyClass.prototype) MyClass.prototype.____setters = {} @@ -295,9 +295,9 @@ a.abc = \\"def\\"" `; exports[`Transformation (methodRestArguments) 1`] = ` -"MyClass = MyClass or {} +"MyClass = {} MyClass.__index = MyClass -MyClass.prototype = MyClass.prototype or {} +MyClass.prototype = {} MyClass.prototype.__index = MyClass.prototype MyClass.prototype.constructor = MyClass function MyClass.new(...) @@ -313,52 +313,54 @@ end" `; exports[`Transformation (modulesChangedVariableExport) 1`] = ` -"local exports = exports or {} -exports.foo = 1 -return exports" +"local ____exports = {} +____exports.foo = 1 +return ____exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"local exports = exports or {} -exports.TestClass = exports.TestClass or {} -exports.TestClass.__index = exports.TestClass -exports.TestClass.prototype = exports.TestClass.prototype or {} -exports.TestClass.prototype.__index = exports.TestClass.prototype -exports.TestClass.prototype.constructor = exports.TestClass -function exports.TestClass.new(...) - local self = setmetatable({}, exports.TestClass.prototype) +"local ____exports = {} +____exports.TestClass = {} +local TestClass = ____exports.TestClass +TestClass.__index = TestClass +TestClass.prototype = {} +TestClass.prototype.__index = TestClass.prototype +TestClass.prototype.constructor = TestClass +function TestClass.new(...) + local self = setmetatable({}, TestClass.prototype) self:____constructor(...) return self end -function exports.TestClass.prototype.____constructor(self) +function TestClass.prototype.____constructor(self) end -return exports" +return ____exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"local exports = exports or {} -exports.TestClass = exports.TestClass or {} -exports.TestClass.__index = exports.TestClass -exports.TestClass.prototype = exports.TestClass.prototype or {} -exports.TestClass.prototype.__index = exports.TestClass.prototype -exports.TestClass.prototype.constructor = exports.TestClass -function exports.TestClass.new(...) - local self = setmetatable({}, exports.TestClass.prototype) +"local ____exports = {} +____exports.TestClass = {} +local TestClass = ____exports.TestClass +TestClass.__index = TestClass +TestClass.prototype = {} +TestClass.prototype.__index = TestClass.prototype +TestClass.prototype.constructor = TestClass +function TestClass.new(...) + local self = setmetatable({}, TestClass.prototype) self:____constructor(...) return self end -function exports.TestClass.prototype.____constructor(self) +function TestClass.prototype.____constructor(self) end -function exports.TestClass.prototype.memberFunc(self) +function TestClass.prototype.memberFunc(self) end -return exports" +return ____exports" `; exports[`Transformation (modulesFunctionExport) 1`] = ` -"local exports = exports or {} -function exports.publicFunc(self) +"local ____exports = {} +function ____exports.publicFunc(self) end -return exports" +return ____exports" `; exports[`Transformation (modulesFunctionNoExport) 1`] = ` @@ -407,16 +409,15 @@ local RenamedClass = __TSTL_space_module.TestClass" exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\")"`; exports[`Transformation (modulesNamespaceExport) 1`] = ` -"local exports = exports or {} -exports.TestSpace = exports.TestSpace or {} -local TestSpace = exports.TestSpace -return exports" +"local ____exports = {} +____exports.TestSpace = {} +return ____exports" `; exports[`Transformation (modulesNamespaceExportEnum) 1`] = ` -"local exports = exports or {} -exports.test = exports.test or {} -local test = exports.test +"local ____exports = {} +____exports.test = {} +local test = ____exports.test do test.TestEnum = {} test.TestEnum.foo = \\"foo\\" @@ -424,58 +425,57 @@ do test.TestEnum.bar = \\"bar\\" test.TestEnum.bar = \\"bar\\" end -return exports" +return ____exports" `; exports[`Transformation (modulesNamespaceNestedWithMemberExport) 1`] = ` -"local exports = exports or {} -exports.TestSpace = exports.TestSpace or {} -local TestSpace = exports.TestSpace +"local ____exports = {} +____exports.TestSpace = {} +local TestSpace = ____exports.TestSpace do - TestSpace.TestNestedSpace = TestSpace.TestNestedSpace or {} + TestSpace.TestNestedSpace = {} local TestNestedSpace = TestSpace.TestNestedSpace do function TestNestedSpace.innerFunc(self) end end end -return exports" +return ____exports" `; -exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {}"`; +exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = {}"`; exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` -"local exports = exports or {} -exports.TestSpace = exports.TestSpace or {} -local TestSpace = exports.TestSpace +"local ____exports = {} +____exports.TestSpace = {} +local TestSpace = ____exports.TestSpace do function TestSpace.innerFunc(self) end end -return exports" +return ____exports" `; exports[`Transformation (modulesNamespaceWithMemberNoExport) 1`] = ` -"local exports = exports or {} -exports.TestSpace = exports.TestSpace or {} -local TestSpace = exports.TestSpace +"local ____exports = {} +____exports.TestSpace = {} do local function innerFunc(self) end end -return exports" +return ____exports" `; exports[`Transformation (modulesVariableExport) 1`] = ` -"local exports = exports or {} -exports.foo = \\"bar\\" -return exports" +"local ____exports = {} +____exports.foo = \\"bar\\" +return ____exports" `; exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\""`; exports[`Transformation (namespace) 1`] = ` -"myNamespace = myNamespace or {} +"myNamespace = {} do local function nsMember(self) end @@ -483,9 +483,9 @@ end" `; exports[`Transformation (namespaceMerge) 1`] = ` -"MergedClass = MergedClass or {} +"MergedClass = {} MergedClass.__index = MergedClass -MergedClass.prototype = MergedClass.prototype or {} +MergedClass.prototype = {} MergedClass.prototype.__index = MergedClass.prototype MergedClass.prototype.constructor = MergedClass function MergedClass.new(...) @@ -508,7 +508,6 @@ function MergedClass.prototype.methodB(self) self:methodA() self:propertyFunc() end -MergedClass = MergedClass or {} do function MergedClass.namespaceFunc(self) end @@ -521,10 +520,9 @@ MergedClass:namespaceFunc()" `; exports[`Transformation (namespaceNested) 1`] = ` -"myNamespace = myNamespace or {} +"myNamespace = {} do - myNamespace.myNestedNamespace = myNamespace.myNestedNamespace or {} - local myNestedNamespace = myNamespace.myNestedNamespace + local myNestedNamespace = {} do local function nsMember(self) end From dd7e5de7ea7fa9e4652d2118d310baaf7bd8494c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 12 Apr 2019 05:41:58 -0600 Subject: [PATCH 055/764] fixed commenting of inline sourcemaps (#519) * fixed commenting of inline sourcemaps and added test * forgot to run prettier --- src/LuaPrinter.ts | 2 +- test/unit/sourcemaps.spec.ts | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index f4a68dcdc..3d6af0049 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -83,7 +83,7 @@ export class LuaPrinter { const map = sourceMap.toString(); const base64Map = Buffer.from(map).toString('base64'); - return `//# sourceMappingURL=data:application/json;base64,${base64Map}\n`; + return `--# sourceMappingURL=data:application/json;base64,${base64Map}\n`; } private printStackTraceOverride(rootNode: SourceNode): string { diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index e8a374780..e6e6fe766 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -1,5 +1,5 @@ import * as util from "../util"; -import { LuaLibImportKind } from "../../src/CompilerOptions"; +import { LuaLibImportKind, CompilerOptions } from "../../src/CompilerOptions"; import { SourceMapConsumer, Position } from "source-map"; test.each([ @@ -109,6 +109,33 @@ test("sourceMapTraceback saves sourcemap in _G", () => { } }); +test("Inline sourcemaps", () => { + const typeScriptSource = ` + function abc() { + return def(); + } + function def() { + return "foo"; + } + return abc();`; + + const compilerOptions: CompilerOptions = { + inlineSourceMap: true, + }; + + const { lua, sourceMap } = util.transpileStringResult(typeScriptSource, compilerOptions); + + const inlineSourceMapMatch = lua.match( + /--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/, + ); + expect(inlineSourceMapMatch !== null && inlineSourceMapMatch !== undefined).toBe(true); + + const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); + expect(sourceMap).toBe(inlineSourceMap); + + expect(util.executeLua(lua)).toBe("foo"); +}); + // Helper functions function lineAndColumnOf(text: string, pattern: string): Position { From 3df8dfbacce60e14d109303155036629957591a6 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 12 Apr 2019 11:53:32 -0600 Subject: [PATCH 056/764] class name support (#520) -name property accessable on classes and instance constructor property -now using name of class expressions for variable and name property, if it's specified --- src/LuaTransformer.ts | 14 ++++- .../__snapshots__/transformation.spec.ts.snap | 6 +++ test/unit/class.spec.ts | 51 +++++++++++++++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4357414fa..921ce48a5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -613,6 +613,14 @@ export class LuaTransformer { ); } + // className.name = className + result.push( + tstl.createAssignmentStatement( + tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("name")), + tstl.createStringLiteral(className.text) + ) + ); + // className.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { const classGetters = tstl.createTableIndexExpression( @@ -2751,8 +2759,10 @@ export class LuaTransformer { } public transformClassExpression(expression: ts.ClassExpression): ExpressionVisitResult { - const className = tstl.createAnnonymousIdentifier(); - const classDeclaration = this.transformClassDeclaration(expression as ts.ClassExpression, className); + const className = expression.name !== undefined + ? this.transformIdentifier(expression.name) + : tstl.createAnnonymousIdentifier(); + const classDeclaration = this.transformClassDeclaration(expression, className); return this.createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index d6c1a3abb..23dfccd67 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -43,6 +43,7 @@ end" exports[`Transformation (classPureAbstract) 1`] = ` "ClassB = {} +ClassB.name = \\"ClassB\\" ClassB.__index = ClassB ClassB.prototype = {} ClassB.prototype.__index = ClassB.prototype @@ -263,6 +264,7 @@ end" exports[`Transformation (getSetAccessors) 1`] = ` "require(\\"lualib_bundle\\"); MyClass = {} +MyClass.name = \\"MyClass\\" MyClass.__index = MyClass MyClass.prototype = {} MyClass.prototype.____getters = {} @@ -296,6 +298,7 @@ a.abc = \\"def\\"" exports[`Transformation (methodRestArguments) 1`] = ` "MyClass = {} +MyClass.name = \\"MyClass\\" MyClass.__index = MyClass MyClass.prototype = {} MyClass.prototype.__index = MyClass.prototype @@ -322,6 +325,7 @@ exports[`Transformation (modulesClassExport) 1`] = ` "local ____exports = {} ____exports.TestClass = {} local TestClass = ____exports.TestClass +TestClass.name = \\"TestClass\\" TestClass.__index = TestClass TestClass.prototype = {} TestClass.prototype.__index = TestClass.prototype @@ -340,6 +344,7 @@ exports[`Transformation (modulesClassWithMemberExport) 1`] = ` "local ____exports = {} ____exports.TestClass = {} local TestClass = ____exports.TestClass +TestClass.name = \\"TestClass\\" TestClass.__index = TestClass TestClass.prototype = {} TestClass.prototype.__index = TestClass.prototype @@ -484,6 +489,7 @@ end" exports[`Transformation (namespaceMerge) 1`] = ` "MergedClass = {} +MergedClass.name = \\"MergedClass\\" MergedClass.__index = MergedClass MergedClass.prototype = {} MergedClass.prototype.__index = MergedClass.prototype diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index f8f305ea0..75070b578 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -746,3 +746,54 @@ test("Class static instance of self", () => { `; expect(util.transpileAndExecute(code)).toBe("foobar"); }); + +test("Class name", () => { + const code = ` + class Foo {} + return Foo.name; + `; + expect(util.transpileAndExecute(code)).toBe("Foo"); +}); + +test("Class name via constructor", () => { + const code = ` + class Foo {} + const foo = new Foo(); + return foo.constructor.name; + `; + expect(util.transpileAndExecute(code)).toBe("Foo"); +}); + +test("Class expression name", () => { + const code = ` + const foo = class Foo {}; + return foo.name; + `; + expect(util.transpileAndExecute(code)).toBe("Foo"); +}); + +test("Class expression name via constructor", () => { + const code = ` + const foo = class Foo {}; + const bar = new foo(); + return bar.constructor.name; + `; + expect(util.transpileAndExecute(code)).toBe("Foo"); +}); + +test("Class annonymous expression name", () => { + const code = ` + const foo = class {}; + return foo.name; + `; + expect(util.transpileAndExecute(code)).toBe("____"); +}); + +test("Class annonymous expression name via constructor", () => { + const code = ` + const foo = class {}; + const bar = new foo(); + return bar.constructor.name; + `; + expect(util.transpileAndExecute(code)).toBe("____"); +}); From 29047b51c48aad83a905f31c0ba62fb2c3954100 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 13 Apr 2019 11:10:15 -0600 Subject: [PATCH 057/764] ArraySetLength lib function (#521) * added ArrayLengthSet lib function * Disabled tslint error in ArraySetLength * Handling NaN, Infinity, and non-integers * Removed unneeded -Infinity check --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 22 ++++++++++++++++++++ src/TSHelper.ts | 26 +++++++++++++++++++++++ src/lualib/ArraySetLength.ts | 14 +++++++++++++ test/unit/array.spec.ts | 40 ++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+) create mode 100644 src/lualib/ArraySetLength.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7515d8d4b..5b259f66b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -19,6 +19,7 @@ export enum LuaLibFeature { ArraySplice = "ArraySplice", ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", + ArraySetLength = "ArraySetLength", ClassIndex = "ClassIndex", ClassNewIndex = "ClassNewIndex", FunctionApply = "FunctionApply", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 921ce48a5..eede8ed9e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2494,6 +2494,18 @@ export class LuaTransformer { const leftType = this.checker.getTypeAtLocation(expression.left); this.validateFunctionAssignment(expression.right, rightType, leftType); + if (tsHelper.isArrayLengthAssignment(expression, this.checker, this.program)) { + // array.length = x + return tstl.createExpressionStatement( + this.transformLuaLibFunction( + LuaLibFeature.ArraySetLength, + expression, + this.transformExpression(expression.left.expression), + this.transformExpression(expression.right) + ) + ); + } + if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment const left = expression.left.elements.length > 0 @@ -2528,6 +2540,16 @@ export class LuaTransformer { const leftType = this.checker.getTypeAtLocation(expression.left); this.validateFunctionAssignment(expression.right, rightType, leftType); + if (tsHelper.isArrayLengthAssignment(expression, this.checker, this.program)) { + // array.length = x + return this.transformLuaLibFunction( + LuaLibFeature.ArraySetLength, + expression, + this.transformExpression(expression.left.expression), + this.transformExpression(expression.right) + ); + } + if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 521b06f22..d50523fa1 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -752,4 +752,30 @@ export class TSHelper { } return false; } + + public static isArrayLengthAssignment( + expression: ts.BinaryExpression, + checker: ts.TypeChecker, + program: ts.Program + ): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression; } + { + if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return false; + } + + if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) { + return false; + } + + const type = checker.getTypeAtLocation(expression.left.expression); + if (!TSHelper.isArrayType(type, checker, program)) { + return false; + } + + const name = ts.isPropertyAccessExpression(expression.left) + ? expression.left.name.escapedText as string + : ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text; + + return name === "length"; + } } diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts new file mode 100644 index 000000000..3efcf1e2f --- /dev/null +++ b/src/lualib/ArraySetLength.ts @@ -0,0 +1,14 @@ +function __TS__ArraySetLength(this: void, arr: T[], length: number): number { + if (length < 0 + || length !== length // NaN + || length === (1 / 0) // Infinity + || Math.floor(length) !== length) // non-integer + { + // tslint:disable-next-line:no-string-throw + throw `invalid array length: ${length}`; + } + for (let i = arr.length - 1; i >= length; --i) { + arr[i] = undefined; + } + return length; +} diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index 85dcb5dcb..9da08ce1c 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -136,3 +136,43 @@ test("Array property access", () => { `; expect(util.transpileAndExecute(code)).toBe("bar123"); }); + +test.each([{ length: 0, result: 0 }, { length: 1, result: 1 }, { length: 7, result: 3 }])( + "Array length set", + ({ length, result }) => { + const code = ` + const arr = [1, 2, 3]; + arr.length = ${length}; + return arr.length; + `; + expect(util.transpileAndExecute(code)).toBe(result); + }, +); + +test.each([ + { length: 0, result: "0/0" }, + { length: 1, result: "1/1" }, + { length: 7, result: "7/3" }, +])("Array length set as expression", ({ length, result }) => { + const code = ` + const arr = [1, 2, 3]; + const l = arr.length = ${length}; + return \`\${l}/\${arr.length}\`; + `; + expect(util.transpileAndExecute(code)).toBe(result); +}); + +test.each([ + { length: -1, result: -1 }, + { length: -7, result: -7 }, + { length: 0.1, result: 0.1 }, + { length: "0 / 0", result: "NaN" }, + { length: "1 / 0", result: "Infinity" }, + { length: "-1 / 0", result: "-Infinity" }, +])("Invalid array length set", ({ length, result }) => { + const code = ` + const arr = [1, 2, 3]; + arr.length = ${length}; + `; + expect(() => util.transpileAndExecute(code)).toThrowError(`invalid array length: ${result}`); +}); From 16a61b77133f0fa638af2d9e8bc9edba400270d6 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 14 Apr 2019 08:20:16 -0600 Subject: [PATCH 058/764] Fixed merging module into interface (#522) --- src/LuaTransformer.ts | 13 +++++++++---- test/unit/modules.spec.ts | 10 ++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index eede8ed9e..ccb629938 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1300,10 +1300,15 @@ export class LuaTransformer { const symbol = this.checker.getSymbolAtLocation(statement.name); const hasExports = symbol !== undefined && this.checker.getExportsOfModule(symbol).length > 0; - const isFirstDeclaration = symbol !== undefined - && symbol.declarations[0] === statement - // TS allows an empty namespace before a class of the same name - && symbol.declarations.findIndex(d => ts.isClassLike(d)) === -1; + + // This is NOT the first declaration if: + // - declared as a module before this (ignore interfaces with same name) + // - declared as a class or function at all (TS requires these to be before module, unless module is empty) + const isFirstDeclaration = + symbol === undefined + || (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 + && statement === symbol.declarations.find(ts.isModuleDeclaration)); + if (isFirstDeclaration) { const isExported = (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; if (isExported && this.currentNamespace) { diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index c02f052de..6da420d9e 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -63,3 +63,13 @@ test("Access this in module", () => { const code = `return M.bar();`; expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); }); + +test("Module merged with interface", () => { + const header = ` + interface Foo {} + module Foo { + export function bar() { return "foobar"; } + }`; + const code = `return Foo.bar();`; + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); +}); From 27ae2a83afc9c4ebb7cd00769e1d8bc2c53a1b98 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Apr 2019 20:09:10 +0200 Subject: [PATCH 059/764] Enabled strict config (#515) * Fixed strict issues everywhere except transformer * Strict fixes and interface changes * More fixes, addressed PR comments * Fixed some more undefined errors * fixes for last compile errors (#518) * Fixed tests failing * Ran prettier on build_lualib.ts * Fixed jest ignoring diagnostics * Cleaned up throws * Changed non-null expression to explicit undefined check * Addressed PR feedback * Test appveyor settings * Revert appveyor changes * Fix master's strict violations * revert jest config changes * strict tests * Fixed strict test issues * Fixed prettier, added lint step to pretest * Test util method with undefined typeguard --- .travis.yml | 1 - appveyor.yml | 4 +- build_lualib.ts | 5 +- package.json | 2 +- src/CommandLineParser.ts | 6 +- src/Compiler.ts | 33 +- src/Decorator.ts | 9 +- src/LuaAST.ts | 29 +- src/LuaLib.ts | 5 +- src/LuaPrinter.ts | 29 +- src/LuaTransformer.ts | 909 ++++++++++++++++++++------------ src/LuaTranspiler.ts | 8 +- src/TSHelper.ts | 54 +- src/TSTLErrors.ts | 30 ++ test/compiler/project.spec.ts | 2 +- test/tsconfig.json | 3 + test/types/fengari.d.ts | 345 ++++++++++++ test/unit/expressions.spec.ts | 40 +- test/unit/loops.spec.ts | 4 +- test/unit/lualib/lualib.spec.ts | 17 +- test/unit/math.spec.ts | 3 +- test/unit/require.spec.ts | 11 +- test/unit/sourcemaps.spec.ts | 9 +- test/unit/spreadElement.spec.ts | 4 +- test/unit/tshelper.spec.ts | 65 ++- test/util.ts | 13 +- tsconfig.json | 3 +- 27 files changed, 1155 insertions(+), 488 deletions(-) create mode 100644 test/types/fengari.d.ts diff --git a/.travis.yml b/.travis.yml index 79fcbeed8..209eed141 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ node_js: - stable script: - - npm run lint - npm run build - npm test -- --coverage after_success: npx codecov diff --git a/appveyor.yml b/appveyor.yml index 078fad304..89c37dbc4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,9 @@ environment: nodejs_version: "8" +# Do not build feature branch with open Pull Requests +skip_branch_with_pr: true + # Cache dependencies cache: - node_modules @@ -19,7 +22,6 @@ test_script: - node --version - npm --version # run tests - - npm run lint - npm run build - npm test diff --git a/build_lualib.ts b/build_lualib.ts index be376fef6..18fb24bf7 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -27,5 +27,8 @@ if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } -const bundle = luaLib.loadFeatures(Object.keys(LuaLibFeature).map(lib => LuaLibFeature[lib])); +const features = Object.keys(LuaLibFeature).map( + lib => LuaLibFeature[lib as keyof typeof LuaLibFeature], +); +const bundle = luaLib.loadFeatures(features); fs.writeFileSync(bundlePath, bundle); diff --git a/package.json b/package.json index 1f15d68ea..3c063871b 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "scripts": { "build": "tsc -p tsconfig.json && npm run build-lualib", "build-lualib": "ts-node ./build_lualib.ts", - "pretest": "ts-node --transpile-only ./build_lualib.ts", + "pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index 50a1fa738..b0b552e15 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -228,7 +228,7 @@ export function parseTsConfigString( } function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult { - const result = {}; + const result: { [key: string]: string | boolean } = {}; for (let i = 0; i < args.length; i++) { if (args[i].startsWith("--")) { const argumentName = args[i].substr(2); @@ -245,7 +245,7 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL } } else if (args[i].startsWith("-")) { const argument = args[i].substr(1); - let argumentName: string; + let argumentName: string | undefined; for (const key in optionDeclarations) { if (optionDeclarations[key].aliases && optionDeclarations[key].aliases.indexOf(argument) >= 0) { argumentName = key; @@ -253,7 +253,7 @@ function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CL } } - if (argumentName) { + if (argumentName !== undefined) { const argumentResult = getArgumentValue(argumentName, i, args); if (argumentResult.isValid === true) { result[argumentName] = argumentResult.result; diff --git a/src/Compiler.ts b/src/Compiler.ts index 306182f34..a053b44e2 100644 --- a/src/Compiler.ts +++ b/src/Compiler.ts @@ -33,14 +33,9 @@ export function compile(argv: string[]): void { /* istanbul ignore next: tested in test/compiler/watchmode.spec with subproccess */ export function watchWithOptions(fileNames: string[], options: CompilerOptions): void { - let host: ts.WatchCompilerHost; - let config = false; - if (options.project) { - config = true; - host = ts.createWatchCompilerHost(options.project, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram); - } else { - host = ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram); - } + const host = options.project !== undefined + ? ts.createWatchCompilerHost(options.project, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram) + : ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram); let fullRecompile = true; host.afterProgramCreate = program => { @@ -71,7 +66,7 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions): } const errorDiagnostic: ts.Diagnostic = { - category: undefined, + category: ts.DiagnosticCategory.Error, code: 6194, file: undefined, length: 0, @@ -82,10 +77,13 @@ export function watchWithOptions(fileNames: string[], options: CompilerOptions): errorDiagnostic.messageText = "Found Errors. Watching for file changes."; errorDiagnostic.code = 6193; } - host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions()); + + if (host.onWatchStatusChange) { + host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions()); + } }; - if (config) { + if (options.project !== undefined) { ts.createWatchProgram( host as ts.WatchCompilerHostOfConfigFile ); @@ -118,8 +116,8 @@ export function createStringCompilerProgram( ): ts.Program { const compilerHost = { directoryExists: () => true, - fileExists: (fileName): boolean => true, - getCanonicalFileName: fileName => fileName, + fileExists: () => true, + getCanonicalFileName: (fileName: string) => fileName, getCurrentDirectory: () => "", getDefaultLibFileName: ts.getDefaultLibFileName, getDirectories: () => [], @@ -156,7 +154,7 @@ export function createStringCompilerProgram( useCaseSensitiveFileNames: () => false, // Don't write output - writeFile: (name, text, writeByteOrderMark) => undefined, + writeFile: () => undefined, }; const filePaths = typeof input === "string" ? [filePath] : Object.keys(input); return ts.createProgram(filePaths, options, compilerHost); @@ -182,5 +180,10 @@ export function transpileString( const transpiler = new LuaTranspiler(program); - return transpiler.transpileSourceFile(program.getSourceFile(filePath)); + const sourceFile = program.getSourceFile(filePath); + if (sourceFile !== undefined) { + return transpiler.transpileSourceFile(sourceFile); + } else { + throw new Error(`Could not find file ${filePath} in created program.`); + } } diff --git a/src/Decorator.ts b/src/Decorator.ts index 73ac39ea7..7ee84190f 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -3,7 +3,7 @@ export class Decorator { return this.getDecoratorKind(decoratorKindString) !== undefined; } - public static getDecoratorKind(decoratorKindString: string): DecoratorKind { + public static getDecoratorKind(decoratorKindString: string): DecoratorKind | undefined { switch (decoratorKindString.toLowerCase()) { case "extension": return DecoratorKind.Extension; @@ -36,7 +36,12 @@ export class Decorator { public args: string[]; constructor(name: string, args: string[]) { - this.kind = Decorator.getDecoratorKind(name); + const kind = Decorator.getDecoratorKind(name); + if (kind === undefined) { + throw new Error(`Failed to parse decorator '${name}'`); + } + + this.kind = kind; this.args = args; } } diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 3ef1f8612..6925fc885 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -109,6 +109,10 @@ export interface Node extends TextRange { } export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node { + if (tsOriginal === undefined) { + return {kind, parent}; + } + const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { return {kind, parent, line: sourcePosition.line, column: sourcePosition.column}; @@ -128,7 +132,11 @@ export function setNodePosition(node: T, position: TextRange): T return node; } -export function setNodeOriginal(node: T, tsOriginal: ts.Node): T { +export function setNodeOriginal(node: T | undefined, tsOriginal: ts.Node): T | undefined { + if (node === undefined) { + return undefined; + } + const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { setNodePosition(node, sourcePosition); @@ -172,14 +180,14 @@ export function getOriginalPos(node: Node): TextRange { export interface Block extends Node { kind: SyntaxKind.Block; - statements?: Statement[]; + statements: Statement[]; } export function isBlock(node: Node): node is Block { return node.kind === SyntaxKind.Block; } -export function createBlock(statements?: Statement[], tsOriginal?: ts.Node, parent?: Node): Block { +export function createBlock(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): Block { const block = createNode(SyntaxKind.Block, tsOriginal, parent) as Block; setParent(statements, block); block.statements = statements; @@ -192,14 +200,14 @@ export interface Statement extends Node { export interface DoStatement extends Statement { kind: SyntaxKind.DoStatement; - statements?: Statement[]; + statements: Statement[]; } export function isDoStatement(node: Node): node is DoStatement { return node.kind === SyntaxKind.DoStatement; } -export function createDoStatement(statements?: Statement[], tsOriginal?: ts.Node, parent?: Node): DoStatement { +export function createDoStatement(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): DoStatement { const statement = createNode(SyntaxKind.DoStatement, tsOriginal, parent) as DoStatement; setParent(statements, statement); statement.statements = statements; @@ -257,7 +265,7 @@ export function isAssignmentStatement(node: Node): node is AssignmentStatement { export function createAssignmentStatement( left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[], - right: Expression | Expression[], + right?: Expression | Expression[], tsOriginal?: ts.Node, parent?: Node ): AssignmentStatement @@ -273,7 +281,7 @@ export function createAssignmentStatement( if (Array.isArray(right)) { statement.right = right; } else { - statement.right = [right]; + statement.right = right ? [right] : []; } return statement; } @@ -878,18 +886,19 @@ export function isFunctionDefinition(statement: VariableDeclarationStatement | A : statement is FunctionDefinition { return statement.left.length === 1 - && statement.right + && statement.right !== undefined && statement.right.length === 1 && isFunctionExpression(statement.right[0]); } export type InlineFunctionExpression = FunctionExpression & { - body: { statements: [ReturnStatement]; }; + body: { statements: [ReturnStatement & { expressions: Expression[] }]; }; }; export function isInlineFunctionExpression(expression: FunctionExpression) : expression is InlineFunctionExpression { - return expression.body.statements + return expression.body.statements !== undefined && expression.body.statements.length === 1 && isReturnStatement(expression.body.statements[0]) + && (expression.body.statements[0] as ReturnStatement).expressions !== undefined && (expression.flags & FunctionExpressionFlags.Inline) !== 0; } diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 5b259f66b..2d1c5c134 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -67,8 +67,9 @@ export class LuaLib { function load(feature: LuaLibFeature): void { if (!loadedFeatures.has(feature)) { loadedFeatures.add(feature); - if (luaLibDependencies[feature]) { - luaLibDependencies[feature].forEach(load); + const dependencies = luaLibDependencies[feature]; + if (dependencies) { + dependencies.forEach(load); } const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); result += fs.readFileSync(featureFile).toString() + "\n"; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 3d6af0049..118ae789b 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -43,14 +43,14 @@ export class LuaPrinter { private options: CompilerOptions; private currentIndent: string; - private sourceFile: string; + private sourceFile = ""; public constructor(options: CompilerOptions) { this.options = options; this.currentIndent = ""; } - public print(block: tstl.Block, luaLibFeatures?: Set, sourceFile?: string): [string, string] { + public print(block: tstl.Block, luaLibFeatures?: Set, sourceFile = ""): [string, string] { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { if (luaLibFeatures === undefined) { @@ -113,7 +113,7 @@ export class LuaPrinter { private printImplementation( block: tstl.Block, luaLibFeatures?: Set, - sourceFile?: string): SourceNode { + sourceFile = ""): SourceNode { let header = ""; @@ -162,13 +162,15 @@ export class LuaPrinter { private createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { const originalPos = tstl.getOriginalPos(node); - return originalPos !== undefined + return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks) - : new SourceNode(undefined, undefined, this.sourceFile, chunks); + // tslint:disable-next-line:no-null-keyword + : new SourceNode(null, null, this.sourceFile, chunks); } private concatNodes(...chunks: SourceChunk[]): SourceNode { - return new SourceNode(undefined, undefined, this.sourceFile, chunks); + // tslint:disable-next-line:no-null-keyword + return new SourceNode(null, null, this.sourceFile, chunks); } private printBlock(block: tstl.Block): SourceNode { @@ -616,19 +618,26 @@ export class LuaPrinter { private printCallExpression(expression: tstl.CallExpression): SourceNode { const chunks = []; - const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e))); - chunks.push(this.printExpression(expression.expression), "(", ...parameterChunks, ")"); + const parameterChunks = expression.params !== undefined + ? expression.params.map(e => this.printExpression(e)) + : []; + + chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")"); return this.concatNodes(...chunks); } private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { const prefix = this.printExpression(expression.prefixExpression); - const parameterChunks = this.joinChunks(", ", expression.params.map(e => this.printExpression(e))); + + const parameterChunks = expression.params !== undefined + ? expression.params.map(e => this.printExpression(e)) + : []; + const name = this.printIdentifier(expression.name); - return this.concatNodes(prefix, ":", name, "(", ...parameterChunks, ")"); + return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"); } private printIdentifier(expression: tstl.Identifier): SourceNode { diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ccb629938..7a3226625 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -44,26 +44,28 @@ export class LuaTransformer { ]); private isStrict = true; + private luaTarget: LuaTarget; private checker: ts.TypeChecker; protected options: CompilerOptions; protected program: ts.Program; - private isModule: boolean; + private isModule = false; private currentSourceFile?: ts.SourceFile; - private currentNamespace: ts.ModuleDeclaration; - private classStack: ts.ClassLikeDeclaration[]; + private currentNamespace: ts.ModuleDeclaration | undefined; + private classStack: ts.ClassLikeDeclaration[] = []; - private scopeStack: Scope[]; - private genVarCounter: number; + private scopeStack: Scope[] = []; + private genVarCounter = 0; - private luaLibFeatureSet: Set; + private luaLibFeatureSet = new Set(); - private symbolInfo: Map; - private symbolIds: Map; - private genSymbolIdCounter: number; + private symbolInfo = new Map(); + private symbolIds = new Map(); + + private genSymbolIdCounter = 0; private readonly typeValidationCache: Map> = new Map>(); @@ -71,17 +73,18 @@ export class LuaTransformer { this.checker = program.getTypeChecker(); this.options = options; this.program = program; - this.isStrict = this.options.alwaysStrict || (this.options.strict && this.options.alwaysStrict !== false) || - (this.isModule && this.options.target && this.options.target >= ts.ScriptTarget.ES2015); + this.isStrict = this.options.alwaysStrict !== undefined + || (this.options.strict !== undefined && this.options.alwaysStrict !== false) + || (this.isModule + && this.options.target !== undefined + && this.options.target >= ts.ScriptTarget.ES2015); - if (!this.options.luaTarget) { - this.options.luaTarget = LuaTarget.LuaJIT; - } + this.luaTarget = options.luaTarget || LuaTarget.LuaJIT; this.setupState(); } - public setupState(): void { + private setupState(): void { this.genVarCounter = 0; this.currentSourceFile = undefined; this.isModule = false; @@ -108,7 +111,9 @@ export class LuaTransformer { throw TSTLErrors.InvalidJsonFileContent(node); } - statements.push(tstl.createReturnStatement([this.transformExpression(statement.expression)])); + statements.push(tstl.createReturnStatement( + this.filterUndefined([this.transformExpression(statement.expression)])) + ); } else { this.pushScope(ScopeType.File, node); @@ -171,7 +176,7 @@ export class LuaTransformer { case ts.SyntaxKind.ExpressionStatement: return this.transformExpressionStatement(node as ts.ExpressionStatement); case ts.SyntaxKind.ReturnStatement: - return this.transformReturn(node as ts.ReturnStatement); + return this.transformReturnStatement(node as ts.ReturnStatement); case ts.SyntaxKind.IfStatement: return this.transformIfStatement(node as ts.IfStatement); case ts.SyntaxKind.WhileStatement: @@ -204,10 +209,10 @@ export class LuaTransformer { } /** Converts an array of ts.Statements into an array of tstl.Statements */ - public transformStatements(statements: ts.Statement[] | ReadonlyArray): tstl.Statement[] { + private transformStatements(statements: ts.Statement[] | ReadonlyArray): tstl.Statement[] { const tstlStatements: tstl.Statement[] = []; (statements as ts.Statement[]).forEach(statement => { - tstlStatements.push(...this.statementVisitResultToStatementArray(this.transformStatement(statement))); + tstlStatements.push(...this.statementVisitResultToArray(this.transformStatement(statement))); }); return tstlStatements; } @@ -219,7 +224,7 @@ export class LuaTransformer { return tstl.createBlock(statements, block); } - public transformBlockAsDoStatement(block: ts.Block): tstl.DoStatement { + public transformBlockAsDoStatement(block: ts.Block): StatementVisitResult { this.pushScope(ScopeType.Block, block); const statements = this.performHoisting(this.transformStatements(block.statements)); this.popScope(); @@ -228,6 +233,10 @@ export class LuaTransformer { public transformExportDeclaration(statement: ts.ExportDeclaration): StatementVisitResult { if (statement.moduleSpecifier === undefined) { + if (statement.exportClause === undefined) { + throw TSTLErrors.InvalidExportDeclaration(statement); + } + const result = []; for (const exportElement of statement.exportClause.elements) { result.push( @@ -242,8 +251,9 @@ export class LuaTransformer { if (statement.exportClause) { if (statement.exportClause.elements.some(e => - (e.name && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) - || (e.propertyName && e.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword)) + (e.name !== undefined && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) + || (e.propertyName !== undefined + && e.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword)) ) { throw TSTLErrors.UnsupportedDefaultExport(statement); } @@ -278,7 +288,7 @@ export class LuaTransformer { } // Wrap this in a DoStatement to prevent polluting the scope. - return tstl.createDoStatement(result, statement); + return tstl.createDoStatement(this.filterUndefined(result), statement); } else { const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); const tempModuleIdentifier = tstl.createIdentifier("__TSTL_export"); @@ -327,6 +337,10 @@ export class LuaTransformer { } const imports = statement.importClause.namedBindings; + if (imports === undefined) { + throw TSTLErrors.UnsupportedImportType(statement.importClause); + } + const type = this.checker.getTypeAtLocation(imports); const shouldResolve = !tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.NoResolution); const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); @@ -379,14 +393,12 @@ export class LuaTransformer { ); result.push(requireStatement); return result; - } else { - throw TSTLErrors.UnsupportedImportType(imports); } } private createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { const modulePathString = resolveModule - ? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), "")) + ? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), ""), moduleSpecifier) : moduleSpecifier.text; const modulePath = tstl.createStringLiteral(modulePathString); return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath]); @@ -395,7 +407,7 @@ export class LuaTransformer { public transformClassDeclaration( statement: ts.ClassLikeDeclaration, nameOverride?: tstl.Identifier - ): tstl.Statement[] + ): StatementVisitResult { this.classStack.push(statement); @@ -403,14 +415,20 @@ export class LuaTransformer { throw TSTLErrors.MissingClassName(statement); } - let className = nameOverride !== undefined - ? nameOverride - : this.transformIdentifier(statement.name); + let className: tstl.Identifier; + if (nameOverride !== undefined) { + className = nameOverride; + } else if (statement.name !== undefined) { + className = this.transformIdentifier(statement.name); + } else { + throw TSTLErrors.MissingClassName(statement); + } const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); // Find out if this class is extension of existing class - const isExtension = decorators.has(DecoratorKind.Extension); + const extensionDirective = decorators.get(DecoratorKind.Extension); + const isExtension = extensionDirective !== undefined; const isMetaExtension = decorators.has(DecoratorKind.MetaExtension); @@ -469,8 +487,8 @@ export class LuaTransformer { result.push(assignDebugCallIndex); } - if (isExtension) { - const extensionNameArg = decorators.get(DecoratorKind.Extension).args[0]; + if (extensionDirective !== undefined) { + const extensionNameArg = extensionDirective.args[0]; if (extensionNameArg) { className = tstl.createIdentifier(extensionNameArg); } else if (extendsType) { @@ -487,9 +505,11 @@ export class LuaTransformer { result.push(...classCreationMethods); } else { for (const f of instanceFields) { - const fieldName = this.transformPropertyName(f.name); + const fieldName = this.expectExpression(this.transformPropertyName(f.name)); - const value = this.transformExpression(f.initializer); + const value = f.initializer !== undefined + ? this.transformExpression(f.initializer) + : undefined; // className["fieldName"] const classField = tstl.createTableIndexExpression( @@ -509,15 +529,22 @@ export class LuaTransformer { .filter(n => ts.isConstructorDeclaration(n) && n.body)[0] as ts.ConstructorDeclaration; if (constructor) { // Add constructor plus initialization of instance fields - result.push(this.transformConstructor(constructor, className, instanceFields, statement)); + const constructorResult = this.transformConstructorDeclaration( + constructor, + className, + instanceFields, + statement + ); + result.push(...this.statementVisitResultToArray(constructorResult)); } else if (!extendsType) { // Generate a constructor if none was defined in a base class - result.push(this.transformConstructor( + const constructorResult = this.transformConstructorDeclaration( ts.createConstructor([], [], [], ts.createBlock([], true)), className, instanceFields, statement - )); + ); + result.push(...this.statementVisitResultToArray(constructorResult)); } else if (instanceFields.length > 0 || statement.members.some(m => tsHelper.isGetAccessorOverride(m, statement, this.checker))) { @@ -529,7 +556,7 @@ export class LuaTransformer { const superCall = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createTableIndexExpression( - this.transformSuperKeyword(ts.createSuper()), + this.expectExpression(this.transformSuperKeyword(ts.createSuper())), tstl.createStringLiteral("____constructor") ), [this.createSelfIdentifier(), tstl.createDotsLiteral()] @@ -553,23 +580,26 @@ export class LuaTransformer { // Transform get accessors statement.members.filter(ts.isGetAccessor).forEach(getAccessor => { - result.push(this.transformGetAccessorDeclaration(getAccessor, className, statement)); + const transformResult = this.transformGetAccessorDeclaration(getAccessor, className, statement); + result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform set accessors statement.members.filter(ts.isSetAccessor).forEach(setAccessor => { - result.push(this.transformSetAccessorDeclaration(setAccessor, className, statement)); + const transformResult = this.transformSetAccessorDeclaration(setAccessor, className, statement); + result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform methods statement.members.filter(ts.isMethodDeclaration).forEach(method => { - result.push(this.transformMethodDeclaration(method, className, isExtension || isMetaExtension)); + const methodResult = this.transformMethodDeclaration(method, className, isExtension || isMetaExtension); + result.push(...this.statementVisitResultToArray(methodResult)); }); // Add static declarations for (const field of staticFields) { - const fieldName = this.transformPropertyName(field.name); - const value = this.transformExpression(field.initializer); + const fieldName = this.expectExpression(this.transformPropertyName(field.name)); + const value = field.initializer ? this.transformExpression(field.initializer) : undefined; const classField = tstl.createTableIndexExpression( tstl.cloneIdentifier(className), @@ -592,7 +622,7 @@ export class LuaTransformer { public createClassCreationMethods( statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, - extendsType: ts.Type + extendsType?: ts.Type ): tstl.Statement[] { const result: tstl.Statement[] = []; @@ -756,6 +786,10 @@ export class LuaTransformer { if (extendsType) { const extendedTypeNode = tsHelper.getExtendedTypeNode(statement, this.checker); + if (extendedTypeNode === undefined) { + throw TSTLErrors.UndefinedTypeNode(statement); + } + const baseName = ts.isIdentifier(extendedTypeNode.expression) ? this.transformIdentifier(extendedTypeNode.expression) // Skip adding '____exports' : this.transformExpression(extendedTypeNode.expression); @@ -910,7 +944,7 @@ export class LuaTransformer { return result; } - public transformClassInstanceFields( + private transformClassInstanceFields( classDeclarataion: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): tstl.Statement[] @@ -919,9 +953,9 @@ export class LuaTransformer { for (const f of instanceFields) { // Get identifier - const fieldName = this.transformPropertyName(f.name); + const fieldName = this.expectExpression(this.transformPropertyName(f.name)); - const value = this.transformExpression(f.initializer); + const value = f.initializer ? this.transformExpression(f.initializer) : undefined; // self[fieldName] const selfIndex = tstl.createTableIndexExpression(this.createSelfIdentifier(), fieldName); @@ -932,14 +966,17 @@ export class LuaTransformer { statements.push(assignClassField); } - const getOverrides = classDeclarataion.members.filter( - m => tsHelper.isGetAccessorOverride(m, classDeclarataion, this.checker) - ); + const getOverrides = classDeclarataion.members.filter(m => + tsHelper.isGetAccessorOverride(m, classDeclarataion, this.checker) + ) as ts.GetAccessorDeclaration[]; + for (const getter of getOverrides) { + const getterName = this.expectExpression(this.transformPropertyName(getter.name)); + const resetGetter = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("rawset"), - [this.createSelfIdentifier(), this.transformPropertyName(getter.name), tstl.createNilLiteral()] + [this.createSelfIdentifier(), getterName, tstl.createNilLiteral()] ) ); statements.push(resetGetter); @@ -948,7 +985,7 @@ export class LuaTransformer { return statements; } - public createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { + private createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { return tstl.createTableIndexExpression( tstl.createTableIndexExpression( tstl.cloneIdentifier(className), @@ -958,12 +995,12 @@ export class LuaTransformer { ); } - public transformConstructor( + public transformConstructorDeclaration( statement: ts.ConstructorDeclaration, className: tstl.Identifier, instanceFields: ts.PropertyDeclaration[], classDeclaration: ts.ClassLikeDeclaration - ): tstl.AssignmentStatement + ): StatementVisitResult { // Don't transform methods without body (overload declarations) if (!statement.body) { @@ -986,7 +1023,8 @@ export class LuaTransformer { ), tstl.createBinaryExpression( declarationName, - this.transformExpression(declaration.initializer), tstl.SyntaxKind.OrOperator + this.expectExpression(this.transformExpression(declaration.initializer)), + tstl.SyntaxKind.OrOperator ) ); bodyStatements.push(assignement); @@ -1034,8 +1072,12 @@ export class LuaTransformer { getAccessor: ts.GetAccessorDeclaration, className: tstl.Identifier, classDeclaration: ts.ClassLikeDeclaration - ): tstl.AssignmentStatement + ): StatementVisitResult { + if (getAccessor.body === undefined) { + return undefined; + } + const name = this.transformIdentifier(getAccessor.name as ts.Identifier); const [body] = this.transformFunctionBody(getAccessor.parameters, getAccessor.body); @@ -1067,8 +1109,12 @@ export class LuaTransformer { setAccessor: ts.SetAccessorDeclaration, className: tstl.Identifier, classDeclaration: ts.ClassLikeDeclaration - ): tstl.AssignmentStatement + ): StatementVisitResult { + if (setAccessor.body === undefined) { + return undefined; + } + const name = this.transformIdentifier(setAccessor.name as ts.Identifier); const [params, dot, restParam] = this.transformParameters(setAccessor.parameters, this.createSelfIdentifier()); @@ -1102,14 +1148,14 @@ export class LuaTransformer { node: ts.MethodDeclaration, className: tstl.Identifier, noPrototype: boolean - ): tstl.AssignmentStatement + ): StatementVisitResult { // Don't transform methods without body (overload declarations) if (!node.body) { return undefined; } - let methodName = this.transformPropertyName(node.name); + let methodName = this.expectExpression(this.transformPropertyName(node.name)); if (tstl.isStringLiteral(methodName) && methodName.value === "toString") { methodName = tstl.createStringLiteral("__tostring", node.name); } @@ -1143,16 +1189,16 @@ export class LuaTransformer { ); } - public transformParameters(parameters: ts.NodeArray, context?: tstl.Identifier): - [tstl.Identifier[], tstl.DotsLiteral, tstl.Identifier | undefined] { + private transformParameters(parameters: ts.NodeArray, context?: tstl.Identifier): + [tstl.Identifier[], tstl.DotsLiteral | undefined, tstl.Identifier | undefined] { // Build parameter string const paramNames: tstl.Identifier[] = []; if (context) { paramNames.push(context); } - let restParamName: tstl.Identifier; - let dotsLiteral: tstl.DotsLiteral; + let restParamName: tstl.Identifier | undefined; + let dotsLiteral: tstl.DotsLiteral | undefined; let identifierIndex = 0; // Only push parameter name to paramName array if it isn't a spread parameter @@ -1180,7 +1226,7 @@ export class LuaTransformer { return [paramNames, dotsLiteral, restParamName]; } - public transformFunctionBody( + private transformFunctionBody( parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier @@ -1222,9 +1268,9 @@ export class LuaTransformer { return [headerStatements.concat(bodyStatements), scope]; } - public transformParameterDefaultValueDeclaration(declaration: ts.ParameterDeclaration): tstl.Statement { + private transformParameterDefaultValueDeclaration(declaration: ts.ParameterDeclaration): tstl.Statement { const parameterName = this.transformIdentifier(declaration.name as ts.Identifier); - const parameterValue = this.transformExpression(declaration.initializer); + const parameterValue = declaration.initializer ? this.transformExpression(declaration.initializer) : undefined; const assignment = tstl.createAssignmentStatement(parameterName, parameterValue); const nilCondition = tstl.createBinaryExpression( @@ -1253,7 +1299,9 @@ export class LuaTransformer { const propertyName = isObjectBindingPattern ? element.propertyName : ts.createNumericLiteral(String(index + 1)); - propertyAccessStack.push(propertyName); + if (propertyName !== undefined) { + propertyAccessStack.push(propertyName); + } yield* this.transformBindingPattern(element.name, table, propertyAccessStack); } else { // Disallow ellipsis destructure @@ -1266,7 +1314,10 @@ export class LuaTransformer { const propertyName = ts.isPropertyName(property) ? this.transformPropertyName(property) : this.transformNumericLiteral(property); - tableExpression = tstl.createTableIndexExpression(tableExpression, propertyName); + tableExpression = tstl.createTableIndexExpression( + tableExpression, + this.expectExpression(propertyName) + ); }); // The identifier of the new variable const variableName = this.transformIdentifier(element.name as ts.Identifier); @@ -1278,7 +1329,9 @@ export class LuaTransformer { : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); if (element.initializer) { const defaultExpression = tstl.createBinaryExpression(expression, - this.transformExpression(element.initializer), tstl.SyntaxKind.OrOperator); + this.expectExpression(this.transformExpression(element.initializer)), + tstl.SyntaxKind.OrOperator + ); yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, defaultExpression); } else { yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, expression); @@ -1289,7 +1342,7 @@ export class LuaTransformer { propertyAccessStack.pop(); } - public transformModuleDeclaration(statement: ts.ModuleDeclaration): tstl.Statement[] { + public transformModuleDeclaration(statement: ts.ModuleDeclaration): StatementVisitResult { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); // If phantom namespace elide the declaration and return the body if (decorators.has(DecoratorKind.Phantom) && statement.body && ts.isModuleBlock(statement.body)) { @@ -1373,7 +1426,7 @@ export class LuaTransformer { let statements = ts.isModuleBlock(statement.body) ? this.transformStatements(statement.body.statements) : this.transformModuleDeclaration(statement.body); - statements = this.performHoisting(statements); + statements = this.performHoisting(this.statementVisitResultToArray(statements)); this.popScope(); result.push(tstl.createDoStatement(statements)); } @@ -1402,7 +1455,7 @@ export class LuaTransformer { } for (const enumMember of this.computeEnumMembers(enumDeclaration)) { - const memberName = this.transformPropertyName(enumMember.name); + const memberName = this.expectExpression(this.transformPropertyName(enumMember.name)); if (membersOnly) { if (tstl.isIdentifier(memberName)) { result.push(...this.createLocalOrExportedOrGlobalDeclaration( @@ -1430,15 +1483,15 @@ export class LuaTransformer { return result; } - public computeEnumMembers(node: ts.EnumDeclaration): + protected computeEnumMembers(node: ts.EnumDeclaration): Array<{name: ts.PropertyName, value: tstl.Expression, original: ts.Node}> { let numericValue = 0; let hasStringInitializers = false; - const valueMap = new Map(); + const valueMap = new Map(); return node.members.map(member => { - let valueExpression: tstl.Expression; + let valueExpression: ExpressionVisitResult; if (member.initializer) { if (ts.isNumericLiteral(member.initializer)) { @@ -1455,7 +1508,7 @@ export class LuaTransformer { { if (ts.isIdentifier(member.initializer)) { const [isEnumMember, originalName] = tsHelper.isEnumMember(node, member.initializer); - if (isEnumMember) { + if (isEnumMember === true && originalName !== undefined) { valueExpression = valueMap.get(originalName); } else { valueExpression = this.transformExpression(member.initializer); @@ -1480,7 +1533,7 @@ export class LuaTransformer { const enumMember = { name: member.name, original: member, - value: valueExpression, + value: this.expectExpression(valueExpression), }; return enumMember; @@ -1636,6 +1689,10 @@ export class LuaTransformer { : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); + if (functionDeclaration.name === undefined) { + throw TSTLErrors.MissingFunctionName(functionDeclaration); + } + const name = this.transformIdentifier(functionDeclaration.name); const [body, functionScope] = functionDeclaration.asteriskToken ? this.transformGeneratorFunction( @@ -1666,18 +1723,17 @@ export class LuaTransformer { return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); } - public transformTypeAliasDeclaration(statement: ts.TypeAliasDeclaration): undefined { + public transformTypeAliasDeclaration(statement: ts.TypeAliasDeclaration): StatementVisitResult { return undefined; } - public transformInterfaceDeclaration(statement: ts.InterfaceDeclaration): undefined { + public transformInterfaceDeclaration(statement: ts.InterfaceDeclaration): StatementVisitResult { return undefined; } - public transformVariableDeclaration(statement: ts.VariableDeclaration) - : tstl.Statement[] + public transformVariableDeclaration(statement: ts.VariableDeclaration): StatementVisitResult { - if (statement.initializer) { + if (statement.initializer && statement.type) { // Validate assignment const initializerType = this.checker.getTypeAtLocation(statement.initializer); const varType = this.checker.getTypeFromTypeNode(statement.type); @@ -1705,13 +1761,15 @@ export class LuaTransformer { || statement.name.elements.some(elem => !ts.isBindingElement(elem) || !ts.isIdentifier(elem.name))) { const statements = []; let table: tstl.Identifier; - if (ts.isIdentifier(statement.initializer)) { + if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { table = this.transformIdentifier(statement.initializer); } else { // Contain the expression in a temporary variable table = tstl.createAnnonymousIdentifier(); - statements.push(tstl.createVariableDeclarationStatement( - table, this.transformExpression(statement.initializer))); + if (statement.initializer) { + statements.push(tstl.createVariableDeclarationStatement( + table, this.transformExpression(statement.initializer))); + } } statements.push(...this.transformBindingPattern(statement.name, table)); return statements; @@ -1723,7 +1781,9 @@ export class LuaTransformer { } const vars = statement.name.elements.length > 0 - ? statement.name.elements.map(e => this.transformArrayBindingElement(e)) + ? this.filterUndefinedAndCast( + statement.name.elements.map(e => this.transformArrayBindingElement(e)), + tstl.isIdentifier) : tstl.createAnnonymousIdentifier(statement.name); // Don't unpack TupleReturn decorated functions @@ -1737,7 +1797,7 @@ export class LuaTransformer { } else { // local vars = this.transpileDestructingAssignmentValue(node.initializer); const initializer = this.createUnpackCall( - this.transformExpression(statement.initializer), + this.expectExpression(this.transformExpression(statement.initializer)), statement.initializer ); return this.createLocalOrExportedOrGlobalDeclaration(vars, initializer, statement); @@ -1752,18 +1812,20 @@ export class LuaTransformer { } } - public transformVariableStatement(statement: ts.VariableStatement): tstl.Statement[] { + public transformVariableStatement(statement: ts.VariableStatement): StatementVisitResult { const result: tstl.Statement[] = []; - statement.declarationList.declarations - .forEach(declaration => result.push(...this.transformVariableDeclaration(declaration))); + statement.declarationList.declarations.forEach(declaration => { + const declarationStatements = this.transformVariableDeclaration(declaration); + result.push(...this.statementVisitResultToArray(declarationStatements)); + }); return result; } - public transformExpressionStatement(statement: ts.ExpressionStatement | ts.Expression): tstl.Statement { + public transformExpressionStatement(statement: ts.ExpressionStatement | ts.Expression): StatementVisitResult { const expression = ts.isExpressionStatement(statement) ? statement.expression : statement; if (ts.isBinaryExpression(expression)) { const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(expression.operatorToken.kind); - if (isCompound) { + if (isCompound && replacementOperator) { // +=, -=, etc... return this.transformCompoundAssignmentStatement( expression, @@ -1777,9 +1839,9 @@ export class LuaTransformer { return this.transformAssignmentStatement(expression); } else if (expression.operatorToken.kind === ts.SyntaxKind.CommaToken) { - const lhs = this.transformExpressionStatement(expression.left); - const rhs = this.transformExpressionStatement(expression.right); - return tstl.createDoStatement([lhs, rhs], expression); + const lhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)); + const rhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.right)); + return tstl.createDoStatement([...lhs, ...rhs], expression); } } else if ( @@ -1829,16 +1891,22 @@ export class LuaTransformer { ); } - return tstl.createExpressionStatement(this.transformExpression(expression)); + return tstl.createExpressionStatement(this.expectExpression(this.transformExpression(expression))); } - public transformYield(expression: ts.YieldExpression): tstl.Expression { + public transformYield(expression: ts.YieldExpression): ExpressionVisitResult { return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("yield")), - expression.expression?[this.transformExpression(expression.expression)]:[], expression); + tstl.createTableIndexExpression( + tstl.createIdentifier("coroutine"), + tstl.createStringLiteral("yield")), + expression.expression + ? [this.expectExpression(this.transformExpression(expression.expression))] + : [], + expression + ); } - public transformReturn(statement: ts.ReturnStatement): tstl.Statement { + public transformReturnStatement(statement: ts.ReturnStatement): StatementVisitResult { if (statement.expression) { const returnType = tsHelper.getContainingFunctionReturnType(statement, this.checker); if (returnType) { @@ -1849,8 +1917,9 @@ export class LuaTransformer { // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(statement.expression)) { // If return expression is an array literal, leave out brackets. - return tstl.createReturnStatement(statement.expression.elements - .map(elem => this.transformExpression(elem))); + return tstl.createReturnStatement(this.filterUndefined( + statement.expression.elements.map(elem => this.transformExpression(elem)) + )); } const expressionType = this.checker.getTypeAtLocation(statement.expression); @@ -1859,28 +1928,30 @@ export class LuaTransformer { { // If return expression is an array-type and not another TupleReturn call, unpack it const expression = this.createUnpackCall( - this.transformExpression(statement.expression), + this.expectExpression(this.transformExpression(statement.expression)), statement.expression ); return tstl.createReturnStatement([expression]); } } - return tstl.createReturnStatement([this.transformExpression(statement.expression)], statement); + const returnExpressions = [this.expectExpression(this.transformExpression(statement.expression))]; + return tstl.createReturnStatement(returnExpressions, statement); } else { // Empty return return tstl.createReturnStatement([], statement); } } - public transformIfStatement(statement: ts.IfStatement): tstl.IfStatement { + public transformIfStatement(statement: ts.IfStatement): StatementVisitResult { this.pushScope(ScopeType.Conditional, statement.thenStatement); - const condition = this.transformExpression(statement.expression); + const condition = this.expectExpression(this.transformExpression(statement.expression)); const statements = this.performHoisting(this.transformBlockOrStatement(statement.thenStatement)); this.popScope(); const ifBlock = tstl.createBlock(statements); if (statement.elseStatement) { if (ts.isIfStatement(statement.elseStatement)) { - return tstl.createIfStatement(condition, ifBlock, this.transformIfStatement(statement.elseStatement)); + const elseStatement = this.transformIfStatement(statement.elseStatement) as tstl.IfStatement; + return tstl.createIfStatement(condition, ifBlock, elseStatement); } else { this.pushScope(ScopeType.Conditional, statement.elseStatement); const elseStatements = this.performHoisting(this.transformBlockOrStatement(statement.elseStatement)); @@ -1892,36 +1963,40 @@ export class LuaTransformer { return tstl.createIfStatement(condition, ifBlock); } - public transformWhileStatement(statement: ts.WhileStatement): tstl.WhileStatement { + public transformWhileStatement(statement: ts.WhileStatement): StatementVisitResult { return tstl.createWhileStatement( tstl.createBlock(this.transformLoopBody(statement)), - this.transformExpression(statement.expression), + this.expectExpression(this.transformExpression(statement.expression)), statement ); } - public transformDoStatement(statement: ts.DoStatement): tstl.RepeatStatement { + public transformDoStatement(statement: ts.DoStatement): StatementVisitResult { return tstl.createRepeatStatement( tstl.createBlock(this.transformLoopBody(statement)), tstl.createUnaryExpression( - tstl.createParenthesizedExpression(this.transformExpression(statement.expression)), + tstl.createParenthesizedExpression( + this.expectExpression(this.transformExpression(statement.expression)) + ), tstl.SyntaxKind.NotOperator ), statement ); } - public transformForStatement(statement: ts.ForStatement): tstl.DoStatement { + public transformForStatement(statement: ts.ForStatement): StatementVisitResult { const result: tstl.Statement[] = []; if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { for (const variableDeclaration of statement.initializer.declarations) { // local initializer = value - result.push(...this.transformVariableDeclaration(variableDeclaration)); + const declarations = this.transformVariableDeclaration(variableDeclaration); + result.push(...this.statementVisitResultToArray(declarations)); } } else { - result.push(this.transformExpressionStatement(statement.initializer)); + const initializerStatements = this.transformExpressionStatement(statement.initializer); + result.push(...this.statementVisitResultToArray(initializerStatements)); } } @@ -1933,11 +2008,12 @@ export class LuaTransformer { const body: tstl.Statement[] = this.transformLoopBody(statement); if (statement.incrementor) { - body.push(this.transformExpressionStatement(statement.incrementor)); + const bodyStatements = this.transformExpressionStatement(statement.incrementor); + body.push(...this.statementVisitResultToArray(bodyStatements)); } // while (condition) do ... end - result.push(tstl.createWhileStatement(tstl.createBlock(body), condition)); + result.push(tstl.createWhileStatement(tstl.createBlock(body), this.expectExpression(condition))); return tstl.createDoStatement(result, statement); } @@ -1949,9 +2025,15 @@ export class LuaTransformer { if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { expression = this.createUnpackCall(expression, initializer); } - // we can safely assume that for vars are not exported and therefore declarationstatenents - return tstl.createVariableDeclarationStatement( - (variableDeclarations[0] as tstl.VariableDeclarationStatement).left, expression); + + const variableStatements = this.statementVisitResultToArray(variableDeclarations); + if (variableStatements[0]) { + // we can safely assume that for vars are not exported and therefore declarationstatenents + return tstl.createVariableDeclarationStatement( + (variableStatements[0] as tstl.VariableDeclarationStatement).left, expression); + } else { + throw TSTLErrors.MissingForOfVariables(initializer); + } } else { // Assignment to existing variable @@ -1990,11 +2072,11 @@ export class LuaTransformer { public transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { return ts.isBlock(statement) ? this.transformStatements(statement.statements) - : this.statementVisitResultToStatementArray(this.transformStatement(statement)); + : this.statementVisitResultToArray(this.transformStatement(statement)); } public transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const arrayExpression = this.transformExpression(statement.expression); + const arrayExpression = this.expectExpression(this.transformExpression(statement.expression)); // Arrays use numeric for loop (performs better than ipairs) const indexVariable = tstl.createIdentifier("____TS_index"); @@ -2034,7 +2116,7 @@ export class LuaTransformer { } public transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const luaIterator = this.transformExpression(statement.expression); + const luaIterator = this.expectExpression(this.transformExpression(statement.expression)); const type = this.checker.getTypeAtLocation(statement.expression); const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); if (tupleReturn) { @@ -2046,7 +2128,9 @@ export class LuaTransformer { if (ts.isArrayBindingPattern(initializerVariable)) { return tstl.createForInStatement( block, - initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), + this.filterUndefinedAndCast( + initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), + tstl.isIdentifier), [luaIterator] ); @@ -2105,7 +2189,7 @@ export class LuaTransformer { } public transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const iterable = this.transformExpression(statement.expression); + const iterable = this.expectExpression(this.transformExpression(statement.expression)); if (ts.isVariableDeclarationList(statement.initializer) && ts.isIdentifier(statement.initializer.declarations[0].name)) { // Single variable declared in for loop @@ -2160,7 +2244,8 @@ export class LuaTransformer { // Transpile expression const pairsIdentifier = tstl.createIdentifier("pairs"); - const expression = tstl.createCallExpression(pairsIdentifier, [this.transformExpression(statement.expression)]); + const expression = this.expectExpression(this.transformExpression(statement.expression)); + const pairsCall = tstl.createCallExpression(pairsIdentifier, [expression]); if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program)) { throw TSTLErrors.ForbiddenForIn(statement); @@ -2171,14 +2256,14 @@ export class LuaTransformer { return tstl.createForInStatement( body, [this.transformIdentifier(identifier)], - [expression], + [pairsCall], statement ); } public transformSwitchStatement(statement: ts.SwitchStatement): StatementVisitResult { - if (this.options.luaTarget === LuaTarget.Lua51) { - throw TSTLErrors.UnsupportedForTarget("Switch statements", this.options.luaTarget, statement); + if (this.luaTarget === LuaTarget.Lua51) { + throw TSTLErrors.UnsupportedForTarget("Switch statements", this.luaTarget, statement); } this.pushScope(ScopeType.Switch, statement); @@ -2199,7 +2284,7 @@ export class LuaTransformer { // If the clause condition holds, go to the correct label const condition = tstl.createBinaryExpression( switchVariable, - this.transformExpression(clause.expression), + this.expectExpression(this.transformExpression(clause.expression)), tstl.SyntaxKind.EqualityOperator ); const goto = tstl.createGotoStatement(`${switchName}_case_${i}`); @@ -2234,6 +2319,11 @@ export class LuaTransformer { public transformBreakStatement(breakStatement: ts.BreakStatement): StatementVisitResult { const breakableScope = this.findScope(ScopeType.Loop | ScopeType.Switch); + + if (breakableScope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + if (breakableScope.type === ScopeType.Switch) { return tstl.createGotoStatement(`____TS_switch${breakableScope.id}_end`); } else { @@ -2280,11 +2370,18 @@ export class LuaTransformer { } public transformThrowStatement(statement: ts.ThrowStatement): StatementVisitResult { + if (statement.expression === undefined) { + throw TSTLErrors.InvalidThrowExpression(statement); + } + const type = this.checker.getTypeAtLocation(statement.expression); if (tsHelper.isStringType(type)) { const error = tstl.createIdentifier("error"); return tstl.createExpressionStatement( - tstl.createCallExpression(error, [this.transformExpression(statement.expression)]), + tstl.createCallExpression( + error, + this.filterUndefined([this.transformExpression(statement.expression)]) + ), statement ); } else { @@ -2293,11 +2390,15 @@ export class LuaTransformer { } public transformContinueStatement(statement: ts.ContinueStatement): StatementVisitResult { - if (this.options.luaTarget === LuaTarget.Lua51) { - throw TSTLErrors.UnsupportedForTarget("Continue statement", this.options.luaTarget, statement); + if (this.luaTarget === LuaTarget.Lua51) { + throw TSTLErrors.UnsupportedForTarget("Continue statement", this.luaTarget, statement); } const scope = this.findScope(ScopeType.Loop); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + scope.loopContinued = true; return tstl.createGotoStatement( `__continue${scope.id}`, @@ -2388,7 +2489,7 @@ export class LuaTransformer { right: tstl.Expression, operator: ts.BinaryOperator, tsOriginal: ts.Node - ): tstl.Expression + ): ExpressionVisitResult { switch (operator) { case ts.SyntaxKind.AmpersandToken: @@ -2408,11 +2509,11 @@ export class LuaTransformer { } } - public transformBinaryExpression(expression: ts.BinaryExpression): tstl.Expression { + public transformBinaryExpression(expression: ts.BinaryExpression): ExpressionVisitResult { // Check if this is an assignment token, then handle accordingly const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(expression.operatorToken.kind); - if (isCompound) { + if (isCompound && replacementOperator) { return this.transformCompoundAssignmentExpression( expression, expression.left, @@ -2422,8 +2523,8 @@ export class LuaTransformer { ); } - const lhs = this.transformExpression(expression.left); - const rhs = this.transformExpression(expression.right); + const lhs = this.expectExpression(this.transformExpression(expression.left)); + const rhs = this.expectExpression(this.transformExpression(expression.right)); // Transpile operators switch (expression.operatorToken.kind) { @@ -2475,7 +2576,7 @@ export class LuaTransformer { case ts.SyntaxKind.CommaToken: return this.createImmediatelyInvokedFunctionExpression( - [this.transformExpressionStatement(expression.left)], + this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)), rhs, expression ); @@ -2485,7 +2586,7 @@ export class LuaTransformer { } } - public transformAssignment(lhs: ts.Expression, right: tstl.Expression): tstl.Statement { + private transformAssignment(lhs: ts.Expression, right?: tstl.Expression): tstl.Statement { return tstl.createAssignmentStatement( this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression, right, @@ -2493,7 +2594,7 @@ export class LuaTransformer { ); } - public transformAssignmentStatement(expression: ts.BinaryExpression): tstl.Statement { + public transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { // Validate assignment const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); @@ -2505,8 +2606,8 @@ export class LuaTransformer { this.transformLuaLibFunction( LuaLibFeature.ArraySetLength, expression, - this.transformExpression(expression.left.expression), - this.transformExpression(expression.right) + this.expectExpression(this.transformExpression(expression.left.expression)), + this.expectExpression(this.transformExpression(expression.right)) ) ); } @@ -2518,11 +2619,14 @@ export class LuaTransformer { : [tstl.createAnnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.length > 0 - ? expression.right.elements.map(e => this.transformExpression(e)) - : [tstl.createNilLiteral()]; + if (expression.right.elements.length > 0) { + const visitResults = expression.right.elements.map(e => this.transformExpression(e)); + right = this.filterUndefined(visitResults); + } else { + right = [tstl.createNilLiteral()]; + } } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = [this.transformExpression(expression.right)]; + right = this.filterUndefined([this.transformExpression(expression.right)]); } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } @@ -2550,8 +2654,8 @@ export class LuaTransformer { return this.transformLuaLibFunction( LuaLibFeature.ArraySetLength, expression, - this.transformExpression(expression.left.expression), - this.transformExpression(expression.right) + this.expectExpression(this.transformExpression(expression.left.expression)), + this.expectExpression(this.transformExpression(expression.right)) ); } @@ -2564,10 +2668,10 @@ export class LuaTransformer { let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { right = expression.right.elements.length > 0 - ? expression.right.elements.map(e => this.transformExpression(e)) + ? this.filterUndefined(expression.right.elements.map(e => this.transformExpression(e))) : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = [this.transformExpression(expression.right)]; + right = this.filterUndefined([this.transformExpression(expression.right)]); } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } @@ -2605,7 +2709,7 @@ export class LuaTransformer { indexExpression = tstl.createStringLiteral(expression.left.name.text); } else { // Element access - indexExpression = this.transformExpression(expression.left.argumentExpression); + indexExpression = this.expectExpression(this.transformExpression(expression.left.argumentExpression)); const argType = this.checker.getTypeAtLocation(expression.left.expression); if (tsHelper.isArrayType(argType, this.checker, this.program)) { // Array access needs a +1 @@ -2613,12 +2717,16 @@ export class LuaTransformer { } } const args = [objExpression, indexExpression, this.transformExpression(expression.right)]; - return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), args); + return tstl.createCallExpression( + tstl.createParenthesizedExpression(iife), + this.filterUndefined(args), + expression + ); } else { // Simple assignment // (function() ${left} = ${right}; return ${left} end)() - const left = this.transformExpression(expression.left); + const left = this.expectExpression(this.transformExpression(expression.left)); const right = this.transformExpression(expression.right); return this.createImmediatelyInvokedFunctionExpression( [this.transformAssignment(expression.left, right)], @@ -2637,20 +2745,25 @@ export class LuaTransformer { ): tstl.CallExpression { const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; - let right = this.transformExpression(rhs); + let right = this.expectExpression(this.transformExpression(rhs)); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, this.checker, this.program ); - if (hasEffects) { + if (hasEffects && objExpression && indexExpression) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __TS_obj, __TS_index = ${objExpression}, ${indexExpression}; const obj = tstl.createIdentifier("____TS_obj"); const index = tstl.createIdentifier("____TS_index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( - [obj, index], [this.transformExpression(objExpression), this.transformExpression(indexExpression)]); + [obj, index], + this.filterUndefined( + [this.transformExpression(objExpression), + this.transformExpression(indexExpression)] + ) + ); const accessExpression = tstl.createTableIndexExpression(obj, index); const tmp = tstl.createIdentifier("____TS_tmp"); @@ -2789,8 +2902,13 @@ export class LuaTransformer { const className = expression.name !== undefined ? this.transformIdentifier(expression.name) : tstl.createAnnonymousIdentifier(); + const classDeclaration = this.transformClassDeclaration(expression, className); - return this.createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); + return this.createImmediatelyInvokedFunctionExpression( + this.statementVisitResultToArray(classDeclaration), + className, + expression + ); } public transformCompoundAssignmentStatement( @@ -2801,21 +2919,26 @@ export class LuaTransformer { ): tstl.Statement { const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; - const right = this.transformExpression(rhs); + const right = this.expectExpression(this.transformExpression(rhs)); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, this.checker, this.program ); - if (hasEffects) { + if (hasEffects && objExpression && indexExpression) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __TS_obj, __TS_index = ${objExpression}, ${indexExpression}; // ____TS_obj[____TS_index] = ____TS_obj[____TS_index] ${replacementOperator} ${right}; const obj = tstl.createIdentifier("____TS_obj"); const index = tstl.createIdentifier("____TS_index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( - [obj, index], [this.transformExpression(objExpression), this.transformExpression(indexExpression)]); + [obj, index], + this.filterUndefined([ + this.transformExpression(objExpression), + this.transformExpression(indexExpression), + ]) + ); const accessExpression = tstl.createTableIndexExpression(obj, index); const operatorExpression = this.transformBinaryOperation( accessExpression, @@ -2862,9 +2985,9 @@ export class LuaTransformer { operator: tstl.UnaryBitwiseOperator ): ExpressionVisitResult { - switch (this.options.luaTarget) { + switch (this.luaTarget) { case LuaTarget.Lua51: - throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.options.luaTarget, node); + throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); case LuaTarget.Lua52: return this.transformUnaryBitLibOperation(node, expression, operator, "bit32"); @@ -2915,16 +3038,16 @@ export class LuaTransformer { ); } - public transformBinaryBitOperation( + private transformBinaryBitOperation( node: ts.Node, left: tstl.Expression, right: tstl.Expression, operator: ts.BinaryOperator ): ExpressionVisitResult { - switch (this.options.luaTarget) { + switch (this.luaTarget) { case LuaTarget.Lua51: - throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.options.luaTarget, node); + throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); case LuaTarget.Lua52: return this.transformBinaryBitLibOperation(node, left, right, operator, "bit32"); @@ -2938,10 +3061,10 @@ export class LuaTransformer { } } - public transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { - const condition = this.transformExpression(expression.condition); - const val1 = this.transformExpression(expression.whenTrue); - const val2 = this.transformExpression(expression.whenFalse); + private transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { + const condition = this.expectExpression(this.transformExpression(expression.condition)); + const val1 = this.expectExpression(this.transformExpression(expression.whenTrue)); + const val2 = this.expectExpression(this.transformExpression(expression.whenFalse)); const val1Function = this.wrapInFunctionCall(val1); const val2Function = this.wrapInFunctionCall(val2); @@ -2952,14 +3075,14 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression); } - public transformConditionalExpression(expression: ts.ConditionalExpression): tstl.Expression { - const isStrict = this.options.strict || this.options.strictNullChecks; + private transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { + const isStrict = this.options.strict === true || this.options.strictNullChecks === true; if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { - return this.transformProtectedConditionalExpression(expression); + return this.transformProtectedConditionalExpression(expression); } - const condition = this.transformExpression(expression.condition); - const val1 = this.transformExpression(expression.whenTrue); - const val2 = this.transformExpression(expression.whenFalse); + const condition = this.expectExpression(this.transformExpression(expression.condition)); + const val1 = this.expectExpression(this.transformExpression(expression.whenTrue)); + const val2 = this.expectExpression(this.transformExpression(expression.whenFalse)); // condition and v1 or v2 const conditionAnd = tstl.createBinaryExpression(condition, val1, tstl.SyntaxKind.AndOperator); @@ -2971,7 +3094,7 @@ export class LuaTransformer { ); } - public transformPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): tstl.Expression { + public transformPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): ExpressionVisitResult { switch (expression.operator) { case ts.SyntaxKind.PlusPlusToken: return this.transformCompoundAssignmentExpression( @@ -2996,7 +3119,7 @@ export class LuaTransformer { } } - public transformPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): tstl.Expression { + public transformPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): ExpressionVisitResult { switch (expression.operator) { case ts.SyntaxKind.PlusPlusToken: return this.transformCompoundAssignmentExpression( @@ -3021,20 +3144,20 @@ export class LuaTransformer { case ts.SyntaxKind.MinusToken: return tstl.createUnaryExpression( - this.transformExpression(expression.operand), + this.expectExpression(this.transformExpression(expression.operand)), tstl.SyntaxKind.NegationOperator ); case ts.SyntaxKind.ExclamationToken: return tstl.createUnaryExpression( - this.transformExpression(expression.operand), + this.expectExpression(this.transformExpression(expression.operand)), tstl.SyntaxKind.NotOperator ); case ts.SyntaxKind.TildeToken: return this.transformUnaryBitOperation( expression, - this.transformExpression(expression.operand), + this.expectExpression(this.transformExpression(expression.operand)), tstl.SyntaxKind.BitwiseNotOperator ); @@ -3043,29 +3166,32 @@ export class LuaTransformer { } } - public transformArrayLiteral(node: ts.ArrayLiteralExpression): tstl.TableExpression { + public transformArrayLiteral(node: ts.ArrayLiteralExpression): ExpressionVisitResult { const values: tstl.TableFieldExpression[] = []; node.elements.forEach(child => { - values.push(tstl.createTableFieldExpression(this.transformExpression(child), undefined, child)); + const childExpression = this.transformExpression(child); + if (childExpression) { + values.push(tstl.createTableFieldExpression(childExpression, undefined, child)); + } }); return tstl.createTableExpression(values, node); } - public transformObjectLiteral(node: ts.ObjectLiteralExpression): tstl.TableExpression { + public transformObjectLiteral(node: ts.ObjectLiteralExpression): ExpressionVisitResult { const properties: tstl.TableFieldExpression[] = []; // Add all property assignments node.properties.forEach(element => { - const name = this.transformPropertyName(element.name); + const name = element.name ? this.transformPropertyName(element.name) : undefined; if (ts.isPropertyAssignment(element)) { - const expression = this.transformExpression(element.initializer); + const expression = this.expectExpression(this.transformExpression(element.initializer)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { const identifier = this.transformIdentifier(element.name); properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { - const expression = this.transformFunctionExpression(element); + const expression = this.expectExpression(this.transformFunctionExpression(element)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, node); @@ -3075,7 +3201,7 @@ export class LuaTransformer { return tstl.createTableExpression(properties, node); } - public transformDeleteExpression(expression: ts.DeleteExpression): tstl.CallExpression { + public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { const lhs = this.transformExpression(expression.expression) as tstl.IdentifierOrTableIndexExpression; const assignment = tstl.createAssignmentStatement( lhs, @@ -3110,6 +3236,11 @@ export class LuaTransformer { const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters(node.parameters, context); let flags = tstl.FunctionExpressionFlags.None; + + if (node.body === undefined) { + throw TSTLErrors.UnsupportedFunctionWithoutBody(node); + } + let body: ts.Block; if (ts.isBlock(node.body)) { body = node.body; @@ -3117,9 +3248,12 @@ export class LuaTransformer { const returnExpression = ts.createReturn(node.body); body = ts.createBlock([returnExpression]); returnExpression.parent = body; - body.parent = node.body.parent; + if (node.body) { + body.parent = node.body.parent; + } flags |= tstl.FunctionExpressionFlags.Inline; } + const [transformedBody] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); return tstl.createFunctionExpression( @@ -3132,11 +3266,11 @@ export class LuaTransformer { ); } - public transformNewExpression(node: ts.NewExpression): tstl.CallExpression { - const name = this.transformExpression(node.expression); - const sig = this.checker.getResolvedSignature(node); + public transformNewExpression(node: ts.NewExpression): ExpressionVisitResult { + const name = this.expectExpression(this.transformExpression(node.expression)); + const signature = this.checker.getResolvedSignature(node); const params = node.arguments - ? this.transformArguments(node.arguments, sig) + ? this.transformArguments(node.arguments, signature) : [tstl.createBooleanLiteral(true)]; const type = this.checker.getTypeAtLocation(node); @@ -3150,12 +3284,13 @@ export class LuaTransformer { if (classDecorators.has(DecoratorKind.CustomConstructor)) { const customDecorator = classDecorators.get(DecoratorKind.CustomConstructor); - if (!customDecorator.args[0]) { + if (customDecorator === undefined || customDecorator.args[0] === undefined) { throw TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, node); } + return tstl.createCallExpression( tstl.createIdentifier(customDecorator.args[0]), - this.transformArguments(node.arguments), + this.transformArguments(node.arguments || []), node ); } @@ -3167,26 +3302,35 @@ export class LuaTransformer { ); } - public transformParenthesizedExpression(expression: ts.ParenthesizedExpression): tstl.Expression { + public transformParenthesizedExpression(expression: ts.ParenthesizedExpression): ExpressionVisitResult { if (ts.isAssertionExpression(expression.expression)) { // Strip parenthesis from casts return this.transformExpression(expression.expression); } return tstl.createParenthesizedExpression( - this.transformExpression(expression.expression), + this.expectExpression(this.transformExpression(expression.expression)), expression ); } - public transformSuperKeyword(expression: ts.SuperExpression): tstl.Expression { + public transformSuperKeyword(expression: ts.SuperExpression): ExpressionVisitResult { const classDeclaration = this.classStack[this.classStack.length - 1]; - const extendsExpression = tsHelper.getExtendedTypeNode(classDeclaration, this.checker).expression; + const typeNode = tsHelper.getExtendedTypeNode(classDeclaration, this.checker); + if (typeNode === undefined) { + throw TSTLErrors.UnknownSuperType(expression); + } + + const extendsExpression = typeNode.expression; let baseClassName: tstl.IdentifierOrTableIndexExpression; if (ts.isIdentifier(extendsExpression)) { // Use "baseClassName" if base is a simple identifier baseClassName = this.transformIdentifier(extendsExpression); } else { + if (classDeclaration.name === undefined) { + throw TSTLErrors.MissingClassName(expression); + } + // Use "className.____super" if the base is not a simple identifier baseClassName = tstl.createTableIndexExpression( this.transformIdentifier(classDeclaration.name), @@ -3197,7 +3341,7 @@ export class LuaTransformer { return tstl.createTableIndexExpression(baseClassName, tstl.createStringLiteral("prototype")); } - public transformCallExpression(node: ts.CallExpression): tstl.Expression { + public transformCallExpression(node: ts.CallExpression): ExpressionVisitResult { // Check for calls on primitives to override let parameters: tstl.Expression[] = []; @@ -3212,12 +3356,12 @@ export class LuaTransformer { && !isInSpread && returnValueIsUsed; if (ts.isPropertyAccessExpression(node.expression)) { - const result = this.transformPropertyCall(node); + const result = this.expectExpression(this.transformPropertyCall(node)); return wrapResult ? this.wrapInTable(result) : result; } if (ts.isElementAccessExpression(node.expression)) { - const result = this.transformElementCall(node); + const result = this.expectExpression(this.transformElementCall(node)); return wrapResult ? this.wrapInTable(result) : result; } @@ -3229,14 +3373,14 @@ export class LuaTransformer { return tstl.createCallExpression( tstl.createTableIndexExpression( - this.transformSuperKeyword(ts.createSuper()), + this.expectExpression(this.transformSuperKeyword(ts.createSuper())), tstl.createStringLiteral("____constructor") ), parameters ); } - const callPath = this.transformExpression(node.expression); + const callPath = this.expectExpression(this.transformExpression(node.expression)); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) @@ -3256,7 +3400,7 @@ export class LuaTransformer { return wrapResult ? this.wrapInTable(callExpression) : callExpression; } - public transformPropertyCall(node: ts.CallExpression): tstl.Expression { + public transformPropertyCall(node: ts.CallExpression): ExpressionVisitResult { let parameters: tstl.Expression[] = []; // Check if call is actually on a property access expression @@ -3279,7 +3423,7 @@ export class LuaTransformer { if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) { return tstl.createCallExpression( - this.transformStringExpression(node.expression.name), + this.expectExpression(this.transformStringExpression(node.expression.name)), this.transformArguments(node.arguments, signature), node ); @@ -3318,26 +3462,35 @@ export class LuaTransformer { if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) parameters = this.transformArguments(node.arguments, signature, ts.createThis()); - return tstl.createCallExpression(this.transformExpression(node.expression), parameters); + return tstl.createCallExpression( + this.expectExpression(this.transformExpression(node.expression)), + parameters + ); } else { // Replace last . with : here const name = node.expression.name.escapedText; if (name === "toString") { const toStringIdentifier = tstl.createIdentifier("tostring"); return tstl.createCallExpression( - toStringIdentifier, [this.transformExpression(node.expression.expression)], node); + toStringIdentifier, + this.filterUndefined([this.transformExpression(node.expression.expression)]), + node + ); } else if (name === "hasOwnProperty") { const expr = this.transformExpression(node.expression.expression); parameters = this.transformArguments(node.arguments, signature); const rawGetIdentifier = tstl.createIdentifier("rawget"); - const rawGetCall = tstl.createCallExpression(rawGetIdentifier, [expr, ...parameters]); + const rawGetCall = tstl.createCallExpression( + rawGetIdentifier, + this.filterUndefined([expr, ...parameters]) + ); return tstl.createParenthesizedExpression( tstl.createBinaryExpression( rawGetCall, tstl.createNilLiteral(), tstl.SyntaxKind.InequalityOperator, node) ); } else { const parameters = this.transformArguments(node.arguments, signature); - const table = this.transformExpression(node.expression.expression); + const table = this.expectExpression(this.transformExpression(node.expression.expression)); const signatureDeclaration = signature && signature.getDeclaration(); if (!signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) @@ -3362,7 +3515,7 @@ export class LuaTransformer { } } - public transformElementCall(node: ts.CallExpression): tstl.CallExpression { + public transformElementCall(node: ts.CallExpression): ExpressionVisitResult { if (!ts.isElementAccessExpression(node.expression)) { throw TSTLErrors.InvalidElementCall(node); } @@ -3375,7 +3528,7 @@ export class LuaTransformer { || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { // Pass left-side as context - const context = this.transformExpression(node.expression.expression); + const context = this.expectExpression(this.transformExpression(node.expression.expression)); if (tsHelper.isExpressionWithEvaluationEffect(node.expression.expression)) { // Inject context parameter if (node.arguments.length > 0) { @@ -3386,23 +3539,25 @@ export class LuaTransformer { // Cache left-side if it has effects //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() - const argument = this.transformExpression(node.expression.argumentExpression); + const argument = this.expectExpression(this.transformExpression(node.expression.argumentExpression)); const selfIdentifier = tstl.createIdentifier("____TS_self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); const callExpression = tstl.createCallExpression(index, parameters); return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); } else { - return tstl.createCallExpression(this.transformExpression(node.expression), [context, ...parameters]); + const expression = this.expectExpression(this.transformExpression(node.expression)); + return tstl.createCallExpression(expression, [context, ...parameters]); } } else { // No context - return tstl.createCallExpression(this.transformExpression(node.expression), parameters); + const expression = this.expectExpression(this.transformExpression(node.expression)); + return tstl.createCallExpression(expression, parameters); } } - public transformArguments( - params: ts.NodeArray, + private transformArguments( + params: ts.NodeArray | ts.Expression[], sig?: ts.Signature, context?: T ): tstl.Expression[] @@ -3411,7 +3566,7 @@ export class LuaTransformer { // Add context as first param if present if (context) { - parameters.push(this.transformExpression(context)); + parameters.push(this.expectExpression(this.transformExpression(context))); } if (sig && sig.parameters.length >= params.length) { @@ -3420,18 +3575,20 @@ export class LuaTransformer { const paramType = this.checker.getTypeAtLocation(param); const sigType = this.checker.getTypeAtLocation(sig.parameters[i].valueDeclaration); this.validateFunctionAssignment(param, paramType, sigType, sig.parameters[i].name); - parameters.push(this.transformExpression(param)); + + const transformedParam = this.transformExpression(param); + if (transformedParam) { + parameters.push(transformedParam); + } } } else { - params.forEach(param => { - parameters.push(this.transformExpression(param)); - }); + parameters.push(...this.filterUndefined(params.map(param => this.transformExpression(param)))); } return parameters; } - public transformPropertyAccessExpression(node: ts.PropertyAccessExpression): tstl.Expression { + public transformPropertyAccessExpression(node: ts.PropertyAccessExpression): ExpressionVisitResult { const property = node.name.text; // Check for primitive types to override @@ -3469,12 +3626,12 @@ export class LuaTransformer { } } - const callPath = this.transformExpression(node.expression); + const callPath = this.expectExpression(this.transformExpression(node.expression)); return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), node); } // Transpile a Math._ property - public transformMathExpression(identifier: ts.Identifier): tstl.Expression { + private transformMathExpression(identifier: ts.Identifier): tstl.Expression { const name = identifier.escapedText as string; switch (name) { case "PI": @@ -3497,7 +3654,7 @@ export class LuaTransformer { } // Transpile a Math._ property - public transformMathCallExpression(node: ts.CallExpression): tstl.Expression { + private transformMathCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); @@ -3575,53 +3732,57 @@ export class LuaTransformer { } // Transpile access of string properties, only supported properties are allowed - public transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { + private transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": - return tstl.createUnaryExpression( - this.transformExpression(node.expression), tstl.SyntaxKind.LengthOperator, node); + const expression = this.expectExpression(this.transformExpression(node.expression)); + return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: throw TSTLErrors.UnsupportedProperty("string", node.name.escapedText as string, node); } } // Transpile access of array properties, only supported properties are allowed - public transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { + private transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { switch (node.name.escapedText) { case "length": - return tstl.createUnaryExpression( - this.transformExpression(node.expression), tstl.SyntaxKind.LengthOperator, node); + const expression = this.expectExpression(this.transformExpression(node.expression)); + return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: return undefined; } } - public transformElementAccessExpression(node: ts.ElementAccessExpression): tstl.Expression { - const table = this.transformExpression(node.expression); - const index = this.transformExpression(node.argumentExpression); + public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { + const table = this.expectExpression(this.transformExpression(expression.expression)); + const index = this.expectExpression(this.transformExpression(expression.argumentExpression)); - const type = this.checker.getTypeAtLocation(node.expression); + const type = this.checker.getTypeAtLocation(expression.expression); if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum) - && ts.isStringLiteral(node.argumentExpression)) + && ts.isStringLiteral(expression.argumentExpression)) { - return this.transformConstEnumValue(type, node.argumentExpression.text, node); + return this.transformConstEnumValue(type, expression.argumentExpression.text, expression); } if (tsHelper.isArrayType(type, this.checker, this.program)) { - return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), node); + return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), expression); } else if (tsHelper.isStringType(type)) { return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")), [table, this.expressionPlusOne(index), this.expressionPlusOne(index)], - node + expression ); } else { - return tstl.createTableIndexExpression(table, index, node); + return tstl.createTableIndexExpression(table, index, expression); } } - private transformConstEnumValue(enumType: ts.EnumType, memberName: string, tsOriginal: ts.Node): tstl.Expression { + private transformConstEnumValue( + enumType: ts.EnumType, + memberName: string, + tsOriginal: ts.Node + ): ExpressionVisitResult { // Assumption: the enum only has one declaration const enumDeclaration = enumType.symbol.declarations.find(d => ts.isEnumDeclaration(d)) as ts.EnumDeclaration; const enumMember = enumDeclaration.members @@ -3631,7 +3792,7 @@ export class LuaTransformer { if (enumMember.initializer) { if (ts.isIdentifier(enumMember.initializer)) { const [isEnumMember, valueName] = tsHelper.isEnumMember(enumDeclaration, enumMember.initializer); - if (isEnumMember) { + if (isEnumMember && valueName) { if (ts.isIdentifier(valueName)) { return this.transformConstEnumValue(enumType, valueName.text, tsOriginal); } @@ -3660,11 +3821,11 @@ export class LuaTransformer { throw TSTLErrors.CouldNotFindEnumMember(enumDeclaration, memberName, tsOriginal); } - public transformStringCallExpression(node: ts.CallExpression): tstl.Expression { + private transformStringCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); + const caller = this.expectExpression(this.transformExpression(expression.expression)); const expressionName = expression.name.escapedText as string; switch (expressionName) { @@ -3698,7 +3859,8 @@ export class LuaTransformer { ); case "substr": if (node.arguments.length === 1) { - const arg1 = this.expressionPlusOne(this.transformExpression(node.arguments[0])); + const argument = this.expectExpression(this.transformExpression(node.arguments[0])); + const arg1 = this.expressionPlusOne(argument); return this.createStringCall("sub", node, caller, arg1); } else { const arg1 = params[0]; @@ -3763,7 +3925,7 @@ export class LuaTransformer { case "unpack": case "upper": // Allow lua's string instance methods - let stringVariable = this.transformExpression(expression.expression); + let stringVariable = this.expectExpression(this.transformExpression(expression.expression)); if (ts.isStringLiteral(expression.expression)) { // "foo":method() needs to be ("foo"):method() stringVariable = tstl.createParenthesizedExpression(stringVariable); @@ -3779,7 +3941,7 @@ export class LuaTransformer { } } - public createStringCall( + private createStringCall( methodName: string, tsOriginal: ts.Node, ...params: tstl.Expression[] @@ -3794,7 +3956,7 @@ export class LuaTransformer { } // Transpile a String._ property - public transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { + private transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { const identifierString = identifier.escapedText as string; switch (identifierString) { @@ -3806,14 +3968,14 @@ export class LuaTransformer { default: throw TSTLErrors.UnsupportedForTarget( `string property ${identifierString}`, - this.options.luaTarget, + this.luaTarget, identifier ); } } // Transpile an Object._ property - public transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { + private transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments); @@ -3834,13 +3996,13 @@ export class LuaTransformer { default: throw TSTLErrors.UnsupportedForTarget( `object property ${methodName}`, - this.options.luaTarget, + this.luaTarget, expression ); } } - public transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { + private transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const methodName = method.name.escapedText; const signature = this.checker.getResolvedSignature(expression); @@ -3922,7 +4084,7 @@ export class LuaTransformer { default: throw TSTLErrors.UnsupportedForTarget( `console property ${methodName}`, - this.options.luaTarget, + this.luaTarget, expression ); } @@ -3933,7 +4095,7 @@ export class LuaTransformer { } // Transpile a Symbol._ property - public transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { + private transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments, signature); @@ -3949,17 +4111,17 @@ export class LuaTransformer { default: throw TSTLErrors.UnsupportedForTarget( `symbol property ${methodName}`, - this.options.luaTarget, + this.luaTarget, expression ); } } - public transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { + private transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); + const caller = this.expectExpression(this.transformExpression(expression.expression)); const expressionName = expression.name.escapedText; switch (expressionName) { case "concat": @@ -4017,7 +4179,7 @@ export class LuaTransformer { } } - public transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { + private transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { @@ -4025,7 +4187,7 @@ export class LuaTransformer { } const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); + const caller = this.expectExpression(this.transformExpression(expression.expression)); const expressionName = expression.name.escapedText; switch (expressionName) { case "apply": @@ -4039,7 +4201,7 @@ export class LuaTransformer { } } - public transformArrayBindingElement(name: ts.ArrayBindingElement): tstl.Identifier { + public transformArrayBindingElement(name: ts.ArrayBindingElement): ExpressionVisitResult { if (ts.isOmittedExpression(name)) { return tstl.createIdentifier("__", name); } else if (ts.isIdentifier(name)) { @@ -4051,7 +4213,7 @@ export class LuaTransformer { } } - public transformAssertionExpression(node: ts.AssertionExpression): tstl.Expression { + public transformAssertionExpression(node: ts.AssertionExpression): ExpressionVisitResult { this.validateFunctionAssignment( node, this.checker.getTypeAtLocation(node.expression), @@ -4061,7 +4223,7 @@ export class LuaTransformer { } public transformTypeOfExpression(node: ts.TypeOfExpression): ExpressionVisitResult { - const expression = this.transformExpression(node.expression); + const expression = this.expectExpression(this.transformExpression(node.expression)); const typeFunctionIdentifier = tstl.createIdentifier("type"); const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [expression]); const tableString = tstl.createStringLiteral("table"); @@ -4080,7 +4242,7 @@ export class LuaTransformer { } public transformSpreadElement(expression: ts.SpreadElement): ExpressionVisitResult { - const innerExpression = this.transformExpression(expression.expression); + const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) { return innerExpression; } else { @@ -4088,33 +4250,33 @@ export class LuaTransformer { } } - public transformStringLiteral(literal: ts.StringLiteralLike): tstl.StringLiteral { + public transformStringLiteral(literal: ts.StringLiteralLike): ExpressionVisitResult { const text = tsHelper.escapeString(literal.text); return tstl.createStringLiteral(text, literal); } - public transformNumericLiteral(literal: ts.NumericLiteral): tstl.NumericLiteral { + public transformNumericLiteral(literal: ts.NumericLiteral): ExpressionVisitResult { const value = Number(literal.text); return tstl.createNumericLiteral(value, literal); } - public transformTrueKeyword(trueKeyword: ts.BooleanLiteral): tstl.BooleanLiteral { + public transformTrueKeyword(trueKeyword: ts.BooleanLiteral): ExpressionVisitResult { return tstl.createBooleanLiteral(true, trueKeyword); } - public transformFalseKeyword(falseKeyword: ts.BooleanLiteral): tstl.BooleanLiteral { + public transformFalseKeyword(falseKeyword: ts.BooleanLiteral): ExpressionVisitResult { return tstl.createBooleanLiteral(false, falseKeyword); } - public transformNullOrUndefinedKeyword(originalNode: ts.Node): tstl.NilLiteral { + public transformNullOrUndefinedKeyword(originalNode: ts.Node): ExpressionVisitResult { return tstl.createNilLiteral(originalNode); } - public transformThisKeyword(thisKeyword: ts.ThisExpression): tstl.Expression { + public transformThisKeyword(thisKeyword: ts.ThisExpression): ExpressionVisitResult { return this.createSelfIdentifier(thisKeyword); } - public transformTemplateExpression(expression: ts.TemplateExpression): tstl.Expression { + public transformTemplateExpression(expression: ts.TemplateExpression): ExpressionVisitResult { const parts: tstl.Expression[] = []; const head = tsHelper.escapeString(expression.head.text); @@ -4123,11 +4285,14 @@ export class LuaTransformer { } expression.templateSpans.forEach(span => { - parts.push(this.wrapInToStringForConcat(this.transformExpression(span.expression))); + const expression = this.transformExpression(span.expression); + if (expression !== undefined) { + parts.push(this.wrapInToStringForConcat(expression)); - const text = tsHelper.escapeString(span.literal.text); - if (text.length > 0) { - parts.push(tstl.createStringLiteral(text, span.literal)); + const text = tsHelper.escapeString(span.literal.text); + if (text.length > 0) { + parts.push(tstl.createStringLiteral(text, span.literal)); + } } }); @@ -4138,7 +4303,7 @@ export class LuaTransformer { ); } - public transformPropertyName(propertyName: ts.PropertyName): tstl.Expression { + public transformPropertyName(propertyName: ts.PropertyName): ExpressionVisitResult { if (ts.isComputedPropertyName(propertyName)) { return this.transformExpression(propertyName.expression); } else if (ts.isStringLiteral(propertyName)) { @@ -4151,7 +4316,7 @@ export class LuaTransformer { } } - public getIdentifierText(identifier: ts.Identifier): string { + private getIdentifierText(identifier: ts.Identifier): string { let escapedText = identifier.escapedText as string; const underScoreCharCode = "_".charCodeAt(0); if (escapedText.length >= 3 && escapedText.charCodeAt(0) === underScoreCharCode && @@ -4179,7 +4344,7 @@ export class LuaTransformer { return tstl.createIdentifier(escapedText, expression, symbolId); } - public transformIdentifierExpression(expression: ts.Identifier): tstl.IdentifierOrTableIndexExpression { + private transformIdentifierExpression(expression: ts.Identifier): tstl.IdentifierOrTableIndexExpression { const identifier = this.transformIdentifier(expression); if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); @@ -4187,7 +4352,7 @@ export class LuaTransformer { return identifier; } - public isIdentifierExported(identifier: tstl.Identifier): boolean { + private isIdentifierExported(identifier: tstl.Identifier): boolean { if (!this.isModule && !this.currentNamespace) { return false; } @@ -4198,12 +4363,21 @@ export class LuaTransformer { } const currentScope = this.currentNamespace ? this.currentNamespace : this.currentSourceFile; + if (currentScope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + const scopeSymbol = this.checker.getSymbolAtLocation(currentScope) ? this.checker.getSymbolAtLocation(currentScope) : this.checker.getTypeAtLocation(currentScope).getSymbol(); + if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { + return false; + } + const scopeSymbolExports = scopeSymbol.exports; + const it: Iterable = { - [Symbol.iterator]: () => scopeSymbol.exports.values(), // Why isn't ts.SymbolTable.values() iterable? + [Symbol.iterator]: () => scopeSymbolExports.values(), // Why isn't ts.SymbolTable.values() iterable? }; for (const symbol of it) { if (symbol === symbolInfo.symbol) { @@ -4213,14 +4387,14 @@ export class LuaTransformer { return false; } - public addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { + private addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); } return identifier; } - public createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { + private createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { const exportTable = this.currentNamespace ? this.transformIdentifier(this.currentNamespace.name as ts.Identifier) : this.createExportsIdentifier(); @@ -4230,9 +4404,9 @@ export class LuaTransformer { tstl.createStringLiteral(identifier.text)); } - public transformLuaLibFunction( + private transformLuaLibFunction( func: LuaLibFeature, - tsParent: ts.Expression, + tsParent?: ts.Expression, ...params: tstl.Expression[] ): tstl.CallExpression { @@ -4260,7 +4434,7 @@ export class LuaTransformer { } } - public importLuaLibFeature(feature: LuaLibFeature): void { + private importLuaLibFeature(feature: LuaLibFeature): void { // Add additional lib requirements if (feature === LuaLibFeature.Map || feature === LuaLibFeature.Set) { this.luaLibFeatureSet.add(LuaLibFeature.InstanceOf); @@ -4269,7 +4443,7 @@ export class LuaTransformer { this.luaLibFeatureSet.add(feature); } - public createImmediatelyInvokedFunctionExpression( + private createImmediatelyInvokedFunctionExpression( statements: tstl.Statement[], result: tstl.Expression | tstl.Expression[], tsOriginal: ts.Node @@ -4282,18 +4456,21 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); } - public createUnpackCall(expression: tstl.Expression, tsOriginal: ts.Node): tstl.Expression { - switch (this.options.luaTarget) { + private createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { + switch (this.luaTarget) { case LuaTarget.Lua51: case LuaTarget.LuaJIT: - return tstl.createCallExpression(tstl.createIdentifier("unpack"), [expression], tsOriginal); - + return tstl.createCallExpression( + tstl.createIdentifier("unpack"), + this.filterUndefined([expression]), + tsOriginal + ); case LuaTarget.Lua52: case LuaTarget.Lua53: default: return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("unpack")), - [expression], + this.filterUndefined([expression]), tsOriginal ); } @@ -4303,10 +4480,15 @@ export class LuaTransformer { if (relativePath.charAt(0) !== "." && this.options.baseUrl) { return path.resolve(this.options.baseUrl, relativePath); } + + if (this.currentSourceFile === undefined) { + throw TSTLErrors.MissingSourceFile(); + } + return path.resolve(path.dirname(this.currentSourceFile.fileName), relativePath); } - private getImportPath(relativePath: string): string { + private getImportPath(relativePath: string, node: ts.Node): string { const rootDir = this.options.rootDir ? path.resolve(this.options.rootDir) : path.resolve("."); const absoluteImportPath = path.format(path.parse(this.getAbsoluteImportPath(relativePath))); const absoluteRootDirPath = path.format(path.parse(rootDir)); @@ -4314,7 +4496,7 @@ export class LuaTransformer { return this.formatPathToLuaPath( absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); } else { - throw TSTLErrors.UnresolvableRequirePath(undefined, + throw TSTLErrors.UnresolvableRequirePath(node, `Cannot create require path. Module does not exist within --rootDir`, relativePath); } @@ -4415,6 +4597,10 @@ export class LuaTransformer { ? this.peekScope() : this.findScope(ScopeType.Function | ScopeType.File); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + if (!scope.variableDeclarations) { scope.variableDeclarations = []; } scope.variableDeclarations.push(declaration); } @@ -4431,8 +4617,12 @@ export class LuaTransformer { if (!this.options.noHoisting && functionDeclaration) { // Remember function definitions for hoisting later const functionSymbolId = (lhs as tstl.Identifier).symbolId; - if (functionSymbolId !== undefined) { - this.peekScope().functionDefinitions.get(functionSymbolId).definition = declaration || assignment; + const scope = this.peekScope(); + if (functionSymbolId && scope && scope.functionDefinitions) { + const definitions = scope.functionDefinitions.get(functionSymbolId); + if (definitions) { + definitions.definition = declaration || assignment; + } } } @@ -4440,8 +4630,10 @@ export class LuaTransformer { return [declaration, assignment]; } else if (declaration) { return [declaration]; - } else { + } else if (assignment) { return [assignment]; + } else { + return []; } } @@ -4490,14 +4682,19 @@ export class LuaTransformer { if ((ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode))) { // Recurse into arrays/tuples - const fromTypeReference = fromType as ts.TypeReference; - const toTypeReference = toType as ts.TypeReference; - const count = Math.min(fromTypeReference.typeArguments.length, toTypeReference.typeArguments.length); + const fromTypeArguments = (fromType as ts.TypeReference).typeArguments; + const toTypeArguments = (toType as ts.TypeReference).typeArguments; + + if (fromTypeArguments === undefined || toTypeArguments === undefined) { + return; + } + + const count = Math.min(fromTypeArguments.length, toTypeArguments.length); for (let i = 0; i < count; ++i) { this.validateFunctionAssignment( node, - fromTypeReference.typeArguments[i], - toTypeReference.typeArguments[i], + fromTypeArguments[i], + toTypeArguments[i], toName ); } @@ -4509,12 +4706,18 @@ export class LuaTransformer { { // Recurse into interfaces toType.symbol.members.forEach((toMember, memberName) => { - const fromMember = fromType.symbol.members.get(memberName); - if (fromMember) { - const toMemberType = this.checker.getTypeOfSymbolAtLocation(toMember, node); - const fromMemberType = this.checker.getTypeOfSymbolAtLocation(fromMember, node); - this.validateFunctionAssignment( - node, fromMemberType, toMemberType, toName ? `${toName}.${memberName}` : memberName.toString()); + if (fromType.symbol.members) { + const fromMember = fromType.symbol.members.get(memberName); + if (fromMember) { + const toMemberType = this.checker.getTypeOfSymbolAtLocation(toMember, node); + const fromMemberType = this.checker.getTypeOfSymbolAtLocation(fromMember, node); + this.validateFunctionAssignment( + node, fromMemberType, toMemberType, + toName + ? `${toName}.${memberName}` + : memberName.toString() + ); + } } }); } @@ -4553,7 +4756,7 @@ export class LuaTransformer { return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } - private getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId { + private getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { const symbol = this.checker.getSymbolAtLocation(identifier); let symbolId: number | undefined; if (symbol) { @@ -4574,12 +4777,14 @@ export class LuaTransformer { throw TSTLErrors.ReferencedBeforeDeclaration(identifier); } - } else { + } else if (symbolId !== undefined) { //Mark symbol as seen in all current scopes - this.scopeStack.forEach(s => { - if (!s.referencedSymbols) { s.referencedSymbols = new Set(); } - s.referencedSymbols.add(symbolId); - }); + for (const scope of this.scopeStack) { + if (!scope.referencedSymbols) { + scope.referencedSymbols = new Set(); + } + scope.referencedSymbols.add(symbolId); + } } } return symbolId; @@ -4617,18 +4822,25 @@ export class LuaTransformer { } if (scope.functionDefinitions) { + if (this.currentSourceFile === undefined) { + throw TSTLErrors.MissingSourceFile(); + } + for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { + if (functionDefinition.definition === undefined) { + throw TSTLErrors.UndefinedFunctionDefinition(functionSymbolId); + } + const { line, column } = tstl.getOriginalPos(functionDefinition.definition); - const definitionPos = ts.getPositionOfLineAndCharacter( - this.currentSourceFile, - line, - column); - if (functionSymbolId !== symbolId // Don't recurse into self - && declaration.pos < definitionPos // Ignore functions before symbol declaration - && functionDefinition.referencedSymbols.has(symbolId) - && this.shouldHoist(functionSymbolId, scope)) - { - return true; + if (line !== undefined && column !== undefined) { + const definitionPos = ts.getPositionOfLineAndCharacter(this.currentSourceFile, line, column); + if (functionSymbolId !== symbolId // Don't recurse into self + && declaration.pos < definitionPos // Ignore functions before symbol declaration + && functionDefinition.referencedSymbols.has(symbolId) + && this.shouldHoist(functionSymbolId, scope)) + { + return true; + } } } } @@ -4660,6 +4872,10 @@ export class LuaTransformer { const result = statements.slice(); const hoistedFunctions: Array = []; for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { + if (functionDefinition.definition === undefined) { + throw TSTLErrors.UndefinedFunctionDefinition(functionSymbolId); + } + if (this.shouldHoist(functionSymbolId, scope)) { const i = result.indexOf(functionDefinition.definition); result.splice(i, 1); @@ -4680,7 +4896,7 @@ export class LuaTransformer { const result = statements.slice(); const hoistedLocals: tstl.Identifier[] = []; for (const declaration of scope.variableDeclarations) { - const symbols = declaration.left.map(i => i.symbolId).filter(s => s !== undefined); + const symbols = this.filterUndefined(declaration.left.map(i => i.symbolId)); if (symbols.some(s => this.shouldHoist(s, scope))) { let assignment: tstl.AssignmentStatement | undefined; if (declaration.right) { @@ -4723,6 +4939,11 @@ export class LuaTransformer { protected popScope(): Scope { const scope = this.scopeStack.pop(); + + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + return scope; } @@ -4743,25 +4964,37 @@ export class LuaTransformer { return declaration; } - private statementVisitResultToStatementArray(visitResult: StatementVisitResult): tstl.Statement[] { + private statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { if (!Array.isArray(visitResult)) { if (visitResult) { return [visitResult]; } return []; } - const flatten = (arr, result = []) => { - for (let i = 0, length = arr.length; i < length; i++) { - const value = arr[i]; - if (Array.isArray(value)) { - flatten(value, result); - } else if (value) { - // ignore value if undefined - result.push(value); - } - } - return result; - }; - return flatten(visitResult); + + return visitResult.filter(s => s !== undefined); + } + + private filterUndefined(items: Array): T[] { + return items.filter(i => i !== undefined) as T[]; + } + + private filterUndefinedAndCast( + items: Array, cast: (item: TOriginal) => item is TCast + ): TCast[] { + const filteredItems = items.filter(i => i !== undefined) as TOriginal[]; + if (filteredItems.every(i => cast(i))) { + return filteredItems as TCast[]; + } else { + throw TSTLErrors.CouldNotCast(cast.name); + } + } + + private expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { + if (visitResult === undefined) { + throw new Error("Expected single visit result expression, but found undefined"); + } else { + return visitResult; + } } } diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts index 771a32642..2f9a23ab6 100644 --- a/src/LuaTranspiler.ts +++ b/src/LuaTranspiler.ts @@ -60,7 +60,7 @@ export class LuaTranspiler { } public emitLuaLib(): string { - const outPath = path.join(this.options.outDir, "lualib_bundle.lua"); + const outPath = path.join(this.options.outDir || "", "lualib_bundle.lua"); fs.copyFileSync( path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), outPath @@ -93,14 +93,14 @@ export class LuaTranspiler { public emitSourceFile(sourceFile: ts.SourceFile): number { if (!sourceFile.isDeclarationFile) { try { - const rootDir = this.options.rootDir; + const rootDir = this.options.rootDir || ""; const { lua, luaAST, sourceMap } = this.transpileSourceFile(sourceFile); let outPath = sourceFile.fileName; if (this.options.outDir !== this.options.rootDir) { const relativeSourcePath = path.resolve(sourceFile.fileName).replace(path.resolve(rootDir), ""); - outPath = path.join(this.options.outDir, relativeSourcePath); + outPath = path.join(this.options.outDir || "", relativeSourcePath); } // change extension or rename to outFile @@ -109,7 +109,7 @@ export class LuaTranspiler { outPath = this.options.outFile; } else { // append to workingDir or outDir - outPath = path.resolve(this.options.outDir, this.options.outFile); + outPath = path.resolve(this.options.outDir || "", this.options.outFile); } } else { const fileNameLua = path.basename(outPath, path.extname(outPath)) + ".lua"; diff --git a/src/TSHelper.ts b/src/TSHelper.ts index d50523fa1..d17214251 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -77,10 +77,7 @@ export class TSHelper { } public static isFileModule(sourceFile: ts.SourceFile): boolean { - if (sourceFile) { - return sourceFile.statements.some(TSHelper.isStatementExported); - } - return false; + return sourceFile.statements.some(TSHelper.isStatementExported); } public static isStatementExported(statement: ts.Statement): boolean { @@ -151,12 +148,12 @@ export class TSHelper { const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; const typeNode = checker.typeToTypeNode(type, undefined, flags); - return typeNode && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); + return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); } public static isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode && ts.isFunctionTypeNode(typeNode); + return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); } public static isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean { @@ -225,11 +222,11 @@ export class TSHelper { } } - public static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type { + public static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { const signature = checker.getSignatureFromDeclaration(declaration); - return checker.getReturnTypeOfSignature(signature); + return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature); } return undefined; } @@ -302,7 +299,9 @@ export class TSHelper { } // Search up until finding a node satisfying the callback - public static findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T { + public static findFirstNodeAbove( + node: ts.Node, callback: (n: ts.Node) => n is T + ): T | undefined { let current = node; while (current.parent) { if (callback(current.parent)) { @@ -314,7 +313,7 @@ export class TSHelper { return undefined; } - public static isBinaryAssignmentToken(token: ts.SyntaxKind): [boolean, ts.BinaryOperator] { + public static isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined] { switch (token) { case ts.SyntaxKind.BarEqualsToken: return [true, ts.SyntaxKind.BarToken]; @@ -371,7 +370,7 @@ export class TSHelper { node: ts.Expression, checker: ts.TypeChecker, program: ts.Program - ): [boolean, ts.Expression, ts.Expression] + ): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] { if (ts.isElementAccessExpression(node) && (TSHelper.isExpressionWithEvaluationEffect(node.expression) @@ -396,7 +395,9 @@ export class TSHelper { return defaultArrayCallMethodNames.has(methodName); } - public static getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration { + public static getExplicitThisParameter( + signatureDeclaration: ts.SignatureDeclaration + ): ts.ParameterDeclaration | undefined { return signatureDeclaration.parameters.find( param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword); } @@ -405,7 +406,7 @@ export class TSHelper { classDeclaration: ts.ClassLikeDeclarationBase, callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, checker: ts.TypeChecker - ): ts.ClassLikeDeclarationBase + ): ts.ClassLikeDeclarationBase | undefined { if (callback(classDeclaration)) { return classDeclaration; @@ -417,7 +418,16 @@ export class TSHelper { } const symbol = extendsType.getSymbol(); - const declaration = symbol.getDeclarations().find(ts.isClassLike); + if (symbol === undefined) { + return undefined; + } + + const symbolDeclarations = symbol.getDeclarations(); + if (symbolDeclarations === undefined) { + return undefined; + } + + const declaration = symbolDeclarations.find(ts.isClassLike); if (!declaration) { return undefined; } @@ -477,7 +487,7 @@ export class TSHelper { const hasInitializedField = (e: ts.ClassElement) => ts.isPropertyDeclaration(e) - && e.initializer + && e.initializer !== undefined && TSHelper.isSamePropertyName(e.name, element.name); return TSHelper.findInClassOrAncestor( @@ -570,6 +580,11 @@ export class TSHelper { || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) ); + + if (scopeDeclaration === undefined) { + return ContextType.NonVoid; + } + const scopeType = checker.getTypeAtLocation(scopeDeclaration); if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { return ContextType.Void; @@ -649,7 +664,7 @@ export class TSHelper { public static isValidLuaIdentifier(str: string): boolean { const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/); - return match && match[0] === str; + return match !== undefined && match !== null && match[0] === str; } // Checks that a name is valid for use in lua function declaration syntax: @@ -657,7 +672,7 @@ export class TSHelper { // 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) public static isValidLuaFunctionDeclarationName(str: string): boolean { const match = str.match(/[a-zA-Z0-9_\.]+/); - return match && match[0] === str; + return match !== undefined && match !== null && match[0] === str; } public static isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { @@ -720,7 +735,10 @@ export class TSHelper { return this.isStandardLibraryDeclaration(declaration, program); } - public static isEnumMember(enumDeclaration: ts.EnumDeclaration, value: ts.Expression): [boolean, ts.PropertyName] { + public static isEnumMember( + enumDeclaration: ts.EnumDeclaration, + value: ts.Expression + ): [true, ts.PropertyName] | [false, undefined] { if (ts.isIdentifier(value)) { const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text); if (enumMember !== undefined) { diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 56ee4e73b..07e57e634 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -3,6 +3,9 @@ import { TranspileError } from "./TranspileError"; import { TSHelper as tsHelper } from "./TSHelper"; export class TSTLErrors { + public static CouldNotCast = (castName: string) => + new Error(`Failed to cast all elements to expected type using ${castName}.`); + public static CouldNotFindEnumMember = (enumDeclaration: ts.EnumDeclaration, enumMember: string, node: ts.Node) => new TranspileError(`Could not find ${enumMember} in ${enumDeclaration.name.text}`, node); @@ -29,6 +32,9 @@ export class TSTLErrors { public static InvalidNewExpressionOnExtension = (node: ts.Node) => new TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node); + public static InvalidExportDeclaration = (declaration: ts.ExportDeclaration) => + new TranspileError("Encountered invalid export declaration without exports and without module.", declaration); + public static InvalidExtendsExtension = (node: ts.Node) => new TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node); @@ -56,9 +62,30 @@ export class TSTLErrors { public static MissingClassName = (node: ts.Node) => new TranspileError(`Class declarations must have a name.`, node); + public static MissingForOfVariables = (node: ts.Node) => + new TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node); + + public static MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => + new TranspileError("Unsupported function declaration without name.", declaration); + public static MissingMetaExtension = (node: ts.Node) => new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); + public static MissingSourceFile = () => + new Error("Expected transformer.sourceFile to be set, but it isn't."); + + public static UndefinedFunctionDefinition = (functionSymbolId: number) => + new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); + + public static UndefinedScope = () => + new Error("Expected to pop a scope, but found undefined."); + + public static UndefinedTypeNode = (node: ts.Node) => + new TranspileError("Failed to resolve required type node.", node); + + public static UnknownSuperType = (node: ts.Node) => + new TranspileError("Unable to resolve type of super expression.", node); + public static UnsupportedDefaultExport = (node: ts.Node) => new TranspileError(`Default exports are not supported.`, node); @@ -77,6 +104,9 @@ export class TSTLErrors { public static UnsupportedForTarget = (functionality: string, version: string, node: ts.Node) => new TranspileError(`${functionality} is/are not supported for target Lua ${version}.`, node); + public static UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) => + new TranspileError("Functions with undefined bodies are not supported.", node); + public static UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { if (name) { return new TranspileError( diff --git a/test/compiler/project.spec.ts b/test/compiler/project.spec.ts index c72c0041e..a23fe9209 100644 --- a/test/compiler/project.spec.ts +++ b/test/compiler/project.spec.ts @@ -6,7 +6,7 @@ import { compile } from "../../src/Compiler"; * Find all files inside a dir, recursively. */ function getAllFiles(dir: string): string[] { - return fs.readdirSync(dir).reduce((files, file) => { + return fs.readdirSync(dir).reduce((files: string[], file) => { const name = path.join(dir, file); const isDirectory = fs.statSync(name).isDirectory(); return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; diff --git a/test/tsconfig.json b/test/tsconfig.json index 786d64a68..666a6006e 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,5 +1,8 @@ { "compilerOptions": { + "baseUrl": ".", + "paths": { "*": ["types/*"] }, + "strict": true, "target": "es2017", "types": ["node", "jest"], diff --git a/test/types/fengari.d.ts b/test/types/fengari.d.ts new file mode 100644 index 000000000..5e76ec549 --- /dev/null +++ b/test/types/fengari.d.ts @@ -0,0 +1,345 @@ +export const FENGARI_AUTHORS: string; +export const FENGARI_COPYRIGHT: string; +export const FENGARI_RELEASE: string; +export const FENGARI_VERSION: string; +export const FENGARI_VERSION_MAJOR: string; +export const FENGARI_VERSION_MINOR: string; +export const FENGARI_VERSION_NUM: number; +export const FENGARI_VERSION_RELEASE: string; +export namespace lauxlib { + const LUA_ERRFILE: number; + const LUA_FILEHANDLE: Uint8Array; + const LUA_LOADED_TABLE: Uint8Array; + const LUA_NOREF: number; + const LUA_PRELOAD_TABLE: Uint8Array; + const LUA_REFNIL: number; + class luaL_Buffer { + L: any; + b: any; + n: any; + } + function luaL_addchar(B: any, c: any): void; + function luaL_addlstring(B: any, s: any, l: any): void; + function luaL_addsize(B: any, s: any): void; + function luaL_addstring(B: any, s: any): void; + function luaL_addvalue(B: any): void; + function luaL_argcheck(L: any, cond: any, arg: any, extramsg: any): void; + function luaL_argerror(L: any, arg: any, extramsg: any): any; + function luaL_buffinit(L: any, B: any): void; + function luaL_buffinitsize(L: any, B: any, sz: any): any; + function luaL_callmeta(L: any, obj: any, event: any): any; + function luaL_checkany(L: any, arg: any): void; + function luaL_checkinteger(L: any, arg: any): any; + function luaL_checklstring(L: any, arg: any): any; + function luaL_checknumber(L: any, arg: any): any; + function luaL_checkoption(L: any, arg: any, def: any, lst: any): any; + function luaL_checkstack(L: any, space: any, msg: any): void; + function luaL_checkstring(L: any, arg: any): any; + function luaL_checktype(L: any, arg: any, t: any): void; + function luaL_checkudata(L: any, ud: any, tname: any): any; + function luaL_checkversion(L: any): void; + function luaL_checkversion_(L: any, ver: any, sz: any): void; + function luaL_dofile(L: any, filename: any): any; + function luaL_dostring(L: any, s: any): any; + function luaL_error(L: any, fmt: any, argp: any): any; + function luaL_execresult(L: any, e: any): any; + function luaL_fileresult(L: any, stat: any, fname: any, e: any): any; + function luaL_getmetafield(L: any, obj: any, event: any): any; + function luaL_getmetatable(L: any, n: any): any; + function luaL_getsubtable(L: any, idx: any, fname: any): any; + function luaL_gsub(L: any, s: any, p: any, r: any): any; + function luaL_len(L: any, idx: any): any; + function luaL_loadbuffer(L: any, s: any, sz: any, n: any): any; + function luaL_loadbufferx(L: any, buff: any, size: any, name: any, mode: any): any; + function luaL_loadfile(L: any, filename: any): any; + function luaL_loadfilex(L: any, filename: any, mode: any): any; + function luaL_loadstring(L: any, s: any): any; + function luaL_newlib(L: any, l: any): void; + function luaL_newlibtable(L: any): void; + function luaL_newmetatable(L: any, tname: any): any; + function luaL_newstate(): any; + function luaL_opt(L: any, f: any, n: any, d: any): any; + function luaL_optinteger(L: any, arg: any, def: any): any; + function luaL_optlstring(L: any, arg: any, def: any): any; + function luaL_optnumber(L: any, arg: any, def: any): any; + function luaL_optstring(L: any, arg: any, def: any): any; + function luaL_prepbuffer(B: any): any; + function luaL_prepbuffsize(B: any, sz: any): any; + function luaL_pushresult(B: any): void; + function luaL_pushresultsize(B: any, sz: any): void; + function luaL_ref(L: any, t: any): any; + function luaL_requiref(L: any, modname: any, openf: any, glb: any): void; + function luaL_setfuncs(L: any, l: any, nup: any): void; + function luaL_setmetatable(L: any, tname: any): void; + function luaL_testudata(L: any, ud: any, tname: any): any; + function luaL_tolstring(L: any, idx: any): any; + function luaL_traceback(L: any, L1: any, msg: any, level: any): void; + function luaL_typename(L: any, i: any): any; + function luaL_unref(L: any, t: any, ref: any): void; + function luaL_where(L: any, level: any): void; + function lua_writestringerror(...args: any[]): void; +} +export namespace lua { + const LUA_AUTHORS: string; + const LUA_COPYRIGHT: string; + const LUA_ERRERR: number; + const LUA_ERRGCMM: number; + const LUA_ERRMEM: number; + const LUA_ERRRUN: number; + const LUA_ERRSYNTAX: number; + const LUA_HOOKCALL: number; + const LUA_HOOKCOUNT: number; + const LUA_HOOKLINE: number; + const LUA_HOOKRET: number; + const LUA_HOOKTAILCALL: number; + const LUA_MASKCALL: number; + const LUA_MASKCOUNT: number; + const LUA_MASKLINE: number; + const LUA_MASKRET: number; + const LUA_MINSTACK: number; + const LUA_MULTRET: number; + const LUA_NUMTAGS: number; + const LUA_OK: number; + const LUA_OPADD: number; + const LUA_OPBAND: number; + const LUA_OPBNOT: number; + const LUA_OPBOR: number; + const LUA_OPBXOR: number; + const LUA_OPDIV: number; + const LUA_OPEQ: number; + const LUA_OPIDIV: number; + const LUA_OPLE: number; + const LUA_OPLT: number; + const LUA_OPMOD: number; + const LUA_OPMUL: number; + const LUA_OPPOW: number; + const LUA_OPSHL: number; + const LUA_OPSHR: number; + const LUA_OPSUB: number; + const LUA_OPUNM: number; + const LUA_REGISTRYINDEX: number; + const LUA_RELEASE: string; + const LUA_RIDX_GLOBALS: number; + const LUA_RIDX_LAST: number; + const LUA_RIDX_MAINTHREAD: number; + const LUA_SIGNATURE: Uint8Array; + const LUA_TBOOLEAN: number; + const LUA_TFUNCTION: number; + const LUA_TLIGHTUSERDATA: number; + const LUA_TNIL: number; + const LUA_TNONE: number; + const LUA_TNUMBER: number; + const LUA_TSTRING: number; + const LUA_TTABLE: number; + const LUA_TTHREAD: number; + const LUA_TUSERDATA: number; + const LUA_VERSION: string; + const LUA_VERSION_MAJOR: string; + const LUA_VERSION_MINOR: string; + const LUA_VERSION_NUM: number; + const LUA_VERSION_RELEASE: string; + const LUA_YIELD: number; + class lua_Debug { + event: any; + name: any; + namewhat: any; + what: any; + source: any; + currentline: any; + linedefined: any; + lastlinedefined: any; + nups: any; + nparams: any; + isvararg: any; + istailcall: any; + short_src: any; + i_ci: any; + } + function lua_absindex(L: any, idx: any): any; + function lua_arith(L: any, op: any): void; + function lua_atnativeerror(L: any, errorf: any): any; + function lua_atpanic(L: any, panicf: any): any; + function lua_call(L: any, n: any, r: any): void; + function lua_callk(L: any, nargs: any, nresults: any, ctx: any, k: any): void; + function lua_checkstack(L: any, n: any): any; + function lua_close(L: any): void; + function lua_compare(L: any, index1: any, index2: any, op: any): any; + function lua_concat(L: any, n: any): void; + function lua_copy(L: any, fromidx: any, toidx: any): void; + function lua_createtable(L: any, narray: any, nrec: any): void; + function lua_dump(L: any, writer: any, data: any, strip: any): any; + function lua_error(L: any): void; + function lua_gc(): void; + function lua_getallocf(): any; + function lua_getextraspace(): any; + function lua_getfield(L: any, idx: any, k: any): any; + function lua_getglobal(L: any, name: any): any; + function lua_gethook(L: any): any; + function lua_gethookcount(L: any): any; + function lua_gethookmask(L: any): any; + function lua_geti(L: any, idx: any, n: any): any; + function lua_getinfo(L: any, what: any, ar: any): any; + function lua_getlocal(L: any, ar: any, n: any): any; + function lua_getmetatable(L: any, objindex: any): any; + function lua_getstack(L: any, level: any, ar: any): any; + function lua_gettable(L: any, idx: any): any; + function lua_gettop(L: any): any; + function lua_getupvalue(L: any, funcindex: any, n: any): any; + function lua_getuservalue(L: any, idx: any): any; + function lua_insert(L: any, idx: any): void; + function lua_isboolean(L: any, n: any): any; + function lua_iscfunction(L: any, idx: any): any; + function lua_isfunction(L: any, idx: any): any; + function lua_isinteger(L: any, idx: any): any; + function lua_islightuserdata(L: any, idx: any): any; + function lua_isnil(L: any, n: any): any; + function lua_isnone(L: any, n: any): any; + function lua_isnoneornil(L: any, n: any): any; + function lua_isnumber(L: any, idx: any): any; + function lua_isproxy(p: any, L: any): any; + function lua_isstring(L: any, idx: any): any; + function lua_istable(L: any, idx: any): any; + function lua_isthread(L: any, idx: any): any; + function lua_isuserdata(L: any, idx: any): any; + function lua_isyieldable(L: any): any; + function lua_len(L: any, idx: any): void; + function lua_load(L: any, reader: any, data: any, chunkname: any, mode: any): any; + function lua_newstate(): any; + function lua_newtable(L: any): void; + function lua_newthread(L: any): any; + function lua_newuserdata(L: any, size: any): any; + function lua_next(L: any, idx: any): any; + function lua_pcall(L: any, n: any, r: any, f: any): any; + function lua_pcallk(L: any, nargs: any, nresults: any, errfunc: any, ctx: any, k: any): any; + function lua_pop(L: any, n: any): void; + function lua_pushboolean(L: any, b: any): void; + function lua_pushcclosure(L: any, fn: any, n: any): void; + function lua_pushcfunction(L: any, fn: any): void; + function lua_pushfstring(L: any, fmt: any, argp: any): any; + function lua_pushglobaltable(L: any): void; + function lua_pushinteger(L: any, n: any): void; + function lua_pushjsclosure(L: any, fn: any, n: any): void; + function lua_pushjsfunction(L: any, fn: any): void; + function lua_pushlightuserdata(L: any, p: any): void; + function lua_pushliteral(L: any, s: any): any; + function lua_pushlstring(L: any, s: any, len: any): any; + function lua_pushnil(L: any): void; + function lua_pushnumber(L: any, n: any): void; + function lua_pushstring(L: any, s: any): any; + function lua_pushthread(L: any): any; + function lua_pushvalue(L: any, idx: any): void; + function lua_pushvfstring(L: any, fmt: any, argp: any): any; + function lua_rawequal(L: any, index1: any, index2: any): any; + function lua_rawget(L: any, idx: any): any; + function lua_rawgeti(L: any, idx: any, n: any): any; + function lua_rawgetp(L: any, idx: any, p: any): any; + function lua_rawlen(L: any, idx: any): any; + function lua_rawset(L: any, idx: any): void; + function lua_rawseti(L: any, idx: any, n: any): void; + function lua_rawsetp(L: any, idx: any, p: any): void; + function lua_register(L: any, n: any, f: any): void; + function lua_remove(L: any, idx: any): void; + function lua_replace(L: any, idx: any): void; + function lua_resume(L: any, from: any, nargs: any): any; + function lua_rotate(L: any, idx: any, n: any): void; + const lua_setallof: any; + function lua_setfield(L: any, idx: any, k: any): void; + function lua_setglobal(L: any, name: any): void; + function lua_sethook(L: any, func: any, mask: any, count: any): void; + function lua_seti(L: any, idx: any, n: any): void; + function lua_setlocal(L: any, ar: any, n: any): any; + function lua_setmetatable(L: any, objindex: any): any; + function lua_settable(L: any, idx: any): void; + function lua_settop(L: any, idx: any): void; + function lua_setupvalue(L: any, funcindex: any, n: any): any; + function lua_setuservalue(L: any, idx: any): void; + function lua_status(L: any): any; + function lua_stringtonumber(L: any, s: any): any; + function lua_toboolean(L: any, idx: any): any; + function lua_tocfunction(L: any, idx: any): any; + function lua_todataview(L: any, idx: any): any; + function lua_tointeger(L: any, idx: any): any; + function lua_tointegerx(L: any, idx: any): any; + function lua_tojsstring(L: any, idx: any): any; + function lua_tolstring(L: any, idx: any): any; + function lua_tonumber(L: any, idx: any): any; + function lua_tonumberx(L: any, idx: any): any; + function lua_topointer(L: any, idx: any): any; + function lua_toproxy(L: any, idx: any): any; + function lua_tostring(L: any, idx: any): LuaString; + function lua_tothread(L: any, idx: any): any; + function lua_touserdata(L: any, idx: any): any; + function lua_type(L: any, idx: any): any; + function lua_typename(L: any, t: any): any; + function lua_upvalueid(L: any, fidx: any, n: any): any; + function lua_upvalueindex(i: any): any; + function lua_upvaluejoin(L: any, fidx1: any, n1: any, fidx2: any, n2: any): void; + function lua_version(L: any): any; + function lua_xmove(from: any, to: any, n: any): void; + function lua_yield(L: any, n: any): void; + function lua_yieldk(L: any, nresults: any, ctx: any, k: any): any; +} +export namespace luaconf { + const LUAI_MAXSTACK: number; + const LUAL_BUFFERSIZE: number; + const LUA_COMPAT_FLOATSTRING: boolean; + const LUA_DIRSEP: string; + const LUA_EXEC_DIR: string; + const LUA_IDSIZE: number; + const LUA_INTEGER_FMT: string; + const LUA_INTEGER_FRMLEN: string; + const LUA_JSDIR: string; + const LUA_JSPATH_DEFAULT: Uint8Array; + const LUA_LDIR: string; + const LUA_MAXINTEGER: number; + const LUA_MININTEGER: number; + const LUA_NUMBER_FMT: string; + const LUA_NUMBER_FRMLEN: string; + const LUA_PATH_DEFAULT: Uint8Array; + const LUA_PATH_MARK: string; + const LUA_PATH_SEP: string; + const LUA_SHRDIR: string; + const LUA_VDIR: string; + function frexp(value: any): any; + function ldexp(mantissa: any, exponent: any): any; + function lua_getlocaledecpoint(): any; + function lua_integer2str(n: any): any; + function lua_number2str(n: any): any; + function lua_numbertointeger(n: any): any; + function luai_apicheck(l: any, e: any): void; +} +export namespace lualib { + const LUA_BITLIBNAME: string; + const LUA_COLIBNAME: string; + const LUA_DBLIBNAME: string; + const LUA_FENGARILIBNAME: string; + const LUA_IOLIBNAME: string; + const LUA_LOADLIBNAME: string; + const LUA_MATHLIBNAME: string; + const LUA_OSLIBNAME: string; + const LUA_STRLIBNAME: string; + const LUA_TABLIBNAME: string; + const LUA_UTF8LIBNAME: string; + const LUA_VERSUFFIX: string; + function luaL_openlibs(L: any): void; + function lua_assert(c: any): void; + function luaopen_coroutine(L: any): any; + function luaopen_debug(L: any): any; + function luaopen_fengari(L: any): any; + function luaopen_io(L: any): any; + function luaopen_math(L: any): any; + function luaopen_os(L: any): any; + function luaopen_package(L: any): any; + function luaopen_string(L: any): any; + function luaopen_table(L: any): any; + function luaopen_utf8(L: any): any; +} + +export type LuaString = number[]; + +export function luastring_eq(a: any, b: any): any; +export function luastring_indexOf(s: any, v: any, i: any): any; +export function luastring_of(): any; +export function to_jsstring(value: LuaString, from?: any, to?: any, replacement_char?: any): string; +export function to_luastring(str: string, cache?: any): LuaString; +export function to_uristring(a: any): any; diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 0fd43b914..7a2268624 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -484,51 +484,31 @@ test("Unknown unary postfix error", () => { }); test("Incompatible fromCodePoint expression error", () => { - const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); - - const identifier = ts.createIdentifier("fromCodePoint"); - expect(() => transformer.transformStringExpression(identifier)).toThrowExactError( + expect(() => util.transpileString("const abc = String.fromCodePoint(123);")).toThrowExactError( TSTLErrors.UnsupportedForTarget( "string property fromCodePoint", - LuaTarget.LuaJIT, + LuaTarget.Lua53, util.nodeStub, ), ); }); test("Unknown string expression error", () => { - const transformer = util.makeTestTransformer(LuaTarget.LuaJIT); - - const identifier = ts.createIdentifier("abcd"); - expect(() => transformer.transformStringExpression(identifier)).toThrowExactError( - TSTLErrors.UnsupportedForTarget("string property abcd", LuaTarget.LuaJIT, util.nodeStub), + expect(() => util.transpileString("const abc = String.abcd();")).toThrowExactError( + TSTLErrors.UnsupportedForTarget("string property abcd", LuaTarget.Lua53, util.nodeStub), ); }); test("Unsupported array function error", () => { - const transformer = util.makeTestTransformer(); - - const mockNode: any = { - kind: ts.SyntaxKind.CallExpression, - arguments: [], - caller: ts.createLiteral(false), - expression: { - name: ts.createIdentifier("unknownFunction"), - expression: ts.createLiteral(false), - }, - }; - - expect(() => - transformer.transformArrayCallExpression(mockNode as ts.CallExpression), - ).toThrowExactError(TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub)); + expect(() => util.transpileString("const abc = [].unknownFunction();")).toThrowExactError( + TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub), + ); }); test("Unsupported math property error", () => { - const transformer = util.makeTestTransformer(); - - expect(() => - transformer.transformMathExpression(ts.createIdentifier("unknownProperty")), - ).toThrowExactError(TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub)); + expect(() => util.transpileString("const abc = Math.unknownProperty;")).toThrowExactError( + TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub), + ); }); test("Unsupported object literal element error", () => { diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 1b78813d8..bf1439006 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -774,8 +774,8 @@ test.each([ const lua53 = { luaTarget: LuaTarget.Lua53 }; const luajit = { luaTarget: LuaTarget.LuaJIT }; - expect(() => util.transpileString(loop, lua51)).toThrowError( - TSTLErrors.UnsupportedForTarget("Continue statement", LuaTarget.Lua51, undefined), + expect(() => util.transpileString(loop, lua51)).toThrowExactError( + TSTLErrors.UnsupportedForTarget("Continue statement", LuaTarget.Lua51, ts.createContinue()), ); expect(util.transpileString(loop, lua52).indexOf("::__continue1::") !== -1).toBe(true); expect(util.transpileString(loop, lua53).indexOf("::__continue1::") !== -1).toBe(true); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 87913fd84..e9c5dee7b 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -393,12 +393,12 @@ test.each([ }); test.each([ - { array: [1, [2, 3], [4]], map: (value: T) => value }, - { array: [1, 2, 3], map: (v: number) => v * 2 }, - { array: [1, 2, 3], map: (v: number) => [v, v * 2] }, - { array: [1, 2, 3], map: (v: number) => [v, [v]] }, - { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i] }, -])("array.flatMap (%p)", ({ array, map }) => { + { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, + { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, + { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, +])("array.flatMap (%p)", ({ array, map, expected }) => { const result = util.transpileAndExecute(` const array = ${JSON.stringify(array)}; const result = array.flatMap(${map.toString()}); @@ -406,7 +406,6 @@ test.each([ `); // TODO(node 12): array.flatMap(map) - const expected = [].concat(...(array as any[]).map(map)); expect(JSON.parse(result)).toEqual(expected); }); @@ -447,9 +446,7 @@ test.each([ `); const result = JSON.parse(jsonResult); - for (const key in expected) { - expect(result[key]).toBe(expected[key]); - } + expect(result).toEqual(expected); }); test.each([ diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index c518c69a3..46c23b0f4 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -22,7 +22,8 @@ test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])( "Math constant (%p)", constant => { const epsilon = 0.000001; - const code = `return Math.abs(Math.${constant} - ${Math[constant]}) <= ${epsilon}`; + const jsValue: number = (Math as Math & { [key: string]: any })[constant]; + const code = `return Math.abs(Math.${constant} - ${jsValue}) <= ${epsilon}`; expect(util.transpileAndExecute(code)).toBe(true); }, ); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index 747ce7b7a..a7e5e378c 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -87,7 +87,10 @@ test.each([ ); const regex = /require\("(.*?)"\)/; const match = regex.exec(lua); - expect(match[1]).toBe(expectedPath); + + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe(expectedPath); + } } }, ); @@ -108,6 +111,10 @@ test.each([ "src/file.ts", ); const regex = /require\("(.*?)"\)/; - expect(regex.exec(lua)[1]).toBe(expectedPath); + const match = regex.exec(lua); + + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe(expectedPath); + } }, ); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index e6e6fe766..fef652744 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -128,12 +128,13 @@ test("Inline sourcemaps", () => { const inlineSourceMapMatch = lua.match( /--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/, ); - expect(inlineSourceMapMatch !== null && inlineSourceMapMatch !== undefined).toBe(true); - const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); - expect(sourceMap).toBe(inlineSourceMap); + if (util.expectToBeDefined(inlineSourceMapMatch)) { + const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); + expect(sourceMap).toBe(inlineSourceMap); - expect(util.executeLua(lua)).toBe("foo"); + expect(util.executeLua(lua)).toBe("foo"); + } }); // Helper functions diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 00acb8d05..dcd40db5e 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -5,9 +5,9 @@ test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])( "Spread Element Push (%p)", ({ inp }) => { const result = util.transpileAndExecute( - `return JSONStringify([].push(...${JSON.stringify(inp)}));`, + `return JSONStringify(([] as Array).push(...${JSON.stringify(inp)}));`, ); - expect(result).toBe([].push(...inp)); + expect(result).toBe(([] as Array).push(...inp)); }, ); diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 6e1b0d9df..9513250e4 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -33,10 +33,6 @@ test.each([ expect(result).toEqual(expected); }); -test("IsFileModuleNull", () => { - expect(tsHelper.isFileModule(undefined)).toEqual(false); -}); - test("GetCustomDecorators single", () => { const source = ` /** @compileMembersOnly */ @@ -52,12 +48,15 @@ test("GetCustomDecorators single", () => { const [sourceFile, typeChecker] = util.parseTypeScript(source); const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + if (util.expectToBeDefined(identifier)) { + const enumType = typeChecker.getTypeAtLocation(identifier); - expect(decorators.size).toBe(1); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(1); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + } }); test("GetCustomDecorators multiple", () => { @@ -76,13 +75,16 @@ test("GetCustomDecorators multiple", () => { const [sourceFile, typeChecker] = util.parseTypeScript(source); const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + if (util.expectToBeDefined(identifier)) { + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + } }); test("GetCustomDecorators single jsdoc", () => { @@ -100,12 +102,15 @@ test("GetCustomDecorators single jsdoc", () => { const [sourceFile, typeChecker] = util.parseTypeScript(source); const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + if (util.expectToBeDefined(identifier)) { + const enumType = typeChecker.getTypeAtLocation(identifier); - expect(decorators.size).toBe(1); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + + expect(decorators.size).toBe(1); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + } }); test("GetCustomDecorators multiple jsdoc", () => { @@ -124,13 +129,16 @@ test("GetCustomDecorators multiple jsdoc", () => { const [sourceFile, typeChecker] = util.parseTypeScript(source); const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + if (util.expectToBeDefined(identifier)) { + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + } }); test("GetCustomDecorators multiple default jsdoc", () => { @@ -151,11 +159,14 @@ test("GetCustomDecorators multiple default jsdoc", () => { const [sourceFile, typeChecker] = util.parseTypeScript(source); const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - const enumType = typeChecker.getTypeAtLocation(identifier); - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); + if (util.expectToBeDefined(identifier)) { + const enumType = typeChecker.getTypeAtLocation(identifier); + + const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + expect(decorators.size).toBe(2); + expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); + expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); + } }); diff --git a/test/util.ts b/test/util.ts index d09cd7824..fd09d9541 100644 --- a/test/util.ts +++ b/test/util.ts @@ -198,7 +198,13 @@ export function parseTypeScript( target: LuaTarget = LuaTarget.Lua53, ): [ts.SourceFile, ts.TypeChecker] { const program = createStringCompilerProgram(typescript, { luaTarget: target }); - return [program.getSourceFile("file.ts"), program.getTypeChecker()]; + const sourceFile = program.getSourceFile("file.ts"); + + if (sourceFile === undefined) { + throw new Error("Could not find source file file.ts in program."); + } + + return [sourceFile, program.getTypeChecker()]; } export function findFirstChild( @@ -217,3 +223,8 @@ export function findFirstChild( } return undefined; } + +export function expectToBeDefined(subject: T | null | undefined): subject is T { + expect(subject).toBeDefined(); + return true; // If this was false the expect would have thrown an error +} diff --git a/tsconfig.json b/tsconfig.json index 84d667105..59ea10e64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "compilerOptions": { - "noImplicitThis": true, - "alwaysStrict": true, + "strict": true, "rootDir": "./src", "outDir": "./dist", "declaration": true, From 576c7e5eac768fa999466049f7f1ca99be02250c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 14 Apr 2019 12:46:47 -0600 Subject: [PATCH 060/764] Ensuring super call is always first statement in constructors (#524) * made sure super calls in constructors are always first statement * adhering to strictness * a slight refactor --- src/LuaTransformer.ts | 28 +++++++++++++++++++++++----- test/unit/class.spec.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7a3226625..4b236a734 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1007,7 +1007,10 @@ export class LuaTransformer { return undefined; } - const bodyStatements: tstl.Statement[] = this.transformClassInstanceFields(classDeclaration, instanceFields); + const bodyWithFieldInitializers: tstl.Statement[] = this.transformClassInstanceFields( + classDeclaration, + instanceFields + ); // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); @@ -1027,7 +1030,7 @@ export class LuaTransformer { tstl.SyntaxKind.OrOperator ) ); - bodyStatements.push(assignement); + bodyWithFieldInitializers.push(assignement); } else { // self.declarationName = declarationName const assignement = tstl.createAssignmentStatement( @@ -1037,7 +1040,7 @@ export class LuaTransformer { ), declarationName ); - bodyStatements.push(assignement); + bodyWithFieldInitializers.push(assignement); } } @@ -1049,9 +1052,24 @@ export class LuaTransformer { ); const [body] = this.transformFunctionBody(statement.parameters, statement.body, restParamName); - bodyStatements.push(...body); - const block: tstl.Block = tstl.createBlock(bodyStatements); + // If there are field initializers and the first statement is a super call, hoist the super call to the top + if (bodyWithFieldInitializers.length > 0 && statement.body && statement.body.statements.length > 0) { + const firstStatement = statement.body.statements[0]; + if (ts.isExpressionStatement(firstStatement) + && ts.isCallExpression(firstStatement.expression) + && firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword) + { + const superCall = body.shift(); + if (superCall) { + bodyWithFieldInitializers.unshift(superCall); + } + } + } + + bodyWithFieldInitializers.push(...body); + + const block: tstl.Block = tstl.createBlock(bodyWithFieldInitializers); const result = tstl.createAssignmentStatement( this.createConstructorName(className), diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 75070b578..0ffc8421b 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -797,3 +797,29 @@ test("Class annonymous expression name via constructor", () => { `; expect(util.transpileAndExecute(code)).toBe("____"); }); + +test("Class field override in subclass", () => { + const code = ` + class Foo { + field = "foo"; + } + class Bar extends Foo { + field = "bar"; + } + return (new Foo()).field + (new Bar()).field;`; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("Class field override in subclass with constructors", () => { + const code = ` + class Foo { + field = "foo"; + constructor() {} + } + class Bar extends Foo { + field = "bar"; + constructor() { super(); } + } + return (new Foo()).field + (new Bar()).field;`; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); From 291300edd0ef769ba91568a23702d77990b6a4dc Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 14 Apr 2019 20:55:10 +0200 Subject: [PATCH 061/764] 0.18.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index dda947979..93a71eafd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.17.0", + "version": "0.18.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3c063871b..98ef1b9a5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.17.0", + "version": "0.18.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From e9a7b0f5d547363845e2435278db2a5772d93758 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Apr 2019 21:01:46 +0200 Subject: [PATCH 062/764] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6650811d9..6ba2e0c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.18.0 +* Added support for setting array length. Doing `array.length = x` will set the length of the array to `x` (or shorter, if the starting array was shorter!). +* Added the `.name` property to all transpiled classes, so `class.name` will contain the classname as string. +* Changed `class = class or {}` syntax to just be `class = {}`. +* Cleaned up printer output so it produces more human-readable code. + +* Fixed bug with expression statements. +* Fixed incorrect inline sourcemap format. +* Fixed bug when merging an interface and module. +* Fixed a bug with inherited constructor super call ordering. + +* Enabled strict tsconfig. + ## 0.17.0 * We now support source maps in the [standard JS v3 format](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1). You can generate source maps with the `--sourceMap` CLI argument, or by adding `sourceMap: true` to your tsconfig. Inline source maps are also supported with `--inlineSourceMap` CLI/tsconfig parameter. * Also added [tstl option](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options) `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). From 043b87db0211927d441862e12c36543c487a333c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 17 Apr 2019 08:42:16 -0600 Subject: [PATCH 063/764] Import hoisting (#526) * Hoisting all imports * Fixed hoisting order * Preventing "export...from" imports from being hoisted out of block * Variable rename --- src/LuaTransformer.ts | 56 ++++++++++++++++++++++++++++++-------- test/unit/hoisting.spec.ts | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4b236a734..be5cd0535 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -34,6 +34,7 @@ interface Scope { referencedSymbols?: Set; variableDeclarations?: tstl.VariableDeclarationStatement[]; functionDefinitions?: Map; + importStatements?: tstl.Statement[]; loopContinued?: boolean; } @@ -273,9 +274,9 @@ export class LuaTransformer { statement.moduleSpecifier ); - const importResult = this.transformImportDeclaration(importDeclaration); - - const result = Array.isArray(importResult) ? importResult : [importResult]; + // Wrap in block to prevent imports from hoisting out of `do` statement + const block = ts.createBlock([importDeclaration]); + const result = this.transformBlock(block).statements; // Now the module is imported, add the imports to the export table for (const exportVariable of statement.exportClause.elements) { @@ -327,13 +328,23 @@ export class LuaTransformer { const result: tstl.Statement[] = []; + const scope = this.peekScope(); + if (!this.options.noHoisting && !scope.importStatements) { + scope.importStatements = []; + } + const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), ""); if (!statement.importClause) { const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); result.push(tstl.createExpressionStatement(requireCall)); - return result; + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } } const imports = statement.importClause.namedBindings; @@ -369,30 +380,41 @@ export class LuaTransformer { if (importSpecifier.propertyName) { const propertyIdentifier = this.transformIdentifier(importSpecifier.propertyName); const propertyName = tstl.createStringLiteral(propertyIdentifier.text); - const renamedImport = this.createHoistableVariableDeclarationStatement( - importSpecifier.name, + const renamedImport = tstl.createVariableDeclarationStatement( + this.transformIdentifier(importSpecifier.name), tstl.createTableIndexExpression(importUniqueName, propertyName), importSpecifier); result.push(renamedImport); } else { const name = tstl.createStringLiteral(importSpecifier.name.text); - const namedImport = this.createHoistableVariableDeclarationStatement( - importSpecifier.name, + const namedImport = tstl.createVariableDeclarationStatement( + this.transformIdentifier(importSpecifier.name), tstl.createTableIndexExpression(importUniqueName, name), importSpecifier ); result.push(namedImport); } }); - return result; + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } + } else if (ts.isNamespaceImport(imports)) { - const requireStatement = this.createHoistableVariableDeclarationStatement( - imports.name, + const requireStatement = tstl.createVariableDeclarationStatement( + this.transformIdentifier(imports.name), requireCall, statement ); result.push(requireStatement); - return result; + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } } } @@ -4882,6 +4904,14 @@ export class LuaTransformer { } } + protected hoistImportStatements(scope: Scope, statements: tstl.Statement[]): tstl.Statement[] { + if (!scope.importStatements) { + return statements; + } + + return [...scope.importStatements, ...statements]; + } + protected hoistFunctionDefinitions(scope: Scope, statements: tstl.Statement[]): tstl.Statement[] { if (!scope.functionDefinitions) { return statements; @@ -4952,6 +4982,8 @@ export class LuaTransformer { result = this.hoistVariableDeclarations(scope, result); + result = this.hoistImportStatements(scope, result); + return result; } diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 215d38c49..37d893335 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -243,3 +243,55 @@ test.each([ TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)), ); }); + +test("Import hoisting (named)", () => { + const importCode = ` + const bar = foo; + import {foo} from "myMod";`; + const luaHeader = ` + package.loaded["myMod"] = {foo = "foobar"} + ${util.transpileString(importCode)}`; + const tsHeader = "declare const bar: any;"; + const code = "return bar;"; + expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); +}); + +test("Import hoisting (namespace)", () => { + const importCode = ` + const bar = myMod.foo; + import * as myMod from "myMod";`; + const luaHeader = ` + package.loaded["myMod"] = {foo = "foobar"} + ${util.transpileString(importCode)}`; + const tsHeader = "declare const bar: any;"; + const code = "return bar;"; + expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); +}); + +test("Import hoisting (side-effect)", () => { + const importCode = ` + const bar = foo; + import "myMod";`; + const luaHeader = ` + package.loaded["myMod"] = {_ = (function() foo = "foobar" end)()} + ${util.transpileString(importCode)}`; + const tsHeader = "declare const bar: any;"; + const code = "return bar;"; + expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); +}); + +test("Import hoisted before function", () => { + const importCode = ` + let bar: any; + import {foo} from "myMod"; + baz(); + function baz() { + bar = foo; + }`; + const luaHeader = ` + package.loaded["myMod"] = {foo = "foobar"} + ${util.transpileString(importCode)}`; + const tsHeader = "declare const bar: any;"; + const code = "return bar;"; + expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); +}); From a980e1393d422f26f13b67716ef76c84a7add580 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 17 Apr 2019 09:40:23 -0600 Subject: [PATCH 064/764] Adjusted peekScope return and added appropriate errors (#527) * made peekScope return Scope | undefined and added appropriate errors * removed unneccessary checks * removed unneccessary checks --- src/LuaTransformer.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index be5cd0535..9645d126e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -329,6 +329,9 @@ export class LuaTransformer { const result: tstl.Statement[] = []; const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } if (!this.options.noHoisting && !scope.importStatements) { scope.importStatements = []; } @@ -1756,6 +1759,9 @@ export class LuaTransformer { // Remember symbols referenced in this function for hoisting later if (!this.options.noHoisting && name.symbolId !== undefined) { const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } if (!scope.functionDefinitions) { scope.functionDefinitions = new Map(); } const functionInfo = {referencedSymbols: functionScope.referencedSymbols || new Set()}; scope.functionDefinitions.set(name.symbolId, functionInfo); @@ -2309,7 +2315,11 @@ export class LuaTransformer { this.pushScope(ScopeType.Switch, statement); // Give the switch a unique name to prevent nested switches from acting up. - const switchName = `____TS_switch${this.peekScope().id}`; + const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + const switchName = `____TS_switch${scope.id}`; const expression = this.transformExpression(statement.expression); const switchVariable = tstl.createIdentifier(switchName); @@ -4658,7 +4668,10 @@ export class LuaTransformer { // Remember function definitions for hoisting later const functionSymbolId = (lhs as tstl.Identifier).symbolId; const scope = this.peekScope(); - if (functionSymbolId && scope && scope.functionDefinitions) { + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + if (functionSymbolId && scope.functionDefinitions) { const definitions = scope.functionDefinitions.get(functionSymbolId); if (definitions) { definitions.definition = declaration || assignment; @@ -4834,7 +4847,7 @@ export class LuaTransformer { return this.scopeStack.slice().reverse().find(s => (scopeTypes & s.type) !== 0); } - protected peekScope(): Scope { + protected peekScope(): Scope | undefined { return this.scopeStack[this.scopeStack.length - 1]; } @@ -4977,6 +4990,9 @@ export class LuaTransformer { } const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } let result = this.hoistFunctionDefinitions(scope, statements); @@ -5008,6 +5024,9 @@ export class LuaTransformer { const declaration = tstl.createVariableDeclarationStatement(variable, initializer, tsOriginal, parent); if (!this.options.noHoisting && variable.symbolId) { const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } if (!scope.variableDeclarations) { scope.variableDeclarations = []; } scope.variableDeclarations.push(declaration); } From 247cebaded56bf83498a83f9b2334c5cc02d2446 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 29 Apr 2019 00:19:50 +1000 Subject: [PATCH 065/764] false default binding pattern values (#538) * false default binding pattern values * Tidied up tests * Added array binding pattern default test * Array binding pattern default parameters --- src/LuaTransformer.ts | 76 +++++++++++++++++++++++++------ test/unit/bindingpatterns.spec.ts | 19 ++++++++ 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9645d126e..59a91edbb 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1370,14 +1370,26 @@ export class LuaTransformer { const expression = isObjectBindingPattern ? tstl.createTableIndexExpression(tableExpression, tstl.createStringLiteral(propertyName.text)) : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); + yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, expression); if (element.initializer) { - const defaultExpression = tstl.createBinaryExpression(expression, - this.expectExpression(this.transformExpression(element.initializer)), - tstl.SyntaxKind.OrOperator + const identifier = this.shouldExportIdentifier(variableName) + ? this.createExportedIdentifier(variableName) + : variableName; + yield tstl.createIfStatement( + tstl.createBinaryExpression( + identifier, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ), + tstl.createBlock( + [ + tstl.createAssignmentStatement( + identifier, + this.transformExpression(element.initializer) + ), + ] + ) ); - yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, defaultExpression); - } else { - yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, expression); } } } @@ -1802,6 +1814,8 @@ export class LuaTransformer { } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { // Destructuring types + const statements: tstl.Statement[] = []; + // For nested bindings and object bindings, fall back to transformBindingPattern if (ts.isObjectBindingPattern(statement.name) || statement.name.elements.some(elem => !ts.isBindingElement(elem) || !ts.isIdentifier(elem.name))) { @@ -1835,10 +1849,12 @@ export class LuaTransformer { // Don't unpack TupleReturn decorated functions if (statement.initializer) { if (tsHelper.isTupleReturnCall(statement.initializer, this.checker)) { - return this.createLocalOrExportedOrGlobalDeclaration( - vars, - this.transformExpression(statement.initializer), - statement + statements.push( + ...this.createLocalOrExportedOrGlobalDeclaration( + vars, + this.transformExpression(statement.initializer), + statement + ) ); } else { // local vars = this.transpileDestructingAssignmentValue(node.initializer); @@ -1846,15 +1862,45 @@ export class LuaTransformer { this.expectExpression(this.transformExpression(statement.initializer)), statement.initializer ); - return this.createLocalOrExportedOrGlobalDeclaration(vars, initializer, statement); + statements.push(...this.createLocalOrExportedOrGlobalDeclaration(vars, initializer, statement)); } } else { - return this.createLocalOrExportedOrGlobalDeclaration( - vars, - tstl.createNilLiteral(), - statement + statements.push( + ...this.createLocalOrExportedOrGlobalDeclaration( + vars, + tstl.createNilLiteral(), + statement + ) ); } + + statement.name.elements.forEach(element => { + if (!ts.isOmittedExpression(element) && element.initializer) { + const variableName = this.transformIdentifier(element.name as ts.Identifier); + const identifier = this.shouldExportIdentifier(variableName) + ? this.createExportedIdentifier(variableName) + : variableName; + statements.push( + tstl.createIfStatement( + tstl.createBinaryExpression( + identifier, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ), + tstl.createBlock( + [ + tstl.createAssignmentStatement( + identifier, + this.transformExpression(element.initializer) + ), + ] + ) + ) + ); + } + }); + + return statements; } } diff --git a/test/unit/bindingpatterns.spec.ts b/test/unit/bindingpatterns.spec.ts index 6cc1b5bc3..b7ed32de5 100644 --- a/test/unit/bindingpatterns.spec.ts +++ b/test/unit/bindingpatterns.spec.ts @@ -90,3 +90,22 @@ test.each(testCases)( expect(result).toBe(true); }, ); + +test.each([ + { bindingString: "{x, y = true}", objectString: "{x: false, y: false}", returnVariable: "y" }, + { + bindingString: "{x, y: [z = true]}", + objectString: "{x: false, y: [false]}", + returnVariable: "z", + }, + { bindingString: "[x = true]", objectString: "[false]", returnVariable: "x" }, +])( + "Binding patterns handle false correctly (%p)", + ({ bindingString, objectString, returnVariable }) => { + const result = util.transpileExecuteAndReturnExport( + `export const ${bindingString} = ${objectString};`, + returnVariable, + ); + expect(result).toBe(false); + }, +); From 5d4ed09f13960a6cae9c585ce6acb9fbdce69db0 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 May 2019 15:01:02 +0500 Subject: [PATCH 066/764] New emit pipeline and API/CLI refactor (#511) * New emit pipeline and API/CLI refactor * Move high-level API to index file * Extract multi-file `transpileString` input to `transpileVirtualProgram` * Return an results from emitTranspiledFiles instead of a using a callback * Refactor CommandLineParser and further CLI refactor * Fix strict issues * Fix rootDir and outDir defaults always being used * Remove failing test * Remove command line parser tests that test standard TS parser features * Use tsconfig source file during parse to get better diagnostics * Parse command line options more similar to typescript * Refactor commandLineParser tests * Rename transpileVirtualProgram to transpileVirtualProject * Remove export from CLI * Add expect(received).toHaveDiagnostics() matcher * Parse command line options case-insensitively * Disallow unknown options in "tstl" config object * Rename compiler tests to CLI tests * Refactor CLI tests * Add transpile tests * Fix invalid behavior with relative outFile and outDir * Rename getTranspileOutput to getTranspilationResult * Remove `options` argument from `getTranspilationResult` * Rename getTranspilationResult to transpile * Extract luaLibImport to a variable * Add command line parsing integration tests * Make diagnostics use node's source file instead of transformed one * Cast getCompilerOptions calls to custom compiler options * Export TranspileError and all LuaTransformer exports from package index * Remove options argument from LuaTransformer * Rename sourceFile variable * Set printer default during destructuring * Rename * Use emitTranspiledFiles in transpileFiles and transpileProject * Use transpileFiles in transpile tests runner * Fix typos * Deprecate root-level options * Move TranspileError diagnostic to diagnostics.ts * Add source to custom diagnostics * Show custom diagnostics as `TSTL` in CLI * Fix quotes * Always import tstl as a namespace in tests * Simplify tstl object formatting in deprecation warning * Add Lua AST to TranspiledFile interface --- .prettierignore | 1 - build_lualib.ts | 43 +- jest.config.js | 10 +- package-lock.json | 6 +- package.json | 2 +- src/CommandLineParser.ts | 499 ++++++------------ src/Compiler.ts | 189 ------- src/Emit.ts | 78 +++ src/LuaAST.ts | 42 +- src/LuaPrinter.ts | 22 +- src/LuaTransformer.ts | 46 +- src/LuaTranspiler.ts | 158 ------ src/Transpile.ts | 179 +++++++ src/diagnostics.ts | 88 +++ src/index.ts | 128 ++++- src/tstl.ts | 295 ++++++++++- test/cli/errors.spec.ts | 27 + test/cli/errors/error.ts | 2 + test/cli/run.ts | 31 ++ test/cli/watch.spec.ts | 66 +++ test/cli/watch/tsconfig.json | 1 + test/cli/watch/watch.ts | 1 + test/compiler/errorreport.spec.ts | 24 - test/compiler/outfile.spec.ts | 47 -- test/compiler/project.spec.ts | 102 ---- .../projects/baseurl/test_src/main.ts | 5 - test/compiler/projects/baseurl/tsconfig.json | 10 - .../basic/tsconfig.bothDirOptions.json | 7 - test/compiler/projects/basic/tsconfig.json | 7 - .../projects/basic/tsconfig.outDir.json | 6 - .../projects/basic/tsconfig.rootDir.json | 6 - .../compiler/projects/watchmode/tsconfig.json | 7 - test/compiler/projects/watchmode/watch.ts | 1 - test/compiler/testfiles/default_import.ts | 1 - test/compiler/testfiles/invalid_syntax.ts | 1 - test/compiler/testfiles/watch.ts | 1 - test/compiler/watcher_proccess.ts | 5 - test/compiler/watchmode.spec.ts | 74 --- test/setup.ts | 58 ++ test/translation/transformation.spec.ts | 4 +- .../__snapshots__/directories.spec.ts.snap | 41 ++ test/transpile/directories.spec.ts | 33 ++ .../baseurl/src/lib/nested/file.ts} | 0 .../transpile/directories/baseurl/src/main.ts | 3 + .../directories/basic/src/lib}/file.ts | 0 .../directories/basic/src}/main.ts | 0 test/transpile/outFile.spec.ts | 44 ++ .../outFile/index.ts} | 0 test/transpile/run.ts | 24 + test/tsconfig.json | 8 +- test/tslint.json | 2 +- test/unit/assignmentDestructuring.spec.ts | 14 +- test/unit/commandLineParser.spec.ts | 439 +++++++-------- .../configuration/mixed/index.spec.ts | 40 -- .../configuration/mixed/project-tsconfig.json | 8 - .../compiler/configuration/options.spec.ts | 19 - test/unit/conditionals.spec.ts | 6 +- test/unit/expressions.spec.ts | 44 +- test/unit/json.spec.ts | 4 +- test/unit/loops.spec.ts | 76 +-- test/unit/lualib/inlining.spec.ts | 2 +- test/unit/modules.spec.ts | 25 +- test/unit/require.spec.ts | 45 +- test/unit/sourcemaps.spec.ts | 29 +- test/unit/spreadElement.spec.ts | 22 +- test/util.ts | 152 ++---- tsconfig.json | 3 +- 67 files changed, 1747 insertions(+), 1616 deletions(-) delete mode 100644 src/Compiler.ts create mode 100644 src/Emit.ts delete mode 100644 src/LuaTranspiler.ts create mode 100644 src/Transpile.ts create mode 100644 src/diagnostics.ts create mode 100644 test/cli/errors.spec.ts create mode 100644 test/cli/errors/error.ts create mode 100644 test/cli/run.ts create mode 100644 test/cli/watch.spec.ts create mode 100644 test/cli/watch/tsconfig.json create mode 100644 test/cli/watch/watch.ts delete mode 100644 test/compiler/errorreport.spec.ts delete mode 100644 test/compiler/outfile.spec.ts delete mode 100644 test/compiler/project.spec.ts delete mode 100644 test/compiler/projects/baseurl/test_src/main.ts delete mode 100644 test/compiler/projects/baseurl/tsconfig.json delete mode 100644 test/compiler/projects/basic/tsconfig.bothDirOptions.json delete mode 100644 test/compiler/projects/basic/tsconfig.json delete mode 100644 test/compiler/projects/basic/tsconfig.outDir.json delete mode 100644 test/compiler/projects/basic/tsconfig.rootDir.json delete mode 100644 test/compiler/projects/watchmode/tsconfig.json delete mode 100644 test/compiler/projects/watchmode/watch.ts delete mode 100644 test/compiler/testfiles/default_import.ts delete mode 100644 test/compiler/testfiles/invalid_syntax.ts delete mode 100644 test/compiler/testfiles/watch.ts delete mode 100644 test/compiler/watcher_proccess.ts delete mode 100644 test/compiler/watchmode.spec.ts create mode 100644 test/setup.ts create mode 100644 test/transpile/__snapshots__/directories.spec.ts.snap create mode 100644 test/transpile/directories.spec.ts rename test/{compiler/projects/baseurl/test_src/test_lib/nested/lib_file.ts => transpile/directories/baseurl/src/lib/nested/file.ts} (100%) create mode 100644 test/transpile/directories/baseurl/src/main.ts rename test/{compiler/projects/basic/test_src/test_lib => transpile/directories/basic/src/lib}/file.ts (100%) rename test/{compiler/projects/basic/test_src => transpile/directories/basic/src}/main.ts (100%) create mode 100644 test/transpile/outFile.spec.ts rename test/{compiler/testfiles/out_file.ts => transpile/outFile/index.ts} (100%) create mode 100644 test/transpile/run.ts delete mode 100644 test/unit/compiler/configuration/mixed/index.spec.ts delete mode 100644 test/unit/compiler/configuration/mixed/project-tsconfig.json delete mode 100644 test/unit/compiler/configuration/options.spec.ts diff --git a/.prettierignore b/.prettierignore index a9b94c668..fef924d04 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,5 @@ /dist /coverage -/test/compiler/testfiles/invalid_syntax.ts /test/translation/transformation/characterEscapeSequence.ts /src diff --git a/build_lualib.ts b/build_lualib.ts index 18fb24bf7..cca39f055 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -1,34 +1,27 @@ import * as fs from "fs"; import * as glob from "glob"; -import { compile } from "./src/Compiler"; -import { LuaLib as luaLib, LuaLibFeature } from "./src/LuaLib"; +import * as path from "path"; +import * as ts from "typescript"; +import * as tstl from "./src"; +import { LuaLib } from "./src/LuaLib"; -const bundlePath = "./dist/lualib/lualib_bundle.lua"; +const options: tstl.CompilerOptions = { + skipLibCheck: true, + types: [], + luaLibImport: tstl.LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.Lua51, + noHeader: true, + outDir: path.join(__dirname, "./dist/lualib"), + rootDir: path.join(__dirname, "./src/lualib"), +}; -compile([ - "--skipLibCheck", - "--types", - "node", - "--luaLibImport", - "none", - "--luaTarget", - "5.1", - "--noHeader", - "--outDir", - "./dist/lualib", - "--rootDir", - "./src/lualib", - "--noHeader", - "true", - ...glob.sync("./src/lualib/**/*.ts"), -]); +// TODO: Check diagnostics +const { emitResult } = tstl.transpileFiles(glob.sync("./src/lualib/**/*.ts"), options); +emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); +const bundlePath = path.join(__dirname, "./dist/lualib/lualib_bundle.lua"); if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } -const features = Object.keys(LuaLibFeature).map( - lib => LuaLibFeature[lib as keyof typeof LuaLibFeature], -); -const bundle = luaLib.loadFeatures(features); -fs.writeFileSync(bundlePath, bundle); +fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature))); diff --git a/jest.config.js b/jest.config.js index adedec88f..5a98e2b3d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -3,9 +3,15 @@ const isCI = require("is-ci"); /** @type {Partial} */ module.exports = { testMatch: ["**/test/**/*.spec.ts"], - collectCoverageFrom: ["/src/**/*", "!/src/lualib/**/*"], - watchPathIgnorePatterns: ["/watch\\.ts$"], + collectCoverageFrom: [ + "/src/**/*", + "!/src/lualib/**/*", + // https://github.com/facebook/jest/issues/5274 + "!/src/tstl.ts", + ], + watchPathIgnorePatterns: ["cli/watch/[^/]+$"], + setupFilesAfterEnv: ["/test/setup.ts"], testEnvironment: "node", testRunner: "jest-circus/runner", preset: "ts-jest", diff --git a/package-lock.json b/package-lock.json index 93a71eafd..645c6181a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -764,9 +764,9 @@ "dev": true }, "@types/node": { - "version": "9.6.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-9.6.23.tgz", - "integrity": "sha512-d2SJJpwkiPudEQ3+9ysANN2Nvz4QJKUPoe/WL5zyQzI0RaEeZWH5K5xjvUIGszTItHQpFPdH+u51f6G/LkS8Cg==", + "version": "11.13.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.0.tgz", + "integrity": "sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng==", "dev": true }, "@types/stack-utils": { diff --git a/package.json b/package.json index 98ef1b9a5..3a63c6ac1 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@types/glob": "^5.0.35", "@types/jest": "^24.0.11", - "@types/node": "^9.6.23", + "@types/node": "^11.13.0", "fengari": "^0.1.2", "glob": "^7.1.2", "jest": "^24.5.0", diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index b0b552e15..76d5c12ee 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -1,411 +1,242 @@ -import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; +import * as diagnostics from "./diagnostics"; -export type CLIParseResult = ParseResult; - -type ParseResult = - { isValid: true; result: T } - | { isValid: false, errorMessage: string}; - -type ArgumentParseResult = - { isValid: true; result: T; increment?: number } - | { isValid: false, errorMessage: string }; - -interface ParsedCommandLine extends ts.ParsedCommandLine { +export interface ParsedCommandLine extends ts.ParsedCommandLine { options: CompilerOptions; } -interface BaseCLIOption { - aliases: string[]; +interface CommandLineOptionBase { + name: string; + aliases?: string[]; describe: string; - type: string; } -interface CLIOption extends BaseCLIOption { - choices: T[]; - default: T; +interface CommandLineOptionOfEnum extends CommandLineOptionBase { + type: "enum"; + choices: string[]; +} + +interface CommandLineOptionOfBoolean extends CommandLineOptionBase { + type: "boolean"; } -const optionDeclarations: {[key: string]: CLIOption} = { - luaLibImport: { - choices: [LuaLibImportKind.Inline, LuaLibImportKind.Require, LuaLibImportKind.Always, LuaLibImportKind.None], - default: LuaLibImportKind.Inline, +type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean; +const optionDeclarations: CommandLineOption[] = [ + { + name: "luaLibImport", describe: "Specifies how js standard features missing in lua are imported.", type: "enum", - } as CLIOption, - luaTarget: { + choices: Object.values(LuaLibImportKind), + }, + { + name: "luaTarget", aliases: ["lt"], - choices: [LuaTarget.LuaJIT, LuaTarget.Lua53, LuaTarget.Lua52, LuaTarget.Lua51], - default: LuaTarget.LuaJIT, describe: "Specify Lua target version.", type: "enum", - } as CLIOption, - noHeader: { - default: false, + choices: Object.values(LuaTarget), + }, + { + name: "noHeader", describe: "Specify if a header will be added to compiled files.", type: "boolean", - } as CLIOption, - noHoisting: { - default: false, + }, + { + name: "noHoisting", describe: "Disables hoisting.", type: "boolean", - } as CLIOption, - sourceMapTraceback: { - default: false, + }, + { + name: "sourceMapTraceback", describe: "Applies the source map to show source TS files and lines in error tracebacks.", type: "boolean", - } as CLIOption, -}; - -export const { version } = require("../package.json"); - -const helpString = - `Version ${version}\n` + - "Syntax: tstl [options] [files...]\n\n" + - - "Examples: tstl path/to/file.ts [...]\n" + - " tstl -p path/to/tsconfig.json\n\n" + - - "In addition to the options listed below you can also pass options\n" + - "for the typescript compiler (For a list of options use tsc -h).\n" + - "Some tsc options might have no effect."; - -/** - * Parse the supplied arguments. - * The result will include arguments supplied via CLI and arguments from tsconfig. - */ -export function parseCommandLine(args: string[]): CLIParseResult -{ - let commandLine = ts.parseCommandLine(args); - - // Run diagnostics to check for invalid tsc options - const diagnosticsResult = runTsDiagnostics(commandLine); - if (diagnosticsResult.isValid === false) { - return diagnosticsResult; - } + }, +]; - // This will add TS and TSTL options from a tsconfig - const configResult = readTsConfig(commandLine); - if (configResult.isValid === true) { - commandLine = configResult.result; - } else { - return { isValid: false, errorMessage: configResult.errorMessage }; - } +export const version = `Version ${require("../package.json").version}`; - // Run diagnostics to check for invalid tsconfig - const diagnosticsResult2 = runTsDiagnostics(commandLine); - if (diagnosticsResult2.isValid === false) { - return diagnosticsResult2; - } +const helpString = ` +Syntax: tstl [options] [files...] - // Merge TSTL CLI options in (highest priority) will also set defaults if none specified - const tstlCLIResult = parseTSTLOptions(commandLine, args); - if (tstlCLIResult.isValid === true) { - commandLine = tstlCLIResult.result; - } else { - return { isValid: false, errorMessage: tstlCLIResult.errorMessage }; - } +Examples: tstl path/to/file.ts [...] + tstl -p path/to/tsconfig.json - if (commandLine.options.project && !commandLine.options.rootDir) { - commandLine.options.rootDir = path.dirname(commandLine.options.project); - } - - if (!commandLine.options.rootDir) { - commandLine.options.rootDir = process.cwd(); - } - - if (!commandLine.options.outDir) { - commandLine.options.outDir = commandLine.options.rootDir; - } - - return { isValid: true, result: commandLine as ParsedCommandLine }; -} +In addition to the options listed below you can also pass options +for the typescript compiler (For a list of options use tsc -h). +Some tsc options might have no effect. +`.trim(); export function getHelpString(): string { let result = helpString + "\n\n"; result += "Options:\n"; - for (const optionName in optionDeclarations) { - const option = optionDeclarations[optionName]; - const aliasStrings = option.aliases - ? option.aliases.map(a => "-" + a) - : []; - - const optionString = aliasStrings.concat(["--" + optionName]).join("|"); + for (const option of optionDeclarations) { + const aliasStrings = (option.aliases || []).map(a => "-" + a); + const optionString = aliasStrings.concat(["--" + option.name]).join("|"); - const parameterDescribe = option.choices - ? option.choices.join("|") - : option.type; + const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; + const spacing = " ".repeat(Math.max(1, 45 - optionString.length - valuesHint.length)); - const spacing = " ".repeat(Math.max(1, 45 - optionString.length - parameterDescribe.length)); - - result += `\n ${optionString} <${parameterDescribe}>${spacing}${option.describe}\n`; + result += `\n ${optionString} <${valuesHint}>${spacing}${option.describe}\n`; } return result; } -function readTsConfig(parsedCommandLine: ts.ParsedCommandLine): CLIParseResult -{ - const options = parsedCommandLine.options; - - // Load config - if (options.project) { - const findProjectPathResult = findConfigFile(options); - if (findProjectPathResult.isValid === true) { - options.project = findProjectPathResult.result; - } else { - return { isValid: false, errorMessage: findProjectPathResult.errorMessage }; - } - - const configPath = options.project; - const parsedJsonConfig = parseTsConfigFile(configPath, options); +export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { + let hasRootLevelOptions = false; + for (const key in parsedConfigFile.raw) { + const option = optionDeclarations.find(option => option.name === key); + if (!option) continue; - return parsedJsonConfig; + if (parsedConfigFile.raw.tstl === undefined) parsedConfigFile.raw.tstl = {}; + parsedConfigFile.raw.tstl[key] = parsedConfigFile.raw[key]; + hasRootLevelOptions = true; } - return { isValid: true, result: parsedCommandLine }; -} - -export function parseTsConfigFile(filePath: string, existingOptions?: ts.CompilerOptions): CLIParseResult { - const configContents = fs.readFileSync(filePath).toString(); - return parseTsConfigString(configContents, filePath, existingOptions); -} -export function parseTsConfigString( - tsConfigString: string, - configPath: string, - existingOptions?: ts.CompilerOptions -): CLIParseResult { - const configJson = ts.parseConfigFileTextToJson(configPath, tsConfigString); - const parsedJsonConfig = ts.parseJsonConfigFileContent( - configJson.config, - ts.sys, - path.dirname(configPath), - existingOptions - ); - - for (const key in parsedJsonConfig.raw) { - const option = optionDeclarations[key]; - if (option !== undefined) { - const value = readValue(parsedJsonConfig.raw[key], option.type, key); - if (option.choices) { - if (option.choices.indexOf(value) < 0) { - return { - isValid: false, - errorMessage: `Unknown ${key} value '${value}'.\nAccepted values: ${option.choices}`, - }; - } - } - // console.warn(`[Deprectated] TSTL options are moving to the luaConfig object. Adjust your tsconfig to ` - // + `look like { "compilerOptions": { }, "tstl": { } }`); - parsedJsonConfig.options[key] = value; + if (parsedConfigFile.raw.tstl) { + if (hasRootLevelOptions) { + parsedConfigFile.errors.push( + diagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl) + ); } - } - // Eventually we will only look for the tstl object for tstl options - if (parsedJsonConfig.raw.tstl) { - for (const key in parsedJsonConfig.raw.tstl) { - const option = optionDeclarations[key]; - if (option !== undefined) { - const value = readValue(parsedJsonConfig.raw.tstl[key], option.type, key); - if (option.choices) { - if (option.choices.indexOf(value) < 0) { - return { - isValid: false, - errorMessage: `Unknown ${key} value '${value}'.\nAccepted values: ${option.choices}`, - }; - } - } - - parsedJsonConfig.options[key] = value; + for (const key in parsedConfigFile.raw.tstl) { + const option = optionDeclarations.find(option => option.name === key); + if (!option) { + parsedConfigFile.errors.push(diagnostics.unknownCompilerOption(key)); + continue; } + + const { error, value } = readValue(option, parsedConfigFile.raw.tstl[key]); + if (error) parsedConfigFile.errors.push(error); + if (parsedConfigFile.options[key] === undefined) parsedConfigFile.options[key] = value; } } - return { isValid: true, result: parsedJsonConfig }; + return parsedConfigFile; } -function parseTSTLOptions(commandLine: ts.ParsedCommandLine, args: string[]): CLIParseResult { - const result: { [key: string]: string | boolean } = {}; - for (let i = 0; i < args.length; i++) { - if (args[i].startsWith("--")) { - const argumentName = args[i].substr(2); - const option = optionDeclarations[argumentName]; - if (option) { - const argumentResult = getArgumentValue(argumentName, i, args); - if (argumentResult.isValid === true) { - result[argumentName] = argumentResult.result; - // Skip value from being considered as option - i += argumentResult.increment !== undefined ? argumentResult.increment : 1; - } else { - return { isValid: false, errorMessage: argumentResult.errorMessage }; - } - } - } else if (args[i].startsWith("-")) { - const argument = args[i].substr(1); - let argumentName: string | undefined; - for (const key in optionDeclarations) { - if (optionDeclarations[key].aliases && optionDeclarations[key].aliases.indexOf(argument) >= 0) { - argumentName = key; - break; - } - } - - if (argumentName !== undefined) { - const argumentResult = getArgumentValue(argumentName, i, args); - if (argumentResult.isValid === true) { - result[argumentName] = argumentResult.result; - // Skip value from being considered as option - i += argumentResult.increment !== undefined ? argumentResult.increment : 1; - } else { - return { isValid: false, errorMessage: argumentResult.errorMessage }; - } - } - } - } - for (const option in result) { - commandLine.options[option] = result[option]; - } - // Add defaults if not set - const defaultOptions = getDefaultOptions(); - for (const option in defaultOptions) { - if (!commandLine.options[option]) { - commandLine.options[option] = defaultOptions[option]; - } - } - return { isValid: true, result: commandLine }; +export function parseCommandLine(args: string[]): ParsedCommandLine { + return updateParsedCommandLine(ts.parseCommandLine(args), args); } -function getArgumentValue( - argumentName: string, - argumentIndex: number, +function updateParsedCommandLine( + parsedCommandLine: ts.ParsedCommandLine, args: string[] -): ArgumentParseResult -{ - const option = optionDeclarations[argumentName]; - const argument = args[argumentIndex + 1]; - - if (option.type === "boolean" && (argument === undefined || argument.startsWith("-"))) { - // Set boolean arguments without supplied value to true - return { isValid: true, result: true, increment: 0 }; - } - - if (argument === undefined) { - return { isValid: false, errorMessage: `Missing value for parameter ${argumentName}`}; - } +): ParsedCommandLine { + for (let i = 0; i < args.length; i++) { + if (!args[i].startsWith("-")) continue; + + const isShorthand = !args[i].startsWith("--"); + const argumentName = args[i].substr(isShorthand ? 1 : 2); + const option = optionDeclarations.find(option => { + if (option.name.toLowerCase() === argumentName.toLowerCase()) return true; + if (isShorthand && option.aliases) { + return option.aliases.some(a => a.toLowerCase() === argumentName.toLowerCase()); + } - const value = readValue(argument, option.type, argumentName); + return false; + }); - if (option.choices) { - if (option.choices.indexOf(value) < 0) { - return { - isValid: false, - errorMessage: `Unknown ${argumentName} value '${value}'. Accepted values are: ${option.choices}`, - }; + if (option) { + // Ignore errors caused by tstl specific compiler options + const tsInvalidCompilerOptionErrorCode = 5023; + parsedCommandLine.errors = parsedCommandLine.errors.filter(err => { + return !( + err.code === tsInvalidCompilerOptionErrorCode && + String(err.messageText).endsWith(`'${args[i]}'.`) + ); + }); + + const { error, value, increment } = readCommandLineArgument(option, args[i + 1]); + if (error) parsedCommandLine.errors.push(error); + parsedCommandLine.options[option.name] = value; + i += increment; } } - return { isValid: true, result: value }; + return parsedCommandLine; } -function readValue(value: string | boolean, valueType: string, parameterName: string): string | boolean { - if (valueType === "boolean") { - return value === true || value === "true" || value === "t" - ? true - : false; - } else if (valueType === "enum") { - return value.toString().toLowerCase(); - } else { - return value; - } +interface CommandLineArgument extends ReadValueResult { + increment: number; } -function getDefaultOptions(): CompilerOptions { - const options: CompilerOptions = {}; - - for (const optionName in optionDeclarations) { - if (optionDeclarations[optionName].default !== undefined) { - options[optionName] = optionDeclarations[optionName].default; +function readCommandLineArgument(option: CommandLineOption, value: any): CommandLineArgument { + if (option.type === "boolean") { + if (value === "true" || value === "false") { + value = value === "true"; + } else { + // Set boolean arguments without supplied value to true + return { value: true, increment: 0 }; } + } else if (value === undefined) { + return { + error: diagnostics.compilerOptionExpectsAnArgument(option.name), + value: undefined, + increment: 0, + }; } - return options; + return { ...readValue(option, value), increment: 1 }; } -/** Check the current state of the ParsedCommandLine for errors */ -function runTsDiagnostics(commandLine: ts.ParsedCommandLine): ParseResult { - // Remove files that dont exist - commandLine.fileNames = commandLine.fileNames.filter(file => fs.existsSync(file) || fs.existsSync(file + ".ts")); - - const tsInvalidCompilerOptionErrorCode = 5023; - if (commandLine.errors.length !== 0) { - // Generate a list of valid option names and aliases - const optionNames: string[] = []; - for (const key of Object.keys(optionDeclarations)) { - optionNames.push(key); - const alias = optionDeclarations[key].aliases; - if (alias) { - if (typeof alias === "string") { - optionNames.push(alias); - } else { - optionNames.push(...alias); - } - } - } +interface ReadValueResult { + error?: ts.Diagnostic; + value: any; +} - for (const err of commandLine.errors) { - // Ignore errors caused by tstl specific compiler options - if (err.code === tsInvalidCompilerOptionErrorCode) { - let ignore = false; - for (const optionName of optionNames) { - if (err.messageText.toString().indexOf(optionName) !== -1) { - ignore = true; - break; - } - } - - if (!ignore) { - return { isValid: false, errorMessage: `error TS${err.code}: ${err.messageText}`}; - } +function readValue(option: CommandLineOption, value: unknown): ReadValueResult { + if (value === null) return { value }; + + switch (option.type) { + case "boolean": { + if (typeof value !== "boolean") { + return { + value: undefined, + error: diagnostics.compilerOptionRequiresAValueOfType(option.name, "boolean"), + }; } + + return { value }; } - } - return { isValid: true, result: true }; -} + case "enum": { + if (typeof value !== "string") { + return { + value: undefined, + error: diagnostics.compilerOptionRequiresAValueOfType(option.name, "string"), + }; + } -/** Find configFile, function from ts api seems to be broken? */ -export function findConfigFile(options: ts.CompilerOptions): ParseResult { - if (!options.project) { - return { isValid: false, errorMessage: `error no base path provided, could not find config.`}; - } - let configPath = options.project; - // If the project path is wrapped in double quotes, remove them - if (/^".*"$/.test(configPath)) { - configPath = configPath.substring(1, configPath.length - 1); - } - /* istanbul ignore if: Testing else part is not really possible via automated tests */ - if (!path.isAbsolute(configPath)) { - // TODO check if options.project can even contain non absolute paths - configPath = path.join(process.cwd(), configPath); - } - if (fs.statSync(configPath).isDirectory()) { - configPath = path.join(configPath, "tsconfig.json"); - } else if (fs.statSync(configPath).isFile() && path.extname(configPath) === ".ts") { - // Search for tsconfig upwards in directory hierarchy starting from the file path - const dir = path.dirname(configPath).split(path.sep); - for (let i = dir.length; i > 0; i--) { - const searchPath = dir.slice(0, i).join("/") + path.sep + "tsconfig.json"; - - // If tsconfig.json was found, stop searching - if (ts.sys.fileExists(searchPath)) { - configPath = searchPath; - break; + const normalizedValue = value.toLowerCase(); + if (option.choices && !option.choices.includes(normalizedValue)) { + const optionChoices = option.choices.join(", "); + return { + value: undefined, + error: diagnostics.argumentForOptionMustBe(`--${option.name}`, optionChoices), + }; } + + return { value: normalizedValue }; } } +} + +export function parseConfigFileWithSystem( + configFileName: string, + commandLineOptions?: CompilerOptions, + system = ts.sys +): ParsedCommandLine { + const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent( + ts.readJsonConfigFile(configFileName, system.readFile), + system, + path.dirname(configFileName), + commandLineOptions, + configFileName + ); - return { isValid: true, result: configPath }; + return updateParsedConfigFile(parsedConfigFile); } diff --git a/src/Compiler.ts b/src/Compiler.ts deleted file mode 100644 index a053b44e2..000000000 --- a/src/Compiler.ts +++ /dev/null @@ -1,189 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import * as CommandLineParser from "./CommandLineParser"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; -import { LuaTranspiler, TranspileResult } from "./LuaTranspiler"; - -export function compile(argv: string[]): void { - const parseResult = CommandLineParser.parseCommandLine(argv); - - if (parseResult.isValid === true) { - - if (parseResult.result.options.help) { - console.log(CommandLineParser.getHelpString()); - return; - } - - if (parseResult.result.options.version) { - console.log(CommandLineParser.version); - return; - } - - /* istanbul ignore if: tested in test/compiler/watchmode.spec with subproccess */ - if (parseResult.result.options.watch) { - watchWithOptions(parseResult.result.fileNames, parseResult.result.options); - } else { - compileFilesWithOptions(parseResult.result.fileNames, parseResult.result.options); - } - } else { - console.error(`Invalid CLI input: ${parseResult.errorMessage}`); - } -} - -/* istanbul ignore next: tested in test/compiler/watchmode.spec with subproccess */ -export function watchWithOptions(fileNames: string[], options: CompilerOptions): void { - const host = options.project !== undefined - ? ts.createWatchCompilerHost(options.project, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram) - : ts.createWatchCompilerHost(fileNames, options, ts.sys, ts.createSemanticDiagnosticsBuilderProgram); - - let fullRecompile = true; - host.afterProgramCreate = program => { - const transpiler = new LuaTranspiler(program.getProgram()); - let status = transpiler.reportErrors(); - - if (status === 0) { - if (fullRecompile) { - status = transpiler.emitFilesAndReportErrors(); - } else { - while (true) { - const currentFile = program.getSemanticDiagnosticsOfNextAffectedFile(); - if (!currentFile) { break; } - - if ("fileName" in currentFile.affected) { // test if currentFile.affected is `ts.SourceFile` - const fileStatus = transpiler.emitSourceFile(currentFile.affected); - status |= fileStatus; - } else { - for (const sourceFile of currentFile.affected.getSourceFiles()) { - const fileStatus = transpiler.emitSourceFile(sourceFile); - status |= fileStatus; - } - } - } - } - // do a full recompile after transpiler error. - fullRecompile = status !== 0; - } - - const errorDiagnostic: ts.Diagnostic = { - category: ts.DiagnosticCategory.Error, - code: 6194, - file: undefined, - length: 0, - messageText: "Found 0 errors. Watching for file changes.", - start: 0, - }; - if (status !== 0) { - errorDiagnostic.messageText = "Found Errors. Watching for file changes."; - errorDiagnostic.code = 6193; - } - - if (host.onWatchStatusChange) { - host.onWatchStatusChange(errorDiagnostic, host.getNewLine(), program.getCompilerOptions()); - } - }; - - if (options.project !== undefined) { - ts.createWatchProgram( - host as ts.WatchCompilerHostOfConfigFile - ); - } else { - ts.createWatchProgram( - host as ts.WatchCompilerHostOfFilesAndCompilerOptions - ); - } -} - -export function compileFilesWithOptions(fileNames: string[], options: CompilerOptions): void { - const program = ts.createProgram(fileNames, options); - - const transpiler = new LuaTranspiler(program); - - transpiler.emitFilesAndReportErrors(); -} - -const libCache: {[key: string]: ts.SourceFile} = {}; - -const defaultCompilerOptions: CompilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, -}; - -export function createStringCompilerProgram( - input: string | { [filename: string]: string }, - options: CompilerOptions = defaultCompilerOptions, - filePath = "file.ts" -): ts.Program { - const compilerHost = { - directoryExists: () => true, - fileExists: () => true, - getCanonicalFileName: (fileName: string) => fileName, - getCurrentDirectory: () => "", - getDefaultLibFileName: ts.getDefaultLibFileName, - getDirectories: () => [], - getNewLine: () => "\n", - - getSourceFile: (filename: string) => { - switch (typeof input) { - case "string": - if (filename === filePath) { - return ts.createSourceFile(filename, input, ts.ScriptTarget.Latest, false); - } - break; - case "object": - if (filename in input) { - return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); - } - break; - } - - if (filename.startsWith('lib.')) { - if (libCache[filename]) return libCache[filename]; - const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, filename); - const content = fs.readFileSync(filePath, 'utf8'); - - libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); - return libCache[filename]; - } - - return undefined; - }, - - readFile: () => "", - - useCaseSensitiveFileNames: () => false, - // Don't write output - writeFile: () => undefined, - }; - const filePaths = typeof input === "string" ? [filePath] : Object.keys(input); - return ts.createProgram(filePaths, options, compilerHost); -} - -export function transpileString( - input: string | { [filename: string]: string }, - options: CompilerOptions = defaultCompilerOptions, - ignoreDiagnostics = false, - filePath = "file.ts" -): TranspileResult { - const program = createStringCompilerProgram(input, options, filePath); - - if (!ignoreDiagnostics) { - const diagnostics = ts.getPreEmitDiagnostics(program); - const typeScriptErrors = diagnostics.filter(diag => diag.category === ts.DiagnosticCategory.Error); - - if (typeScriptErrors.length > 0) { - typeScriptErrors.forEach(e => console.warn(e.messageText)); - throw new Error("Encountered invalid TypeScript."); - } - } - - const transpiler = new LuaTranspiler(program); - - const sourceFile = program.getSourceFile(filePath); - if (sourceFile !== undefined) { - return transpiler.transpileSourceFile(sourceFile); - } else { - throw new Error(`Could not find file ${filePath} in created program.`); - } -} diff --git a/src/Emit.ts b/src/Emit.ts new file mode 100644 index 000000000..16af6318b --- /dev/null +++ b/src/Emit.ts @@ -0,0 +1,78 @@ +import * as fs from "fs"; +import * as path from "path"; +import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; +import { TranspiledFile } from "./Transpile"; + +const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); +const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); + +export interface OutputFile { + name: string; + text: string; +} + +let lualibContent: string; +export function emitTranspiledFiles( + options: CompilerOptions, + transpiledFiles: Map +): OutputFile[] { + let { rootDir, outDir, outFile, luaLibImport } = options; + + const configFileName = options.configFilePath as string | undefined; + // TODO: Use getCommonSourceDirectory + const baseDir = configFileName ? path.dirname(configFileName) : process.cwd(); + + rootDir = rootDir || baseDir; + outDir = outDir ? path.resolve(baseDir, outDir) : rootDir; + + const files: OutputFile[] = []; + for (const [fileName, { lua, sourceMap, declaration, declarationMap }] of transpiledFiles) { + let outPath = fileName; + if (outDir !== rootDir) { + outPath = path.resolve(outDir, path.relative(rootDir, fileName)); + } + + // change extension or rename to outFile + if (outFile) { + outPath = path.isAbsolute(outFile) ? outFile : path.resolve(baseDir, outFile); + } else { + outPath = trimExt(outPath) + ".lua"; + } + + outPath = normalizeSlashes(outPath); + + if (lua !== undefined) { + files.push({ name: outPath, text: lua }); + } + + if (sourceMap !== undefined && options.sourceMap) { + files.push({ name: outPath + ".map", text: sourceMap }); + } + + if (declaration !== undefined) { + files.push({ name: trimExt(outPath) + ".d.ts", text: declaration }); + } + + if (declarationMap !== undefined) { + files.push({ name: trimExt(outPath) + ".d.ts.map", text: declarationMap }); + } + } + + if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) { + if (lualibContent === undefined) { + lualibContent = fs.readFileSync( + path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), + "utf8" + ); + } + + let outPath = path.resolve(rootDir, "lualib_bundle.lua"); + if (outDir !== rootDir) { + outPath = path.join(outDir, path.relative(rootDir, outPath)); + } + + files.push({ name: normalizeSlashes(outPath), text: lualibContent }); + } + + return files; +} diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 6925fc885..d9983979e 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -1,8 +1,8 @@ // Simplified Lua AST based roughly on http://lua-users.org/wiki/MetaLuaAbstractSyntaxTree, // https://www.lua.org/manual/5.3/manual.html (9 – The Complete Syntax of Lua) and the TS AST implementation -// We can ellide a lot of nodes especially tokens and keyowords -// becasue we dont create the AST from text +// We can elide a lot of nodes especially tokens and keywords +// because we dont create the AST from text import * as ts from "typescript"; @@ -41,14 +41,14 @@ export enum SyntaxKind { TableIndexExpression, // Operators // Arithmetic - AdditionOperator, // Maybe use abreviations for those add, sub, mul ... - SubractionOperator, + AdditionOperator, // Maybe use abbreviations for those add, sub, mul ... + SubtractionOperator, MultiplicationOperator, DivisionOperator, FloorDivisionOperator, ModuloOperator, PowerOperator, - NegationOperator, // Unaray minus + NegationOperator, // Unary minus // Concat ConcatOperator, // Length @@ -87,7 +87,7 @@ export type BinaryBitwiseOperator = SyntaxKind.BitwiseAndOperator | SyntaxKind.B | SyntaxKind.BitwiseLeftShiftOperator; export type BinaryOperator = - SyntaxKind.AdditionOperator | SyntaxKind.SubractionOperator | SyntaxKind.MultiplicationOperator + SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator @@ -288,7 +288,7 @@ export function createAssignmentStatement( export interface IfStatement extends Statement { kind: SyntaxKind.IfStatement; - condtion: Expression; + condition: Expression; ifBlock: Block; elseBlock?: Block | IfStatement; } @@ -298,7 +298,7 @@ export function isIfStatement(node: Node): node is IfStatement { } export function createIfStatement( - condtion: Expression, + condition: Expression, ifBlock: Block, elseBlock?: Block | IfStatement, tsOriginal?: ts.Node, @@ -306,8 +306,8 @@ export function createIfStatement( ): IfStatement { const statement = createNode(SyntaxKind.IfStatement, tsOriginal, parent) as IfStatement; - setParent(condtion, statement); - statement.condtion = condtion; + setParent(condition, statement); + statement.condition = condition; setParent(ifBlock, statement); statement.ifBlock = ifBlock; setParent(ifBlock, statement); @@ -326,7 +326,7 @@ export function isIterationStatement(node: Node): node is IterationStatement { export interface WhileStatement extends IterationStatement { kind: SyntaxKind.WhileStatement; - condtion: Expression; + condition: Expression; } export function isWhileStatement(node: Node): node is WhileStatement { @@ -335,7 +335,7 @@ export function isWhileStatement(node: Node): node is WhileStatement { export function createWhileStatement( body: Block, - condtion: Expression, + condition: Expression, tsOriginal?: ts.Node, parent?: Node ): WhileStatement @@ -343,14 +343,14 @@ export function createWhileStatement( const statement = createNode(SyntaxKind.WhileStatement, tsOriginal, parent) as WhileStatement; setParent(body, statement); statement.body = body; - setParent(condtion, statement); - statement.condtion = condtion; + setParent(condition, statement); + statement.condition = condition; return statement; } export interface RepeatStatement extends IterationStatement { kind: SyntaxKind.RepeatStatement; - condtion: Expression; + condition: Expression; } export function isRepeatStatement(node: Node): node is RepeatStatement { @@ -359,7 +359,7 @@ export function isRepeatStatement(node: Node): node is RepeatStatement { export function createRepeatStatement( body: Block, - condtion: Expression, + condition: Expression, tsOriginal?: ts.Node, parent?: Node ): RepeatStatement @@ -367,8 +367,8 @@ export function createRepeatStatement( const statement = createNode(SyntaxKind.RepeatStatement, tsOriginal, parent) as RepeatStatement; setParent(body, statement); statement.body = body; - setParent(condtion, statement); - statement.condtion = condtion; + setParent(condition, statement); + statement.condition = condition; return statement; } @@ -745,7 +745,7 @@ export function createBinaryExpression( export interface ParenthesizedExpression extends Expression { kind: SyntaxKind.ParenthesizedExpression; - innerEpxression: Expression; + innerExpression: Expression; } export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { @@ -760,7 +760,7 @@ export function createParenthesizedExpression( { const expression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal, parent) as ParenthesizedExpression; setParent(innerExpression, expression); - expression.innerEpxression = innerExpression; + expression.innerExpression = innerExpression; return expression; } @@ -845,7 +845,7 @@ export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): I return createIdentifier(identifier.text, tsOriginal, identifier.symbolId); } -export function createAnnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { +export function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; expression.text = "____"; return expression; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 118ae789b..40b05d8a2 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -10,10 +10,9 @@ import { TSHelper as tsHelper } from "./TSHelper"; type SourceChunk = string | SourceNode; export class LuaPrinter { - /* tslint:disable:object-literal-sort-keys */ private static operatorMap: {[key in tstl.Operator]: string} = { [tstl.SyntaxKind.AdditionOperator]: "+", - [tstl.SyntaxKind.SubractionOperator]: "-", + [tstl.SyntaxKind.SubtractionOperator]: "-", [tstl.SyntaxKind.MultiplicationOperator]: "*", [tstl.SyntaxKind.DivisionOperator]: "/", [tstl.SyntaxKind.FloorDivisionOperator]: "//", @@ -38,7 +37,6 @@ export class LuaPrinter { [tstl.SyntaxKind.BitwiseLeftShiftOperator]: "<<", [tstl.SyntaxKind.BitwiseNotOperator]: "~", }; - /* tslint:enable:object-literal-sort-keys */ private options: CompilerOptions; private currentIndent: string; @@ -117,20 +115,20 @@ export class LuaPrinter { let header = ""; - if (this.options.noHeader === undefined || this.options.noHeader === false) { + if (!this.options.noHeader) { header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`; } if (luaLibFeatures) { + const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Inline; // Require lualib bundle - if ((this.options.luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) - || this.options.luaLibImport === LuaLibImportKind.Always) + if ((luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) + || luaLibImport === LuaLibImportKind.Always) { header += `require("lualib_bundle");\n`; } // Inline lualib features - else if (this.options.luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) - { + else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { header += "-- Lua Library inline imports\n"; header += LuaLib.loadFeatures(luaLibFeatures); } @@ -312,7 +310,7 @@ export class LuaPrinter { const prefix = isElseIf ? "elseif" : "if"; - chunks.push(this.indent(prefix + " "), this.printExpression(statement.condtion), " then\n"); + chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n"); this.pushIndent(); chunks.push(this.printBlock(statement.ifBlock)); @@ -338,7 +336,7 @@ export class LuaPrinter { private printWhileStatement(statement: tstl.WhileStatement): SourceNode { const chunks: SourceChunk[] = []; - chunks.push(this.indent("while "), this.printExpression(statement.condtion), " do\n"); + chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n"); this.pushIndent(); chunks.push(this.printBlock(statement.body)); @@ -358,7 +356,7 @@ export class LuaPrinter { chunks.push(this.printBlock(statement.body)); this.popIndent(); - chunks.push(this.indent("until "), this.printExpression(statement.condtion)); + chunks.push(this.indent("until "), this.printExpression(statement.condition)); return this.concatNodes(...chunks); } @@ -613,7 +611,7 @@ export class LuaPrinter { } private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { - return this.createSourceNode(expression, ["(", this.printExpression(expression.innerEpxression), ")"]); + return this.createSourceNode(expression, ["(", this.printExpression(expression.innerExpression), ")"]); } private printCallExpression(expression: tstl.CallExpression): SourceNode { diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 59a91edbb..979d2d6ee 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -44,12 +44,11 @@ export class LuaTransformer { "not", "or", "repeat", "return", "self", "then", "until", "while", ]); - private isStrict = true; + private isStrict: boolean; private luaTarget: LuaTarget; private checker: ts.TypeChecker; protected options: CompilerOptions; - protected program: ts.Program; private isModule = false; @@ -70,17 +69,16 @@ export class LuaTransformer { private readonly typeValidationCache: Map> = new Map>(); - public constructor(program: ts.Program, options: CompilerOptions) { + public constructor(protected program: ts.Program) { this.checker = program.getTypeChecker(); - this.options = options; - this.program = program; + this.options = program.getCompilerOptions(); this.isStrict = this.options.alwaysStrict !== undefined || (this.options.strict !== undefined && this.options.alwaysStrict !== false) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); - this.luaTarget = options.luaTarget || LuaTarget.LuaJIT; + this.luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; this.setupState(); } @@ -970,7 +968,7 @@ export class LuaTransformer { } private transformClassInstanceFields( - classDeclarataion: ts.ClassLikeDeclaration, + classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): tstl.Statement[] { @@ -991,8 +989,8 @@ export class LuaTransformer { statements.push(assignClassField); } - const getOverrides = classDeclarataion.members.filter(m => - tsHelper.isGetAccessorOverride(m, classDeclarataion, this.checker) + const getOverrides = classDeclaration.members.filter(m => + tsHelper.isGetAccessorOverride(m, classDeclaration, this.checker) ) as ts.GetAccessorDeclaration[]; for (const getter of getOverrides) { @@ -1045,7 +1043,7 @@ export class LuaTransformer { const declarationName = this.transformIdentifier(declaration.name as ts.Identifier); if (declaration.initializer) { // self.declarationName = declarationName or initializer - const assignement = tstl.createAssignmentStatement( + const assignment = tstl.createAssignmentStatement( tstl.createTableIndexExpression( this.createSelfIdentifier(), tstl.createStringLiteral(declarationName.text) ), @@ -1055,17 +1053,17 @@ export class LuaTransformer { tstl.SyntaxKind.OrOperator ) ); - bodyWithFieldInitializers.push(assignement); + bodyWithFieldInitializers.push(assignment); } else { // self.declarationName = declarationName - const assignement = tstl.createAssignmentStatement( + const assignment = tstl.createAssignmentStatement( tstl.createTableIndexExpression( this.createSelfIdentifier(), tstl.createStringLiteral(declarationName.text) ), declarationName ); - bodyWithFieldInitializers.push(assignement); + bodyWithFieldInitializers.push(assignment); } } @@ -1686,7 +1684,7 @@ export class LuaTransformer { //function(____, ...) const nextFunctionDeclaration = tstl.createFunctionExpression( tstl.createBlock(nextBody), - [tstl.createAnnonymousIdentifier()], + [tstl.createAnonymousIdentifier()], tstl.createDotsLiteral()); //____it = {next = function(____, ...)} @@ -1825,7 +1823,7 @@ export class LuaTransformer { table = this.transformIdentifier(statement.initializer); } else { // Contain the expression in a temporary variable - table = tstl.createAnnonymousIdentifier(); + table = tstl.createAnonymousIdentifier(); if (statement.initializer) { statements.push(tstl.createVariableDeclarationStatement( table, this.transformExpression(statement.initializer))); @@ -1844,7 +1842,7 @@ export class LuaTransformer { ? this.filterUndefinedAndCast( statement.name.elements.map(e => this.transformArrayBindingElement(e)), tstl.isIdentifier) - : tstl.createAnnonymousIdentifier(statement.name); + : tstl.createAnonymousIdentifier(statement.name); // Don't unpack TupleReturn decorated functions if (statement.initializer) { @@ -1978,7 +1976,7 @@ export class LuaTransformer { if (!ts.isCallLikeExpression(expression)) { // Assign expression statements to dummy to make sure they're legal lua return tstl.createVariableDeclarationStatement( - tstl.createAnnonymousIdentifier(), + tstl.createAnonymousIdentifier(), this.transformExpression(expression) ); } @@ -2712,7 +2710,7 @@ export class LuaTransformer { // Destructuring assignment const left = expression.left.elements.length > 0 ? expression.left.elements.map(e => this.transformExpression(e)) - : [tstl.createAnnonymousIdentifier(expression.left)]; + : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { if (expression.right.elements.length > 0) { @@ -2760,7 +2758,7 @@ export class LuaTransformer { // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() const left = expression.left.elements.length > 0 ? expression.left.elements.map(e => this.transformExpression(e)) - : [tstl.createAnnonymousIdentifier(expression.left)]; + : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { right = expression.right.elements.length > 0 @@ -2956,7 +2954,7 @@ export class LuaTransformer { case ts.SyntaxKind.BarBarToken: return tstl.SyntaxKind.OrOperator; case ts.SyntaxKind.MinusToken: - return tstl.SyntaxKind.SubractionOperator; + return tstl.SyntaxKind.SubtractionOperator; case ts.SyntaxKind.PlusToken: if (ts.isBinaryExpression(node)) { // Check is we need to use string concat operator @@ -2997,7 +2995,7 @@ export class LuaTransformer { public transformClassExpression(expression: ts.ClassExpression): ExpressionVisitResult { const className = expression.name !== undefined ? this.transformIdentifier(expression.name) - : tstl.createAnnonymousIdentifier(); + : tstl.createAnonymousIdentifier(); const classDeclaration = this.transformClassDeclaration(expression, className); return this.createImmediatelyInvokedFunctionExpression( @@ -3320,7 +3318,7 @@ export class LuaTransformer { if (ts.isArrowFunction(node)) { // dummy context for arrow functions with parameters if (node.parameters.length > 0) { - context = tstl.createAnnonymousIdentifier(); + context = tstl.createAnonymousIdentifier(); } } else { // self context @@ -3949,7 +3947,7 @@ export class LuaTransformer { ) ), tstl.createNumericLiteral(1), - tstl.SyntaxKind.SubractionOperator, + tstl.SyntaxKind.SubtractionOperator, node ) ); @@ -4431,7 +4429,7 @@ export class LuaTransformer { if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { return tstl.createIdentifier("nil"); // TODO this is a hack that allows use to keep Identifier // as return time as changing that would break a lot of stuff. - // But this should be changed to retun tstl.createNilLiteral() + // But this should be changed to return tstl.createNilLiteral() // at some point. } diff --git a/src/LuaTranspiler.ts b/src/LuaTranspiler.ts deleted file mode 100644 index 2f9a23ab6..000000000 --- a/src/LuaTranspiler.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; -import * as tstl from "./LuaAST"; -import { LuaPrinter } from "./LuaPrinter"; -import { LuaTransformer } from "./LuaTransformer"; - -export interface TranspileResult { - lua: string; - luaAST: tstl.Node; - sourceMap: string; -} - -export class LuaTranspiler { - private program: ts.Program; - - private options: CompilerOptions; - - private luaTransformer: LuaTransformer; - - private luaPrinter: LuaPrinter; - - constructor(program: ts.Program) { - this.program = program; - this.options = this.getOptions(program); - this.luaTransformer = new LuaTransformer(this.program, this.options); - this.luaPrinter = new LuaPrinter(this.options); - } - - private getOptions(program: ts.Program): CompilerOptions { - const options = program.getCompilerOptions() as CompilerOptions; - - // Make options case-insenstive - if (options.luaTarget) { - options.luaTarget = options.luaTarget.toLowerCase() as LuaTarget; - } - if (options.luaLibImport) { - options.luaLibImport = options.luaLibImport.toLocaleLowerCase() as LuaLibImportKind; - } - - return options; - } - - public reportErrors(): number { - // Get all diagnostics, ignore unsupported extension - const diagnostics = ts.getPreEmitDiagnostics(this.program).filter(diag => diag.code !== 6054); - diagnostics.forEach(diag => this.reportDiagnostic(diag)); - - // If there are errors dont emit - if (diagnostics.filter(diag => diag.category === ts.DiagnosticCategory.Error).length > 0) { - if (!this.options.watch) { - process.exit(1); - } else { - return 1; - } - } - - return 0; - } - - public emitLuaLib(): string { - const outPath = path.join(this.options.outDir || "", "lualib_bundle.lua"); - fs.copyFileSync( - path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), - outPath - ); - return outPath; - } - - public emitFilesAndReportErrors(): number { - let status = this.reportErrors(); - - if (status > 0) { - return status; - } - - this.program.getSourceFiles().forEach(sourceFile => { - const sourceStatus = this.emitSourceFile(sourceFile); - status |= sourceStatus; - }); - - // Copy lualib to target dir - if (this.options.luaLibImport === LuaLibImportKind.Require - || this.options.luaLibImport === LuaLibImportKind.Always - ) { - this.emitLuaLib(); - } - - return status; - } - - public emitSourceFile(sourceFile: ts.SourceFile): number { - if (!sourceFile.isDeclarationFile) { - try { - const rootDir = this.options.rootDir || ""; - - const { lua, luaAST, sourceMap } = this.transpileSourceFile(sourceFile); - - let outPath = sourceFile.fileName; - if (this.options.outDir !== this.options.rootDir) { - const relativeSourcePath = path.resolve(sourceFile.fileName).replace(path.resolve(rootDir), ""); - outPath = path.join(this.options.outDir || "", relativeSourcePath); - } - - // change extension or rename to outFile - if (this.options.outFile) { - if (path.isAbsolute(this.options.outFile)) { - outPath = this.options.outFile; - } else { - // append to workingDir or outDir - outPath = path.resolve(this.options.outDir || "", this.options.outFile); - } - } else { - const fileNameLua = path.basename(outPath, path.extname(outPath)) + ".lua"; - outPath = path.join(path.dirname(outPath), fileNameLua); - } - - // Write output - ts.sys.writeFile(outPath, lua); - if (this.options.sourceMap) { - ts.sys.writeFile(outPath + ".map", sourceMap); - } - } catch (exception) { - /* istanbul ignore else: Testing else part would require to add a bug/exception to our code */ - if (exception.node) { - const pos = ts.getLineAndCharacterOfPosition(sourceFile, exception.node.pos); - // Graciously handle transpilation errors - console.error("Encountered error parsing file: " + exception.message); - console.error(`${sourceFile.fileName} (${1 + pos.line},${pos.character})\n${exception.stack}`); - return 1; - } else { - throw exception; - } - } - } - return 0; - } - - public transpileSourceFile(sourceFile: ts.SourceFile): TranspileResult { - // Transform AST - const [luaAST, lualibFeatureSet] = this.luaTransformer.transformSourceFile(sourceFile); - // Print AST - const [lua, sourceMap] = this.luaPrinter.print(luaAST, lualibFeatureSet, sourceFile.fileName); - - return { lua, luaAST, sourceMap }; - } - - public reportDiagnostic(diagnostic: ts.Diagnostic): void { - if (diagnostic.file) { - const {line, character} = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start!); - const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); - console.log(`${diagnostic.code}: ${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); - } else { - console.log(`${diagnostic.code}: ${ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")}`); - } - } -} diff --git a/src/Transpile.ts b/src/Transpile.ts new file mode 100644 index 000000000..ee59af81d --- /dev/null +++ b/src/Transpile.ts @@ -0,0 +1,179 @@ +import * as ts from "typescript"; +import { CompilerOptions } from "./CompilerOptions"; +import { transpileError } from "./diagnostics"; +import { Block } from './LuaAST'; +import { LuaPrinter } from "./LuaPrinter"; +import { LuaTransformer } from "./LuaTransformer"; +import { TranspileError } from "./TranspileError"; + +function getCustomTransformers( + program: ts.Program, + customTransformers: ts.CustomTransformers, + onSourceFile: (sourceFile: ts.SourceFile) => void +): ts.CustomTransformers { + // TODO: https://github.com/Microsoft/TypeScript/issues/28310 + const forEachSourceFile = ( + node: ts.SourceFile, + callback: (sourceFile: ts.SourceFile) => ts.SourceFile + ) => + ts.isBundle(node) + ? ((ts.updateBundle(node, node.sourceFiles.map(callback)) as unknown) as ts.SourceFile) + : callback(node); + + const luaTransformer: ts.TransformerFactory = () => node => + forEachSourceFile(node, sourceFile => { + onSourceFile(sourceFile); + return ts.createSourceFile(sourceFile.fileName, "", ts.ScriptTarget.ESNext); + }); + + return { + afterDeclarations: customTransformers.afterDeclarations, + before: [ + ...(customTransformers.before || []), + ...(customTransformers.after || []), + luaTransformer, + ], + }; +} + +export interface TranspiledFile { + luaAst?: Block; + lua?: string; + sourceMap?: string; + declaration?: string; + declarationMap?: string; +} + +export interface TranspileResult { + diagnostics: ts.Diagnostic[]; + transpiledFiles: Map; +} + +export interface TranspileOptions { + program: ts.Program; + sourceFiles?: ts.SourceFile[]; + customTransformers?: ts.CustomTransformers; + transformer?: LuaTransformer; + printer?: LuaPrinter; +} + +export function transpile({ + program, + sourceFiles: targetSourceFiles, + customTransformers = {}, + transformer = new LuaTransformer(program), + printer = new LuaPrinter(program.getCompilerOptions()), +}: TranspileOptions): TranspileResult { + const options = program.getCompilerOptions() as CompilerOptions; + + const diagnostics: ts.Diagnostic[] = []; + const transpiledFiles = new Map(); + const updateTranspiledFile = (filePath: string, file: TranspiledFile) => { + if (transpiledFiles.has(filePath)) { + Object.assign(transpiledFiles.get(filePath), file); + } else { + transpiledFiles.set(filePath, file); + } + }; + + if (options.noEmitOnError) { + const preEmitDiagnostics = [ + ...program.getOptionsDiagnostics(), + ...program.getGlobalDiagnostics(), + ]; + + if (targetSourceFiles) { + for (const sourceFile of targetSourceFiles) { + preEmitDiagnostics.push(...program.getSyntacticDiagnostics(sourceFile)); + preEmitDiagnostics.push(...program.getSemanticDiagnostics(sourceFile)); + } + } else { + preEmitDiagnostics.push(...program.getSyntacticDiagnostics()); + preEmitDiagnostics.push(...program.getSemanticDiagnostics()); + } + + if (preEmitDiagnostics.length === 0 && (options.declaration || options.composite)) { + preEmitDiagnostics.push(...program.getDeclarationDiagnostics()); + } + + if (preEmitDiagnostics.length > 0) { + return { diagnostics: preEmitDiagnostics, transpiledFiles }; + } + } + + const processSourceFile = (sourceFile: ts.SourceFile) => { + try { + const [luaAst, lualibFeatureSet] = transformer.transformSourceFile(sourceFile); + if (!options.noEmit && !options.emitDeclarationOnly) { + const [lua, sourceMap] = printer.print( + luaAst, + lualibFeatureSet, + sourceFile.fileName + ); + updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap }); + } + } catch (err) { + if (!(err instanceof TranspileError)) throw err; + + diagnostics.push(transpileError(err)); + + updateTranspiledFile(sourceFile.fileName, { + lua: `error(${JSON.stringify(err.message)})\n`, + sourceMap: "", + }); + } + }; + + const transformers = getCustomTransformers(program, customTransformers, processSourceFile); + + const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { + for (const sourceFile of sourceFiles) { + const isDeclaration = fileName.endsWith(".d.ts"); + const isDeclarationMap = fileName.endsWith(".d.ts.map"); + if (isDeclaration) { + updateTranspiledFile(sourceFile.fileName, { declaration: data }); + } else if (isDeclarationMap) { + updateTranspiledFile(sourceFile.fileName, { declarationMap: data }); + } + } + }; + + const isEmittableJsonFile = (sourceFile: ts.SourceFile) => + sourceFile.flags & ts.NodeFlags.JsonFile && + !options.emitDeclarationOnly && + !program.isSourceFileFromExternalLibrary(sourceFile); + + // We always have to emit to get transformer diagnostics + const oldNoEmit = options.noEmit; + options.noEmit = false; + + if (targetSourceFiles) { + for (const file of targetSourceFiles) { + if (isEmittableJsonFile(file)) { + processSourceFile(file); + } else { + diagnostics.push( + ...program.emit(file, writeFile, undefined, false, transformers).diagnostics + ); + } + } + } else { + diagnostics.push( + ...program.emit(undefined, writeFile, undefined, false, transformers).diagnostics + ); + + // JSON files don't get through transformers and aren't written when outDir is the same as rootDir + program + .getSourceFiles() + .filter(isEmittableJsonFile) + .forEach(processSourceFile); + } + + options.noEmit = oldNoEmit; + + if (options.noEmit || (options.noEmitOnError && diagnostics.length > 0)) { + transpiledFiles.clear(); + } + + return { diagnostics, transpiledFiles }; +} diff --git a/src/diagnostics.ts b/src/diagnostics.ts new file mode 100644 index 000000000..ddc8611c4 --- /dev/null +++ b/src/diagnostics.ts @@ -0,0 +1,88 @@ +import * as ts from "typescript"; +import { TranspileError } from "./TranspileError"; + +export const transpileError = (error: TranspileError) => ({ + file: error.node.getSourceFile(), + start: error.node.getStart(), + length: error.node.getWidth(), + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: error.message, +}); + +export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record) => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Warning, + code: 0, + source: "typescript-to-lua", + messageText: + 'TSTL options are moving to the "tstl" object. Adjust your tsconfig to look like\n' + + `"tstl": ${JSON.stringify(tstl, undefined, 4)}`, +}); + +export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Message, + code: errorCount === 1 ? 6193 : 6194, + messageText: + errorCount === 1 + ? "Found 1 error. Watching for file changes." + : `Found ${errorCount} errors. Watching for file changes.`, +}); + +const createCommandLineError = ( + code: number, + getMessage: (...args: Args) => string +) => (...args: Args): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code, + messageText: getMessage(...args), +}); + +export const unknownCompilerOption = createCommandLineError( + 5023, + (name: string) => `Unknown compiler option '${name}'.` +); + +export const compilerOptionRequiresAValueOfType = createCommandLineError( + 5024, + (name: string, type: string) => `Compiler option '${name}' requires a value of type ${type}.` +); + +export const optionProjectCannotBeMixedWithSourceFilesOnACommandLine = createCommandLineError( + 5042, + () => "Option 'project' cannot be mixed with source files on a command line." +); + +export const cannotFindATsconfigJsonAtTheSpecifiedDirectory = createCommandLineError( + 5057, + (dir: string) => `Cannot find a tsconfig.json file at the specified directory: '${dir}'.` +); + +export const theSpecifiedPathDoesNotExist = createCommandLineError( + 5058, + (dir: string) => `The specified path does not exist: '${dir}'.` +); + +export const compilerOptionExpectsAnArgument = createCommandLineError( + 6044, + (name: string) => `Compiler option '${name}' expects an argument.` +); + +export const argumentForOptionMustBe = createCommandLineError( + 6046, + (name: string, values: string) => `Argument for '${name}' option must be: ${values}.` +); + +export const optionBuildMustBeFirstCommandLineArgument = createCommandLineError( + 6369, + () => "Option '--build' must be the first command line argument." +); diff --git a/src/index.ts b/src/index.ts index eb153d7bc..283fbee02 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,125 @@ -export { parseCommandLine } from "./CommandLineParser"; -export { compile, compileFilesWithOptions, transpileString, watchWithOptions } from "./Compiler"; -export { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; +import * as fs from "fs"; +import * as path from "path"; +import * as ts from "typescript"; +import { parseConfigFileWithSystem } from "./CommandLineParser"; +import { CompilerOptions } from "./CompilerOptions"; +import { emitTranspiledFiles, OutputFile } from "./Emit"; +import { transpile, TranspiledFile, TranspileResult } from "./Transpile"; + +export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./CommandLineParser"; +export * from "./CompilerOptions"; +export * from "./Emit"; +export * from "./LuaAST"; export { LuaLibFeature } from "./LuaLib"; -export { LuaTranspiler } from "./LuaTranspiler"; +export * from "./LuaPrinter"; +export * from "./LuaTransformer"; +export * from "./Transpile"; +export * from "./TranspileError"; + +export interface TranspileFilesResult { + diagnostics: ts.Diagnostic[]; + emitResult: OutputFile[]; +} + +export function transpileFiles( + rootNames: string[], + options: CompilerOptions = {} +): TranspileFilesResult { + const program = ts.createProgram(rootNames, options); + const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); + const emitResult = emitTranspiledFiles(program.getCompilerOptions(), transpiledFiles); + + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...transpileDiagnostics, + ]); + + return { diagnostics: [...diagnostics], emitResult }; +} + +export function transpileProject( + fileName: string, + optionsToExtend?: CompilerOptions +): TranspileFilesResult { + const parseResult = parseConfigFileWithSystem(fileName, optionsToExtend); + if (parseResult.errors.length > 0) { + return { diagnostics: parseResult.errors, emitResult: [] }; + } + + return transpileFiles(parseResult.fileNames, parseResult.options); +} + +const libCache: { [key: string]: ts.SourceFile } = {}; + +/** @internal */ +export function createVirtualProgram( + input: Record, + options: CompilerOptions = {} +): ts.Program { + const compilerHost: ts.CompilerHost = { + fileExists: () => true, + getCanonicalFileName: fileName => fileName, + getCurrentDirectory: () => "", + getDefaultLibFileName: ts.getDefaultLibFileName, + readFile: () => "", + getNewLine: () => "\n", + useCaseSensitiveFileNames: () => false, + writeFile: () => {}, + + getSourceFile: filename => { + if (filename in input) { + return ts.createSourceFile( + filename, + input[filename], + ts.ScriptTarget.Latest, + false + ); + } + + if (filename.startsWith("lib.")) { + if (libCache[filename]) return libCache[filename]; + const typeScriptDir = path.dirname(require.resolve("typescript")); + const filePath = path.join(typeScriptDir, filename); + const content = fs.readFileSync(filePath, "utf8"); + + libCache[filename] = ts.createSourceFile( + filename, + content, + ts.ScriptTarget.Latest, + false + ); + + return libCache[filename]; + } + }, + }; + + return ts.createProgram(Object.keys(input), options, compilerHost); +} + +export function transpileVirtualProject( + files: Record, + options: CompilerOptions = {} +): TranspileResult { + const program = createVirtualProgram(files, options); + const result = transpile({ program }); + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...result.diagnostics, + ]); + + return { ...result, diagnostics: [...diagnostics] }; +} + +export interface TranspileStringResult { + diagnostics: ts.Diagnostic[]; + file?: TranspiledFile; +} + +export function transpileString( + main: string, + options: CompilerOptions = {} +): TranspileStringResult { + const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); + return { diagnostics, file: transpiledFiles.get("main.ts") }; +} diff --git a/src/tstl.ts b/src/tstl.ts index 5055ec8aa..ea6489c3f 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -1,5 +1,296 @@ #!/usr/bin/env node +import * as path from "path"; +import * as ts from "typescript"; +import * as tstl from "."; +import * as CommandLineParser from "./CommandLineParser"; +import * as cliDiagnostics from "./diagnostics"; -import { compile } from "./Compiler"; +function createDiagnosticReporter(pretty: boolean): ts.DiagnosticReporter { + const reporter: ts.DiagnosticReporter = (ts as any).createDiagnosticReporter(ts.sys, pretty); + return diagnostic => { + if (diagnostic.source === "typescript-to-lua") { + diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; + } -compile(process.argv.slice(2)); + reporter(diagnostic); + }; +} + +function createWatchStatusReporter(options?: ts.CompilerOptions): ts.WatchStatusReporter { + return (ts as any).createWatchStatusReporter(ts.sys, shouldBePretty(options)); +} + +function shouldBePretty(options?: ts.CompilerOptions): boolean { + return !options || options.pretty === undefined + ? ts.sys.writeOutputIsTTY !== undefined && ts.sys.writeOutputIsTTY() + : Boolean(options.pretty); +} + +let reportDiagnostic = createDiagnosticReporter(false); +function updateReportDiagnostic(options?: ts.CompilerOptions): void { + reportDiagnostic = createDiagnosticReporter(shouldBePretty(options)); +} + +function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefined { + const { project } = commandLine.options; + if (!project) { + if (commandLine.fileNames.length === 0) { + const searchPath = path.posix.normalize(ts.sys.getCurrentDirectory()); + return ts.findConfigFile(searchPath, ts.sys.fileExists); + } + return; + } + + if (commandLine.fileNames.length !== 0) { + reportDiagnostic(cliDiagnostics.optionProjectCannotBeMixedWithSourceFilesOnACommandLine()); + ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + return; + } + + let fileOrDirectory = path.posix.normalize(project); + if (!path.isAbsolute(fileOrDirectory)) { + fileOrDirectory = path.posix.join(ts.sys.getCurrentDirectory(), fileOrDirectory); + } + + if (!fileOrDirectory || ts.sys.directoryExists(fileOrDirectory)) { + const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); + if (ts.sys.fileExists(configFileName)) { + return configFileName; + } else { + reportDiagnostic( + cliDiagnostics.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project) + ); + ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + } + } else { + if (ts.sys.fileExists(fileOrDirectory)) { + return fileOrDirectory; + } else { + reportDiagnostic(cliDiagnostics.theSpecifiedPathDoesNotExist(project)); + ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + } + } +} + +function executeCommandLine(args: string[]): void { + if (args.length > 0 && args[0].startsWith("-")) { + const firstOption = args[0].slice(args[0].startsWith("--") ? 2 : 1).toLowerCase(); + if (firstOption === "build" || firstOption === "b") { + return performBuild(args.slice(1)); + } + } + + const commandLine = CommandLineParser.parseCommandLine(args); + + if (commandLine.options.build) { + reportDiagnostic(cliDiagnostics.optionBuildMustBeFirstCommandLineArgument()); + return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + } + + // TODO: ParsedCommandLine.errors isn't meant to contain warnings. Once root-level options + // support would be dropped it should be changed to `commandLine.errors.length > 0`. + if (commandLine.errors.some(e => e.category === ts.DiagnosticCategory.Error)) { + commandLine.errors.forEach(reportDiagnostic); + return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + } + + if (commandLine.options.version) { + console.log(CommandLineParser.version); + return ts.sys.exit(ts.ExitStatus.Success); + } + + if (commandLine.options.help) { + console.log(CommandLineParser.version); + console.log(CommandLineParser.getHelpString()); + return ts.sys.exit(ts.ExitStatus.Success); + } + + const configFileName = locateConfigFile(commandLine); + const commandLineOptions = commandLine.options; + if (configFileName) { + const configParseResult = CommandLineParser.parseConfigFileWithSystem( + configFileName, + commandLineOptions + ); + + updateReportDiagnostic(configParseResult.options); + if (configParseResult.options.watch) { + createWatchOfConfigFile(configFileName, commandLineOptions); + } else { + performCompilation( + configParseResult.fileNames, + configParseResult.projectReferences, + configParseResult.options, + ts.getConfigFileParsingDiagnostics(configParseResult) + ); + } + } else { + updateReportDiagnostic(commandLineOptions); + if (commandLineOptions.watch) { + createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions); + } else { + performCompilation( + commandLine.fileNames, + commandLine.projectReferences, + commandLineOptions + ); + } + } +} + +function performBuild(_args: string[]): void { + console.log("Option '--build' is not supported."); + return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); +} + +function performCompilation( + rootNames: string[], + projectReferences: ReadonlyArray | undefined, + options: tstl.CompilerOptions, + configFileParsingDiagnostics?: ReadonlyArray +): void { + const program = ts.createProgram({ + rootNames, + options, + projectReferences, + configFileParsingDiagnostics, + }); + + const { transpiledFiles, diagnostics: transpileDiagnostics } = tstl.transpile({ program }); + + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...transpileDiagnostics, + ]); + + const emitResult = tstl.emitTranspiledFiles(options, transpiledFiles); + emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); + + diagnostics.forEach(reportDiagnostic); + const exitCode = + diagnostics.length === 0 + ? ts.ExitStatus.Success + : transpiledFiles.size === 0 + ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped + : ts.ExitStatus.DiagnosticsPresent_OutputsGenerated; + + return ts.sys.exit(exitCode); +} + +function createWatchOfConfigFile( + configFileName: string, + optionsToExtend: tstl.CompilerOptions +): void { + const watchCompilerHost = ts.createWatchCompilerHost( + configFileName, + optionsToExtend, + ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + undefined, + createWatchStatusReporter(optionsToExtend) + ); + + updateWatchCompilationHost(watchCompilerHost, optionsToExtend); + ts.createWatchProgram(watchCompilerHost); +} + +function createWatchOfFilesAndCompilerOptions( + rootFiles: string[], + options: tstl.CompilerOptions +): void { + const watchCompilerHost = ts.createWatchCompilerHost( + rootFiles, + options, + ts.sys, + ts.createSemanticDiagnosticsBuilderProgram, + undefined, + createWatchStatusReporter(options) + ); + + updateWatchCompilationHost(watchCompilerHost, options); + ts.createWatchProgram(watchCompilerHost); +} + +function updateWatchCompilationHost( + host: ts.WatchCompilerHost, + optionsToExtend: tstl.CompilerOptions +): void { + let fullRecompile = true; + const configFileMap = new WeakMap(); + + host.afterProgramCreate = builderProgram => { + const program = builderProgram.getProgram(); + const options = builderProgram.getCompilerOptions() as tstl.CompilerOptions; + + let configFileParsingDiagnostics: ts.Diagnostic[] = []; + const configFile = options.configFile as ts.TsConfigSourceFile | undefined; + const configFilePath = options.configFilePath as string | undefined; + if (configFile && configFilePath) { + if (!configFileMap.has(configFile)) { + const parsedConfigFile = CommandLineParser.updateParsedConfigFile( + ts.parseJsonSourceFileConfigFileContent( + configFile, + ts.sys, + path.dirname(configFilePath), + optionsToExtend, + configFilePath + ) + ); + + configFileMap.set(configFile, parsedConfigFile); + } + + const parsedConfigFile = configFileMap.get(configFile)!; + Object.assign(options, parsedConfigFile.options); + configFileParsingDiagnostics = parsedConfigFile.errors; + } + + let sourceFiles: ts.SourceFile[] | undefined; + if (!fullRecompile) { + sourceFiles = []; + while (true) { + const currentFile = builderProgram.getSemanticDiagnosticsOfNextAffectedFile(); + if (!currentFile) break; + + if ("fileName" in currentFile.affected) { + sourceFiles.push(currentFile.affected); + } else { + sourceFiles.push(...currentFile.affected.getSourceFiles()); + } + } + } + + const { diagnostics: emitDiagnostics, transpiledFiles } = tstl.transpile({ + program, + sourceFiles, + }); + + const emitResult = tstl.emitTranspiledFiles(options, transpiledFiles); + emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); + + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...configFileParsingDiagnostics, + ...program.getOptionsDiagnostics(), + ...program.getSyntacticDiagnostics(), + ...program.getGlobalDiagnostics(), + ...program.getSemanticDiagnostics(), + ...emitDiagnostics, + ]); + + diagnostics.forEach(reportDiagnostic); + + const errors = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error); + // do a full recompile after an error + fullRecompile = errors.length > 0; + + host.onWatchStatusChange!( + cliDiagnostics.watchErrorSummary(errors.length), + host.getNewLine(), + options + ); + }; +} + +if ((ts.sys as any).setBlocking) (ts.sys as any).setBlocking(); + +executeCommandLine(ts.sys.args); diff --git a/test/cli/errors.spec.ts b/test/cli/errors.spec.ts new file mode 100644 index 000000000..8ff45ce14 --- /dev/null +++ b/test/cli/errors.spec.ts @@ -0,0 +1,27 @@ +import * as fs from "fs"; +import * as path from "path"; +import { runCli } from "./run"; + +const srcFilePath = path.resolve(__dirname, "errors", "error.ts"); +const outFilePath = path.resolve(__dirname, "errors", "error.lua"); +const errorMessage = "Unable to convert function with no 'this' parameter to function with 'this'."; + +afterEach(() => { + if (fs.existsSync(outFilePath)) fs.unlinkSync(outFilePath); +}); + +test("should report errors", async () => { + const { exitCode, output } = await runCli([srcFilePath]); + + expect(output).toContain(errorMessage); + expect(exitCode).toBe(2); + expect(fs.existsSync(outFilePath)).toBe(true); +}); + +test("shouldn't emit files with --noEmitOnError", async () => { + const { exitCode, output } = await runCli(["--noEmitOnError", srcFilePath]); + + expect(output).toContain(errorMessage); + expect(exitCode).toBe(1); + expect(fs.existsSync(outFilePath)).toBe(false); +}); diff --git a/test/cli/errors/error.ts b/test/cli/errors/error.ts new file mode 100644 index 000000000..6b4c5320c --- /dev/null +++ b/test/cli/errors/error.ts @@ -0,0 +1,2 @@ +const foo: (this: void) => void = () => {}; +const bar: () => void = foo; diff --git a/test/cli/run.ts b/test/cli/run.ts new file mode 100644 index 000000000..59d2e9263 --- /dev/null +++ b/test/cli/run.ts @@ -0,0 +1,31 @@ +import { ChildProcess, fork } from "child_process"; +import * as path from "path"; + +jest.setTimeout(20000); + +const cliPath = path.join(__dirname, "../../src/tstl.ts"); + +const defaultArgs = ["--skipLibCheck", "--types", "node"]; +export function forkCli(args: string[]): ChildProcess { + return fork(cliPath, [...defaultArgs, ...args], { + stdio: "pipe", + execArgv: ["--require", "ts-node/register/transpile-only"], + }); +} + +export interface CliResult { + exitCode: number; + output: string; +} + +export async function runCli(args: string[]): Promise { + const child = forkCli(args); + + let output = ""; + child.stdout!.on("data", data => (output += data)); + child.stderr!.on("data", data => (output += data)); + + return new Promise(resolve => { + child.on("close", exitCode => resolve({ exitCode, output })); + }); +} diff --git a/test/cli/watch.spec.ts b/test/cli/watch.spec.ts new file mode 100644 index 000000000..d1274f865 --- /dev/null +++ b/test/cli/watch.spec.ts @@ -0,0 +1,66 @@ +import * as fs from "fs"; +import * as path from "path"; +import { forkCli } from "./run"; + +let testsCleanup: Array<() => void> = []; +afterEach(() => { + testsCleanup.forEach(x => x()); + testsCleanup = []; +}); + +function waitForFileExists(filePath: string): Promise { + return new Promise(resolve => { + const intervalTimerId = setInterval(() => { + if (fs.existsSync(filePath)) { + clearInterval(intervalTimerId); + resolve(); + } + }, 100); + + testsCleanup.push(() => clearInterval(intervalTimerId)); + }); +} + +function forkWatchProcess(args: string[]): void { + const child = forkCli(["--watch", ...args]); + testsCleanup.push(() => child.kill()); +} + +const watchedFile = path.join(__dirname, "./watch/watch.ts"); +const watchedFileOut = watchedFile.replace(".ts", ".lua"); + +afterEach(() => { + if (fs.existsSync(watchedFileOut)) fs.unlinkSync(watchedFileOut); +}); + +async function compileChangeAndCompare(filePath: string, content: string): Promise { + await waitForFileExists(watchedFileOut); + const initialResultLua = fs.readFileSync(watchedFileOut, "utf8"); + + fs.unlinkSync(watchedFileOut); + + const originalContent = fs.readFileSync(filePath, "utf8"); + fs.writeFileSync(filePath, content); + testsCleanup.push(() => fs.writeFileSync(filePath, originalContent)); + + await waitForFileExists(watchedFileOut); + const updatedResultLua = fs.readFileSync(watchedFileOut, "utf8"); + + expect(initialResultLua).not.toEqual(updatedResultLua); +} + +test("should watch single file", async () => { + forkWatchProcess([path.join(__dirname, "./watch/watch.ts")]); + await compileChangeAndCompare(watchedFile, "const value = 1;"); +}); + +test("should watch project", async () => { + forkWatchProcess(["--project", path.join(__dirname, "./watch")]); + await compileChangeAndCompare(watchedFile, "const value = 1;"); +}); + +test("should watch config file", async () => { + const configFilePath = path.join(__dirname, "./watch/tsconfig.json"); + forkWatchProcess(["--project", configFilePath]); + await compileChangeAndCompare(configFilePath, '{ "tstl": { "luaTarget": "5.3" } }'); +}); diff --git a/test/cli/watch/tsconfig.json b/test/cli/watch/tsconfig.json new file mode 100644 index 000000000..922b8de4c --- /dev/null +++ b/test/cli/watch/tsconfig.json @@ -0,0 +1 @@ +{ "tstl": { "luaTarget": "JIT" } } diff --git a/test/cli/watch/watch.ts b/test/cli/watch/watch.ts new file mode 100644 index 000000000..45813bdf9 --- /dev/null +++ b/test/cli/watch/watch.ts @@ -0,0 +1 @@ +const value = 0 & 0; diff --git a/test/compiler/errorreport.spec.ts b/test/compiler/errorreport.spec.ts deleted file mode 100644 index 1c588ee04..000000000 --- a/test/compiler/errorreport.spec.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as path from "path"; -import { compileFilesWithOptions } from "../../src/Compiler"; - -test.each([ - { - errorMsg: - "Encountered error parsing file: Default Imports are not supported, please use named imports instead!", - fileName: "default_import.ts", - }, -])("Compile project (%p)", ({ errorMsg, fileName }) => { - jest.spyOn(console, "log").mockReturnValue(undefined); - const errorMock = jest.spyOn(console, "error").mockReturnValue(undefined); - const exitMock = jest.spyOn(process, "exit").mockReturnValue(undefined as never); - - fileName = path.resolve(__dirname, "testfiles", fileName); - compileFilesWithOptions([fileName], { outDir: ".", rootDir: ".", types: [] }); - - jest.restoreAllMocks(); - - expect(exitMock).toHaveBeenCalledWith(1); - expect(errorMock).toHaveBeenCalledTimes(2); - expect(errorMock).toHaveBeenNthCalledWith(1, errorMsg); - expect(errorMock).toHaveBeenNthCalledWith(2, expect.any(String)); -}); diff --git a/test/compiler/outfile.spec.ts b/test/compiler/outfile.spec.ts deleted file mode 100644 index e82e7341b..000000000 --- a/test/compiler/outfile.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import { compile } from "../../src/Compiler"; - -let outFileRelPath: string; -let outFileAbsPath: string; - -beforeAll(() => { - outFileRelPath = "./testfiles/out_file.script"; - outFileAbsPath = path.join(__dirname, outFileRelPath); -}); - -afterEach(() => { - fs.unlink(outFileAbsPath, err => { - if (err) { - throw err; - } - }); -}); - -test("Outfile absoulte path", () => { - compile([ - "--types", - "node", - "--skipLibCheck", - "--outFile", - outFileAbsPath, - path.join(__dirname, "./testfiles/out_file.ts"), - ]); - - expect(fs.existsSync(outFileAbsPath)).toBe(true); -}); - -test("Outfile relative path", () => { - compile([ - "--types", - "node", - "--skipLibCheck", - "--outDir", - __dirname, - "--outFile", - outFileRelPath, - path.join(__dirname, "./testfiles/out_file.ts"), - ]); - - expect(fs.existsSync(outFileAbsPath)).toBe(true); -}); diff --git a/test/compiler/project.spec.ts b/test/compiler/project.spec.ts deleted file mode 100644 index a23fe9209..000000000 --- a/test/compiler/project.spec.ts +++ /dev/null @@ -1,102 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import { compile } from "../../src/Compiler"; - -/** - * Find all files inside a dir, recursively. - */ -function getAllFiles(dir: string): string[] { - return fs.readdirSync(dir).reduce((files: string[], file) => { - const name = path.join(dir, file); - const isDirectory = fs.statSync(name).isDirectory(); - return isDirectory ? [...files, ...getAllFiles(name)] : [...files, name]; - }, []); -} - -let existingFiles: string[]; -let filesAfterCompile: string[]; - -afterEach(() => { - // Remove files that were created by the test - const createdFiles = filesAfterCompile.filter(v => existingFiles.indexOf(v) < 0); - for (const file of createdFiles) { - fs.unlinkSync(file); - } - existingFiles = []; - filesAfterCompile = []; -}); - -test.each([ - { - projectName: "basic", - tsconfig: "tsconfig.json", - expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], - }, - { - projectName: "basic", - tsconfig: ".", - expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], - }, - { - projectName: "basic", - tsconfig: "test_src/main.ts", - expectedFiles: ["lualib_bundle.lua", "test_src/test_lib/file.lua", "test_src/main.lua"], - }, - { - projectName: "basic", - tsconfig: "tsconfig.outDir.json", - expectedFiles: [ - "out_dir/lualib_bundle.lua", - "out_dir/test_src/test_lib/file.lua", - "out_dir/test_src/main.lua", - ], - }, - { - projectName: "basic", - tsconfig: "tsconfig.rootDir.json", - expectedFiles: [ - "test_src/lualib_bundle.lua", - "test_src/test_lib/file.lua", - "test_src/main.lua", - ], - }, - { - projectName: "basic", - tsconfig: "tsconfig.bothDirOptions.json", - expectedFiles: [ - "out_dir/lualib_bundle.lua", - "out_dir/test_lib/file.lua", - "out_dir/main.lua", - ], - }, - { - projectName: "baseurl", - tsconfig: "tsconfig.json", - expectedFiles: [ - "out_dir/lualib_bundle.lua", - "out_dir/test_src/test_lib/nested/lib_file.lua", - "out_dir/test_src/main.lua", - ], - }, -])("Compile project (%p)", ({ projectName, tsconfig, expectedFiles }) => { - const relPathToProject = path.join("projects", projectName); - - // Setup we cant do this in beforeEach because we need the projectname - existingFiles = getAllFiles(path.resolve(__dirname, relPathToProject)); - filesAfterCompile = []; - // Setup End - - const tsconfigPath = path.resolve(__dirname, relPathToProject, tsconfig); - - compile(["-p", tsconfigPath]); - - filesAfterCompile = getAllFiles(path.resolve(__dirname, relPathToProject)); - expectedFiles = expectedFiles.map(relPath => - path.resolve(__dirname, relPathToProject, relPath), - ); - expectedFiles.push(...existingFiles); - - for (const existingFile of filesAfterCompile) { - expect(expectedFiles).toContain(existingFile); - } -}); diff --git a/test/compiler/projects/baseurl/test_src/main.ts b/test/compiler/projects/baseurl/test_src/main.ts deleted file mode 100644 index 62afd2ad1..000000000 --- a/test/compiler/projects/baseurl/test_src/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as test from "nested/lib_file"; - -let hello = "12"; - -hello = "13"; diff --git a/test/compiler/projects/baseurl/tsconfig.json b/test/compiler/projects/baseurl/tsconfig.json deleted file mode 100644 index 299ae7cf8..000000000 --- a/test/compiler/projects/baseurl/tsconfig.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "luaTarget": "JIT", - "compilerOptions": { - "outDir": "./out_dir", - "rootDir": ".", - "baseUrl": "./test_src/test_lib", - "types": [], - "skipLibCheck": true - } -} diff --git a/test/compiler/projects/basic/tsconfig.bothDirOptions.json b/test/compiler/projects/basic/tsconfig.bothDirOptions.json deleted file mode 100644 index b21881ae5..000000000 --- a/test/compiler/projects/basic/tsconfig.bothDirOptions.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "out_dir", - "rootDir": "test_src" - } -} diff --git a/test/compiler/projects/basic/tsconfig.json b/test/compiler/projects/basic/tsconfig.json deleted file mode 100644 index ec7262ddf..000000000 --- a/test/compiler/projects/basic/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "luaTarget": "JIT", - "compilerOptions": { - "types": [], - "skipLibCheck": true - } -} diff --git a/test/compiler/projects/basic/tsconfig.outDir.json b/test/compiler/projects/basic/tsconfig.outDir.json deleted file mode 100644 index cd2de0d24..000000000 --- a/test/compiler/projects/basic/tsconfig.outDir.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "out_dir" - } -} diff --git a/test/compiler/projects/basic/tsconfig.rootDir.json b/test/compiler/projects/basic/tsconfig.rootDir.json deleted file mode 100644 index d9506e7ee..000000000 --- a/test/compiler/projects/basic/tsconfig.rootDir.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "rootDir": "test_src" - } -} diff --git a/test/compiler/projects/watchmode/tsconfig.json b/test/compiler/projects/watchmode/tsconfig.json deleted file mode 100644 index ec7262ddf..000000000 --- a/test/compiler/projects/watchmode/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "luaTarget": "JIT", - "compilerOptions": { - "types": [], - "skipLibCheck": true - } -} diff --git a/test/compiler/projects/watchmode/watch.ts b/test/compiler/projects/watchmode/watch.ts deleted file mode 100644 index fa2edc21a..000000000 --- a/test/compiler/projects/watchmode/watch.ts +++ /dev/null @@ -1 +0,0 @@ -class MyTest {} diff --git a/test/compiler/testfiles/default_import.ts b/test/compiler/testfiles/default_import.ts deleted file mode 100644 index 9f80d14ac..000000000 --- a/test/compiler/testfiles/default_import.ts +++ /dev/null @@ -1 +0,0 @@ -import Test from "./default_export"; diff --git a/test/compiler/testfiles/invalid_syntax.ts b/test/compiler/testfiles/invalid_syntax.ts deleted file mode 100644 index 6d38d3866..000000000 --- a/test/compiler/testfiles/invalid_syntax.ts +++ /dev/null @@ -1 +0,0 @@ -const variable = () => {} => {}; diff --git a/test/compiler/testfiles/watch.ts b/test/compiler/testfiles/watch.ts deleted file mode 100644 index fa2edc21a..000000000 --- a/test/compiler/testfiles/watch.ts +++ /dev/null @@ -1 +0,0 @@ -class MyTest {} diff --git a/test/compiler/watcher_proccess.ts b/test/compiler/watcher_proccess.ts deleted file mode 100644 index 25b4bd344..000000000 --- a/test/compiler/watcher_proccess.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { compile } from "../../src/Compiler"; - -process.on("message", args => { - compile(args); -}); diff --git a/test/compiler/watchmode.spec.ts b/test/compiler/watchmode.spec.ts deleted file mode 100644 index f4115dcc3..000000000 --- a/test/compiler/watchmode.spec.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { fork } from "child_process"; -import * as fs from "fs"; -import * as path from "path"; - -let testsCleanup: Array<() => void> = []; -afterEach(() => { - testsCleanup.forEach(x => x()); - testsCleanup = []; -}); - -function waitForFileExists(filePath: string): Promise { - return new Promise(resolve => { - const intervalTimerId = setInterval(() => { - if (fs.existsSync(filePath)) { - clearInterval(intervalTimerId); - resolve(); - } - }, 100); - - testsCleanup.push(() => clearInterval(intervalTimerId)); - }); -} - -test.each([ - { - args: [ - "--types", - "node", - "--skipLibCheck", - "-w", - path.join(__dirname, "./testfiles/watch.ts"), - ], - fileToChange: path.join(__dirname, "./testfiles/watch.ts"), - }, - { - args: ["-w", "-p", path.join(__dirname, "./projects/watchmode/")], - fileToChange: path.join(__dirname, "./projects/watchmode/watch.ts"), - }, -])( - "Watch single File (%p)", - async ({ args, fileToChange }) => { - const fileToChangeOut = fileToChange.replace(".ts", ".lua"); - const originalTS = fs.readFileSync(fileToChange, "utf-8"); - - const child = fork(path.join(__dirname, "watcher_proccess.ts"), [], { - silent: true, - execArgv: ["--require", "ts-node/register/transpile-only"], - }); - - testsCleanup.push(() => { - try { - fs.unlinkSync(fileToChangeOut); - } catch (err) { - if (err.code !== "ENOENT") throw err; - } - fs.writeFileSync(fileToChange, originalTS); - child.kill(); - }); - - child.send(args); - - await waitForFileExists(fileToChangeOut); - const initialResultLua = fs.readFileSync(fileToChangeOut, "utf-8"); - - fs.unlinkSync(fileToChangeOut); - fs.writeFileSync(fileToChange, "class MyTest2 {}"); - - await waitForFileExists(fileToChangeOut); - const updatedResultLua = fs.readFileSync(fileToChangeOut, "utf-8"); - - expect(initialResultLua).not.toEqual(updatedResultLua); - }, - 20000, -); diff --git a/test/setup.ts b/test/setup.ts new file mode 100644 index 000000000..8e4e5fbb5 --- /dev/null +++ b/test/setup.ts @@ -0,0 +1,58 @@ +import * as ts from "typescript"; +import * as util from "./util"; + +declare global { + namespace jest { + interface Matchers { + toThrowExactError(error: Error): void; + toHaveDiagnostics(): void; + } + } +} + +expect.extend({ + toThrowExactError(callback: () => void, error: Error): jest.CustomMatcherResult { + if (this.isNot) { + return { pass: true, message: () => "Inverted toThrowExactError is not implemented" }; + } + + let executionError: Error | undefined; + try { + callback(); + } catch (err) { + executionError = err; + } + + // TODO: + if (util.expectToBeDefined(executionError)) { + expect(executionError.message).toContain(error.message); + } + + return { pass: true, message: () => "" }; + }, + toHaveDiagnostics(diagnostics: ts.Diagnostic[]): jest.CustomMatcherResult { + expect(Array.isArray(diagnostics)).toBe(true); + const options = { isNot: this.isNot }; + // @ts-ignore + const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", options); + + const diagnosticMessages = ts.formatDiagnosticsWithColorAndContext(diagnostics, { + getCurrentDirectory: () => "", + getCanonicalFileName: fileName => fileName, + getNewLine: () => "\n", + }); + + return { + pass: diagnostics.length > 0, + message: () => { + return ( + matcherHint + + "\n\n" + + (this.isNot + ? diagnosticMessages + : `Received: ${this.utils.printReceived(diagnostics)}\n`) + ); + }, + }; + }, +}); diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index bd246dddf..d7467a78f 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -1,7 +1,7 @@ import * as fs from "fs"; import * as path from "path"; +import * as tstl from "../../src"; import * as util from "../util"; -import { LuaLibImportKind } from "../../src/CompilerOptions"; const fixturesPath = path.join(__dirname, "./transformation"); const fixtures = fs @@ -11,6 +11,6 @@ const fixtures = fs .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); test.each(fixtures)("Transformation (%s)", (_name, content) => { - const result = util.transpileString(content, { luaLibImport: LuaLibImportKind.Require }); + const result = util.transpileString(content, { luaLibImport: tstl.LuaLibImportKind.Require }); expect(result).toMatchSnapshot(); }); diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap new file mode 100644 index 000000000..952fd709b --- /dev/null +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should be able to resolve ({"name": "baseurl", "options": [Object]}) 1`] = ` +Array [ + "directories/baseurl/out/lualib_bundle.lua", + "directories/baseurl/out/src/lib/nested/file.lua", + "directories/baseurl/out/src/main.lua", +] +`; + +exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` +Array [ + "directories/basic/lualib_bundle.lua", + "directories/basic/src/lib/file.lua", + "directories/basic/src/main.lua", +] +`; + +exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 2`] = ` +Array [ + "directories/basic/out/lualib_bundle.lua", + "directories/basic/out/src/lib/file.lua", + "directories/basic/out/src/main.lua", +] +`; + +exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 3`] = ` +Array [ + "directories/basic/src/lib/file.lua", + "directories/basic/src/lualib_bundle.lua", + "directories/basic/src/main.lua", +] +`; + +exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 4`] = ` +Array [ + "directories/basic/out/lib/file.lua", + "directories/basic/out/lualib_bundle.lua", + "directories/basic/out/main.lua", +] +`; diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts new file mode 100644 index 000000000..877e58f50 --- /dev/null +++ b/test/transpile/directories.spec.ts @@ -0,0 +1,33 @@ +import * as path from "path"; +import * as ts from "typescript"; +import * as tstl from "../../src"; +import { buildVirtualProject } from "./run"; + +interface DirectoryTestCase { + name: string; + options: tstl.CompilerOptions; +} + +test.each([ + { name: "basic", options: {} }, + { name: "basic", options: { outDir: "out" } }, + { name: "basic", options: { rootDir: "src" } }, + { name: "basic", options: { rootDir: "src", outDir: "out" } }, + { name: "baseurl", options: { baseUrl: "./src/lib", rootDir: ".", outDir: "./out" } }, +])("should be able to resolve (%p)", async ({ name, options: compilerOptions }) => { + const projectPath = path.join(__dirname, "directories", name); + jest.spyOn(process, "cwd").mockReturnValue(projectPath); + + const config = { + compilerOptions: { ...compilerOptions, types: [], skipLibCheck: true }, + tstl: { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.Always }, + }; + + const { fileNames, options } = tstl.updateParsedConfigFile( + ts.parseJsonConfigFileContent(config, ts.sys, projectPath), + ); + + const { diagnostics, emittedFiles } = buildVirtualProject(fileNames, options); + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toMatchSnapshot(); +}); diff --git a/test/compiler/projects/baseurl/test_src/test_lib/nested/lib_file.ts b/test/transpile/directories/baseurl/src/lib/nested/file.ts similarity index 100% rename from test/compiler/projects/baseurl/test_src/test_lib/nested/lib_file.ts rename to test/transpile/directories/baseurl/src/lib/nested/file.ts diff --git a/test/transpile/directories/baseurl/src/main.ts b/test/transpile/directories/baseurl/src/main.ts new file mode 100644 index 000000000..1665f4e08 --- /dev/null +++ b/test/transpile/directories/baseurl/src/main.ts @@ -0,0 +1,3 @@ +import { test } from "nested/file"; + +test(); diff --git a/test/compiler/projects/basic/test_src/test_lib/file.ts b/test/transpile/directories/basic/src/lib/file.ts similarity index 100% rename from test/compiler/projects/basic/test_src/test_lib/file.ts rename to test/transpile/directories/basic/src/lib/file.ts diff --git a/test/compiler/projects/basic/test_src/main.ts b/test/transpile/directories/basic/src/main.ts similarity index 100% rename from test/compiler/projects/basic/test_src/main.ts rename to test/transpile/directories/basic/src/main.ts diff --git a/test/transpile/outFile.spec.ts b/test/transpile/outFile.spec.ts new file mode 100644 index 000000000..5a2e9c399 --- /dev/null +++ b/test/transpile/outFile.spec.ts @@ -0,0 +1,44 @@ +import * as path from "path"; +import { buildVirtualProject } from "./run"; + +const inputFilePath = path.join(__dirname, "outFile/index.ts"); +test("should support absolute outFile", () => { + const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { + outFile: path.join(__dirname, "output.script"), + }); + + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toEqual(["output.script"]); +}); + +test("should support relative outFile", () => { + jest.spyOn(process, "cwd").mockReturnValue(__dirname); + const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { + outFile: "output.script", + }); + + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toEqual(["output.script"]); +}); + +test("should support outFile with declaration", () => { + const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { + outFile: path.join(__dirname, "output.script"), + declaration: true, + }); + + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toEqual(["output.d.ts", "output.script"]); +}); + +test("should resolve outFile relative to base directory", () => { + jest.spyOn(process, "cwd").mockReturnValue(__dirname); + const { diagnostics, emittedFiles, emitResult } = buildVirtualProject([inputFilePath], { + outFile: "output.script", + outDir: "out", + declaration: true, + }); + + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toEqual(["output.d.ts", "output.script"]); +}); diff --git a/test/compiler/testfiles/out_file.ts b/test/transpile/outFile/index.ts similarity index 100% rename from test/compiler/testfiles/out_file.ts rename to test/transpile/outFile/index.ts diff --git a/test/transpile/run.ts b/test/transpile/run.ts new file mode 100644 index 000000000..57bbc8f6b --- /dev/null +++ b/test/transpile/run.ts @@ -0,0 +1,24 @@ +import * as ts from "typescript"; +import * as tstl from "../../src"; +import * as path from "path"; + +interface BuildVirtualProjectResult { + diagnostics: ts.Diagnostic[]; + emitResult: tstl.OutputFile[]; + emittedFiles: string[]; +} + +export function buildVirtualProject( + rootNames: string[], + options: tstl.CompilerOptions, +): BuildVirtualProjectResult { + options.skipLibCheck = true; + options.types = []; + + const { diagnostics, emitResult } = tstl.transpileFiles(rootNames, options); + const emittedFiles = emitResult + .map(result => path.relative(__dirname, result.name).replace(/\\/g, "/")) + .sort(); + + return { diagnostics, emitResult, emittedFiles }; +} diff --git a/test/tsconfig.json b/test/tsconfig.json index 666a6006e..684b6c260 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -9,5 +9,11 @@ "noEmit": true, "module": "commonjs" }, - "exclude": ["translation/transformation", "compiler/projects", "compiler/testfiles"] + "exclude": [ + "translation/transformation", + "cli/errors", + "cli/watch", + "transpile/directories", + "transpile/outFile" + ] } diff --git a/test/tslint.json b/test/tslint.json index e8bb9a2cf..2796d7894 100644 --- a/test/tslint.json +++ b/test/tslint.json @@ -42,7 +42,7 @@ "no-var-keyword": true, "object-literal-shorthand": true, "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], - "prefer-const": true, + "prefer-const": [true, { "destructuring": "all" }], "radix": true, "switch-default": false, "triple-equals": [true, "allow-null-check"], diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 34ccacee5..0aeca594d 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import * as util from "../util"; const assignmentDestruturingTs = ` @@ -7,24 +7,24 @@ const assignmentDestruturingTs = ` test("Assignment destructuring [5.1]", () => { const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: LuaTarget.Lua51, - luaLibImport: LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.Lua51, + luaLibImport: tstl.LuaLibImportKind.None, }); expect(lua).toBe(`local a, b = unpack(myFunc())`); }); test("Assignment destructuring [5.2]", () => { const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: LuaTarget.Lua52, - luaLibImport: LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.Lua52, + luaLibImport: tstl.LuaLibImportKind.None, }); expect(lua).toBe(`local a, b = table.unpack(myFunc())`); }); test("Assignment destructuring [JIT]", () => { const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: LuaTarget.LuaJIT, - luaLibImport: LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.LuaJIT, + luaLibImport: tstl.LuaLibImportKind.None, }); expect(lua).toBe(`local a, b = unpack(myFunc())`); }); diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts index 2e4f8d1d2..8572f7c58 100644 --- a/test/unit/commandLineParser.spec.ts +++ b/test/unit/commandLineParser.spec.ts @@ -1,235 +1,206 @@ -import { findConfigFile, parseCommandLine, parseTsConfigString } from "../../src/CommandLineParser"; -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; - -test.each([ - { args: [""], expected: LuaLibImportKind.Inline }, - { args: ["--luaLibImport", "none"], expected: LuaLibImportKind.None }, - { args: ["--luaLibImport", "always"], expected: LuaLibImportKind.Always }, - { args: ["--luaLibImport", "inline"], expected: LuaLibImportKind.Inline }, - { args: ["--luaLibImport", "require"], expected: LuaLibImportKind.Require }, -])("CLI parser luaLibImportKind (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.luaLibImport).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test("CLI parser invalid luaLibImportKind", () => { - const result = parseCommandLine(["--luaLibImport", "invalid"]); - expect(result.isValid).toBe(false); -}); - -test.each([ - { args: [""], expected: LuaTarget.LuaJIT }, - { args: ["--luaTarget", "5.1"], expected: LuaTarget.Lua51 }, - { args: ["--luaTarget", "5.2"], expected: LuaTarget.Lua52 }, - { args: ["--luaTarget", "jit"], expected: LuaTarget.LuaJIT }, - { args: ["--luaTarget", "JIT"], expected: LuaTarget.LuaJIT }, - { args: ["--luaTarget", "5.3"], expected: LuaTarget.Lua53 }, -])("CLI parser luaTarget (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.luaTarget).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { args: ["-lt", "5.1"], expected: LuaTarget.Lua51 }, - { args: ["-lt", "5.2"], expected: LuaTarget.Lua52 }, - { args: ["-lt", "jit"], expected: LuaTarget.LuaJIT }, - { args: ["-lt", "JIT"], expected: LuaTarget.LuaJIT }, - { args: ["-lt", "5.3"], expected: LuaTarget.Lua53 }, -])("CLI parser luaTarget (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.luaTarget).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test("CLI parser invalid luaTarget", () => { - const result = parseCommandLine(["--luatTarget", "invalid"]); - expect(result.isValid).toBe(false); -}); - -test.each([ - { args: [""], expected: false }, - { args: ["--noHeader", "true"], expected: true }, - { args: ["--noHeader", "false"], expected: false }, - { args: ["--noHeader"], expected: true }, - { args: ["--noHeader", "--noHoisting"], expected: true }, -])("CLI parser noHeader (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.noHeader).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { args: [""], expected: false }, - { args: ["--noHoisting", "true"], expected: true }, - { args: ["--noHoisting", "false"], expected: false }, - { args: ["--noHoisting"], expected: true }, - { args: ["--noHoisting", "--noHeader"], expected: true }, -])("CLI parser noHoisting (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.noHoisting).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { args: [""], expected: false }, - { args: ["--project", "tsconfig.json"], expected: true }, - { args: ["-p", "tsconfig.json"], expected: true }, -])("CLI parser project (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.project !== undefined).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test("CLI Parser Multiple Options", () => { - const commandLine = "--project tsconfig.json --noHeader --noHoisting -lt 5.3"; - const result = parseCommandLine(commandLine.split(" ")); - - if (result.isValid === true) { - expect(result.result.options.project).toBeDefined(); - expect(result.result.options.noHeader).toBe(true); - expect(result.result.options.noHoisting).toBe(true); - expect(result.result.options.luaTarget).toBe(LuaTarget.Lua53); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { args: [""], expected: false }, - { args: ["--help"], expected: true }, - { args: ["-h"], expected: true }, -])("CLI parser project (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.help === true).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { args: [""], expected: false }, - { args: ["--version"], expected: true }, - { args: ["-v"], expected: true }, -])("CLI parser project (%p)", ({ args, expected }) => { - const result = parseCommandLine(args); - if (result.isValid === true) { - expect(result.result.options.version === true).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } -}); - -test.each([ - { option: "luaTarget", expected: LuaTarget.LuaJIT }, - { option: "noHeader", expected: false }, - { option: "luaLibImport", expected: "inline" }, - { option: "rootDir", expected: process.cwd() }, - { option: "outDir", expected: process.cwd() }, -])("defaultOption (%p)", ({ option, expected }) => { - const parsedCommandLine = parseCommandLine([]); - if (parsedCommandLine.isValid) { - expect(expected).toBe(parsedCommandLine.result.options[option]); - } else { - expect(parsedCommandLine.isValid).toBeTruthy(); - } -}); - -test("ValidLuaTarget", () => { - const parsedCommandLine = parseCommandLine(["--luaTarget", "5.3"]); - if (parsedCommandLine.isValid) { - expect(parsedCommandLine.result.options["luaTarget"]).toBe("5.3"); - } else { - expect(parsedCommandLine.isValid).toBeTruthy(); - } -}); - -test("InvalidLuaTarget", () => { - // Don't check error message because the yargs library messes the message up. - const result = parseCommandLine(["--luaTarget", "42"]); - expect(result.isValid).toBe(false); -}); - -test("InvalidArgumentTSTL", () => { - // Don't check error message because the yargs library messes the message up. - const result = parseCommandLine(["--invalidTarget", "test"]); - expect(result.isValid).toBe(false); -}); - -test("outDir", () => { - const parsedCommandLine = parseCommandLine(["--outDir", "./test"]); - - if (parsedCommandLine.isValid) { - expect(parsedCommandLine.result.options["outDir"]).toBe("./test"); - } else { - expect(parsedCommandLine.isValid).toBeTruthy(); - } -}); - -test("rootDir", () => { - const parsedCommandLine = parseCommandLine(["--rootDir", "./test"]); - - if (parsedCommandLine.isValid) { - expect(parsedCommandLine.result.options["rootDir"]).toBe("./test"); - expect(parsedCommandLine.result.options["outDir"]).toBe("./test"); - } else { - expect(parsedCommandLine.isValid).toBeTruthy(); - } -}); - -test("outDirAndRooDir", () => { - const parsedCommandLine = parseCommandLine([ - "--outDir", - "./testOut", - "--rootDir", - "./testRoot", - ]); - - if (parsedCommandLine.isValid) { - expect(parsedCommandLine.result.options["outDir"]).toBe("./testOut"); - expect(parsedCommandLine.result.options["rootDir"]).toBe("./testRoot"); - } else { - expect(parsedCommandLine.isValid).toBeTruthy(); - } -}); - -test("Find config no path", () => { - const result = findConfigFile({ options: {}, fileNames: [], errors: [] }); - expect(result.isValid).toBe(false); -}); - -test.each([ - { tsConfig: "{}" }, - { tsConfig: `{ noHeader: true }`, expected: true }, - { tsConfig: `{ noHeader: "true" }`, expected: true }, - { tsConfig: `{ tstl: { noHeader: true } }`, expected: true }, - { tsConfig: `{ tstl: { noHeader: "true" } }`, expected: true }, -])("TsConfig noHeader (%p)", ({ tsConfig, expected }) => { - const result = parseTsConfigString(tsConfig, ""); - - if (result.isValid) { - expect(result.result.options.noHeader).toBe(expected); - } else { - expect(result.isValid).toBeTruthy(); - } +import * as ts from "typescript"; +import * as tstl from "../../src"; + +describe("command line", () => { + test("should support aliases", () => { + const full = tstl.parseCommandLine(["--luaTarget", "5.1"]); + const alias = tstl.parseCommandLine(["-lt", "5.1"]); + expect(full).toEqual(alias); + }); + + test("should support standard typescript options", () => { + const commandLine = "--project tsconfig.json --noHeader -t es3 -lt 5.3"; + const result = tstl.parseCommandLine(commandLine.split(" ")); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options).toEqual({ + project: "tsconfig.json", + noHeader: true, + target: ts.ScriptTarget.ES3, + luaTarget: tstl.LuaTarget.Lua53, + }); + }); + + test("should error on unknown options", () => { + const result = tstl.parseCommandLine(["--unknownOption"]); + + expect(result.errors).toHaveDiagnostics(); + }); + + test("should parse options case-insensitively", () => { + const result = tstl.parseCommandLine(["--NoHeader"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(true); + }); + + describe("enum options", () => { + test("should parse enums", () => { + const result = tstl.parseCommandLine(["--luaTarget", "5.1"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.luaTarget).toBe(tstl.LuaTarget.Lua51); + }); + + test("should be case-insensitive", () => { + for (const value of ["jit", "JiT", "JIT"]) { + const result = tstl.parseCommandLine(["--luaTarget", value]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.luaTarget).toBe(tstl.LuaTarget.LuaJIT); + } + }); + + test("should error on invalid value", () => { + const result = tstl.parseCommandLine(["--luaTarget", "invalid"]); + + expect(result.errors).toHaveDiagnostics(); + }); + }); + + describe("boolean options", () => { + test.each([true, false])("should parse booleans (%p)", value => { + const result = tstl.parseCommandLine(["--noHeader", value.toString()]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(value); + }); + + test("should be case-sensitive", () => { + const result = tstl.parseCommandLine(["--noHeader", "FALSE"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(true); + expect(result.fileNames).toEqual(["FALSE"]); + }); + + test("should be parsed without a value", () => { + const result = tstl.parseCommandLine(["--noHeader"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(true); + }); + + test("shouldn't parse following arguments as values", () => { + const result = tstl.parseCommandLine(["--noHeader", "--noHoisting"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(true); + expect(result.options.noHoisting).toBe(true); + }); + + test("shouldn't parse following files as values", () => { + const result = tstl.parseCommandLine(["--noHeader", "file.ts"]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(true); + }); + }); + + describe("integration", () => { + test.each<[string, string, tstl.CompilerOptions]>([ + ["noHeader", "false", { noHeader: false }], + ["noHeader", "true", { noHeader: true }], + ["noHoisting", "false", { noHoisting: false }], + ["noHoisting", "true", { noHoisting: true }], + ["sourceMapTraceback", "false", { sourceMapTraceback: false }], + ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], + ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], + ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], + ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], + + ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], + ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], + ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], + ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], + ])("--%s %s", (optionName, value, expected) => { + const result = tstl.parseCommandLine([`--${optionName}`, value]); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options).toEqual(expected); + }); + }); +}); + +describe("tsconfig", () => { + const parseConfigFileContent = (config: any) => { + // Specifying `files` option disables automatic file searching, that includes all files in + // the project, making these tests slow. Empty file list is considered as an error. + config.files = ["src/index.ts"]; + return tstl.updateParsedConfigFile(ts.parseJsonConfigFileContent(config, ts.sys, "")); + }; + + test("should support deprecated root-level options", () => { + const rootLevel = parseConfigFileContent({ noHeader: true }); + const namespaced = parseConfigFileContent({ tstl: { noHeader: true } }); + + expect(rootLevel.errors).toEqual([ + expect.objectContaining({ category: ts.DiagnosticCategory.Warning }), + ]); + expect(rootLevel.options).toEqual(namespaced.options); + }); + + test("should allow unknown root-level options", () => { + const result = parseConfigFileContent({ unknownOption: true }); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.unknownOption).toBeUndefined(); + }); + + test("should error on unknown namespaced options", () => { + const result = parseConfigFileContent({ tstl: { unknownOption: true } }); + + expect(result.errors).toHaveDiagnostics(); + expect(result.options.unknownOption).toBeUndefined(); + }); + + test("should parse options case-sensitively", () => { + const result = parseConfigFileContent({ tstl: { NoHeader: true } }); + + expect(result.errors).toHaveDiagnostics(); + expect(result.options.NoHeader).toBeUndefined(); + expect(result.options.noHeader).toBeUndefined(); + }); + + describe("enum options", () => { + test("should parse enums", () => { + const result = parseConfigFileContent({ tstl: { luaTarget: "5.1" } }); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.luaTarget).toBe(tstl.LuaTarget.Lua51); + }); + + test("should be case-insensitive", () => { + for (const value of ["jit", "JiT", "JIT"]) { + const result = parseConfigFileContent({ tstl: { luaTarget: value } }); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.luaTarget).toBe(tstl.LuaTarget.LuaJIT); + } + }); + + test("should error on invalid value", () => { + const result = parseConfigFileContent({ tstl: { luaTarget: "invalid" } }); + + expect(result.errors).toHaveDiagnostics(); + }); + }); + + describe("boolean options", () => { + test.each([true, false])("should parse booleans (%p)", value => { + const result = parseConfigFileContent({ tstl: { noHeader: value } }); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options.noHeader).toBe(value); + }); + + test("shouldn't parse strings", () => { + const result = parseConfigFileContent({ tstl: { noHeader: "true" } }); + + expect(result.errors).toHaveDiagnostics(); + expect(result.options.noHeader).toBeUndefined(); + }); + }); }); diff --git a/test/unit/compiler/configuration/mixed/index.spec.ts b/test/unit/compiler/configuration/mixed/index.spec.ts deleted file mode 100644 index cb98a7d45..000000000 --- a/test/unit/compiler/configuration/mixed/index.spec.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import { parseCommandLine } from "../../../../../src/CommandLineParser"; -import { CompilerOptions, LuaLibImportKind } from "../../../../../src/CompilerOptions"; - -test("tsconfig.json mixed with cmd line args", () => { - const rootPath = __dirname; - const tsConfigPath = path.join(rootPath, "project-tsconfig.json"); - const expectedTsConfig = ts.parseJsonConfigFileContent( - ts.parseConfigFileTextToJson(tsConfigPath, fs.readFileSync(tsConfigPath).toString()).config, - ts.sys, - path.dirname(tsConfigPath), - ); - - const parsedArgs = parseCommandLine([ - "-p", - `"${tsConfigPath}"`, - "--luaLibImport", - LuaLibImportKind.Inline, - `${path.join(rootPath, "test.ts")}`, - ]); - - if (parsedArgs.isValid === true) { - expect(parsedArgs.result.options).toEqual({ - ...expectedTsConfig.options, - // Overridden by cmd args (set to "none" in project-tsconfig.json) - luaLibImport: LuaLibImportKind.Inline, - // Only set in tsconfig, TSTL default is "JIT" - luaTarget: "5.1", - // Only present in TSTL dfaults - noHeader: false, - project: tsConfigPath, - noHoisting: false, - sourceMapTraceback: false, - } as CompilerOptions); - } else { - expect(parsedArgs.isValid).toBeTruthy(); - } -}); diff --git a/test/unit/compiler/configuration/mixed/project-tsconfig.json b/test/unit/compiler/configuration/mixed/project-tsconfig.json deleted file mode 100644 index 3fe0b7e03..000000000 --- a/test/unit/compiler/configuration/mixed/project-tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "compilerOptions": { - "outDir": "./dist/foo/bar", - "rootDir": "./src/foo/bar" - }, - "luaTarget": "5.1", - "luaLibImport": "none" -} diff --git a/test/unit/compiler/configuration/options.spec.ts b/test/unit/compiler/configuration/options.spec.ts deleted file mode 100644 index 31b9a6fe1..000000000 --- a/test/unit/compiler/configuration/options.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { LuaLibImportKind, LuaTarget } from "../../../../src/CompilerOptions"; -import * as util from "../../../util"; - -test.each([LuaTarget.LuaJIT, "jit", "JiT"])("Options luaTarget case-insensitive (%p)", target => { - const options = { luaTarget: target as LuaTarget }; - const result = util.transpileString("~a", options); - - expect(result).toBe("local ____ = bit.bnot(a)"); -}); - -test.each([LuaLibImportKind.None, "none", "NoNe"])( - "Options luaLibImport case-insensitive (%p)", - importKind => { - const options = { luaLibImport: importKind as LuaLibImportKind }; - const result = util.transpileString("const a = new Map();", options); - - expect(result).toBe("local a = Map.new()"); - }, -); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 6d79a37a8..d09d54a7f 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,4 +1,4 @@ -import { LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; @@ -373,8 +373,8 @@ test("switch dead code after return", () => { test("switch not allowed in 5.1", () => { expect(() => - util.transpileString(`switch ("abc") {}`, { luaTarget: LuaTarget.Lua51 }), + util.transpileString(`switch ("abc") {}`, { luaTarget: tstl.LuaTarget.Lua51 }), ).toThrowExactError( - TSTLErrors.UnsupportedForTarget("Switch statements", LuaTarget.Lua51, util.nodeStub), + TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub), ); }); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 7a2268624..28f758a98 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; @@ -99,8 +99,8 @@ test.each([ // Bit operations not supported in 5.1, expect an exception expect(() => util.transpileString(input, { - luaTarget: LuaTarget.Lua51, - luaLibImport: LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.Lua51, + luaLibImport: tstl.LuaLibImportKind.None, }), ).toThrow(); }); @@ -120,7 +120,7 @@ test.each([ { input: "a>>>b", lua: "local ____ = bit.rshift(a, b)" }, { input: "a>>>=b", lua: "a = bit.rshift(a, b)" }, ])("Bitop [JIT] (%p)", ({ input, lua }) => { - const options = { luaTarget: LuaTarget.LuaJIT, luaLibImport: LuaLibImportKind.None }; + const options = { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); }); @@ -139,7 +139,7 @@ test.each([ { input: "a>>>b", lua: "local ____ = bit32.rshift(a, b)" }, { input: "a>>>=b", lua: "a = bit32.rshift(a, b)" }, ])("Bitop [5.2] (%p)", ({ input, lua }) => { - const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; + const options = { luaTarget: tstl.LuaTarget.Lua52, luaLibImport: tstl.LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); }); @@ -156,15 +156,15 @@ test.each([ { input: "a>>>b", lua: "local ____ = a >> b" }, { input: "a>>>=b", lua: "a = a >> b" }, ])("Bitop [5.3] (%p)", ({ input, lua }) => { - const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; + const options = { luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }; expect(util.transpileString(input, options)).toBe(lua); }); test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { expect(() => util.transpileString(input, { - luaTarget: LuaTarget.Lua53, - luaLibImport: LuaLibImportKind.None, + luaTarget: tstl.LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.None, }), ).toThrowExactError( TSTLErrors.UnsupportedKind( @@ -232,12 +232,20 @@ test.each([ }, { input: "true ? undefined : true", options: { strictNullChecks: true } }, { input: "true ? null : true", options: { strictNullChecks: true } }, - { input: "true ? false : true", expected: false, options: { luaTarget: LuaTarget.Lua51 } }, - { input: "false ? false : true", expected: true, options: { luaTarget: LuaTarget.Lua51 } }, - { input: "true ? undefined : true", options: { luaTarget: LuaTarget.Lua51 } }, - { input: "true ? false : true", expected: false, options: { luaTarget: LuaTarget.LuaJIT } }, - { input: "false ? false : true", expected: true, options: { luaTarget: LuaTarget.LuaJIT } }, - { input: "true ? undefined : true", options: { luaTarget: LuaTarget.LuaJIT } }, + { input: "true ? false : true", expected: false, options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { input: "false ? false : true", expected: true, options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { + input: "true ? false : true", + expected: false, + options: { luaTarget: tstl.LuaTarget.LuaJIT }, + }, + { + input: "false ? false : true", + expected: true, + options: { luaTarget: tstl.LuaTarget.LuaJIT }, + }, + { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, ])("Ternary operator (%p)", ({ input, expected, options }) => { const result = util.transpileAndExecute( `const literalValue = 'literal'; @@ -487,7 +495,7 @@ test("Incompatible fromCodePoint expression error", () => { expect(() => util.transpileString("const abc = String.fromCodePoint(123);")).toThrowExactError( TSTLErrors.UnsupportedForTarget( "string property fromCodePoint", - LuaTarget.Lua53, + tstl.LuaTarget.Lua53, util.nodeStub, ), ); @@ -495,7 +503,11 @@ test("Incompatible fromCodePoint expression error", () => { test("Unknown string expression error", () => { expect(() => util.transpileString("const abc = String.abcd();")).toThrowExactError( - TSTLErrors.UnsupportedForTarget("string property abcd", LuaTarget.Lua53, util.nodeStub), + TSTLErrors.UnsupportedForTarget( + "string property abcd", + tstl.LuaTarget.Lua53, + util.nodeStub, + ), ); }); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index 079188cba..e651f71d6 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -12,7 +12,7 @@ test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } "JSON (%p)", json => { const lua = util - .transpileString(json, jsonOptions, false, "file.json") + .transpileString({ "main.json": json }, jsonOptions, false) .replace(/^return ([\s\S]+)$/, "return JSONStringify($1)"); const result = util.executeLua(lua); @@ -21,7 +21,7 @@ test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } ); test("Empty JSON", () => { - expect(() => util.transpileString("", jsonOptions, false, "file.json")).toThrowExactError( + expect(() => util.transpileString({ "main.json": "" }, jsonOptions, false)).toThrowExactError( TSTLErrors.InvalidJsonFileContent(util.nodeStub), ); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index bf1439006..ddf9de97d 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; @@ -418,8 +418,8 @@ test("forof with iterator", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -444,8 +444,8 @@ test("forof with iterator and existing variable", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -469,8 +469,8 @@ test("forof destructuring with iterator", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -496,8 +496,8 @@ test("forof destructuring with iterator and existing variables", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -518,8 +518,8 @@ test("forof lua iterator", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -540,8 +540,8 @@ test("forof array lua iterator", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -563,8 +563,8 @@ test("forof lua iterator with existing variable", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -585,8 +585,8 @@ test("forof lua iterator destructuring", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -609,8 +609,8 @@ test("forof lua iterator destructuring with existing variables", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -634,8 +634,8 @@ test("forof lua iterator tuple-return", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -661,8 +661,8 @@ test("forof lua iterator tuple-return with existing variables", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -678,8 +678,8 @@ test("forof lua iterator tuple-return single variable", () => { for (let x of luaIter()) {} `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( @@ -697,8 +697,8 @@ test("forof lua iterator tuple-return single existing variable", () => { for (x of luaIter()) {} `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( @@ -725,8 +725,8 @@ test("forof forwarded lua iterator", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -754,8 +754,8 @@ test("forof forwarded lua iterator with tupleReturn", () => { return result; `; const compilerOptions = { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, target: ts.ScriptTarget.ES2015, }; const result = util.transpileAndExecute(code, compilerOptions); @@ -769,13 +769,17 @@ test.each([ "for (let a in b) { continue; }", "for (let a of b) { continue; }", ])("loop continue in different lua versions (%p)", loop => { - const lua51 = { luaTarget: LuaTarget.Lua51 }; - const lua52 = { luaTarget: LuaTarget.Lua52 }; - const lua53 = { luaTarget: LuaTarget.Lua53 }; - const luajit = { luaTarget: LuaTarget.LuaJIT }; + const lua51 = { luaTarget: tstl.LuaTarget.Lua51 }; + const lua52 = { luaTarget: tstl.LuaTarget.Lua52 }; + const lua53 = { luaTarget: tstl.LuaTarget.Lua53 }; + const luajit = { luaTarget: tstl.LuaTarget.LuaJIT }; expect(() => util.transpileString(loop, lua51)).toThrowExactError( - TSTLErrors.UnsupportedForTarget("Continue statement", LuaTarget.Lua51, ts.createContinue()), + TSTLErrors.UnsupportedForTarget( + "Continue statement", + tstl.LuaTarget.Lua51, + ts.createContinue(), + ), ); expect(util.transpileString(loop, lua52).indexOf("::__continue1::") !== -1).toBe(true); expect(util.transpileString(loop, lua53).indexOf("::__continue1::") !== -1).toBe(true); diff --git a/test/unit/lualib/inlining.spec.ts b/test/unit/lualib/inlining.spec.ts index f4a6e2b45..fcb5ba938 100644 --- a/test/unit/lualib/inlining.spec.ts +++ b/test/unit/lualib/inlining.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind, LuaTarget } from "../../../src/CompilerOptions"; +import { LuaLibImportKind, LuaTarget } from "../../../src"; import * as util from "../../util"; test("map constructor", () => { diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 6da420d9e..679e6e615 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; @@ -10,8 +10,8 @@ test("defaultImport", () => { test("lualibRequire", () => { const lua = util.transpileString(`let a = b instanceof c;`, { - luaLibImport: LuaLibImportKind.Require, - luaTarget: LuaTarget.LuaJIT, + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.LuaJIT, }); expect(lua.startsWith(`require("lualib_bundle")`)); @@ -19,8 +19,8 @@ test("lualibRequire", () => { test("lualibRequireAlways", () => { const lua = util.transpileString(``, { - luaLibImport: LuaLibImportKind.Always, - luaTarget: LuaTarget.LuaJIT, + luaLibImport: tstl.LuaLibImportKind.Always, + luaTarget: tstl.LuaTarget.LuaJIT, }); expect(lua).toBe(`require("lualib_bundle");`); @@ -37,14 +37,15 @@ test("Non-exported module", () => { expect(result).toBe(3); }); -test.each([LuaLibImportKind.Inline, LuaLibImportKind.None, LuaLibImportKind.Require])( - "LuaLib no uses? No code (%p)", - impKind => { - const lua = util.transpileString(``, { luaLibImport: impKind }); +test.each([ + tstl.LuaLibImportKind.Inline, + tstl.LuaLibImportKind.None, + tstl.LuaLibImportKind.Require, +])("LuaLib no uses? No code (%p)", luaLibImport => { + const lua = util.transpileString(``, { luaLibImport }); - expect(lua).toBe(``); - }, -); + expect(lua).toBe(``); +}); test("Nested module with dot in name", () => { const code = `module a.b { diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index a7e5e378c..f8d6d9a4f 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -2,70 +2,70 @@ import * as util from "../util"; test.each([ { - filePath: "file.ts", + filePath: "main.ts", usedPath: "./folder/Module", expectedPath: "folder.Module", options: { rootDir: "." }, throwsError: false, }, { - filePath: "file.ts", + filePath: "main.ts", usedPath: "./folder/Module", expectedPath: "folder.Module", options: { rootDir: "./" }, throwsError: false, }, { - filePath: "src/file.ts", + filePath: "src/main.ts", usedPath: "./folder/Module", expectedPath: "src.folder.Module", options: { rootDir: "." }, throwsError: false, }, { - filePath: "file.ts", + filePath: "main.ts", usedPath: "folder/Module", expectedPath: "folder.Module", options: { rootDir: ".", baseUrl: "." }, throwsError: false, }, { - filePath: "file.ts", + filePath: "main.ts", usedPath: "folder/Module", expectedPath: "folder.Module", options: { rootDir: "./", baseUrl: "." }, throwsError: false, }, { - filePath: "src/file.ts", + filePath: "src/main.ts", usedPath: "./folder/Module", expectedPath: "folder.Module", options: { rootDir: "src" }, throwsError: false, }, { - filePath: "src/file.ts", + filePath: "src/main.ts", usedPath: "./folder/Module", expectedPath: "folder.Module", options: { rootDir: "./src" }, throwsError: false, }, { - filePath: "file.ts", + filePath: "main.ts", usedPath: "../Module", expectedPath: "", options: { rootDir: "./src" }, throwsError: true, }, { - filePath: "src/dir/file.ts", + filePath: "src/dir/main.ts", usedPath: "../Module", expectedPath: "Module", options: { rootDir: "./src" }, throwsError: false, }, { - filePath: "src/dir/dir/file.ts", + filePath: "src/dir/dir/main.ts", usedPath: "../../dir/Module", expectedPath: "dir.Module", options: { rootDir: "./src" }, @@ -74,17 +74,11 @@ test.each([ ])( "require paths root from --baseUrl or --rootDir (%p)", ({ filePath, usedPath, expectedPath, options, throwsError }) => { + const input = { [filePath]: `import * from "${usedPath}";` }; if (throwsError) { - expect(() => - util.transpileString(`import * from "${usedPath}";`, options, true, filePath), - ).toThrow(); + expect(() => util.transpileString(input, options)).toThrow(); } else { - const lua = util.transpileString( - `import * from "${usedPath}";`, - options, - true, - filePath, - ); + const lua = util.transpileString(input, options); const regex = /require\("(.*?)"\)/; const match = regex.exec(lua); @@ -101,15 +95,10 @@ test.each([ ])( "noResolution on ambient modules causes no path alterations (%p)", ({ comment, expectedPath }) => { - const lua = util.transpileString( - { - "src/file.ts": `import * as fake from "fake";`, - "module.d.ts": `${comment} declare module "fake" {}`, - }, - undefined, - true, - "src/file.ts", - ); + const lua = util.transpileString({ + "src/main.ts": `import * as fake from "fake";`, + "module.d.ts": `${comment} declare module "fake" {}`, + }); const regex = /require\("(.*?)"\)/; const match = regex.exec(lua); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index fef652744..905e3dc05 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -1,6 +1,6 @@ +import { Position, SourceMapConsumer } from "source-map"; +import * as tstl from "../../src"; import * as util from "../util"; -import { LuaLibImportKind, CompilerOptions } from "../../src/CompilerOptions"; -import { SourceMapConsumer, Position } from "source-map"; test.each([ { @@ -47,13 +47,14 @@ test.each([ }, ])("Source map has correct mapping (%p)", async ({ typeScriptSource, assertPatterns }) => { // Act - const { lua, sourceMap } = util.transpileStringResult(typeScriptSource); + const { file } = util.transpileStringResult(typeScriptSource); // Assert - const consumer = await new SourceMapConsumer(sourceMap); + if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + const consumer = await new SourceMapConsumer(file.sourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { - const luaPosition = lineAndColumnOf(lua, luaPattern); + const luaPosition = lineAndColumnOf(file.lua, luaPattern); const mappedPosition = consumer.originalPositionFor(luaPosition); const typescriptPosition = lineAndColumnOf(typeScriptSource, typeScriptPattern); @@ -71,7 +72,10 @@ test("sourceMapTraceback saves sourcemap in _G", () => { } return JSONStringify(_G.__TS__sourcemap);`; - const options = { sourceMapTraceback: true, luaLibImport: LuaLibImportKind.Inline }; + const options: tstl.CompilerOptions = { + sourceMapTraceback: true, + luaLibImport: tstl.LuaLibImportKind.Inline, + }; // Act const transpiledLua = util.transpileString(typeScriptSource, options); @@ -119,21 +123,20 @@ test("Inline sourcemaps", () => { } return abc();`; - const compilerOptions: CompilerOptions = { - inlineSourceMap: true, - }; + const compilerOptions: tstl.CompilerOptions = { inlineSourceMap: true }; - const { lua, sourceMap } = util.transpileStringResult(typeScriptSource, compilerOptions); + const { file } = util.transpileStringResult(typeScriptSource, compilerOptions); + if (!util.expectToBeDefined(file.lua)) return; - const inlineSourceMapMatch = lua.match( + const inlineSourceMapMatch = file.lua.match( /--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/, ); if (util.expectToBeDefined(inlineSourceMapMatch)) { const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); - expect(sourceMap).toBe(inlineSourceMap); + expect(file.sourceMap).toBe(inlineSourceMap); - expect(util.executeLua(lua)).toBe("foo"); + expect(util.executeLua(file.lua)).toBe("foo"); } }); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index dcd40db5e..dfcb345d1 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind, LuaTarget } from "../../src/CompilerOptions"; +import * as tstl from "../../src"; import * as util from "../util"; test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])( @@ -13,25 +13,37 @@ test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])( test("Spread Element Lua 5.1", () => { // Cant test functional because our VM doesn't run on 5.1 - const options = { luaTarget: LuaTarget.Lua51, luaLibImport: LuaLibImportKind.None }; + const options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.Lua51, + luaLibImport: tstl.LuaLibImportKind.None, + }; const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); expect(lua).toBe("__TS__ArrayPush({}, unpack({\n 1,\n 2,\n 3,\n}))"); }); test("Spread Element Lua 5.2", () => { - const options = { luaTarget: LuaTarget.Lua52, luaLibImport: LuaLibImportKind.None }; + const options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.Lua52, + luaLibImport: tstl.LuaLibImportKind.None, + }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); }); test("Spread Element Lua 5.3", () => { - const options = { luaTarget: LuaTarget.Lua53, luaLibImport: LuaLibImportKind.None }; + const options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.Lua53, + luaLibImport: tstl.LuaLibImportKind.None, + }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); }); test("Spread Element Lua JIT", () => { - const options = { luaTarget: "JiT" as LuaTarget, luaLibImport: LuaLibImportKind.None }; + const options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.LuaJIT, + luaLibImport: tstl.LuaLibImportKind.None, + }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})}"); }); diff --git a/test/util.ts b/test/util.ts index fd09d9541..b43f09dc5 100644 --- a/test/util.ts +++ b/test/util.ts @@ -2,115 +2,54 @@ import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; -import { - createStringCompilerProgram, - transpileString as compilerTranspileString, -} from "../src/Compiler"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../src/CompilerOptions"; -import { LuaTransformer } from "../src/LuaTransformer"; -import { TranspileResult } from "../src/LuaTranspiler"; +import * as tstl from "../src"; export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); -declare global { - namespace jest { - interface Matchers { - toThrowExactError(error: Error): void; - } - } -} - -expect.extend({ - toThrowExactError( - callback: () => void, - error: Error, - ): { pass: boolean; message: () => string } { - if (this.isNot) { - return { pass: true, message: () => "Inverted toThrowExactError is not implemented" }; - } - - let executionError: Error | undefined; - try { - callback(); - } catch (err) { - executionError = err; - } - - expect(() => { - if (executionError) throw executionError; - }).toThrowError(error.constructor as any); - expect(() => { - if (executionError) throw executionError; - }).toThrowError(error); - - return { pass: true, message: () => "" }; - }, -}); - -function compilerTranspile( - str: string | { [filename: string]: string }, - options: CompilerOptions = {}, - ignoreDiagnostics = true, - filePath = "file.ts", -): TranspileResult { - return compilerTranspileString( - str, - { - luaLibImport: LuaLibImportKind.Inline, - luaTarget: LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: [ - "lib.es2015.d.ts", - "lib.es2016.d.ts", - "lib.es2017.d.ts", - "lib.es2018.d.ts", - "lib.esnext.d.ts", - ], - ...options, - }, - ignoreDiagnostics, - filePath, - ); -} - export function transpileString( str: string | { [filename: string]: string }, - options: CompilerOptions = {}, + options: tstl.CompilerOptions = {}, ignoreDiagnostics = true, - filePath = "file.ts", ): string { - const { lua } = transpileStringResult(str, options, ignoreDiagnostics, filePath); - return lua.trim(); + const { diagnostics, file } = transpileStringResult(str, options); + if (!expectToBeDefined(file) || !expectToBeDefined(file.lua)) return ""; + + const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); + expect(errors).not.toHaveDiagnostics(); + + return file.lua.trim(); } export function transpileStringResult( - str: string | { [filename: string]: string }, - options: CompilerOptions = {}, - ignoreDiagnostics = true, - filePath = "file.ts", -): TranspileResult { - return compilerTranspileString( - str, - { - luaLibImport: LuaLibImportKind.Inline, - luaTarget: LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: [ - "lib.es2015.d.ts", - "lib.es2016.d.ts", - "lib.es2017.d.ts", - "lib.es2018.d.ts", - "lib.esnext.d.ts", - ], - ...options, - }, - ignoreDiagnostics, - filePath, + input: string | Record, + options: tstl.CompilerOptions = {}, +): Required { + const optionsWithDefaults = { + luaTarget: tstl.LuaTarget.Lua53, + noHeader: true, + skipLibCheck: true, + target: ts.ScriptTarget.ESNext, + lib: [ + "lib.es2015.d.ts", + "lib.es2016.d.ts", + "lib.es2017.d.ts", + "lib.es2018.d.ts", + "lib.esnext.d.ts", + ], + ...options, + }; + + const { diagnostics, transpiledFiles } = tstl.transpileVirtualProject( + typeof input === "string" ? { "main.ts": input } : input, + optionsWithDefaults, ); + + const mainFileName = [...transpiledFiles.keys()].find(x => /\bmain\.[a-z]+$/.test(x)); + if (mainFileName === undefined) { + throw new Error('Program should have a file named "main"'); + } + + return { diagnostics, file: transpiledFiles.get(mainFileName)! }; } const lualibContent = fs.readFileSync( @@ -154,14 +93,13 @@ export function executeLua(luaStr: string, withLib = true): any { } // Get a mock transformer to use for testing -export function makeTestTransformer(target: LuaTarget = LuaTarget.Lua53): LuaTransformer { - const options = { luaTarget: target }; - return new LuaTransformer(ts.createProgram([], options), options); +export function makeTestTransformer(luaTarget = tstl.LuaTarget.Lua53): tstl.LuaTransformer { + return new tstl.LuaTransformer(ts.createProgram([], { luaTarget })); } export function transpileAndExecute( tsStr: string, - compilerOptions?: CompilerOptions, + compilerOptions?: tstl.CompilerOptions, luaHeader?: string, tsHeader?: string, ): any { @@ -179,7 +117,7 @@ export function transpileAndExecute( export function transpileExecuteAndReturnExport( tsStr: string, returnExport: string, - compilerOptions?: CompilerOptions, + compilerOptions?: tstl.CompilerOptions, luaHeader?: string, ): any { const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; @@ -195,13 +133,13 @@ export function transpileExecuteAndReturnExport( export function parseTypeScript( typescript: string, - target: LuaTarget = LuaTarget.Lua53, + target: tstl.LuaTarget = tstl.LuaTarget.Lua53, ): [ts.SourceFile, ts.TypeChecker] { - const program = createStringCompilerProgram(typescript, { luaTarget: target }); - const sourceFile = program.getSourceFile("file.ts"); + const program = tstl.createVirtualProgram({ "main.ts": typescript }, { luaTarget: target }); + const sourceFile = program.getSourceFile("main.ts"); if (sourceFile === undefined) { - throw new Error("Could not find source file file.ts in program."); + throw new Error("Could not find source file main.ts in program."); } return [sourceFile, program.getTypeChecker()]; diff --git a/tsconfig.json b/tsconfig.json index 59ea10e64..e6ecaae97 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "declaration": true, "sourceMap": true, "target": "es2017", - "module": "commonjs" + "module": "commonjs", + "stripInternal": true }, "include": ["src"], "exclude": ["src/lualib"] From cb2c4796f82ede756285e9ae0c18238403123325 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 May 2019 15:41:35 +0500 Subject: [PATCH 067/764] Improve string.replace implementation (#549) --- src/lualib/StringReplace.ts | 23 +++++++++++++++++++++-- src/lualib/declarations/string.d.ts | 11 +++++++---- test/unit/string.spec.ts | 17 +++++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index 6ba303451..7a22992ed 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -1,3 +1,22 @@ -function __TS__StringReplace(this: void, source: string, searchValue: string, replaceValue: string): string { - return string.gsub(source, searchValue, replaceValue)[0]; +function __TS__StringReplace( + this: void, + source: string, + searchValue: string, + replaceValue: string | ((substring: string) => string) +): string { + [searchValue] = string.gsub(searchValue, "[%%%(%)%.%+%-%*%?%[%^%$]", "%%%1"); + + if (typeof replaceValue === "string") { + [replaceValue] = string.gsub(replaceValue, "[%%%(%)%.%+%-%*%?%[%^%$]", "%%%1"); + const [result] = string.gsub(source, searchValue, replaceValue, 1); + return result; + } else { + const [result] = string.gsub( + source, + searchValue, + match => (replaceValue as (substring: string) => string)(match), + 1 + ); + return result; + } } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 6e387692b..4d546b746 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -1,12 +1,15 @@ /** @luaIterator */ -interface GMatchResult extends Array { } +interface GMatchResult extends Array {} /** @noSelf */ declare namespace string { /** @tupleReturn */ - function gsub(source: string, searchValue: string, replaceValue: string): [string, number]; - /** @tupleReturn */ - function gsub(source: string, searchValue: string, replaceValue: (...groups: string[]) => string): [string, number]; + function gsub( + source: string, + searchValue: string, + replaceValue: string | ((...groups: string[]) => string), + n?: number + ): [string, number]; function gmatch(haystack: string, pattern: string): GMatchResult; } diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index dfb494c62..8da62e2dd 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -79,12 +79,25 @@ test.each([ { inp: "hello test", searchValue: "hello", replaceValue: "" }, { inp: "hello test", searchValue: "test", replaceValue: "" }, { inp: "hello test", searchValue: "test", replaceValue: "world" }, + { inp: "hello test", searchValue: "test", replaceValue: "%world" }, + { inp: "hello %test", searchValue: "test", replaceValue: "world" }, + { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, + { inp: "hello test", searchValue: "test", replaceValue: (): string => "a" }, + { inp: "hello test", searchValue: "test", replaceValue: (): string => "%a" }, + { inp: "aaa", searchValue: "a", replaceValue: "b" }, ])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { + const replaceValueString = + typeof replaceValue === "string" ? JSON.stringify(replaceValue) : replaceValue.toString(); const result = util.transpileAndExecute( - `return "${inp}".replace("${searchValue}", "${replaceValue}");`, + `return "${inp}".replace("${searchValue}", ${replaceValueString});`, ); - expect(result).toBe(inp.replace(searchValue, replaceValue)); + // https://github.com/Microsoft/TypeScript/issues/22378 + if (typeof replaceValue === "string") { + expect(result).toBe(inp.replace(searchValue, replaceValue)); + } else { + expect(result).toBe(inp.replace(searchValue, replaceValue)); + } }); test.each([ From 952672950596c1aad43768ddd269b03865a4ba4b Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 May 2019 15:44:44 +0500 Subject: [PATCH 068/764] Add string.{starts,ends}With (#551) --- src/LuaLib.ts | 4 +++- src/LuaTransformer.ts | 4 ++++ src/lualib/StringEndsWith.ts | 7 +++++++ src/lualib/StringStartsWith.ts | 7 +++++++ src/lualib/declarations/string.d.ts | 1 + test/unit/string.spec.ts | 24 ++++++++++++++++++++++++ 6 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/lualib/StringEndsWith.ts create mode 100644 src/lualib/StringStartsWith.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 2d1c5c134..525bfc46c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -39,9 +39,11 @@ export enum LuaLibFeature { WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", + StringConcat = "StringConcat", + StringEndsWith = "StringEndsWith", StringReplace = "StringReplace", StringSplit = "StringSplit", - StringConcat = "StringConcat", + StringStartsWith = "StringStartsWith", Symbol = "Symbol", SymbolRegistry = "SymbolRegistry", } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 979d2d6ee..e782f96c9 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4001,6 +4001,10 @@ export class LuaTransformer { const firstParamPlusOne = this.expressionPlusOne(params[0]); return this.createStringCall("byte", node, caller, firstParamPlusOne); } + case "startsWith": + return this.transformLuaLibFunction(LuaLibFeature.StringStartsWith, node, caller, ...params); + case "endsWith": + return this.transformLuaLibFunction(LuaLibFeature.StringEndsWith, node, caller, ...params); case "byte": case "char": case "dump": diff --git a/src/lualib/StringEndsWith.ts b/src/lualib/StringEndsWith.ts new file mode 100644 index 000000000..b519a77eb --- /dev/null +++ b/src/lualib/StringEndsWith.ts @@ -0,0 +1,7 @@ +function __TS__StringEndsWith(this: string, searchString: string, endPosition?: number): boolean { + if (endPosition === undefined || endPosition > this.length) { + endPosition = this.length; + } + + return string.sub(this, endPosition - searchString.length + 1, endPosition) === searchString; +} diff --git a/src/lualib/StringStartsWith.ts b/src/lualib/StringStartsWith.ts new file mode 100644 index 000000000..8de8fa8ec --- /dev/null +++ b/src/lualib/StringStartsWith.ts @@ -0,0 +1,7 @@ +function __TS__StringStartsWith(this: string, searchString: string, position?: number): boolean { + if (position === undefined || position < 0) { + position = 0; + } + + return string.sub(this, position + 1, searchString.length + position) === searchString; +} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 4d546b746..0663ada37 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -12,4 +12,5 @@ declare namespace string { ): [string, number]; function gmatch(haystack: string, pattern: string): GMatchResult; + function sub(s: string, i: number, j?: number): string; } diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 8da62e2dd..6690a4111 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -284,6 +284,30 @@ test.each([ expect(result).toBe(inp.charAt(index)); }); +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["hello"] }, + { inp: "hello test", args: ["test"] }, + { inp: "hello test", args: ["test", 6] }, +])("string.startsWith (%p)", ({ inp, args }) => { + const argsString = args.map(arg => JSON.stringify(arg)).join(", "); + const result = util.transpileAndExecute(`return "${inp}".startsWith(${argsString})`); + + expect(result).toBe(inp.startsWith(...args)); +}); + +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["test"] }, + { inp: "hello test", args: ["hello"] }, + { inp: "hello test", args: ["hello", 5] }, +])("string.endsWith (%p)", ({ inp, args }) => { + const argsString = args.map(arg => JSON.stringify(arg)).join(", "); + const result = util.transpileAndExecute(`return "${inp}".endsWith(${argsString})`); + + expect(result).toBe(inp.endsWith(...args)); +}); + test.each([ { input: "abcd", index: 3 }, { input: "abcde", index: 3 }, From bd2d81b84f9b38ee92e22f73ce68b6c892f273b4 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 May 2019 18:34:39 +0500 Subject: [PATCH 069/764] Make transpiledFiles an Array (#553) --- src/Emit.ts | 4 ++-- src/Transpile.ts | 19 ++++++++++++------- src/index.ts | 2 +- src/tstl.ts | 2 +- test/util.ts | 6 +++--- 5 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Emit.ts b/src/Emit.ts index 16af6318b..74b6f3eb3 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -14,7 +14,7 @@ export interface OutputFile { let lualibContent: string; export function emitTranspiledFiles( options: CompilerOptions, - transpiledFiles: Map + transpiledFiles: TranspiledFile[] ): OutputFile[] { let { rootDir, outDir, outFile, luaLibImport } = options; @@ -26,7 +26,7 @@ export function emitTranspiledFiles( outDir = outDir ? path.resolve(baseDir, outDir) : rootDir; const files: OutputFile[] = []; - for (const [fileName, { lua, sourceMap, declaration, declarationMap }] of transpiledFiles) { + for (const { fileName, lua, sourceMap, declaration, declarationMap } of transpiledFiles) { let outPath = fileName; if (outDir !== rootDir) { outPath = path.resolve(outDir, path.relative(rootDir, fileName)); diff --git a/src/Transpile.ts b/src/Transpile.ts index ee59af81d..db1460cd5 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -37,6 +37,7 @@ function getCustomTransformers( } export interface TranspiledFile { + fileName: string; luaAst?: Block; lua?: string; sourceMap?: string; @@ -46,7 +47,7 @@ export interface TranspiledFile { export interface TranspileResult { diagnostics: ts.Diagnostic[]; - transpiledFiles: Map; + transpiledFiles: TranspiledFile[]; } export interface TranspileOptions { @@ -67,12 +68,16 @@ export function transpile({ const options = program.getCompilerOptions() as CompilerOptions; const diagnostics: ts.Diagnostic[] = []; - const transpiledFiles = new Map(); - const updateTranspiledFile = (filePath: string, file: TranspiledFile) => { - if (transpiledFiles.has(filePath)) { - Object.assign(transpiledFiles.get(filePath), file); + let transpiledFiles: TranspiledFile[] = []; + + // TODO: Included in TS3.5 + type Omit = Pick>; + const updateTranspiledFile = (fileName: string, update: Omit) => { + const file = transpiledFiles.find(f => f.fileName === fileName); + if (file) { + Object.assign(file, update); } else { - transpiledFiles.set(filePath, file); + transpiledFiles.push({ fileName, ...update }); } }; @@ -172,7 +177,7 @@ export function transpile({ options.noEmit = oldNoEmit; if (options.noEmit || (options.noEmitOnError && diagnostics.length > 0)) { - transpiledFiles.clear(); + transpiledFiles = []; } return { diagnostics, transpiledFiles }; diff --git a/src/index.ts b/src/index.ts index 283fbee02..80d2064ab 100644 --- a/src/index.ts +++ b/src/index.ts @@ -121,5 +121,5 @@ export function transpileString( options: CompilerOptions = {} ): TranspileStringResult { const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); - return { diagnostics, file: transpiledFiles.get("main.ts") }; + return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") }; } diff --git a/src/tstl.ts b/src/tstl.ts index ea6489c3f..64c5bb53a 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -170,7 +170,7 @@ function performCompilation( const exitCode = diagnostics.length === 0 ? ts.ExitStatus.Success - : transpiledFiles.size === 0 + : transpiledFiles.length === 0 ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped : ts.ExitStatus.DiagnosticsPresent_OutputsGenerated; diff --git a/test/util.ts b/test/util.ts index b43f09dc5..c8dfa1e21 100644 --- a/test/util.ts +++ b/test/util.ts @@ -44,12 +44,12 @@ export function transpileStringResult( optionsWithDefaults, ); - const mainFileName = [...transpiledFiles.keys()].find(x => /\bmain\.[a-z]+$/.test(x)); - if (mainFileName === undefined) { + const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); + if (file === undefined) { throw new Error('Program should have a file named "main"'); } - return { diagnostics, file: transpiledFiles.get(mainFileName)! }; + return { diagnostics, file }; } const lualibContent = fs.readFileSync( From 1d2cd1393edfe7103bc51f72baff592c623a981b Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 May 2019 18:59:17 +0500 Subject: [PATCH 070/764] Add Symbol.hasInstance support (#550) --- build_lualib.ts | 8 +++-- src/LuaLib.ts | 2 ++ src/LuaTransformer.ts | 17 +++++------ src/lualib/InstanceOf.ts | 9 ++++++ src/lualib/InstanceOfObject.ts | 4 +++ src/lualib/Symbol.ts | 1 + src/lualib/declarations/global.d.ts | 4 +++ test/unit/typechecking.spec.ts | 46 +++++++++++++++++++++++++---- 8 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 src/lualib/InstanceOfObject.ts create mode 100644 src/lualib/declarations/global.d.ts diff --git a/build_lualib.ts b/build_lualib.ts index cca39f055..253fa59d5 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -8,11 +8,15 @@ import { LuaLib } from "./src/LuaLib"; const options: tstl.CompilerOptions = { skipLibCheck: true, types: [], + target: ts.ScriptTarget.ESNext, + lib: ["lib.esnext.d.ts"], + + outDir: path.join(__dirname, "./dist/lualib"), + rootDir: path.join(__dirname, "./src/lualib"), + luaLibImport: tstl.LuaLibImportKind.None, luaTarget: tstl.LuaTarget.Lua51, noHeader: true, - outDir: path.join(__dirname, "./dist/lualib"), - rootDir: path.join(__dirname, "./src/lualib"), }; // TODO: Check diagnostics diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 525bfc46c..a42ec07dd 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -27,6 +27,7 @@ export enum LuaLibFeature { FunctionCall = "FunctionCall", Index = "Index", InstanceOf = "InstanceOf", + InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", Map = "Map", NewIndex = "NewIndex", @@ -51,6 +52,7 @@ export enum LuaLibFeature { const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], + InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e782f96c9..75392d1ad 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2658,14 +2658,18 @@ export class LuaTransformer { ); case ts.SyntaxKind.InstanceOfKeyword: - const decorators = tsHelper.getCustomDecorators( - this.checker.getTypeAtLocation(expression.right), - this.checker - ); + const rhsType = this.checker.getTypeAtLocation(expression.right); + const decorators = tsHelper.getCustomDecorators(rhsType, this.checker); + if (decorators.has(DecoratorKind.Extension) || decorators.has(DecoratorKind.MetaExtension)) { // Cannot use instanceof on extension classes throw TSTLErrors.InvalidInstanceOfExtension(expression); } + + if (tsHelper.isStandardLibraryType(rhsType, "ObjectConstructor", this.program)) { + return this.transformLuaLibFunction(LuaLibFeature.InstanceOfObject, expression, lhs); + } + return this.transformLuaLibFunction(LuaLibFeature.InstanceOf, expression, lhs, rhs); case ts.SyntaxKind.CommaToken: @@ -4533,11 +4537,6 @@ export class LuaTransformer { } private importLuaLibFeature(feature: LuaLibFeature): void { - // Add additional lib requirements - if (feature === LuaLibFeature.Map || feature === LuaLibFeature.Set) { - this.luaLibFeatureSet.add(LuaLibFeature.InstanceOf); - } - this.luaLibFeatureSet.add(feature); } diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index b59674943..6f6dd1c3c 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -7,6 +7,15 @@ interface LuaObject { } function __TS__InstanceOf(this: void, obj: LuaObject, classTbl: LuaClass): boolean { + if (typeof classTbl !== "object") { + // tslint:disable-next-line: no-string-throw + throw "Right-hand side of 'instanceof' is not an object"; + } + + if (classTbl[Symbol.hasInstance] !== undefined) { + return !!classTbl[Symbol.hasInstance](obj); + } + if (obj !== undefined) { let luaClass = obj.constructor; while (luaClass !== undefined) { diff --git a/src/lualib/InstanceOfObject.ts b/src/lualib/InstanceOfObject.ts new file mode 100644 index 000000000..681e243c5 --- /dev/null +++ b/src/lualib/InstanceOfObject.ts @@ -0,0 +1,4 @@ +function __TS__InstanceOfObject(this: void, value: unknown): boolean { + const valueType = type(value); + return valueType === "table" || valueType === "function"; +} diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 5c7bf0a7c..ef110af61 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -17,4 +17,5 @@ function __TS__Symbol(description?: string | number): symbol { Symbol = { iterator: __TS__Symbol('Symbol.iterator'), + hasInstance: __TS__Symbol('Symbol.hasInstance'), } as any; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts new file mode 100644 index 000000000..6d88460ed --- /dev/null +++ b/src/lualib/declarations/global.d.ts @@ -0,0 +1,4 @@ +declare function type( + this: void, + value: any +): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index e52337405..8088994b0 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -50,7 +50,7 @@ test("instanceof", () => { "class myClass {} let inst = new myClass(); return inst instanceof myClass;", ); - expect(result).toBeTruthy(); + expect(result).toBe(true); }); test("instanceof inheritance", () => { @@ -60,7 +60,7 @@ test("instanceof inheritance", () => { let inst = new childClass(); return inst instanceof myClass; `); - expect(result).toBeTruthy(); + expect(result).toBe(true); }); test("instanceof inheritance false", () => { @@ -73,15 +73,33 @@ test("instanceof inheritance false", () => { expect(result).toBe(false); }); +test("{} instanceof Object", () => { + const result = util.transpileAndExecute("return {} instanceof Object;"); + + expect(result).toBe(true); +}); + +test("function instanceof Object", () => { + const result = util.transpileAndExecute("return (() => {}) instanceof Object;"); + + expect(result).toBe(true); +}); + test("null instanceof Object", () => { - const result = util.transpileAndExecute("return (null) instanceof Object;"); + const result = util.transpileAndExecute("return (null as any) instanceof Object;"); expect(result).toBe(false); }); +test("instanceof undefined", () => { + expect(() => { + util.transpileAndExecute("return {} instanceof (undefined as any);"); + }).toThrow("Right-hand side of 'instanceof' is not an object"); +}); + test("null instanceof Class", () => { const result = util.transpileAndExecute( - "class myClass {} return (null) instanceof myClass;", + "class myClass {} return (null as any) instanceof myClass;", ); expect(result).toBe(false); @@ -108,5 +126,23 @@ test("instanceof export", () => { "result", ); - expect(result).toBeTruthy(); + expect(result).toBe(true); +}); + +test("instanceof Symbol.hasInstance", () => { + const result = util.transpileAndExecute(` + class myClass { + static [Symbol.hasInstance]() { + return false; + } + } + + const inst = new myClass(); + const isInstanceOld = inst instanceof myClass; + myClass[Symbol.hasInstance] = () => true; + const isInstanceNew = inst instanceof myClass; + return isInstanceOld !== isInstanceNew; + `); + + expect(result).toBe(true); }); From 720a4dc20f8406831edf3e27b7b5c67771bae54c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 3 May 2019 08:27:30 -0600 Subject: [PATCH 071/764] Array support in __TS__Iterator (#556) --- src/lualib/Iterator.ts | 26 +++++++++++++++++--------- test/unit/loops.spec.ts | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index b45fafe46..8e7afcfe9 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,11 +1,19 @@ function __TS__Iterator(this: void, iterable: Iterable): (this: void) => T { - const iterator = iterable[Symbol.iterator](); - return () => { - const result = iterator.next(); - if (!result.done) { - return result.value; - } else { - return undefined; - } - }; + if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + return () => { + const result = iterator.next(); + if (!result.done) { + return result.value; + } else { + return undefined; + } + }; + } else { + let i = 0; + return () => { + i = i + 1; + return iterable[i]; + }; + } } diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index ddf9de97d..3ddb55998 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -504,6 +504,20 @@ test("forof destructuring with iterator and existing variables", () => { expect(result).toBe("0a1b2c"); }); +test("forof with array typed as iterable", () => { + const code = ` + function foo(): Iterable { + return ["A", "B", "C"]; + } + let result = ""; + for (const x of foo()) { + result += x; + } + return result; + `; + expect(util.transpileAndExecute(code)).toBe("ABC"); +}); + test("forof lua iterator", () => { const code = ` const arr = ["a", "b", "c"]; From 3de430d39734d93a98d33eb187094c376331967f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sat, 4 May 2019 23:08:45 +1000 Subject: [PATCH 072/764] Lua table (#516) * LuaTable draft * Refactor and added tests * Fixed tripped watch file * Missing semicolon * Prettified * Cannot extend LuaTable classes * luaTable classes can only be declared * Restricted LuaTable parameter length * string -> LuaTable correction * LuaTable length cannot be re-assigned * Prettier * LuaTable interface tests * LuaTables cannot be constructed with arguments * Test splitting and more interface tests * instanceof LuaTable not allowed * Purpose in life for exception * No more other methods * Broke down transformLuaTableCallExpression into other methods * LuaTable -> luaTable * luaTables must be within an ambient context * Added isAmbient and disallowed argument spreading * Unsupported method consistency * tsHelper.isDeclared is unused * public -> private * Missed one more public * Allowed transpileAndExecute to use ambient code * luaTable functional tests * transpileString signature change * Revert util.ts changes --- src/Decorator.ts | 3 + src/LuaTransformer.ts | 172 ++++++++++++++++++ src/TSHelper.ts | 4 + src/TSTLErrors.ts | 16 ++ .../__snapshots__/transformation.spec.ts.snap | 10 + test/translation/transformation/luaTable.ts | 23 +++ test/unit/luaTable.spec.ts | 138 ++++++++++++++ 7 files changed, 366 insertions(+) create mode 100644 test/translation/transformation/luaTable.ts create mode 100644 test/unit/luaTable.spec.ts diff --git a/src/Decorator.ts b/src/Decorator.ts index 7ee84190f..b8a4f3ad3 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -23,6 +23,8 @@ export class Decorator { return DecoratorKind.TupleReturn; case "luaiterator": return DecoratorKind.LuaIterator; + case "luatable": + return DecoratorKind.LuaTable; case "noself": return DecoratorKind.NoSelf; case "noselfinfile": @@ -56,6 +58,7 @@ export enum DecoratorKind { Phantom = "Phantom", TupleReturn = "TupleReturn", LuaIterator = "LuaIterator", + LuaTable = "LuaTable", NoSelf = "NoSelf", NoSelfInFile = "NoSelfInFile", } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 75392d1ad..4ad2163e7 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -475,6 +475,19 @@ export class LuaTransformer { } } + // You cannot extend LuaTable classes + if (extendsType) { + const decorators = tsHelper.getCustomDecorators(extendsType, this.checker); + if (decorators.has(DecoratorKind.LuaTable)) { + throw TSTLErrors.InvalidExtendsLuaTable(statement); + } + } + + // LuaTable classes must be ambient + if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isAmbient(statement)) { + throw TSTLErrors.ForbiddenLuaTableNonDeclaration(statement); + } + // Get all properties with value const properties = statement.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); @@ -1981,6 +1994,22 @@ export class LuaTransformer { ); } + if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { + const ownerType = this.checker.getTypeAtLocation(expression.expression.expression); + const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); + if (classDecorators.has(DecoratorKind.LuaTable)) { + this.validateLuaTableCall( + expression as ts.CallExpression & { expression: ts.PropertyAccessExpression }, + true + ); + return this.transformLuaTableExpressionStatement( + statement as ts.ExpressionStatement + & { expression: ts.CallExpression } + & { expression: { expression: ts.PropertyAccessExpression } } + ); + } + } + return tstl.createExpressionStatement(this.expectExpression(this.transformExpression(expression))); } @@ -2666,6 +2695,10 @@ export class LuaTransformer { throw TSTLErrors.InvalidInstanceOfExtension(expression); } + if (decorators.has(DecoratorKind.LuaTable)) { + throw TSTLErrors.InvalidInstanceOfLuaTable(expression); + } + if (tsHelper.isStandardLibraryType(rhsType, "ObjectConstructor", this.program)) { return this.transformLuaLibFunction(LuaLibFeature.InstanceOfObject, expression, lhs); } @@ -2697,6 +2730,7 @@ export class LuaTransformer { const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); this.validateFunctionAssignment(expression.right, rightType, leftType); + this.validatePropertyAssignment(expression); if (tsHelper.isArrayLengthAssignment(expression, this.checker, this.program)) { // array.length = x @@ -3393,6 +3427,17 @@ export class LuaTransformer { ); } + if (classDecorators.has(DecoratorKind.LuaTable)) { + if (node.arguments && node.arguments.length > 0) { + throw TSTLErrors.ForbiddenLuaTableUseException( + "No parameters are allowed when constructing a LuaTable object.", + node + ); + } else { + return tstl.createTableExpression(); + } + } + return tstl.createCallExpression( tstl.createTableIndexExpression(name, tstl.createStringLiteral("new")), params, @@ -3535,6 +3580,18 @@ export class LuaTransformer { return this.transformSymbolCallExpression(node); } + const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); + + if (classDecorators.has(DecoratorKind.LuaTable)) { + this.validateLuaTableCall( + node as ts.CallExpression & { expression: ts.PropertyAccessExpression }, + false + ); + return this.transformLuaTableCallExpression( + node as ts.CallExpression & { expression: ts.PropertyAccessExpression } + ); + } + switch (ownerType.flags) { case ts.TypeFlags.String: case ts.TypeFlags.StringLiteral: @@ -3712,6 +3769,10 @@ export class LuaTransformer { return tstl.createIdentifier(property, node); } + if (decorators.has(DecoratorKind.LuaTable)) { + return this.transformLuaTableProperty(node); + } + // Catch math expressions if (ts.isIdentifier(node.expression)) { const ownerType = this.checker.getTypeAtLocation(node.expression); @@ -3851,6 +3912,16 @@ export class LuaTransformer { } } + private transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { + switch (node.name.escapedText) { + case "length": + const propertyAccessExpression = this.expectExpression(this.transformExpression(node.expression)); + return tstl.createUnaryExpression(propertyAccessExpression, tstl.SyntaxKind.LengthOperator, node); + default: + throw TSTLErrors.UnsupportedProperty("LuaTable", node.name.escapedText as string, node); + } + } + public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { const table = this.expectExpression(this.transformExpression(expression.expression)); const index = this.expectExpression(this.transformExpression(expression.argumentExpression)); @@ -4219,6 +4290,91 @@ export class LuaTransformer { } } + private validateLuaTableCall( + expression: ts.CallExpression & { expression: ts.PropertyAccessExpression }, + isWithinExpressionStatement: boolean + ): void { + const methodName = expression.expression.name.escapedText; + if (expression.arguments.some(argument => ts.isSpreadElement(argument))) { + throw TSTLErrors.ForbiddenLuaTableUseException("Arguments cannot be spread.", expression); + } + + switch (methodName) { + case "get": + if (expression.arguments.length !== 1) { + throw TSTLErrors.ForbiddenLuaTableUseException( + "One parameter is required for get().", + expression + ); + } + break; + case "set": + if (expression.arguments.length !== 2) { + throw TSTLErrors.ForbiddenLuaTableUseException( + "Two parameters are required for set().", + expression + ); + } + if (!isWithinExpressionStatement) { + throw TSTLErrors.ForbiddenLuaTableSetExpression(expression); + } + break; + } + } + + private transformLuaTableExpressionStatement( + node: ts.ExpressionStatement + & { expression: ts.CallExpression } + & { expression: { expression: ts.PropertyAccessExpression }} + ): tstl.VariableDeclarationStatement | tstl.AssignmentStatement { + const methodName = node.expression.expression.name.escapedText; + const signature = this.checker.getResolvedSignature(node.expression); + const tableName = (node.expression.expression.expression as ts.Identifier).escapedText; + const luaTable = tstl.createIdentifier(tableName); + const params = this.transformArguments((node.expression as ts.CallExpression).arguments, signature); + + switch (methodName) { + case "get": + return tstl.createVariableDeclarationStatement( + tstl.createAnonymousIdentifier(node.expression), + tstl.createTableIndexExpression(luaTable, params[0], node.expression), + node.expression + ); + case "set": + return tstl.createAssignmentStatement( + tstl.createTableIndexExpression(luaTable, params[0], node.expression), + params.splice(1), + node.expression + ); + default: + throw TSTLErrors.ForbiddenLuaTableUseException( + "Unsupported method.", + node.expression + ); + } + } + + private transformLuaTableCallExpression( + expression: ts.CallExpression & { expression: ts.PropertyAccessExpression } + ): tstl.Expression { + const method = expression.expression; + const methodName = method.name.escapedText; + const signature = this.checker.getResolvedSignature(expression); + const tableName = (method.expression as ts.Identifier).escapedText; + const luaTable = tstl.createIdentifier(tableName); + const params = this.transformArguments(expression.arguments, signature); + + switch (methodName) { + case "get": + return tstl.createTableIndexExpression(luaTable, params[0], expression); + default: + throw TSTLErrors.ForbiddenLuaTableUseException( + "Unsupported method.", + expression + ); + } + } + private transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); @@ -4823,6 +4979,22 @@ export class LuaTransformer { } } + private validatePropertyAssignment(node: ts.Node): void { + if (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left)) { + const leftType = this.checker.getTypeAtLocation(node.left.expression); + const decorators = tsHelper.getCustomDecorators(leftType, this.checker); + if (decorators.has(DecoratorKind.LuaTable)) { + switch (node.left.name.escapedText as string) { + case "length": + throw TSTLErrors.ForbiddenLuaTableUseException( + `A LuaTable object's length cannot be re-assigned.`, + node + ); + } + } + } + } + private wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { const returnStatement = tstl.createReturnStatement([expression]); return tstl.createFunctionExpression( diff --git a/src/TSHelper.ts b/src/TSHelper.ts index d17214251..403780b48 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -128,6 +128,10 @@ export class TSHelper { return false; } + public static isAmbient(node: ts.Declaration): boolean { + return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0); + } + public static isStatic(node: ts.Node): boolean { return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 07e57e634..1b1684246 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -18,6 +18,22 @@ export class TSTLErrors { public static ForbiddenForIn = (node: ts.Node) => new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); + public static ForbiddenLuaTableSetExpression = (node: ts.Node) => new TranspileError( + `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, + node); + + public static ForbiddenLuaTableNonDeclaration = (node: ts.Node) => + new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); + + public static InvalidExtendsLuaTable = (node: ts.Node) => + new TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node); + + public static InvalidInstanceOfLuaTable = (node: ts.Node) => + new TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node); + + public static ForbiddenLuaTableUseException = (description: string, node: ts.Node) => + new TranspileError(`Invalid @luaTable usage: ${description}`, node); + public static HeterogeneousEnum = (node: ts.Node) => new TranspileError( `Invalid heterogeneous enum. Enums should either specify no member values, ` + `or specify values (of the same type) for all members.`, diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 23dfccd67..27e78d0c8 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -296,6 +296,16 @@ exports[`Transformation (interfaceIndex) 1`] = ` a.abc = \\"def\\"" `; +exports[`Transformation (luaTable) 1`] = ` +"tbl = {} +tbl.value = 5 +local value = tbl.value +local tblLength = #tbl +itbl.value = 5 +local ivalue = itbl.value +local ilength = #tbl" +`; + exports[`Transformation (methodRestArguments) 1`] = ` "MyClass = {} MyClass.name = \\"MyClass\\" diff --git a/test/translation/transformation/luaTable.ts b/test/translation/transformation/luaTable.ts new file mode 100644 index 000000000..06bd03cd2 --- /dev/null +++ b/test/translation/transformation/luaTable.ts @@ -0,0 +1,23 @@ +/** @luaTable */ +declare class Table { + public readonly length: number; + public set(key: K, value: V): void; + public get(key: K): V; +} +declare let tbl: Table; +tbl = new Table(); +tbl.set("value", 5); +const value = tbl.get("value"); +const tblLength = tbl.length; + +/** @luaTable */ +declare interface InterfaceTable { + readonly length: number; + set(key: K, value: V): void; + get(key: K): V; +} + +declare const itbl: InterfaceTable; +itbl.set("value", 5); +const ivalue = itbl.get("value"); +const ilength = tbl.length; diff --git a/test/unit/luaTable.spec.ts b/test/unit/luaTable.spec.ts new file mode 100644 index 000000000..1ea3d2f9b --- /dev/null +++ b/test/unit/luaTable.spec.ts @@ -0,0 +1,138 @@ +import { TSTLErrors } from "../../src/TSTLErrors"; +import * as util from "../util"; + +const tableLibClass = ` +/** @luaTable */ +declare class Table { + length: number; + constructor(notAllowed?: boolean); + set(key?: K, value?: V): void; + get(key?: K): V; + other(): void; +} +declare let tbl: Table; +`; + +const tableLibInterface = ` +/** @luaTable */ +declare interface Table { + length: number; + constructor(notAllowed?: boolean); + set(key?: K, value?: V): void; + get(key?: K): V; + other(): void; +} +declare let tbl: Table; +`; + +test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { + expect(() => + util.transpileString(tableLib + `const table = new Table(true);`), + ).toThrowExactError( + TSTLErrors.ForbiddenLuaTableUseException( + "No parameters are allowed when constructing a LuaTable object.", + util.nodeStub, + ), + ); +}); + +test.each([tableLibClass, tableLibInterface])( + "LuaTable set() cannot be used in an expression position", + tableLib => { + expect(() => + util.transpileString(tableLib + `const exp = tbl.set("value", 5)`), + ).toThrowExactError(TSTLErrors.ForbiddenLuaTableSetExpression(util.nodeStub)); + }, +); + +test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { + expect(() => util.transpileString(tableLib + `tbl.other()`)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub), + ); +}); + +test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { + expect(() => util.transpileString(tableLib + `let x = tbl.other()`)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub), + ); +}); + +test.each([tableLibClass])("LuaTable new", tableLib => { + const content = tableLib + `tbl = new Table();`; + expect(util.transpileString(content)).toEqual("tbl = {}"); +}); + +test.each([tableLibClass])("LuaTable length", tableLib => { + const content = tableLib + `tbl = new Table();\nreturn tbl.length;`; + const lua = util.transpileString(content); + expect(util.executeLua(lua)).toEqual(0); +}); + +test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { + expect(() => util.transpileString(tableLib + `tbl.length = 2;`)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableUseException( + "A LuaTable object's length cannot be re-assigned.", + util.nodeStub, + ), + ); +}); + +test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { + test.each([ + [`tbl.get()`, "One parameter is required for get()."], + [`tbl.get("field", "field2")`, "One parameter is required for get()."], + [`tbl.set()`, "Two parameters are required for set()."], + [`tbl.set("field")`, "Two parameters are required for set()."], + [`tbl.set("field", 0, 1)`, "Two parameters are required for set()."], + [`tbl.set("field", ...[0, 1])`, "Arguments cannot be spread."], + ])("Forbidden LuaTable use (%p)", (invalidCode, errorDescription) => { + expect(() => util.transpileString(tableLib + invalidCode)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableUseException(errorDescription, util.nodeStub), + ); + }); +}); + +test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { + test.each([`class Ext extends Table {}`, `const c = class Ext extends Table {}`])( + "Cannot extend LuaTable class (%p)", + code => { + expect(() => util.transpileString(tableLib + code)).toThrowExactError( + TSTLErrors.InvalidExtendsLuaTable(util.nodeStub), + ); + }, + ); +}); + +test.each([ + `/** @luaTable */ class Table {}`, + `/** @luaTable */ export class Table {}`, + `/** @luaTable */ const c = class Table {}`, +])("LuaTable classes must be ambient (%p)", code => { + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableNonDeclaration(util.nodeStub), + ); +}); + +test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { + test.each([`tbl instanceof Table`])("Cannot use instanceof on a LuaTable class (%p)", code => { + expect(() => util.transpileString(tableLib + code)).toThrowExactError( + TSTLErrors.InvalidInstanceOfLuaTable(util.nodeStub), + ); + }); +}); + +test.each([tableLibClass])("LuaTable functional tests", tableLib => { + test.each<[string, any]>([ + [`const t = new Table(); t.set("field", "value"); return t.get("field");`, "value"], + [`const t = new Table(); t.set("field", 0); return t.get("field");`, 0], + [`const t = new Table(); t.set(1, true); return t.length`, 1], + [ + `const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length`, + 2, + ], + ])("LuaTable test (%p)", (code, expectedReturnValue) => { + expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe( + expectedReturnValue, + ); + }); +}); From 2ec3234f26f797aaf487314cfdd7d25baeab36c6 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 4 May 2019 18:22:28 +0500 Subject: [PATCH 073/764] Add NaN, Infinity and related number functions (#557) * Add NaN, Infinity and related number functions * Add noSelfInFile to global declorations file * Add few number test cases * Remove TODOs --- jest.config.js | 2 +- src/LuaLib.ts | 3 + src/LuaTransformer.ts | 99 ++++++++++++++++++++++++----- src/TSHelper.ts | 14 +++- src/lualib/ArraySetLength.ts | 2 +- src/lualib/Number.ts | 20 ++++++ src/lualib/NumberIsFinite.ts | 5 ++ src/lualib/NumberIsNaN.ts | 3 + src/lualib/Symbol.ts | 10 +-- src/lualib/declarations/global.d.ts | 4 +- test/unit/numbers.spec.ts | 79 +++++++++++++++++++++++ test/unit/objectLiteral.spec.ts | 24 +++++-- 12 files changed, 230 insertions(+), 35 deletions(-) create mode 100644 src/lualib/Number.ts create mode 100644 src/lualib/NumberIsFinite.ts create mode 100644 src/lualib/NumberIsNaN.ts create mode 100644 test/unit/numbers.spec.ts diff --git a/jest.config.js b/jest.config.js index 5a98e2b3d..09d82545f 100644 --- a/jest.config.js +++ b/jest.config.js @@ -9,7 +9,7 @@ module.exports = { // https://github.com/facebook/jest/issues/5274 "!/src/tstl.ts", ], - watchPathIgnorePatterns: ["cli/watch/[^/]+$"], + watchPathIgnorePatterns: ["cli/watch/[^/]+$", "src/lualib"], setupFilesAfterEnv: ["/test/setup.ts"], testEnvironment: "node", diff --git a/src/LuaLib.ts b/src/LuaLib.ts index a42ec07dd..08a02e9c3 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -31,6 +31,9 @@ export enum LuaLibFeature { Iterator = "Iterator", Map = "Map", NewIndex = "NewIndex", + Number = "Number", + NumberIsFinite = "NumberIsFinite", + NumberIsNaN = "NumberIsNaN", ObjectAssign = "ObjectAssign", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4ad2163e7..ead94c6dc 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3320,7 +3320,7 @@ export class LuaTransformer { const expression = this.expectExpression(this.transformExpression(element.initializer)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { - const identifier = this.transformIdentifier(element.name); + const identifier = this.transformIdentifierExpression(element.name); properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { const expression = this.expectExpression(this.transformFunctionExpression(element)); @@ -3523,6 +3523,14 @@ export class LuaTransformer { ); } + const expressionType = this.checker.getTypeAtLocation(node.expression); + if (tsHelper.isStandardLibraryType(expressionType, undefined, this.program)) { + const result = this.transformGlobalFunctionCall(node); + if (result) { + return result; + } + } + const callPath = this.expectExpression(this.transformExpression(node.expression)); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration @@ -3534,15 +3542,35 @@ export class LuaTransformer { parameters = this.transformArguments(node.arguments, signature, context); } - const expressionType = this.checker.getTypeAtLocation(node.expression); - if (tsHelper.isStandardLibraryType(expressionType, "SymbolConstructor", this.program)) { - return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); - } - const callExpression = tstl.createCallExpression(callPath, parameters, node); return wrapResult ? this.wrapInTable(callExpression) : callExpression; } + private transformGlobalFunctionCall(node: ts.CallExpression): ExpressionVisitResult { + const signature = this.checker.getResolvedSignature(node); + const parameters = this.transformArguments(node.arguments, signature); + + const expressionType = this.checker.getTypeAtLocation(node.expression); + const name = expressionType.symbol.name; + switch (name) { + case "SymbolConstructor": + return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); + case "NumberConstructor": + return this.transformLuaLibFunction(LuaLibFeature.Number, node, ...parameters); + case "isNaN": + case "isFinite": + const numberParameters = tsHelper.isNumberType(expressionType) + ? parameters + : [this.transformLuaLibFunction(LuaLibFeature.Number, undefined, ...parameters)]; + + return this.transformLuaLibFunction( + name === "isNaN" ? LuaLibFeature.NumberIsNaN : LuaLibFeature.NumberIsFinite, + node, + ...numberParameters + ); + } + } + public transformPropertyCall(node: ts.CallExpression): ExpressionVisitResult { let parameters: tstl.Expression[] = []; @@ -3580,6 +3608,10 @@ export class LuaTransformer { return this.transformSymbolCallExpression(node); } + if (tsHelper.isStandardLibraryType(ownerType, "NumberConstructor", this.program)) { + return this.transformNumberCallExpression(node); + } + const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); if (classDecorators.has(DecoratorKind.LuaTable)) { @@ -4290,6 +4322,26 @@ export class LuaTransformer { } } + // Transpile a Number._ property + private transformNumberCallExpression(expression: ts.CallExpression): tstl.CallExpression { + const method = expression.expression as ts.PropertyAccessExpression; + const parameters = this.transformArguments(expression.arguments); + const methodName = method.name.escapedText; + + switch (methodName) { + case "isNaN": + return this.transformLuaLibFunction(LuaLibFeature.NumberIsNaN, expression, ...parameters); + case "isFinite": + return this.transformLuaLibFunction(LuaLibFeature.NumberIsFinite, expression, ...parameters); + default: + throw TSTLErrors.UnsupportedForTarget( + `number property ${methodName}`, + this.luaTarget, + expression + ); + } + } + private validateLuaTableCall( expression: ts.CallExpression & { expression: ts.PropertyAccessExpression }, isWithinExpressionStatement: boolean @@ -4575,18 +4627,13 @@ export class LuaTransformer { } private getIdentifierText(identifier: ts.Identifier): string { - let escapedText = identifier.escapedText as string; - const underScoreCharCode = "_".charCodeAt(0); - if (escapedText.length >= 3 && escapedText.charCodeAt(0) === underScoreCharCode && - escapedText.charCodeAt(1) === underScoreCharCode && escapedText.charCodeAt(2) === underScoreCharCode) { - escapedText = escapedText.substr(1); - } + const text = ts.idText(identifier); - if (this.luaKeywords.has(escapedText)) { + if (this.luaKeywords.has(text)) { throw TSTLErrors.KeywordIdentifier(identifier); } - return escapedText; + return text; } public transformIdentifier(expression: ts.Identifier): tstl.Identifier { @@ -4597,16 +4644,34 @@ export class LuaTransformer { // at some point. } - const escapedText = this.getIdentifierText(expression); + const text = this.getIdentifierText(expression); const symbolId = this.getIdentifierSymbolId(expression); - return tstl.createIdentifier(escapedText, expression, symbolId); + return tstl.createIdentifier(text, expression, symbolId); } - private transformIdentifierExpression(expression: ts.Identifier): tstl.IdentifierOrTableIndexExpression { + private transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { const identifier = this.transformIdentifier(expression); if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); } + + switch (this.getIdentifierText(expression)) { + case "NaN": + return tstl.createParenthesizedExpression( + tstl.createBinaryExpression( + tstl.createNumericLiteral(0), + tstl.createNumericLiteral(0), + tstl.SyntaxKind.DivisionOperator, + expression + ) + ); + + case "Infinity": + const math = tstl.createIdentifier("math"); + const huge = tstl.createStringLiteral("huge"); + return tstl.createTableIndexExpression(math, huge, expression); + } + return identifier; } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 403780b48..ebf86b61b 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -141,6 +141,11 @@ export class TSHelper { (type.flags & ts.TypeFlags.StringLiteral) !== 0; } + public static isNumberType(type: ts.Type): boolean { + return (type.flags & ts.TypeFlags.Number) !== 0 || (type.flags & ts.TypeFlags.NumberLike) !== 0 || + (type.flags & ts.TypeFlags.NumberLiteral) !== 0; + } + public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { if (type.isUnionOrIntersection()) { return type.types.some(t => TSHelper.isExplicitArrayType(t, checker, program)); @@ -731,9 +736,12 @@ export class TSHelper { return program.isSourceFileDefaultLibrary(source); } - public static isStandardLibraryType(type: ts.Type, name: string, program: ts.Program): boolean { - const symbol = type.symbol; - if (!symbol || symbol.escapedName !== name) { return false; } + public static isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean { + const symbol = type.getSymbol(); + if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === '__type')) { + return false; + } + const declaration = symbol.valueDeclaration; if(!declaration) { return true; } // assume to be lib function if no valueDeclaration exists return this.isStandardLibraryDeclaration(declaration, program); diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 3efcf1e2f..2d6b0b87f 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -1,7 +1,7 @@ function __TS__ArraySetLength(this: void, arr: T[], length: number): number { if (length < 0 || length !== length // NaN - || length === (1 / 0) // Infinity + || length === Infinity // Infinity || Math.floor(length) !== length) // non-integer { // tslint:disable-next-line:no-string-throw diff --git a/src/lualib/Number.ts b/src/lualib/Number.ts new file mode 100644 index 000000000..c333c1ed1 --- /dev/null +++ b/src/lualib/Number.ts @@ -0,0 +1,20 @@ +function __TS__Number(this: void, value: unknown): number { + const valueType = type(value); + if (valueType === "number") { + return value as number; + } else if (valueType === "string") { + const numberValue = tonumber(value); + if (numberValue) return numberValue; + + if (value === "Infinity") return Infinity; + if (value === "-Infinity") return -Infinity; + const [stringWithoutSpaces] = string.gsub(value as string, '%s', ''); + if (stringWithoutSpaces === "") return 0; + + return NaN; + } else if (valueType === "boolean") { + return value ? 1 : 0; + } else { + return NaN; + } +} diff --git a/src/lualib/NumberIsFinite.ts b/src/lualib/NumberIsFinite.ts new file mode 100644 index 000000000..9338f2e34 --- /dev/null +++ b/src/lualib/NumberIsFinite.ts @@ -0,0 +1,5 @@ +function __TS__NumberIsFinite(this: void, value: unknown): boolean { + return ( + typeof value === "number" && value === value && value !== Infinity && value !== -Infinity + ); +} diff --git a/src/lualib/NumberIsNaN.ts b/src/lualib/NumberIsNaN.ts new file mode 100644 index 000000000..b040f5e5b --- /dev/null +++ b/src/lualib/NumberIsNaN.ts @@ -0,0 +1,3 @@ +function __TS__NumberIsNaN(this: void, value: unknown): boolean { + return value !== value; +} diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index ef110af61..032086ff8 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -4,18 +4,18 @@ declare function setmetatable(this: void, obj: T, metatable: a const ____symbolMetatable = { __tostring(): string { if (this.description === undefined) { - return 'Symbol()'; + return "Symbol()"; } else { - return 'Symbol(' + this.description + ')'; + return "Symbol(" + this.description + ")"; } }, }; -function __TS__Symbol(description?: string | number): symbol { +function __TS__Symbol(this: void, description?: string | number): symbol { return setmetatable({ description }, ____symbolMetatable) as any; } Symbol = { - iterator: __TS__Symbol('Symbol.iterator'), - hasInstance: __TS__Symbol('Symbol.hasInstance'), + iterator: __TS__Symbol("Symbol.iterator"), + hasInstance: __TS__Symbol("Symbol.hasInstance"), } as any; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 6d88460ed..ecedef17d 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,4 +1,6 @@ +/** @noSelfInFile */ + +declare function tonumber(value: any, base?: number): number | undefined; declare function type( - this: void, value: any ): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; diff --git a/test/unit/numbers.spec.ts b/test/unit/numbers.spec.ts new file mode 100644 index 000000000..623335683 --- /dev/null +++ b/test/unit/numbers.spec.ts @@ -0,0 +1,79 @@ +import * as util from "../util"; + +test.each([ + "NaN === NaN", + "NaN !== NaN", + "NaN + NaN", + "NaN - NaN", + "NaN * NaN", + "NaN / NaN", + "NaN + 1", + "1 + NaN", + "1 / NaN", + "NaN * 0", +])("%s", code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code))); + +test("NaN reassignment", () => { + const result = util.transpileAndExecute(`const NaN = 1; return NaN`); + + expect(result).toBe(NaN); +}); + +test.each([ + "Infinity", + "Infinity - Infinity", + "Infinity / -1", + "Infinity * -1", + "Infinity + 1", + "Infinity - 1", +])("%s", code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code))); + +test("Infinity reassignment", () => { + const result = util.transpileAndExecute(`const Infinity = 1; return Infinity`); + + expect(result).toBe(Infinity); +}); + +const numberCases = [-1, 0, 1, 1.5, Infinity, -Infinity]; +const stringCases = ["-1", "0", "1", "1.5", "Infinity", "-Infinity"]; +const restCases: any[] = [true, false, "", " ", "\t", "\n", "foo", {}]; +const cases: any[] = [...numberCases, ...stringCases, ...restCases]; + +// TODO: Add more general utils to serialize values +const valueToString = (value: unknown) => + value === Infinity || value === -Infinity || (typeof value === "number" && Number.isNaN(value)) + ? String(value) + : JSON.stringify(value); + +describe("Number", () => { + test.each(cases)("constructor(%p)", value => { + const result = util.transpileAndExecute(`return Number(${valueToString(value)})`); + expect(result).toBe(Number(value)); + }); + + test.each(cases)("isNaN(%p)", value => { + const result = util.transpileAndExecute(` + return Number.isNaN(${valueToString(value)} as any) + `); + + expect(result).toBe(Number.isNaN(value)); + }); + + test.each(cases)("isFinite(%p)", value => { + const result = util.transpileAndExecute(` + return Number.isFinite(${valueToString(value)} as any) + `); + + expect(result).toBe(Number.isFinite(value)); + }); +}); + +test.each(cases)("isNaN(%p)", value => { + const result = util.transpileAndExecute(`return isNaN(${valueToString(value)} as any)`); + expect(result).toBe(isNaN(value)); +}); + +test.each(cases)("isFinite(%p)", value => { + const result = util.transpileAndExecute(`return isFinite(${valueToString(value)} as any)`); + expect(result).toBe(isFinite(value)); +}); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index a37ab815d..ed31245a7 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -13,13 +13,23 @@ test.each([ expect(lua).toBe(`local myvar = ${out}`); }); -test.each([{ input: "3", expected: 3 }])( - "Shorthand Property Assignment (%p)", - ({ input, expected }) => { - const result = util.transpileAndExecute(`const x = ${input}; const o = {x}; return o.x;`); - expect(result).toBe(expected); - }, -); +describe("property shorthand", () => { + test("should support property shorthand", () => { + const result = util.transpileAndExecute(` + const x = 1; + const o = { x }; + return o.x; + `); + + expect(result).toBe(1); + }); + + test.each([NaN, Infinity])("should support %p shorthand", identifier => { + const result = util.transpileAndExecute(`return ({ ${identifier} }).${identifier}`); + + expect(result).toBe(identifier); + }); +}); test("undefined as object key", () => { const code = `const foo = {undefined: "foo"}; From 55da476f6faff08c55d4489bd5a737368c95dbb8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 4 May 2019 17:17:31 +0200 Subject: [PATCH 074/764] Feature/api interface (#561) * Fixed bug where elseBlock statement did not get parent assigned correctly * Improved printer interface * Cleaned up transformer a little * Renamed isEmptyStatement to isStatementEmpty --- src/LuaAST.ts | 2 +- src/LuaPrinter.ts | 102 ++++++++++--------- src/LuaTransformer.ts | 230 ++++++++++++++++++++++-------------------- 3 files changed, 172 insertions(+), 162 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index d9983979e..8f015bc3f 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -310,7 +310,7 @@ export function createIfStatement( statement.condition = condition; setParent(ifBlock, statement); statement.ifBlock = ifBlock; - setParent(ifBlock, statement); + setParent(elseBlock, statement); statement.elseBlock = elseBlock; return statement; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 40b05d8a2..e3cb3ff5f 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,6 +1,6 @@ import * as path from "path"; -import {SourceNode, SourceMapGenerator, RawSourceMap, SourceMapConsumer} from "source-map"; +import {SourceNode, SourceMapGenerator} from "source-map"; import * as tstl from "./LuaAST"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -145,19 +145,19 @@ export class LuaPrinter { return this.concatNodes(header, fileBlockNode); } - private pushIndent(): void { + protected pushIndent(): void { this.currentIndent = this.currentIndent + " "; } - private popIndent(): void { + protected popIndent(): void { this.currentIndent = this.currentIndent.slice(4); } - private indent(input: SourceChunk = ""): SourceChunk { + protected indent(input: SourceChunk = ""): SourceChunk { return this.concatNodes(this.currentIndent, input); } - private createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { + protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { const originalPos = tstl.getOriginalPos(node); return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined @@ -166,12 +166,12 @@ export class LuaPrinter { : new SourceNode(null, null, this.sourceFile, chunks); } - private concatNodes(...chunks: SourceChunk[]): SourceNode { + protected concatNodes(...chunks: SourceChunk[]): SourceNode { // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, this.sourceFile, chunks); } - private printBlock(block: tstl.Block): SourceNode { + protected printBlock(block: tstl.Block): SourceNode { return this.createSourceNode(block, this.printStatementArray(block.statements)); } @@ -196,7 +196,7 @@ export class LuaPrinter { return result || false; } - private printStatementArray(statements: tstl.Statement[]): SourceChunk[] { + protected printStatementArray(statements: tstl.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; statements = this.removeDeadAndEmptyStatements(statements); statements.forEach( @@ -216,7 +216,7 @@ export class LuaPrinter { return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } - private printStatement(statement: tstl.Statement): SourceNode { + public printStatement(statement: tstl.Statement): SourceNode { switch (statement.kind) { case tstl.SyntaxKind.DoStatement: return this.printDoStatement(statement as tstl.DoStatement); @@ -249,7 +249,7 @@ export class LuaPrinter { } } - private printDoStatement(statement: tstl.DoStatement): SourceNode { + public printDoStatement(statement: tstl.DoStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("do\n")); @@ -261,7 +261,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { + public printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("local ")); @@ -282,7 +282,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { + public printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent()); @@ -305,9 +305,12 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - private printIfStatement(statement: tstl.IfStatement, isElseIf?: boolean): SourceNode { + public printIfStatement(statement: tstl.IfStatement): SourceNode { const chunks: SourceChunk[] = []; + const isElseIf = statement.parent !== undefined + && tstl.isIfStatement(statement.parent); + const prefix = isElseIf ? "elseif" : "if"; chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n"); @@ -318,7 +321,7 @@ export class LuaPrinter { if (statement.elseBlock) { if (tstl.isIfStatement(statement.elseBlock)) { - chunks.push(this.printIfStatement(statement.elseBlock, true)); + chunks.push(this.printIfStatement(statement.elseBlock)); } else { chunks.push(this.indent("else\n")); this.pushIndent(); @@ -333,7 +336,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printWhileStatement(statement: tstl.WhileStatement): SourceNode { + public printWhileStatement(statement: tstl.WhileStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n"); @@ -347,7 +350,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { + public printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent(`repeat\n`)); @@ -361,7 +364,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printForStatement(statement: tstl.ForStatement): SourceNode { + public printForStatement(statement: tstl.ForStatement): SourceNode { const ctrlVar = this.printExpression(statement.controlVariable); const ctrlVarInit = this.printExpression(statement.controlVariableInitializer); const limit = this.printExpression(statement.limitExpression); @@ -384,7 +387,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printForInStatement(statement: tstl.ForInStatement): SourceNode { + public printForInStatement(statement: tstl.ForInStatement): SourceNode { const names = statement.names.map(i => this.printIdentifier(i)).join(", "); const expressions = statement.expressions.map(e => this.printExpression(e)).join(", "); @@ -400,15 +403,15 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - private printGotoStatement(statement: tstl.GotoStatement): SourceNode { + public printGotoStatement(statement: tstl.GotoStatement): SourceNode { return this.createSourceNode(statement, [this.indent("goto "), statement.label]); } - private printLabelStatement(statement: tstl.LabelStatement): SourceNode { + public printLabelStatement(statement: tstl.LabelStatement): SourceNode { return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]); } - private printReturnStatement(statement: tstl.ReturnStatement): SourceNode { + public printReturnStatement(statement: tstl.ReturnStatement): SourceNode { if (!statement.expressions || statement.expressions.length === 0) { return this.createSourceNode(statement, this.indent("return")); } @@ -420,16 +423,16 @@ export class LuaPrinter { return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } - private printBreakStatement(statement: tstl.BreakStatement): SourceNode { + public printBreakStatement(statement: tstl.BreakStatement): SourceNode { return this.createSourceNode(statement, this.indent("break")); } - private printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { + public printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { return this.concatNodes(this.indent(), this.printExpression(statement.expression)); } // Expressions - private printExpression(expression: tstl.Expression): SourceNode { + public printExpression(expression: tstl.Expression): SourceNode { switch (expression.kind) { case tstl.SyntaxKind.StringLiteral: return this.printStringLiteral(expression as tstl.StringLiteral); @@ -467,23 +470,23 @@ export class LuaPrinter { } } - private printStringLiteral(expression: tstl.StringLiteral): SourceNode { + public printStringLiteral(expression: tstl.StringLiteral): SourceNode { return this.createSourceNode(expression, `"${expression.value}"`); } - private printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { + public printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { return this.createSourceNode(expression, String(expression.value)); } - private printNilLiteral(expression: tstl.NilLiteral): SourceNode { + public printNilLiteral(expression: tstl.NilLiteral): SourceNode { return this.createSourceNode(expression, "nil"); } - private printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { + public printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { return this.createSourceNode(expression, "..."); } - private printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { + public printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { if (expression.kind === tstl.SyntaxKind.TrueKeyword) { return this.createSourceNode(expression, "true"); } else { @@ -503,7 +506,7 @@ export class LuaPrinter { return this.joinChunks(", ", parameterChunks); } - private printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { + public printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("function("); @@ -531,7 +534,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { + public printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { const expression = statement.right[0]; const chunks: SourceChunk[] = []; @@ -549,7 +552,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { + public printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { const chunks: SourceChunk[] = []; const value = this.printExpression(expression.value); @@ -567,7 +570,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printTableExpression(expression: tstl.TableExpression): SourceNode { + public printTableExpression(expression: tstl.TableExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("{"); @@ -591,7 +594,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { + public printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); @@ -600,7 +603,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { + public printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.left)); @@ -610,11 +613,11 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { + public printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { return this.createSourceNode(expression, ["(", this.printExpression(expression.innerExpression), ")"]); } - private printCallExpression(expression: tstl.CallExpression): SourceNode { + public printCallExpression(expression: tstl.CallExpression): SourceNode { const chunks = []; const parameterChunks = expression.params !== undefined @@ -626,7 +629,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - private printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { + public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { const prefix = this.printExpression(expression.prefixExpression); const parameterChunks = expression.params !== undefined @@ -638,11 +641,11 @@ export class LuaPrinter { return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"); } - private printIdentifier(expression: tstl.Identifier): SourceNode { + public printIdentifier(expression: tstl.Identifier): SourceNode { return this.createSourceNode(expression, expression.text); } - private printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { + public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.table)); @@ -654,18 +657,15 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private printOperator(kind: tstl.Operator): string { - return LuaPrinter.operatorMap[kind]; - } - - private isEmptyStatement(statement: tstl.Statement): boolean { - return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + public printOperator(kind: tstl.Operator): SourceNode { + // tslint:disable-next-line:no-null-keyword + return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } - private removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { + protected removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { const aliveStatements = []; for (const statement of statements) { - if (!this.isEmptyStatement(statement)) { + if (!this.isStatementEmpty(statement)) { aliveStatements.push(statement); } if (tstl.isReturnStatement(statement)) { @@ -675,7 +675,11 @@ export class LuaPrinter { return aliveStatements; } - private joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { + protected isStatementEmpty(statement: tstl.Statement): boolean { + return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + } + + protected joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { const result = []; for (let i = 0; i < chunks.length; i++) { result.push(chunks[i]); diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ead94c6dc..9aee708ba 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -616,13 +616,13 @@ export class LuaTransformer { // Transform get accessors statement.members.filter(ts.isGetAccessor).forEach(getAccessor => { - const transformResult = this.transformGetAccessorDeclaration(getAccessor, className, statement); + const transformResult = this.transformGetAccessorDeclaration(getAccessor, className); result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform set accessors statement.members.filter(ts.isSetAccessor).forEach(setAccessor => { - const transformResult = this.transformSetAccessorDeclaration(setAccessor, className, statement); + const transformResult = this.transformSetAccessorDeclaration(setAccessor, className); result.push(...this.statementVisitResultToArray(transformResult)); }); @@ -655,7 +655,7 @@ export class LuaTransformer { return result; } - public createClassCreationMethods( + private createClassCreationMethods( statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, extendsType?: ts.Type @@ -1031,7 +1031,7 @@ export class LuaTransformer { ); } - public transformConstructorDeclaration( + private transformConstructorDeclaration( statement: ts.ConstructorDeclaration, className: tstl.Identifier, instanceFields: ts.PropertyDeclaration[], @@ -1124,8 +1124,7 @@ export class LuaTransformer { public transformGetAccessorDeclaration( getAccessor: ts.GetAccessorDeclaration, - className: tstl.Identifier, - classDeclaration: ts.ClassLikeDeclaration + className: tstl.Identifier ): StatementVisitResult { if (getAccessor.body === undefined) { @@ -1161,8 +1160,7 @@ export class LuaTransformer { public transformSetAccessorDeclaration( setAccessor: ts.SetAccessorDeclaration, - className: tstl.Identifier, - classDeclaration: ts.ClassLikeDeclaration + className: tstl.Identifier ): StatementVisitResult { if (setAccessor.body === undefined) { @@ -1309,7 +1307,9 @@ export class LuaTransformer { parameters.forEach(binding => { if (ts.isObjectBindingPattern(binding.name) || ts.isArrayBindingPattern(binding.name)) { const identifier = tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`); - bindingPatternDeclarations.push(...this.transformBindingPattern(binding.name, identifier)); + bindingPatternDeclarations.push(...this.statementVisitResultToArray( + this.transformBindingPattern(binding.name, identifier) + )); } }); @@ -1338,12 +1338,13 @@ export class LuaTransformer { return tstl.createIfStatement(nilCondition, ifBlock, undefined, declaration); } - public * transformBindingPattern( + public transformBindingPattern( pattern: ts.BindingPattern, table: tstl.Identifier, propertyAccessStack: ts.PropertyName[] = [] - ): IterableIterator + ): StatementVisitResult { + const result: tstl.Statement[] = []; const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (let index = 0; index < pattern.elements.length; index++) { const element = pattern.elements[index]; @@ -1356,7 +1357,9 @@ export class LuaTransformer { if (propertyName !== undefined) { propertyAccessStack.push(propertyName); } - yield* this.transformBindingPattern(element.name, table, propertyAccessStack); + result.push(...this.statementVisitResultToArray( + this.transformBindingPattern(element.name, table, propertyAccessStack) + )); } else { // Disallow ellipsis destructure if (element.dotDotDotToken) { @@ -1381,12 +1384,12 @@ export class LuaTransformer { const expression = isObjectBindingPattern ? tstl.createTableIndexExpression(tableExpression, tstl.createStringLiteral(propertyName.text)) : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); - yield* this.createLocalOrExportedOrGlobalDeclaration(variableName, expression); + result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); if (element.initializer) { const identifier = this.shouldExportIdentifier(variableName) ? this.createExportedIdentifier(variableName) : variableName; - yield tstl.createIfStatement( + result.push(tstl.createIfStatement( tstl.createBinaryExpression( identifier, tstl.createNilLiteral(), @@ -1400,12 +1403,13 @@ export class LuaTransformer { ), ] ) - ); + )); } } } } propertyAccessStack.pop(); + return result; } public transformModuleDeclaration(statement: ts.ModuleDeclaration): StatementVisitResult { @@ -1842,7 +1846,9 @@ export class LuaTransformer { table, this.transformExpression(statement.initializer))); } } - statements.push(...this.transformBindingPattern(statement.name, table)); + statements.push(...this.statementVisitResultToArray( + this.transformBindingPattern(statement.name, table) + )); return statements; } @@ -2013,7 +2019,7 @@ export class LuaTransformer { return tstl.createExpressionStatement(this.expectExpression(this.transformExpression(expression))); } - public transformYield(expression: ts.YieldExpression): ExpressionVisitResult { + public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { return tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("coroutine"), @@ -2137,7 +2143,7 @@ export class LuaTransformer { return tstl.createDoStatement(result, statement); } - public transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { + private transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); @@ -2168,7 +2174,7 @@ export class LuaTransformer { } } - public transformLoopBody( + protected transformLoopBody( loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement ): tstl.Statement[] { @@ -2188,13 +2194,13 @@ export class LuaTransformer { return baseResult; } - public transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { + private transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { return ts.isBlock(statement) ? this.transformStatements(statement.statements) : this.statementVisitResultToArray(this.transformStatement(statement)); } - public transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const arrayExpression = this.expectExpression(this.transformExpression(statement.expression)); // Arrays use numeric for loop (performs better than ipairs) @@ -2234,7 +2240,7 @@ export class LuaTransformer { } } - public transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const luaIterator = this.expectExpression(this.transformExpression(statement.expression)); const type = this.checker.getTypeAtLocation(statement.expression); const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); @@ -2307,7 +2313,7 @@ export class LuaTransformer { } } - public transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + private transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const iterable = this.expectExpression(this.transformExpression(statement.expression)); if (ts.isVariableDeclarationList(statement.initializer) && ts.isIdentifier(statement.initializer.declarations[0].name)) { @@ -2529,7 +2535,7 @@ export class LuaTransformer { ); } - public transformEmptyStatement(arg0: ts.EmptyStatement): StatementVisitResult { + public transformEmptyStatement(statement: ts.EmptyStatement): StatementVisitResult { return undefined; } @@ -2593,7 +2599,7 @@ export class LuaTransformer { case ts.SyntaxKind.NonNullExpression: return this.transformExpression((expression as ts.NonNullExpression).expression); case ts.SyntaxKind.YieldExpression: - return this.transformYield(expression as ts.YieldExpression); + return this.transformYieldExpression(expression as ts.YieldExpression); case ts.SyntaxKind.EmptyStatement: return undefined; case ts.SyntaxKind.NotEmittedStatement: @@ -2607,7 +2613,7 @@ export class LuaTransformer { } } - public transformBinaryOperation( + protected transformBinaryOperation( left: tstl.Expression, right: tstl.Expression, operator: ts.BinaryOperator, @@ -2725,7 +2731,7 @@ export class LuaTransformer { ); } - public transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { + private transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { // Validate assignment const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); @@ -2773,7 +2779,7 @@ export class LuaTransformer { } } - public transformAssignmentExpression(expression: ts.BinaryExpression) + private transformAssignmentExpression(expression: ts.BinaryExpression) : tstl.CallExpression | tstl.MethodCallExpression { // Validate assignment @@ -2868,7 +2874,7 @@ export class LuaTransformer { } } - public transformCompoundAssignmentExpression( + private transformCompoundAssignmentExpression( expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, @@ -3043,7 +3049,7 @@ export class LuaTransformer { ); } - public transformCompoundAssignmentStatement( + private transformCompoundAssignmentStatement( node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, @@ -3089,7 +3095,7 @@ export class LuaTransformer { } } - public transformUnaryBitLibOperation( + private transformUnaryBitLibOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator, @@ -3111,7 +3117,7 @@ export class LuaTransformer { ); } - public transformUnaryBitOperation( + private transformUnaryBitOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator @@ -3132,7 +3138,7 @@ export class LuaTransformer { } } - public transformBinaryBitLibOperation( + private transformBinaryBitLibOperation( node: ts.Node, left: tstl.Expression, right: tstl.Expression, @@ -3207,7 +3213,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression); } - private transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { + public transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { const isStrict = this.options.strict === true || this.options.strictNullChecks === true; if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { return this.transformProtectedConditionalExpression(expression); @@ -3298,23 +3304,23 @@ export class LuaTransformer { } } - public transformArrayLiteral(node: ts.ArrayLiteralExpression): ExpressionVisitResult { + public transformArrayLiteral(expression: ts.ArrayLiteralExpression): ExpressionVisitResult { const values: tstl.TableFieldExpression[] = []; - node.elements.forEach(child => { + expression.elements.forEach(child => { const childExpression = this.transformExpression(child); if (childExpression) { values.push(tstl.createTableFieldExpression(childExpression, undefined, child)); } }); - return tstl.createTableExpression(values, node); + return tstl.createTableExpression(values, expression); } - public transformObjectLiteral(node: ts.ObjectLiteralExpression): ExpressionVisitResult { + public transformObjectLiteral(expression: ts.ObjectLiteralExpression): ExpressionVisitResult { const properties: tstl.TableFieldExpression[] = []; // Add all property assignments - node.properties.forEach(element => { + expression.properties.forEach(element => { const name = element.name ? this.transformPropertyName(element.name) : undefined; if (ts.isPropertyAssignment(element)) { const expression = this.expectExpression(this.transformExpression(element.initializer)); @@ -3326,11 +3332,11 @@ export class LuaTransformer { const expression = this.expectExpression(this.transformFunctionExpression(element)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else { - throw TSTLErrors.UnsupportedKind("object literal element", element.kind, node); + throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); } }); - return tstl.createTableExpression(properties, node); + return tstl.createTableExpression(properties, expression); } public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { @@ -3484,35 +3490,35 @@ export class LuaTransformer { return tstl.createTableIndexExpression(baseClassName, tstl.createStringLiteral("prototype")); } - public transformCallExpression(node: ts.CallExpression): ExpressionVisitResult { + public transformCallExpression(expression: ts.CallExpression): ExpressionVisitResult { // Check for calls on primitives to override let parameters: tstl.Expression[] = []; - const isTupleReturn = tsHelper.isTupleReturnCall(node, this.checker); - const isTupleReturnForward = node.parent - && ts.isReturnStatement(node.parent) - && tsHelper.isInTupleReturnFunction(node, this.checker); - const isInDestructingAssignment = tsHelper.isInDestructingAssignment(node); - const isInSpread = node.parent && ts.isSpreadElement(node.parent); - const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); + const isTupleReturn = tsHelper.isTupleReturnCall(expression, this.checker); + const isTupleReturnForward = expression.parent + && ts.isReturnStatement(expression.parent) + && tsHelper.isInTupleReturnFunction(expression, this.checker); + const isInDestructingAssignment = tsHelper.isInDestructingAssignment(expression); + const isInSpread = expression.parent && ts.isSpreadElement(expression.parent); + const returnValueIsUsed = expression.parent && !ts.isExpressionStatement(expression.parent); const wrapResult = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment && !isInSpread && returnValueIsUsed; - if (ts.isPropertyAccessExpression(node.expression)) { - const result = this.expectExpression(this.transformPropertyCall(node)); + if (ts.isPropertyAccessExpression(expression.expression)) { + const result = this.expectExpression(this.transformPropertyCall(expression)); return wrapResult ? this.wrapInTable(result) : result; } - if (ts.isElementAccessExpression(node.expression)) { - const result = this.expectExpression(this.transformElementCall(node)); + if (ts.isElementAccessExpression(expression.expression)) { + const result = this.expectExpression(this.transformElementCall(expression)); return wrapResult ? this.wrapInTable(result) : result; } - const signature = this.checker.getResolvedSignature(node); + const signature = this.checker.getResolvedSignature(expression); // Handle super calls properly - if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { - parameters = this.transformArguments(node.arguments, signature, ts.createThis()); + if (expression.expression.kind === ts.SyntaxKind.SuperKeyword) { + parameters = this.transformArguments(expression.arguments, signature, ts.createThis()); return tstl.createCallExpression( tstl.createTableIndexExpression( @@ -3523,26 +3529,26 @@ export class LuaTransformer { ); } - const expressionType = this.checker.getTypeAtLocation(node.expression); + const expressionType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStandardLibraryType(expressionType, undefined, this.program)) { - const result = this.transformGlobalFunctionCall(node); + const result = this.transformGlobalFunctionCall(expression); if (result) { return result; } } - const callPath = this.expectExpression(this.transformExpression(node.expression)); + const callPath = this.expectExpression(this.transformExpression(expression.expression)); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) { - parameters = this.transformArguments(node.arguments, signature); + parameters = this.transformArguments(expression.arguments, signature); } else { const context = this.isStrict ? ts.createNull() : ts.createIdentifier("_G"); - parameters = this.transformArguments(node.arguments, signature, context); + parameters = this.transformArguments(expression.arguments, signature, context); } - const callExpression = tstl.createCallExpression(callPath, parameters, node); + const callExpression = tstl.createCallExpression(callPath, parameters, expression); return wrapResult ? this.wrapInTable(callExpression) : callExpression; } @@ -3775,22 +3781,22 @@ export class LuaTransformer { return parameters; } - public transformPropertyAccessExpression(node: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = node.name.text; + public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { + const property = expression.name.text; // Check for primitive types to override - const type = this.checker.getTypeAtLocation(node.expression); + const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStringType(type)) { - return this.transformStringProperty(node); + return this.transformStringProperty(expression); } else if (tsHelper.isArrayType(type, this.checker, this.program)) { - const arrayPropertyAccess = this.transformArrayProperty(node); + const arrayPropertyAccess = this.transformArrayProperty(expression); if (arrayPropertyAccess) { return arrayPropertyAccess; } } else if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) { - return this.transformConstEnumValue(type, property, node); + return this.transformConstEnumValue(type, property, expression); } this.checkForLuaLibType(type); @@ -3798,27 +3804,27 @@ export class LuaTransformer { const decorators = tsHelper.getCustomDecorators(type, this.checker); // Do not output path for member only enums if (decorators.has(DecoratorKind.CompileMembersOnly)) { - return tstl.createIdentifier(property, node); + return tstl.createIdentifier(property, expression); } if (decorators.has(DecoratorKind.LuaTable)) { - return this.transformLuaTableProperty(node); + return this.transformLuaTableProperty(expression); } // Catch math expressions - if (ts.isIdentifier(node.expression)) { - const ownerType = this.checker.getTypeAtLocation(node.expression); + if (ts.isIdentifier(expression.expression)) { + const ownerType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { - return this.transformMathExpression(node.name); + return this.transformMathExpression(expression.name); } else if (tsHelper.isStandardLibraryType(ownerType, "Symbol", this.program)) { // Pull in Symbol lib this.importLuaLibFeature(LuaLibFeature.Symbol); } } - const callPath = this.expectExpression(this.transformExpression(node.expression)); - return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), node); + const callPath = this.expectExpression(this.transformExpression(expression.expression)); + return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression); } // Transpile a Math._ property @@ -4523,19 +4529,19 @@ export class LuaTransformer { } } - public transformAssertionExpression(node: ts.AssertionExpression): ExpressionVisitResult { + public transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult { this.validateFunctionAssignment( - node, - this.checker.getTypeAtLocation(node.expression), - this.checker.getTypeAtLocation(node.type) + expression, + this.checker.getTypeAtLocation(expression.expression), + this.checker.getTypeAtLocation(expression.type) ); - return this.transformExpression(node.expression); + return this.transformExpression(expression.expression); } - public transformTypeOfExpression(node: ts.TypeOfExpression): ExpressionVisitResult { - const expression = this.expectExpression(this.transformExpression(node.expression)); + public transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult { + const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); const typeFunctionIdentifier = tstl.createIdentifier("type"); - const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [expression]); + const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [innerExpression]); const tableString = tstl.createStringLiteral("table"); const objectString = tstl.createStringLiteral("object"); const condition = tstl.createBinaryExpression(typeCall, tableString, tstl.SyntaxKind.EqualityOperator); @@ -4546,7 +4552,7 @@ export class LuaTransformer { andClause, tstl.cloneNode(typeCall), tstl.SyntaxKind.OrOperator, - node + expression ) ); } @@ -4626,7 +4632,7 @@ export class LuaTransformer { } } - private getIdentifierText(identifier: ts.Identifier): string { + protected getIdentifierText(identifier: ts.Identifier): string { const text = ts.idText(identifier); if (this.luaKeywords.has(text)) { @@ -4675,7 +4681,7 @@ export class LuaTransformer { return identifier; } - private isIdentifierExported(identifier: tstl.Identifier): boolean { + protected isIdentifierExported(identifier: tstl.Identifier): boolean { if (!this.isModule && !this.currentNamespace) { return false; } @@ -4710,14 +4716,14 @@ export class LuaTransformer { return false; } - private addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { + protected addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); } return identifier; } - private createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { + protected createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { const exportTable = this.currentNamespace ? this.transformIdentifier(this.currentNamespace.name as ts.Identifier) : this.createExportsIdentifier(); @@ -4727,7 +4733,7 @@ export class LuaTransformer { tstl.createStringLiteral(identifier.text)); } - private transformLuaLibFunction( + protected transformLuaLibFunction( func: LuaLibFeature, tsParent?: ts.Expression, ...params: tstl.Expression[] @@ -4738,7 +4744,7 @@ export class LuaTransformer { return tstl.createCallExpression(functionIdentifier, params, tsParent); } - public checkForLuaLibType(type: ts.Type): void { + protected checkForLuaLibType(type: ts.Type): void { if (type.symbol) { switch (this.checker.getFullyQualifiedName(type.symbol)) { case "Map": @@ -4757,11 +4763,11 @@ export class LuaTransformer { } } - private importLuaLibFeature(feature: LuaLibFeature): void { + protected importLuaLibFeature(feature: LuaLibFeature): void { this.luaLibFeatureSet.add(feature); } - private createImmediatelyInvokedFunctionExpression( + protected createImmediatelyInvokedFunctionExpression( statements: tstl.Statement[], result: tstl.Expression | tstl.Expression[], tsOriginal: ts.Node @@ -4774,7 +4780,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); } - private createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { + protected createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { switch (this.luaTarget) { case LuaTarget.Lua51: case LuaTarget.LuaJIT: @@ -4794,7 +4800,7 @@ export class LuaTransformer { } } - private getAbsoluteImportPath(relativePath: string): string { + protected getAbsoluteImportPath(relativePath: string): string { if (relativePath.charAt(0) !== "." && this.options.baseUrl) { return path.resolve(this.options.baseUrl, relativePath); } @@ -4806,7 +4812,7 @@ export class LuaTransformer { return path.resolve(path.dirname(this.currentSourceFile.fileName), relativePath); } - private getImportPath(relativePath: string, node: ts.Node): string { + protected getImportPath(relativePath: string, node: ts.Node): string { const rootDir = this.options.rootDir ? path.resolve(this.options.rootDir) : path.resolve("."); const absoluteImportPath = path.format(path.parse(this.getAbsoluteImportPath(relativePath))); const absoluteRootDirPath = path.format(path.parse(rootDir)); @@ -4820,7 +4826,7 @@ export class LuaTransformer { } } - private formatPathToLuaPath(filePath: string): string { + protected formatPathToLuaPath(filePath: string): string { filePath = filePath.replace(/\.json$/, ""); if (process.platform === "win32") { // Windows can use backslashes @@ -4833,7 +4839,7 @@ export class LuaTransformer { .replace(/\//g, "."); } - private shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { + protected shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { if (!this.isModule && !this.currentNamespace) { return false; } @@ -4844,15 +4850,15 @@ export class LuaTransformer { } } - private createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { + protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { return tstl.createIdentifier("self", tsOriginal); } - private createExportsIdentifier(): tstl.Identifier { + protected createExportsIdentifier(): tstl.Identifier { return tstl.createIdentifier("____exports"); } - private createLocalOrExportedOrGlobalDeclaration( + protected createLocalOrExportedOrGlobalDeclaration( lhs: tstl.Identifier | tstl.Identifier[], rhs?: tstl.Expression, tsOriginal?: ts.Node, @@ -4958,7 +4964,7 @@ export class LuaTransformer { } } - private validateFunctionAssignment(node: ts.Node, fromType: ts.Type, toType: ts.Type, toName?: string): void { + protected validateFunctionAssignment(node: ts.Node, fromType: ts.Type, toType: ts.Type, toName?: string): void { if (toType === fromType) { return; } @@ -5044,7 +5050,7 @@ export class LuaTransformer { } } - private validatePropertyAssignment(node: ts.Node): void { + protected validatePropertyAssignment(node: ts.Node): void { if (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left)) { const leftType = this.checker.getTypeAtLocation(node.left.expression); const decorators = tsHelper.getCustomDecorators(leftType, this.checker); @@ -5060,7 +5066,7 @@ export class LuaTransformer { } } - private wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { + protected wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { const returnStatement = tstl.createReturnStatement([expression]); return tstl.createFunctionExpression( tstl.createBlock([returnStatement]), @@ -5071,12 +5077,12 @@ export class LuaTransformer { ); } - private wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { + protected wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { const fields = expressions.map(e => tstl.createTableFieldExpression(e)); return tstl.createParenthesizedExpression(tstl.createTableExpression(fields)); } - private wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { + protected wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { if (tstl.isStringLiteral(expression) || tstl.isNumericLiteral(expression) || (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator)) @@ -5086,14 +5092,14 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); } - private expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { + protected expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { if (tstl.isBinaryExpression(expression)) { expression = tstl.createParenthesizedExpression(expression); } return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } - private getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { + protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { const symbol = this.checker.getSymbolAtLocation(identifier); let symbolId: number | undefined; if (symbol) { @@ -5317,7 +5323,7 @@ export class LuaTransformer { return declaration; } - private statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { + protected statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { if (!Array.isArray(visitResult)) { if (visitResult) { return [visitResult]; @@ -5325,14 +5331,14 @@ export class LuaTransformer { return []; } - return visitResult.filter(s => s !== undefined); + return this.filterUndefined(visitResult); } - private filterUndefined(items: Array): T[] { + protected filterUndefined(items: Array): T[] { return items.filter(i => i !== undefined) as T[]; } - private filterUndefinedAndCast( + protected filterUndefinedAndCast( items: Array, cast: (item: TOriginal) => item is TCast ): TCast[] { const filteredItems = items.filter(i => i !== undefined) as TOriginal[]; @@ -5343,7 +5349,7 @@ export class LuaTransformer { } } - private expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { + protected expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { if (visitResult === undefined) { throw new Error("Expected single visit result expression, but found undefined"); } else { From c30407839196835d6c6046c03d1c9f20037caf5b Mon Sep 17 00:00:00 2001 From: Evan Hemsley <2342303+ehemsley@users.noreply.github.com> Date: Sun, 5 May 2019 06:53:14 -0700 Subject: [PATCH 075/764] Class decorators (#558) * class decorator tests * decorate lualib function * fix decorate emission + decorate lualib * add variable argument decorator test * add decorator with class inheritance test * forgot to remove a comment * add missing end newline * revert accidental import * use transformLuaLibFunction * revert importLuaLib refactor * add test case for applying decorators in order * change decorator name in test case * improve decorator order test * improve Decorate helper * rename generate to create * simplify decorator expression table generator * shorten test string * fix prettier style * add error if decorator function context is void * remove accidental this: void from decorator test * clarified error message * change createConstructorDecorationStatement to private * better decorator application test name --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 40 +++++++ src/TSTLErrors.ts | 3 + src/lualib/Decorate.ts | 25 ++++ test/unit/classDecorator.spec.ts | 190 +++++++++++++++++++++++++++++++ test/util.ts | 1 + 6 files changed, 260 insertions(+) create mode 100644 src/lualib/Decorate.ts create mode 100644 test/unit/classDecorator.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 08a02e9c3..6f724c9ee 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -22,6 +22,7 @@ export enum LuaLibFeature { ArraySetLength = "ArraySetLength", ClassIndex = "ClassIndex", ClassNewIndex = "ClassNewIndex", + Decorate = "Decorate", FunctionApply = "FunctionApply", FunctionBind = "FunctionBind", FunctionCall = "FunctionCall", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9aee708ba..fcf09596f 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -650,6 +650,11 @@ export class LuaTransformer { result.push(fieldAssign); } + const decorationStatement = this.createConstructorDecorationStatement(statement); + if (decorationStatement) { + result.push(decorationStatement); + } + this.classStack.pop(); return result; @@ -5356,4 +5361,39 @@ export class LuaTransformer { return visitResult; } } + + private createConstructorDecorationStatement( + declaration: ts.ClassLikeDeclaration + ): tstl.AssignmentStatement | undefined { + const className = declaration.name !== undefined + ? this.transformIdentifier(declaration.name) + : tstl.createAnonymousIdentifier(); + + const decorators = declaration.decorators; + if (!decorators) { return undefined; } + + const decoratorExpressions = this.filterUndefined( + decorators.map(decorator => { + const expression = decorator.expression; + const type = this.checker.getTypeAtLocation(expression); + const context = tsHelper.getFunctionContextType(type, this.checker); + if (context === ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } + return this.transformExpression(expression); + }) + ); + + const decoratorArguments: tstl.Expression[] = []; + + const decoratorTable = tstl.createTableExpression( + decoratorExpressions.map(expression => tstl.createTableFieldExpression(expression)) + ); + + decoratorArguments.push(decoratorTable); + decoratorArguments.push(className); + + return tstl.createAssignmentStatement( + className, + this.transformLuaLibFunction(LuaLibFeature.Decorate, undefined, ...decoratorArguments) + ); + } } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 1b1684246..050b77d6f 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -42,6 +42,9 @@ export class TSTLErrors { public static InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); + public static InvalidDecoratorContext = (node: ts.Node) => + new TranspileError(`Decorator function cannot have 'this: void'.`, node); + public static InvalidExtensionMetaExtension = (node: ts.Node) => new TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node); diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts new file mode 100644 index 000000000..15dbee15d --- /dev/null +++ b/src/lualib/Decorate.ts @@ -0,0 +1,25 @@ +/** + * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 + */ +function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: string, desc?: any): {} { + let result = target; + + for (let i = decorators.length; i >= 0; i--) { + const decorator = decorators[i]; + if (decorator) { + const oldResult = result; + + if (key === undefined) { + result = decorator(result); + } else if (desc !== undefined) { + result = decorator(target, key, result); + } else { + result = decorator(target, key); + } + + result = result || oldResult; + } + } + + return result; +} diff --git a/test/unit/classDecorator.spec.ts b/test/unit/classDecorator.spec.ts new file mode 100644 index 000000000..96e2ed474 --- /dev/null +++ b/test/unit/classDecorator.spec.ts @@ -0,0 +1,190 @@ +import * as util from "../util"; +import { TSTLErrors } from "../../src/TSTLErrors"; + +test("Class decorator with no parameters", () => { + const source = ` + function SetBool(constructor: T) { + return class extends constructor { + decoratorBool = true; + } + } + + @SetBool + class TestClass { + public decoratorBool = false; + } + + const classInstance = new TestClass(); + return classInstance.decoratorBool; + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe(true); +}); + +test("Class decorator with parameters", () => { + const source = ` + function SetNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + @SetNum(420) + class TestClass { + public decoratorNum; + } + + const classInstance = new TestClass(); + return classInstance.decoratorNum; + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe(420); +}); + +test("Class decorator with variable parameters", () => { + const source = ` + function SetNumbers(...numArgs: number[]) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNums = new Set(numArgs); + }; + }; + } + + @SetNumbers(120, 30, 54) + class TestClass { + public decoratorNums; + } + + const classInstance = new TestClass(); + let sum = 0; + for (const value of classInstance.decoratorNums) { + sum += value; + } + return sum; + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe(204); +}); + +test("Multiple class decorators", () => { + const source = ` + function SetTen(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + function SetNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + @SetTen + @SetNum(410) + class TestClass { + public decoratorTen; + public decoratorNum; + } + + const classInstance = new TestClass(); + return classInstance.decoratorNum + classInstance.decoratorTen; + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe(420); +}); + +test("Class decorator with inheritance", () => { + const source = ` + function SetTen(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + function SetNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + class TestClass { + public decoratorTen = 0; + public decoratorNum = 0; + } + + @SetTen + @SetNum(410) + class SubTestClass extends TestClass {} + + const classInstance = new SubTestClass(); + return classInstance.decoratorNum + classInstance.decoratorTen; + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe(420); +}); + +test("Class decorators are applied in order and executed in reverse order", () => { + const source = ` + const order = []; + + function SetString(stringArg: string) { + order.push("eval " + stringArg); + return {}>(constructor: T) => { + order.push("execute " + stringArg); + return class extends constructor { + decoratorString = stringArg; + }; + }; + } + + @SetString("fox") + @SetString("jumped") + @SetString("over dog") + class TestClass { + public static decoratorString = ""; + } + + const inst = new TestClass(); + return order.join(" "); + `; + + const result = util.transpileAndExecute(source); + expect(result).toBe( + "eval fox eval jumped eval over dog execute over dog execute jumped execute fox", + ); +}); + +test("Throws error if decorator function has void context", () => { + const source = ` + function SetBool(this: void, constructor: T) { + return class extends constructor { + decoratorBool = true; + } + } + + @SetBool + class TestClass { + public decoratorBool = false; + } + + const classInstance = new TestClass(); + return classInstance.decoratorBool; + `; + + expect(() => util.transpileAndExecute(source)).toThrowExactError( + TSTLErrors.InvalidDecoratorContext(util.nodeStub), + ); +}); diff --git a/test/util.ts b/test/util.ts index c8dfa1e21..092e6afda 100644 --- a/test/util.ts +++ b/test/util.ts @@ -36,6 +36,7 @@ export function transpileStringResult( "lib.es2018.d.ts", "lib.esnext.d.ts", ], + experimentalDecorators: true, ...options, }; From 1fc5f2607d386fffa17115add60ad0784db5b945 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 5 May 2019 08:22:03 -0600 Subject: [PATCH 076/764] Support for spread operator on iterables (#569) * Support for spread operator on iterables fixes #534 * adressing feedback on test --- src/LuaLib.ts | 2 ++ src/LuaTransformer.ts | 7 ++++++- src/lualib/Spread.ts | 13 +++++++++++++ test/unit/spreadElement.spec.ts | 20 ++++++++++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 src/lualib/Spread.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 6f724c9ee..6ab22d97c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -44,6 +44,7 @@ export enum LuaLibFeature { WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", + Spread = "Spread", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", StringReplace = "StringReplace", @@ -63,6 +64,7 @@ const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], + Spread: [LuaLibFeature.Iterator], SymbolRegistry: [LuaLibFeature.Symbol], }; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index fcf09596f..c06518268 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4566,9 +4566,14 @@ export class LuaTransformer { const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) { return innerExpression; - } else { + } + + const type = this.checker.getTypeAtLocation(expression.expression); + if (tsHelper.isArrayType(type, this.checker, this.program)) { return this.createUnpackCall(innerExpression, expression); } + + return this.transformLuaLibFunction(LuaLibFeature.Spread, expression, innerExpression); } public transformStringLiteral(literal: ts.StringLiteralLike): ExpressionVisitResult { diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts new file mode 100644 index 000000000..316f34ef5 --- /dev/null +++ b/src/lualib/Spread.ts @@ -0,0 +1,13 @@ +declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; + +declare namespace table { + export function unpack(this: void, list: T[], i?: number, j?: number): T[]; +} + +function __TS__Spread(this: void, iterable: Iterable): T[] { + const arr: T[] = []; + for (const item of iterable) { + arr[arr.length] = item; + } + return (table.unpack || unpack)(arr); +} diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index dfcb345d1..ad50137ef 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -47,3 +47,23 @@ test("Spread Element Lua JIT", () => { const lua = util.transpileString(`[...[0, 1, 2]]`, options); expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})}"); }); + +test("Spread Element Iterable", () => { + const code = ` + const it = { + i: -1, + [Symbol.iterator]() { + return this; + }, + next() { + ++this.i; + return { + value: 2 ** this.i, + done: this.i == 9, + } + } + }; + const arr = [...it]; + return JSONStringify(arr)`; + expect(JSON.parse(util.transpileAndExecute(code))).toEqual([1, 2, 4, 8, 16, 32, 64, 128, 256]); +}); From 512c4575282fa86b76882f02a204432bc6b1bb31 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 5 May 2019 08:29:17 -0600 Subject: [PATCH 077/764] fixed property shorthand with exported identifier (#562) fixes #560 --- src/LuaTransformer.ts | 29 ++++++++++++++++++++--------- test/unit/objectLiteral.spec.ts | 9 +++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index c06518268..26f818335 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3331,7 +3331,13 @@ export class LuaTransformer { const expression = this.expectExpression(this.transformExpression(element.initializer)); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { - const identifier = this.transformIdentifierExpression(element.name); + let identifier = this.transformIdentifierExpression(element.name); + if (tstl.isIdentifier(identifier)) { + const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol !== undefined && this.isSymbolExported(valueSymbol)) { + identifier = this.createExportedIdentifier(identifier); + } + } properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { const expression = this.expectExpression(this.transformFunctionExpression(element)); @@ -4692,12 +4698,16 @@ export class LuaTransformer { } protected isIdentifierExported(identifier: tstl.Identifier): boolean { - if (!this.isModule && !this.currentNamespace) { + const symbolInfo = identifier.symbolId && this.symbolInfo.get(identifier.symbolId); + if (!symbolInfo) { return false; } - const symbolInfo = identifier.symbolId && this.symbolInfo.get(identifier.symbolId); - if (!symbolInfo) { + return this.isSymbolExported(symbolInfo.symbol); + } + + protected isSymbolExported(symbol: ts.Symbol): boolean { + if (!this.isModule && !this.currentNamespace) { return false; } @@ -4706,9 +4716,10 @@ export class LuaTransformer { throw TSTLErrors.UndefinedScope(); } - const scopeSymbol = this.checker.getSymbolAtLocation(currentScope) - ? this.checker.getSymbolAtLocation(currentScope) - : this.checker.getTypeAtLocation(currentScope).getSymbol(); + let scopeSymbol = this.checker.getSymbolAtLocation(currentScope); + if (scopeSymbol === undefined) { + scopeSymbol = this.checker.getTypeAtLocation(currentScope).getSymbol(); + } if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { return false; @@ -4718,8 +4729,8 @@ export class LuaTransformer { const it: Iterable = { [Symbol.iterator]: () => scopeSymbolExports.values(), // Why isn't ts.SymbolTable.values() iterable? }; - for (const symbol of it) { - if (symbol === symbolInfo.symbol) { + for (const exportedSymbol of it) { + if (exportedSymbol === symbol) { return true; } } diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index ed31245a7..9c1be2618 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -29,6 +29,15 @@ describe("property shorthand", () => { expect(result).toBe(identifier); }); + + test("should support export property shorthand", () => { + const code = ` + export const x = 1; + const o = { x }; + export const y = o.x; + `; + expect(util.transpileExecuteAndReturnExport(code, "y")).toBe(1); + }); }); test("undefined as object key", () => { From bd7dcd52678c68e7ba749bfc9b89ecbe074f7bd0 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 5 May 2019 19:41:19 +0500 Subject: [PATCH 078/764] Remove undefined from expression visitors (#566) * Remove undefined from expression visitors * Remove some no longer required checks --- src/LuaAST.ts | 2 + src/LuaTransformer.ts | 263 ++++++++++++++++++------------------------ 2 files changed, 115 insertions(+), 150 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 8f015bc3f..81f3cb7ce 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -132,6 +132,8 @@ export function setNodePosition(node: T, position: TextRange): T return node; } +export function setNodeOriginal(node: T, tsOriginal: ts.Node): T; +export function setNodeOriginal(node: T | undefined, tsOriginal: ts.Node): T | undefined; export function setNodeOriginal(node: T | undefined, tsOriginal: ts.Node): T | undefined { if (node === undefined) { return undefined; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 26f818335..cb9c6cb25 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -8,7 +8,7 @@ import { ContextType, TSHelper as tsHelper } from "./TSHelper"; import { TSTLErrors } from "./TSTLErrors"; export type StatementVisitResult = tstl.Statement | tstl.Statement[] | undefined; -export type ExpressionVisitResult = tstl.Expression | undefined; +export type ExpressionVisitResult = tstl.Expression; export enum ScopeType { File = 0x1, Function = 0x2, @@ -110,8 +110,8 @@ export class LuaTransformer { throw TSTLErrors.InvalidJsonFileContent(node); } - statements.push(tstl.createReturnStatement( - this.filterUndefined([this.transformExpression(statement.expression)])) + statements.push( + tstl.createReturnStatement([this.transformExpression(statement.expression)]) ); } else { this.pushScope(ScopeType.File, node); @@ -541,7 +541,7 @@ export class LuaTransformer { result.push(...classCreationMethods); } else { for (const f of instanceFields) { - const fieldName = this.expectExpression(this.transformPropertyName(f.name)); + const fieldName = this.transformPropertyName(f.name); const value = f.initializer !== undefined ? this.transformExpression(f.initializer) @@ -592,7 +592,7 @@ export class LuaTransformer { const superCall = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createTableIndexExpression( - this.expectExpression(this.transformSuperKeyword(ts.createSuper())), + this.transformSuperKeyword(ts.createSuper()), tstl.createStringLiteral("____constructor") ), [this.createSelfIdentifier(), tstl.createDotsLiteral()] @@ -634,7 +634,7 @@ export class LuaTransformer { // Add static declarations for (const field of staticFields) { - const fieldName = this.expectExpression(this.transformPropertyName(field.name)); + const fieldName = this.transformPropertyName(field.name); const value = field.initializer ? this.transformExpression(field.initializer) : undefined; const classField = tstl.createTableIndexExpression( @@ -994,7 +994,7 @@ export class LuaTransformer { for (const f of instanceFields) { // Get identifier - const fieldName = this.expectExpression(this.transformPropertyName(f.name)); + const fieldName = this.transformPropertyName(f.name); const value = f.initializer ? this.transformExpression(f.initializer) : undefined; @@ -1012,7 +1012,7 @@ export class LuaTransformer { ) as ts.GetAccessorDeclaration[]; for (const getter of getOverrides) { - const getterName = this.expectExpression(this.transformPropertyName(getter.name)); + const getterName = this.transformPropertyName(getter.name); const resetGetter = tstl.createExpressionStatement( tstl.createCallExpression( @@ -1067,7 +1067,7 @@ export class LuaTransformer { ), tstl.createBinaryExpression( declarationName, - this.expectExpression(this.transformExpression(declaration.initializer)), + this.transformExpression(declaration.initializer), tstl.SyntaxKind.OrOperator ) ); @@ -1212,7 +1212,7 @@ export class LuaTransformer { return undefined; } - let methodName = this.expectExpression(this.transformPropertyName(node.name)); + let methodName = this.transformPropertyName(node.name); if (tstl.isStringLiteral(methodName) && methodName.value === "toString") { methodName = tstl.createStringLiteral("__tostring", node.name); } @@ -1378,7 +1378,7 @@ export class LuaTransformer { : this.transformNumericLiteral(property); tableExpression = tstl.createTableIndexExpression( tableExpression, - this.expectExpression(propertyName) + propertyName ); }); // The identifier of the new variable @@ -1530,7 +1530,7 @@ export class LuaTransformer { } for (const enumMember of this.computeEnumMembers(enumDeclaration)) { - const memberName = this.expectExpression(this.transformPropertyName(enumMember.name)); + const memberName = this.transformPropertyName(enumMember.name); if (membersOnly) { if (tstl.isIdentifier(memberName)) { result.push(...this.createLocalOrExportedOrGlobalDeclaration( @@ -1584,7 +1584,11 @@ export class LuaTransformer { if (ts.isIdentifier(member.initializer)) { const [isEnumMember, originalName] = tsHelper.isEnumMember(node, member.initializer); if (isEnumMember === true && originalName !== undefined) { - valueExpression = valueMap.get(originalName); + if (valueMap.has(originalName)) { + valueExpression = valueMap.get(originalName)!; + } else { + throw new Error(`Expected valueMap to contain ${originalName}`); + } } else { valueExpression = this.transformExpression(member.initializer); } @@ -1608,7 +1612,7 @@ export class LuaTransformer { const enumMember = { name: member.name, original: member, - value: this.expectExpression(valueExpression), + value: valueExpression, }; return enumMember; @@ -1881,7 +1885,7 @@ export class LuaTransformer { } else { // local vars = this.transpileDestructingAssignmentValue(node.initializer); const initializer = this.createUnpackCall( - this.expectExpression(this.transformExpression(statement.initializer)), + this.transformExpression(statement.initializer), statement.initializer ); statements.push(...this.createLocalOrExportedOrGlobalDeclaration(vars, initializer, statement)); @@ -2021,7 +2025,7 @@ export class LuaTransformer { } } - return tstl.createExpressionStatement(this.expectExpression(this.transformExpression(expression))); + return tstl.createExpressionStatement(this.transformExpression(expression)); } public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { @@ -2030,7 +2034,7 @@ export class LuaTransformer { tstl.createIdentifier("coroutine"), tstl.createStringLiteral("yield")), expression.expression - ? [this.expectExpression(this.transformExpression(expression.expression))] + ? [this.transformExpression(expression.expression)] : [], expression ); @@ -2047,9 +2051,9 @@ export class LuaTransformer { // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(statement.expression)) { // If return expression is an array literal, leave out brackets. - return tstl.createReturnStatement(this.filterUndefined( + return tstl.createReturnStatement( statement.expression.elements.map(elem => this.transformExpression(elem)) - )); + ); } const expressionType = this.checker.getTypeAtLocation(statement.expression); @@ -2058,13 +2062,13 @@ export class LuaTransformer { { // If return expression is an array-type and not another TupleReturn call, unpack it const expression = this.createUnpackCall( - this.expectExpression(this.transformExpression(statement.expression)), + this.transformExpression(statement.expression), statement.expression ); return tstl.createReturnStatement([expression]); } } - const returnExpressions = [this.expectExpression(this.transformExpression(statement.expression))]; + const returnExpressions = [this.transformExpression(statement.expression)]; return tstl.createReturnStatement(returnExpressions, statement); } else { // Empty return @@ -2074,7 +2078,7 @@ export class LuaTransformer { public transformIfStatement(statement: ts.IfStatement): StatementVisitResult { this.pushScope(ScopeType.Conditional, statement.thenStatement); - const condition = this.expectExpression(this.transformExpression(statement.expression)); + const condition = this.transformExpression(statement.expression); const statements = this.performHoisting(this.transformBlockOrStatement(statement.thenStatement)); this.popScope(); const ifBlock = tstl.createBlock(statements); @@ -2096,7 +2100,7 @@ export class LuaTransformer { public transformWhileStatement(statement: ts.WhileStatement): StatementVisitResult { return tstl.createWhileStatement( tstl.createBlock(this.transformLoopBody(statement)), - this.expectExpression(this.transformExpression(statement.expression)), + this.transformExpression(statement.expression), statement ); } @@ -2106,7 +2110,7 @@ export class LuaTransformer { tstl.createBlock(this.transformLoopBody(statement)), tstl.createUnaryExpression( tstl.createParenthesizedExpression( - this.expectExpression(this.transformExpression(statement.expression)) + this.transformExpression(statement.expression) ), tstl.SyntaxKind.NotOperator ), @@ -2143,7 +2147,7 @@ export class LuaTransformer { } // while (condition) do ... end - result.push(tstl.createWhileStatement(tstl.createBlock(body), this.expectExpression(condition))); + result.push(tstl.createWhileStatement(tstl.createBlock(body), condition)); return tstl.createDoStatement(result, statement); } @@ -2206,7 +2210,7 @@ export class LuaTransformer { } private transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const arrayExpression = this.expectExpression(this.transformExpression(statement.expression)); + const arrayExpression = this.transformExpression(statement.expression); // Arrays use numeric for loop (performs better than ipairs) const indexVariable = tstl.createIdentifier("____TS_index"); @@ -2246,7 +2250,7 @@ export class LuaTransformer { } private transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const luaIterator = this.expectExpression(this.transformExpression(statement.expression)); + const luaIterator = this.transformExpression(statement.expression); const type = this.checker.getTypeAtLocation(statement.expression); const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); if (tupleReturn) { @@ -2277,8 +2281,9 @@ export class LuaTransformer { const tmps = statement.initializer.elements .map((_, i) => tstl.createIdentifier(`____TS_value${i}`)); const assign = tstl.createAssignmentStatement( - statement.initializer.elements - .map(e => this.transformExpression(e)) as tstl.IdentifierOrTableIndexExpression[], + statement.initializer.elements.map(e => + this.transformExpression(e) as tstl.IdentifierOrTableIndexExpression + ), tmps ); block.statements.splice(0, 0, assign); @@ -2319,7 +2324,7 @@ export class LuaTransformer { } private transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const iterable = this.expectExpression(this.transformExpression(statement.expression)); + const iterable = this.transformExpression(statement.expression); if (ts.isVariableDeclarationList(statement.initializer) && ts.isIdentifier(statement.initializer.declarations[0].name)) { // Single variable declared in for loop @@ -2374,7 +2379,7 @@ export class LuaTransformer { // Transpile expression const pairsIdentifier = tstl.createIdentifier("pairs"); - const expression = this.expectExpression(this.transformExpression(statement.expression)); + const expression = this.transformExpression(statement.expression); const pairsCall = tstl.createCallExpression(pairsIdentifier, [expression]); if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program)) { @@ -2418,7 +2423,7 @@ export class LuaTransformer { // If the clause condition holds, go to the correct label const condition = tstl.createBinaryExpression( switchVariable, - this.expectExpression(this.transformExpression(clause.expression)), + this.transformExpression(clause.expression), tstl.SyntaxKind.EqualityOperator ); const goto = tstl.createGotoStatement(`${switchName}_case_${i}`); @@ -2512,10 +2517,7 @@ export class LuaTransformer { if (tsHelper.isStringType(type)) { const error = tstl.createIdentifier("error"); return tstl.createExpressionStatement( - tstl.createCallExpression( - error, - this.filterUndefined([this.transformExpression(statement.expression)]) - ), + tstl.createCallExpression(error, [this.transformExpression(statement.expression)]), statement ); } else { @@ -2605,10 +2607,6 @@ export class LuaTransformer { return this.transformExpression((expression as ts.NonNullExpression).expression); case ts.SyntaxKind.YieldExpression: return this.transformYieldExpression(expression as ts.YieldExpression); - case ts.SyntaxKind.EmptyStatement: - return undefined; - case ts.SyntaxKind.NotEmittedStatement: - return undefined; case ts.SyntaxKind.ClassExpression: return this.transformClassExpression(expression as ts.ClassExpression); case ts.SyntaxKind.PartiallyEmittedExpression: @@ -2657,8 +2655,8 @@ export class LuaTransformer { ); } - const lhs = this.expectExpression(this.transformExpression(expression.left)); - const rhs = this.expectExpression(this.transformExpression(expression.right)); + const lhs = this.transformExpression(expression.left); + const rhs = this.transformExpression(expression.right); // Transpile operators switch (expression.operatorToken.kind) { @@ -2749,8 +2747,8 @@ export class LuaTransformer { this.transformLuaLibFunction( LuaLibFeature.ArraySetLength, expression, - this.expectExpression(this.transformExpression(expression.left.expression)), - this.expectExpression(this.transformExpression(expression.right)) + this.transformExpression(expression.left.expression), + this.transformExpression(expression.right) ) ); } @@ -2769,7 +2767,7 @@ export class LuaTransformer { right = [tstl.createNilLiteral()]; } } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = this.filterUndefined([this.transformExpression(expression.right)]); + right = [this.transformExpression(expression.right)]; } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } @@ -2797,8 +2795,8 @@ export class LuaTransformer { return this.transformLuaLibFunction( LuaLibFeature.ArraySetLength, expression, - this.expectExpression(this.transformExpression(expression.left.expression)), - this.expectExpression(this.transformExpression(expression.right)) + this.transformExpression(expression.left.expression), + this.transformExpression(expression.right) ); } @@ -2811,10 +2809,10 @@ export class LuaTransformer { let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { right = expression.right.elements.length > 0 - ? this.filterUndefined(expression.right.elements.map(e => this.transformExpression(e))) + ? expression.right.elements.map(e => this.transformExpression(e)) : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = this.filterUndefined([this.transformExpression(expression.right)]); + right = [this.transformExpression(expression.right)]; } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } @@ -2852,24 +2850,20 @@ export class LuaTransformer { indexExpression = tstl.createStringLiteral(expression.left.name.text); } else { // Element access - indexExpression = this.expectExpression(this.transformExpression(expression.left.argumentExpression)); + indexExpression = this.transformExpression(expression.left.argumentExpression); const argType = this.checker.getTypeAtLocation(expression.left.expression); if (tsHelper.isArrayType(argType, this.checker, this.program)) { // Array access needs a +1 indexExpression = this.expressionPlusOne(indexExpression); } } - const args = [objExpression, indexExpression, this.transformExpression(expression.right)]; - return tstl.createCallExpression( - tstl.createParenthesizedExpression(iife), - this.filterUndefined(args), - expression - ); + const args = [objExpression, indexExpression, this.transformExpression(expression.right)]; + return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), args, expression); } else { // Simple assignment // (function() ${left} = ${right}; return ${left} end)() - const left = this.expectExpression(this.transformExpression(expression.left)); + const left = this.transformExpression(expression.left); const right = this.transformExpression(expression.right); return this.createImmediatelyInvokedFunctionExpression( [this.transformAssignment(expression.left, right)], @@ -2888,7 +2882,7 @@ export class LuaTransformer { ): tstl.CallExpression { const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; - let right = this.expectExpression(this.transformExpression(rhs)); + let right = this.transformExpression(rhs); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, @@ -2902,10 +2896,7 @@ export class LuaTransformer { const index = tstl.createIdentifier("____TS_index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( [obj, index], - this.filterUndefined( - [this.transformExpression(objExpression), - this.transformExpression(indexExpression)] - ) + [this.transformExpression(objExpression), this.transformExpression(indexExpression)] ); const accessExpression = tstl.createTableIndexExpression(obj, index); @@ -3062,7 +3053,7 @@ export class LuaTransformer { ): tstl.Statement { const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; - const right = this.expectExpression(this.transformExpression(rhs)); + const right = this.transformExpression(rhs); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( lhs, @@ -3077,10 +3068,7 @@ export class LuaTransformer { const index = tstl.createIdentifier("____TS_index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( [obj, index], - this.filterUndefined([ - this.transformExpression(objExpression), - this.transformExpression(indexExpression), - ]) + [this.transformExpression(objExpression), this.transformExpression(indexExpression)] ); const accessExpression = tstl.createTableIndexExpression(obj, index); const operatorExpression = this.transformBinaryOperation( @@ -3205,9 +3193,9 @@ export class LuaTransformer { } private transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { - const condition = this.expectExpression(this.transformExpression(expression.condition)); - const val1 = this.expectExpression(this.transformExpression(expression.whenTrue)); - const val2 = this.expectExpression(this.transformExpression(expression.whenFalse)); + const condition = this.transformExpression(expression.condition); + const val1 = this.transformExpression(expression.whenTrue); + const val2 = this.transformExpression(expression.whenFalse); const val1Function = this.wrapInFunctionCall(val1); const val2Function = this.wrapInFunctionCall(val2); @@ -3223,9 +3211,9 @@ export class LuaTransformer { if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { return this.transformProtectedConditionalExpression(expression); } - const condition = this.expectExpression(this.transformExpression(expression.condition)); - const val1 = this.expectExpression(this.transformExpression(expression.whenTrue)); - const val2 = this.expectExpression(this.transformExpression(expression.whenFalse)); + const condition = this.transformExpression(expression.condition); + const val1 = this.transformExpression(expression.whenTrue); + const val2 = this.transformExpression(expression.whenFalse); // condition and v1 or v2 const conditionAnd = tstl.createBinaryExpression(condition, val1, tstl.SyntaxKind.AndOperator); @@ -3287,20 +3275,20 @@ export class LuaTransformer { case ts.SyntaxKind.MinusToken: return tstl.createUnaryExpression( - this.expectExpression(this.transformExpression(expression.operand)), + this.transformExpression(expression.operand), tstl.SyntaxKind.NegationOperator ); case ts.SyntaxKind.ExclamationToken: return tstl.createUnaryExpression( - this.expectExpression(this.transformExpression(expression.operand)), + this.transformExpression(expression.operand), tstl.SyntaxKind.NotOperator ); case ts.SyntaxKind.TildeToken: return this.transformUnaryBitOperation( expression, - this.expectExpression(this.transformExpression(expression.operand)), + this.transformExpression(expression.operand), tstl.SyntaxKind.BitwiseNotOperator ); @@ -3310,14 +3298,9 @@ export class LuaTransformer { } public transformArrayLiteral(expression: ts.ArrayLiteralExpression): ExpressionVisitResult { - const values: tstl.TableFieldExpression[] = []; - - expression.elements.forEach(child => { - const childExpression = this.transformExpression(child); - if (childExpression) { - values.push(tstl.createTableFieldExpression(childExpression, undefined, child)); - } - }); + const values = expression.elements.map( + e => tstl.createTableFieldExpression(this.transformExpression(e), undefined, e) + ); return tstl.createTableExpression(values, expression); } @@ -3328,7 +3311,7 @@ export class LuaTransformer { expression.properties.forEach(element => { const name = element.name ? this.transformPropertyName(element.name) : undefined; if (ts.isPropertyAssignment(element)) { - const expression = this.expectExpression(this.transformExpression(element.initializer)); + const expression = this.transformExpression(element.initializer); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { let identifier = this.transformIdentifierExpression(element.name); @@ -3340,7 +3323,7 @@ export class LuaTransformer { } properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { - const expression = this.expectExpression(this.transformFunctionExpression(element)); + const expression = this.transformFunctionExpression(element); properties.push(tstl.createTableFieldExpression(expression, name, element)); } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); @@ -3416,7 +3399,7 @@ export class LuaTransformer { } public transformNewExpression(node: ts.NewExpression): ExpressionVisitResult { - const name = this.expectExpression(this.transformExpression(node.expression)); + const name = this.transformExpression(node.expression); const signature = this.checker.getResolvedSignature(node); const params = node.arguments ? this.transformArguments(node.arguments, signature) @@ -3469,7 +3452,7 @@ export class LuaTransformer { } return tstl.createParenthesizedExpression( - this.expectExpression(this.transformExpression(expression.expression)), + this.transformExpression(expression.expression), expression ); } @@ -3516,12 +3499,12 @@ export class LuaTransformer { && !isInSpread && returnValueIsUsed; if (ts.isPropertyAccessExpression(expression.expression)) { - const result = this.expectExpression(this.transformPropertyCall(expression)); + const result = this.transformPropertyCall(expression); return wrapResult ? this.wrapInTable(result) : result; } if (ts.isElementAccessExpression(expression.expression)) { - const result = this.expectExpression(this.transformElementCall(expression)); + const result = this.transformElementCall(expression); return wrapResult ? this.wrapInTable(result) : result; } @@ -3533,7 +3516,7 @@ export class LuaTransformer { return tstl.createCallExpression( tstl.createTableIndexExpression( - this.expectExpression(this.transformSuperKeyword(ts.createSuper())), + this.transformSuperKeyword(ts.createSuper()), tstl.createStringLiteral("____constructor") ), parameters @@ -3548,7 +3531,7 @@ export class LuaTransformer { } } - const callPath = this.expectExpression(this.transformExpression(expression.expression)); + const callPath = this.transformExpression(expression.expression); const signatureDeclaration = signature && signature.getDeclaration(); if (signatureDeclaration && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) @@ -3563,7 +3546,7 @@ export class LuaTransformer { return wrapResult ? this.wrapInTable(callExpression) : callExpression; } - private transformGlobalFunctionCall(node: ts.CallExpression): ExpressionVisitResult { + private transformGlobalFunctionCall(node: ts.CallExpression): tstl.Expression | undefined { const signature = this.checker.getResolvedSignature(node); const parameters = this.transformArguments(node.arguments, signature); @@ -3611,7 +3594,7 @@ export class LuaTransformer { if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) { return tstl.createCallExpression( - this.expectExpression(this.transformStringExpression(node.expression.name)), + this.transformStringExpression(node.expression.name), this.transformArguments(node.arguments, signature), node ); @@ -3667,7 +3650,7 @@ export class LuaTransformer { // Super calls take the format of super.call(self,...) parameters = this.transformArguments(node.arguments, signature, ts.createThis()); return tstl.createCallExpression( - this.expectExpression(this.transformExpression(node.expression)), + this.transformExpression(node.expression), parameters ); } else { @@ -3677,24 +3660,21 @@ export class LuaTransformer { const toStringIdentifier = tstl.createIdentifier("tostring"); return tstl.createCallExpression( toStringIdentifier, - this.filterUndefined([this.transformExpression(node.expression.expression)]), + [this.transformExpression(node.expression.expression)], node ); } else if (name === "hasOwnProperty") { const expr = this.transformExpression(node.expression.expression); parameters = this.transformArguments(node.arguments, signature); const rawGetIdentifier = tstl.createIdentifier("rawget"); - const rawGetCall = tstl.createCallExpression( - rawGetIdentifier, - this.filterUndefined([expr, ...parameters]) - ); + const rawGetCall = tstl.createCallExpression(rawGetIdentifier, [expr, ...parameters]); return tstl.createParenthesizedExpression( tstl.createBinaryExpression( rawGetCall, tstl.createNilLiteral(), tstl.SyntaxKind.InequalityOperator, node) ); } else { const parameters = this.transformArguments(node.arguments, signature); - const table = this.expectExpression(this.transformExpression(node.expression.expression)); + const table = this.transformExpression(node.expression.expression); const signatureDeclaration = signature && signature.getDeclaration(); if (!signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) @@ -3732,7 +3712,7 @@ export class LuaTransformer { || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { // Pass left-side as context - const context = this.expectExpression(this.transformExpression(node.expression.expression)); + const context = this.transformExpression(node.expression.expression); if (tsHelper.isExpressionWithEvaluationEffect(node.expression.expression)) { // Inject context parameter if (node.arguments.length > 0) { @@ -3743,19 +3723,19 @@ export class LuaTransformer { // Cache left-side if it has effects //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() - const argument = this.expectExpression(this.transformExpression(node.expression.argumentExpression)); + const argument = this.transformExpression(node.expression.argumentExpression); const selfIdentifier = tstl.createIdentifier("____TS_self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); const callExpression = tstl.createCallExpression(index, parameters); return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); } else { - const expression = this.expectExpression(this.transformExpression(node.expression)); + const expression = this.transformExpression(node.expression); return tstl.createCallExpression(expression, [context, ...parameters]); } } else { // No context - const expression = this.expectExpression(this.transformExpression(node.expression)); + const expression = this.transformExpression(node.expression); return tstl.createCallExpression(expression, parameters); } } @@ -3770,7 +3750,7 @@ export class LuaTransformer { // Add context as first param if present if (context) { - parameters.push(this.expectExpression(this.transformExpression(context))); + parameters.push(this.transformExpression(context)); } if (sig && sig.parameters.length >= params.length) { @@ -3780,13 +3760,10 @@ export class LuaTransformer { const sigType = this.checker.getTypeAtLocation(sig.parameters[i].valueDeclaration); this.validateFunctionAssignment(param, paramType, sigType, sig.parameters[i].name); - const transformedParam = this.transformExpression(param); - if (transformedParam) { - parameters.push(transformedParam); - } + parameters.push(this.transformExpression(param)); } } else { - parameters.push(...this.filterUndefined(params.map(param => this.transformExpression(param)))); + parameters.push(...params.map(param => this.transformExpression(param))); } return parameters; @@ -3834,7 +3811,7 @@ export class LuaTransformer { } } - const callPath = this.expectExpression(this.transformExpression(expression.expression)); + const callPath = this.transformExpression(expression.expression); return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression); } @@ -3943,7 +3920,7 @@ export class LuaTransformer { private transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": - const expression = this.expectExpression(this.transformExpression(node.expression)); + const expression = this.transformExpression(node.expression); return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: throw TSTLErrors.UnsupportedProperty("string", node.name.escapedText as string, node); @@ -3954,17 +3931,17 @@ export class LuaTransformer { private transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { switch (node.name.escapedText) { case "length": - const expression = this.expectExpression(this.transformExpression(node.expression)); + const expression = this.transformExpression(node.expression); return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: return undefined; } } - private transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { + private transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": - const propertyAccessExpression = this.expectExpression(this.transformExpression(node.expression)); + const propertyAccessExpression = this.transformExpression(node.expression); return tstl.createUnaryExpression(propertyAccessExpression, tstl.SyntaxKind.LengthOperator, node); default: throw TSTLErrors.UnsupportedProperty("LuaTable", node.name.escapedText as string, node); @@ -3972,8 +3949,8 @@ export class LuaTransformer { } public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { - const table = this.expectExpression(this.transformExpression(expression.expression)); - const index = this.expectExpression(this.transformExpression(expression.argumentExpression)); + const table = this.transformExpression(expression.expression); + const index = this.transformExpression(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); @@ -4043,7 +4020,7 @@ export class LuaTransformer { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.expectExpression(this.transformExpression(expression.expression)); + const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText as string; switch (expressionName) { @@ -4077,7 +4054,7 @@ export class LuaTransformer { ); case "substr": if (node.arguments.length === 1) { - const argument = this.expectExpression(this.transformExpression(node.arguments[0])); + const argument = this.transformExpression(node.arguments[0]); const arg1 = this.expressionPlusOne(argument); return this.createStringCall("sub", node, caller, arg1); } else { @@ -4147,7 +4124,7 @@ export class LuaTransformer { case "unpack": case "upper": // Allow lua's string instance methods - let stringVariable = this.expectExpression(this.transformExpression(expression.expression)); + let stringVariable = this.transformExpression(expression.expression); if (ts.isStringLiteral(expression.expression)) { // "foo":method() needs to be ("foo"):method() stringVariable = tstl.createParenthesizedExpression(stringVariable); @@ -4199,9 +4176,7 @@ export class LuaTransformer { // Transpile an Object._ property private transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments); - const caller = this.transformExpression(expression.expression); const methodName = method.name.escapedText; switch (methodName) { @@ -4448,7 +4423,7 @@ export class LuaTransformer { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.expectExpression(this.transformExpression(expression.expression)); + const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText; switch (expressionName) { case "concat": @@ -4514,7 +4489,7 @@ export class LuaTransformer { } const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const caller = this.expectExpression(this.transformExpression(expression.expression)); + const caller = this.transformExpression(expression.expression); const expressionName = expression.name.escapedText; switch (expressionName) { case "apply": @@ -4550,7 +4525,7 @@ export class LuaTransformer { } public transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult { - const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); + const innerExpression = this.transformExpression(expression.expression); const typeFunctionIdentifier = tstl.createIdentifier("type"); const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [innerExpression]); const tableString = tstl.createStringLiteral("table"); @@ -4569,7 +4544,7 @@ export class LuaTransformer { } public transformSpreadElement(expression: ts.SpreadElement): ExpressionVisitResult { - const innerExpression = this.expectExpression(this.transformExpression(expression.expression)); + const innerExpression = this.transformExpression(expression.expression); if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) { return innerExpression; } @@ -4618,13 +4593,11 @@ export class LuaTransformer { expression.templateSpans.forEach(span => { const expression = this.transformExpression(span.expression); - if (expression !== undefined) { - parts.push(this.wrapInToStringForConcat(expression)); + parts.push(this.wrapInToStringForConcat(expression)); - const text = tsHelper.escapeString(span.literal.text); - if (text.length > 0) { - parts.push(tstl.createStringLiteral(text, span.literal)); - } + const text = tsHelper.escapeString(span.literal.text); + if (text.length > 0) { + parts.push(tstl.createStringLiteral(text, span.literal)); } }); @@ -5370,14 +5343,6 @@ export class LuaTransformer { } } - protected expectExpression(visitResult: ExpressionVisitResult): tstl.Expression { - if (visitResult === undefined) { - throw new Error("Expected single visit result expression, but found undefined"); - } else { - return visitResult; - } - } - private createConstructorDecorationStatement( declaration: ts.ClassLikeDeclaration ): tstl.AssignmentStatement | undefined { @@ -5388,15 +5353,13 @@ export class LuaTransformer { const decorators = declaration.decorators; if (!decorators) { return undefined; } - const decoratorExpressions = this.filterUndefined( - decorators.map(decorator => { - const expression = decorator.expression; - const type = this.checker.getTypeAtLocation(expression); - const context = tsHelper.getFunctionContextType(type, this.checker); - if (context === ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } - return this.transformExpression(expression); - }) - ); + const decoratorExpressions = decorators.map(decorator => { + const expression = decorator.expression; + const type = this.checker.getTypeAtLocation(expression); + const context = tsHelper.getFunctionContextType(type, this.checker); + if (context === ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } + return this.transformExpression(expression); + }); const decoratorArguments: tstl.Expression[] = []; From 4c72ad596d4d23507c13b3d312849f639e94ed0e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 5 May 2019 18:16:35 +0200 Subject: [PATCH 079/764] 0.19.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 645c6181a..45c898918 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.18.0", + "version": "0.19.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3a63c6ac1..e3c67ed34 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.18.0", + "version": "0.19.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 988c82ae41eb1ebe509822a6483056a89d951e63 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 5 May 2019 18:31:19 +0200 Subject: [PATCH 080/764] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ba2e0c73..d5ca489c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +- Added a compiler API to programmatically invoke TypeScriptToLua, and to modify or extend the default transpiler. More info on the [Compiler API wiki page](). +- Added support for [class decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators). +- Added support for the [@luaTable directive](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luatable) which will force a class to be transpiled as vanilla lua table. +- Added support for NaN, Infinity and related number functions. +- Added support for string.startsWith, string.endsWith and improved string.replace implementation. +- Added support for Symbol.hasInstance. + +- Hoisting now also considers imports. +- Various improvements to iterators and arrays, they also work with the spread operator now. +- Fixed an issue with parameters that had `false` as default value. + ## 0.18.0 * Added support for setting array length. Doing `array.length = x` will set the length of the array to `x` (or shorter, if the starting array was shorter!). * Added the `.name` property to all transpiled classes, so `class.name` will contain the classname as string. From c78856e286d789ace498ed1f9ad00243e2b5f690 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 5 May 2019 22:47:07 +0200 Subject: [PATCH 081/764] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d5ca489c3..6bb28c173 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ # Changelog +- **BREAKING CHANGE:** All tstl-specific options should now be inside the "tstl" section in tsconfig.json (see README.md). **Root-level options are no longer supported**. - Added a compiler API to programmatically invoke TypeScriptToLua, and to modify or extend the default transpiler. More info on the [Compiler API wiki page](). - Added support for [class decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators). - Added support for the [@luaTable directive](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luatable) which will force a class to be transpiled as vanilla lua table. From e385af04af8ab51a2d3c6b5d3191f4ef328c9e63 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 11 May 2019 07:39:43 -0600 Subject: [PATCH 082/764] Sourcemap fixes (#575) * custom source-map building - replaced toStringWithSourceMap with custom method - support for sourceRoot * ending mappings on newlines and a few concat/create fixes * fixing parent nodes for sourcemapping * original location for ____TS_array and added sourcemap tests * fixed broken tests * fixed issue where sourcemap sources were absolute paths * added tests for sources and sourceRoot --- src/LuaAST.ts | 4 -- src/LuaPrinter.ts | 86 +++++++++++++++++++++++++++----- src/LuaTransformer.ts | 94 +++++++++++++++++++---------------- test/unit/sourcemaps.spec.ts | 95 ++++++++++++++++++++++++++++++++++++ 4 files changed, 221 insertions(+), 58 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 81f3cb7ce..bb400a5aa 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -173,10 +173,6 @@ function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { } export function getOriginalPos(node: Node): TextRange { - while (node.line === undefined && node.parent !== undefined) { - node = node.parent; - } - return { line: node.line, column: node.column }; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e3cb3ff5f..42609ea6c 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,6 +1,6 @@ import * as path from "path"; -import {SourceNode, SourceMapGenerator} from "source-map"; +import { Mapping, SourceNode, SourceMapGenerator } from "source-map"; import * as tstl from "./LuaAST"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -59,14 +59,15 @@ export class LuaPrinter { const rootSourceNode = this.printImplementation(block, luaLibFeatures, sourceFile); - const codeWithSourceMap = rootSourceNode - // TODO is the file: part really required? and should this be handled in the printer? - .toStringWithSourceMap({file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua"}); + const sourceRoot = this.options.sourceRoot + || (this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : "."); - let codeResult = codeWithSourceMap.code; + const sourceMap = this.buildSourceMap(sourceFile, sourceRoot, rootSourceNode); + + let codeResult = rootSourceNode.toString(); if (this.options.inlineSourceMap) { - codeResult += "\n" + this.printInlineSourceMap(codeWithSourceMap.map); + codeResult += "\n" + this.printInlineSourceMap(sourceMap); } if (this.options.sourceMapTraceback) { @@ -74,7 +75,7 @@ export class LuaPrinter { codeResult = codeResult.replace("{#SourceMapTraceback}", stackTraceOverride); } - return [codeResult, codeWithSourceMap.map.toString()]; + return [codeResult, sourceMap.toString()]; } private printInlineSourceMap(sourceMap: SourceMapGenerator): string { @@ -140,7 +141,7 @@ export class LuaPrinter { header += "{#SourceMapTraceback}\n"; } - const fileBlockNode = this.createSourceNode(block, this.printBlock(block)); + const fileBlockNode = this.printBlock(block); return this.concatNodes(header, fileBlockNode); } @@ -172,7 +173,7 @@ export class LuaPrinter { } protected printBlock(block: tstl.Block): SourceNode { - return this.createSourceNode(block, this.printStatementArray(block.statements)); + return this.concatNodes(...this.printStatementArray(block.statements)); } private statementMayRequireSemiColon(statement: tstl.Statement): boolean { @@ -428,7 +429,7 @@ export class LuaPrinter { } public printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { - return this.concatNodes(this.indent(), this.printExpression(statement.expression)); + return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]); } // Expressions @@ -626,7 +627,7 @@ export class LuaPrinter { chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")"); - return this.concatNodes(...chunks); + return this.createSourceNode(expression, chunks); } public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { @@ -638,7 +639,10 @@ export class LuaPrinter { const name = this.printIdentifier(expression.name); - return this.concatNodes(prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"); + return this.createSourceNode( + expression, + [prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"] + ); } public printIdentifier(expression: tstl.Identifier): SourceNode { @@ -689,4 +693,62 @@ export class LuaPrinter { } return result; } + + // The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column + // will not generate 'empty' mappings in the source map that point to nothing in the original TS. + private buildSourceMap(sourceFile: string, sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { + const map = new SourceMapGenerator({ + file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua", + sourceRoot, + }); + + let generatedLine = 1; + let generatedColumn = 0; + let currentMapping: Mapping | undefined; + + const isNewMapping = (sourceNode: SourceNode) => { + if (sourceNode.line === null) { + return false; + } + if (currentMapping === undefined) { + return true; + } + if (currentMapping.generated.line === generatedLine + && currentMapping.generated.column === generatedColumn) + { + return false; + } + return (currentMapping.original.line !== sourceNode.line + || currentMapping.original.column !== sourceNode.column); + }; + + const build = (sourceNode: SourceNode) => { + if (isNewMapping(sourceNode)) { + currentMapping = { + source: sourceNode.source, + original: { line: sourceNode.line, column: sourceNode.column }, + generated: { line: generatedLine, column: generatedColumn }, + }; + map.addMapping(currentMapping); + } + + for (const chunk of sourceNode.children) { + if (typeof chunk === "string") { + const lines = (chunk as string).split("\n"); + if (lines.length > 1) { + generatedLine += lines.length - 1; + generatedColumn = 0; + currentMapping = undefined; // Mappings end at newlines + } + generatedColumn += lines[lines.length - 1].length; + + } else { + build(chunk); + } + } + }; + build(rootSourceNode); + + return map; + } } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index cb9c6cb25..9a03e1382 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -424,7 +424,7 @@ export class LuaTransformer { ? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), ""), moduleSpecifier) : moduleSpecifier.text; const modulePath = tstl.createStringLiteral(modulePathString); - return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath]); + return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); } public transformClassDeclaration( @@ -669,7 +669,7 @@ export class LuaTransformer { const result: tstl.Statement[] = []; // [____exports.]className = {} - const classTable: tstl.Expression = tstl.createTableExpression([], statement); + const classTable: tstl.Expression = tstl.createTableExpression([]); const classVar = this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); result.push(...classVar); @@ -678,7 +678,7 @@ export class LuaTransformer { // local className = ____exports.className result.push( tstl.createVariableDeclarationStatement( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(className, statement), this.addExportToIdentifier(tstl.cloneIdentifier(className)) ) ); @@ -688,7 +688,8 @@ export class LuaTransformer { result.push( tstl.createAssignmentStatement( tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("name")), - tstl.createStringLiteral(className.text) + tstl.createStringLiteral(className.text), + statement ) ); @@ -696,8 +697,7 @@ export class LuaTransformer { if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { const classGetters = tstl.createTableIndexExpression( tstl.cloneIdentifier(className), - tstl.createStringLiteral("____getters"), - statement + tstl.createStringLiteral("____getters") ); const assignClassGetters = tstl.createAssignmentStatement( classGetters, @@ -712,8 +712,7 @@ export class LuaTransformer { // className.__index = className const classIndex = tstl.createTableIndexExpression( tstl.cloneIdentifier(className), - tstl.createStringLiteral("__index"), - statement + tstl.createStringLiteral("__index") ); const assignClassIndex = tstl.createAssignmentStatement(classIndex, tstl.cloneIdentifier(className), statement); result.push(assignClassIndex); @@ -737,19 +736,21 @@ export class LuaTransformer { // className.prototype = {} const createClassPrototype = () => tstl.createTableIndexExpression( tstl.cloneIdentifier(className), - tstl.createStringLiteral("prototype"), - statement + tstl.createStringLiteral("prototype") ); const classPrototypeTable = tstl.createTableExpression(); - const assignClassPrototype = tstl.createAssignmentStatement(createClassPrototype(), classPrototypeTable); + const assignClassPrototype = tstl.createAssignmentStatement( + createClassPrototype(), + classPrototypeTable, + statement + ); result.push(assignClassPrototype); // className.prototype.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStatic(m))) { const classPrototypeGetters = tstl.createTableIndexExpression( createClassPrototype(), - tstl.createStringLiteral("____getters"), - statement + tstl.createStringLiteral("____getters") ); const assignClassPrototypeGetters = tstl.createAssignmentStatement( classPrototypeGetters, @@ -786,8 +787,7 @@ export class LuaTransformer { // className.prototype.____setters = {} const classPrototypeSetters = tstl.createTableIndexExpression( createClassPrototype(), - tstl.createStringLiteral("____setters"), - statement + tstl.createStringLiteral("____setters") ); const assignClassPrototypeSetters = tstl.createAssignmentStatement( classPrototypeSetters, @@ -805,7 +805,8 @@ export class LuaTransformer { ); const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeNewIndex, - this.transformLuaLibFunction(LuaLibFeature.NewIndex, undefined, createClassPrototype()) + this.transformLuaLibFunction(LuaLibFeature.NewIndex, undefined, createClassPrototype()), + statement ); result.push(assignClassPrototypeIndex); } @@ -838,10 +839,13 @@ export class LuaTransformer { // className.____super = baseName const createClassBase = () => tstl.createTableIndexExpression( tstl.cloneIdentifier(className), - tstl.createStringLiteral("____super"), - statement + tstl.createStringLiteral("____super") + ); + const assignClassBase = tstl.createAssignmentStatement( + createClassBase(), + baseName, + extendedTypeNode.expression ); - const assignClassBase = tstl.createAssignmentStatement(createClassBase(), baseName, statement); result.push(assignClassBase); if (hasStaticGetters || hasStaticSetters) { @@ -851,13 +855,18 @@ export class LuaTransformer { metatableFields.push( tstl.createTableFieldExpression( tstl.createIdentifier("__TS__ClassIndex"), - tstl.createStringLiteral("__index") + tstl.createStringLiteral("__index"), + extendedTypeNode.expression ) ); } else { // __index = className.____super metatableFields.push( - tstl.createTableFieldExpression(createClassBase(), tstl.createStringLiteral("__index")) + tstl.createTableFieldExpression( + createClassBase(), + tstl.createStringLiteral("__index"), + extendedTypeNode.expression + ) ); } @@ -866,7 +875,8 @@ export class LuaTransformer { metatableFields.push( tstl.createTableFieldExpression( tstl.createIdentifier("__TS__ClassNewIndex"), - tstl.createStringLiteral("__newindex") + tstl.createStringLiteral("__newindex"), + extendedTypeNode.expression ) ); } @@ -874,7 +884,8 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)] + [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)], + extendedTypeNode.expression ) ); result.push(setClassMetatable); @@ -884,7 +895,8 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(className), createClassBase()] + [tstl.cloneIdentifier(className), createClassBase()], + extendedTypeNode.expression ) ); result.push(setClassMetatable); @@ -893,15 +905,14 @@ export class LuaTransformer { // setmetatable(className.prototype, className.____super.prototype) const basePrototype = tstl.createTableIndexExpression( createClassBase(), - tstl.createStringLiteral("prototype"), - statement + tstl.createStringLiteral("prototype") ); const setClassPrototypeMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), [createClassPrototype(), basePrototype] ), - statement + extendedTypeNode.expression ); result.push(setClassPrototypeMetatable); @@ -912,7 +923,8 @@ export class LuaTransformer { metatableFields.push( tstl.createTableFieldExpression( tstl.createIdentifier("__TS__ClassIndex"), - tstl.createStringLiteral("__index") + tstl.createStringLiteral("__index"), + statement ) ); } @@ -922,7 +934,8 @@ export class LuaTransformer { metatableFields.push( tstl.createTableFieldExpression( tstl.createIdentifier("__TS__ClassNewIndex"), - tstl.createStringLiteral("__newindex") + tstl.createStringLiteral("__newindex"), + statement ) ); } @@ -931,7 +944,8 @@ export class LuaTransformer { tstl.createCallExpression( tstl.createIdentifier("setmetatable"), [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)] - ) + ), + statement ); result.push(setClassMetatable); } @@ -944,8 +958,7 @@ export class LuaTransformer { tstl.createCallExpression( tstl.createIdentifier("setmetatable"), [tstl.createTableExpression(), createClassPrototype()] - ), - statement + ) ); newFuncStatements.push(assignSelf); @@ -955,13 +968,12 @@ export class LuaTransformer { this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [tstl.createDotsLiteral()] - ), - statement + ) ); newFuncStatements.push(callConstructor); // return self - const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()], statement); + const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()]); newFuncStatements.push(returnSelf); // function className.new(construct, ...) ... end @@ -975,10 +987,8 @@ export class LuaTransformer { undefined, tstl.createDotsLiteral(), undefined, - tstl.FunctionExpressionFlags.Declaration, - statement - ), - statement + tstl.FunctionExpressionFlags.Declaration + ) ); result.push(newFunc); @@ -1159,7 +1169,7 @@ export class LuaTransformer { classGetters, tstl.createStringLiteral(name.text) ); - const assignGetter = tstl.createAssignmentStatement(getter, accessorFunction); + const assignGetter = tstl.createAssignmentStatement(getter, accessorFunction, getAccessor); return assignGetter; } @@ -1197,7 +1207,7 @@ export class LuaTransformer { classSetters, tstl.createStringLiteral(name.text) ); - const assignSetter = tstl.createAssignmentStatement(setter, accessorFunction); + const assignSetter = tstl.createAssignmentStatement(setter, accessorFunction, setAccessor); return assignSetter; } @@ -2219,7 +2229,7 @@ export class LuaTransformer { // local ____TS_array = ${iterable}; // for ____TS_index = 1, #____TS_array do // local ${initializer} = ____TS_array[____TS_index] - const arrayVariable = tstl.createIdentifier("____TS_array"); + const arrayVariable = tstl.createIdentifier("____TS_array", statement.expression); const arrayAccess = tstl.createTableIndexExpression(arrayVariable, indexVariable); const initializer = this.transformForOfInitializer(statement.initializer, arrayAccess); block.statements.splice(0, 0, initializer); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index 905e3dc05..f4bda8503 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -45,6 +45,78 @@ test.each([ { luaPattern: "2", typeScriptPattern: "abc.foo" }, ], }, + { + typeScriptSource: ` + import {Foo} from "foo"; + `, + + assertPatterns: [ + { luaPattern: 'require("foo")', typeScriptPattern: '"foo"' }, + { luaPattern: "Foo", typeScriptPattern: "Foo" }, + ], + }, + { + typeScriptSource: ` + import * as Foo from "foo"; + `, + + assertPatterns: [ + { luaPattern: 'require("foo")', typeScriptPattern: '"foo"' }, + { luaPattern: "Foo", typeScriptPattern: "Foo" }, + ], + }, + { + typeScriptSource: ` + class Bar extends Foo {} + `, + + assertPatterns: [ + { luaPattern: "Bar = {}", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.name =", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.__index =", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.prototype =", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.prototype.__index =", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.prototype.constructor =", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar.____super = Foo", typeScriptPattern: "Foo {" }, + { luaPattern: "setmetatable(Bar,", typeScriptPattern: "Foo {" }, + { luaPattern: "setmetatable(Bar.prototype,", typeScriptPattern: "Foo {" }, + ], + }, + { + typeScriptSource: ` + declare const arr: string[]; + for (const element of arr) {} + `, + + assertPatterns: [ + { luaPattern: "arr", typeScriptPattern: "arr)" }, + { luaPattern: "element", typeScriptPattern: "element" }, + ], + }, + { + typeScriptSource: ` + declare function getArr(this: void): string[]; + for (const element of getArr()) {} + `, + + assertPatterns: [ + { luaPattern: "getArr()", typeScriptPattern: "getArr()" }, + { luaPattern: "____TS_array", typeScriptPattern: "getArr()" }, + { luaPattern: "element", typeScriptPattern: "element" }, + ], + }, + { + typeScriptSource: ` + declare const arr: string[] + for (let i = 0; i < arr.length; ++i) {} + `, + + assertPatterns: [ + { luaPattern: "i = 0", typeScriptPattern: "i = 0" }, + { luaPattern: "i < #arr", typeScriptPattern: "i < arr.length" }, + { luaPattern: "i + 1", typeScriptPattern: "++i" }, + ], + }, ])("Source map has correct mapping (%p)", async ({ typeScriptSource, assertPatterns }) => { // Act const { file } = util.transpileStringResult(typeScriptSource); @@ -64,6 +136,29 @@ test.each([ } }); +test("Source map has correct sources", async () => { + const code = `const foo = "foo"`; + + const { file } = util.transpileStringResult(code); + + if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + + const consumer = await new SourceMapConsumer(file.sourceMap); + expect(consumer.sources.length).toBe(1); + expect(consumer.sources[0]).toBe("main.ts"); +}); + +test("Source map has correct source root", async () => { + const code = `const foo = "foo"`; + + const { file } = util.transpileStringResult(code); + + if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + + const sourceMap = JSON.parse(file.sourceMap); + expect(sourceMap.sourceRoot).toBe("."); +}); + test("sourceMapTraceback saves sourcemap in _G", () => { // Arrange const typeScriptSource = ` From 26cf33c1a8e7ee6c97e64c082aa8039f9e280cd2 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 14 May 2019 12:59:04 +0500 Subject: [PATCH 083/764] Add string.{repeat,padStart,padEnd} (#571) * Add string.{repeat,padStart,padEnd} * Add non-integer string.repeat test cases * Fix non-integer length errors in string pad --- src/LuaLib.ts | 2 ++ src/LuaTransformer.ts | 9 ++++++ src/lualib/StringPadEnd.ts | 18 ++++++++++++ src/lualib/StringPadStart.ts | 18 ++++++++++++ test/unit/numbers.spec.ts | 16 ++++------- test/unit/string.spec.ts | 56 ++++++++++++++++++++++++++++++------ test/util.ts | 7 +++++ 7 files changed, 106 insertions(+), 20 deletions(-) create mode 100644 src/lualib/StringPadEnd.ts create mode 100644 src/lualib/StringPadStart.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 6ab22d97c..d339fc945 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -47,6 +47,8 @@ export enum LuaLibFeature { Spread = "Spread", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", + StringPadEnd = "StringPadEnd", + StringPadStart = "StringPadStart", StringReplace = "StringReplace", StringSplit = "StringSplit", StringStartsWith = "StringStartsWith", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9a03e1382..0245dccb7 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4116,6 +4116,15 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.StringStartsWith, node, caller, ...params); case "endsWith": return this.transformLuaLibFunction(LuaLibFeature.StringEndsWith, node, caller, ...params); + case "repeat": + const math = tstl.createIdentifier("math"); + const floor = tstl.createStringLiteral("floor"); + const parameter = tstl.createCallExpression(tstl.createTableIndexExpression(math, floor), [params[0]]); + return this.createStringCall("rep", node, caller, parameter); + case "padStart": + return this.transformLuaLibFunction(LuaLibFeature.StringPadStart, node, caller, ...params); + case "padEnd": + return this.transformLuaLibFunction(LuaLibFeature.StringPadEnd, node, caller, ...params); case "byte": case "char": case "dump": diff --git a/src/lualib/StringPadEnd.ts b/src/lualib/StringPadEnd.ts new file mode 100644 index 000000000..6be8b8853 --- /dev/null +++ b/src/lualib/StringPadEnd.ts @@ -0,0 +1,18 @@ +function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): string { + if (maxLength !== maxLength) maxLength = 0; + if (maxLength === -Infinity || maxLength === Infinity) { + // tslint:disable-next-line: no-string-throw + throw "Invalid string length"; + } + + if (this.length >= maxLength || fillString.length === 0) { + return this; + } + + maxLength = maxLength - this.length; + if (maxLength > fillString.length) { + fillString += fillString.repeat(maxLength / fillString.length); + } + + return this + fillString.slice(0, Math.floor(maxLength)); +} diff --git a/src/lualib/StringPadStart.ts b/src/lualib/StringPadStart.ts new file mode 100644 index 000000000..1fee2e64d --- /dev/null +++ b/src/lualib/StringPadStart.ts @@ -0,0 +1,18 @@ +function __TS__StringPadStart(this: string, maxLength: number, fillString = " "): string { + if (maxLength !== maxLength) maxLength = 0; + if (maxLength === -Infinity || maxLength === Infinity) { + // tslint:disable-next-line: no-string-throw + throw "Invalid string length"; + } + + if (this.length >= maxLength || fillString.length === 0) { + return this; + } + + maxLength = maxLength - this.length; + if (maxLength > fillString.length) { + fillString += fillString.repeat(maxLength / fillString.length); + } + + return fillString.slice(0, Math.floor(maxLength)) + this; +} diff --git a/test/unit/numbers.spec.ts b/test/unit/numbers.spec.ts index 623335683..e3f78ff10 100644 --- a/test/unit/numbers.spec.ts +++ b/test/unit/numbers.spec.ts @@ -39,21 +39,15 @@ const stringCases = ["-1", "0", "1", "1.5", "Infinity", "-Infinity"]; const restCases: any[] = [true, false, "", " ", "\t", "\n", "foo", {}]; const cases: any[] = [...numberCases, ...stringCases, ...restCases]; -// TODO: Add more general utils to serialize values -const valueToString = (value: unknown) => - value === Infinity || value === -Infinity || (typeof value === "number" && Number.isNaN(value)) - ? String(value) - : JSON.stringify(value); - describe("Number", () => { test.each(cases)("constructor(%p)", value => { - const result = util.transpileAndExecute(`return Number(${valueToString(value)})`); + const result = util.transpileAndExecute(`return Number(${util.valueToString(value)})`); expect(result).toBe(Number(value)); }); test.each(cases)("isNaN(%p)", value => { const result = util.transpileAndExecute(` - return Number.isNaN(${valueToString(value)} as any) + return Number.isNaN(${util.valueToString(value)} as any) `); expect(result).toBe(Number.isNaN(value)); @@ -61,7 +55,7 @@ describe("Number", () => { test.each(cases)("isFinite(%p)", value => { const result = util.transpileAndExecute(` - return Number.isFinite(${valueToString(value)} as any) + return Number.isFinite(${util.valueToString(value)} as any) `); expect(result).toBe(Number.isFinite(value)); @@ -69,11 +63,11 @@ describe("Number", () => { }); test.each(cases)("isNaN(%p)", value => { - const result = util.transpileAndExecute(`return isNaN(${valueToString(value)} as any)`); + const result = util.transpileAndExecute(`return isNaN(${util.valueToString(value)} as any)`); expect(result).toBe(isNaN(value)); }); test.each(cases)("isFinite(%p)", value => { - const result = util.transpileAndExecute(`return isFinite(${valueToString(value)} as any)`); + const result = util.transpileAndExecute(`return isFinite(${util.valueToString(value)} as any)`); expect(result).toBe(isFinite(value)); }); diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 6690a4111..9bbf57ef6 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -73,6 +73,17 @@ test.each([ expect(result).toBe(`${a} ${b} test ${c}`); }); +test.each([ + { input: "abcd", index: 3 }, + { input: "abcde", index: 3 }, + { input: "abcde", index: 0 }, + { input: "a", index: 0 }, +])("string index (%p)", ({ input, index }) => { + const result = util.transpileAndExecute(`return "${input}"[${index}];`); + + expect(result).toBe(input[index]); +}); + test.each([ { inp: "hello test", searchValue: "", replaceValue: "" }, { inp: "hello test", searchValue: " ", replaceValue: "" }, @@ -290,7 +301,7 @@ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: ["test"] }, { inp: "hello test", args: ["test", 6] }, ])("string.startsWith (%p)", ({ inp, args }) => { - const argsString = args.map(arg => JSON.stringify(arg)).join(", "); + const argsString = util.valuesToString(args); const result = util.transpileAndExecute(`return "${inp}".startsWith(${argsString})`); expect(result).toBe(inp.startsWith(...args)); @@ -302,19 +313,46 @@ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: ["hello"] }, { inp: "hello test", args: ["hello", 5] }, ])("string.endsWith (%p)", ({ inp, args }) => { - const argsString = args.map(arg => JSON.stringify(arg)).join(", "); + const argsString = util.valuesToString(args); const result = util.transpileAndExecute(`return "${inp}".endsWith(${argsString})`); expect(result).toBe(inp.endsWith(...args)); }); test.each([ - { input: "abcd", index: 3 }, - { input: "abcde", index: 3 }, - { input: "abcde", index: 0 }, - { input: "a", index: 0 }, -])("string index (%p)", ({ input, index }) => { - const result = util.transpileAndExecute(`return "${input}"[${index}];`); + { inp: "hello test", count: 0 }, + { inp: "hello test", count: 1 }, + { inp: "hello test", count: 2 }, + { inp: "hello test", count: 1.1 }, + { inp: "hello test", count: 1.5 }, + { inp: "hello test", count: 1.9 }, +])("string.repeat (%p)", ({ inp, count }) => { + const result = util.transpileAndExecute(`return "${inp}".repeat(${count})`); + + expect(result).toBe(inp.repeat(count)); +}); - expect(result).toBe(input[index]); +const padCases = [ + { inp: "foo", maxLength: 0 }, + { inp: "foo", maxLength: 3 }, + { inp: "foo", maxLength: 5 }, + { inp: "foo", maxLength: 4, fillString: " " }, + { inp: "foo", maxLength: 10, fillString: " " }, + { inp: "foo", maxLength: 5, fillString: "1234" }, + { inp: "foo", maxLength: 5.9, fillString: "1234" }, + { inp: "foo", maxLength: NaN }, +]; + +test.each(padCases)("string.padStart (%p)", ({ inp, maxLength, fillString }) => { + const argsString = util.valuesToString([maxLength, fillString]); + const result = util.transpileAndExecute(`return "${inp}".padStart(${argsString})`); + + expect(result).toBe(inp.padStart(maxLength, fillString)); +}); + +test.each(padCases)("string.padEnd (%p)", ({ inp, maxLength, fillString }) => { + const argsString = util.valuesToString([maxLength, fillString]); + const result = util.transpileAndExecute(`return "${inp}".padEnd(${argsString})`); + + expect(result).toBe(inp.padEnd(maxLength, fillString)); }); diff --git a/test/util.ts b/test/util.ts index 092e6afda..84b77d0e9 100644 --- a/test/util.ts +++ b/test/util.ts @@ -167,3 +167,10 @@ export function expectToBeDefined(subject: T | null | undefined): subject is expect(subject).toBeDefined(); return true; // If this was false the expect would have thrown an error } + +export const valueToString = (value: unknown) => + value === Infinity || value === -Infinity || (typeof value === "number" && Number.isNaN(value)) + ? String(value) + : JSON.stringify(value); + +export const valuesToString = (values: Array) => values.map(valueToString).join(", "); From 9faa80da8445e1368770a3e2291547d3f77739f6 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 18 May 2019 22:59:06 +0500 Subject: [PATCH 084/764] Small improvements (#570) * LuaJIT target in help now is uppercased * Unsupported for target error message now correctly formats `LuaJIT` * Remove some unused helpers * Specify only esnext lib in options It already references all previous ones. * Add lib to tsconfig and remove browser global `name` usage * Enable noUnusedLocals and noUnusedParameters * Fix `Function expression type inference in constructor` test * Move lua types in lualib to declarations directory * Remove unused string.gmatch declaration * Fix expectToBeDefined not checking for null * Improve toHaveDiagnostics message * Declare correct return type for custom jest matchers * Rename IdentifierOrTableIndexExpression to LeftHandSideExpression * Update dependencies * Remove unused rimraf dependency * Run CI on lowest supported node version * Upgrade npm on appveyor * Add tsconfig to lualib * Check diagnostics of lualib * Rename some variables in Map and Set to match decloration files * Use TypeScript 3.4 readonly array literals syntax * Simplify `expression + 1` for numeric literals * Simplify expression - 1 + 1 * Rename LeftHandSideExpression to AssignmentLeftHandSideExpression * Add generic and literal array form tests * Fix lint warning from tslint version upgrade * Change lualib tslint command to use project --- .travis.yml | 3 +- README.md | 4 +- appveyor.yml | 8 +- build_lualib.ts | 24 +- package-lock.json | 4561 +++++++++++++---- package.json | 22 +- src/CommandLineParser.ts | 17 +- src/CompilerOptions.ts | 2 +- src/LuaAST.ts | 6 +- src/LuaTransformer.ts | 73 +- src/TSHelper.ts | 48 +- src/TSTLErrors.ts | 14 +- src/Transpile.ts | 2 +- src/index.ts | 11 +- src/lualib/ArrayConcat.ts | 3 - src/lualib/ArrayFlatMap.ts | 2 +- src/lualib/ArrayShift.ts | 3 - src/lualib/ArraySort.ts | 3 - src/lualib/ArrayUnshift.ts | 3 - src/lualib/ClassIndex.ts | 9 +- src/lualib/ClassNewIndex.ts | 10 +- src/lualib/FunctionApply.ts | 19 +- src/lualib/FunctionBind.ts | 23 +- src/lualib/FunctionCall.ts | 15 +- src/lualib/Index.ts | 14 +- src/lualib/InstanceOf.ts | 8 - src/lualib/Map.ts | 137 +- src/lualib/NewIndex.ts | 15 +- src/lualib/Set.ts | 114 +- src/lualib/SourceMapTraceBack.ts | 10 +- src/lualib/Spread.ts | 6 - src/lualib/Symbol.ts | 6 +- src/lualib/WeakMap.ts | 54 +- src/lualib/WeakSet.ts | 50 +- src/lualib/declarations/debug.d.ts | 5 + src/lualib/declarations/global.d.ts | 14 + src/lualib/declarations/string.d.ts | 5 - src/lualib/declarations/table.d.ts | 8 + src/lualib/declarations/tstl.d.ts | 14 + src/lualib/tsconfig.json | 16 + src/tstl.ts | 19 +- test/setup.ts | 9 +- test/transpile/outFile.spec.ts | 2 +- test/tsconfig.json | 3 + test/unit/array.spec.ts | 20 +- .../functionExpressionTypeInference.spec.ts | 4 +- test/unit/error.spec.ts | 2 +- test/unit/lualib/lualib.spec.ts | 28 +- test/unit/modules.spec.ts | 2 +- test/unit/objectLiteral.spec.ts | 1 - test/unit/string.spec.ts | 11 +- test/unit/tshelper.spec.ts | 30 - test/util.ts | 11 +- tsconfig.json | 3 + 54 files changed, 4081 insertions(+), 1425 deletions(-) create mode 100644 src/lualib/declarations/debug.d.ts create mode 100644 src/lualib/declarations/table.d.ts create mode 100644 src/lualib/declarations/tstl.d.ts create mode 100644 src/lualib/tsconfig.json diff --git a/.travis.yml b/.travis.yml index 209eed141..e75d82b40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js -node_js: - - stable +node_js: "8.5.0" script: - npm run build diff --git a/README.md b/README.md index 6051d5be8..21b013de7 100644 --- a/README.md +++ b/README.md @@ -42,11 +42,11 @@ Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/Type { "compilerOptions": { "target": "esnext", - "lib": ["es2015", "es2016", "es2017", "es2018", "esnext"], + "lib": ["esnext"], "strict": true }, "tstl": { - "luaTarget": "JIT" + "luaTarget": "JIT" } } ``` diff --git a/appveyor.yml b/appveyor.yml index 89c37dbc4..5e5b29138 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ # Test against the latest version of this Node.js version environment: - nodejs_version: "8" + nodejs_version: "8.5.0" # Do not build feature branch with open Pull Requests skip_branch_with_pr: true @@ -13,7 +13,9 @@ cache: install: # Get the latest stable version of Node.js or io.js - ps: Install-Product node $env:nodejs_version - # install modules + # Upgrade npm + - npm install --global npm@6 + # Install modules - npm ci # Post-install test scripts. @@ -21,7 +23,7 @@ test_script: # Output useful info for debugging. - node --version - npm --version - # run tests + # Run tests - npm run build - npm test diff --git a/build_lualib.ts b/build_lualib.ts index 253fa59d5..a620df2ac 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -1,29 +1,17 @@ import * as fs from "fs"; -import * as glob from "glob"; import * as path from "path"; import * as ts from "typescript"; import * as tstl from "./src"; import { LuaLib } from "./src/LuaLib"; -const options: tstl.CompilerOptions = { - skipLibCheck: true, - types: [], - target: ts.ScriptTarget.ESNext, - lib: ["lib.esnext.d.ts"], - - outDir: path.join(__dirname, "./dist/lualib"), - rootDir: path.join(__dirname, "./src/lualib"), - - luaLibImport: tstl.LuaLibImportKind.None, - luaTarget: tstl.LuaTarget.Lua51, - noHeader: true, -}; - -// TODO: Check diagnostics -const { emitResult } = tstl.transpileFiles(glob.sync("./src/lualib/**/*.ts"), options); +const configFileName = path.resolve(__dirname, "src/lualib/tsconfig.json"); +const { emitResult, diagnostics } = tstl.transpileProject(configFileName); emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); -const bundlePath = path.join(__dirname, "./dist/lualib/lualib_bundle.lua"); +const reportDiagnostic = tstl.createDiagnosticReporter(true); +diagnostics.forEach(reportDiagnostic); + +const bundlePath = path.join(__dirname, "dist/lualib/lualib_bundle.lua"); if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } diff --git a/package-lock.json b/package-lock.json index 45c898918..36d02357f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -365,75 +365,43 @@ } }, "@jest/console": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.3.0.tgz", - "integrity": "sha512-NaCty/OOei6rSDcbPdMiCbYCI0KGFGPgGO6B09lwWt5QTxnkuhKYET9El5u5z1GAcSxkQmSMtM63e24YabCWqA==", + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", "dev": true, "requires": { "@jest/source-map": "^24.3.0", - "@types/node": "*", "chalk": "^2.0.1", "slash": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@jest/core": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.5.0.tgz", - "integrity": "sha512-RDZArRzAs51YS7dXG1pbXbWGxK53rvUu8mCDYsgqqqQ6uSOaTjcVyBl2Jce0exT2rSLk38ca7az7t2f3b0/oYQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.8.0.tgz", + "integrity": "sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A==", "dev": true, "requires": { - "@jest/console": "^24.3.0", - "@jest/reporters": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/transform": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/console": "^24.7.1", + "@jest/reporters": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", "exit": "^0.1.2", "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.5.0", - "jest-config": "^24.5.0", - "jest-haste-map": "^24.5.0", - "jest-message-util": "^24.5.0", + "jest-changed-files": "^24.8.0", + "jest-config": "^24.8.0", + "jest-haste-map": "^24.8.0", + "jest-message-util": "^24.8.0", "jest-regex-util": "^24.3.0", - "jest-resolve-dependencies": "^24.5.0", - "jest-runner": "^24.5.0", - "jest-runtime": "^24.5.0", - "jest-snapshot": "^24.5.0", - "jest-util": "^24.5.0", - "jest-validate": "^24.5.0", - "jest-watcher": "^24.5.0", + "jest-resolve-dependencies": "^24.8.0", + "jest-runner": "^24.8.0", + "jest-runtime": "^24.8.0", + "jest-snapshot": "^24.8.0", + "jest-util": "^24.8.0", + "jest-validate": "^24.8.0", + "jest-watcher": "^24.8.0", "micromatch": "^3.1.10", "p-each-series": "^1.0.0", "pirates": "^4.0.1", @@ -442,6 +410,79 @@ "strip-ansi": "^5.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", @@ -468,6 +509,187 @@ "supports-color": "^5.3.0" } }, + "expect": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", + "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-regex-util": "^24.3.0" + } + }, + "jest-diff": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", + "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-matcher-utils": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", + "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.8.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-snapshot": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", + "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "expect": "^24.8.0", + "jest-diff": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.8.0", + "semver": "^5.5.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", @@ -489,58 +711,142 @@ } }, "@jest/environment": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.5.0.tgz", - "integrity": "sha512-tzUHR9SHjMXwM8QmfHb/EJNbF0fjbH4ieefJBvtwO8YErLTrecc1ROj0uo2VnIT6SlpEGZnvdCK6VgKYBo8LsA==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", "dev": true, "requires": { - "@jest/fake-timers": "^24.5.0", - "@jest/transform": "^24.5.0", - "@jest/types": "^24.5.0", - "@types/node": "*", - "jest-mock": "^24.5.0" + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" } }, "@jest/fake-timers": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.5.0.tgz", - "integrity": "sha512-i59KVt3QBz9d+4Qr4QxsKgsIg+NjfuCjSOWj3RQhjF5JNy+eVJDhANQ4WzulzNCHd72srMAykwtRn5NYDGVraw==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", "dev": true, "requires": { - "@jest/types": "^24.5.0", - "@types/node": "*", - "jest-message-util": "^24.5.0", - "jest-mock": "^24.5.0" + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" } }, "@jest/reporters": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.5.0.tgz", - "integrity": "sha512-vfpceiaKtGgnuC3ss5czWOihKOUSyjJA4M4udm6nH8xgqsuQYcyDCi4nMMcBKsHXWgz9/V5G7iisnZGfOh1w6Q==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.8.0.tgz", + "integrity": "sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw==", "dev": true, "requires": { - "@jest/environment": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/transform": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/environment": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", "chalk": "^2.0.1", "exit": "^0.1.2", "glob": "^7.1.2", - "istanbul-api": "^2.1.1", "istanbul-lib-coverage": "^2.0.2", "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", "istanbul-lib-source-maps": "^3.0.1", - "jest-haste-map": "^24.5.0", - "jest-resolve": "^24.5.0", - "jest-runtime": "^24.5.0", - "jest-util": "^24.5.0", - "jest-worker": "^24.4.0", + "istanbul-reports": "^2.1.1", + "jest-haste-map": "^24.8.0", + "jest-resolve": "^24.8.0", + "jest-runtime": "^24.8.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", "node-notifier": "^5.2.1", "slash": "^2.0.0", "source-map": "^0.6.0", "string-length": "^2.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -561,6 +867,105 @@ "supports-color": "^5.3.0" } }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -598,39 +1003,86 @@ } }, "@jest/test-result": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.5.0.tgz", - "integrity": "sha512-u66j2vBfa8Bli1+o3rCaVnVYa9O8CAFZeqiqLVhnarXtreSXG33YQ6vNYBogT7+nYiFNOohTU21BKiHlgmxD5A==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", "dev": true, "requires": { - "@jest/console": "^24.3.0", - "@jest/types": "^24.5.0", - "@types/istanbul-lib-coverage": "^1.1.0" + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + }, + "dependencies": { + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + } } }, - "@jest/transform": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.5.0.tgz", - "integrity": "sha512-XSsDz1gdR/QMmB8UCKlweAReQsZrD/DK7FuDlNo/pE8EcKMrfi2kqLRk8h8Gy/PDzgqJj64jNEzOce9pR8oj1w==", + "@jest/test-sequencer": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz", + "integrity": "sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.5.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.5.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.5.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "@jest/test-result": "^24.8.0", + "jest-haste-map": "^24.8.0", + "jest-runner": "^24.8.0", + "jest-runtime": "^24.8.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -651,6 +1103,92 @@ "supports-color": "^5.3.0" } }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -668,20 +1206,60 @@ } } }, - "@jest/types": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.5.0.tgz", - "integrity": "sha512-kN7RFzNMf2R8UDadPOl6ReyI+MT8xfqRuAnuVL+i4gwjv/zubdDK+EDeLHYwq1j0CSSR2W/MmgaRlMZJzXdmVA==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^1.1.0", - "@types/yargs": "^12.0.9" - } - }, - "@types/babel__core": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.0.tgz", - "integrity": "sha512-wJTeJRt7BToFx3USrCDs2BhEi4ijBInTQjOIukj6a/5tEkwpFMVZ+1ppgmE+Q/FQyc5P/VWUbx7I9NELrKruHA==", + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + }, + "dependencies": { + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + } + } + }, + "@types/babel__core": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.1.tgz", + "integrity": "sha512-+hjBtgcFPYyCTo0A15+nxrCVJL7aC6Acg87TXd5OW3QhHswdrOLoles+ldL2Uk8q++7yIfl4tURtztccdeeyOw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -720,15 +1298,15 @@ } }, "@types/events": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", - "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, "@types/glob": { - "version": "5.0.35", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-5.0.35.tgz", - "integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", "dev": true, "requires": { "@types/events": "*", @@ -742,10 +1320,29 @@ "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==", "dev": true }, + "@types/istanbul-lib-report": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", + "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, "@types/jest": { - "version": "24.0.11", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.11.tgz", - "integrity": "sha512-2kLuPC5FDnWIDvaJBzsGTBQaBbnDweznicvK7UGYzlIJP4RJR2a4A/ByLUXEyEgag6jz8eHdlWExGDtH3EYUXQ==", + "version": "24.0.12", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.12.tgz", + "integrity": "sha512-60sjqMhat7i7XntZckcSGV8iREJyXXI6yFHZkSZvCPUeOnEJ/VP1rU/WpEWQ56mvoh8NhC+sfKAuJRTyGtCOow==", "dev": true, "requires": { "@types/jest-diff": "*" @@ -794,9 +1391,9 @@ "dev": true }, "acorn-globals": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.0.tgz", - "integrity": "sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", + "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", "dev": true, "requires": { "acorn": "^6.0.1", @@ -842,10 +1439,13 @@ "dev": true }, "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } }, "anymatch": { "version": "2.0.0", @@ -857,15 +1457,6 @@ "normalize-path": "^2.1.1" } }, - "append-transform": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", - "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", - "dev": true, - "requires": { - "default-require-extensions": "^2.0.0" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -873,6 +1464,14 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } } }, "arr-diff": { @@ -938,15 +1537,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", - "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", - "dev": true, - "requires": { - "lodash": "^4.17.11" - } - }, "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", @@ -977,32 +1567,94 @@ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, "babel-jest": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.5.0.tgz", - "integrity": "sha512-0fKCXyRwxFTJL0UXDJiT2xYxO9Lu2vBd9n+cC+eDjESzcVG3s2DRGAxbzJX21fceB1WYoBjAh8pQ83dKcl003g==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.8.0.tgz", + "integrity": "sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==", "dev": true, "requires": { - "@jest/transform": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", "@types/babel__core": "^7.1.0", "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.3.0", + "babel-preset-jest": "^24.6.0", "chalk": "^2.4.2", "slash": "^2.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -1023,6 +1675,98 @@ "supports-color": "^5.3.0" } }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -1046,22 +1790,22 @@ } }, "babel-plugin-jest-hoist": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.3.0.tgz", - "integrity": "sha512-nWh4N1mVH55Tzhx2isvUN5ebM5CDUvIpXPZYMRazQughie/EqGnbR+czzoQlhUmJG9pPJmYDRhvocotb2THl1w==", + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz", + "integrity": "sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==", "dev": true, "requires": { "@types/babel__traverse": "^7.0.6" } }, "babel-preset-jest": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.3.0.tgz", - "integrity": "sha512-VGTV2QYBa/Kn3WCOKdfS31j9qomaXSgJqi65B6o05/1GsJyj9LVhSljM9ro4S+IBGj/ENhNBuH9bpqzztKAQSw==", + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz", + "integrity": "sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==", "dev": true, "requires": { "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.3.0" + "babel-plugin-jest-hoist": "^24.6.0" } }, "balanced-match": { @@ -1250,9 +1994,9 @@ "dev": true }, "camelcase": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.2.0.tgz", - "integrity": "sha512-IXFsBS2pC+X0j0N/GE7Dm7j3bsEBp+oTpb7F50dwEVX7rf3IgwO9XatnegTsDtniKCUtEJH4fSU6Asw7uoVLfQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "capture-exit": { @@ -1271,16 +2015,14 @@ "dev": true }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" } }, "ci-info": { @@ -1387,15 +2129,9 @@ } }, "commander": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz", - "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==", - "dev": true - }, - "compare-versions": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.4.0.tgz", - "integrity": "sha512-tK69D7oNXXqUW3ZNo/z7NXTEz22TCF0pTE+YF9cxvaAM9XnkLo1fV621xCLrRR6aevJlKxExkss0vWqUCUpqdg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, "component-emitter": { @@ -1451,9 +2187,9 @@ "dev": true }, "cssstyle": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.1.tgz", - "integrity": "sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", + "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", "dev": true, "requires": { "cssom": "0.3.x" @@ -1519,15 +2255,6 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "default-require-extensions": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", - "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", - "dev": true, - "requires": { - "strip-bom": "^3.0.0" - } - }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1699,9 +2426,9 @@ } }, "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "estraverse": { @@ -1794,28 +2521,17 @@ } }, "expect": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.5.0.tgz", - "integrity": "sha512-p2Gmc0CLxOgkyA93ySWmHFYHUPFIHG6XZ06l7WArWAsrqYVaVEkOU5NtT5i68KUyGKbkQgDCkiT65bWmdoL6Bw==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", + "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "ansi-styles": "^3.2.0", - "jest-get-type": "^24.3.0", - "jest-matcher-utils": "^24.5.0", - "jest-message-util": "^24.5.0", + "jest-get-type": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", "jest-regex-util": "^24.3.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - } } }, "extend": { @@ -1944,32 +2660,14 @@ } }, "fengari": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.2.tgz", - "integrity": "sha512-NleQtQymPtbjBPnGOQiXfZfKpP3R7si+Sbkke631PWNnZt86eZSlymRJ0qv/KUTcz0fSsWO1iltZYz5/JV1uYQ==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", + "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", "dev": true, "requires": { "readline-sync": "^1.4.9", "sprintf-js": "^1.1.1", "tmp": "^0.0.33" - }, - "dependencies": { - "sprintf-js": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz", - "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=", - "dev": true - } - } - }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true, - "requires": { - "glob": "^7.0.3", - "minimatch": "^3.0.3" } }, "fill-range": { @@ -2042,100 +2740,648 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", - "dev": true - }, - "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "handlebars": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.1.tgz", - "integrity": "sha512-3Zhi6C0euYZL5sM0Zcy7lInLXKQ+YLcF/olbN010mzGQ4XVm50JeyBnMqofHh696GrciGruC7kCcApPDJvVgwA==", + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", "dev": true, + "optional": true, "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "handlebars": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", + "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "dev": true, + "requires": { + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", @@ -2155,15 +3401,6 @@ "function-bind": "^1.1.1" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -2495,54 +3732,12 @@ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, - "istanbul-api": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-2.1.1.tgz", - "integrity": "sha512-kVmYrehiwyeBAk/wE71tW6emzLiHGjYIiDrc8sfyty4F8M02/lrgXSm+R1kXysmF20zArvmZXjlE/mg24TVPJw==", - "dev": true, - "requires": { - "async": "^2.6.1", - "compare-versions": "^3.2.1", - "fileset": "^2.0.3", - "istanbul-lib-coverage": "^2.0.3", - "istanbul-lib-hook": "^2.0.3", - "istanbul-lib-instrument": "^3.1.0", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.2", - "istanbul-reports": "^2.1.1", - "js-yaml": "^3.12.0", - "make-dir": "^1.3.0", - "minimatch": "^3.0.4", - "once": "^1.4.0" - }, - "dependencies": { - "js-yaml": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", - "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - } - } - }, "istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", "dev": true }, - "istanbul-lib-hook": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.3.tgz", - "integrity": "sha512-CLmEqwEhuCYtGcpNVJjLV1DQyVnIqavMLFHV/DP+np/g3qvdxu3gsPqYoJMXm15sN84xOlckFB3VNvRbf5yEgA==", - "dev": true, - "requires": { - "append-transform": "^1.0.0" - } - }, "istanbul-lib-instrument": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", @@ -2559,16 +3754,22 @@ } }, "istanbul-lib-report": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.4.tgz", - "integrity": "sha512-sOiLZLAWpA0+3b5w5/dq0cjm2rrNdAfHWaGhmn7XEFW6X++IV9Ohn+pnELAl9K3rfpaeBfbmH9JU5sejacdLeA==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", + "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "supports-color": "^6.0.0" + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "supports-color": "^6.1.0" }, "dependencies": { + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -2581,18 +3782,24 @@ } }, "istanbul-lib-source-maps": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.2.tgz", - "integrity": "sha512-JX4v0CiKTGp9fZPmoxpu9YEkPbEqCqBbO3403VabKjH+NRXo72HafD5UgnjTEqHL2SAjaZK1XDuDOkn6I5QVfQ==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", + "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.3", - "make-dir": "^1.3.0", - "rimraf": "^2.6.2", + "istanbul-lib-coverage": "^2.0.5", + "make-dir": "^2.1.0", + "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { + "istanbul-lib-coverage": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2602,24 +3809,74 @@ } }, "istanbul-reports": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.1.1.tgz", - "integrity": "sha512-FzNahnidyEPBCI0HcufJoSEoKykesRlFcSzQqjH9x0+LC8tnnE/p/90PBLu8iZTxr8yYZNyTtiAujUqyN+CIxw==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.4.tgz", + "integrity": "sha512-QCHGyZEK0bfi9GR215QSm+NJwFKEShbtc7tfbUdLAEzn3kKhLDDZqvljn8rPZM9v8CEOhzL1nlYoO4r1ryl67w==", "dev": true, "requires": { - "handlebars": "^4.1.0" + "handlebars": "^4.1.2" } }, "jest": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.5.0.tgz", - "integrity": "sha512-lxL+Fq5/RH7inxxmfS2aZLCf8MsS+YCUBfeiNO6BWz/MmjhDGaIEA/2bzEf9q4Q0X+mtFHiinHFvQ0u+RvW/qQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz", + "integrity": "sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==", "dev": true, "requires": { "import-local": "^2.0.0", - "jest-cli": "^24.5.0" + "jest-cli": "^24.8.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2641,26 +3898,77 @@ } }, "jest-cli": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.5.0.tgz", - "integrity": "sha512-P+Jp0SLO4KWN0cGlNtC7JV0dW1eSFR7eRpoOucP2UM0sqlzp/bVHeo71Omonvigrj9AvCKy7NtQANtqJ7FXz8g==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.8.0.tgz", + "integrity": "sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA==", "dev": true, "requires": { - "@jest/core": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/core": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "chalk": "^2.0.1", "exit": "^0.1.2", "import-local": "^2.0.0", "is-ci": "^2.0.0", - "jest-config": "^24.5.0", - "jest-util": "^24.5.0", - "jest-validate": "^24.5.0", + "jest-config": "^24.8.0", + "jest-util": "^24.8.0", + "jest-validate": "^24.8.0", "prompts": "^2.0.1", "realpath-native": "^1.1.0", "yargs": "^12.0.2" } }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2673,41 +3981,386 @@ } }, "jest-changed-files": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.5.0.tgz", - "integrity": "sha512-Ikl29dosYnTsH9pYa1Tv9POkILBhN/TLZ37xbzgNsZ1D2+2n+8oEZS2yP1BrHn/T4Rs4Ggwwbp/x8CKOS5YJOg==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.8.0.tgz", + "integrity": "sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "execa": "^1.0.0", "throat": "^4.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + } } }, "jest-circus": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.5.0.tgz", - "integrity": "sha512-meGSoAA5rMv+93Wz8KY3FZcJ7aEbXqrgI2F/emPRCVzGXOvR8oQl8GvYBrIbpJW7G0vwnVSjLQMeTMHs1geu5g==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.8.0.tgz", + "integrity": "sha512-2QASG3QuDdk0SMP2O73D8u3/lc/A/E2G7q23v5WhbUR+hCGzWZXwRMKif18f11dSLfL1wcrMbwE4IorvV0DRVw==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", - "@types/node": "*", + "@jest/environment": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "chalk": "^2.0.1", "co": "^4.6.0", - "expect": "^24.5.0", + "expect": "^24.8.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.5.0", - "jest-matcher-utils": "^24.5.0", - "jest-message-util": "^24.5.0", - "jest-snapshot": "^24.5.0", - "jest-util": "^24.5.0", - "pretty-format": "^24.5.0", + "jest-each": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-snapshot": "^24.8.0", + "jest-util": "^24.8.0", + "pretty-format": "^24.8.0", "stack-utils": "^1.0.1", "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.8.0.tgz", + "integrity": "sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^24.8.0", + "@jest/types": "^24.8.0", + "babel-jest": "^24.8.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^24.8.0", + "jest-environment-node": "^24.8.0", + "jest-get-type": "^24.8.0", + "jest-jasmine2": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.8.0", + "jest-util": "^24.8.0", + "jest-validate": "^24.8.0", + "micromatch": "^3.1.10", + "pretty-format": "^24.8.0", + "realpath-native": "^1.1.0" + }, + "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "jest-diff": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", + "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-docblock": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", + "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-each": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz", + "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.8.0", + "jest-util": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-environment-jsdom": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz", + "integrity": "sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==", + "dev": true, + "requires": { + "@jest/environment": "^24.8.0", + "@jest/fake-timers": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0", + "jest-util": "^24.8.0", + "jsdom": "^11.5.1" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2728,61 +4381,98 @@ "supports-color": "^5.3.0" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" } - } - } - }, - "jest-config": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.5.0.tgz", - "integrity": "sha512-t2UTh0Z2uZhGBNVseF8wA2DS2SuBiLOL6qpLq18+OZGfFUxTM7BzUVKyHFN/vuN+s/aslY1COW95j1Rw81huOQ==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.5.0", - "babel-jest": "^24.5.0", - "chalk": "^2.0.1", - "glob": "^7.1.1", - "jest-environment-jsdom": "^24.5.0", - "jest-environment-node": "^24.5.0", - "jest-get-type": "^24.3.0", - "jest-jasmine2": "^24.5.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.5.0", - "jest-util": "^24.5.0", - "jest-validate": "^24.5.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.5.0", - "realpath-native": "^1.1.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@jest/types": "^24.8.0" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2794,71 +4484,104 @@ } } }, - "jest-diff": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.5.0.tgz", - "integrity": "sha512-mCILZd9r7zqL9Uh6yNoXjwGQx0/J43OD2vvWVKwOEOLZliQOsojXwqboubAQ+Tszrb6DHGmNU7m4whGeB9YOqw==", + "jest-environment-node": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.8.0.tgz", + "integrity": "sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q==", "dev": true, "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.3.0", - "pretty-format": "^24.5.0" + "@jest/environment": "^24.8.0", + "@jest/fake-timers": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0", + "jest-util": "^24.8.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" } - } - } - }, - "jest-docblock": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", - "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", - "dev": true, - "requires": { - "detect-newline": "^2.1.0" - } - }, - "jest-each": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.5.0.tgz", - "integrity": "sha512-6gy3Kh37PwIT5sNvNY2VchtIFOOBh8UCYnBlxXMb5sr5wpJUDPTUATX2Axq1Vfk+HWTMpsYPeVYp4TXx5uqUBw==", - "dev": true, - "requires": { - "@jest/types": "^24.5.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.3.0", - "jest-util": "^24.5.0", - "pretty-format": "^24.5.0" - }, - "dependencies": { + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2879,6 +4602,98 @@ "supports-color": "^5.3.0" } }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2890,100 +4705,361 @@ } } }, - "jest-environment-jsdom": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.5.0.tgz", - "integrity": "sha512-62Ih5HbdAWcsqBx2ktUnor/mABBo1U111AvZWcLKeWN/n/gc5ZvDBKe4Og44fQdHKiXClrNGC6G0mBo6wrPeGQ==", - "dev": true, - "requires": { - "@jest/environment": "^24.5.0", - "@jest/fake-timers": "^24.5.0", - "@jest/types": "^24.5.0", - "jest-mock": "^24.5.0", - "jest-util": "^24.5.0", - "jsdom": "^11.5.1" - } - }, - "jest-environment-node": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.5.0.tgz", - "integrity": "sha512-du6FuyWr/GbKLsmAbzNF9mpr2Iu2zWSaq/BNHzX+vgOcts9f2ayXBweS7RAhr+6bLp6qRpMB6utAMF5Ygktxnw==", - "dev": true, - "requires": { - "@jest/environment": "^24.5.0", - "@jest/fake-timers": "^24.5.0", - "@jest/types": "^24.5.0", - "jest-mock": "^24.5.0", - "jest-util": "^24.5.0" - } - }, "jest-get-type": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.3.0.tgz", - "integrity": "sha512-HYF6pry72YUlVcvUx3sEpMRwXEWGEPlJ0bSPVnB3b3n++j4phUEoSPcS6GC0pPJ9rpyPSe4cb5muFo6D39cXow==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", "dev": true }, "jest-haste-map": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.5.0.tgz", - "integrity": "sha512-mb4Yrcjw9vBgSvobDwH8QUovxApdimGcOkp+V1ucGGw4Uvr3VzZQBJhNm1UY3dXYm4XXyTW2G7IBEZ9pM2ggRQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", "graceful-fs": "^4.1.15", "invariant": "^2.2.4", "jest-serializer": "^24.4.0", - "jest-util": "^24.5.0", - "jest-worker": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", "micromatch": "^3.1.10", - "sane": "^4.0.3" + "sane": "^4.0.3", + "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.5.0.tgz", - "integrity": "sha512-sfVrxVcx1rNUbBeyIyhkqZ4q+seNKyAG6iM0S2TYBdQsXjoFDdqWFfsUxb6uXSsbimbXX/NMkJIwUZ1uT9+/Aw==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz", + "integrity": "sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/environment": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "chalk": "^2.0.1", "co": "^4.6.0", - "expect": "^24.5.0", + "expect": "^24.8.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.5.0", - "jest-matcher-utils": "^24.5.0", - "jest-message-util": "^24.5.0", - "jest-runtime": "^24.5.0", - "jest-snapshot": "^24.5.0", - "jest-util": "^24.5.0", - "pretty-format": "^24.5.0", + "jest-each": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-runtime": "^24.8.0", + "jest-snapshot": "^24.8.0", + "jest-util": "^24.8.0", + "pretty-format": "^24.8.0", "throat": "^4.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "expect": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", + "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-regex-util": "^24.3.0" + } + }, + "jest-diff": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", + "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-each": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz", + "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "jest-get-type": "^24.8.0", + "jest-util": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-matcher-utils": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", + "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.8.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-snapshot": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", + "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "expect": "^24.8.0", + "jest-diff": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.8.0", + "semver": "^5.5.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" } }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -2996,26 +5072,37 @@ } }, "jest-leak-detector": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.5.0.tgz", - "integrity": "sha512-LZKBjGovFRx3cRBkqmIg+BZnxbrLqhQl09IziMk3oeh1OV81Hg30RUIx885mq8qBv1PA0comB9bjKcuyNO1bCQ==", - "dev": true, - "requires": { - "pretty-format": "^24.5.0" - } - }, - "jest-matcher-utils": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.5.0.tgz", - "integrity": "sha512-QM1nmLROjLj8GMGzg5VBra3I9hLpjMPtF1YqzQS3rvWn2ltGZLrGAO1KQ9zUCVi5aCvrkbS5Ndm2evIP9yZg1Q==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz", + "integrity": "sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g==", "dev": true, "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.5.0", - "jest-get-type": "^24.3.0", - "pretty-format": "^24.5.0" + "pretty-format": "^24.8.0" }, "dependencies": { + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3025,82 +5112,55 @@ "color-convert": "^1.9.0" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" } } } }, + "jest-matcher-utils": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", + "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.8.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, "jest-message-util": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.5.0.tgz", - "integrity": "sha512-6ZYgdOojowCGiV0D8WdgctZEAe+EcFU+KrVds+0ZjvpZurUW2/oKJGltJ6FWY2joZwYXN5VL36GPV6pNVRqRnQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "@types/stack-utils": "^1.0.1", "chalk": "^2.0.1", "micromatch": "^3.1.10", "slash": "^2.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-mock": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.5.0.tgz", - "integrity": "sha512-ZnAtkWrKf48eERgAOiUxVoFavVBziO2pAi2MfZ1+bGXVkDfxWLxU0//oJBkgwbsv6OAmuLBz4XFFqvCFMqnGUw==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", "dev": true, "requires": { - "@jest/types": "^24.5.0" + "@jest/types": "^24.8.0" } }, "jest-pnp-resolver": { @@ -3116,18 +5176,74 @@ "dev": true }, "jest-resolve": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.5.0.tgz", - "integrity": "sha512-ZIfGqLX1Rg8xJpQqNjdoO8MuxHV1q/i2OO1hLXjgCWFWs5bsedS8UrOdgjUqqNae6DXA+pCyRmdcB7lQEEbXew==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "browser-resolve": "^1.11.3", "chalk": "^2.0.1", "jest-pnp-resolver": "^1.2.1", "realpath-native": "^1.1.0" + } + }, + "jest-resolve-dependencies": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz", + "integrity": "sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-snapshot": "^24.8.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3148,6 +5264,111 @@ "supports-color": "^5.3.0" } }, + "expect": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", + "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-regex-util": "^24.3.0" + } + }, + "jest-diff": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", + "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "jest-matcher-utils": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", + "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.8.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-snapshot": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", + "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "expect": "^24.8.0", + "jest-diff": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.8.0", + "semver": "^5.5.0" + } + }, + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3159,44 +5380,118 @@ } } }, - "jest-resolve-dependencies": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.5.0.tgz", - "integrity": "sha512-dRVM1D+gWrFfrq2vlL5P9P/i8kB4BOYqYf3S7xczZ+A6PC3SgXYSErX/ScW/469pWMboM1uAhgLF+39nXlirCQ==", - "dev": true, - "requires": { - "@jest/types": "^24.5.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.5.0" - } - }, "jest-runner": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.5.0.tgz", - "integrity": "sha512-oqsiS9TkIZV5dVkD+GmbNfWBRPIvxqmlTQ+AQUJUQ07n+4xTSDc40r+aKBynHw9/tLzafC00DIbJjB2cOZdvMA==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.8.0.tgz", + "integrity": "sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow==", "dev": true, "requires": { - "@jest/console": "^24.3.0", - "@jest/environment": "^24.5.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/console": "^24.7.1", + "@jest/environment": "^24.8.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "chalk": "^2.4.2", "exit": "^0.1.2", "graceful-fs": "^4.1.15", - "jest-config": "^24.5.0", + "jest-config": "^24.8.0", "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.5.0", - "jest-jasmine2": "^24.5.0", - "jest-leak-detector": "^24.5.0", - "jest-message-util": "^24.5.0", - "jest-resolve": "^24.5.0", - "jest-runtime": "^24.5.0", - "jest-util": "^24.5.0", - "jest-worker": "^24.4.0", + "jest-haste-map": "^24.8.0", + "jest-jasmine2": "^24.8.0", + "jest-leak-detector": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "jest-runtime": "^24.8.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3217,6 +5512,111 @@ "supports-color": "^5.3.0" } }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3229,36 +5629,127 @@ } }, "jest-runtime": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.5.0.tgz", - "integrity": "sha512-GTFHzfLdwpaeoDPilNpBrorlPoNZuZrwKKzKJs09vWwHo+9TOsIIuszK8cWOuKC7ss07aN1922Ge8fsGdsqCuw==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz", + "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==", "dev": true, "requires": { - "@jest/console": "^24.3.0", - "@jest/environment": "^24.5.0", + "@jest/console": "^24.7.1", + "@jest/environment": "^24.8.0", "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.5.0", - "@jest/types": "^24.5.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", "@types/yargs": "^12.0.2", "chalk": "^2.0.1", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.1.15", - "jest-config": "^24.5.0", - "jest-haste-map": "^24.5.0", - "jest-message-util": "^24.5.0", - "jest-mock": "^24.5.0", + "jest-config": "^24.8.0", + "jest-haste-map": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0", "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.5.0", - "jest-snapshot": "^24.5.0", - "jest-util": "^24.5.0", - "jest-validate": "^24.5.0", + "jest-resolve": "^24.8.0", + "jest-snapshot": "^24.8.0", + "jest-util": "^24.8.0", + "jest-validate": "^24.8.0", "realpath-native": "^1.1.0", "slash": "^2.0.0", "strip-bom": "^3.0.0", "yargs": "^12.0.2" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/environment": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", + "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^24.8.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/transform": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", + "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^24.8.0", + "babel-plugin-istanbul": "^5.1.0", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.1.15", + "jest-haste-map": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-util": "^24.8.0", + "micromatch": "^3.1.10", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "2.4.1" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3279,6 +5770,20 @@ "supports-color": "^5.3.0" } }, + "expect": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", + "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-styles": "^3.2.0", + "jest-get-type": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-regex-util": "^24.3.0" + } + }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -3293,6 +5798,173 @@ "path-is-absolute": "^1.0.0" } }, + "jest-diff": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", + "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff-sequences": "^24.3.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "jest-haste-map": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", + "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "anymatch": "^2.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.7", + "graceful-fs": "^4.1.15", + "invariant": "^2.2.4", + "jest-serializer": "^24.4.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "micromatch": "^3.1.10", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-matcher-utils": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", + "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^24.8.0", + "jest-get-type": "^24.8.0", + "pretty-format": "^24.8.0" + } + }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-resolve": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", + "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "browser-resolve": "^1.11.3", + "chalk": "^2.0.1", + "jest-pnp-resolver": "^1.2.1", + "realpath-native": "^1.1.0" + } + }, + "jest-snapshot": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", + "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^24.8.0", + "chalk": "^2.0.1", + "expect": "^24.8.0", + "jest-diff": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^24.8.0", + "semver": "^5.5.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "jest-worker": { + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "dev": true, + "requires": { + "merge-stream": "^1.0.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3311,68 +5983,36 @@ "dev": true }, "jest-snapshot": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.5.0.tgz", - "integrity": "sha512-eBEeJb5ROk0NcpodmSKnCVgMOo+Qsu5z9EDl3tGffwPzK1yV37mjGWF2YeIz1NkntgTzP+fUL4s09a0+0dpVWA==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", + "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "chalk": "^2.0.1", - "expect": "^24.5.0", - "jest-diff": "^24.5.0", - "jest-matcher-utils": "^24.5.0", - "jest-message-util": "^24.5.0", - "jest-resolve": "^24.5.0", + "expect": "^24.8.0", + "jest-diff": "^24.8.0", + "jest-matcher-utils": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^24.5.0", + "pretty-format": "^24.8.0", "semver": "^5.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-util": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.5.0.tgz", - "integrity": "sha512-Xy8JsD0jvBz85K7VsTIQDuY44s+hYJyppAhcsHsOsGisVtdhar6fajf2UOf2mEVEgh15ZSdA0zkCuheN8cbr1Q==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", "dev": true, "requires": { - "@jest/console": "^24.3.0", - "@jest/fake-timers": "^24.5.0", + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", - "@types/node": "*", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "callsites": "^3.0.0", "chalk": "^2.0.1", "graceful-fs": "^4.1.15", @@ -3382,57 +6022,51 @@ "source-map": "^0.6.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, "jest-validate": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.5.0.tgz", - "integrity": "sha512-gg0dYszxjgK2o11unSIJhkOFZqNRQbWOAB2/LOUdsd2LfD9oXiMeuee8XsT0iRy5EvSccBgB4h/9HRbIo3MHgQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.8.0.tgz", + "integrity": "sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "camelcase": "^5.0.0", "chalk": "^2.0.1", - "jest-get-type": "^24.3.0", + "jest-get-type": "^24.8.0", "leven": "^2.1.0", - "pretty-format": "^24.5.0" + "pretty-format": "^24.8.0" }, "dependencies": { + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3453,6 +6087,24 @@ "supports-color": "^5.3.0" } }, + "jest-get-type": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", + "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "dev": true + }, + "pretty-format": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + } + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3465,21 +6117,70 @@ } }, "jest-watcher": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.5.0.tgz", - "integrity": "sha512-/hCpgR6bg0nKvD3nv4KasdTxuhwfViVMHUATJlnGCD0r1QrmIssimPbmc5KfAQblAVxkD8xrzuij9vfPUk1/rA==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.8.0.tgz", + "integrity": "sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw==", "dev": true, "requires": { - "@jest/test-result": "^24.5.0", - "@jest/types": "^24.5.0", - "@types/node": "*", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", "@types/yargs": "^12.0.9", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", - "jest-util": "^24.5.0", + "jest-util": "^24.8.0", "string-length": "^2.0.0" }, "dependencies": { + "@jest/console": { + "version": "24.7.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", + "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "dev": true, + "requires": { + "@jest/source-map": "^24.3.0", + "chalk": "^2.0.1", + "slash": "^2.0.0" + } + }, + "@jest/fake-timers": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", + "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0" + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + } + }, + "@jest/types": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", + "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^12.0.9" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -3500,6 +6201,57 @@ "supports-color": "^5.3.0" } }, + "jest-message-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", + "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^2.0.1", + "micromatch": "^3.1.10", + "slash": "^2.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", + "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "dev": true, + "requires": { + "@jest/types": "^24.8.0" + } + }, + "jest-util": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", + "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/fake-timers": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/test-result": "^24.8.0", + "@jest/types": "^24.8.0", + "callsites": "^3.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.15", + "is-ci": "^2.0.0", + "mkdirp": "^0.5.1", + "slash": "^2.0.0", + "source-map": "^0.6.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -3512,12 +6264,11 @@ } }, "jest-worker": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.4.0.tgz", - "integrity": "sha512-BH9X/klG9vxwoO99ZBUbZFfV8qO0XNZ5SIiCyYK2zOuJBl6YJVAeNIQjcoOVNu4HGEHeYEKsUWws8kSlSbZ9YQ==", + "version": "24.6.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", + "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", "dev": true, "requires": { - "@types/node": "*", "merge-stream": "^1.0.1", "supports-color": "^6.1.0" }, @@ -3540,9 +6291,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.0.tgz", - "integrity": "sha512-pZZoSxcCYco+DIKBTimr67J6Hy+EYGZDY/HCWC+iAEA9h1ByhMXAIVUXMcMFpOCxQ/xjXmPI2MkDL5HRm5eFrQ==", + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -3647,9 +6398,9 @@ "dev": true }, "kleur": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.2.tgz", - "integrity": "sha512-3h7B2WRT5LNXOtQiAaWonilegHcPSf9nLVXlSTci8lu1dZUuui61+EsPEZqSVxY7rXYmB2DVKMQILxaO5WL61Q==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, "lcid": { @@ -3727,12 +6478,27 @@ } }, "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { - "pify": "^3.0.0" + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } } }, "make-error": { @@ -3775,9 +6541,9 @@ } }, "mem": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", - "integrity": "sha512-5fJxa68urlY0Ir8ijatKa3eRz5lwXnRCTvo9+TbTGAuTFJOwpGcY0X05moBd0nW45965Njt4CDI2GFQoG8DvqA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", @@ -3816,24 +6582,24 @@ } }, "mime-db": { - "version": "1.38.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", - "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", "dev": true }, "mime-types": { - "version": "2.1.22", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", - "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "dev": true, "requires": { - "mime-db": "~1.38.0" + "mime-db": "1.40.0" } }, "mimic-fn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.0.0.tgz", - "integrity": "sha512-jbex9Yd/3lmICXwYT6gA/j2mNQGU48wCh/VzRd+/Y/PjYQtlg1gLMdZqvu9s/xH7qKvngxRObl56XZR609IMbA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "minimatch": { @@ -3895,6 +6661,13 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "nan": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", + "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "dev": true, + "optional": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -4011,9 +6784,9 @@ "dev": true }, "nwsapi": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.1.tgz", - "integrity": "sha512-T5GaA1J/d34AC8mkrFD2O0DR17kwJ702ZOtJOsS8RpbsQZVOC2/xYFb1i/cw+xdM54JIlMuojjDOYct8GIWtwg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", "dev": true }, "oauth-sign": { @@ -4175,9 +6948,9 @@ "dev": true }, "p-is-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", - "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { @@ -4314,18 +7087,18 @@ "dev": true }, "prettier": { - "version": "1.16.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", - "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", + "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", "dev": true }, "pretty-format": { - "version": "24.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.5.0.tgz", - "integrity": "sha512-/3RuSghukCf8Riu5Ncve0iI+BzVkbRU5EeUoArKARZobREycuH5O4waxvaNIloEXdb0qwgmEAed5vTpX1HNROQ==", + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", + "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", "dev": true, "requires": { - "@jest/types": "^24.5.0", + "@jest/types": "^24.8.0", "ansi-regex": "^4.0.0", "ansi-styles": "^3.2.0", "react-is": "^16.8.4" @@ -4336,15 +7109,6 @@ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } } } }, @@ -4958,9 +7722,9 @@ } }, "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", "dev": true }, "sshpk": { @@ -5098,10 +7862,13 @@ "dev": true }, "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } }, "symbol-tree": { "version": "3.2.2", @@ -5216,9 +7983,9 @@ "dev": true }, "ts-jest": { - "version": "24.0.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.0.0.tgz", - "integrity": "sha512-o8BO3TkMREpAATaFTrXkovMsCpBl2z4NDBoLJuWZcJJj1ijI49UnvDMfVpj+iogn/Jl8Pbhuei5nc/Ti+frEHw==", + "version": "24.0.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.0.2.tgz", + "integrity": "sha512-h6ZCZiA1EQgjczxq+uGLXQlNgeg02WWJBbeT8j6nyIBRQdglqbvzDoHahTEIiS6Eor6x8mK6PfZ7brQ9Q6tzHw==", "dev": true, "requires": { "bs-logger": "0.x", @@ -5272,60 +8039,30 @@ "dev": true }, "tslint": { - "version": "5.11.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.11.0.tgz", - "integrity": "sha1-mPMMAurjzecAYgHkwzywi0hYHu0=", + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", + "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", "dev": true, "requires": { - "babel-code-frame": "^6.22.0", + "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.7.0", + "js-yaml": "^3.13.0", "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", "resolve": "^1.3.2", "semver": "^5.3.0", "tslib": "^1.8.0", - "tsutils": "^2.27.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "tsutils": "^2.29.0" } }, "tsutils": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.28.0.tgz", - "integrity": "sha512-bh5nAtW0tuhvOJnx1GLRn5ScraRLICGyJV5wJhtRWOLsxW70Kk5tZtpK3O/hW6LDnqKS9mlUMPZj9fEMJ0gxqA==", + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -5356,25 +8093,25 @@ } }, "typescript": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", - "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==" + "version": "3.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", + "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==" }, "uglify-js": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.1.tgz", - "integrity": "sha512-kI+3c+KphOAKIikQsZoT2oDsVYH5qvhpTtFObfMCdhPAYnjSvmW4oTWMhvDD4jtAGHJwztlBXQgozGcq3Xw9oQ==", + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.10.tgz", + "integrity": "sha512-/GTF0nosyPLbdJBd+AwYiZ+Hu5z8KXWnO0WCGt1BQ/u9Iamhejykqmz5o1OHJ53+VAk6xVxychonnApDjuqGsw==", "dev": true, "optional": true, "requires": { - "commander": "~2.19.0", + "commander": "~2.20.0", "source-map": "~0.6.1" }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true, "optional": true }, diff --git a/package.json b/package.json index e3c67ed34..aabe0e00d 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", - "lint:tslint": "tslint -p . && tslint -p test && tslint src/lualib/*.ts", + "lint:tslint": "tslint -p . && tslint -p test && tslint -p src/lualib", "fix:prettier": "prettier --check --write **/*.{js,ts,yml,json}", "release-major": "npm version major", "release-minor": "npm version minor", @@ -40,20 +40,18 @@ }, "dependencies": { "source-map": "^0.7.3", - "typescript": "^3.3.1" + "typescript": "^3.4.5" }, "devDependencies": { - "@types/glob": "^5.0.35", - "@types/jest": "^24.0.11", + "@types/glob": "^7.1.1", + "@types/jest": "^24.0.12", "@types/node": "^11.13.0", - "fengari": "^0.1.2", - "glob": "^7.1.2", - "jest": "^24.5.0", - "jest-circus": "^24.5.0", - "prettier": "^1.16.4", - "rimraf": "^2.6.3", - "ts-jest": "^24.0.0", + "fengari": "^0.1.4", + "jest": "^24.8.0", + "jest-circus": "^24.8.0", + "prettier": "^1.17.0", + "ts-jest": "^24.0.2", "ts-node": "^7.0.0", - "tslint": "^5.10.0" + "tslint": "^5.16.0" } } diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index 76d5c12ee..a63f936d3 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -211,8 +211,8 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { }; } - const normalizedValue = value.toLowerCase(); - if (option.choices && !option.choices.includes(normalizedValue)) { + const enumValue = option.choices.find(c => c.toLowerCase() === value.toLowerCase()); + if (enumValue === undefined) { const optionChoices = option.choices.join(", "); return { value: undefined, @@ -220,7 +220,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { }; } - return { value: normalizedValue }; + return { value: enumValue }; } } } @@ -240,3 +240,14 @@ export function parseConfigFileWithSystem( return updateParsedConfigFile(parsedConfigFile); } + +export function createDiagnosticReporter(pretty: boolean, system = ts.sys): ts.DiagnosticReporter { + const reporter: ts.DiagnosticReporter = (ts as any).createDiagnosticReporter(system, pretty); + return diagnostic => { + if (diagnostic.source === "typescript-to-lua") { + diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; + } + + reporter(diagnostic); + }; +} diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 49ad4eabf..01d0211c3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -19,5 +19,5 @@ export enum LuaTarget { Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", - LuaJIT = "jit", + LuaJIT = "JIT", } diff --git a/src/LuaAST.ts b/src/LuaAST.ts index bb400a5aa..edce002e1 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -253,7 +253,7 @@ export function createVariableDeclarationStatement( // `test1, test2 = 12, 42` export interface AssignmentStatement extends Statement { kind: SyntaxKind.AssignmentStatement; - left: IdentifierOrTableIndexExpression[]; + left: AssignmentLeftHandSideExpression[]; right: Expression[]; } @@ -262,7 +262,7 @@ export function isAssignmentStatement(node: Node): node is AssignmentStatement { } export function createAssignmentStatement( - left: IdentifierOrTableIndexExpression | IdentifierOrTableIndexExpression[], + left: AssignmentLeftHandSideExpression | AssignmentLeftHandSideExpression[], right?: Expression | Expression[], tsOriginal?: ts.Node, parent?: Node @@ -874,7 +874,7 @@ export function createTableIndexExpression( return expression; } -export type IdentifierOrTableIndexExpression = Identifier | TableIndexExpression; +export type AssignmentLeftHandSideExpression = Identifier | TableIndexExpression; export type FunctionDefinition = (VariableDeclarationStatement | AssignmentStatement) & { right: [FunctionExpression]; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 0245dccb7..f2f2cdc6e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -114,7 +114,7 @@ export class LuaTransformer { tstl.createReturnStatement([this.transformExpression(statement.expression)]) ); } else { - this.pushScope(ScopeType.File, node); + this.pushScope(ScopeType.File); this.isModule = tsHelper.isFileModule(node); statements = this.performHoisting(this.transformStatements(node.statements)); @@ -208,7 +208,7 @@ export class LuaTransformer { } /** Converts an array of ts.Statements into an array of tstl.Statements */ - private transformStatements(statements: ts.Statement[] | ReadonlyArray): tstl.Statement[] { + private transformStatements(statements: readonly ts.Statement[]): tstl.Statement[] { const tstlStatements: tstl.Statement[] = []; (statements as ts.Statement[]).forEach(statement => { tstlStatements.push(...this.statementVisitResultToArray(this.transformStatement(statement))); @@ -217,14 +217,14 @@ export class LuaTransformer { } public transformBlock(block: ts.Block): tstl.Block { - this.pushScope(ScopeType.Block, block); + this.pushScope(ScopeType.Block); const statements = this.performHoisting(this.transformStatements(block.statements)); this.popScope(); return tstl.createBlock(statements, block); } public transformBlockAsDoStatement(block: ts.Block): StatementVisitResult { - this.pushScope(ScopeType.Block, block); + this.pushScope(ScopeType.Block); const statements = this.performHoisting(this.transformStatements(block.statements)); this.popScope(); return tstl.createDoStatement(statements, block); @@ -1299,7 +1299,7 @@ export class LuaTransformer { spreadIdentifier?: tstl.Identifier ): [tstl.Statement[], Scope] { - this.pushScope(ScopeType.Function, body); + this.pushScope(ScopeType.Function); const headerStatements = []; @@ -1507,7 +1507,7 @@ export class LuaTransformer { // Transform moduleblock to block and visit it if (tsHelper.moduleHasEmittedBody(statement)) { - this.pushScope(ScopeType.Block, statement); + this.pushScope(ScopeType.Block); let statements = ts.isModuleBlock(statement.body) ? this.transformStatements(statement.body.statements) : this.transformModuleDeclaration(statement.body); @@ -1815,11 +1815,11 @@ export class LuaTransformer { return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); } - public transformTypeAliasDeclaration(statement: ts.TypeAliasDeclaration): StatementVisitResult { + public transformTypeAliasDeclaration(_statement: ts.TypeAliasDeclaration): StatementVisitResult { return undefined; } - public transformInterfaceDeclaration(statement: ts.InterfaceDeclaration): StatementVisitResult { + public transformInterfaceDeclaration(_statement: ts.InterfaceDeclaration): StatementVisitResult { return undefined; } @@ -2005,7 +2005,7 @@ export class LuaTransformer { else if (ts.isDeleteExpression(expression)) { return tstl.createAssignmentStatement( - this.transformExpression(expression.expression) as tstl.IdentifierOrTableIndexExpression, + this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression, tstl.createNilLiteral(), expression ); @@ -2087,7 +2087,7 @@ export class LuaTransformer { } public transformIfStatement(statement: ts.IfStatement): StatementVisitResult { - this.pushScope(ScopeType.Conditional, statement.thenStatement); + this.pushScope(ScopeType.Conditional); const condition = this.transformExpression(statement.expression); const statements = this.performHoisting(this.transformBlockOrStatement(statement.thenStatement)); this.popScope(); @@ -2097,7 +2097,7 @@ export class LuaTransformer { const elseStatement = this.transformIfStatement(statement.elseStatement) as tstl.IfStatement; return tstl.createIfStatement(condition, ifBlock, elseStatement); } else { - this.pushScope(ScopeType.Conditional, statement.elseStatement); + this.pushScope(ScopeType.Conditional); const elseStatements = this.performHoisting(this.transformBlockOrStatement(statement.elseStatement)); this.popScope(); const elseBlock = tstl.createBlock(elseStatements); @@ -2181,13 +2181,13 @@ export class LuaTransformer { } else { // Assignment to existing variable - let variables: tstl.IdentifierOrTableIndexExpression | tstl.IdentifierOrTableIndexExpression[]; + let variables: tstl.AssignmentLeftHandSideExpression | tstl.AssignmentLeftHandSideExpression[]; if (ts.isArrayLiteralExpression(initializer)) { expression = this.createUnpackCall(expression, initializer); variables = initializer.elements - .map(e => this.transformExpression(e)) as tstl.IdentifierOrTableIndexExpression[]; + .map(e => this.transformExpression(e)) as tstl.AssignmentLeftHandSideExpression[]; } else { - variables = this.transformExpression(initializer) as tstl.IdentifierOrTableIndexExpression; + variables = this.transformExpression(initializer) as tstl.AssignmentLeftHandSideExpression; } return tstl.createAssignmentStatement(variables, expression); } @@ -2197,7 +2197,7 @@ export class LuaTransformer { loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement ): tstl.Statement[] { - this.pushScope(ScopeType.Loop, loop.statement); + this.pushScope(ScopeType.Loop); const body = this.performHoisting(this.transformBlockOrStatement(loop.statement)); const scope = this.popScope(); const scopeId = scope.id; @@ -2292,7 +2292,7 @@ export class LuaTransformer { .map((_, i) => tstl.createIdentifier(`____TS_value${i}`)); const assign = tstl.createAssignmentStatement( statement.initializer.elements.map(e => - this.transformExpression(e) as tstl.IdentifierOrTableIndexExpression + this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression ), tmps ); @@ -2411,7 +2411,7 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedForTarget("Switch statements", this.luaTarget, statement); } - this.pushScope(ScopeType.Switch, statement); + this.pushScope(ScopeType.Switch); // Give the switch a unique name to prevent nested switches from acting up. const scope = this.peekScope(); @@ -2552,7 +2552,7 @@ export class LuaTransformer { ); } - public transformEmptyStatement(statement: ts.EmptyStatement): StatementVisitResult { + public transformEmptyStatement(_statement: ts.EmptyStatement): StatementVisitResult { return undefined; } @@ -2738,7 +2738,7 @@ export class LuaTransformer { private transformAssignment(lhs: ts.Expression, right?: tstl.Expression): tstl.Statement { return tstl.createAssignmentStatement( - this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression, + this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression, right, lhs.parent ); @@ -2782,7 +2782,7 @@ export class LuaTransformer { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } return tstl.createAssignmentStatement( - left as tstl.IdentifierOrTableIndexExpression[], + left as tstl.AssignmentLeftHandSideExpression[], right, expression ); @@ -2829,7 +2829,7 @@ export class LuaTransformer { const tmps = left.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); const statements: tstl.Statement[] = [ tstl.createVariableDeclarationStatement(tmps, right), - tstl.createAssignmentStatement(left as tstl.IdentifierOrTableIndexExpression[], tmps), + tstl.createAssignmentStatement(left as tstl.AssignmentLeftHandSideExpression[], tmps), ]; return this.createImmediatelyInvokedFunctionExpression( statements, @@ -2891,7 +2891,7 @@ export class LuaTransformer { isPostfix: boolean ): tstl.CallExpression { - const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; + const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; let right = this.transformExpression(rhs); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( @@ -3062,7 +3062,7 @@ export class LuaTransformer { replacementOperator: ts.BinaryOperator ): tstl.Statement { - const left = this.transformExpression(lhs) as tstl.IdentifierOrTableIndexExpression; + const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; const right = this.transformExpression(rhs); const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( @@ -3344,7 +3344,7 @@ export class LuaTransformer { } public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { - const lhs = this.transformExpression(expression.expression) as tstl.IdentifierOrTableIndexExpression; + const lhs = this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression; const assignment = tstl.createAssignmentStatement( lhs, tstl.createNilLiteral(), @@ -3475,7 +3475,7 @@ export class LuaTransformer { } const extendsExpression = typeNode.expression; - let baseClassName: tstl.IdentifierOrTableIndexExpression; + let baseClassName: tstl.AssignmentLeftHandSideExpression; if (ts.isIdentifier(extendsExpression)) { // Use "baseClassName" if base is a simple identifier baseClassName = this.transformIdentifier(extendsExpression); @@ -3922,7 +3922,7 @@ export class LuaTransformer { } default: - throw TSTLErrors.UnsupportedProperty("math", name, expression); + throw TSTLErrors.UnsupportedProperty("math", expressionName, expression); } } @@ -4729,7 +4729,7 @@ export class LuaTransformer { return false; } - protected addExportToIdentifier(identifier: tstl.Identifier): tstl.IdentifierOrTableIndexExpression { + protected addExportToIdentifier(identifier: tstl.Identifier): tstl.AssignmentLeftHandSideExpression { if (this.isIdentifierExported(identifier)) { return this.createExportedIdentifier(identifier); } @@ -5105,10 +5105,25 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); } - protected expressionPlusOne(expression: tstl.Expression): tstl.BinaryExpression { + protected expressionPlusOne(expression: tstl.Expression): tstl.Expression { + if (tstl.isNumericLiteral(expression)) { + const newNode = tstl.cloneNode(expression); + newNode.value += 1; + return newNode; + } + if (tstl.isBinaryExpression(expression)) { + if ( + expression.operator === tstl.SyntaxKind.SubtractionOperator && + tstl.isNumericLiteral(expression.right) && + expression.right.value === 1 + ) { + return expression.left; + } + expression = tstl.createParenthesizedExpression(expression); } + return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } @@ -5154,7 +5169,7 @@ export class LuaTransformer { return this.scopeStack[this.scopeStack.length - 1]; } - protected pushScope(scopeType: ScopeType, node: ts.Node): void { + protected pushScope(scopeType: ScopeType): void { this.scopeStack.push({ type: scopeType, id: this.genVarCounter, diff --git a/src/TSHelper.ts b/src/TSHelper.ts index ebf86b61b..6b4d76615 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -29,32 +29,7 @@ const defaultArrayCallMethodNames = new Set([ "flatMap", ]); -const defaultArrayPropertyNames = new Set([ - "length", -]); - export class TSHelper { - // Reverse lookup of enum key by value - public static enumName(needle: T, haystack: any): string { - for (const name in haystack) { - if (haystack[name] === needle) { - return name; - } - } - return "unknown"; - } - - // Breaks down a mask into all flag names. - public static enumNames(mask: number, haystack: any): string[] { - const result = []; - for (const name in haystack) { - if ((mask & haystack[name]) !== 0 && mask >= haystack[name]) { - result.push(name); - } - } - return result; - } - public static getExtendedTypeNode(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.ExpressionWithTypeArguments | undefined { if (node && node.heritageClauses) { @@ -353,21 +328,6 @@ export class TSHelper { return [false, undefined]; } - public static isExpressionStatement(node: ts.Expression): boolean { - return node.parent === undefined || ts.isExpressionStatement(node.parent) || ts.isForStatement(node.parent); - } - - public static isInGlobalScope(node: ts.Node): boolean { - let parent = node.parent; - while (parent !== undefined) { - if (ts.isBlock(parent)) { - return false; - } - parent = parent.parent; - } - return true; - } - // Returns true for expressions that may have effects when evaluated public static isExpressionWithEvaluationEffect(node: ts.Expression): boolean { return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); @@ -510,7 +470,7 @@ export class TSHelper { return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); } - public static getAllCallSignatures(type: ts.Type): ReadonlyArray { + public static getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { if (type.isUnion()) { return type.types.map(t => TSHelper.getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); } @@ -518,7 +478,7 @@ export class TSHelper { } public static getSignatureDeclarations( - signatures: ReadonlyArray, + signatures: readonly ts.Signature[], checker: ts.TypeChecker ): ts.SignatureDeclaration[] { @@ -644,10 +604,6 @@ export class TSHelper { signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker))); } - public static isDefaultArrayPropertyName(methodName: string): boolean { - return defaultArrayPropertyNames.has(methodName); - } - public static escapeString(text: string): string { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String const escapeSequences: Array<[RegExp, string]> = [ diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 050b77d6f..bc700088f 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -1,6 +1,9 @@ import * as ts from "typescript"; import { TranspileError } from "./TranspileError"; -import { TSHelper as tsHelper } from "./TSHelper"; +import { LuaTarget } from "./CompilerOptions"; + +const getLuaTargetName = (version: LuaTarget) => + version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`; export class TSTLErrors { public static CouldNotCast = (castName: string) => @@ -112,16 +115,13 @@ export class TSTLErrors { new TranspileError(`Unsupported import type.`, node); public static UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => - { - const kindName = tsHelper.enumName(kind, ts.SyntaxKind); - return new TranspileError(`Unsupported ${description} kind: ${kindName}`, node); - }; + new TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node); public static UnsupportedProperty = (parentName: string, property: string, node: ts.Node) => new TranspileError(`Unsupported property on ${parentName}: ${property}`, node); - public static UnsupportedForTarget = (functionality: string, version: string, node: ts.Node) => - new TranspileError(`${functionality} is/are not supported for target Lua ${version}.`, node); + public static UnsupportedForTarget = (functionality: string, version: LuaTarget, node: ts.Node) => + new TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node); public static UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) => new TranspileError("Functions with undefined bodies are not supported.", node); diff --git a/src/Transpile.ts b/src/Transpile.ts index db1460cd5..a8df4c38e 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -7,7 +7,7 @@ import { LuaTransformer } from "./LuaTransformer"; import { TranspileError } from "./TranspileError"; function getCustomTransformers( - program: ts.Program, + _program: ts.Program, customTransformers: ts.CustomTransformers, onSourceFile: (sourceFile: ts.SourceFile) => void ): ts.CustomTransformers { diff --git a/src/index.ts b/src/index.ts index 80d2064ab..76cacd36a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,7 +6,12 @@ import { CompilerOptions } from "./CompilerOptions"; import { emitTranspiledFiles, OutputFile } from "./Emit"; import { transpile, TranspiledFile, TranspileResult } from "./Transpile"; -export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./CommandLineParser"; +export { + parseCommandLine, + ParsedCommandLine, + updateParsedConfigFile, + createDiagnosticReporter, +} from "./CommandLineParser"; export * from "./CompilerOptions"; export * from "./Emit"; export * from "./LuaAST"; @@ -38,10 +43,10 @@ export function transpileFiles( } export function transpileProject( - fileName: string, + configFileName: string, optionsToExtend?: CompilerOptions ): TranspileFilesResult { - const parseResult = parseConfigFileWithSystem(fileName, optionsToExtend); + const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend); if (parseResult.errors.length > 0) { return { diagnostics: parseResult.errors, emitResult: [] }; } diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index 5eaf56cb7..ee34e427b 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -1,6 +1,3 @@ -declare function pcall(this: void, func: () => any): any; -declare function type(this: void, val: any): string; - function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { const out: any[] = []; for (const val of arr1) { diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 9c73db579..7bd7a8a22 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -1,7 +1,7 @@ function __TS__ArrayFlatMap( this: void, array: T[], - callback: (value: T, index: number, array: T[]) => U | ReadonlyArray + callback: (value: T, index: number, array: T[]) => U | readonly U[] ): U[] { let result: U[] = []; for (let i = 0; i < array.length; i++) { diff --git a/src/lualib/ArrayShift.ts b/src/lualib/ArrayShift.ts index 475886eb2..e39d9616b 100644 --- a/src/lualib/ArrayShift.ts +++ b/src/lualib/ArrayShift.ts @@ -1,6 +1,3 @@ -declare namespace table { - function remove(this: void, arr: T[], idx: number): T; -} function __TS__ArrayShift(this: void, arr: T[]): T { return table.remove(arr, 1); } diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts index 49fc196b0..1855c3bb5 100644 --- a/src/lualib/ArraySort.ts +++ b/src/lualib/ArraySort.ts @@ -1,6 +1,3 @@ -declare namespace table { - function sort(this: void, arr: T[], compareFn?: (this: void, a: T, b: T) => boolean): void; -} function __TS__ArraySort(this: void, arr: T[], compareFn?: (a: T, b: T) => number): T[] { if (compareFn !== undefined) { table.sort(arr, (a, b) => compareFn(a, b) < 0); diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts index 1239033ea..f12d6e913 100644 --- a/src/lualib/ArrayUnshift.ts +++ b/src/lualib/ArrayUnshift.ts @@ -1,6 +1,3 @@ -declare namespace table { - function insert(this: void, arr: T[], idx: number, val: T): void; -} function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { for (let i = items.length - 1; i >= 0; --i) { table.insert(arr, 1, items[i]); diff --git a/src/lualib/ClassIndex.ts b/src/lualib/ClassIndex.ts index a231205bb..0f753e3bb 100644 --- a/src/lualib/ClassIndex.ts +++ b/src/lualib/ClassIndex.ts @@ -1,11 +1,4 @@ -interface LuaClass { - ____super?: LuaClass; - ____getters?: { [key: string]: (this: void, self: LuaClass) => any }; -} - -declare function rawget(this: void, obj: T, key: K): T[K]; - -function __TS__ClassIndex(this: void, classTable: LuaClass, key: keyof LuaClass): any { +function __TS__ClassIndex(this: void, classTable: LuaClass, key: any): any { while (true) { const getters = rawget(classTable, "____getters"); if (getters) { diff --git a/src/lualib/ClassNewIndex.ts b/src/lualib/ClassNewIndex.ts index 68b5db7f7..6447f9b8f 100644 --- a/src/lualib/ClassNewIndex.ts +++ b/src/lualib/ClassNewIndex.ts @@ -1,12 +1,4 @@ -interface LuaClass { - ____super?: LuaClass; - ____setters?: { [key: string]: (this: void, self: LuaClass, val: any) => void }; -} - -declare function rawget(this: void, obj: T, key: K): T[K]; -declare function rawset(this: void, obj: T, key: K, val: T[K]): void; - -function __TS__ClassNewIndex(this: void, classTable: LuaClass, key: keyof LuaClass, val: any): void { +function __TS__ClassNewIndex(this: void, classTable: LuaClass, key: any, val: any): void { let tbl = classTable; do { const setters = rawget(tbl, "____setters"); diff --git a/src/lualib/FunctionApply.ts b/src/lualib/FunctionApply.ts index 80e7b69b6..896e75978 100644 --- a/src/lualib/FunctionApply.ts +++ b/src/lualib/FunctionApply.ts @@ -1,14 +1,11 @@ -declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; - -declare namespace table { - export function unpack(this: void, list: T[], i?: number, j?: number): T[]; -} - -type ApplyFn = (this: void, ...argArray: any[]) => any; - -function __TS__FunctionApply(this: void, fn: ApplyFn, thisArg: any, argsArray?: any[]): any { - if (argsArray) { - return fn(thisArg, (unpack || table.unpack)(argsArray)); +function __TS__FunctionApply( + this: void, + fn: (this: void, ...args: any[]) => any, + thisArg: any, + args?: any[] +): any { + if (args) { + return fn(thisArg, (unpack || table.unpack)(args)); } else { return fn(thisArg); } diff --git a/src/lualib/FunctionBind.ts b/src/lualib/FunctionBind.ts index 09e663c91..671570ab9 100644 --- a/src/lualib/FunctionBind.ts +++ b/src/lualib/FunctionBind.ts @@ -1,18 +1,13 @@ -declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; - -declare namespace table { - export function insert(this: void, t: T[], pos: number, value: T): void; - - export function unpack(this: void, list: T[], i?: number, j?: number): T[]; -} - -type BindFn = (this: void, ...argArray: any[]) => any; - -function __TS__FunctionBind(this: void, fn: BindFn, thisArg: any, ...boundArgs: any[]): (...args: any[]) => any { - return (...argArray: any[]) => { +function __TS__FunctionBind( + this: void, + fn: (this: void, ...argArray: any[]) => any, + thisArg: any, + ...boundArgs: any[] +): (...args: any[]) => any { + return (...args: any[]) => { for (let i = 0; i < boundArgs.length; ++i) { - table.insert(argArray, i + 1, boundArgs[i]); + table.insert(args, i + 1, boundArgs[i]); } - return fn(thisArg, (unpack || table.unpack)(argArray)); + return fn(thisArg, (unpack || table.unpack)(args)); }; } diff --git a/src/lualib/FunctionCall.ts b/src/lualib/FunctionCall.ts index 66a2be373..525086b58 100644 --- a/src/lualib/FunctionCall.ts +++ b/src/lualib/FunctionCall.ts @@ -1,11 +1,8 @@ -declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; - -declare namespace table { - export function unpack(this: void, list: T[], i?: number, j?: number): T[]; -} - -type CallFn = (this: void, ...argArray: any[]) => any; - -function __TS__FunctionCall(this: void, fn: CallFn, thisArg: any, ...args: any[]): any { +function __TS__FunctionCall( + this: void, + fn: (this: void, ...args: any[]) => any, + thisArg: any, + ...args: any[] +): any { return fn(thisArg, (unpack || table.unpack)(args)); } diff --git a/src/lualib/Index.ts b/src/lualib/Index.ts index 88c8e0035..ee7c2b9c7 100644 --- a/src/lualib/Index.ts +++ b/src/lualib/Index.ts @@ -1,16 +1,4 @@ -interface LuaClass { - prototype: LuaObject; - ____super?: LuaClass; -} - -declare interface LuaObject { - constructor: LuaClass; - ____getters?: { [key: string]: (this: void, self: LuaObject) => any }; -} - -declare function rawget(obj: T, key: K): T[K]; - -function __TS__Index(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: keyof LuaObject) => any { +function __TS__Index(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: any) => any { return (tbl, key) => { let proto = classProto; while (true) { diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index 6f6dd1c3c..b9b47f707 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -1,11 +1,3 @@ -interface LuaClass { - ____super?: LuaClass; -} - -interface LuaObject { - constructor: LuaClass; -} - function __TS__InstanceOf(this: void, obj: LuaObject, classTbl: LuaClass): boolean { if (typeof classTbl !== "object") { // tslint:disable-next-line: no-string-throw diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index f47d81abb..57da9d86d 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -1,34 +1,31 @@ -/** @tupleReturn */ -declare function next(this: void, t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; +Map = class Map { + public static [Symbol.species] = Map; + public [Symbol.toStringTag] = "Map"; -class Map { - public size: number; + // Type of key is actually K + private items: { [key: string]: V } = {}; + public size = 0; - private items: {[key: string]: TValue}; // Type of key is actually TKey + constructor(entries?: Iterable | Array) { + if (entries === undefined) return; - constructor(other: Iterable<[TKey, TValue]> | Array<[TKey, TValue]>) { - this.items = {}; - this.size = 0; - - if (other) { - const iterable = other as Iterable<[TKey, TValue]>; - if (iterable[Symbol.iterator]) { - // Iterate manually because Map is compiled with ES5 which doesn't support Iterables in for...of - const iterator = iterable[Symbol.iterator](); - while (true) { - const result = iterator.next(); - if (result.done) { - break; - } - const value: [TKey, TValue] = result.value; // Ensures index is offset when tuple is accessed - this.set(value[0], value[1]); - } - } else { - const arr = other as Array<[TKey, TValue]>; - this.size = arr.length; - for (const kvp of arr) { - this.items[kvp[0] as any] = kvp[1]; + const iterable = entries as Iterable<[K, V]>; + if (iterable[Symbol.iterator]) { + // Iterate manually because Map is compiled with ES5 which doesn't support Iterables in for...of + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + break; } + const value: [K, V] = result.value; // Ensures index is offset when tuple is accessed + this.set(value[0], value[1]); + } + } else { + const array = entries as Array<[K, V]>; + this.size = array.length; + for (const kvp of array) { + this.items[kvp[0] as any] = kvp[1]; } } } @@ -39,7 +36,7 @@ class Map { return; } - public delete(key: TKey): boolean { + public delete(key: K): boolean { const contains = this.has(key); if (contains) { this.size--; @@ -48,68 +45,74 @@ class Map { return contains; } - public [Symbol.iterator](): IterableIterator<[TKey, TValue]> { - return this.entries(); - } - - public entries(): IterableIterator<[TKey, TValue]> { - const items = this.items; - let key: TKey; - let value: TValue; - return { - [Symbol.iterator](): IterableIterator<[TKey, TValue]> { return this; }, - next(): IteratorResult<[TKey, TValue]> { - [key, value] = next(items, key); - return {done: !key, value: [key, value]}; - }, - }; - } - - public forEach(callback: (value: TValue, key: TKey, map: Map) => any): void { + public forEach(callback: (value: V, key: K, map: Map) => any): void { for (const key in this.items) { callback(this.items[key], key as any, this); } return; } - public get(key: TKey): TValue { + public get(key: K): V | undefined { return this.items[key as any]; } - public has(key: TKey): boolean { + public has(key: K): boolean { return this.items[key as any] !== undefined; } - public keys(): IterableIterator { + public set(key: K, value: V): this { + if (!this.has(key)) { + this.size++; + } + this.items[key as any] = value; + return this; + } + + public [Symbol.iterator](): IterableIterator<[K, V]> { + return this.entries(); + } + + public entries(): IterableIterator<[K, V]> { const items = this.items; - let key: TKey; + let key: K; + let value: V; return { - [Symbol.iterator](): IterableIterator { return this; }, - next(): IteratorResult { - [key] = next(items, key); - return {done: !key, value: key}; + [Symbol.iterator](): IterableIterator<[K, V]> { + return this; + }, + next(): IteratorResult<[K, V]> { + [key, value] = next(items, key); + return { done: !key, value: [key, value] }; }, }; } - public set(key: TKey, value: TValue): Map { - if (!this.has(key)) { - this.size++; - } - this.items[key as any] = value; - return this; + public keys(): IterableIterator { + const items = this.items; + let key: K; + return { + [Symbol.iterator](): IterableIterator { + return this; + }, + next(): IteratorResult { + [key] = next(items, key); + return { done: !key, value: key }; + }, + }; } - public values(): IterableIterator { + public values(): IterableIterator { const items = this.items; - let key: TKey; - let value: TValue; + let key: K; + let value: V; return { - [Symbol.iterator](): IterableIterator { return this; }, - next(): IteratorResult { + [Symbol.iterator](): IterableIterator { + return this; + }, + next(): IteratorResult { [key, value] = next(items, key); - return {done: !key, value}; + return { done: !key, value }; }, }; } -} +}; diff --git a/src/lualib/NewIndex.ts b/src/lualib/NewIndex.ts index efe07f075..1c912fa6f 100644 --- a/src/lualib/NewIndex.ts +++ b/src/lualib/NewIndex.ts @@ -1,18 +1,5 @@ -interface LuaClass { - prototype: LuaObject; - ____super?: LuaClass; -} - -declare interface LuaObject { - constructor: LuaClass; - ____setters?: { [key: string]: (this: void, self: LuaObject, val: any) => void }; -} - -declare function rawget(this: void, obj: T, key: K): T[K]; -declare function rawset(this: void, obj: T, key: K, val: T[K]): void; - function __TS__NewIndex(this: void, classProto: LuaObject) - : (this: void, tbl: LuaObject, key: keyof LuaObject, val: any) => void + : (this: void, tbl: LuaObject, key: any, val: any) => void { return (tbl, key, val) => { let proto = classProto; diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index e1bf8fc39..238843d8c 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -1,38 +1,35 @@ -/** @tupleReturn */ -declare function next(this: void, t: { [k: string]: TValue }, index?: TKey): [TKey, TValue]; +Set = class Set { + public static [Symbol.species] = Set; + public [Symbol.toStringTag] = "Set"; -class Set { - public size: number; + // Key type is actually T + private items: { [key: string]: boolean } = {}; + public size = 0; - private items: {[key: string]: boolean}; // Key type is actually TValue + constructor(values?: Iterable | T[]) { + if (values === undefined) return; - constructor(other: Iterable | TValue[]) { - this.items = {}; - this.size = 0; - - if (other) { - const iterable = other as Iterable; - if (iterable[Symbol.iterator]) { - // Iterate manually because Set is compiled with ES5 which doesn't support Iterables in for...of - const iterator = iterable[Symbol.iterator](); - while (true) { - const result = iterator.next(); - if (result.done) { - break; - } - this.add(result.value); - } - } else { - const arr = other as TValue[]; - this.size = arr.length; - for (const value of arr) { - this.items[value as any] = true; + const iterable = values as Iterable; + if (iterable[Symbol.iterator]) { + // Iterate manually because Set is compiled with ES5 which doesn't support Iterables in for...of + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + break; } + this.add(result.value); + } + } else { + const array = values as T[]; + this.size = array.length; + for (const value of array) { + this.items[value as any] = true; } } } - public add(value: TValue): Set { + public add(value: T): Set { if (!this.has(value)) { this.size++; } @@ -46,7 +43,7 @@ class Set { return; } - public delete(value: TValue): boolean { + public delete(value: T): boolean { const contains = this.has(value); if (contains) { this.size--; @@ -55,54 +52,59 @@ class Set { return contains; } - public [Symbol.iterator](): IterableIterator { + public forEach(callback: (value: T, key: T, set: Set) => any): void { + for (const key in this.items) { + callback(key as any, key as any, this); + } + } + + public has(value: T): boolean { + return this.items[value as any] === true; + } + + public [Symbol.iterator](): IterableIterator { return this.values(); } - public entries(): IterableIterator<[TValue, TValue]> { + public entries(): IterableIterator<[T, T]> { const items = this.items; - let key: TValue; + let key: T; return { - [Symbol.iterator](): IterableIterator<[TValue, TValue]> { return this; }, - next(): IteratorResult<[TValue, TValue]> { + [Symbol.iterator](): IterableIterator<[T, T]> { + return this; + }, + next(): IteratorResult<[T, T]> { [key] = next(items, key); - return {done: !key, value: [key, key]}; + return { done: !key, value: [key, key] }; }, }; } - public forEach(callback: (value: TValue, key: TValue, set: Set) => any): void { - for (const key in this.items) { - callback(key as any, key as any, this); - } - return; - } - - public has(value: TValue): boolean { - return this.items[value as any] === true; - } - - public keys(): IterableIterator { + public keys(): IterableIterator { const items = this.items; - let key: TValue; + let key: T; return { - [Symbol.iterator](): IterableIterator { return this; }, - next(): IteratorResult { + [Symbol.iterator](): IterableIterator { + return this; + }, + next(): IteratorResult { [key] = next(items, key); - return {done: !key, value: key}; + return { done: !key, value: key }; }, }; } - public values(): IterableIterator { + public values(): IterableIterator { const items = this.items; - let key: TValue; + let key: T; return { - [Symbol.iterator](): IterableIterator { return this; }, - next(): IteratorResult { + [Symbol.iterator](): IterableIterator { + return this; + }, + next(): IteratorResult { [key] = next(items, key); - return {done: !key, value: key}; + return { done: !key, value: key }; }, }; } -} +}; diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index eb5215d64..827ce7874 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,11 +1,3 @@ -declare const debug: { - traceback: (this: void, ...args: any[]) => string; -}; - -type TraceBackFunction = (this: void, thread?: any, message?: string, level?: number) => string; - -declare const _G: {[key: string]: any} & {__TS__originalTraceback: TraceBackFunction}; - // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: {[line: number]: number}): void { @@ -16,7 +8,7 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: {[lin _G.__TS__originalTraceback = debug.traceback; debug.traceback = (thread, message, level) => { const trace = _G["__TS__originalTraceback"](thread, message, level); - const [result, occurrences] = string.gsub( + const [result] = string.gsub( trace, "(%S+).lua:(%d+)", (file, line) => { diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 316f34ef5..aee6ac66b 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,9 +1,3 @@ -declare function unpack(this: void, list: T[], i?: number, j?: number): T[]; - -declare namespace table { - export function unpack(this: void, list: T[], i?: number, j?: number): T[]; -} - function __TS__Spread(this: void, iterable: Iterable): T[] { const arr: T[] = []; for (const item of iterable) { diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 032086ff8..f9e7d5eb5 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,5 +1,3 @@ -declare function setmetatable(this: void, obj: T, metatable: any): T; - // tslint:disable-next-line: variable-name const ____symbolMetatable = { __tostring(): string { @@ -18,4 +16,8 @@ function __TS__Symbol(this: void, description?: string | number): symbol { Symbol = { iterator: __TS__Symbol("Symbol.iterator"), hasInstance: __TS__Symbol("Symbol.hasInstance"), + + // Not implemented + species: __TS__Symbol("Symbol.species"), + toStringTag: __TS__Symbol("Symbol.toStringTag"), } as any; diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 407b268a3..e3b08543d 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,49 +1,49 @@ -declare function setmetatable(this: void, obj: T, metatable: any): T; +WeakMap = class WeakMap { + public static [Symbol.species] = WeakMap; + public [Symbol.toStringTag] = "WeakMap"; -class WeakMap { - private items: {[key: string]: TValue}; // Type of key is actually TKey + // Type of key is actually K + private items: { [key: string]: V } = {}; - constructor(other: Iterable<[TKey, TValue]> | Array<[TKey, TValue]>) { - this.items = {}; - setmetatable(this.items, { __mode: 'k' }); + constructor(entries?: Iterable | Array) { + setmetatable(this.items, { __mode: "k" }); + if (entries === undefined) return; - if (other) { - const iterable = other as Iterable<[TKey, TValue]>; - if (iterable[Symbol.iterator]) { - // Iterate manually because WeakMap is compiled with ES5 which doesn't support Iterables in for...of - const iterator = iterable[Symbol.iterator](); - while (true) { - const result = iterator.next(); - if (result.done) { - break; - } - const value: [TKey, TValue] = result.value; // Ensures index is offset when tuple is accessed - this.set(value[0], value[1]); - } - } else { - for (const kvp of other as Array<[TKey, TValue]>) { - this.items[kvp[0] as any] = kvp[1]; + const iterable = entries as Iterable<[K, V]>; + if (iterable[Symbol.iterator]) { + // Iterate manually because WeakMap is compiled with ES5 which doesn't support Iterables in for...of + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + break; } + const value: [K, V] = result.value; // Ensures index is offset when tuple is accessed + this.set(value[0], value[1]); + } + } else { + for (const kvp of entries as Array<[K, V]>) { + this.items[kvp[0] as any] = kvp[1]; } } } - public delete(key: TKey): boolean { + public delete(key: K): boolean { const contains = this.has(key); this.items[key as any] = undefined; return contains; } - public get(key: TKey): TValue { + public get(key: K): V | undefined { return this.items[key as any]; } - public has(key: TKey): boolean { + public has(key: K): boolean { return this.items[key as any] !== undefined; } - public set(key: TKey, value: TValue): WeakMap { + public set(key: K, value: V): this { this.items[key as any] = value; return this; } -} +}; diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index cbe7b5ede..80b3ffda1 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,44 +1,44 @@ -declare function setmetatable(this: void, obj: T, metatable: any): T; +WeakSet = class WeakSet { + public static [Symbol.species] = WeakSet; + public [Symbol.toStringTag] = "WeakSet"; -class WeakSet { - private items: {[key: string]: boolean}; // Key type is actually TValue + // Key type is actually T + private items: { [key: string]: boolean } = {}; - constructor(other: Iterable | TValue[]) { - this.items = {}; - setmetatable(this.items, { __mode: 'k' }); + constructor(values?: Iterable | T[]) { + setmetatable(this.items, { __mode: "k" }); + if (values === undefined) return; - if (other) { - const iterable = other as Iterable; - if (iterable[Symbol.iterator]) { - // Iterate manually because WeakSet is compiled with ES5 which doesn't support Iterables in for...of - const iterator = iterable[Symbol.iterator](); - while (true) { - const result = iterator.next(); - if (result.done) { - break; - } - this.add(result.value); - } - } else { - for (const value of other as TValue[]) { - this.items[value as any] = true; + const iterable = values as Iterable; + if (iterable[Symbol.iterator]) { + // Iterate manually because WeakSet is compiled with ES5 which doesn't support Iterables in for...of + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + break; } + this.add(result.value); + } + } else { + for (const value of values as T[]) { + this.items[value as any] = true; } } } - public add(value: TValue): WeakSet { + public add(value: T): this { this.items[value as any] = true; return this; } - public delete(value: TValue): boolean { + public delete(value: T): boolean { const contains = this.has(value); this.items[value as any] = undefined; return contains; } - public has(value: TValue): boolean { + public has(value: T): boolean { return this.items[value as any] === true; } -} +}; diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts new file mode 100644 index 000000000..d5bd489d4 --- /dev/null +++ b/src/lualib/declarations/debug.d.ts @@ -0,0 +1,5 @@ +/** @noSelfInFile */ + +declare namespace debug { + function traceback(...args: any[]): string; +} diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index ecedef17d..b34b857f4 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,6 +1,20 @@ /** @noSelfInFile */ +// TODO: TS3.4: typeof globalThis +declare const _G: { + // Required? + __TS__originalTraceback(this: void, thread?: any, message?: string, level?: number): string; + [key: string]: any; +}; + declare function tonumber(value: any, base?: number): number | undefined; declare function type( value: any ): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; +declare function setmetatable(table: T, metatable: any): T; +declare function rawget(table: T, key: K): T[K]; +declare function rawset(table: T, key: K, val: T[K]): void; +/** @tupleReturn */ +declare function next(table: Record, index?: K): [K, V]; +declare function pcall(func: () => any): any; +declare function unpack(list: T[], i?: number, j?: number): T[]; diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 0663ada37..1003f5450 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -1,6 +1,3 @@ -/** @luaIterator */ -interface GMatchResult extends Array {} - /** @noSelf */ declare namespace string { /** @tupleReturn */ @@ -10,7 +7,5 @@ declare namespace string { replaceValue: string | ((...groups: string[]) => string), n?: number ): [string, number]; - - function gmatch(haystack: string, pattern: string): GMatchResult; function sub(s: string, i: number, j?: number): string; } diff --git a/src/lualib/declarations/table.d.ts b/src/lualib/declarations/table.d.ts new file mode 100644 index 000000000..776fe72b0 --- /dev/null +++ b/src/lualib/declarations/table.d.ts @@ -0,0 +1,8 @@ +/** @noSelfInFile */ + +declare namespace table { + function sort(list: T[], compareFn?: (a: T, b: T) => boolean): void; + function remove(list: T[], idx: number): T; + function insert(list: T[], idx: number, val: T): void; + function unpack(list: T[], i?: number, j?: number): T[]; +} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts new file mode 100644 index 000000000..8441e227b --- /dev/null +++ b/src/lualib/declarations/tstl.d.ts @@ -0,0 +1,14 @@ +/** @noSelfInFile */ + +interface LuaClass { + prototype: LuaObject; + ____super?: LuaClass; + ____getters?: { [key: string]: (self: LuaClass) => any }; + ____setters?: { [key: string]: (self: LuaClass, val: any) => void }; +} + +interface LuaObject { + constructor: LuaClass; + ____getters?: { [key: string]: (self: LuaObject) => any }; + ____setters?: { [key: string]: (self: LuaObject, val: any) => void }; +} diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json new file mode 100644 index 000000000..350f34824 --- /dev/null +++ b/src/lualib/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "outDir": "../../dist/lualib", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "skipLibCheck": true, + + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "tstl": { + "luaLibImport": "none", + "luaTarget": "5.1" + } +} diff --git a/src/tstl.ts b/src/tstl.ts index 64c5bb53a..7a21449aa 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -5,17 +5,6 @@ import * as tstl from "."; import * as CommandLineParser from "./CommandLineParser"; import * as cliDiagnostics from "./diagnostics"; -function createDiagnosticReporter(pretty: boolean): ts.DiagnosticReporter { - const reporter: ts.DiagnosticReporter = (ts as any).createDiagnosticReporter(ts.sys, pretty); - return diagnostic => { - if (diagnostic.source === "typescript-to-lua") { - diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; - } - - reporter(diagnostic); - }; -} - function createWatchStatusReporter(options?: ts.CompilerOptions): ts.WatchStatusReporter { return (ts as any).createWatchStatusReporter(ts.sys, shouldBePretty(options)); } @@ -26,9 +15,9 @@ function shouldBePretty(options?: ts.CompilerOptions): boolean { : Boolean(options.pretty); } -let reportDiagnostic = createDiagnosticReporter(false); +let reportDiagnostic = tstl.createDiagnosticReporter(false); function updateReportDiagnostic(options?: ts.CompilerOptions): void { - reportDiagnostic = createDiagnosticReporter(shouldBePretty(options)); + reportDiagnostic = tstl.createDiagnosticReporter(shouldBePretty(options)); } function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefined { @@ -145,9 +134,9 @@ function performBuild(_args: string[]): void { function performCompilation( rootNames: string[], - projectReferences: ReadonlyArray | undefined, + projectReferences: readonly ts.ProjectReference[] | undefined, options: tstl.CompilerOptions, - configFileParsingDiagnostics?: ReadonlyArray + configFileParsingDiagnostics?: readonly ts.Diagnostic[] ): void { const program = ts.createProgram({ rootNames, diff --git a/test/setup.ts b/test/setup.ts index 8e4e5fbb5..e1c041d8c 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -4,8 +4,8 @@ import * as util from "./util"; declare global { namespace jest { interface Matchers { - toThrowExactError(error: Error): void; - toHaveDiagnostics(): void; + toThrowExactError(error: Error): R; + toHaveDiagnostics(): R; } } } @@ -31,10 +31,9 @@ expect.extend({ return { pass: true, message: () => "" }; }, toHaveDiagnostics(diagnostics: ts.Diagnostic[]): jest.CustomMatcherResult { - expect(Array.isArray(diagnostics)).toBe(true); - const options = { isNot: this.isNot }; + expect(diagnostics).toBeInstanceOf(Array); // @ts-ignore - const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", options); + const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", this); const diagnosticMessages = ts.formatDiagnosticsWithColorAndContext(diagnostics, { getCurrentDirectory: () => "", diff --git a/test/transpile/outFile.spec.ts b/test/transpile/outFile.spec.ts index 5a2e9c399..fa073490e 100644 --- a/test/transpile/outFile.spec.ts +++ b/test/transpile/outFile.spec.ts @@ -33,7 +33,7 @@ test("should support outFile with declaration", () => { test("should resolve outFile relative to base directory", () => { jest.spyOn(process, "cwd").mockReturnValue(__dirname); - const { diagnostics, emittedFiles, emitResult } = buildVirtualProject([inputFilePath], { + const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { outFile: "output.script", outDir: "out", declaration: true, diff --git a/test/tsconfig.json b/test/tsconfig.json index 684b6c260..34b2ee7a4 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,7 +3,10 @@ "baseUrl": ".", "paths": { "*": ["types/*"] }, "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "target": "es2017", + "lib": ["es2017"], "types": ["node", "jest"], "noEmit": true, diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index 9da08ce1c..85dde6455 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -2,13 +2,13 @@ import * as util from "../util"; test("Array access", () => { const result = util.transpileAndExecute( - `const arr: number[] = [3,5,1]; + `const arr: Array = [3,5,1]; return arr[1];`, ); expect(result).toBe(5); }); -test("Readonly Array access", () => { +test("ReadonlyArray access", () => { const result = util.transpileAndExecute( `const arr: ReadonlyArray = [3,5,1]; return arr[1];`, @@ -16,6 +16,22 @@ test("Readonly Array access", () => { expect(result).toBe(5); }); +test("Array literal access", () => { + const result = util.transpileAndExecute( + `const arr: number[] = [3,5,1]; + return arr[1];`, + ); + expect(result).toBe(5); +}); + +test("Readonly array literal access", () => { + const result = util.transpileAndExecute( + `const arr: readonly number[] = [3,5,1]; + return arr[1];`, + ); + expect(result).toBe(5); +}); + test("Array union access", () => { const result = util.transpileAndExecute( `function makeArray(): number[] | string[] { return [3,5,1]; } diff --git a/test/unit/assignments/functionExpressionTypeInference.spec.ts b/test/unit/assignments/functionExpressionTypeInference.spec.ts index e393d477c..aa47a8c18 100644 --- a/test/unit/assignments/functionExpressionTypeInference.spec.ts +++ b/test/unit/assignments/functionExpressionTypeInference.spec.ts @@ -335,9 +335,9 @@ test.each([ const code = ` class C { result: string; - constructor(fn: (s: string) => string) { this.result = fn("foo"); } + constructor(fn: ${funcType}) { this.result = fn("foo"); } } - const c = new C(s => s); + const c = new C(${funcExp}); return c.result; `; expect(util.transpileAndExecute(code)).toBe("foo"); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 7adc5a29a..e53407bc8 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -8,7 +8,7 @@ test("throwString", () => { test("throwError", () => { expect(() => { - const lua = util.transpileString(`throw Error("Some Error")`); + util.transpileString(`throw Error("Some Error")`); }).toThrowExactError(TSTLErrors.InvalidThrowExpression(util.nodeStub)); }); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index e9c5dee7b..eaf54d1f8 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -190,26 +190,26 @@ test.each([ }); test.each([ - { inp: [], expected: "" }, - { inp: ["test1"], expected: "test1" }, - { inp: ["test1", "test2"], expected: "test1,test2" }, - { inp: ["test1", "test2"], expected: "test1;test2", seperator: ";" }, - { inp: ["test1", "test2"], expected: "test1test2", seperator: "" }, -])("array.join (%p)", ({ inp, expected, seperator }) => { - let seperatorLua; - if (seperator === "") { - seperatorLua = '""'; - } else if (seperator) { - seperatorLua = '"' + seperator + '"'; + { inp: [] }, + { inp: ["test1"] }, + { inp: ["test1", "test2"] }, + { inp: ["test1", "test2"], separator: ";" }, + { inp: ["test1", "test2"], separator: "" }, +])("array.join (%p)", ({ inp, separator }) => { + let separatorLua; + if (separator === "") { + separatorLua = '""'; + } else if (separator) { + separatorLua = '"' + separator + '"'; } else { - seperatorLua = ""; + separatorLua = ""; } const result = util.transpileAndExecute( `let joinTestTable = ${JSON.stringify(inp)}; - return joinTestTable.join(${seperatorLua});`, + return joinTestTable.join(${separatorLua});`, ); - const joinedInp = inp.join(seperator); + const joinedInp = inp.join(separator); expect(result).toBe(joinedInp); }); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 679e6e615..ba9d7ce55 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -4,7 +4,7 @@ import * as util from "../util"; test("defaultImport", () => { expect(() => { - const lua = util.transpileString(`import TestClass from "test"`); + util.transpileString(`import TestClass from "test"`); }).toThrowExactError(TSTLErrors.DefaultImportsNotSupported(util.nodeStub)); }); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 9c1be2618..7b7aa40fe 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -1,5 +1,4 @@ import * as util from "../util"; -const fs = require("fs"); test.each([ { inp: `{a:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 9bbf57ef6..17a340975 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -226,14 +226,11 @@ test.each([ expect(result).toBe(inp.substr(start, end)); }); -test.each([{ inp: "", expected: 0 }, { inp: "h", expected: 1 }, { inp: "hello", expected: 5 }])( - "string.length (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute(`return "${inp}".length`); +test.each(["", "h", "hello"])("string.length (%p)", input => { + const result = util.transpileAndExecute(`return "${input}".length`); - expect(result).toBe(inp.length); - }, -); + expect(result).toBe(input.length); +}); test.each(["hello TEST"])("string.toLowerCase (%p)", inp => { const result = util.transpileAndExecute(`return "${inp}".toLowerCase()`); diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 9513250e4..681c0a1b3 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -3,36 +3,6 @@ import { DecoratorKind } from "../../src/Decorator"; import { TSHelper as tsHelper } from "../../src/TSHelper"; import * as util from "../util"; -enum TestEnum { - testA = 1, - testB = 2, - testC = 4, -} - -test.each([ - { inp: TestEnum.testA, expected: "testA" }, - { inp: -1, expected: "unknown" }, - { inp: TestEnum.testA | TestEnum.testB, expected: "unknown" }, -])("EnumName (%p)", ({ inp, expected }) => { - const result = tsHelper.enumName(inp, TestEnum); - - expect(result).toEqual(expected); -}); - -test.each([ - { inp: TestEnum.testA, expected: ["testA"] }, - { inp: -1, expected: [] }, - { inp: TestEnum.testA | TestEnum.testC, expected: ["testA", "testC"] }, - { - inp: TestEnum.testA | TestEnum.testB | TestEnum.testC, - expected: ["testA", "testB", "testC"], - }, -])("EnumNames (%p)", ({ inp, expected }) => { - const result = tsHelper.enumNames(inp, TestEnum); - - expect(result).toEqual(expected); -}); - test("GetCustomDecorators single", () => { const source = ` /** @compileMembersOnly */ diff --git a/test/util.ts b/test/util.ts index 84b77d0e9..43b748907 100644 --- a/test/util.ts +++ b/test/util.ts @@ -29,13 +29,7 @@ export function transpileStringResult( noHeader: true, skipLibCheck: true, target: ts.ScriptTarget.ESNext, - lib: [ - "lib.es2015.d.ts", - "lib.es2016.d.ts", - "lib.es2017.d.ts", - "lib.es2018.d.ts", - "lib.esnext.d.ts", - ], + lib: ["lib.esnext.d.ts"], experimentalDecorators: true, ...options, }; @@ -165,6 +159,7 @@ export function findFirstChild( export function expectToBeDefined(subject: T | null | undefined): subject is T { expect(subject).toBeDefined(); + expect(subject).not.toBeNull(); return true; // If this was false the expect would have thrown an error } @@ -173,4 +168,4 @@ export const valueToString = (value: unknown) => ? String(value) : JSON.stringify(value); -export const valuesToString = (values: Array) => values.map(valueToString).join(", "); +export const valuesToString = (values: unknown[]) => values.map(valueToString).join(", "); diff --git a/tsconfig.json b/tsconfig.json index e6ecaae97..8f1275d19 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,11 +1,14 @@ { "compilerOptions": { "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "rootDir": "./src", "outDir": "./dist", "declaration": true, "sourceMap": true, "target": "es2017", + "lib": ["es2017"], "module": "commonjs", "stripInternal": true }, From 63f5568a916a82a321fab680a0f57abe29b3e637 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 18 May 2019 12:06:12 -0600 Subject: [PATCH 085/764] Fixed @tupleReturn on interface function properties (#582) * Fixed @tupleReturn on interface function properties Also fixed detection of @tupleReturn on object literal methods/function-properties that are assigned to interaces. * unpack checks in tuple tests, destructuring array literals doesn't pack+unpack anymore, and addressed feedback * revised destructuring array literals so right side is always evaluated --- src/LuaTransformer.ts | 16 +++- src/TSHelper.ts | 22 ++++- test/unit/tuples.spec.ts | 171 ++++++++++++++++++++++++++++++++++----- 3 files changed, 185 insertions(+), 24 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index f2f2cdc6e..3f0278947 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1882,9 +1882,9 @@ export class LuaTransformer { tstl.isIdentifier) : tstl.createAnonymousIdentifier(statement.name); - // Don't unpack TupleReturn decorated functions if (statement.initializer) { if (tsHelper.isTupleReturnCall(statement.initializer, this.checker)) { + // Don't unpack TupleReturn decorated functions statements.push( ...this.createLocalOrExportedOrGlobalDeclaration( vars, @@ -1892,6 +1892,18 @@ export class LuaTransformer { statement ) ); + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Don't unpack array literals + const values = statement.initializer.elements.length > 0 + ? statement.initializer.elements.map(e => this.transformExpression(e)) + : tstl.createNilLiteral(); + statements.push( + ...this.createLocalOrExportedOrGlobalDeclaration( + vars, + values, + statement + ) + ); } else { // local vars = this.transpileDestructingAssignmentValue(node.initializer); const initializer = this.createUnpackCall( @@ -4873,7 +4885,7 @@ export class LuaTransformer { protected createLocalOrExportedOrGlobalDeclaration( lhs: tstl.Identifier | tstl.Identifier[], - rhs?: tstl.Expression, + rhs?: tstl.Expression | tstl.Expression[], tsOriginal?: ts.Node, parent?: tstl.Node ): tstl.Statement[] diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 6b4d76615..a42407c19 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -183,10 +183,18 @@ export class TSHelper { public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); if (declaration) { - let functionType: ts.Type; + let functionType: ts.Type | undefined; if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { functionType = TSHelper.inferAssignedType(declaration, checker); - } else { + } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { + // Manually lookup type for object literal properties declared with method syntax + const interfaceType = TSHelper.inferAssignedType(declaration.parent, checker); + const propertySymbol = interfaceType.getProperty(declaration.name.getText()); + if (propertySymbol) { + functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); + } + } + if (functionType === undefined) { functionType = checker.getTypeAtLocation(declaration); } @@ -279,6 +287,16 @@ export class TSHelper { { const directivesMap = new Map(); TSHelper.collectCustomDecorators(signature, checker, directivesMap); + + // Function properties on interfaces have the JSDoc tags on the parent PropertySignature + const declaration = signature.getDeclaration(); + if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { + const symbol = checker.getSymbolAtLocation(declaration.parent.name); + if (symbol) { + TSHelper.collectCustomDecorators(symbol, checker, directivesMap); + } + } + return directivesMap; } diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 41fa43676..08fbad709 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -64,6 +64,30 @@ test("Tuple Destruct", () => { expect(result).toBe(5); }); +test("Tuple Destruct Array Literal", () => { + const code = ` + const [a,b,c] = [3,5,1]; + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Destruct Array Literal Extra Values", () => { + const code = ` + let result = ""; + const set = () => { result = "bar"; }; + const [a] = ["foo", set()]; + return a + result;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe("foobar"); +}); + test("Tuple length", () => { const result = util.transpileAndExecute( `const tuple: [number, number, number] = [3,5,1]; @@ -74,62 +98,169 @@ test("Tuple length", () => { }); test("Tuple Return Access", () => { - const result = util.transpileAndExecute( - `/** @tupleReturn */ + const code = ` + /** @tupleReturn */ function tuple(): [number, number, number] { return [3,5,1]; } - return tuple()[2];`, - ); + return tuple()[2];`; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); expect(result).toBe(1); }); test("Tuple Return Destruct Declaration", () => { - const result = util.transpileAndExecute( - `/** @tupleReturn */ + const code = ` + /** @tupleReturn */ function tuple(): [number, number, number] { return [3,5,1]; } const [a,b,c] = tuple(); - return b;`, - ); + return b;`; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); expect(result).toBe(5); }); test("Tuple Return Destruct Assignment", () => { - const result = util.transpileAndExecute( - `/** @tupleReturn */ + const code = ` + /** @tupleReturn */ function tuple(): [number, number] { return [3,6]; } let [a,b] = [1,2]; [b,a] = tuple(); - return a - b;`, - ); + return a - b;`; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); expect(result).toBe(3); }); test("Tuple Static Method Return Destruct", () => { - const result = util.transpileAndExecute( - `class Test { + const code = ` + class Test { /** @tupleReturn */ static tuple(): [number, number, number] { return [3,5,1]; } } const [a,b,c] = Test.tuple(); - return b;`, - ); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Static Function Property Return Destruct", () => { + const code = ` + class Test { + /** @tupleReturn */ + static tuple: () => [number, number, number] = () => [3,5,1]; + } + const [a,b,c] = Test.tuple(); + return b;`; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); expect(result).toBe(5); }); test("Tuple Non-Static Method Return Destruct", () => { - const result = util.transpileAndExecute( - `class Test { + const code = ` + class Test { /** @tupleReturn */ tuple(): [number, number, number] { return [3,5,1]; } } const t = new Test(); const [a,b,c] = t.tuple(); - return b;`, - ); + return b;`; + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Non-Static Function Property Return Destruct", () => { + const code = ` + class Test { + /** @tupleReturn */ + tuple: () => [number, number, number] = () => [3,5,1]; + } + const t = new Test(); + const [a,b,c] = t.tuple(); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Interface Method Return Destruct", () => { + const code = ` + interface Test { + /** @tupleReturn */ + tuple(): [number, number, number]; + } + const t: Test = { + tuple() { return [3,5,1]; } + }; + const [a,b,c] = t.tuple(); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Interface Function Property Return Destruct", () => { + const code = ` + interface Test { + /** @tupleReturn */ + tuple: () => [number, number, number]; + } + const t: Test = { + tuple: () => [3,5,1] + }; + const [a,b,c] = t.tuple(); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Object Literal Method Return Destruct", () => { + const code = ` + const t = { + /** @tupleReturn */ + tuple() { return [3,5,1]; } + }; + const [a,b,c] = t.tuple(); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); + expect(result).toBe(5); +}); + +test("Tuple Object Literal Function Property Return Destruct", () => { + const code = ` + const t = { + /** @tupleReturn */ + tuple: () => [3,5,1] + }; + const [a,b,c] = t.tuple(); + return b;`; + + const lua = util.transpileString(code); + expect(lua).not.toContain("unpack"); + const result = util.executeLua(lua); expect(result).toBe(5); }); From e18bf5903c649bc62ffbc933f2393b5b151111d5 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 19 May 2019 08:04:31 -0600 Subject: [PATCH 086/764] Allow lua keywords and identifiers with invalid characters (#581) * allowing lua keywords as identifier names by prepending 4 underscores * big refactor, invalid character support, and more tests * using getIdentifierText and formatting fixes * explicit checks for static "new" method/property --- src/LuaTransformer.ts | 292 ++++++--- src/TSHelper.ts | 4 + src/TSTLErrors.ts | 4 +- .../__snapshots__/transformation.spec.ts.snap | 40 +- test/unit/assignments/assignments.spec.ts | 9 - test/unit/class.spec.ts | 40 ++ test/unit/identifiers.spec.ts | 574 ++++++++++++++++++ test/unit/importexport.spec.ts | 15 + 8 files changed, 857 insertions(+), 121 deletions(-) create mode 100644 test/unit/identifiers.spec.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 3f0278947..1ec5009d6 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -40,8 +40,10 @@ interface Scope { export class LuaTransformer { public luaKeywords: Set = new Set([ - "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "if", "in", "local", "new", "nil", - "not", "or", "repeat", "return", "self", "then", "until", "while", + "_G", "and", "assert", "break", "coroutine", "debug", "do", "else", "elseif", "end", "error", "false", "for", + "function", "goto", "if", "ipairs", "in", "local", "math", "nil", "not", "or", "pairs", "pcall", "print", + "rawget", "rawset", "repeat", "return", "require", "self", "string", "table", "then", "tostring", "type", + "unpack", "until", "while", ]); private isStrict: boolean; @@ -238,10 +240,23 @@ export class LuaTransformer { const result = []; for (const exportElement of statement.exportClause.elements) { + let exportedIdentifier: tstl.Expression | undefined; + if (exportElement.propertyName !== undefined) { + exportedIdentifier = this.transformIdentifier(exportElement.propertyName); + + } else { + const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(exportElement); + if (exportedSymbol !== undefined) { + exportedIdentifier = this.createIdentifierFromSymbol(exportedSymbol, exportElement.name); + } else { + exportedIdentifier = this.transformIdentifier(exportElement.name); + } + } + result.push( tstl.createAssignmentStatement( this.createExportedIdentifier(this.transformIdentifier(exportElement.name)), - this.transformIdentifier(exportElement.propertyName || exportElement.name) + exportedIdentifier ) ); } @@ -368,7 +383,7 @@ export class LuaTransformer { return undefined; } - const tstlIdentifier = (name: string) => "__TSTL_" + name.replace(new RegExp("-|\\$| |#|'", "g"), "_"); + const tstlIdentifier = (name: string) => "__TSTL_" + tsHelper.fixInvalidLuaIdentifier(name); const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename((importPath)))); const requireStatement = tstl.createVariableDeclarationStatement( tstl.createIdentifier(tstlIdentifier(path.basename((importPath)))), @@ -379,8 +394,7 @@ export class LuaTransformer { filteredElements.forEach(importSpecifier => { if (importSpecifier.propertyName) { - const propertyIdentifier = this.transformIdentifier(importSpecifier.propertyName); - const propertyName = tstl.createStringLiteral(propertyIdentifier.text); + const propertyName = this.transformPropertyName(importSpecifier.propertyName); const renamedImport = tstl.createVariableDeclarationStatement( this.transformIdentifier(importSpecifier.name), tstl.createTableIndexExpression(importUniqueName, propertyName), @@ -427,6 +441,14 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); } + private validateClassElement(element: ts.ClassElement): void { + if (element.name && (ts.isStringLiteral(element.name) || ts.isIdentifier(element.name))) { + if (tsHelper.isStatic(element) && element.name.text === "new") { + throw TSTLErrors.ForbiddenStaticClassPropertyName(element, element.name.text); + } + } + } + public transformClassDeclaration( statement: ts.ClassLikeDeclaration, nameOverride?: tstl.Identifier @@ -532,10 +554,23 @@ export class LuaTransformer { } } + let localClassName: tstl.Identifier; + if (this.isUnsafeName(className.text)) { + localClassName = tstl.createIdentifier( + this.createSafeName(className.text), + undefined, + className.symbolId + ); + tstl.setNodePosition(localClassName, className); + } else { + localClassName = className; + } + if (!isExtension && !isMetaExtension) { const classCreationMethods = this.createClassCreationMethods( statement, className, + localClassName, extendsType ); result.push(...classCreationMethods); @@ -567,7 +602,7 @@ export class LuaTransformer { // Add constructor plus initialization of instance fields const constructorResult = this.transformConstructorDeclaration( constructor, - className, + localClassName, instanceFields, statement ); @@ -576,7 +611,7 @@ export class LuaTransformer { // Generate a constructor if none was defined in a base class const constructorResult = this.transformConstructorDeclaration( ts.createConstructor([], [], [], ts.createBlock([], true)), - className, + localClassName, instanceFields, statement ); @@ -585,7 +620,7 @@ export class LuaTransformer { || statement.members.some(m => tsHelper.isGetAccessorOverride(m, statement, this.checker))) { // Generate a constructor if none was defined in a class with instance fields that need initialization - // className.prototype.____constructor = function(self, ...) + // localClassName.prototype.____constructor = function(self, ...) // baseClassName.prototype.____constructor(self, ...) // ... const constructorBody = this.transformClassInstanceFields(statement, instanceFields); @@ -607,7 +642,7 @@ export class LuaTransformer { tstl.FunctionExpressionFlags.Declaration ); result.push(tstl.createAssignmentStatement( - this.createConstructorName(className), + this.createConstructorName(localClassName), constructorFunction, statement )); @@ -616,29 +651,35 @@ export class LuaTransformer { // Transform get accessors statement.members.filter(ts.isGetAccessor).forEach(getAccessor => { - const transformResult = this.transformGetAccessorDeclaration(getAccessor, className); + const transformResult = this.transformGetAccessorDeclaration(getAccessor, localClassName); result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform set accessors statement.members.filter(ts.isSetAccessor).forEach(setAccessor => { - const transformResult = this.transformSetAccessorDeclaration(setAccessor, className); + const transformResult = this.transformSetAccessorDeclaration(setAccessor, localClassName); result.push(...this.statementVisitResultToArray(transformResult)); }); // Transform methods statement.members.filter(ts.isMethodDeclaration).forEach(method => { - const methodResult = this.transformMethodDeclaration(method, className, isExtension || isMetaExtension); + const methodResult = this.transformMethodDeclaration( + method, + localClassName, + isExtension || isMetaExtension + ); result.push(...this.statementVisitResultToArray(methodResult)); }); // Add static declarations for (const field of staticFields) { + this.validateClassElement(field); + const fieldName = this.transformPropertyName(field.name); const value = field.initializer ? this.transformExpression(field.initializer) : undefined; const classField = tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), fieldName ); @@ -663,6 +704,7 @@ export class LuaTransformer { private createClassCreationMethods( statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, + localClassName: tstl.Identifier, extendsType?: ts.Type ): tstl.Statement[] { @@ -675,28 +717,28 @@ export class LuaTransformer { result.push(...classVar); if (this.isIdentifierExported(className)) { - // local className = ____exports.className + // local localClassName = ____exports.className result.push( tstl.createVariableDeclarationStatement( - tstl.cloneIdentifier(className, statement), + localClassName, this.addExportToIdentifier(tstl.cloneIdentifier(className)) ) ); } - // className.name = className + // localClassName.name = className result.push( tstl.createAssignmentStatement( - tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("name")), - tstl.createStringLiteral(className.text), + tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("name")), + tstl.createStringLiteral(localClassName.text), statement ) ); - // className.____getters = {} + // localClassName.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { const classGetters = tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("____getters") ); const assignClassGetters = tstl.createAssignmentStatement( @@ -709,18 +751,22 @@ export class LuaTransformer { this.importLuaLibFeature(LuaLibFeature.ClassIndex); } - // className.__index = className + // localClassName.__index = localClassName const classIndex = tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("__index") ); - const assignClassIndex = tstl.createAssignmentStatement(classIndex, tstl.cloneIdentifier(className), statement); + const assignClassIndex = tstl.createAssignmentStatement( + classIndex, + tstl.cloneIdentifier(localClassName), + statement + ); result.push(assignClassIndex); - // className.____setters = {} + // localClassName.____setters = {} if (statement.members.some(m => ts.isSetAccessor(m) && tsHelper.isStatic(m))) { const classSetters = tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("____setters") ); const assignClassSetters = tstl.createAssignmentStatement( @@ -733,9 +779,9 @@ export class LuaTransformer { this.importLuaLibFeature(LuaLibFeature.ClassNewIndex); } - // className.prototype = {} + // localClassName.prototype = {} const createClassPrototype = () => tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("prototype") ); const classPrototypeTable = tstl.createTableExpression(); @@ -746,7 +792,7 @@ export class LuaTransformer { ); result.push(assignClassPrototype); - // className.prototype.____getters = {} + // localClassName.prototype.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStatic(m))) { const classPrototypeGetters = tstl.createTableIndexExpression( createClassPrototype(), @@ -765,7 +811,7 @@ export class LuaTransformer { tstl.createStringLiteral("__index") ); if (tsHelper.hasGetAccessorInClassOrAncestor(statement, false, this.checker)) { - // className.prototype.__index = __TS_Index(className.prototype) + // localClassName.prototype.__index = __TS_Index(localClassName.prototype) const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeIndex, this.transformLuaLibFunction(LuaLibFeature.Index, undefined, createClassPrototype()), @@ -774,7 +820,7 @@ export class LuaTransformer { result.push(assignClassPrototypeIndex); } else { - // className.prototype.__index = className.prototype + // localClassName.prototype.__index = localClassName.prototype const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeIndex, createClassPrototype(), @@ -784,7 +830,7 @@ export class LuaTransformer { } if (statement.members.some(m => ts.isSetAccessor(m) && !tsHelper.isStatic(m))) { - // className.prototype.____setters = {} + // localClassName.prototype.____setters = {} const classPrototypeSetters = tstl.createTableIndexExpression( createClassPrototype(), tstl.createStringLiteral("____setters") @@ -798,7 +844,7 @@ export class LuaTransformer { } if (tsHelper.hasSetAccessorInClassOrAncestor(statement, false, this.checker)) { - // className.prototype.__newindex = __TS_NewIndex(className.prototype) + // localClassName.prototype.__newindex = __TS_NewIndex(localClassName.prototype) const classPrototypeNewIndex = tstl.createTableIndexExpression( createClassPrototype(), tstl.createStringLiteral("__newindex") @@ -811,14 +857,14 @@ export class LuaTransformer { result.push(assignClassPrototypeIndex); } - // className.prototype.constructor = className + // localClassName.prototype.constructor = localClassName const classPrototypeConstructor = tstl.createTableIndexExpression( createClassPrototype(), tstl.createStringLiteral("constructor") ); const assignClassPrototypeConstructor = tstl.createAssignmentStatement( classPrototypeConstructor, - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), statement ); result.push(assignClassPrototypeConstructor); @@ -832,18 +878,14 @@ export class LuaTransformer { throw TSTLErrors.UndefinedTypeNode(statement); } - const baseName = ts.isIdentifier(extendedTypeNode.expression) - ? this.transformIdentifier(extendedTypeNode.expression) // Skip adding '____exports' - : this.transformExpression(extendedTypeNode.expression); - - // className.____super = baseName + // localClassName.____super = extendsExpression const createClassBase = () => tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("____super") ); const assignClassBase = tstl.createAssignmentStatement( createClassBase(), - baseName, + this.transformExpression(extendedTypeNode.expression), extendedTypeNode.expression ); result.push(assignClassBase); @@ -860,7 +902,7 @@ export class LuaTransformer { ) ); } else { - // __index = className.____super + // __index = localClassName.____super metatableFields.push( tstl.createTableFieldExpression( createClassBase(), @@ -884,25 +926,25 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)], + [tstl.cloneIdentifier(localClassName), tstl.createTableExpression(metatableFields)], extendedTypeNode.expression ) ); result.push(setClassMetatable); } else { - // setmetatable(className, className.____super) + // setmetatable(localClassName, localClassName.____super) const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(className), createClassBase()], + [tstl.cloneIdentifier(localClassName), createClassBase()], extendedTypeNode.expression ) ); result.push(setClassMetatable); } - // setmetatable(className.prototype, className.____super.prototype) + // setmetatable(localClassName.prototype, localClassName.____super.prototype) const basePrototype = tstl.createTableIndexExpression( createClassBase(), tstl.createStringLiteral("prototype") @@ -943,7 +985,7 @@ export class LuaTransformer { const setClassMetatable = tstl.createExpressionStatement( tstl.createCallExpression( tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(className), tstl.createTableExpression(metatableFields)] + [tstl.cloneIdentifier(localClassName), tstl.createTableExpression(metatableFields)] ), statement ); @@ -952,7 +994,7 @@ export class LuaTransformer { const newFuncStatements: tstl.Statement[] = []; - // local self = setmetatable({}, className.prototype) + // local self = setmetatable({}, localClassName.prototype) const assignSelf = tstl.createVariableDeclarationStatement( this.createSelfIdentifier(), tstl.createCallExpression( @@ -976,11 +1018,11 @@ export class LuaTransformer { const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()]); newFuncStatements.push(returnSelf); - // function className.new(construct, ...) ... end - // or function export.className.new(construct, ...) ... end + // function localClassName.new(construct, ...) ... end + // or function export.localClassName.new(construct, ...) ... end const newFunc = tstl.createAssignmentStatement( tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), + tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("new")), tstl.createFunctionExpression( tstl.createBlock(newFuncStatements), @@ -1003,6 +1045,8 @@ export class LuaTransformer { const statements: tstl.Statement[] = []; for (const f of instanceFields) { + this.validateClassElement(f); + // Get identifier const fieldName = this.transformPropertyName(f.name); @@ -1146,6 +1190,8 @@ export class LuaTransformer { return undefined; } + this.validateClassElement(getAccessor); + const name = this.transformIdentifier(getAccessor.name as ts.Identifier); const [body] = this.transformFunctionBody(getAccessor.parameters, getAccessor.body); @@ -1182,6 +1228,8 @@ export class LuaTransformer { return undefined; } + this.validateClassElement(setAccessor); + const name = this.transformIdentifier(setAccessor.name as ts.Identifier); const [params, dot, restParam] = this.transformParameters(setAccessor.parameters, this.createSelfIdentifier()); @@ -1222,6 +1270,8 @@ export class LuaTransformer { return undefined; } + this.validateClassElement(node); + let methodName = this.transformPropertyName(node.name); if (tstl.isStringLiteral(methodName) && methodName.value === "toString") { methodName = tstl.createStringLiteral("__tostring", node.name); @@ -1394,10 +1444,9 @@ export class LuaTransformer { // The identifier of the new variable const variableName = this.transformIdentifier(element.name as ts.Identifier); // The field to extract - const propertyName = this.transformIdentifier( - (element.propertyName || element.name) as ts.Identifier); + const propertyName = this.transformPropertyName(element.propertyName || element.name); const expression = isObjectBindingPattern - ? tstl.createTableIndexExpression(tableExpression, tstl.createStringLiteral(propertyName.text)) + ? tstl.createTableIndexExpression(tableExpression, propertyName) : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); if (element.initializer) { @@ -1427,6 +1476,18 @@ export class LuaTransformer { return result; } + protected createModuleLocalNameIdentifier(declaration: ts.ModuleDeclaration): tstl.Identifier { + const moduleSymbol = this.checker.getSymbolAtLocation(declaration.name); + if (moduleSymbol !== undefined && this.isUnsafeName(moduleSymbol.name)) { + return tstl.createIdentifier( + this.createSafeName(declaration.name.text), + declaration.name, + moduleSymbol && this.symbolIds.get(moduleSymbol) + ); + } + return this.transformIdentifier(declaration.name as ts.Identifier); + } + public transformModuleDeclaration(statement: ts.ModuleDeclaration): StatementVisitResult { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); // If phantom namespace elide the declaration and return the body @@ -1447,14 +1508,17 @@ export class LuaTransformer { || (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 && statement === symbol.declarations.find(ts.isModuleDeclaration)); + const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); + if (isFirstDeclaration) { const isExported = (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; if (isExported && this.currentNamespace) { // outerNS.innerNS = {} const namespaceDeclaration = tstl.createAssignmentStatement( tstl.createTableIndexExpression( - this.transformIdentifier(this.currentNamespace.name as ts.Identifier), - tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text)), + this.createModuleLocalNameIdentifier(this.currentNamespace), + tstl.createStringLiteral(nameIdentifier.text) + ), tstl.createTableExpression() ); @@ -1463,10 +1527,12 @@ export class LuaTransformer { if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { // local innerNS = outerNS.innerNS const localDeclaration = this.createHoistableVariableDeclarationStatement( - statement.name as ts.Identifier, + this.createModuleLocalNameIdentifier(statement), tstl.createTableIndexExpression( - this.transformIdentifier(this.currentNamespace.name as ts.Identifier), - tstl.createStringLiteral(this.transformIdentifier(statement.name as ts.Identifier).text))); + this.createModuleLocalNameIdentifier(this.currentNamespace), + tstl.createStringLiteral(nameIdentifier.text) + ) + ); result.push(localDeclaration); } @@ -1474,7 +1540,7 @@ export class LuaTransformer { } else if (isExported && !this.currentNamespace && this.isModule) { // exports.NS = {} const namespaceDeclaration = tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier)), + this.createExportedIdentifier(nameIdentifier), tstl.createTableExpression() ); @@ -1483,8 +1549,9 @@ export class LuaTransformer { if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { // local NS = exports.NS const localDeclaration = this.createHoistableVariableDeclarationStatement( - statement.name as ts.Identifier, - this.createExportedIdentifier(this.transformIdentifier(statement.name as ts.Identifier))); + this.createModuleLocalNameIdentifier(statement), + this.createExportedIdentifier(tstl.cloneIdentifier(nameIdentifier, statement.name)) + ); result.push(localDeclaration); } @@ -1492,7 +1559,7 @@ export class LuaTransformer { } else { // local NS = {} const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( - this.transformIdentifier(statement.name as ts.Identifier), + this.createModuleLocalNameIdentifier(statement), tstl.createTableExpression() ); @@ -3335,18 +3402,25 @@ export class LuaTransformer { if (ts.isPropertyAssignment(element)) { const expression = this.transformExpression(element.initializer); properties.push(tstl.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { - let identifier = this.transformIdentifierExpression(element.name); - if (tstl.isIdentifier(identifier)) { - const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol !== undefined && this.isSymbolExported(valueSymbol)) { - identifier = this.createExportedIdentifier(identifier); - } + let identifier: tstl.Expression | undefined; + const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol !== undefined && this.symbolIds.has(valueSymbol)) { + // Ignore unknown symbols so things like NaN still get transformed properly + identifier = this.createIdentifierFromSymbol(valueSymbol, element.name); + } else { + identifier = this.transformIdentifierExpression(element.name); + } + if (tstl.isIdentifier(identifier) && valueSymbol !== undefined && this.isSymbolExported(valueSymbol)) { + identifier = this.createExportedIdentifier(identifier); } properties.push(tstl.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { const expression = this.transformFunctionExpression(element); properties.push(tstl.createTableFieldExpression(expression, name, element)); + } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); } @@ -4653,26 +4727,23 @@ export class LuaTransformer { } protected getIdentifierText(identifier: ts.Identifier): string { - const text = ts.idText(identifier); - - if (this.luaKeywords.has(text)) { - throw TSTLErrors.KeywordIdentifier(identifier); - } - - return text; + return ts.idText(identifier); } - public transformIdentifier(expression: ts.Identifier): tstl.Identifier { - if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + public transformIdentifier(identifier: ts.Identifier): tstl.Identifier { + if (identifier.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { return tstl.createIdentifier("nil"); // TODO this is a hack that allows use to keep Identifier // as return time as changing that would break a lot of stuff. // But this should be changed to return tstl.createNilLiteral() // at some point. } - const text = this.getIdentifierText(expression); - const symbolId = this.getIdentifierSymbolId(expression); - return tstl.createIdentifier(text, expression, symbolId); + const text = this.hasUnsafeIdentifierName(identifier) + ? this.createSafeName(this.getIdentifierText(identifier)) + : this.getIdentifierText(identifier); + + const symbolId = this.getIdentifierSymbolId(identifier); + return tstl.createIdentifier(text, identifier, symbolId); } private transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { @@ -4749,9 +4820,17 @@ export class LuaTransformer { } protected createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { - const exportTable = this.currentNamespace - ? this.transformIdentifier(this.currentNamespace.name as ts.Identifier) - : this.createExportsIdentifier(); + let exportTable: tstl.Identifier; + if (this.currentNamespace !== undefined) { + if (this.isUnsafeName(this.currentNamespace.name.text)) { + exportTable = this.createModuleLocalNameIdentifier(this.currentNamespace); + } else { + exportTable = this.transformIdentifier(this.currentNamespace.name as ts.Identifier); + } + + } else { + exportTable = this.createExportsIdentifier(); + } return tstl.createTableIndexExpression( exportTable, @@ -5139,16 +5218,50 @@ export class LuaTransformer { return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } + protected createIdentifierFromSymbol(symbol: ts.Symbol, tsOriginal?: ts.Node): tstl.Identifier { + const name = this.hasUnsafeSymbolName(symbol) + ? this.createSafeName(symbol.name) + : symbol.name; + return tstl.createIdentifier(name, tsOriginal, this.symbolIds.get(symbol)); + } + + protected isUnsafeName(name: string): boolean { + return this.luaKeywords.has(name) || !tsHelper.isValidLuaIdentifier(name); + } + + protected hasUnsafeSymbolName(symbol: ts.Symbol): boolean { + if (this.luaKeywords.has(symbol.name)) { + // lua keywords are only unsafe when non-ambient and not exported + const isNonAmbient = symbol.declarations.find(d => !tsHelper.isAmbient(d)) !== undefined; + return isNonAmbient && !this.isSymbolExported(symbol); + } + return this.isUnsafeName(symbol.name); + } + + protected hasUnsafeIdentifierName(identifier: ts.Identifier): boolean { + const symbol = this.checker.getSymbolAtLocation(identifier); + if (symbol !== undefined) { + return this.hasUnsafeSymbolName(symbol); + } + return false; + } + + protected createSafeName(name: string): string { + return "____" + tsHelper.fixInvalidLuaIdentifier(name); + } + protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { const symbol = this.checker.getSymbolAtLocation(identifier); - let symbolId: number | undefined; + let symbolId: tstl.SymbolId | undefined; if (symbol) { // Track first time symbols are seen if (!this.symbolIds.has(symbol)) { symbolId = this.genSymbolIdCounter++; + const symbolInfo: SymbolInfo = {symbol, firstSeenAtPos: identifier.pos}; this.symbolIds.set(symbol, symbolId); this.symbolInfo.set(symbolId, symbolInfo); + } else { symbolId = this.symbolIds.get(symbol); } @@ -5344,15 +5457,14 @@ export class LuaTransformer { } protected createHoistableVariableDeclarationStatement( - identifier: ts.Identifier, + identifier: tstl.Identifier, initializer?: tstl.Expression, tsOriginal?: ts.Node, parent?: tstl.Node ): tstl.AssignmentStatement | tstl.VariableDeclarationStatement { - const variable = this.transformIdentifier(identifier); - const declaration = tstl.createVariableDeclarationStatement(variable, initializer, tsOriginal, parent); - if (!this.options.noHoisting && variable.symbolId) { + const declaration = tstl.createVariableDeclarationStatement(identifier, initializer, tsOriginal, parent); + if (!this.options.noHoisting && identifier.symbolId) { const scope = this.peekScope(); if (scope === undefined) { throw TSTLErrors.UndefinedScope(); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index a42407c19..f532690be 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -650,6 +650,10 @@ export class TSHelper { return match !== undefined && match !== null && match[0] === str; } + public static fixInvalidLuaIdentifier(name: string): string { + return name.replace(/[^a-zA-Z0-9_]/g, c => `_${c.charCodeAt(0).toString(16).toUpperCase()}`); + } + // Checks that a name is valid for use in lua function declaration syntax: // 'foo.bar' => passes ('function foo.bar()' is valid) // 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index bc700088f..49f6420f8 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -78,8 +78,8 @@ export class TSTLErrors { public static InvalidThrowExpression = (node: ts.Node) => new TranspileError(`Invalid throw expression, only strings can be thrown.`, node); - public static KeywordIdentifier = (node: ts.Identifier) => - new TranspileError(`Cannot use Lua keyword ${node.escapedText} as identifier.`, node); + public static ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => + new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); public static MissingClassName = (node: ts.Node) => new TranspileError(`Class declarations must have a name.`, node); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 27e78d0c8..5a1e12df6 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -391,16 +391,16 @@ local TestClass = __TSTL_test.TestClass" `; exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` -"local __TSTL_kebab_module = require(\\"kebab-module\\") -local TestClass = __TSTL_kebab_module.TestClass -local __TSTL_dollar_module = require(\\"dollar$module\\") -local TestClass = __TSTL_dollar_module.TestClass -local __TSTL_singlequote_module = require(\\"singlequote'module\\") -local TestClass = __TSTL_singlequote_module.TestClass -local __TSTL_hash_module = require(\\"hash#module\\") -local TestClass = __TSTL_hash_module.TestClass -local __TSTL_space_module = require(\\"space module\\") -local TestClass = __TSTL_space_module.TestClass" +"local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") +local TestClass = __TSTL_kebab_2Dmodule.TestClass +local __TSTL_dollar_24module = require(\\"dollar$module\\") +local TestClass = __TSTL_dollar_24module.TestClass +local __TSTL_singlequote_27module = require(\\"singlequote'module\\") +local TestClass = __TSTL_singlequote_27module.TestClass +local __TSTL_hash_23module = require(\\"hash#module\\") +local TestClass = __TSTL_hash_23module.TestClass +local __TSTL_space_20module = require(\\"space module\\") +local TestClass = __TSTL_space_20module.TestClass" `; exports[`Transformation (modulesImportRenamed) 1`] = ` @@ -409,16 +409,16 @@ local RenamedClass = __TSTL_test.TestClass" `; exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` -"local __TSTL_kebab_module = require(\\"kebab-module\\") -local RenamedClass = __TSTL_kebab_module.TestClass -local __TSTL_dollar_module = require(\\"dollar$module\\") -local RenamedClass = __TSTL_dollar_module.TestClass -local __TSTL_singlequote_module = require(\\"singlequote'module\\") -local RenamedClass = __TSTL_singlequote_module.TestClass -local __TSTL_hash_module = require(\\"hash#module\\") -local RenamedClass = __TSTL_hash_module.TestClass -local __TSTL_space_module = require(\\"space module\\") -local RenamedClass = __TSTL_space_module.TestClass" +"local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") +local RenamedClass = __TSTL_kebab_2Dmodule.TestClass +local __TSTL_dollar_24module = require(\\"dollar$module\\") +local RenamedClass = __TSTL_dollar_24module.TestClass +local __TSTL_singlequote_27module = require(\\"singlequote'module\\") +local RenamedClass = __TSTL_singlequote_27module.TestClass +local __TSTL_hash_23module = require(\\"hash#module\\") +local RenamedClass = __TSTL_hash_23module.TestClass +local __TSTL_space_20module = require(\\"space module\\") +local RenamedClass = __TSTL_space_20module.TestClass" `; exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\")"`; diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index 4e47bd849..f7abcef6b 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -176,15 +176,6 @@ test("TupleReturn in expression", () => { expect(result).toBe("a3"); }); -test.each(["and", "local", "nil", "not", "or", "repeat", "then", "until"])( - "Keyword identifier error (%p)", - identifier => { - expect(() => util.transpileString(`const ${identifier} = 3;`)).toThrowExactError( - TSTLErrors.KeywordIdentifier(ts.createIdentifier(identifier)), - ); - }, -); - test("String table access", () => { const code = ` const dict : {[key:string]:any} = {}; diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 0ffc8421b..42b575064 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -823,3 +823,43 @@ test("Class field override in subclass with constructors", () => { return (new Foo()).field + (new Bar()).field;`; expect(util.transpileAndExecute(code)).toBe("foobar"); }); + +test("Class cannot have static new method", () => { + const code = ` + class Foo { + static new() {} + }`; + expect(() => util.transpileAndExecute(code)).toThrow( + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + ); +}); + +test("Class cannot have static new property", () => { + const code = ` + class Foo { + static new = "foobar"; + }`; + expect(() => util.transpileAndExecute(code)).toThrow( + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + ); +}); + +test("Class cannot have static new get accessor", () => { + const code = ` + class Foo { + static get new() { return "foobar" } + }`; + expect(() => util.transpileAndExecute(code)).toThrow( + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + ); +}); + +test("Class cannot have static new set accessor", () => { + const code = ` + class Foo { + static set new(value: string) {} + }`; + expect(() => util.transpileAndExecute(code)).toThrow( + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + ); +}); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts new file mode 100644 index 000000000..58ead74ff --- /dev/null +++ b/test/unit/identifiers.spec.ts @@ -0,0 +1,574 @@ +import * as util from "../util"; + +test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])("invalid lua identifier name (%p)", name => { + const code = ` + const ${name} = "foobar"; + return ${name};`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +describe("lua keyword as identifier doesn't interfere with lua's value", () => { + test("variable (nil)", () => { + const code = ` + const nil = "foobar"; + return \`\${undefined}|\${nil}\``; + + expect(util.transpileAndExecute(code)).toBe("nil|foobar"); + }); + + test("variable (and)", () => { + const code = ` + const and = "foobar"; + return true && and;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (elseif)", () => { + const code = ` + const elseif = "foobar"; + if (false) { + } else if (elseif) { + return elseif; + }`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (end)", () => { + const code = ` + const end = "foobar"; + { + return end; + }`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (local)", () => { + const code = ` + const local = "foobar"; + return local;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (not)", () => { + const code = ` + const not = "foobar"; + return (!false) && not;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (or)", () => { + const code = ` + const or = "foobar"; + return false || or;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (repeat)", () => { + const code = ` + const repeat = "foobar"; + do {} while (false); + return repeat;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (then)", () => { + const code = ` + const then = "foobar"; + if (then) { + return then; + }`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (until)", () => { + const code = ` + const until = "foobar"; + do {} while (false); + return until;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (goto)", () => { + const code = ` + const goto = "foobar"; + switch (goto) { + case goto: + return goto; + }`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (print)", () => { + const luaHeader = ` + local result = "" + print = function(s) + result = result .. s + end`; + + const tsHeader = ` + declare let result: string;`; + + const code = ` + const print = "foobar"; + console.log(print); + return result;`; + + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toBe("foobar"); + }); + + test("variable (type)", () => { + const code = ` + function type(this: void, a: unknown) { + return (typeof a) + "|foobar"; + } + return type(7);`; + + expect(util.transpileAndExecute(code)).toBe("number|foobar"); + }); + + test("variable (error)", () => { + const code = ` + const error = "foobar"; + throw error;`; + + expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: .+ foobar$/); + }); + + test("variable (assert)", () => { + const code = ` + const assert = false; + console.assert(assert, "foobar");`; + + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow( + /^LUA ERROR: .+ foobar$/, + ); + }); + + test("variable (debug)", () => { + const luaHeader = ` + local result = "" + print = function(s) + result = result .. s + end`; + + const tsHeader = ` + declare let result: string;`; + + const code = ` + const debug = "foobar"; + console.trace(debug); + return result;`; + + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toMatch( + /^foobar\nstack traceback.+/, + ); + }); + + test("variable (string)", () => { + const code = ` + const string = "foobar"; + return string[0];`; + + expect(util.transpileAndExecute(code)).toBe("f"); + }); + + test("variable (math)", () => { + const code = ` + const math = -17; + return Math.abs(math);`; + + expect(util.transpileAndExecute(code)).toBe(17); + }); + + test("variable (table)", () => { + const code = ` + const table = ["foobar"]; + return table.pop();`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (coroutine)", () => { + const code = ` + const coroutine = "foobar"; + function *foo() { yield coroutine; } + return foo().next().value;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (pairs)", () => { + const code = ` + const pairs = {foobar: "foobar"}; + let result = ""; + for (const key in pairs) { + result += key; + } + return result;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (pcall)", () => { + const code = ` + const pcall = "foobar"; + try {} finally {} + return pcall;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (rawget)", () => { + const code = ` + const rawget = {foobar: "foobar"}; + return rawget.hasOwnProperty("foobar");`; + + expect(util.transpileAndExecute(code)).toBe(true); + }); + + test("variable (rawset)", () => { + const code = ` + const rawset = "foobar"; + class A { + prop = "prop"; + } + class B extends A { + get prop() { return rawset; } + } + const b = new B(); + return b.prop;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }); + + test("variable (require)", () => { + const code = ` + const require = "foobar"; + export { foo } from "someModule"; + export const result = require;`; + + const lua = ` + package.loaded.someModule = {foo = "bar"} + return (function() + ${util.transpileString(code, undefined, true)} + end)().result`; + + expect(util.executeLua(lua)).toBe("foobar"); + }); + + test("variable (tostring)", () => { + const code = ` + const tostring = 17; + return tostring.toString();`; + + expect(util.transpileAndExecute(code)).toBe(17); + }); + + test("variable (unpack)", () => { + const code = ` + const unpack = ["foo", "bar"]; + const [foo, bar] = unpack;`; + + const lua = ` + unpack = table.unpack + ${util.transpileString(code, undefined, false)} + return foo .. bar`; + + expect(util.executeLua(lua)).toBe("foobar"); + }); + + test("variable (_G)", () => { + const tsHeader = ` + var foobar = "foo";`; + + const code = ` + const _G = "bar"; + function foo(this: any) { + return this.foobar + _G; + } + return foo();`; + + expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("foobar"); + }); + + test("function parameter", () => { + const code = ` + function foo(type: unknown) { + return \`\${typeof type}|\${type}\`; + } + return foo("foobar");`; + + expect(util.transpileAndExecute(code)).toBe("string|foobar"); + }); + + test("destructured property function parameter", () => { + const code = ` + function foo({type}: any) { + return \`\${typeof type}|\${type}\`; + } + return foo({type: "foobar"});`; + + expect(util.transpileAndExecute(code)).toBe("string|foobar"); + }); + + test("destructured array element function parameter", () => { + const code = ` + function foo([type]: any) { + return \`\${typeof type}|\${type}\`; + } + return foo(["foobar"]);`; + + expect(util.transpileAndExecute(code)).toBe("string|foobar"); + }); + + test("property", () => { + const code = ` + const type = "foobar"; + const foo = { type: type }; + return type + "|" + foo.type + "|" + typeof type;`; + + expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + }); + + test("shorthand property", () => { + const code = ` + const type = "foobar"; + const foo = { type }; + return type + "|" + foo.type + "|" + typeof type;`; + + expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + }); + + test("destructured property", () => { + const code = ` + const foo = { type: "foobar" }; + const { type: type } = foo; + return type + "|" + foo.type + "|" + typeof type;`; + + expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + }); + + test("destructured shorthand property", () => { + const code = ` + const foo = { type: "foobar" }; + const { type } = foo; + return type + "|" + foo.type + "|" + typeof type;`; + + expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + }); + + test("destructured array element", () => { + const code = ` + const foo = ["foobar"]; + const [type] = foo; + return type + "|" + typeof type;`; + + expect(util.transpileAndExecute(code)).toBe("foobar|string"); + }); + + test.each(["type", "type as type"])("imported variable (%p)", importName => { + const luaHeader = ` + package.loaded.someModule = {type = "foobar"}`; + + const code = ` + import {${importName}} from "someModule"; + return typeof 7 + "|" + type;`; + + const lua = util.transpileString(code); + + expect(util.executeLua(`${luaHeader} ${lua}`)).toBe("number|foobar"); + }); + + test.each([ + { returnExport: "type", expectResult: "foobar" }, + { returnExport: "mytype", expectResult: "foobar" }, + { returnExport: "result", expectResult: "string|foobar" }, + ])("separately exported variable (%p)", ({ returnExport, expectResult }) => { + const code = ` + const type = "foobar"; + export { type } + export { type as mytype } + export const result = typeof type + "|" + type;`; + + expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + }); + + test.each(["type", "type as type"])( + "re-exported variable with lua keyword as name (%p)", + importName => { + const code = ` + export { ${importName} } from "someModule"`; + + const lua = ` + package.loaded.someModule = {type = "foobar"} + return (function() + ${util.transpileString(code)} + end)().type`; + + expect(util.executeLua(lua)).toBe("foobar"); + }, + ); + + test("class", () => { + const code = ` + class type { + method() { return typeof 0; } + static staticMethod() { return typeof "foo"; } + } + const t = new type(); + return t.method() + "|" + type.staticMethod();`; + + expect(util.transpileAndExecute(code)).toBe("number|string"); + }); + + test("subclass of class", () => { + const code = ` + class type { + method() { return typeof 0; } + static staticMethod() { return typeof "foo"; } + } + class Foo extends type {} + const foo = new Foo(); + return foo.method() + "|" + Foo.staticMethod();`; + + expect(util.transpileAndExecute(code)).toBe("number|string"); + }); + + test.each([ + { returnExport: "result", expectResult: "number|string" }, + { returnExport: "type ~= nil", expectResult: true }, + ])("exported class (%p)", ({ returnExport, expectResult }) => { + const code = ` + export class type { + method() { return typeof 0; } + static staticMethod() { return typeof "foo"; } + } + const t = new type(); + export const result = t.method() + "|" + type.staticMethod();`; + + expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + }); + + test.each([ + { returnExport: "result", expectResult: "number|string" }, + { returnExport: "type ~= nil", expectResult: true }, + ])("subclass of exported class (%p)", ({ returnExport, expectResult }) => { + const code = ` + export class type { + method() { return typeof 0; } + static staticMethod() { return typeof "foo"; } + } + class Foo extends type {} + const foo = new Foo(); + export const result = foo.method() + "|" + Foo.staticMethod();`; + + expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + }); + + test("namespace", () => { + const tsHeader = ` + namespace type { + export const foo = "foobar"; + }`; + + const code = ` + return typeof type.foo + "|" + type.foo`; + + expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe( + "string|foobar", + ); + }); + + test.each([ + { returnExport: "result", expectResult: "string|foobar" }, + { returnExport: "type ~= nil", expectResult: true }, + ])("exported namespace (%p)", ({ returnExport, expectResult }) => { + const code = ` + export namespace type { + export const foo = "foobar"; + } + export const result = typeof type.foo + "|" + type.foo;`; + + expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + }); + + test("merged namespace", () => { + const tsHeader = ` + class type { + method() { return typeof 0; } + static staticMethod() { return typeof true; } + } + + namespace type { + export const foo = "foo"; + } + + namespace type { + export const bar = "bar"; + }`; + + const code = ` + const t = new type(); + return \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; + + expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe( + "number|boolean|string|foo|bar", + ); + }); + + test.each([ + { returnExport: "result", expectResult: "number|boolean|string|foo|bar" }, + { returnExport: "type ~= nil", expectResult: true }, + ])("exported merged namespace (%p)", ({ returnExport, expectResult }) => { + const code = ` + export class type { + method() { return typeof 0; } + static staticMethod() { return typeof true; } + } + + export namespace type { + export const foo = "foo"; + } + + export namespace type { + export const bar = "bar"; + } + + const t = new type(); + export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; + + expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + }); +}); + +test("declaration-only variable with lua keyword as name is not renamed", () => { + const code = ` + declare function type(this: void, a: unknown): string; + type(7);`; + + expect(util.transpileString(code, undefined, false)).toBe("type(7)"); +}); + +test("exported variable with lua keyword as name is not renamed", () => { + const code = ` + export const print = "foobar";`; + + expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); +}); diff --git a/test/unit/importexport.spec.ts b/test/unit/importexport.spec.ts index cd98b0b4f..ee50cb4e0 100644 --- a/test/unit/importexport.spec.ts +++ b/test/unit/importexport.spec.ts @@ -10,3 +10,18 @@ test.each([ TSTLErrors.UnsupportedDefaultExport(util.nodeStub), ); }); + +test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( + "Import module names with invalid lua identifier characters (%p)", + name => { + const code = ` + import { foo } from "${name}";`; + + const lua = ` + setmetatable(package.loaded, {__index = function() return {foo = "bar"} end}) + ${util.transpileString(code)} + return foo;`; + + expect(util.executeLua(lua)).toBe("bar"); + }, +); From 84bcf7b124e1f5e675d524a4666e640cf531919b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 May 2019 19:38:26 +0200 Subject: [PATCH 087/764] Removed unused variable that was failing the build --- src/TSHelper.ts | 2 +- test/unit/assignments/assignments.spec.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index f532690be..8764f500f 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -488,7 +488,7 @@ export class TSHelper { return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); } - public static getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { + public static getAllCallSignatures(type: ts.Type): ReadonlyArray { if (type.isUnion()) { return type.types.map(t => TSHelper.getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); } diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index f7abcef6b..b6fd9350d 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -1,4 +1,3 @@ -import * as ts from "typescript"; import { TSTLErrors } from "../../../src/TSTLErrors"; import * as util from "../../util"; From 3d5540d82debbe635cb2073d28abed0db227c57c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 May 2019 20:28:08 +0200 Subject: [PATCH 088/764] 0.20.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 36d02357f..a7dbc4de9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.19.0", + "version": "0.20.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index aabe0e00d..8bceba6b6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.19.0", + "version": "0.20.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 026317c55f3c1683bf93b455a51d99ad3112bebb Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 19 May 2019 20:32:09 +0200 Subject: [PATCH 089/764] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb28c173..72034d078 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 0.20.0 +- Added support for `string.repeat`, `string.padStart` and `string.padEnd`. +- Added automatic variable renaming for invalid Lua identifiers. +- Fixed `/** @tupleReturn */` not working for function types (i.e `myFunc: () => [number, number]`) +- Various improvements to source map output format. +- Various small code tweaks and improvements. + +## 0.19.0 - **BREAKING CHANGE:** All tstl-specific options should now be inside the "tstl" section in tsconfig.json (see README.md). **Root-level options are no longer supported**. - Added a compiler API to programmatically invoke TypeScriptToLua, and to modify or extend the default transpiler. More info on the [Compiler API wiki page](). - Added support for [class decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators). From 97fa41e8ea1daafa556429d151e8b42ca6daa1ba Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 22 May 2019 13:23:04 +0500 Subject: [PATCH 090/764] Add module import/export elision (#565) * Add module import/export elision * Reference imported values in tests to avoid elision * Remove TODO comment --- src/LuaTransformer.ts | 106 +++++++++++------- .../__snapshots__/transformation.spec.ts.snap | 41 ++++--- .../transformation/modulesImportAll.ts | 2 + .../transformation/modulesImportNamed.ts | 2 + .../modulesImportNamedSpecialChars.ts | 16 ++- .../transformation/modulesImportRenamed.ts | 2 + .../modulesImportRenamedSpecialChars.ts | 16 ++- test/unit/identifiers.spec.ts | 8 +- test/unit/importexport.spec.ts | 27 ----- test/unit/modules.spec.ts | 79 +++++++++++++ test/unit/require.spec.ts | 4 +- test/unit/sourcemaps.spec.ts | 2 + 12 files changed, 211 insertions(+), 94 deletions(-) delete mode 100644 test/unit/importexport.spec.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 1ec5009d6..5a7d14fc7 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -38,6 +38,16 @@ interface Scope { loopContinued?: boolean; } +export interface EmitResolver { + isValueAliasDeclaration(node: ts.Node): boolean; + isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; + moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; +} + +export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { + getEmitResolver(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): EmitResolver; +} + export class LuaTransformer { public luaKeywords: Set = new Set([ "_G", "and", "assert", "break", "coroutine", "debug", "do", "else", "elseif", "end", "error", "false", "for", @@ -49,11 +59,13 @@ export class LuaTransformer { private isStrict: boolean; private luaTarget: LuaTarget; - private checker: ts.TypeChecker; + private checker: DiagnosticsProducingTypeChecker; protected options: CompilerOptions; - private isModule = false; + // Resolver is lazy-initialized in transformSourceFile to avoid type-checking all files + private resolver!: EmitResolver; + private isModule = false; private currentSourceFile?: ts.SourceFile; private currentNamespace: ts.ModuleDeclaration | undefined; @@ -72,7 +84,7 @@ export class LuaTransformer { private readonly typeValidationCache: Map> = new Map>(); public constructor(protected program: ts.Program) { - this.checker = program.getTypeChecker(); + this.checker = (program as any).getDiagnosticsProducingTypeChecker(); this.options = program.getCompilerOptions(); this.isStrict = this.options.alwaysStrict !== undefined || (this.options.strict !== undefined && this.options.alwaysStrict !== false) @@ -102,6 +114,7 @@ export class LuaTransformer { this.setupState(); this.currentSourceFile = node; + this.resolver = this.checker.getEmitResolver(node); let statements: tstl.Statement[] = []; if (node.flags & ts.NodeFlags.JsonFile) { @@ -233,36 +246,6 @@ export class LuaTransformer { } public transformExportDeclaration(statement: ts.ExportDeclaration): StatementVisitResult { - if (statement.moduleSpecifier === undefined) { - if (statement.exportClause === undefined) { - throw TSTLErrors.InvalidExportDeclaration(statement); - } - - const result = []; - for (const exportElement of statement.exportClause.elements) { - let exportedIdentifier: tstl.Expression | undefined; - if (exportElement.propertyName !== undefined) { - exportedIdentifier = this.transformIdentifier(exportElement.propertyName); - - } else { - const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(exportElement); - if (exportedSymbol !== undefined) { - exportedIdentifier = this.createIdentifierFromSymbol(exportedSymbol, exportElement.name); - } else { - exportedIdentifier = this.transformIdentifier(exportElement.name); - } - } - - result.push( - tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(exportElement.name)), - exportedIdentifier - ) - ); - } - return result; - } - if (statement.exportClause) { if (statement.exportClause.elements.some(e => (e.name !== undefined && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) @@ -272,11 +255,40 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedDefaultExport(statement); } + if (!this.resolver.isValueAliasDeclaration(statement)) { + return undefined; + } + + const exportSpecifiers = statement.exportClause.elements.filter(e => + this.resolver.isValueAliasDeclaration(e) + ); + + if (statement.moduleSpecifier === undefined) { + return exportSpecifiers.map(specifier => { + let exportedIdentifier: tstl.Expression | undefined; + if (specifier.propertyName !== undefined) { + exportedIdentifier = this.transformIdentifier(specifier.propertyName); + } else { + const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(specifier); + if (exportedSymbol !== undefined) { + exportedIdentifier = this.createIdentifierFromSymbol(exportedSymbol, specifier.name); + } else { + exportedIdentifier = this.transformIdentifier(specifier.name); + } + } + + return tstl.createAssignmentStatement( + this.createExportedIdentifier(this.transformIdentifier(specifier.name)), + exportedIdentifier + ); + }); + } + // First transpile as import clause const importClause = ts.createImportClause( undefined, - ts.createNamedImports(statement.exportClause.elements - .map(e => ts.createImportSpecifier(e.propertyName, e.name)) + ts.createNamedImports( + exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name)) ) ); @@ -292,11 +304,11 @@ export class LuaTransformer { const result = this.transformBlock(block).statements; // Now the module is imported, add the imports to the export table - for (const exportVariable of statement.exportClause.elements) { + for (const specifier of exportSpecifiers) { result.push( tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(exportVariable.name)), - this.transformIdentifier(exportVariable.name) + this.createExportedIdentifier(this.transformIdentifier(specifier.name)), + this.transformIdentifier(specifier.name) ) ); } @@ -304,6 +316,14 @@ export class LuaTransformer { // Wrap this in a DoStatement to prevent polluting the scope. return tstl.createDoStatement(this.filterUndefined(result), statement); } else { + if (statement.moduleSpecifier === undefined) { + throw TSTLErrors.InvalidExportDeclaration(statement); + } + + if (!this.resolver.moduleExportsSomeValue(statement.moduleSpecifier)) { + return undefined; + } + const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); const tempModuleIdentifier = tstl.createIdentifier("__TSTL_export"); @@ -375,7 +395,11 @@ export class LuaTransformer { if (ts.isNamedImports(imports)) { const filteredElements = imports.elements.filter(e => { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); - return !decorators.has(DecoratorKind.Extension) && !decorators.has(DecoratorKind.MetaExtension); + return ( + this.resolver.isReferencedAliasDeclaration(e) + && !decorators.has(DecoratorKind.Extension) + && !decorators.has(DecoratorKind.MetaExtension) + ); }); // Elide import if all imported types are extension classes @@ -418,6 +442,10 @@ export class LuaTransformer { } } else if (ts.isNamespaceImport(imports)) { + if (!this.resolver.isReferencedAliasDeclaration(imports)) { + return undefined; + } + const requireStatement = tstl.createVariableDeclarationStatement( this.transformIdentifier(imports.name), requireCall, diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 5a1e12df6..09544594d 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -383,42 +383,57 @@ exports[`Transformation (modulesFunctionNoExport) 1`] = ` end" `; -exports[`Transformation (modulesImportAll) 1`] = `"local Test = require(\\"test\\")"`; +exports[`Transformation (modulesImportAll) 1`] = ` +"local Test = require(\\"test\\") +local ____ = Test" +`; exports[`Transformation (modulesImportNamed) 1`] = ` "local __TSTL_test = require(\\"test\\") -local TestClass = __TSTL_test.TestClass" +local TestClass = __TSTL_test.TestClass +local ____ = TestClass" `; exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` "local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") -local TestClass = __TSTL_kebab_2Dmodule.TestClass +local TestClass1 = __TSTL_kebab_2Dmodule.TestClass1 local __TSTL_dollar_24module = require(\\"dollar$module\\") -local TestClass = __TSTL_dollar_24module.TestClass +local TestClass2 = __TSTL_dollar_24module.TestClass2 local __TSTL_singlequote_27module = require(\\"singlequote'module\\") -local TestClass = __TSTL_singlequote_27module.TestClass +local TestClass3 = __TSTL_singlequote_27module.TestClass3 local __TSTL_hash_23module = require(\\"hash#module\\") -local TestClass = __TSTL_hash_23module.TestClass +local TestClass4 = __TSTL_hash_23module.TestClass4 local __TSTL_space_20module = require(\\"space module\\") -local TestClass = __TSTL_space_20module.TestClass" +local TestClass5 = __TSTL_space_20module.TestClass5 +local ____ = TestClass1 +local ____ = TestClass2 +local ____ = TestClass3 +local ____ = TestClass4 +local ____ = TestClass5" `; exports[`Transformation (modulesImportRenamed) 1`] = ` "local __TSTL_test = require(\\"test\\") -local RenamedClass = __TSTL_test.TestClass" +local RenamedClass = __TSTL_test.TestClass +local ____ = RenamedClass" `; exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` "local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") -local RenamedClass = __TSTL_kebab_2Dmodule.TestClass +local RenamedClass1 = __TSTL_kebab_2Dmodule.TestClass local __TSTL_dollar_24module = require(\\"dollar$module\\") -local RenamedClass = __TSTL_dollar_24module.TestClass +local RenamedClass2 = __TSTL_dollar_24module.TestClass local __TSTL_singlequote_27module = require(\\"singlequote'module\\") -local RenamedClass = __TSTL_singlequote_27module.TestClass +local RenamedClass3 = __TSTL_singlequote_27module.TestClass local __TSTL_hash_23module = require(\\"hash#module\\") -local RenamedClass = __TSTL_hash_23module.TestClass +local RenamedClass4 = __TSTL_hash_23module.TestClass local __TSTL_space_20module = require(\\"space module\\") -local RenamedClass = __TSTL_space_20module.TestClass" +local RenamedClass5 = __TSTL_space_20module.TestClass +local ____ = RenamedClass1 +local ____ = RenamedClass2 +local ____ = RenamedClass3 +local ____ = RenamedClass4 +local ____ = RenamedClass5" `; exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\")"`; diff --git a/test/translation/transformation/modulesImportAll.ts b/test/translation/transformation/modulesImportAll.ts index b452afb73..28b470640 100644 --- a/test/translation/transformation/modulesImportAll.ts +++ b/test/translation/transformation/modulesImportAll.ts @@ -1 +1,3 @@ import * as Test from "test"; + +Test; diff --git a/test/translation/transformation/modulesImportNamed.ts b/test/translation/transformation/modulesImportNamed.ts index b4c16e54b..d147081ff 100644 --- a/test/translation/transformation/modulesImportNamed.ts +++ b/test/translation/transformation/modulesImportNamed.ts @@ -1 +1,3 @@ import { TestClass } from "test"; + +TestClass; diff --git a/test/translation/transformation/modulesImportNamedSpecialChars.ts b/test/translation/transformation/modulesImportNamedSpecialChars.ts index 7237d70a2..dbb54990c 100644 --- a/test/translation/transformation/modulesImportNamedSpecialChars.ts +++ b/test/translation/transformation/modulesImportNamedSpecialChars.ts @@ -1,5 +1,11 @@ -import { TestClass } from "kebab-module"; -import { TestClass } from "dollar$module"; -import { TestClass } from "singlequote'module"; -import { TestClass } from "hash#module"; -import { TestClass } from "space module"; +import { TestClass1 } from "kebab-module"; +import { TestClass2 } from "dollar$module"; +import { TestClass3 } from "singlequote'module"; +import { TestClass4 } from "hash#module"; +import { TestClass5 } from "space module"; + +TestClass1; +TestClass2; +TestClass3; +TestClass4; +TestClass5; diff --git a/test/translation/transformation/modulesImportRenamed.ts b/test/translation/transformation/modulesImportRenamed.ts index 42129a291..74c82598b 100644 --- a/test/translation/transformation/modulesImportRenamed.ts +++ b/test/translation/transformation/modulesImportRenamed.ts @@ -1 +1,3 @@ import { TestClass as RenamedClass } from "test"; + +RenamedClass; diff --git a/test/translation/transformation/modulesImportRenamedSpecialChars.ts b/test/translation/transformation/modulesImportRenamedSpecialChars.ts index 59e7ed862..a200c07e9 100644 --- a/test/translation/transformation/modulesImportRenamedSpecialChars.ts +++ b/test/translation/transformation/modulesImportRenamedSpecialChars.ts @@ -1,5 +1,11 @@ -import { TestClass as RenamedClass } from "kebab-module"; -import { TestClass as RenamedClass } from "dollar$module"; -import { TestClass as RenamedClass } from "singlequote'module"; -import { TestClass as RenamedClass } from "hash#module"; -import { TestClass as RenamedClass } from "space module"; +import { TestClass as RenamedClass1 } from "kebab-module"; +import { TestClass as RenamedClass2 } from "dollar$module"; +import { TestClass as RenamedClass3 } from "singlequote'module"; +import { TestClass as RenamedClass4 } from "hash#module"; +import { TestClass as RenamedClass5 } from "space module"; + +RenamedClass1; +RenamedClass2; +RenamedClass3; +RenamedClass4; +RenamedClass5; diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 58ead74ff..20a889a34 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -388,12 +388,14 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { package.loaded.someModule = {type = "foobar"}`; const code = ` - import {${importName}} from "someModule"; - return typeof 7 + "|" + type;`; + import {${importName}} from "someModule"; + export const result = typeof 7 + "|" + type; + `; const lua = util.transpileString(code); + const result = util.executeLua(`${luaHeader} return (function() ${lua} end)().result`); - expect(util.executeLua(`${luaHeader} ${lua}`)).toBe("number|foobar"); + expect(result).toBe("number|foobar"); }); test.each([ diff --git a/test/unit/importexport.spec.ts b/test/unit/importexport.spec.ts deleted file mode 100644 index ee50cb4e0..000000000 --- a/test/unit/importexport.spec.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; -import * as util from "../util"; - -test.each([ - "export { default } from '...'", - "export { x as default } from '...';", - "export { default as x } from '...';", -])("Export default keyword disallowed (%p)", exportStatement => { - expect(() => util.transpileString(exportStatement)).toThrowExactError( - TSTLErrors.UnsupportedDefaultExport(util.nodeStub), - ); -}); - -test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( - "Import module names with invalid lua identifier characters (%p)", - name => { - const code = ` - import { foo } from "${name}";`; - - const lua = ` - setmetatable(package.loaded, {__index = function() return {foo = "bar"} end}) - ${util.transpileString(code)} - return foo;`; - - expect(util.executeLua(lua)).toBe("bar"); - }, -); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index ba9d7ce55..3869beadd 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -2,6 +2,85 @@ import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; +describe("module import/export elision", () => { + const moduleDeclaration = ` + declare module "module" { + export type Type = string; + export declare const value: string; + } + `; + + const expectToElideImport = (code: string) => { + const lua = util.transpileString( + { "module.d.ts": moduleDeclaration, "main.ts": code }, + undefined, + false, + ); + + expect(() => util.executeLua(lua)).not.toThrow(); + }; + + test("should elide named type imports", () => { + expectToElideImport(` + import { Type } from "module"; + const foo: Type = "bar"; + `); + }); + + test("should elide named value imports used only as a type", () => { + expectToElideImport(` + import { value } from "module"; + const foo: typeof value = "bar"; + `); + }); + + test("should elide namespace imports with unused values", () => { + expectToElideImport(` + import * as module from "module"; + const foo: module.Type = "bar"; + `); + }); + + test("should elide type exports", () => { + const code = ` + declare const _G: any; + + _G.foo = true; + type foo = boolean; + export { foo }; + `; + + expect(util.transpileExecuteAndReturnExport(code, "foo")).toBeUndefined(); + }); +}); + +test.each([ + "export { default } from '...'", + "export { x as default } from '...';", + "export { default as x } from '...';", +])("Export default keyword disallowed (%p)", exportStatement => { + expect(() => util.transpileString(exportStatement)).toThrowExactError( + TSTLErrors.UnsupportedDefaultExport(util.nodeStub), + ); +}); + +test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( + "Import module names with invalid lua identifier characters (%p)", + name => { + const code = ` + import { foo } from "${name}"; + foo; + `; + + const lua = ` + setmetatable(package.loaded, {__index = function() return {foo = "bar"} end}) + ${util.transpileString(code)} + return foo;`; + + expect(util.executeLua(lua)).toBe("bar"); + }, +); + test("defaultImport", () => { expect(() => { util.transpileString(`import TestClass from "test"`); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index f8d6d9a4f..183bac892 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -74,7 +74,7 @@ test.each([ ])( "require paths root from --baseUrl or --rootDir (%p)", ({ filePath, usedPath, expectedPath, options, throwsError }) => { - const input = { [filePath]: `import * from "${usedPath}";` }; + const input = { [filePath]: `import * as module from "${usedPath}"; module;` }; if (throwsError) { expect(() => util.transpileString(input, options)).toThrow(); } else { @@ -96,7 +96,7 @@ test.each([ "noResolution on ambient modules causes no path alterations (%p)", ({ comment, expectedPath }) => { const lua = util.transpileString({ - "src/main.ts": `import * as fake from "fake";`, + "src/main.ts": `import * as fake from "fake"; fake;`, "module.d.ts": `${comment} declare module "fake" {}`, }); const regex = /require\("(.*?)"\)/; diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index f4bda8503..5225ab6b2 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -48,6 +48,7 @@ test.each([ { typeScriptSource: ` import {Foo} from "foo"; + Foo; `, assertPatterns: [ @@ -58,6 +59,7 @@ test.each([ { typeScriptSource: ` import * as Foo from "foo"; + Foo; `, assertPatterns: [ From 3d632777522c46da51675fbca57fbe84424a1a56 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 23 May 2019 13:21:45 -0600 Subject: [PATCH 091/764] fixed default binding pattern parameters (#589) * fixed default binding pattern parameters fixes #530 * refactored default and binding paramaters to work in one pass --- src/LuaTransformer.ts | 57 +++++++++++++++++++++++-------------- test/unit/functions.spec.ts | 35 +++++++++++++++++++++++ 2 files changed, 71 insertions(+), 21 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 5a7d14fc7..dcce7663e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1381,12 +1381,34 @@ export class LuaTransformer { const headerStatements = []; - // Add default parameters - const defaultValueDeclarations = parameters - .filter(declaration => declaration.initializer !== undefined) - .map(declaration => this.transformParameterDefaultValueDeclaration(declaration)); + // Add default parameters and object binding patterns + const bindingPatternDeclarations: tstl.Statement[] = []; + let bindPatternIndex = 0; + for (const declaration of parameters) { + if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) { + const identifier = tstl.createIdentifier(`____TS_bindingPattern${bindPatternIndex++}`); + if (declaration.initializer !== undefined) { + // Default binding parameter + headerStatements.push( + this.transformParameterDefaultValueDeclaration(identifier, declaration.initializer) + ); + } + + // Binding pattern + bindingPatternDeclarations.push(...this.statementVisitResultToArray( + this.transformBindingPattern(declaration.name, identifier) + )); - headerStatements.push(...defaultValueDeclarations); + } else if (declaration.initializer !== undefined) { + // Default parameter + headerStatements.push( + this.transformParameterDefaultValueDeclaration( + this.transformIdentifier(declaration.name), + declaration.initializer + ) + ); + } + } // Push spread operator here if (spreadIdentifier) { @@ -1394,18 +1416,7 @@ export class LuaTransformer { headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } - // Add object binding patterns - let identifierIndex = 0; - const bindingPatternDeclarations: tstl.Statement[] = []; - parameters.forEach(binding => { - if (ts.isObjectBindingPattern(binding.name) || ts.isArrayBindingPattern(binding.name)) { - const identifier = tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`); - bindingPatternDeclarations.push(...this.statementVisitResultToArray( - this.transformBindingPattern(binding.name, identifier) - )); - } - }); - + // Binding pattern statements need to be after spread table is declared headerStatements.push(...bindingPatternDeclarations); const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); @@ -1415,9 +1426,13 @@ export class LuaTransformer { return [headerStatements.concat(bodyStatements), scope]; } - private transformParameterDefaultValueDeclaration(declaration: ts.ParameterDeclaration): tstl.Statement { - const parameterName = this.transformIdentifier(declaration.name as ts.Identifier); - const parameterValue = declaration.initializer ? this.transformExpression(declaration.initializer) : undefined; + private transformParameterDefaultValueDeclaration( + parameterName: tstl.Identifier, + value?: ts.Expression, + tsOriginal?: ts.Node + ): tstl.Statement + { + const parameterValue = value ? this.transformExpression(value) : undefined; const assignment = tstl.createAssignmentStatement(parameterName, parameterValue); const nilCondition = tstl.createBinaryExpression( @@ -1428,7 +1443,7 @@ export class LuaTransformer { const ifBlock = tstl.createBlock([assignment]); - return tstl.createIfStatement(nilCondition, ifBlock, undefined, declaration); + return tstl.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); } public transformBindingPattern( diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index d36dddcdf..98aa48ca4 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -94,6 +94,41 @@ test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])( }, ); +test("Function default array binding parameter", () => { + const code = ` + function foo([bar]: [string] = ["foobar"]) { + return bar; + } + return foo();`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("Function default object binding parameter", () => { + const code = ` + function foo({ bar }: { bar: string } = { bar: "foobar" }) { + return bar; + } + return foo();`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("Function default binding parameter maintains order", () => { + const code = ` + const resultsA = [{x: "foo"}, {x: "baz"}]; + const resultsB = ["blah", "bar"]; + let i = 0; + function a() { return resultsA[i++]; } + function b() { return resultsB[i++]; } + function foo({ x }: { x: string } = a(), y = b()) { + return x + y; + } + return foo();`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + test("Class method call", () => { const returnValue = 4; const source = `class TestClass { From 3d7833ebf98ac12150ed28644275c16a10fe1021 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 24 May 2019 13:06:34 -0600 Subject: [PATCH 092/764] fixed usage of lua keywords as property names (#586) * fixed usage of lua keywords as property names * fixed method calls that use lua keywords or invalid lua names * using transformElementCall for property calls with unsafe names * addressing feedback - not using element call for methods with lua builtin names - fixed shorthand assignment of declared lua builtins - banned lua keywords as identifier names in declare statements * Catching use of lua keywords as ambient identifiers * fixed outdated comment * removed lua keyword identifier check from declare statements --- src/LuaKeywords.ts | 9 ++++ src/LuaPrinter.ts | 11 ++++- src/LuaTransformer.ts | 49 +++++++++++--------- src/TSTLErrors.ts | 9 +++- test/unit/identifiers.spec.ts | 80 +++++++++++++++++++++++++++++++++ test/unit/objectLiteral.spec.ts | 11 +++++ 6 files changed, 146 insertions(+), 23 deletions(-) create mode 100644 src/LuaKeywords.ts diff --git a/src/LuaKeywords.ts b/src/LuaKeywords.ts new file mode 100644 index 000000000..6f3bff133 --- /dev/null +++ b/src/LuaKeywords.ts @@ -0,0 +1,9 @@ +export const luaKeywords: Set = new Set([ + "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", + "not", "or", "repeat", "return", "then", "until", "while", +]); + +export const luaBuiltins: Set = new Set([ + "_G", "assert", "coroutine", "debug", "error", "ipairs", "math", "pairs", "pcall", "print", "rawget", "rawset", + "repeat", "require", "self", "string", "table", "tostring", "type", "unpack", +]); diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 42609ea6c..05b33c044 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -6,6 +6,7 @@ import * as tstl from "./LuaAST"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import { LuaLib, LuaLibFeature } from "./LuaLib"; import { TSHelper as tsHelper } from "./TSHelper"; +import { luaKeywords } from "./LuaKeywords"; type SourceChunk = string | SourceNode; @@ -559,7 +560,10 @@ export class LuaPrinter { const value = this.printExpression(expression.value); if (expression.key) { - if (tstl.isStringLiteral(expression.key) && tsHelper.isValidLuaIdentifier(expression.key.value)) { + if (tstl.isStringLiteral(expression.key) + && tsHelper.isValidLuaIdentifier(expression.key.value) + && !luaKeywords.has(expression.key.value)) + { chunks.push(expression.key.value, " = ", value); } else { chunks.push("[", this.printExpression(expression.key), "] = ", value); @@ -653,7 +657,10 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.table)); - if (tstl.isStringLiteral(expression.index) && tsHelper.isValidLuaIdentifier(expression.index.value)) { + if (tstl.isStringLiteral(expression.index) + && tsHelper.isValidLuaIdentifier(expression.index.value) + && !luaKeywords.has(expression.index.value)) + { chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); } else { chunks.push("[", this.printExpression(expression.index), "]"); diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index dcce7663e..d46b5d107 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -6,6 +6,7 @@ import * as tstl from "./LuaAST"; import { LuaLibFeature } from "./LuaLib"; import { ContextType, TSHelper as tsHelper } from "./TSHelper"; import { TSTLErrors } from "./TSTLErrors"; +import { luaKeywords, luaBuiltins } from "./LuaKeywords"; export type StatementVisitResult = tstl.Statement | tstl.Statement[] | undefined; export type ExpressionVisitResult = tstl.Expression; @@ -49,13 +50,6 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { } export class LuaTransformer { - public luaKeywords: Set = new Set([ - "_G", "and", "assert", "break", "coroutine", "debug", "do", "else", "elseif", "end", "error", "false", "for", - "function", "goto", "if", "ipairs", "in", "local", "math", "nil", "not", "or", "pairs", "pcall", "print", - "rawget", "rawset", "repeat", "return", "require", "self", "string", "table", "then", "tostring", "type", - "unpack", "until", "while", - ]); - private isStrict: boolean; private luaTarget: LuaTarget; @@ -3449,8 +3443,9 @@ export class LuaTransformer { } else if (ts.isShorthandPropertyAssignment(element)) { let identifier: tstl.Expression | undefined; const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol !== undefined && this.symbolIds.has(valueSymbol)) { - // Ignore unknown symbols so things like NaN still get transformed properly + if (valueSymbol !== undefined + // Ignore declarations for things like NaN + && !tsHelper.isStandardLibraryDeclaration(valueSymbol.valueDeclaration, this.program)) { identifier = this.createIdentifierFromSymbol(valueSymbol, element.name); } else { identifier = this.transformIdentifierExpression(element.name); @@ -3818,13 +3813,20 @@ export class LuaTransformer { if (!signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { - // table:name() - return tstl.createMethodCallExpression( - table, - this.transformIdentifier(node.expression.name), - parameters, - node - ); + if (luaKeywords.has(node.expression.name.text) + || !tsHelper.isValidLuaIdentifier(node.expression.name.text)) + { + return this.transformElementCall(node); + + } else { + // table:name() + return tstl.createMethodCallExpression( + table, + this.transformIdentifier(node.expression.name), + parameters, + node + ); + } } else { // table.name() const callPath = tstl.createTableIndexExpression( @@ -3839,7 +3841,7 @@ export class LuaTransformer { } public transformElementCall(node: ts.CallExpression): ExpressionVisitResult { - if (!ts.isElementAccessExpression(node.expression)) { + if (!ts.isElementAccessExpression(node.expression) && !ts.isPropertyAccessExpression(node.expression)) { throw TSTLErrors.InvalidElementCall(node); } @@ -3862,7 +3864,10 @@ export class LuaTransformer { // Cache left-side if it has effects //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() - const argument = this.transformExpression(node.expression.argumentExpression); + const argumentExpression = ts.isElementAccessExpression(node.expression) + ? node.expression.argumentExpression + : ts.createStringLiteral(node.expression.name.text); + const argument = this.transformExpression(argumentExpression); const selfIdentifier = tstl.createIdentifier("____TS_self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); @@ -5269,11 +5274,11 @@ export class LuaTransformer { } protected isUnsafeName(name: string): boolean { - return this.luaKeywords.has(name) || !tsHelper.isValidLuaIdentifier(name); + return luaKeywords.has(name) || luaBuiltins.has(name) || !tsHelper.isValidLuaIdentifier(name); } protected hasUnsafeSymbolName(symbol: ts.Symbol): boolean { - if (this.luaKeywords.has(symbol.name)) { + if (luaKeywords.has(symbol.name) || luaBuiltins.has(symbol.name)) { // lua keywords are only unsafe when non-ambient and not exported const isNonAmbient = symbol.declarations.find(d => !tsHelper.isAmbient(d)) !== undefined; return isNonAmbient && !this.isSymbolExported(symbol); @@ -5284,6 +5289,10 @@ export class LuaTransformer { protected hasUnsafeIdentifierName(identifier: ts.Identifier): boolean { const symbol = this.checker.getSymbolAtLocation(identifier); if (symbol !== undefined) { + if (luaKeywords.has(symbol.name) && symbol.declarations.find(d => !tsHelper.isAmbient(d)) === undefined) { + // Catch ambient declarations of identifiers with lua keyword names + throw TSTLErrors.InvalidAmbientLuaKeywordIdentifier(identifier); + } return this.hasUnsafeSymbolName(symbol); } return false; diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 49f6420f8..c882dafea 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -189,5 +189,12 @@ export class TSTLErrors { "must be moved before the identifier's use, or hoisting must be enabled.", node ); - } + }; + + public static InvalidAmbientLuaKeywordIdentifier = (node: ts.Identifier) => { + return new TranspileError( + `Invalid use of lua keyword "${node.text}" as ambient identifier name.`, + node + ); + }; } diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 20a889a34..355546cbd 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -1,4 +1,7 @@ +import * as ts from "typescript"; import * as util from "../util"; +import { luaKeywords } from "../../src/LuaKeywords"; +import { TSTLErrors } from "../../src/TSTLErrors"; test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])("invalid lua identifier name (%p)", name => { const code = ` @@ -8,6 +11,83 @@ test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])("invalid lua identifier nam expect(util.transpileAndExecute(code)).toBe("foobar"); }); +test.each([...luaKeywords.values()])("lua keyword as property name (%p)", keyword => { + const code = ` + const x = { ${keyword}: "foobar" }; + return x.${keyword};`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test.each(["and", "elseif", "end", "goto", "local", "nil", "not", "or", "repeat", "then", "until"])( + "destructuring lua keyword (%p)", + keyword => { + const code = ` + const { foo: ${keyword} } = { foo: "foobar" }; + return ${keyword};`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }, +); + +test.each(["and", "elseif", "end", "goto", "local", "nil", "not", "or", "repeat", "then", "until"])( + "destructuring shorthand lua keyword (%p)", + keyword => { + const code = ` + const { ${keyword} } = { ${keyword}: "foobar" }; + return ${keyword};`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }, +); + +test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿", ...luaKeywords.values()])( + "lua keyword or invalid identifier as method call (%p)", + name => { + const code = ` + const foo = { + ${name}(arg: string) { return "foo" + arg; } + }; + return foo.${name}("bar");`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }, +); + +test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿", ...luaKeywords.values()])( + "lua keyword or invalid identifier as complex method call (%p)", + name => { + const code = ` + const foo = { + ${name}(arg: string) { return "foo" + arg; } + }; + function getFoo() { return foo; } + return getFoo().${name}("bar");`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); + }, +); + +test.each([ + "var local: any;", + "let local: any;", + "const local: any;", + "const foo: any, bar: any, local: any;", + "class local {}", + "namespace local { export const bar: any; }", + "module local { export const bar: any; }", + "enum local {}", + "function local() {}", +])("ambient identifier cannot be a lua keyword (%p)", statement => { + const code = ` + declare ${statement} + const foo = local;`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidAmbientLuaKeywordIdentifier(ts.createIdentifier("local")).message, + ); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { const code = ` diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 7b7aa40fe..b199d3bf5 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -29,6 +29,17 @@ describe("property shorthand", () => { expect(result).toBe(identifier); }); + test("should support _G shorthand", () => { + const result = util.transpileAndExecute( + `return ({ _G })._G.foobar;`, + undefined, + `foobar = "foobar"`, + "declare const _G: any;", + ); + + expect(result).toBe("foobar"); + }); + test("should support export property shorthand", () => { const code = ` export const x = 1; From 908db3699a4c486b98de0e2d518e3b8d8380198d Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 26 May 2019 05:59:41 -0600 Subject: [PATCH 093/764] Using ipairs for for...of loops (#595) Extracted from #585 Also includes: - Throwing error on attempts to use object destructuring in for...of loops - Fixed issue with sourcemaps in lua for...in loops --- src/LuaPrinter.ts | 6 +- src/LuaTransformer.ts | 67 +++++++++---------- src/TSTLErrors.ts | 4 ++ .../__snapshots__/transformation.spec.ts.snap | 6 +- test/unit/loops.spec.ts | 31 +++++++++ test/unit/sourcemaps.spec.ts | 2 +- 6 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 05b33c044..ba5da24f6 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -390,12 +390,12 @@ export class LuaPrinter { } public printForInStatement(statement: tstl.ForInStatement): SourceNode { - const names = statement.names.map(i => this.printIdentifier(i)).join(", "); - const expressions = statement.expressions.map(e => this.printExpression(e)).join(", "); + const names = this.joinChunks(", ", statement.names.map(i => this.printIdentifier(i))); + const expressions = this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e))); const chunks: SourceChunk[] = []; - chunks.push(this.indent("for "), names, " in ", expressions, " do\n"); + chunks.push(this.indent("for "), ...names, " in ", ...expressions, " do\n"); this.pushIndent(); chunks.push(this.printBlock(statement.body)); diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index d46b5d107..2349837e5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2284,6 +2284,9 @@ export class LuaTransformer { const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { expression = this.createUnpackCall(expression, initializer); + + } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { + throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); } const variableStatements = this.statementVisitResultToArray(variableDeclarations); @@ -2302,6 +2305,10 @@ export class LuaTransformer { expression = this.createUnpackCall(expression, initializer); variables = initializer.elements .map(e => this.transformExpression(e)) as tstl.AssignmentLeftHandSideExpression[]; + + } else if (ts.isObjectLiteralExpression(initializer)) { + throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); + } else { variables = this.transformExpression(initializer) as tstl.AssignmentLeftHandSideExpression; } @@ -2336,43 +2343,35 @@ export class LuaTransformer { } private transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const arrayExpression = this.transformExpression(statement.expression); - - // Arrays use numeric for loop (performs better than ipairs) - const indexVariable = tstl.createIdentifier("____TS_index"); - if (!ts.isIdentifier(statement.expression)) { - // Cache iterable expression if it's not a simple identifier - // local ____TS_array = ${iterable}; - // for ____TS_index = 1, #____TS_array do - // local ${initializer} = ____TS_array[____TS_index] - const arrayVariable = tstl.createIdentifier("____TS_array", statement.expression); - const arrayAccess = tstl.createTableIndexExpression(arrayVariable, indexVariable); - const initializer = this.transformForOfInitializer(statement.initializer, arrayAccess); - block.statements.splice(0, 0, initializer); - return [ - tstl.createVariableDeclarationStatement(arrayVariable, arrayExpression), - tstl.createForStatement( - block, - indexVariable, - tstl.createNumericLiteral(1), - tstl.createUnaryExpression(arrayVariable, tstl.SyntaxKind.LengthOperator) - ), - ]; + let valueVariable: tstl.Identifier; + if (ts.isVariableDeclarationList(statement.initializer)) { + // Declaration of new variable + const variables = statement.initializer.declarations[0].name; + if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { + valueVariable = tstl.createIdentifier("____TS_values"); + block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); + + } else { + valueVariable = this.transformIdentifier(variables); + } } else { - // Simple identifier version - // for ____TS_index = 1, #${iterable} do - // local ${initializer} = ${iterable}[____TS_index] - const iterableAccess = tstl.createTableIndexExpression(arrayExpression, indexVariable); - const initializer = this.transformForOfInitializer(statement.initializer, iterableAccess); - block.statements.splice(0, 0, initializer); - return tstl.createForStatement( - block, - indexVariable, - tstl.createNumericLiteral(1), - tstl.createUnaryExpression(arrayExpression, tstl.SyntaxKind.LengthOperator) - ); + // Assignment to existing variable + valueVariable = tstl.createIdentifier("____TS_value"); + block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); } + + const ipairsCall = tstl.createCallExpression( + tstl.createIdentifier("ipairs"), + [this.transformExpression(statement.expression)] + ); + + return tstl.createForInStatement( + block, + [tstl.createAnonymousIdentifier(), valueVariable], + [ipairsCall], + statement + ); } private transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index c882dafea..4295fc3f2 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -191,6 +191,10 @@ export class TSTLErrors { ); }; + public static UnsupportedObjectDestructuringInForOf = (node: ts.Node) => { + return new TranspileError(`Unsupported object destructuring in for...of statement.`, node); + }; + public static InvalidAmbientLuaKeywordIdentifier = (node: ts.Identifier) => { return new TranspileError( `Invalid use of lua keyword "${node.text}" as ambient identifier name.`, diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 09544594d..ca2e7e42b 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -238,7 +238,7 @@ end" `; exports[`Transformation (forOf) 1`] = ` -"local ____TS_array = { +"for ____, i in ipairs({ 1, 2, 3, @@ -249,9 +249,7 @@ exports[`Transformation (forOf) 1`] = ` 8, 9, 10, -} -for ____TS_index = 1, #____TS_array do - local i = ____TS_array[____TS_index] +}) do end" `; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 3ddb55998..b36ff10ff 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -504,6 +504,37 @@ test("forof destructuring with iterator and existing variables", () => { expect(result).toBe("0a1b2c"); }); +test("forof array which modifies length", () => { + const code = ` + const arr = ["a", "b", "c"]; + let result = ""; + for (const v of arr) { + if (v === "a") { + arr.push("d"); + } + result += v; + } + return result;`; + + expect(util.transpileAndExecute(code)).toBe("abcd"); +}); + +test.each([ + { initializer: "const {a, b}", vars: "" }, + { initializer: "const {a: x, b: y}", vars: "" }, + { initializer: "{a, b}", vars: "let a: string, b: string;" }, + { initializer: "{a: c, b: d}", vars: "let c: string, d: string;" }, +])("forof object destructuring (%p)", ({ initializer, vars }) => { + const code = ` + declare const arr: {a: string, b: string}[]; + ${vars} + for (${initializer} of arr) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message, + ); +}); + test("forof with array typed as iterable", () => { const code = ` function foo(): Iterable { diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index 5225ab6b2..5d571f0d2 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -102,8 +102,8 @@ test.each([ `, assertPatterns: [ + { luaPattern: "for", typeScriptPattern: "for" }, { luaPattern: "getArr()", typeScriptPattern: "getArr()" }, - { luaPattern: "____TS_array", typeScriptPattern: "getArr()" }, { luaPattern: "element", typeScriptPattern: "element" }, ], }, From a2046bd6807f92da9bd719456e31a94e513549bd Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 26 May 2019 12:44:48 -0600 Subject: [PATCH 094/764] Identifier name fixes (#596) * Catching lua keyword ambient identifiers in object literal shorthand * treating undeclared variables as ambient when checking for lua keyword names * dis-allowing ambient/undeclared identifiers with invalid lua names * catching undeclared invalid lua identifiers in object literal shorthand * correctly naming exports with invalid lua names, also some refactoring on tests * class with invalid lua names now keep correct name property * applying suggestion * fixed decorated, exported classes fixes #605 * forgot assertion in test --- src/LuaTransformer.ts | 85 ++++++++++------- src/TSTLErrors.ts | 4 +- test/unit/classDecorator.spec.ts | 13 +++ test/unit/identifiers.spec.ts | 153 ++++++++++++++++++++++++++----- 4 files changed, 198 insertions(+), 57 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2349837e5..d7e0b4eeb 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -264,11 +264,7 @@ export class LuaTransformer { exportedIdentifier = this.transformIdentifier(specifier.propertyName); } else { const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(specifier); - if (exportedSymbol !== undefined) { - exportedIdentifier = this.createIdentifierFromSymbol(exportedSymbol, specifier.name); - } else { - exportedIdentifier = this.transformIdentifier(specifier.name); - } + exportedIdentifier = this.createShorthandIdentifier(exportedSymbol, specifier.name); } return tstl.createAssignmentStatement( @@ -483,10 +479,13 @@ export class LuaTransformer { } let className: tstl.Identifier; + let classNameText: string; if (nameOverride !== undefined) { className = nameOverride; + classNameText = nameOverride.text; } else if (statement.name !== undefined) { className = this.transformIdentifier(statement.name); + classNameText = statement.name.text; } else { throw TSTLErrors.MissingClassName(statement); } @@ -593,6 +592,7 @@ export class LuaTransformer { statement, className, localClassName, + classNameText, extendsType ); result.push(...classCreationMethods); @@ -727,6 +727,7 @@ export class LuaTransformer { statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, localClassName: tstl.Identifier, + classNameText: string, extendsType?: ts.Type ): tstl.Statement[] { @@ -752,7 +753,7 @@ export class LuaTransformer { result.push( tstl.createAssignmentStatement( tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("name")), - tstl.createStringLiteral(localClassName.text), + tstl.createStringLiteral(classNameText), statement ) ); @@ -3440,15 +3441,8 @@ export class LuaTransformer { properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { - let identifier: tstl.Expression | undefined; const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol !== undefined - // Ignore declarations for things like NaN - && !tsHelper.isStandardLibraryDeclaration(valueSymbol.valueDeclaration, this.program)) { - identifier = this.createIdentifierFromSymbol(valueSymbol, element.name); - } else { - identifier = this.transformIdentifierExpression(element.name); - } + let identifier = this.createShorthandIdentifier(valueSymbol, element.name); if (tstl.isIdentifier(identifier) && valueSymbol !== undefined && this.isSymbolExported(valueSymbol)) { identifier = this.createExportedIdentifier(identifier); } @@ -5265,34 +5259,62 @@ export class LuaTransformer { return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); } - protected createIdentifierFromSymbol(symbol: ts.Symbol, tsOriginal?: ts.Node): tstl.Identifier { - const name = this.hasUnsafeSymbolName(symbol) - ? this.createSafeName(symbol.name) - : symbol.name; - return tstl.createIdentifier(name, tsOriginal, this.symbolIds.get(symbol)); + protected createShorthandIdentifier( + valueSymbol: ts.Symbol | undefined, + propertyIdentifier: ts.Identifier + ): tstl.Expression + { + let name: string; + if (valueSymbol !== undefined) { + name = this.hasUnsafeSymbolName(valueSymbol, propertyIdentifier) + ? this.createSafeName(valueSymbol.name) + : valueSymbol.name; + + } else { + const propertyName = this.getIdentifierText(propertyIdentifier); + if (luaKeywords.has(propertyName) || !tsHelper.isValidLuaIdentifier(propertyName)) { + // Catch ambient declarations of identifiers with bad names + throw TSTLErrors.InvalidAmbientIdentifierName(propertyIdentifier); + } + name = this.hasUnsafeIdentifierName(propertyIdentifier) + ? this.createSafeName(propertyName) + : propertyName; + } + + const identifier = this.transformIdentifierExpression(ts.createIdentifier(name)); + tstl.setNodeOriginal(identifier, propertyIdentifier); + if (valueSymbol !== undefined && tstl.isIdentifier(identifier)) { + identifier.symbolId = this.symbolIds.get(valueSymbol); + } + return identifier; } protected isUnsafeName(name: string): boolean { return luaKeywords.has(name) || luaBuiltins.has(name) || !tsHelper.isValidLuaIdentifier(name); } - protected hasUnsafeSymbolName(symbol: ts.Symbol): boolean { - if (luaKeywords.has(symbol.name) || luaBuiltins.has(symbol.name)) { - // lua keywords are only unsafe when non-ambient and not exported - const isNonAmbient = symbol.declarations.find(d => !tsHelper.isAmbient(d)) !== undefined; - return isNonAmbient && !this.isSymbolExported(symbol); + protected hasUnsafeSymbolName(symbol: ts.Symbol, tsOriginal?: ts.Identifier): boolean { + const isLuaKeyword = luaKeywords.has(symbol.name); + const isInvalidIdentifier = !tsHelper.isValidLuaIdentifier(symbol.name); + const isAmbient = symbol.declarations.some(d => tsHelper.isAmbient(d)); + if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { + // Catch ambient declarations of identifiers with bad names + throw TSTLErrors.InvalidAmbientIdentifierName(tsOriginal || ts.createIdentifier(symbol.name)); + } + + if (this.isUnsafeName(symbol.name)) { + // only unsafe when non-ambient and not exported + return !isAmbient && !this.isSymbolExported(symbol); } - return this.isUnsafeName(symbol.name); + return false; } protected hasUnsafeIdentifierName(identifier: ts.Identifier): boolean { const symbol = this.checker.getSymbolAtLocation(identifier); if (symbol !== undefined) { - if (luaKeywords.has(symbol.name) && symbol.declarations.find(d => !tsHelper.isAmbient(d)) === undefined) { - // Catch ambient declarations of identifiers with lua keyword names - throw TSTLErrors.InvalidAmbientLuaKeywordIdentifier(identifier); - } - return this.hasUnsafeSymbolName(symbol); + return this.hasUnsafeSymbolName(symbol, identifier); + } else if (luaKeywords.has(identifier.text) || !tsHelper.isValidLuaIdentifier(identifier.text)) { + throw TSTLErrors.InvalidAmbientIdentifierName(identifier); } return false; } @@ -5556,7 +5578,7 @@ export class LuaTransformer { declaration: ts.ClassLikeDeclaration ): tstl.AssignmentStatement | undefined { const className = declaration.name !== undefined - ? this.transformIdentifier(declaration.name) + ? this.addExportToIdentifier(this.transformIdentifier(declaration.name)) : tstl.createAnonymousIdentifier(); const decorators = declaration.decorators; @@ -5585,3 +5607,4 @@ export class LuaTransformer { ); } } + diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 4295fc3f2..4f2b6e565 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -195,9 +195,9 @@ export class TSTLErrors { return new TranspileError(`Unsupported object destructuring in for...of statement.`, node); }; - public static InvalidAmbientLuaKeywordIdentifier = (node: ts.Identifier) => { + public static InvalidAmbientIdentifierName = (node: ts.Identifier) => { return new TranspileError( - `Invalid use of lua keyword "${node.text}" as ambient identifier name.`, + `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, node ); }; diff --git a/test/unit/classDecorator.spec.ts b/test/unit/classDecorator.spec.ts index 96e2ed474..3575284df 100644 --- a/test/unit/classDecorator.spec.ts +++ b/test/unit/classDecorator.spec.ts @@ -188,3 +188,16 @@ test("Throws error if decorator function has void context", () => { TSTLErrors.InvalidDecoratorContext(util.nodeStub), ); }); + +test("Exported class decorator", () => { + const code = ` + function decorator(c: T): T { + c.bar = "foobar"; + return c; + } + + @decorator + export class Foo {}`; + + expect(util.transpileExecuteAndReturnExport(code, "Foo.bar")).toBe("foobar"); +}); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 355546cbd..7191a986e 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -3,7 +3,24 @@ import * as util from "../util"; import { luaKeywords } from "../../src/LuaKeywords"; import { TSTLErrors } from "../../src/TSTLErrors"; -test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])("invalid lua identifier name (%p)", name => { +const invalidLuaCharNames = ["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"]; +const validTsInvalidLuaKeywordNames = [ + "and", + "elseif", + "end", + "goto", + "local", + "nil", + "not", + "or", + "repeat", + "then", + "until", +]; +const invalidLuaNames = [...invalidLuaCharNames, ...luaKeywords.values()]; +const validTsInvalidLuaNames = [...invalidLuaCharNames, ...validTsInvalidLuaKeywordNames]; + +test.each(validTsInvalidLuaNames)("invalid lua identifier name (%p)", name => { const code = ` const ${name} = "foobar"; return ${name};`; @@ -19,42 +36,33 @@ test.each([...luaKeywords.values()])("lua keyword as property name (%p)", keywor expect(util.transpileAndExecute(code)).toBe("foobar"); }); -test.each(["and", "elseif", "end", "goto", "local", "nil", "not", "or", "repeat", "then", "until"])( - "destructuring lua keyword (%p)", - keyword => { - const code = ` +test.each(validTsInvalidLuaKeywordNames)("destructuring lua keyword (%p)", keyword => { + const code = ` const { foo: ${keyword} } = { foo: "foobar" }; return ${keyword};`; - expect(util.transpileAndExecute(code)).toBe("foobar"); - }, -); + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); -test.each(["and", "elseif", "end", "goto", "local", "nil", "not", "or", "repeat", "then", "until"])( - "destructuring shorthand lua keyword (%p)", - keyword => { - const code = ` +test.each(validTsInvalidLuaKeywordNames)("destructuring shorthand lua keyword (%p)", keyword => { + const code = ` const { ${keyword} } = { ${keyword}: "foobar" }; return ${keyword};`; - expect(util.transpileAndExecute(code)).toBe("foobar"); - }, -); + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); -test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿", ...luaKeywords.values()])( - "lua keyword or invalid identifier as method call (%p)", - name => { - const code = ` +test.each(invalidLuaNames)("lua keyword or invalid identifier as method call (%p)", name => { + const code = ` const foo = { ${name}(arg: string) { return "foo" + arg; } }; return foo.${name}("bar");`; - expect(util.transpileAndExecute(code)).toBe("foobar"); - }, -); + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); -test.each(["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿", ...luaKeywords.values()])( +test.each(invalidLuaNames)( "lua keyword or invalid identifier as complex method call (%p)", name => { const code = ` @@ -84,10 +92,107 @@ test.each([ const foo = local;`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientLuaKeywordIdentifier(ts.createIdentifier("local")).message, + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local")).message, ); }); +test.each([ + "var $$$: any;", + "let $$$: any;", + "const $$$: any;", + "const foo: any, bar: any, $$$: any;", + "class $$$ {}", + "namespace $$$ { export const bar: any; }", + "module $$$ { export const bar: any; }", + "enum $$$ {}", + "function $$$() {}", +])("ambient identifier must be a valid lua identifier (%p)", statement => { + const code = ` + declare ${statement} + const foo = $$$;`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$")).message, + ); +}); + +test.each(validTsInvalidLuaNames)( + "ambient identifier must be a valid lua identifier (object literal shorthand) (%p)", + name => { + const code = ` + declare var ${name}: any; + const foo = { ${name} };`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, + ); + }, +); + +test.each(validTsInvalidLuaNames)( + "undeclared identifier must be a valid lua identifier (%p)", + name => { + expect(() => util.transpileString(`const foo = ${name};`)).toThrow( + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, + ); + }, +); + +test.each(validTsInvalidLuaNames)( + "undeclared identifier must be a valid lua identifier (object literal shorthand) (%p)", + name => { + expect(() => util.transpileString(`const foo = { ${name} };`)).toThrow( + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, + ); + }, +); + +test.each(validTsInvalidLuaNames)( + "exported values with invalid lua identifier names (%p)", + name => { + const code = `export const ${name} = "foobar";`; + const lua = util.transpileString(code); + expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); + expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); + }, +); + +test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name property", name => { + const code = ` + class ${name} {} + return ${name}.name;`; + + expect(util.transpileAndExecute(code)).toBe(name); +}); + +test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name => { + const code = ` + function decorator(c: T): T { + c.bar = "foobar"; + return c; + } + + @decorator + class ${name} {} + return (${name} as any).bar;`; + + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua name", name => { + const code = ` + function decorator(c: T): T { + c.bar = "foobar"; + return c; + } + + @decorator + export class ${name} {}`; + + const lua = util.transpileString(code); + expect(util.executeLua(`return (function() ${lua} end)()["${name}"].bar`)).toBe("foobar"); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { const code = ` From dfcfa1fbe054daf351bb5f961e2d557c51841b7b Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 27 May 2019 16:44:29 +0500 Subject: [PATCH 095/764] Enable prettier on all files (#588) * Chnage prettier options * Enable prettier on all files * Remove formatting rules from main tslint config * Format all files with prettier * Make some manual formatting changes --- .prettierignore | 3 - .prettierrc.js | 5 +- CHANGELOG.md | 324 +++-- CONTRIBUTING.md | 40 +- README.md | 26 +- package.json | 4 +- src/CommandLineParser.ts | 15 +- src/Emit.ts | 10 +- src/LuaAST.ts | 171 +-- src/LuaKeywords.ts | 45 +- src/LuaLib.ts | 2 +- src/LuaPrinter.ts | 120 +- src/LuaTransformer.ts | 1223 +++++++---------- src/TSHelper.ts | 266 ++-- src/TSTLErrors.ts | 73 +- src/Transpile.ts | 32 +- src/TranspileError.ts | 2 +- src/diagnostics.ts | 7 +- src/index.ts | 44 +- src/lualib/ArrayConcat.ts | 28 +- src/lualib/ArrayEvery.ts | 8 +- src/lualib/ArrayFilter.ts | 8 +- src/lualib/ArrayForEach.ts | 8 +- src/lualib/ArraySetLength.ts | 12 +- src/lualib/ArraySome.ts | 8 +- src/lualib/ArraySplice.ts | 6 +- src/lualib/ArrayUnshift.ts | 2 +- src/lualib/ClassNewIndex.ts | 3 +- src/lualib/FunctionApply.ts | 7 +- src/lualib/FunctionCall.ts | 7 +- src/lualib/NewIndex.ts | 4 +- src/lualib/Number.ts | 2 +- src/lualib/NumberIsFinite.ts | 4 +- src/lualib/SourceMapTraceBack.ts | 16 +- src/lualib/StringConcat.ts | 10 +- src/lualib/SymbolRegistry.ts | 2 +- src/lualib/WeakMap.ts | 2 +- src/tstl.ts | 36 +- test/setup.ts | 4 +- test/transpile/directories.spec.ts | 2 +- test/transpile/run.ts | 9 +- test/tsconfig.json | 8 +- test/tslint.json | 59 - test/unit/array.spec.ts | 43 +- test/unit/assignments/assignments.spec.ts | 4 +- .../functionExpressionTypeInference.spec.ts | 54 +- test/unit/assignments/functionPermutations.ts | 64 +- .../invalidFunctionAssignments.spec.ts | 26 +- .../validFunctionAssignments.spec.ts | 115 +- test/unit/bindingpatterns.spec.ts | 61 +- test/unit/class.spec.ts | 108 +- test/unit/classDecorator.spec.ts | 8 +- test/unit/commandLineParser.spec.ts | 4 +- test/unit/conditionals.spec.ts | 231 ++-- test/unit/console.spec.ts | 32 +- test/unit/curry.spec.ts | 2 +- test/unit/decoratorCustomConstructor.spec.ts | 11 +- test/unit/decoratorMetaExtension.spec.ts | 2 +- test/unit/enum.spec.ts | 14 +- test/unit/error.spec.ts | 2 +- test/unit/expressions.spec.ts | 107 +- test/unit/functions.spec.ts | 86 +- test/unit/hoisting.spec.ts | 23 +- test/unit/identifiers.spec.ts | 78 +- test/unit/json.spec.ts | 19 +- test/unit/loops.spec.ts | 261 ++-- test/unit/luaTable.spec.ts | 49 +- test/unit/lualib/inlining.spec.ts | 6 +- test/unit/lualib/lualib.spec.ts | 120 +- test/unit/lualib/map.spec.ts | 36 +- test/unit/lualib/set.spec.ts | 26 +- test/unit/lualib/symbol.spec.ts | 22 +- test/unit/lualib/weakMap.spec.ts | 2 +- test/unit/lualib/weakSet.spec.ts | 2 +- test/unit/math.spec.ts | 31 +- test/unit/modules.spec.ts | 27 +- test/unit/numbers.spec.ts | 12 +- test/unit/objectLiteral.spec.ts | 2 +- test/unit/overloads.spec.ts | 12 +- test/unit/require.spec.ts | 9 +- test/unit/semicolons.spec.ts | 16 +- test/unit/sourcemaps.spec.ts | 6 +- test/unit/spreadElement.spec.ts | 15 +- test/unit/string.spec.ts | 86 +- test/unit/tuples.spec.ts | 14 +- test/unit/typechecking.spec.ts | 16 +- test/util.ts | 27 +- tslint.json | 69 +- 88 files changed, 1995 insertions(+), 2632 deletions(-) delete mode 100644 test/tslint.json diff --git a/.prettierignore b/.prettierignore index fef924d04..cbfe6aa04 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,3 @@ /dist /coverage /test/translation/transformation/characterEscapeSequence.ts - -/src -*.md diff --git a/.prettierrc.js b/.prettierrc.js index 1e032a0bf..87974397e 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -2,10 +2,9 @@ const isCI = require("is-ci"); /** @type {import("prettier").Options} */ module.exports = { - printWidth: 100, + printWidth: 120, tabWidth: 4, - trailingComma: "all", - proseWrap: "always", + trailingComma: "es5", endOfLine: isCI ? "lf" : "auto", overrides: [{ files: ["**/*.md", "**/*.yml", "**/.*.yml"], options: { tabWidth: 2 } }], }; diff --git a/CHANGELOG.md b/CHANGELOG.md index 72034d078..e7eab90af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## 0.20.0 + - Added support for `string.repeat`, `string.padStart` and `string.padEnd`. - Added automatic variable renaming for invalid Lua identifiers. - Fixed `/** @tupleReturn */` not working for function types (i.e `myFunc: () => [number, number]`) @@ -8,8 +9,9 @@ - Various small code tweaks and improvements. ## 0.19.0 + - **BREAKING CHANGE:** All tstl-specific options should now be inside the "tstl" section in tsconfig.json (see README.md). **Root-level options are no longer supported**. -- Added a compiler API to programmatically invoke TypeScriptToLua, and to modify or extend the default transpiler. More info on the [Compiler API wiki page](). +- Added a compiler API to programmatically invoke TypeScriptToLua, and to modify or extend the default transpiler. More info on the [Compiler API wiki page](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/TypeScriptToLua-API). - Added support for [class decorators](https://www.typescriptlang.org/docs/handbook/decorators.html#class-decorators). - Added support for the [@luaTable directive](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luatable) which will force a class to be transpiled as vanilla lua table. - Added support for NaN, Infinity and related number functions. @@ -21,57 +23,60 @@ - Fixed an issue with parameters that had `false` as default value. ## 0.18.0 -* Added support for setting array length. Doing `array.length = x` will set the length of the array to `x` (or shorter, if the starting array was shorter!). -* Added the `.name` property to all transpiled classes, so `class.name` will contain the classname as string. -* Changed `class = class or {}` syntax to just be `class = {}`. -* Cleaned up printer output so it produces more human-readable code. -* Fixed bug with expression statements. -* Fixed incorrect inline sourcemap format. -* Fixed bug when merging an interface and module. -* Fixed a bug with inherited constructor super call ordering. +- Added support for setting array length. Doing `array.length = x` will set the length of the array to `x` (or shorter, if the starting array was shorter!). +- Added the `.name` property to all transpiled classes, so `class.name` will contain the classname as string. +- Changed `class = class or {}` syntax to just be `class = {}`. +- Cleaned up printer output so it produces more human-readable code. + +- Fixed bug with expression statements. +- Fixed incorrect inline sourcemap format. +- Fixed bug when merging an interface and module. +- Fixed a bug with inherited constructor super call ordering. -* Enabled strict tsconfig. +- Enabled strict tsconfig. ## 0.17.0 -* We now support source maps in the [standard JS v3 format](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1). You can generate source maps with the `--sourceMap` CLI argument, or by adding `sourceMap: true` to your tsconfig. Inline source maps are also supported with `--inlineSourceMap` CLI/tsconfig parameter. -* Also added [tstl option](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options) `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). -* Made watch mode incremental. +- We now support source maps in the [standard JS v3 format](https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?hl=en_US&pli=1&pli=1). You can generate source maps with the `--sourceMap` CLI argument, or by adding `sourceMap: true` to your tsconfig. Inline source maps are also supported with `--inlineSourceMap` CLI/tsconfig parameter. +- Also added [tstl option](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options) `--sourceMapTraceback`, which will add an override to Lua's `debug.traceback()` to each file, so source maps will automatically be applied to Lua stacktraces (i.e. in errors). -* Added support for `Object.fromEntries`, `array.flat` and `array.flatMap`. +- Made watch mode incremental. -* **BREAKING CHANGE:** Directive `@tupleReturn` should now be specified **per overload**. +- Added support for `Object.fromEntries`, `array.flat` and `array.flatMap`. -* Fixed a bug where rest parameters would not transpile correctly. -* Fixed an issue with escaped backticks. -* Various small fixes function inference and array detection. +- **BREAKING CHANGE:** Directive `@tupleReturn` should now be specified **per overload**. -* Changed testing framework to [jest](https://github.com/facebook/jest). +- Fixed a bug where rest parameters would not transpile correctly. +- Fixed an issue with escaped backticks. +- Various small fixes function inference and array detection. +- Changed testing framework to [jest](https://github.com/facebook/jest). ## 0.16.0 -* **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument. - * To remove the self parameter from a single function add `this: void` to its declaration: - ```declare function foo(this: void, ...)``` - * To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`: - ```/** @noSelf */ interface Foo {``` - * To remove the self parameter from all functions in a file, add `/** @noSelfInFile */` at the top. + +- **BREAKING CHANGE:** All functions now take a `self` parameter. This means that without further action calls to declaration functions might be given an extra argument. + - To remove the self parameter from a single function add `this: void` to its declaration: + `declare function foo(this: void, ...)` + - To remove the self parameter from all methods or functions in a class/interface/namespace add `/** @noSelf */`: + `/** @noSelf */ interface Foo {` + - To remove the self parameter from all functions in a file, add `/** @noSelfInFile */` at the top. --- -* **BREAKING CHANGE:** Directive `/** @luaIterator */` should now be put on types instead of on the functions returning them. +- **BREAKING CHANGE:** Directive `/** @luaIterator */` should now be put on types instead of on the functions returning them. --- -* Fixed a bug breaking named class expressions. -* Fixed inconsistency between the meaning of `>>` and `>>>` in JS vs. Lua. -* Added `/** @noResolution */` directive to prevent path resolution on declared modules. -* It is now possible to put `/** @luaIterator */` on types extending `Array`. -* Fixed issue with the moment static fields were initialized. -* Fixed issue where `undefined` as property name was not transpiled correctly. -* Various improvements to function/method self parameter inference. -* Tstl options can now be defined in their own `tstl` block in tsconfig.json. For example: +- Fixed a bug breaking named class expressions. +- Fixed inconsistency between the meaning of `>>` and `>>>` in JS vs. Lua. +- Added `/** @noResolution */` directive to prevent path resolution on declared modules. +- It is now possible to put `/** @luaIterator */` on types extending `Array`. +- Fixed issue with the moment static fields were initialized. +- Fixed issue where `undefined` as property name was not transpiled correctly. +- Various improvements to function/method self parameter inference. +- Tstl options can now be defined in their own `tstl` block in tsconfig.json. For example: + ``` { "compilerOptions" : {} @@ -80,152 +85,167 @@ } } ``` -* Fixed issue when redeclaring TypeScript libraries/globals. -* Fixed exception resolving function signatures. -* Added support for automatically transpiling several `console` calls to their Lua equivalent: - * `console.log(...)` -> `print(...)` - * `console.assert(...)` -> `assert(...)` - * `console.trace(...)` -> `print(debug.traceback(...))` -* Added support for `array.findIndex()`. -* Fixed `array.sort()` not working with a compare function. -* Added support for several common `Math.` functions and constants. -* Added support for several common string instance functions such as `upper()`. + +- Fixed issue when redeclaring TypeScript libraries/globals. +- Fixed exception resolving function signatures. +- Added support for automatically transpiling several `console` calls to their Lua equivalent: + - `console.log(...)` -> `print(...)` + - `console.assert(...)` -> `assert(...)` + - `console.trace(...)` -> `print(debug.traceback(...))` +- Added support for `array.findIndex()`. +- Fixed `array.sort()` not working with a compare function. +- Added support for several common `Math.` functions and constants. +- Added support for several common string instance functions such as `upper()`. ## 0.15.2 -* Several improvements to module path resolution. -* Removed header comment appearing in lualib. -* Several package config improvements. -* Static get/set accessors. + +- Several improvements to module path resolution. +- Removed header comment appearing in lualib. +- Several package config improvements. +- Static get/set accessors. ## 0.15.1 -* Fixed array detection for unit and intersection types. -* Support for import without `from`. -* Added support for `WeakMap` and `WeakSet`. -* Added support for `Object.keys` and `Object.assign`. -* Added support for importing JSON files. -* Fixed bug with where loop variables were not properly scoped. -* Added support for ExportDeclarations + +- Fixed array detection for unit and intersection types. +- Support for import without `from`. +- Added support for `WeakMap` and `WeakSet`. +- Added support for `Object.keys` and `Object.assign`. +- Added support for importing JSON files. +- Fixed bug with where loop variables were not properly scoped. +- Added support for ExportDeclarations ## 0.15.0 -* Now written for TypeScript 3.3.x! -* Removed external CLI parser dependency and wrote our own `CommandLineParser.ts` to read CLI and tsconfig input. -* Added support for hoisting, can be disabled with the `noHoisting` option in CLI or tsconfig. -* Added support for generator functions. -* Reworked classes into a system more similar to JavaScript with prototype tables. -* Improved support for ObjectBindingPatterns. -* Added support for enums with identifier values. -* Added support for the binary comma operator. -* Added support for `string.concat`, `string.slice` and `string.charCodeAt`. -* Refactored LuaTranspiler.emitLuaLib to its own method so it can be called from external code. -* Improved function type inference. -* Fixed some bugs in for loops with expressions. -* Fixed a bug forwarding luaIterator functions. + +- Now written for TypeScript 3.3.x! +- Removed external CLI parser dependency and wrote our own `CommandLineParser.ts` to read CLI and tsconfig input. +- Added support for hoisting, can be disabled with the `noHoisting` option in CLI or tsconfig. +- Added support for generator functions. +- Reworked classes into a system more similar to JavaScript with prototype tables. +- Improved support for ObjectBindingPatterns. +- Added support for enums with identifier values. +- Added support for the binary comma operator. +- Added support for `string.concat`, `string.slice` and `string.charCodeAt`. +- Refactored LuaTranspiler.emitLuaLib to its own method so it can be called from external code. +- Improved function type inference. +- Fixed some bugs in for loops with expressions. +- Fixed a bug forwarding luaIterator functions. ## 0.14.0 -* Reworked internal transpiler structure to be more suited for future extension. -* Reworked module and exports system. -* Added support for custom iterators. -* Improved formatting consistency. -* Errors are now reported with location `(line, column)` instead of `line: line, column: column`. -* Added back default lua header: `--[[ Generated with https://github.com/Perryvw/TypescriptToLua ]]`. -* Fixed some bugs with switches and breaks. -* Fixed several bugs with functions and context parameters. + +- Reworked internal transpiler structure to be more suited for future extension. +- Reworked module and exports system. +- Added support for custom iterators. +- Improved formatting consistency. +- Errors are now reported with location `(line, column)` instead of `line: line, column: column`. +- Added back default lua header: `--[[ Generated with https://github.com/Perryvw/TypescriptToLua ]]`. +- Fixed some bugs with switches and breaks. +- Fixed several bugs with functions and context parameters. ## 0.13.0 -* Reworked how functions are transpiled, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods -* Improved handling of types extending Array. -* Fixed several bugs with classes. -* Fixed issues with inherited accessors. + +- Reworked how functions are transpiled, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Differences-Between-Functions-and-Methods +- Improved handling of types extending Array. +- Fixed several bugs with classes. +- Fixed issues with inherited accessors. ## 0.12.0 -* Added detection of types extending Array. -* Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Compiler-Directives -* Fixed bug with constructor default values. -* The Lualib is no longer included when not used. -* Fixed bug with unpack in LuaJIT. + +- Added detection of types extending Array. +- Added new JSDoc-style compiler directives, deprecated the old `!` decorators, see https://github.com/TypeScriptToLua/TypescriptToLua/wiki/Compiler-Directives +- Fixed bug with constructor default values. +- The Lualib is no longer included when not used. +- Fixed bug with unpack in LuaJIT. ## 0.11.0 -* Fixed bug when throwing anything that was not a string. (@tomblind) -* Added support for object literal method declarations. (@tomblind) -* Fixed several issues with assignment operators (@tomblind) -* `else if` statements are now transpiled to Lua `elseif` instead of nested ifs statements. (@tomblind) -* Occurrences of const enum values are now directly replaced with their value in the Lua output. (@DoctorGester) -* Rethrowing is now possible from try/catch blocks (@tomblind) -* Destructing statements in LuaJit now use `unpack` instead of `table.unpack` -* Removed support for switch statements for versions <= 5.1. -* Refactored `for ... of` translation, it now uses numeric `for ` loops instead of `ipairs` for performance reasons. + +- Fixed bug when throwing anything that was not a string. (@tomblind) +- Added support for object literal method declarations. (@tomblind) +- Fixed several issues with assignment operators (@tomblind) +- `else if` statements are now transpiled to Lua `elseif` instead of nested ifs statements. (@tomblind) +- Occurrences of const enum values are now directly replaced with their value in the Lua output. (@DoctorGester) +- Rethrowing is now possible from try/catch blocks (@tomblind) +- Destructing statements in LuaJit now use `unpack` instead of `table.unpack` +- Removed support for switch statements for versions <= 5.1. +- Refactored `for ... of` translation, it now uses numeric `for` loops instead of `ipairs` for performance reasons. ## 0.10.0 -* Added support for NonNullExpression (`abc!` transforming the type from `abc | undefined` to `abc`) -* Added expression position to replacement binary expression to improve error messages. -* Fixed various issues with !TupleReturn (@tomblind) -* Added support for `array.reverse`, `array.shift`, `array.unshift`, `array.sort`. (@andreiradu) -* Added translation for `Object.hasOwnProperty()`. (@andreiradu) -* Added support for class expressions (@andreiradu) -* Fixed bug in detecting array types (@tomblind) -* Added public API functions and better webpack functionality. + +- Added support for NonNullExpression (`abc!` transforming the type from `abc | undefined` to `abc`) +- Added expression position to replacement binary expression to improve error messages. +- Fixed various issues with !TupleReturn (@tomblind) +- Added support for `array.reverse`, `array.shift`, `array.unshift`, `array.sort`. (@andreiradu) +- Added translation for `Object.hasOwnProperty()`. (@andreiradu) +- Added support for class expressions (@andreiradu) +- Fixed bug in detecting array types (@tomblind) +- Added public API functions and better webpack functionality. ## 0.9.0 -* Fixed an issue where default parameter values were ignored in function declarations. -* Fixed a bug where `self` was undefined in function properties. -* Fixed a bug where addition of +1 to indices sometimes caused issues with operation order (thanks @brianhang) -* Fixed super calls having issues with their `self` instance. (thanks @hazzard993) -* Methods now also accept custom decorators (thanks @hazzard993) -* Improved support for `toString` calls (thanks @andreiradu) -* Added support for block expressions (thanks @andreiradu) + +- Fixed an issue where default parameter values were ignored in function declarations. +- Fixed a bug where `self` was undefined in function properties. +- Fixed a bug where addition of +1 to indices sometimes caused issues with operation order (thanks @brianhang) +- Fixed super calls having issues with their `self` instance. (thanks @hazzard993) +- Methods now also accept custom decorators (thanks @hazzard993) +- Improved support for `toString` calls (thanks @andreiradu) +- Added support for block expressions (thanks @andreiradu) Thanks @tomblind for the following changes: -* Fixed a bug where recursive use of a function expression caused a nil error. -* Fixed syntax error when compiling variable declaration lists. -* Fixed an issue with assignment order in exported namespaces. -* Various fixes to `!TupleReturn` functions. -* Fixed an issue with declaration merging. + +- Fixed a bug where recursive use of a function expression caused a nil error. +- Fixed syntax error when compiling variable declaration lists. +- Fixed an issue with assignment order in exported namespaces. +- Various fixes to `!TupleReturn` functions. +- Fixed an issue with declaration merging. ## 0.8.0 -* Added experimental watch mode, use it with `tstl --watch` -* Refactored decorators -* Added `...` spread operator -* Added error when a lua keyword is used as variable name -* Added support for shorthand object literals (thanks @gakada) -* Added array.pop (thanks @andreiradu) -* Added `;` after lines to avoid ambiguous syntax (thanks @andreiradu) -* Fixed issue with tsconfig being overriden (thanks @Janne252) + +- Added experimental watch mode, use it with `tstl --watch` +- Refactored decorators +- Added `...` spread operator +- Added error when a lua keyword is used as variable name +- Added support for shorthand object literals (thanks @gakada) +- Added array.pop (thanks @andreiradu) +- Added `;` after lines to avoid ambiguous syntax (thanks @andreiradu) +- Fixed issue with tsconfig being overriden (thanks @Janne252) ## 0.7.0 -* Lualib runtime library is now compiled from TypeScript using the transpiler when building! - * Split up runtime library definition into individual files. - * Added multiple inclusion modes using the tsconfig option `lubLibImport`, options are: - * `require` : Requires the entire library if lualib features are used. - * `always` : Always require the runtime library. - * `inline` : Inline the library code for used features in the file. - * `none` : Do not include the runtime library -* Added support for assigning expressions (`+=`, `&=`, `++`, etc) in other expressions (i.e. `lastIndex = i++` or `return a += b`) by transpiling them as immediately called anonymous functions. -* Unreachable code (after returns) is no longer transpiled, preventing a Lua syntax error. -* Fixed issue with destructing statements in Lua 5.1 -* Fixed issue with escaped characters in strings. -* Fixed bug regarding changing an exported variable after its export. +- Lualib runtime library is now compiled from TypeScript using the transpiler when building! + - Split up runtime library definition into individual files. + - Added multiple inclusion modes using the tsconfig option `lubLibImport`, options are: + - `require` : Requires the entire library if lualib features are used. + - `always` : Always require the runtime library. + - `inline` : Inline the library code for used features in the file. + - `none` : Do not include the runtime library +- Added support for assigning expressions (`+=`, `&=`, `++`, etc) in other expressions (i.e. `lastIndex = i++` or `return a += b`) by transpiling them as immediately called anonymous functions. +- Unreachable code (after returns) is no longer transpiled, preventing a Lua syntax error. +- Fixed issue with destructing statements in Lua 5.1 +- Fixed issue with escaped characters in strings. +- Fixed bug regarding changing an exported variable after its export. ## 0.6.0 -* Reworked part of the class system to solve some issues. -* Reworked class tests from translation to functional. -* Fixed issue with Lua splice implementation. -* Added threaded test runner to use for faster testing (use with `npm run test-threaded`). -* Added support for string-valued enums. -* Added tsconfig values to target Lua 5.1 and 5.2. + +- Reworked part of the class system to solve some issues. +- Reworked class tests from translation to functional. +- Fixed issue with Lua splice implementation. +- Added threaded test runner to use for faster testing (use with `npm run test-threaded`). +- Added support for string-valued enums. +- Added tsconfig values to target Lua 5.1 and 5.2. ## 0.5.0 -* Added support for `**` operator. -* Added support for `~` operator. -* Improved handling of assignment binary operators (`+=`,`*=`,`&=`, etc). -* Rewrote `Map` and `Set` to implement the ES6 specification for [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set). -* Added support for `baseUrl` in [tsconfig](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). -* Added `bit32` bit operations for Lua 5.2. -* Fixed various little bugs. -* Added tslint rule to enforce use of `/** @override */` decorator. -* Improved tests. + +- Added support for `**` operator. +- Added support for `~` operator. +- Improved handling of assignment binary operators (`+=`,`*=`,`&=`, etc). +- Rewrote `Map` and `Set` to implement the ES6 specification for [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) and [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set). +- Added support for `baseUrl` in [tsconfig](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). +- Added `bit32` bit operations for Lua 5.2. +- Fixed various little bugs. +- Added tslint rule to enforce use of `/** @override */` decorator. +- Improved tests. ## 0.4.0 -* Added support for `typeof` -* Added support for `instanceof` -* Added support for [TypeScript overloads](https://www.typescriptlang.org/docs/handbook/functions.html#overloads) + +- Added support for `typeof` +- Added support for `instanceof` +- Added support for [TypeScript overloads](https://www.typescriptlang.org/docs/handbook/functions.html#overloads) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d298d2374..f44bb3522 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,30 +1,33 @@ # Contributing to TypeScriptToLua -1) [Project Overview](#project-overview) -2) [Running Tests](#running-tests) -3) [Testing Guidelines](#testing-guidelines) -4) [Coding Conventions](#coding-conventions) +1. [Project Overview](#project-overview) +2. [Running Tests](#running-tests) +3. [Testing Guidelines](#testing-guidelines) +4. [Coding Conventions](#coding-conventions) ## Project Overview + To get familiar with the project structure, here is a short overview of each directory and their function. + - `src/` - * Source code for the project, has the transpiler core files in its root. - * `src/lualib/` + - Source code for the project, has the transpiler core files in its root. + - `src/lualib/` - Contains the TypeScript source for the lualib. This consists of implementations of standard TypeScript functions that are not present in Lua. These files are compiled to Lua using the transpiler. They are included in the Lua result when transpiling. - * `src/targets/` + - `src/targets/` - Version-specific transpiler overrides for the different Lua targets. The main transpiler transpiles Lua 5.0, each target-specific transpiler extends the transpiler of the version before it, so the 5.3 inherits 5.2 which inherits 5.1 which inherits 5.0. LuaJIT is based on 5.2 so inherits from the 5.2 transpiler. - * *Compiler.ts* - Main entry point of the transpiler, this is what interfaces with the TypeScript compiler API. - * *LuaTransformer.ts* - Main transpiler code, transforms a TypeScript AST to a Lua AST. - * *LuaPrinter.ts* - Transforms a Lua AST to a string. - * *TSHelper.ts* - Helper methods used during the transpilation process. + - _Compiler.ts_ - Main entry point of the transpiler, this is what interfaces with the TypeScript compiler API. + - _LuaTransformer.ts_ - Main transpiler code, transforms a TypeScript AST to a Lua AST. + - _LuaPrinter.ts_ - Transforms a Lua AST to a string. + - _TSHelper.ts_ - Helper methods used during the transpilation process. - `test/` - * This directory contains all testing code for the transpiler. - * `test/unit/` + - This directory contains all testing code for the transpiler. + - `test/unit/` - Unit/Functional tests for the transpiler. Tests in here are grouped by functionality they are testing. Generally each of these tests uses the transpiler to transpile some TypeScript to Lua, then executes it using the Fengari Lua VM. Assertion is done on the result of the lua code. - * `test/translation/` + - `test/translation/` - **[Obsolete]** Contains tests that only check the transpiled Lua String. We prefer adding unit/functional tests over translation tests. This directory will probably be removed at some point. ## Running Tests + The tests for this project can be executed using the standard `npm test`. This runs all tests. Due to the time required to run all tests, it is impractical to run every test while developing part of the transpiler. To speed up the test run you can: @@ -46,14 +49,17 @@ Due to the time required to run all tests, it is impractical to run every test w ``` ## Testing Guidelines + When submitting a pull request with new functionality, we require some functional (transpile and execute Lua) to be added, to ensure the new functionality works as expected, and will continue to work that way. Translation tests are discouraged as in most cases as we do not really care about the exact Lua output, as long as executing it results in the correct result (which is tested by functional tests). ## Coding Conventions + Most coding conventions are enforced by the TSLint and Prettier. You can check your code locally by running `npm run lint`. The CI build will fail if your code does not pass the linter. For better experience, you can install extensions for your code editor for [TSLint](https://palantir.github.io/tslint/usage/third-party-tools/) and [Prettier](https://prettier.io/docs/en/editors.html). Some extra conventions worth mentioning: -* Do not abbreviate variable names. The exception here are inline lambda arguments, if it is obvious what the argument is you can abbreviate to the first letter, e.g: `statements.filter(s => ts.VariableStatement(s))` -* Readability of code is more important than the amount of space it takes. If extra line breaks make your code more readable, add them. -* Functional style is encouraged! + +- Do not abbreviate variable names. The exception here are inline lambda arguments, if it is obvious what the argument is you can abbreviate to the first letter, e.g: `statements.filter(s => ts.VariableStatement(s))` +- Readability of code is more important than the amount of space it takes. If extra line breaks make your code more readable, add them. +- Functional style is encouraged! diff --git a/README.md b/README.md index 21b013de7..024e3ca3e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ A generic TypeScript to Lua transpiler. Write your code in TypeScript and publis Large projects written in lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good IDE support. This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. ## Documentation + More detailed documentation and info on writing declarations can be found [on the wiki](https://github.com/TypeScriptToLua/TypescriptToLua/wiki). Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CHANGELOG.md) @@ -38,24 +39,28 @@ Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/Type `tstl -p path/to/tsconfig.json --watch` **Example tsconfig.json** + ```json { - "compilerOptions": { - "target": "esnext", - "lib": ["esnext"], - "strict": true - }, - "tstl": { - "luaTarget": "JIT" - } + "compilerOptions": { + "target": "esnext", + "lib": ["esnext"], + "strict": true + }, + "tstl": { + "luaTarget": "JIT" + } } ``` ## Contributing + All contributions are welcome, but please read our [contribution guidelines](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CONTRIBUTING.md)! ## Declarations + The real power of this transpiler is usage together with good declarations for the Lua API provided. Some examples of Lua interface declarations can be found here: + - [Dota 2 Modding](https://github.com/ModDota/API/tree/master/declarations/server) - [Defold Game Engine Scripting](https://github.com/dasannikov/DefoldTypeScript/blob/master/defold.d.ts) - [LÖVE 2D Game Development](https://github.com/hazzard993/love-typescript-definitions) @@ -71,12 +76,14 @@ The real power of this transpiler is usage together with good declarations for t `npm run coverage` or `npm run coverage-html` to generate a coverage report. ## Sublime Text integration + This compiler works great in combination with the [Sublime Text Typescript plugin](https://github.com/Microsoft/TypeScript-Sublime-Plugin) (available through the package manager as `TypeScript`). You can simply open your typescript project assuming a valid tsconfig.json file is present. The default TypeScript plugin will provide all functionality of a regular TypeScript project. ### Setting up a custom build system -To add the option to build with the Lua transpiler instead of the regular typescript compiler, go to `Tools > Build System > New Build System...`. In the new sublime-build file that opens, enter the following (adjust path to tstl if not installed globally): + +To add the option to build with the Lua transpiler instead of the regular typescript compiler, go to `Tools > Build System > New Build System...`. In the new sublime-build file that opens, enter the following (adjust path to tstl if not installed globally): ``` { @@ -84,4 +91,5 @@ To add the option to build with the Lua transpiler instead of the regular typesc "shell": true } ``` + Save this in your Sublime settings as a `TypeScriptToLua.sublime-build`. You can now select the TypeScriptToLua build system in `Tools > Build System` to build using the normal hotkey (`ctrl+B`), or if you have multiple TypeScript projects open, you can choose your compiler before building by pressing `ctrl+shift+B`. diff --git a/package.json b/package.json index 8bceba6b6..aaa0e27b8 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", - "lint:prettier": "prettier --check **/*.{js,ts,yml,json} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", + "lint:prettier": "prettier --check **/*.{js,ts,yml,json,md} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:tslint": "tslint -p . && tslint -p test && tslint -p src/lualib", - "fix:prettier": "prettier --check --write **/*.{js,ts,yml,json}", + "fix:prettier": "prettier --check --write **/*.{js,ts,yml,json,md}", "release-major": "npm version major", "release-minor": "npm version minor", "release-patch": "npm version patch", diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index a63f936d3..c2fb5b975 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -97,9 +97,7 @@ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): if (parsedConfigFile.raw.tstl) { if (hasRootLevelOptions) { - parsedConfigFile.errors.push( - diagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl) - ); + parsedConfigFile.errors.push(diagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl)); } for (const key in parsedConfigFile.raw.tstl) { @@ -122,10 +120,7 @@ export function parseCommandLine(args: string[]): ParsedCommandLine { return updateParsedCommandLine(ts.parseCommandLine(args), args); } -function updateParsedCommandLine( - parsedCommandLine: ts.ParsedCommandLine, - args: string[] -): ParsedCommandLine { +function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: string[]): ParsedCommandLine { for (let i = 0; i < args.length; i++) { if (!args[i].startsWith("-")) continue; @@ -143,10 +138,10 @@ function updateParsedCommandLine( if (option) { // Ignore errors caused by tstl specific compiler options const tsInvalidCompilerOptionErrorCode = 5023; - parsedCommandLine.errors = parsedCommandLine.errors.filter(err => { + parsedCommandLine.errors = parsedCommandLine.errors.filter(error => { return !( - err.code === tsInvalidCompilerOptionErrorCode && - String(err.messageText).endsWith(`'${args[i]}'.`) + error.code === tsInvalidCompilerOptionErrorCode && + String(error.messageText).endsWith(`'${args[i]}'.`) ); }); diff --git a/src/Emit.ts b/src/Emit.ts index 74b6f3eb3..e2004b0f9 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -12,10 +12,7 @@ export interface OutputFile { } let lualibContent: string; -export function emitTranspiledFiles( - options: CompilerOptions, - transpiledFiles: TranspiledFile[] -): OutputFile[] { +export function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: TranspiledFile[]): OutputFile[] { let { rootDir, outDir, outFile, luaLibImport } = options; const configFileName = options.configFilePath as string | undefined; @@ -60,10 +57,7 @@ export function emitTranspiledFiles( if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) { if (lualibContent === undefined) { - lualibContent = fs.readFileSync( - path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), - "utf8" - ); + lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); } let outPath = path.resolve(rootDir, "lualib_bundle.lua"); diff --git a/src/LuaAST.ts b/src/LuaAST.ts index edce002e1..7616177e4 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -8,6 +8,7 @@ import * as ts from "typescript"; export enum SyntaxKind { Block, + // Statements DoStatement, VariableDeclarationStatement, @@ -22,6 +23,7 @@ export enum SyntaxKind { ReturnStatement, BreakStatement, ExpressionStatement, + // Expression StringLiteral, NumericLiteral, @@ -39,60 +41,83 @@ export enum SyntaxKind { MethodCallExpression, Identifier, TableIndexExpression, + // Operators + // Arithmetic - AdditionOperator, // Maybe use abbreviations for those add, sub, mul ... + AdditionOperator, // Maybe use abbreviations for those add, sub, mul ... SubtractionOperator, MultiplicationOperator, DivisionOperator, FloorDivisionOperator, ModuloOperator, PowerOperator, - NegationOperator, // Unary minus + NegationOperator, // Unary minus + // Concat ConcatOperator, + // Length - LengthOperator, // Unary + LengthOperator, // Unary + // Relational Ops EqualityOperator, InequalityOperator, LessThanOperator, LessEqualOperator, - GreaterThanOperator, // Syntax Sugar `x > y` <=> `not (y <= x)` - // but we should probably use them to make the output code more readable - GreaterEqualOperator, // Syntax Sugar `x >= y` <=> `not (y < x)` + // Syntax Sugar `x > y` <=> `not (y <= x)` + // but we should probably use them to make the output code more readable + GreaterThanOperator, + GreaterEqualOperator, // Syntax Sugar `x >= y` <=> `not (y < x)` + // Logical AndOperator, OrOperator, - NotOperator, // Unary + NotOperator, // Unary + // Bitwise BitwiseAndOperator, BitwiseOrOperator, BitwiseExclusiveOrOperator, BitwiseRightShiftOperator, BitwiseLeftShiftOperator, - BitwiseNotOperator, // Unary + BitwiseNotOperator, // Unary } // TODO maybe name this PrefixUnary? not sure it makes sense to do so, because all unary ops in Lua are prefix export type UnaryBitwiseOperator = SyntaxKind.BitwiseNotOperator; -export type UnaryOperator = SyntaxKind.NegationOperator +export type UnaryOperator = + | SyntaxKind.NegationOperator | SyntaxKind.LengthOperator | SyntaxKind.NotOperator | UnaryBitwiseOperator; -export type BinaryBitwiseOperator = SyntaxKind.BitwiseAndOperator | SyntaxKind.BitwiseOrOperator - | SyntaxKind.BitwiseExclusiveOrOperator | SyntaxKind.BitwiseRightShiftOperator +export type BinaryBitwiseOperator = + | SyntaxKind.BitwiseAndOperator + | SyntaxKind.BitwiseOrOperator + | SyntaxKind.BitwiseExclusiveOrOperator + | SyntaxKind.BitwiseRightShiftOperator | SyntaxKind.BitwiseLeftShiftOperator; export type BinaryOperator = - SyntaxKind.AdditionOperator | SyntaxKind.SubtractionOperator | SyntaxKind.MultiplicationOperator - | SyntaxKind.DivisionOperator | SyntaxKind.FloorDivisionOperator | SyntaxKind.ModuloOperator - | SyntaxKind.PowerOperator | SyntaxKind.ConcatOperator | SyntaxKind.EqualityOperator - | SyntaxKind.InequalityOperator | SyntaxKind.LessThanOperator | SyntaxKind.LessEqualOperator - | SyntaxKind.GreaterThanOperator | SyntaxKind.GreaterEqualOperator | SyntaxKind.AndOperator - | SyntaxKind.OrOperator | BinaryBitwiseOperator; + | SyntaxKind.AdditionOperator + | SyntaxKind.SubtractionOperator + | SyntaxKind.MultiplicationOperator + | SyntaxKind.DivisionOperator + | SyntaxKind.FloorDivisionOperator + | SyntaxKind.ModuloOperator + | SyntaxKind.PowerOperator + | SyntaxKind.ConcatOperator + | SyntaxKind.EqualityOperator + | SyntaxKind.InequalityOperator + | SyntaxKind.LessThanOperator + | SyntaxKind.LessEqualOperator + | SyntaxKind.GreaterThanOperator + | SyntaxKind.GreaterEqualOperator + | SyntaxKind.AndOperator + | SyntaxKind.OrOperator + | BinaryBitwiseOperator; export type Operator = UnaryOperator | BinaryOperator; @@ -110,14 +135,14 @@ export interface Node extends TextRange { export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node { if (tsOriginal === undefined) { - return {kind, parent}; + return { kind, parent }; } const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { - return {kind, parent, line: sourcePosition.line, column: sourcePosition.column}; + return { kind, parent, line: sourcePosition.line, column: sourcePosition.column }; } else { - return {kind, parent}; + return { kind, parent }; } } @@ -147,7 +172,7 @@ export function setNodeOriginal(node: T | undefined, tsOriginal: return node; } -export function setParent(node: Node | Node[] | undefined, parent: Node): void { +export function setParent(node: Node | Node[] | undefined, parent: Node): void { if (!node) { return; } @@ -162,7 +187,6 @@ export function setParent(node: Node | Node[] | undefined, parent: Node): void function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { if (sourceNode !== undefined && sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { - const { line, character } = ts.getLineAndCharacterOfPosition( sourceNode.getSourceFile(), sourceNode.pos + sourceNode.getLeadingTriviaWidth() @@ -228,8 +252,7 @@ export function createVariableDeclarationStatement( right?: Expression | Expression[], tsOriginal?: ts.Node, parent?: Node -): VariableDeclarationStatement -{ +): VariableDeclarationStatement { const statement = createNode( SyntaxKind.VariableDeclarationStatement, tsOriginal, @@ -263,11 +286,10 @@ export function isAssignmentStatement(node: Node): node is AssignmentStatement { export function createAssignmentStatement( left: AssignmentLeftHandSideExpression | AssignmentLeftHandSideExpression[], - right?: Expression | Expression[], + right?: Expression | Expression[], tsOriginal?: ts.Node, parent?: Node -): AssignmentStatement -{ +): AssignmentStatement { const statement = createNode(SyntaxKind.AssignmentStatement, tsOriginal, parent) as AssignmentStatement; setParent(left, statement); if (Array.isArray(left)) { @@ -301,8 +323,7 @@ export function createIfStatement( elseBlock?: Block | IfStatement, tsOriginal?: ts.Node, parent?: Node -): IfStatement -{ +): IfStatement { const statement = createNode(SyntaxKind.IfStatement, tsOriginal, parent) as IfStatement; setParent(condition, statement); statement.condition = condition; @@ -318,8 +339,12 @@ export interface IterationStatement extends Statement { } export function isIterationStatement(node: Node): node is IterationStatement { - return node.kind === SyntaxKind.WhileStatement || node.kind === SyntaxKind.RepeatStatement - || node.kind === SyntaxKind.ForStatement || node.kind === SyntaxKind.ForInStatement; + return ( + node.kind === SyntaxKind.WhileStatement || + node.kind === SyntaxKind.RepeatStatement || + node.kind === SyntaxKind.ForStatement || + node.kind === SyntaxKind.ForInStatement + ); } export interface WhileStatement extends IterationStatement { @@ -336,8 +361,7 @@ export function createWhileStatement( condition: Expression, tsOriginal?: ts.Node, parent?: Node -): WhileStatement -{ +): WhileStatement { const statement = createNode(SyntaxKind.WhileStatement, tsOriginal, parent) as WhileStatement; setParent(body, statement); statement.body = body; @@ -360,8 +384,7 @@ export function createRepeatStatement( condition: Expression, tsOriginal?: ts.Node, parent?: Node -): RepeatStatement -{ +): RepeatStatement { const statement = createNode(SyntaxKind.RepeatStatement, tsOriginal, parent) as RepeatStatement; setParent(body, statement); statement.body = body; @@ -391,8 +414,7 @@ export function createForStatement( stepExpression?: Expression, tsOriginal?: ts.Node, parent?: Node -): ForStatement -{ +): ForStatement { const statement = createNode(SyntaxKind.ForStatement, tsOriginal, parent) as ForStatement; setParent(body, statement); statement.body = body; @@ -423,8 +445,7 @@ export function createForInStatement( expressions: Expression[], tsOriginal?: ts.Node, parent?: Node -): ForInStatement -{ +): ForInStatement { const statement = createNode(SyntaxKind.ForInStatement, tsOriginal, parent) as ForInStatement; setParent(body, statement); statement.body = body; @@ -437,7 +458,7 @@ export function createForInStatement( export interface GotoStatement extends Statement { kind: SyntaxKind.GotoStatement; - label: string; // or identifier ? + label: string; // or identifier ? } export function isGotoStatement(node: Node): node is GotoStatement { @@ -452,7 +473,7 @@ export function createGotoStatement(label: string, tsOriginal?: ts.Node, parent? export interface LabelStatement extends Statement { kind: SyntaxKind.LabelStatement; - name: string; // or identifier ? + name: string; // or identifier ? } export function isLabelStatement(node: Node): node is LabelStatement { @@ -478,8 +499,7 @@ export function createReturnStatement( expressions?: Expression[], tsOriginal?: ts.Node, parent?: Node -): ReturnStatement -{ +): ReturnStatement { const statement = createNode(SyntaxKind.ReturnStatement, tsOriginal, parent) as ReturnStatement; setParent(expressions, statement); statement.expressions = expressions; @@ -511,8 +531,7 @@ export function createExpressionStatement( expressions: Expression, tsOriginal?: ts.Node, parent?: Node -): ExpressionStatement -{ +): ExpressionStatement { const statement = createNode(SyntaxKind.ExpressionStatement, tsOriginal, parent) as ExpressionStatement; setParent(expressions, statement); statement.expression = expressions; @@ -628,8 +647,7 @@ export function createFunctionExpression( flags = FunctionExpressionFlags.None, tsOriginal?: ts.Node, parent?: Node -): FunctionExpression -{ +): FunctionExpression { const expression = createNode(SyntaxKind.FunctionExpression, tsOriginal, parent) as FunctionExpression; setParent(body, expression); expression.body = body; @@ -658,8 +676,7 @@ export function createTableFieldExpression( key?: Expression, tsOriginal?: ts.Node, parent?: Node -): TableFieldExpression -{ +): TableFieldExpression { const expression = createNode(SyntaxKind.TableExpression, tsOriginal, parent) as TableFieldExpression; setParent(value, expression); expression.value = value; @@ -681,8 +698,7 @@ export function createTableExpression( fields?: TableFieldExpression[], tsOriginal?: ts.Node, parent?: Node -): TableExpression -{ +): TableExpression { const expression = createNode(SyntaxKind.TableExpression, tsOriginal, parent) as TableExpression; setParent(fields, expression); expression.fields = fields; @@ -704,8 +720,7 @@ export function createUnaryExpression( operator: UnaryOperator, tsOriginal?: ts.Node, parent?: Node -): UnaryExpression -{ +): UnaryExpression { const expression = createNode(SyntaxKind.UnaryExpression, tsOriginal, parent) as UnaryExpression; setParent(operand, expression); expression.operand = operand; @@ -730,8 +745,7 @@ export function createBinaryExpression( operator: BinaryOperator, tsOriginal?: ts.Node, parent?: Node -): BinaryExpression -{ +): BinaryExpression { const expression = createNode(SyntaxKind.BinaryExpression, tsOriginal, parent) as BinaryExpression; setParent(left, expression); expression.left = left; @@ -754,8 +768,7 @@ export function createParenthesizedExpression( innerExpression: Expression, tsOriginal?: ts.Node, parent?: Node -): ParenthesizedExpression -{ +): ParenthesizedExpression { const expression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal, parent) as ParenthesizedExpression; setParent(innerExpression, expression); expression.innerExpression = innerExpression; @@ -777,8 +790,7 @@ export function createCallExpression( params?: Expression[], tsOriginal?: ts.Node, parent?: Node -): CallExpression -{ +): CallExpression { const callExpression = createNode(SyntaxKind.CallExpression, tsOriginal, parent) as CallExpression; setParent(expression, callExpression); callExpression.expression = expression; @@ -804,8 +816,7 @@ export function createMethodCallExpression( params?: Expression[], tsOriginal?: ts.Node, parent?: Node -): MethodCallExpression -{ +): MethodCallExpression { const callExpression = createNode(SyntaxKind.MethodCallExpression, tsOriginal, parent) as MethodCallExpression; setParent(prefixExpression, callExpression); callExpression.prefixExpression = prefixExpression; @@ -831,8 +842,7 @@ export function createIdentifier( tsOriginal?: ts.Node, symbolId?: SymbolId, parent?: Node -): Identifier -{ +): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; expression.text = text as string; expression.symbolId = symbolId; @@ -864,8 +874,7 @@ export function createTableIndexExpression( index: Expression, tsOriginal?: ts.Node, parent?: Node -): TableIndexExpression -{ +): TableIndexExpression { const expression = createNode(SyntaxKind.TableIndexExpression, tsOriginal, parent) as TableIndexExpression; setParent(table, expression); expression.table = table; @@ -880,23 +889,27 @@ export type FunctionDefinition = (VariableDeclarationStatement | AssignmentState right: [FunctionExpression]; }; -export function isFunctionDefinition(statement: VariableDeclarationStatement | AssignmentStatement) - : statement is FunctionDefinition -{ - return statement.left.length === 1 - && statement.right !== undefined - && statement.right.length === 1 - && isFunctionExpression(statement.right[0]); +export function isFunctionDefinition( + statement: VariableDeclarationStatement | AssignmentStatement +): statement is FunctionDefinition { + return ( + statement.left.length === 1 && + statement.right !== undefined && + statement.right.length === 1 && + isFunctionExpression(statement.right[0]) + ); } export type InlineFunctionExpression = FunctionExpression & { - body: { statements: [ReturnStatement & { expressions: Expression[] }]; }; + body: { statements: [ReturnStatement & { expressions: Expression[] }] }; }; -export function isInlineFunctionExpression(expression: FunctionExpression) : expression is InlineFunctionExpression { - return expression.body.statements !== undefined - && expression.body.statements.length === 1 - && isReturnStatement(expression.body.statements[0]) - && (expression.body.statements[0] as ReturnStatement).expressions !== undefined - && (expression.flags & FunctionExpressionFlags.Inline) !== 0; +export function isInlineFunctionExpression(expression: FunctionExpression): expression is InlineFunctionExpression { + return ( + expression.body.statements !== undefined && + expression.body.statements.length === 1 && + isReturnStatement(expression.body.statements[0]) && + (expression.body.statements[0] as ReturnStatement).expressions !== undefined && + (expression.flags & FunctionExpressionFlags.Inline) !== 0 + ); } diff --git a/src/LuaKeywords.ts b/src/LuaKeywords.ts index 6f3bff133..55aa120f9 100644 --- a/src/LuaKeywords.ts +++ b/src/LuaKeywords.ts @@ -1,9 +1,46 @@ export const luaKeywords: Set = new Set([ - "and", "break", "do", "else", "elseif", "end", "false", "for", "function", "goto", "if", "in", "local", "nil", - "not", "or", "repeat", "return", "then", "until", "while", + "and", + "break", + "do", + "else", + "elseif", + "end", + "false", + "for", + "function", + "goto", + "if", + "in", + "local", + "nil", + "not", + "or", + "repeat", + "return", + "then", + "until", + "while", ]); export const luaBuiltins: Set = new Set([ - "_G", "assert", "coroutine", "debug", "error", "ipairs", "math", "pairs", "pcall", "print", "rawget", "rawset", - "repeat", "require", "self", "string", "table", "tostring", "type", "unpack", + "_G", + "assert", + "coroutine", + "debug", + "error", + "ipairs", + "math", + "pairs", + "pcall", + "print", + "rawget", + "rawset", + "repeat", + "require", + "self", + "string", + "table", + "tostring", + "type", + "unpack", ]); diff --git a/src/LuaLib.ts b/src/LuaLib.ts index d339fc945..70799e090 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -56,7 +56,7 @@ export enum LuaLibFeature { SymbolRegistry = "SymbolRegistry", } -const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = { +const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], InstanceOf: [LuaLibFeature.Symbol], diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index ba5da24f6..0792cb7bc 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -11,7 +11,7 @@ import { luaKeywords } from "./LuaKeywords"; type SourceChunk = string | SourceNode; export class LuaPrinter { - private static operatorMap: {[key in tstl.Operator]: string} = { + private static operatorMap: { [key in tstl.Operator]: string } = { [tstl.SyntaxKind.AdditionOperator]: "+", [tstl.SyntaxKind.SubtractionOperator]: "-", [tstl.SyntaxKind.MultiplicationOperator]: "*", @@ -60,8 +60,9 @@ export class LuaPrinter { const rootSourceNode = this.printImplementation(block, luaLibFeatures, sourceFile); - const sourceRoot = this.options.sourceRoot - || (this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : "."); + const sourceRoot = + this.options.sourceRoot || + (this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : "."); const sourceMap = this.buildSourceMap(sourceFile, sourceRoot, rootSourceNode); @@ -81,14 +82,14 @@ export class LuaPrinter { private printInlineSourceMap(sourceMap: SourceMapGenerator): string { const map = sourceMap.toString(); - const base64Map = Buffer.from(map).toString('base64'); + const base64Map = Buffer.from(map).toString("base64"); return `--# sourceMappingURL=data:application/json;base64,${base64Map}\n`; } private printStackTraceOverride(rootNode: SourceNode): string { let line = 1; - const map: {[line: number]: number} = {}; + const map: { [line: number]: number } = {}; rootNode.walk((chunk, mappedPosition) => { if (mappedPosition.line !== undefined && mappedPosition.line > 0) { if (map[line] === undefined) { @@ -110,11 +111,7 @@ export class LuaPrinter { return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printImplementation( - block: tstl.Block, - luaLibFeatures?: Set, - sourceFile = ""): SourceNode { - + private printImplementation(block: tstl.Block, luaLibFeatures?: Set, sourceFile = ""): SourceNode { let header = ""; if (!this.options.noHeader) { @@ -124,9 +121,10 @@ export class LuaPrinter { if (luaLibFeatures) { const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Inline; // Require lualib bundle - if ((luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) - || luaLibImport === LuaLibImportKind.Always) - { + if ( + (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) || + luaLibImport === LuaLibImportKind.Always + ) { header += `require("lualib_bundle");\n`; } // Inline lualib features @@ -164,8 +162,7 @@ export class LuaPrinter { return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks) - // tslint:disable-next-line:no-null-keyword - : new SourceNode(null, null, this.sourceFile, chunks); + : new SourceNode(null, null, this.sourceFile, chunks); // tslint:disable-line:no-null-keyword } protected concatNodes(...chunks: SourceChunk[]): SourceNode { @@ -179,9 +176,11 @@ export class LuaPrinter { private statementMayRequireSemiColon(statement: tstl.Statement): boolean { // Types of statements that could create ambiguous syntax if followed by parenthesis - return tstl.isVariableDeclarationStatement(statement) - || tstl.isAssignmentStatement(statement) - || tstl.isExpressionStatement(statement); + return ( + tstl.isVariableDeclarationStatement(statement) || + tstl.isAssignmentStatement(statement) || + tstl.isExpressionStatement(statement) + ); } private nodeStartsWithParenthesis(sourceNode: SourceNode): boolean { @@ -201,20 +200,15 @@ export class LuaPrinter { protected printStatementArray(statements: tstl.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; statements = this.removeDeadAndEmptyStatements(statements); - statements.forEach( - (s, i) => { - const node = this.printStatement(s); - - if (i > 0 - && this.statementMayRequireSemiColon(statements[i - 1]) - && this.nodeStartsWithParenthesis(node)) - { - statementNodes[i - 1].add(";"); - } + statements.forEach((s, i) => { + const node = this.printStatement(s); - statementNodes.push(node); + if (i > 0 && this.statementMayRequireSemiColon(statements[i - 1]) && this.nodeStartsWithParenthesis(node)) { + statementNodes[i - 1].add(";"); } - ); + + statementNodes.push(node); + }); return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } @@ -271,7 +265,6 @@ export class LuaPrinter { if (tstl.isFunctionDefinition(statement)) { // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion chunks.push(this.printFunctionDefinition(statement)); - } else { chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); @@ -289,9 +282,10 @@ export class LuaPrinter { chunks.push(this.indent()); - if (tstl.isFunctionDefinition(statement) - && (statement.right[0].flags & tstl.FunctionExpressionFlags.Declaration) !== 0) - { + if ( + tstl.isFunctionDefinition(statement) && + (statement.right[0].flags & tstl.FunctionExpressionFlags.Declaration) !== 0 + ) { // Use `function foo()` instead of `foo = function()` const name = this.printExpression(statement.left[0]); if (tsHelper.isValidLuaFunctionDeclarationName(name.toString())) { @@ -310,8 +304,7 @@ export class LuaPrinter { public printIfStatement(statement: tstl.IfStatement): SourceNode { const chunks: SourceChunk[] = []; - const isElseIf = statement.parent !== undefined - && tstl.isIfStatement(statement.parent); + const isElseIf = statement.parent !== undefined && tstl.isIfStatement(statement.parent); const prefix = isElseIf ? "elseif" : "if"; @@ -524,7 +517,6 @@ export class LuaPrinter { ]; chunks.push(this.createSourceNode(returnStatement, returnNode)); chunks.push(" end"); - } else { chunks.push("\n"); this.pushIndent(); @@ -560,10 +552,11 @@ export class LuaPrinter { const value = this.printExpression(expression.value); if (expression.key) { - if (tstl.isStringLiteral(expression.key) - && tsHelper.isValidLuaIdentifier(expression.key.value) - && !luaKeywords.has(expression.key.value)) - { + if ( + tstl.isStringLiteral(expression.key) && + tsHelper.isValidLuaIdentifier(expression.key.value) && + !luaKeywords.has(expression.key.value) + ) { chunks.push(expression.key.value, " = ", value); } else { chunks.push("[", this.printExpression(expression.key), "] = ", value); @@ -584,7 +577,6 @@ export class LuaPrinter { if (expression.fields.length === 1) { // Inline tables with only one entry chunks.push(this.printTableFieldExpression(expression.fields[0])); - } else { chunks.push("\n"); this.pushIndent(); @@ -625,9 +617,8 @@ export class LuaPrinter { public printCallExpression(expression: tstl.CallExpression): SourceNode { const chunks = []; - const parameterChunks = expression.params !== undefined - ? expression.params.map(e => this.printExpression(e)) - : []; + const parameterChunks = + expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : []; chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")"); @@ -637,16 +628,19 @@ export class LuaPrinter { public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { const prefix = this.printExpression(expression.prefixExpression); - const parameterChunks = expression.params !== undefined - ? expression.params.map(e => this.printExpression(e)) - : []; + const parameterChunks = + expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : []; const name = this.printIdentifier(expression.name); - return this.createSourceNode( - expression, - [prefix, ":", name, "(", ...this.joinChunks(", ", parameterChunks), ")"] - ); + return this.createSourceNode(expression, [ + prefix, + ":", + name, + "(", + ...this.joinChunks(", ", parameterChunks), + ")", + ]); } public printIdentifier(expression: tstl.Identifier): SourceNode { @@ -657,10 +651,11 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.table)); - if (tstl.isStringLiteral(expression.index) - && tsHelper.isValidLuaIdentifier(expression.index.value) - && !luaKeywords.has(expression.index.value)) - { + if ( + tstl.isStringLiteral(expression.index) && + tsHelper.isValidLuaIdentifier(expression.index.value) && + !luaKeywords.has(expression.index.value) + ) { chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); } else { chunks.push("[", this.printExpression(expression.index), "]"); @@ -720,13 +715,15 @@ export class LuaPrinter { if (currentMapping === undefined) { return true; } - if (currentMapping.generated.line === generatedLine - && currentMapping.generated.column === generatedColumn) - { + if ( + currentMapping.generated.line === generatedLine && + currentMapping.generated.column === generatedColumn + ) { return false; } - return (currentMapping.original.line !== sourceNode.line - || currentMapping.original.column !== sourceNode.column); + return ( + currentMapping.original.line !== sourceNode.line || currentMapping.original.column !== sourceNode.column + ); }; const build = (sourceNode: SourceNode) => { @@ -748,7 +745,6 @@ export class LuaPrinter { currentMapping = undefined; // Mappings end at newlines } generatedColumn += lines[lines.length - 1].length; - } else { build(chunk); } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index d7e0b4eeb..2cd7db45c 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -80,11 +80,10 @@ export class LuaTransformer { public constructor(protected program: ts.Program) { this.checker = (program as any).getDiagnosticsProducingTypeChecker(); this.options = program.getCompilerOptions(); - this.isStrict = this.options.alwaysStrict !== undefined - || (this.options.strict !== undefined && this.options.alwaysStrict !== false) - || (this.isModule - && this.options.target !== undefined - && this.options.target >= ts.ScriptTarget.ES2015); + this.isStrict = + this.options.alwaysStrict !== undefined || + (this.options.strict !== undefined && this.options.alwaysStrict !== false) || + (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); this.luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; @@ -119,9 +118,7 @@ export class LuaTransformer { throw TSTLErrors.InvalidJsonFileContent(node); } - statements.push( - tstl.createReturnStatement([this.transformExpression(statement.expression)]) - ); + statements.push(tstl.createReturnStatement([this.transformExpression(statement.expression)])); } else { this.pushScope(ScopeType.File); @@ -140,11 +137,7 @@ export class LuaTransformer { ); // return exports - statements.push( - tstl.createReturnStatement( - [this.createExportsIdentifier()] - ) - ); + statements.push(tstl.createReturnStatement([this.createExportsIdentifier()])); } } @@ -241,10 +234,13 @@ export class LuaTransformer { public transformExportDeclaration(statement: ts.ExportDeclaration): StatementVisitResult { if (statement.exportClause) { - if (statement.exportClause.elements.some(e => - (e.name !== undefined && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) - || (e.propertyName !== undefined - && e.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword)) + if ( + statement.exportClause.elements.some( + e => + (e.name !== undefined && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || + (e.propertyName !== undefined && + e.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) + ) ) { throw TSTLErrors.UnsupportedDefaultExport(statement); } @@ -262,7 +258,7 @@ export class LuaTransformer { let exportedIdentifier: tstl.Expression | undefined; if (specifier.propertyName !== undefined) { exportedIdentifier = this.transformIdentifier(specifier.propertyName); - } else { + } else { const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(specifier); exportedIdentifier = this.createShorthandIdentifier(exportedSymbol, specifier.name); } @@ -277,9 +273,7 @@ export class LuaTransformer { // First transpile as import clause const importClause = ts.createImportClause( undefined, - ts.createNamedImports( - exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name)) - ) + ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) ); const importDeclaration = ts.createImportDeclaration( @@ -322,15 +316,12 @@ export class LuaTransformer { const forKey = tstl.createIdentifier("____exportKey"); const forValue = tstl.createIdentifier("____exportValue"); - const body = tstl.createBlock( - [tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createExportsIdentifier(), - forKey - ), + const body = tstl.createBlock([ + tstl.createAssignmentStatement( + tstl.createTableIndexExpression(this.createExportsIdentifier(), forKey), forValue - )] - ); + ), + ]); const pairsIdentifier = tstl.createIdentifier("pairs"); const forIn = tstl.createForInStatement( @@ -360,7 +351,7 @@ export class LuaTransformer { } const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; - const importPath = moduleSpecifier.text.replace(new RegExp("\"", "g"), ""); + const importPath = moduleSpecifier.text.replace(new RegExp('"', "g"), ""); if (!statement.importClause) { const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); @@ -386,9 +377,9 @@ export class LuaTransformer { const filteredElements = imports.elements.filter(e => { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); return ( - this.resolver.isReferencedAliasDeclaration(e) - && !decorators.has(DecoratorKind.Extension) - && !decorators.has(DecoratorKind.MetaExtension) + this.resolver.isReferencedAliasDeclaration(e) && + !decorators.has(DecoratorKind.Extension) && + !decorators.has(DecoratorKind.MetaExtension) ); }); @@ -398,9 +389,9 @@ export class LuaTransformer { } const tstlIdentifier = (name: string) => "__TSTL_" + tsHelper.fixInvalidLuaIdentifier(name); - const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename((importPath)))); + const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename(importPath))); const requireStatement = tstl.createVariableDeclarationStatement( - tstl.createIdentifier(tstlIdentifier(path.basename((importPath)))), + tstl.createIdentifier(tstlIdentifier(path.basename(importPath))), requireCall, statement ); @@ -412,7 +403,8 @@ export class LuaTransformer { const renamedImport = tstl.createVariableDeclarationStatement( this.transformIdentifier(importSpecifier.name), tstl.createTableIndexExpression(importUniqueName, propertyName), - importSpecifier); + importSpecifier + ); result.push(renamedImport); } else { const name = tstl.createStringLiteral(importSpecifier.name.text); @@ -430,7 +422,6 @@ export class LuaTransformer { } else { return result; } - } else if (ts.isNamespaceImport(imports)) { if (!this.resolver.isReferencedAliasDeclaration(imports)) { return undefined; @@ -453,7 +444,7 @@ export class LuaTransformer { private createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { const modulePathString = resolveModule - ? this.getImportPath(moduleSpecifier.text.replace(new RegExp("\"", "g"), ""), moduleSpecifier) + ? this.getImportPath(moduleSpecifier.text.replace(new RegExp('"', "g"), ""), moduleSpecifier) : moduleSpecifier.text; const modulePath = tstl.createStringLiteral(modulePathString); return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); @@ -470,8 +461,7 @@ export class LuaTransformer { public transformClassDeclaration( statement: ts.ClassLikeDeclaration, nameOverride?: tstl.Identifier - ): StatementVisitResult - { + ): StatementVisitResult { this.classStack.push(statement); if (statement.name === undefined && nameOverride === undefined) { @@ -560,8 +550,10 @@ export class LuaTransformer { ), [] ), - extendsName), - statement); + extendsName + ), + statement + ); result.push(assignDebugCallIndex); } @@ -577,11 +569,7 @@ export class LuaTransformer { let localClassName: tstl.Identifier; if (this.isUnsafeName(className.text)) { - localClassName = tstl.createIdentifier( - this.createSafeName(className.text), - undefined, - className.symbolId - ); + localClassName = tstl.createIdentifier(this.createSafeName(className.text), undefined, className.symbolId); tstl.setNodePosition(localClassName, className); } else { localClassName = className; @@ -600,14 +588,10 @@ export class LuaTransformer { for (const f of instanceFields) { const fieldName = this.transformPropertyName(f.name); - const value = f.initializer !== undefined - ? this.transformExpression(f.initializer) - : undefined; + const value = f.initializer !== undefined ? this.transformExpression(f.initializer) : undefined; // className["fieldName"] - const classField = tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), - fieldName); + const classField = tstl.createTableIndexExpression(tstl.cloneIdentifier(className), fieldName); // className["fieldName"] = value; const assignClassField = tstl.createAssignmentStatement(classField, value); @@ -618,8 +602,9 @@ export class LuaTransformer { // Find first constructor with body if (!isExtension && !isMetaExtension) { - const constructor = statement.members - .filter(n => ts.isConstructorDeclaration(n) && n.body)[0] as ts.ConstructorDeclaration; + const constructor = statement.members.filter( + n => ts.isConstructorDeclaration(n) && n.body + )[0] as ts.ConstructorDeclaration; if (constructor) { // Add constructor plus initialization of instance fields const constructorResult = this.transformConstructorDeclaration( @@ -638,9 +623,10 @@ export class LuaTransformer { statement ); result.push(...this.statementVisitResultToArray(constructorResult)); - } else if (instanceFields.length > 0 - || statement.members.some(m => tsHelper.isGetAccessorOverride(m, statement, this.checker))) - { + } else if ( + instanceFields.length > 0 || + statement.members.some(m => tsHelper.isGetAccessorOverride(m, statement, this.checker)) + ) { // Generate a constructor if none was defined in a class with instance fields that need initialization // localClassName.prototype.____constructor = function(self, ...) // baseClassName.prototype.____constructor(self, ...) @@ -663,11 +649,13 @@ export class LuaTransformer { undefined, tstl.FunctionExpressionFlags.Declaration ); - result.push(tstl.createAssignmentStatement( - this.createConstructorName(localClassName), - constructorFunction, - statement - )); + result.push( + tstl.createAssignmentStatement( + this.createConstructorName(localClassName), + constructorFunction, + statement + ) + ); } } @@ -700,15 +688,9 @@ export class LuaTransformer { const fieldName = this.transformPropertyName(field.name); const value = field.initializer ? this.transformExpression(field.initializer) : undefined; - const classField = tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - fieldName - ); + const classField = tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), fieldName); - const fieldAssign = tstl.createAssignmentStatement( - classField, - value - ); + const fieldAssign = tstl.createAssignmentStatement(classField, value); result.push(fieldAssign); } @@ -729,8 +711,7 @@ export class LuaTransformer { localClassName: tstl.Identifier, classNameText: string, extendsType?: ts.Type - ): tstl.Statement[] - { + ): tstl.Statement[] { const result: tstl.Statement[] = []; // [____exports.]className = {} @@ -803,10 +784,11 @@ export class LuaTransformer { } // localClassName.prototype = {} - const createClassPrototype = () => tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("prototype") - ); + const createClassPrototype = () => + tstl.createTableIndexExpression( + tstl.cloneIdentifier(localClassName), + tstl.createStringLiteral("prototype") + ); const classPrototypeTable = tstl.createTableExpression(); const assignClassPrototype = tstl.createAssignmentStatement( createClassPrototype(), @@ -841,7 +823,6 @@ export class LuaTransformer { statement ); result.push(assignClassPrototypeIndex); - } else { // localClassName.prototype.__index = localClassName.prototype const assignClassPrototypeIndex = tstl.createAssignmentStatement( @@ -902,10 +883,11 @@ export class LuaTransformer { } // localClassName.____super = extendsExpression - const createClassBase = () => tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("____super") - ); + const createClassBase = () => + tstl.createTableIndexExpression( + tstl.cloneIdentifier(localClassName), + tstl.createStringLiteral("____super") + ); const assignClassBase = tstl.createAssignmentStatement( createClassBase(), this.transformExpression(extendedTypeNode.expression), @@ -954,7 +936,6 @@ export class LuaTransformer { ) ); result.push(setClassMetatable); - } else { // setmetatable(localClassName, localClassName.____super) const setClassMetatable = tstl.createExpressionStatement( @@ -973,14 +954,13 @@ export class LuaTransformer { tstl.createStringLiteral("prototype") ); const setClassPrototypeMetatable = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("setmetatable"), - [createClassPrototype(), basePrototype] - ), + tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ + createClassPrototype(), + basePrototype, + ]), extendedTypeNode.expression ); result.push(setClassPrototypeMetatable); - } else if (hasStaticGetters || hasStaticSetters) { const metatableFields: tstl.TableFieldExpression[] = []; if (hasStaticGetters) { @@ -1006,10 +986,10 @@ export class LuaTransformer { } const setClassMetatable = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(localClassName), tstl.createTableExpression(metatableFields)] - ), + tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ + tstl.cloneIdentifier(localClassName), + tstl.createTableExpression(metatableFields), + ]), statement ); result.push(setClassMetatable); @@ -1020,20 +1000,18 @@ export class LuaTransformer { // local self = setmetatable({}, localClassName.prototype) const assignSelf = tstl.createVariableDeclarationStatement( this.createSelfIdentifier(), - tstl.createCallExpression( - tstl.createIdentifier("setmetatable"), - [tstl.createTableExpression(), createClassPrototype()] - ) + tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ + tstl.createTableExpression(), + createClassPrototype(), + ]) ); newFuncStatements.push(assignSelf); // self:____constructor(...) const callConstructor = tstl.createExpressionStatement( - tstl.createMethodCallExpression( - this.createSelfIdentifier(), - tstl.createIdentifier("____constructor"), - [tstl.createDotsLiteral()] - ) + tstl.createMethodCallExpression(this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [ + tstl.createDotsLiteral(), + ]) ); newFuncStatements.push(callConstructor); @@ -1044,9 +1022,7 @@ export class LuaTransformer { // function localClassName.new(construct, ...) ... end // or function export.localClassName.new(construct, ...) ... end const newFunc = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("new")), + tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("new")), tstl.createFunctionExpression( tstl.createBlock(newFuncStatements), undefined, @@ -1063,8 +1039,7 @@ export class LuaTransformer { private transformClassInstanceFields( classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] - ): tstl.Statement[] - { + ): tstl.Statement[] { const statements: tstl.Statement[] = []; for (const f of instanceFields) { @@ -1092,10 +1067,11 @@ export class LuaTransformer { const getterName = this.transformPropertyName(getter.name); const resetGetter = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("rawset"), - [this.createSelfIdentifier(), getterName, tstl.createNilLiteral()] - ) + tstl.createCallExpression(tstl.createIdentifier("rawset"), [ + this.createSelfIdentifier(), + getterName, + tstl.createNilLiteral(), + ]) ); statements.push(resetGetter); } @@ -1105,10 +1081,7 @@ export class LuaTransformer { private createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { return tstl.createTableIndexExpression( - tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), - tstl.createStringLiteral("prototype") - ), + tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")), tstl.createStringLiteral("____constructor") ); } @@ -1118,8 +1091,7 @@ export class LuaTransformer { className: tstl.Identifier, instanceFields: ts.PropertyDeclaration[], classDeclaration: ts.ClassLikeDeclaration - ): StatementVisitResult - { + ): StatementVisitResult { // Don't transform methods without body (overload declarations) if (!statement.body) { return undefined; @@ -1140,7 +1112,8 @@ export class LuaTransformer { // self.declarationName = declarationName or initializer const assignment = tstl.createAssignmentStatement( tstl.createTableIndexExpression( - this.createSelfIdentifier(), tstl.createStringLiteral(declarationName.text) + this.createSelfIdentifier(), + tstl.createStringLiteral(declarationName.text) ), tstl.createBinaryExpression( declarationName, @@ -1174,10 +1147,11 @@ export class LuaTransformer { // If there are field initializers and the first statement is a super call, hoist the super call to the top if (bodyWithFieldInitializers.length > 0 && statement.body && statement.body.statements.length > 0) { const firstStatement = statement.body.statements[0]; - if (ts.isExpressionStatement(firstStatement) - && ts.isCallExpression(firstStatement.expression) - && firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword) - { + if ( + ts.isExpressionStatement(firstStatement) && + ts.isCallExpression(firstStatement.expression) && + firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ) { const superCall = body.shift(); if (superCall) { bodyWithFieldInitializers.unshift(superCall); @@ -1207,8 +1181,7 @@ export class LuaTransformer { public transformGetAccessorDeclaration( getAccessor: ts.GetAccessorDeclaration, className: tstl.Identifier - ): StatementVisitResult - { + ): StatementVisitResult { if (getAccessor.body === undefined) { return undefined; } @@ -1230,14 +1203,8 @@ export class LuaTransformer { ? tstl.cloneIdentifier(className) : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); - const classGetters = tstl.createTableIndexExpression( - methodTable, - tstl.createStringLiteral("____getters") - ); - const getter = tstl.createTableIndexExpression( - classGetters, - tstl.createStringLiteral(name.text) - ); + const classGetters = tstl.createTableIndexExpression(methodTable, tstl.createStringLiteral("____getters")); + const getter = tstl.createTableIndexExpression(classGetters, tstl.createStringLiteral(name.text)); const assignGetter = tstl.createAssignmentStatement(getter, accessorFunction, getAccessor); return assignGetter; } @@ -1245,8 +1212,7 @@ export class LuaTransformer { public transformSetAccessorDeclaration( setAccessor: ts.SetAccessorDeclaration, className: tstl.Identifier - ): StatementVisitResult - { + ): StatementVisitResult { if (setAccessor.body === undefined) { return undefined; } @@ -1270,14 +1236,8 @@ export class LuaTransformer { ? tstl.cloneIdentifier(className) : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); - const classSetters = tstl.createTableIndexExpression( - methodTable, - tstl.createStringLiteral("____setters") - ); - const setter = tstl.createTableIndexExpression( - classSetters, - tstl.createStringLiteral(name.text) - ); + const classSetters = tstl.createTableIndexExpression(methodTable, tstl.createStringLiteral("____setters")); + const setter = tstl.createTableIndexExpression(classSetters, tstl.createStringLiteral(name.text)); const assignSetter = tstl.createAssignmentStatement(setter, accessorFunction, setAccessor); return assignSetter; } @@ -1286,8 +1246,7 @@ export class LuaTransformer { node: ts.MethodDeclaration, className: tstl.Identifier, noPrototype: boolean - ): StatementVisitResult - { + ): StatementVisitResult { // Don't transform methods without body (overload declarations) if (!node.body) { return undefined; @@ -1301,9 +1260,10 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(node); - const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void - ? this.createSelfIdentifier() - : undefined; + const context = + tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + ? this.createSelfIdentifier() + : undefined; const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); const [body] = this.transformFunctionBody(node.parameters, node.body, restParamName); @@ -1316,21 +1276,25 @@ export class LuaTransformer { node.body ); - const methodTable = tsHelper.isStatic(node) || noPrototype - ? tstl.cloneIdentifier(className) - : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); + const methodTable = + tsHelper.isStatic(node) || noPrototype + ? tstl.cloneIdentifier(className) + : tstl.createTableIndexExpression( + tstl.cloneIdentifier(className), + tstl.createStringLiteral("prototype") + ); return tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - methodTable, - methodName), + tstl.createTableIndexExpression(methodTable, methodName), functionExpression, node ); } - private transformParameters(parameters: ts.NodeArray, context?: tstl.Identifier): - [tstl.Identifier[], tstl.DotsLiteral | undefined, tstl.Identifier | undefined] { + private transformParameters( + parameters: ts.NodeArray, + context?: tstl.Identifier + ): [tstl.Identifier[], tstl.DotsLiteral | undefined, tstl.Identifier | undefined] { // Build parameter string const paramNames: tstl.Identifier[] = []; if (context) { @@ -1349,9 +1313,10 @@ export class LuaTransformer { // Binding patterns become ____TS_bindingPattern0, ____TS_bindingPattern1, etc as function parameters // See transformFunctionBody for how these values are destructured - const paramName = ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) - ? tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`) - : this.transformIdentifier(param.name as ts.Identifier); + const paramName = + ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) + ? tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`) + : this.transformIdentifier(param.name as ts.Identifier); // This parameter is a spread parameter (...param) if (!param.dotDotDotToken) { @@ -1370,8 +1335,7 @@ export class LuaTransformer { parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier - ): [tstl.Statement[], Scope] - { + ): [tstl.Statement[], Scope] { this.pushScope(ScopeType.Function); const headerStatements = []; @@ -1390,10 +1354,9 @@ export class LuaTransformer { } // Binding pattern - bindingPatternDeclarations.push(...this.statementVisitResultToArray( - this.transformBindingPattern(declaration.name, identifier) - )); - + bindingPatternDeclarations.push( + ...this.statementVisitResultToArray(this.transformBindingPattern(declaration.name, identifier)) + ); } else if (declaration.initializer !== undefined) { // Default parameter headerStatements.push( @@ -1425,8 +1388,7 @@ export class LuaTransformer { parameterName: tstl.Identifier, value?: ts.Expression, tsOriginal?: ts.Node - ): tstl.Statement - { + ): tstl.Statement { const parameterValue = value ? this.transformExpression(value) : undefined; const assignment = tstl.createAssignmentStatement(parameterName, parameterValue); @@ -1445,8 +1407,7 @@ export class LuaTransformer { pattern: ts.BindingPattern, table: tstl.Identifier, propertyAccessStack: ts.PropertyName[] = [] - ): StatementVisitResult - { + ): StatementVisitResult { const result: tstl.Statement[] = []; const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (let index = 0; index < pattern.elements.length; index++) { @@ -1460,9 +1421,11 @@ export class LuaTransformer { if (propertyName !== undefined) { propertyAccessStack.push(propertyName); } - result.push(...this.statementVisitResultToArray( - this.transformBindingPattern(element.name, table, propertyAccessStack) - )); + result.push( + ...this.statementVisitResultToArray( + this.transformBindingPattern(element.name, table, propertyAccessStack) + ) + ); } else { // Disallow ellipsis destructure if (element.dotDotDotToken) { @@ -1474,10 +1437,7 @@ export class LuaTransformer { const propertyName = ts.isPropertyName(property) ? this.transformPropertyName(property) : this.transformNumericLiteral(property); - tableExpression = tstl.createTableIndexExpression( - tableExpression, - propertyName - ); + tableExpression = tstl.createTableIndexExpression(tableExpression, propertyName); }); // The identifier of the new variable const variableName = this.transformIdentifier(element.name as ts.Identifier); @@ -1491,21 +1451,21 @@ export class LuaTransformer { const identifier = this.shouldExportIdentifier(variableName) ? this.createExportedIdentifier(variableName) : variableName; - result.push(tstl.createIfStatement( - tstl.createBinaryExpression( - identifier, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ), - tstl.createBlock( - [ + result.push( + tstl.createIfStatement( + tstl.createBinaryExpression( + identifier, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ), + tstl.createBlock([ tstl.createAssignmentStatement( identifier, this.transformExpression(element.initializer) ), - ] + ]) ) - )); + ); } } } @@ -1542,9 +1502,9 @@ export class LuaTransformer { // - declared as a module before this (ignore interfaces with same name) // - declared as a class or function at all (TS requires these to be before module, unless module is empty) const isFirstDeclaration = - symbol === undefined - || (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 - && statement === symbol.declarations.find(ts.isModuleDeclaration)); + symbol === undefined || + (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 && + statement === symbol.declarations.find(ts.isModuleDeclaration)); const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); @@ -1574,7 +1534,6 @@ export class LuaTransformer { result.push(localDeclaration); } - } else if (isExported && !this.currentNamespace && this.isModule) { // exports.NS = {} const namespaceDeclaration = tstl.createAssignmentStatement( @@ -1593,7 +1552,6 @@ export class LuaTransformer { result.push(localDeclaration); } - } else { // local NS = {} const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( @@ -1648,17 +1606,17 @@ export class LuaTransformer { const memberName = this.transformPropertyName(enumMember.name); if (membersOnly) { if (tstl.isIdentifier(memberName)) { - result.push(...this.createLocalOrExportedOrGlobalDeclaration( - memberName, - enumMember.value, - enumDeclaration - )); + result.push( + ...this.createLocalOrExportedOrGlobalDeclaration(memberName, enumMember.value, enumDeclaration) + ); } else { - result.push(...this.createLocalOrExportedOrGlobalDeclaration( - tstl.createIdentifier(enumMember.name.getText(), enumMember.name), - enumMember.value, - enumDeclaration - )); + result.push( + ...this.createLocalOrExportedOrGlobalDeclaration( + tstl.createIdentifier(enumMember.name.getText(), enumMember.name), + enumMember.value, + enumDeclaration + ) + ); } } else { const enumTable = this.transformIdentifierExpression(enumDeclaration.name); @@ -1673,8 +1631,9 @@ export class LuaTransformer { return result; } - protected computeEnumMembers(node: ts.EnumDeclaration): - Array<{name: ts.PropertyName, value: tstl.Expression, original: ts.Node}> { + protected computeEnumMembers( + node: ts.EnumDeclaration + ): Array<{ name: ts.PropertyName; value: tstl.Expression; original: ts.Node }> { let numericValue = 0; let hasStringInitializers = false; @@ -1683,19 +1642,14 @@ export class LuaTransformer { return node.members.map(member => { let valueExpression: ExpressionVisitResult; if (member.initializer) { - if (ts.isNumericLiteral(member.initializer)) - { + if (ts.isNumericLiteral(member.initializer)) { numericValue = Number(member.initializer.text); valueExpression = this.transformNumericLiteral(member.initializer); numericValue++; - } - else if (ts.isStringLiteral(member.initializer)) - { + } else if (ts.isStringLiteral(member.initializer)) { hasStringInitializers = true; valueExpression = this.transformStringLiteral(member.initializer); - } - else - { + } else { if (ts.isIdentifier(member.initializer)) { const [isEnumMember, originalName] = tsHelper.isEnumMember(node, member.initializer); if (isEnumMember === true && originalName !== undefined) { @@ -1711,13 +1665,9 @@ export class LuaTransformer { valueExpression = this.transformExpression(member.initializer); } } - } - else if (hasStringInitializers) - { + } else if (hasStringInitializers) { throw TSTLErrors.HeterogeneousEnum(node); - } - else - { + } else { valueExpression = tstl.createNumericLiteral(numericValue); numericValue++; } @@ -1738,58 +1688,40 @@ export class LuaTransformer { parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier - ): [tstl.Statement[], Scope] - { + ): [tstl.Statement[], Scope] { this.importLuaLibFeature(LuaLibFeature.Symbol); - const [functionBody, functionScope] = this.transformFunctionBody( - parameters, - body - ); + const [functionBody, functionScope] = this.transformFunctionBody(parameters, body); const coroutineIdentifier = tstl.createIdentifier("____co"); - const valueIdentifier = tstl.createIdentifier("____value"); - const errIdentifier = tstl.createIdentifier("____err"); + const valueIdentifier = tstl.createIdentifier("____value"); + const errIdentifier = tstl.createIdentifier("____err"); const itIdentifier = tstl.createIdentifier("____it"); //local ____co = coroutine.create(originalFunction) - const coroutine = - tstl.createVariableDeclarationStatement(coroutineIdentifier, - tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), - tstl.createStringLiteral("create") - ), - [tstl.createFunctionExpression(tstl.createBlock(functionBody))] - ) - ); + const coroutine = tstl.createVariableDeclarationStatement( + coroutineIdentifier, + tstl.createCallExpression( + tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("create")), + [tstl.createFunctionExpression(tstl.createBlock(functionBody))] + ) + ); const nextBody = []; // coroutine.resume(__co, ...) const resumeCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("coroutine"), - tstl.createStringLiteral("resume") - ), + tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("resume")), [coroutineIdentifier, tstl.createDotsLiteral()] ); // ____err, ____value = coroutine.resume(____co, ...) - nextBody.push(tstl.createVariableDeclarationStatement( - [errIdentifier, valueIdentifier], - resumeCall) - ); + nextBody.push(tstl.createVariableDeclarationStatement([errIdentifier, valueIdentifier], resumeCall)); //if(not ____err){error(____value)} const errorCheck = tstl.createIfStatement( - tstl.createUnaryExpression( - errIdentifier, - tstl.SyntaxKind.NotOperator - ), + tstl.createUnaryExpression(errIdentifier, tstl.SyntaxKind.NotOperator), tstl.createBlock([ tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("error"), - [valueIdentifier] - ) + tstl.createCallExpression(tstl.createIdentifier("error"), [valueIdentifier]) ), ]) ); @@ -1797,10 +1729,7 @@ export class LuaTransformer { //coroutine.status(____co) == "dead"; const coStatus = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("coroutine"), - tstl.createStringLiteral("status") - ), + tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("status")), [coroutineIdentifier] ); const status = tstl.createBinaryExpression( @@ -1811,14 +1740,8 @@ export class LuaTransformer { //{done = coroutine.status(____co) == "dead"; value = ____value} const iteratorResult = tstl.createTableExpression([ - tstl.createTableFieldExpression( - status, - tstl.createStringLiteral("done") - ), - tstl.createTableFieldExpression( - valueIdentifier, - tstl.createStringLiteral("value") - ), + tstl.createTableFieldExpression(status, tstl.createStringLiteral("done")), + tstl.createTableFieldExpression(valueIdentifier, tstl.createStringLiteral("value")), ]); nextBody.push(tstl.createReturnStatement([iteratorResult])); @@ -1826,16 +1749,14 @@ export class LuaTransformer { const nextFunctionDeclaration = tstl.createFunctionExpression( tstl.createBlock(nextBody), [tstl.createAnonymousIdentifier()], - tstl.createDotsLiteral()); + tstl.createDotsLiteral() + ); //____it = {next = function(____, ...)} const iterator = tstl.createVariableDeclarationStatement( itIdentifier, tstl.createTableExpression([ - tstl.createTableFieldExpression( - nextFunctionDeclaration, - tstl.createStringLiteral("next") - ), + tstl.createTableFieldExpression(nextFunctionDeclaration, tstl.createStringLiteral("next")), ]) ); @@ -1849,15 +1770,8 @@ export class LuaTransformer { iterator, //____it[Symbol.iterator] = {return ____it} tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - itIdentifier, - symbolIterator - ), - tstl.createFunctionExpression( - tstl.createBlock( - [tstl.createReturnStatement([itIdentifier])] - ) - ) + tstl.createTableIndexExpression(itIdentifier, symbolIterator), + tstl.createFunctionExpression(tstl.createBlock([tstl.createReturnStatement([itIdentifier])])) ), //return ____it tstl.createReturnStatement([itIdentifier]), @@ -1878,9 +1792,10 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(functionDeclaration); - const context = tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void - ? this.createSelfIdentifier() - : undefined; + const context = + tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + ? this.createSelfIdentifier() + : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); if (functionDeclaration.name === undefined) { @@ -1889,16 +1804,8 @@ export class LuaTransformer { const name = this.transformIdentifier(functionDeclaration.name); const [body, functionScope] = functionDeclaration.asteriskToken - ? this.transformGeneratorFunction( - functionDeclaration.parameters, - functionDeclaration.body, - restParamName - ) - : this.transformFunctionBody( - functionDeclaration.parameters, - functionDeclaration.body, - restParamName - ); + ? this.transformGeneratorFunction(functionDeclaration.parameters, functionDeclaration.body, restParamName) + : this.transformFunctionBody(functionDeclaration.parameters, functionDeclaration.body, restParamName); const block = tstl.createBlock(body); const functionExpression = tstl.createFunctionExpression( block, @@ -1913,8 +1820,10 @@ export class LuaTransformer { if (scope === undefined) { throw TSTLErrors.UndefinedScope(); } - if (!scope.functionDefinitions) { scope.functionDefinitions = new Map(); } - const functionInfo = {referencedSymbols: functionScope.referencedSymbols || new Set()}; + if (!scope.functionDefinitions) { + scope.functionDefinitions = new Map(); + } + const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Set() }; scope.functionDefinitions.set(name.symbolId, functionInfo); } return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); @@ -1928,8 +1837,7 @@ export class LuaTransformer { return undefined; } - public transformVariableDeclaration(statement: ts.VariableDeclaration): StatementVisitResult - { + public transformVariableDeclaration(statement: ts.VariableDeclaration): StatementVisitResult { if (statement.initializer && statement.type) { // Validate assignment const initializerType = this.checker.getTypeAtLocation(statement.initializer); @@ -1944,11 +1852,7 @@ export class LuaTransformer { const value = this.transformExpression(statement.initializer); return this.createLocalOrExportedOrGlobalDeclaration(identifierName, value, statement); } else { - return this.createLocalOrExportedOrGlobalDeclaration( - identifierName, - undefined, - statement - ); + return this.createLocalOrExportedOrGlobalDeclaration(identifierName, undefined, statement); } } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { // Destructuring types @@ -1956,8 +1860,10 @@ export class LuaTransformer { const statements: tstl.Statement[] = []; // For nested bindings and object bindings, fall back to transformBindingPattern - if (ts.isObjectBindingPattern(statement.name) - || statement.name.elements.some(elem => !ts.isBindingElement(elem) || !ts.isIdentifier(elem.name))) { + if ( + ts.isObjectBindingPattern(statement.name) || + statement.name.elements.some(elem => !ts.isBindingElement(elem) || !ts.isIdentifier(elem.name)) + ) { const statements = []; let table: tstl.Identifier; if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { @@ -1966,13 +1872,17 @@ export class LuaTransformer { // Contain the expression in a temporary variable table = tstl.createAnonymousIdentifier(); if (statement.initializer) { - statements.push(tstl.createVariableDeclarationStatement( - table, this.transformExpression(statement.initializer))); + statements.push( + tstl.createVariableDeclarationStatement( + table, + this.transformExpression(statement.initializer) + ) + ); } } - statements.push(...this.statementVisitResultToArray( - this.transformBindingPattern(statement.name, table) - )); + statements.push( + ...this.statementVisitResultToArray(this.transformBindingPattern(statement.name, table)) + ); return statements; } @@ -1981,11 +1891,13 @@ export class LuaTransformer { throw TSTLErrors.ForbiddenEllipsisDestruction(statement); } - const vars = statement.name.elements.length > 0 - ? this.filterUndefinedAndCast( - statement.name.elements.map(e => this.transformArrayBindingElement(e)), - tstl.isIdentifier) - : tstl.createAnonymousIdentifier(statement.name); + const vars = + statement.name.elements.length > 0 + ? this.filterUndefinedAndCast( + statement.name.elements.map(e => this.transformArrayBindingElement(e)), + tstl.isIdentifier + ) + : tstl.createAnonymousIdentifier(statement.name); if (statement.initializer) { if (tsHelper.isTupleReturnCall(statement.initializer, this.checker)) { @@ -1999,16 +1911,11 @@ export class LuaTransformer { ); } else if (ts.isArrayLiteralExpression(statement.initializer)) { // Don't unpack array literals - const values = statement.initializer.elements.length > 0 - ? statement.initializer.elements.map(e => this.transformExpression(e)) - : tstl.createNilLiteral(); - statements.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - vars, - values, - statement - ) - ); + const values = + statement.initializer.elements.length > 0 + ? statement.initializer.elements.map(e => this.transformExpression(e)) + : tstl.createNilLiteral(); + statements.push(...this.createLocalOrExportedOrGlobalDeclaration(vars, values, statement)); } else { // local vars = this.transpileDestructingAssignmentValue(node.initializer); const initializer = this.createUnpackCall( @@ -2019,11 +1926,7 @@ export class LuaTransformer { } } else { statements.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - vars, - tstl.createNilLiteral(), - statement - ) + ...this.createLocalOrExportedOrGlobalDeclaration(vars, tstl.createNilLiteral(), statement) ); } @@ -2040,14 +1943,12 @@ export class LuaTransformer { tstl.createNilLiteral(), tstl.SyntaxKind.EqualityOperator ), - tstl.createBlock( - [ - tstl.createAssignmentStatement( - identifier, - this.transformExpression(element.initializer) - ), - ] - ) + tstl.createBlock([ + tstl.createAssignmentStatement( + identifier, + this.transformExpression(element.initializer) + ), + ]) ) ); } @@ -2078,25 +1979,24 @@ export class LuaTransformer { expression.right, replacementOperator ); - } else if (expression.operatorToken.kind === ts.SyntaxKind.EqualsToken) { // = assignment return this.transformAssignmentStatement(expression); - } else if (expression.operatorToken.kind === ts.SyntaxKind.CommaToken) { const lhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)); const rhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.right)); return tstl.createDoStatement([...lhs, ...rhs], expression); } - } else if ( ts.isPrefixUnaryExpression(expression) && - (expression.operator === ts.SyntaxKind.PlusPlusToken - || expression.operator === ts.SyntaxKind.MinusMinusToken)) { + (expression.operator === ts.SyntaxKind.PlusPlusToken || + expression.operator === ts.SyntaxKind.MinusMinusToken) + ) { // ++i, --i - const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken - ? ts.SyntaxKind.PlusToken - : ts.SyntaxKind.MinusToken; + const replacementOperator = + expression.operator === ts.SyntaxKind.PlusPlusToken + ? ts.SyntaxKind.PlusToken + : ts.SyntaxKind.MinusToken; return this.transformCompoundAssignmentStatement( expression, @@ -2104,13 +2004,12 @@ export class LuaTransformer { ts.createLiteral(1), replacementOperator ); - } - - else if (ts.isPostfixUnaryExpression(expression)) { + } else if (ts.isPostfixUnaryExpression(expression)) { // i++, i-- - const replacementOperator = expression.operator === ts.SyntaxKind.PlusPlusToken - ? ts.SyntaxKind.PlusToken - : ts.SyntaxKind.MinusToken; + const replacementOperator = + expression.operator === ts.SyntaxKind.PlusPlusToken + ? ts.SyntaxKind.PlusToken + : ts.SyntaxKind.MinusToken; return this.transformCompoundAssignmentStatement( expression, @@ -2118,9 +2017,7 @@ export class LuaTransformer { ts.createLiteral(1), replacementOperator ); - } - - else if (ts.isDeleteExpression(expression)) { + } else if (ts.isDeleteExpression(expression)) { return tstl.createAssignmentStatement( this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression, tstl.createNilLiteral(), @@ -2144,11 +2041,9 @@ export class LuaTransformer { expression as ts.CallExpression & { expression: ts.PropertyAccessExpression }, true ); - return this.transformLuaTableExpressionStatement( - statement as ts.ExpressionStatement - & { expression: ts.CallExpression } - & { expression: { expression: ts.PropertyAccessExpression } } - ); + return this.transformLuaTableExpressionStatement(statement as ts.ExpressionStatement & { + expression: ts.CallExpression; + } & { expression: { expression: ts.PropertyAccessExpression } }); } } @@ -2157,14 +2052,10 @@ export class LuaTransformer { public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { return tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("coroutine"), - tstl.createStringLiteral("yield")), - expression.expression - ? [this.transformExpression(expression.expression)] - : [], - expression - ); + tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("yield")), + expression.expression ? [this.transformExpression(expression.expression)] : [], + expression + ); } public transformReturnStatement(statement: ts.ReturnStatement): StatementVisitResult { @@ -2184,9 +2075,10 @@ export class LuaTransformer { } const expressionType = this.checker.getTypeAtLocation(statement.expression); - if (!tsHelper.isTupleReturnCall(statement.expression, this.checker) - && tsHelper.isArrayType(expressionType, this.checker, this.program)) - { + if ( + !tsHelper.isTupleReturnCall(statement.expression, this.checker) && + tsHelper.isArrayType(expressionType, this.checker, this.program) + ) { // If return expression is an array-type and not another TupleReturn call, unpack it const expression = this.createUnpackCall( this.transformExpression(statement.expression), @@ -2236,9 +2128,7 @@ export class LuaTransformer { return tstl.createRepeatStatement( tstl.createBlock(this.transformLoopBody(statement)), tstl.createUnaryExpression( - tstl.createParenthesizedExpression( - this.transformExpression(statement.expression) - ), + tstl.createParenthesizedExpression(this.transformExpression(statement.expression)), tstl.SyntaxKind.NotOperator ), statement @@ -2285,7 +2175,6 @@ export class LuaTransformer { const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { expression = this.createUnpackCall(expression, initializer); - } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); } @@ -2294,22 +2183,22 @@ export class LuaTransformer { if (variableStatements[0]) { // we can safely assume that for vars are not exported and therefore declarationstatenents return tstl.createVariableDeclarationStatement( - (variableStatements[0] as tstl.VariableDeclarationStatement).left, expression); + (variableStatements[0] as tstl.VariableDeclarationStatement).left, + expression + ); } else { throw TSTLErrors.MissingForOfVariables(initializer); } - } else { // Assignment to existing variable let variables: tstl.AssignmentLeftHandSideExpression | tstl.AssignmentLeftHandSideExpression[]; if (ts.isArrayLiteralExpression(initializer)) { expression = this.createUnpackCall(expression, initializer); - variables = initializer.elements - .map(e => this.transformExpression(e)) as tstl.AssignmentLeftHandSideExpression[]; - + variables = initializer.elements.map(e => + this.transformExpression(e) + ) as tstl.AssignmentLeftHandSideExpression[]; } else if (ts.isObjectLiteralExpression(initializer)) { throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); - } else { variables = this.transformExpression(initializer) as tstl.AssignmentLeftHandSideExpression; } @@ -2319,8 +2208,7 @@ export class LuaTransformer { protected transformLoopBody( loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement - ): tstl.Statement[] - { + ): tstl.Statement[] { this.pushScope(ScopeType.Loop); const body = this.performHoisting(this.transformBlockOrStatement(loop.statement)); const scope = this.popScope(); @@ -2351,21 +2239,18 @@ export class LuaTransformer { if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { valueVariable = tstl.createIdentifier("____TS_values"); block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); - } else { valueVariable = this.transformIdentifier(variables); } - } else { // Assignment to existing variable valueVariable = tstl.createIdentifier("____TS_value"); block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); } - const ipairsCall = tstl.createCallExpression( - tstl.createIdentifier("ipairs"), - [this.transformExpression(statement.expression)] - ); + const ipairsCall = tstl.createCallExpression(tstl.createIdentifier("ipairs"), [ + this.transformExpression(statement.expression), + ]); return tstl.createForInStatement( block, @@ -2390,41 +2275,41 @@ export class LuaTransformer { block, this.filterUndefinedAndCast( initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), - tstl.isIdentifier), + tstl.isIdentifier + ), [luaIterator] ); - } else { // Single variable is not allowed throw TSTLErrors.UnsupportedNonDestructuringLuaIterator(statement.initializer); } - } else { // Variables NOT declared in for loop - catch iterator values in temps and assign // for ____TS_value0 in ${iterable} do // ${initializer} = ____TS_value0 if (ts.isArrayLiteralExpression(statement.initializer)) { - const tmps = statement.initializer.elements - .map((_, i) => tstl.createIdentifier(`____TS_value${i}`)); + const tmps = statement.initializer.elements.map((_, i) => + tstl.createIdentifier(`____TS_value${i}`) + ); const assign = tstl.createAssignmentStatement( - statement.initializer.elements.map(e => - this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression + statement.initializer.elements.map( + e => this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression ), tmps ); block.statements.splice(0, 0, assign); return tstl.createForInStatement(block, tmps, [luaIterator]); - } else { // Single variable is not allowed throw TSTLErrors.UnsupportedNonDestructuringLuaIterator(statement.initializer); } } - } else { // LuaIterator (no TupleReturn) - if (ts.isVariableDeclarationList(statement.initializer) - && ts.isIdentifier(statement.initializer.declarations[0].name)) { + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { // Single variable declared in for loop // for ${initializer} in ${iterator} do return tstl.createForInStatement( @@ -2432,7 +2317,6 @@ export class LuaTransformer { [this.transformIdentifier(statement.initializer.declarations[0].name as ts.Identifier)], [luaIterator] ); - } else { // Destructuring or variable NOT declared in for loop // for ____TS_value in ${iterator} do @@ -2440,19 +2324,17 @@ export class LuaTransformer { const valueVariable = tstl.createIdentifier("____TS_value"); const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); block.statements.splice(0, 0, initializer); - return tstl.createForInStatement( - block, - [valueVariable], - [luaIterator] - ); + return tstl.createForInStatement(block, [valueVariable], [luaIterator]); } } } private transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const iterable = this.transformExpression(statement.expression); - if (ts.isVariableDeclarationList(statement.initializer) - && ts.isIdentifier(statement.initializer.declarations[0].name)) { + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { // Single variable declared in for loop // for ${initializer} in __TS__iterator(${iterator}) do return tstl.createForInStatement( @@ -2460,7 +2342,6 @@ export class LuaTransformer { [this.transformIdentifier(statement.initializer.declarations[0].name as ts.Identifier)], [this.transformLuaLibFunction(LuaLibFeature.Iterator, statement.expression, iterable)] ); - } else { // Destructuring or variable NOT declared in for loop // for ____TS_value in __TS__iterator(${iterator}) do @@ -2483,15 +2364,11 @@ export class LuaTransformer { if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { // LuaIterators return this.transformForOfLuaIteratorStatement(statement, body); - - } else if (tsHelper.isArrayType( - this.checker.getTypeAtLocation(statement.expression), - this.checker, - this.program) + } else if ( + tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program) ) { // Arrays return this.transformForOfArrayStatement(statement, body); - } else { // TS Iterables return this.transformForOfIteratorStatement(statement, body); @@ -2514,12 +2391,7 @@ export class LuaTransformer { const body = tstl.createBlock(this.transformLoopBody(statement)); - return tstl.createForInStatement( - body, - [this.transformIdentifier(identifier)], - [pairsCall], - statement - ); + return tstl.createForInStatement(body, [this.transformIdentifier(identifier)], [pairsCall], statement); } public transformSwitchStatement(statement: ts.SwitchStatement): StatementVisitResult { @@ -2606,9 +2478,13 @@ export class LuaTransformer { if (statement.catchClause) { const tryResult = tstl.createIdentifier("____TS_try"); - const returnVariables = statement.catchClause && statement.catchClause.variableDeclaration - ? [tryResult, this.transformIdentifier(statement.catchClause.variableDeclaration.name as ts.Identifier)] - : [tryResult]; + const returnVariables = + statement.catchClause && statement.catchClause.variableDeclaration + ? [ + tryResult, + this.transformIdentifier(statement.catchClause.variableDeclaration.name as ts.Identifier), + ] + : [tryResult]; const catchAssignment = tstl.createVariableDeclarationStatement(returnVariables, tryCall); @@ -2619,7 +2495,6 @@ export class LuaTransformer { tstl.SyntaxKind.NotOperator ); result.push(tstl.createIfStatement(notTryResult, this.transformBlock(statement.catchClause.block))); - } else { result.push(tstl.createExpressionStatement(tryCall)); } @@ -2628,10 +2503,7 @@ export class LuaTransformer { result.push(tstl.createDoStatement(this.transformBlock(statement.finallyBlock).statements)); } - return tstl.createDoStatement( - result, - statement - ); + return tstl.createDoStatement(result, statement); } public transformThrowStatement(statement: ts.ThrowStatement): StatementVisitResult { @@ -2662,10 +2534,7 @@ export class LuaTransformer { } scope.loopContinued = true; - return tstl.createGotoStatement( - `__continue${scope.id}`, - statement - ); + return tstl.createGotoStatement(`__continue${scope.id}`, statement); } public transformEmptyStatement(_statement: ts.EmptyStatement): StatementVisitResult { @@ -2747,8 +2616,7 @@ export class LuaTransformer { right: tstl.Expression, operator: ts.BinaryOperator, tsOriginal: ts.Node - ): ExpressionVisitResult - { + ): ExpressionVisitResult { switch (operator) { case ts.SyntaxKind.AmpersandToken: case ts.SyntaxKind.BarToken: @@ -2881,9 +2749,10 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment - const left = expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformExpression(e)) - : [tstl.createAnonymousIdentifier(expression.left)]; + const left = + expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { if (expression.right.elements.length > 0) { @@ -2897,20 +2766,16 @@ export class LuaTransformer { } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } - return tstl.createAssignmentStatement( - left as tstl.AssignmentLeftHandSideExpression[], - right, - expression - ); + return tstl.createAssignmentStatement(left as tstl.AssignmentLeftHandSideExpression[], right, expression); } else { // Simple assignment return this.transformAssignment(expression.left, this.transformExpression(expression.right)); } } - private transformAssignmentExpression(expression: ts.BinaryExpression) - : tstl.CallExpression | tstl.MethodCallExpression - { + private transformAssignmentExpression( + expression: ts.BinaryExpression + ): tstl.CallExpression | tstl.MethodCallExpression { // Validate assignment const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); @@ -2929,14 +2794,16 @@ export class LuaTransformer { if (ts.isArrayLiteralExpression(expression.left)) { // Destructuring assignment // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() - const left = expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformExpression(e)) - : [tstl.createAnonymousIdentifier(expression.left)]; + const left = + expression.left.elements.length > 0 + ? expression.left.elements.map(e => this.transformExpression(e)) + : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.length > 0 - ? expression.right.elements.map(e => this.transformExpression(e)) - : [tstl.createNilLiteral()]; + right = + expression.right.elements.length > 0 + ? expression.right.elements.map(e => this.transformExpression(e)) + : [tstl.createNilLiteral()]; } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = [this.transformExpression(expression.right)]; } else { @@ -2965,10 +2832,11 @@ export class LuaTransformer { tstl.createAssignmentStatement(indexStatement, valueParameter), tstl.createReturnStatement([valueParameter]), ]; - const iife = tstl.createFunctionExpression( - tstl.createBlock(statements), - [objParameter, indexParameter, valueParameter] - ); + const iife = tstl.createFunctionExpression(tstl.createBlock(statements), [ + objParameter, + indexParameter, + valueParameter, + ]); const objExpression = this.transformExpression(expression.left.expression); let indexExpression: tstl.Expression; if (ts.isPropertyAccessExpression(expression.left)) { @@ -3005,8 +2873,7 @@ export class LuaTransformer { rhs: ts.Expression, replacementOperator: ts.BinaryOperator, isPostfix: boolean - ): tstl.CallExpression - { + ): tstl.CallExpression { const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; let right = this.transformExpression(rhs); @@ -3054,7 +2921,6 @@ export class LuaTransformer { tmp, expression ); - } else if (isPostfix) { // Postfix expressions need to cache original value in temp // local ____TS_tmp = ${left}; @@ -3074,7 +2940,6 @@ export class LuaTransformer { tmpIdentifier, expression ); - } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____TS_tmp = ${left} ${replacementOperator} ${right}; @@ -3089,7 +2954,6 @@ export class LuaTransformer { tmpIdentifier, expression ); - } else { // Simple expressions // ${left} = ${right}; return ${right} @@ -3159,11 +3023,12 @@ export class LuaTransformer { } public transformClassExpression(expression: ts.ClassExpression): ExpressionVisitResult { - const className = expression.name !== undefined - ? this.transformIdentifier(expression.name) - : tstl.createAnonymousIdentifier(); + const className = + expression.name !== undefined + ? this.transformIdentifier(expression.name) + : tstl.createAnonymousIdentifier(); - const classDeclaration = this.transformClassDeclaration(expression, className); + const classDeclaration = this.transformClassDeclaration(expression, className); return this.createImmediatelyInvokedFunctionExpression( this.statementVisitResultToArray(classDeclaration), className, @@ -3176,8 +3041,7 @@ export class LuaTransformer { lhs: ts.Expression, rhs: ts.Expression, replacementOperator: ts.BinaryOperator - ): tstl.Statement - { + ): tstl.Statement { const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; const right = this.transformExpression(rhs); @@ -3205,7 +3069,6 @@ export class LuaTransformer { ); const assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); return tstl.createDoStatement([objAndIndexDeclaration, assignStatement]); - } else { // Simple statements // ${left} = ${left} ${replacementOperator} ${right} @@ -3219,8 +3082,7 @@ export class LuaTransformer { expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator, lib: string - ): ExpressionVisitResult - { + ): ExpressionVisitResult { let bitFunction: string; switch (operator) { case tstl.SyntaxKind.BitwiseNotOperator: @@ -3240,8 +3102,7 @@ export class LuaTransformer { node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator - ): ExpressionVisitResult - { + ): ExpressionVisitResult { switch (this.luaTarget) { case LuaTarget.Lua51: throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); @@ -3263,8 +3124,7 @@ export class LuaTransformer { right: tstl.Expression, operator: ts.BinaryOperator, lib: string - ): ExpressionVisitResult - { + ): ExpressionVisitResult { let bitFunction: string; switch (operator) { case ts.SyntaxKind.AmpersandToken: @@ -3300,8 +3160,7 @@ export class LuaTransformer { left: tstl.Expression, right: tstl.Expression, operator: ts.BinaryOperator - ): ExpressionVisitResult - { + ): ExpressionVisitResult { switch (this.luaTarget) { case LuaTarget.Lua51: throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); @@ -3343,12 +3202,7 @@ export class LuaTransformer { // condition and v1 or v2 const conditionAnd = tstl.createBinaryExpression(condition, val1, tstl.SyntaxKind.AndOperator); - return tstl.createBinaryExpression( - conditionAnd, - val2, - tstl.SyntaxKind.OrOperator, - expression - ); + return tstl.createBinaryExpression(conditionAnd, val2, tstl.SyntaxKind.OrOperator, expression); } public transformPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): ExpressionVisitResult { @@ -3424,8 +3278,8 @@ export class LuaTransformer { } public transformArrayLiteral(expression: ts.ArrayLiteralExpression): ExpressionVisitResult { - const values = expression.elements.map( - e => tstl.createTableFieldExpression(this.transformExpression(e), undefined, e) + const values = expression.elements.map(e => + tstl.createTableFieldExpression(this.transformExpression(e), undefined, e) ); return tstl.createTableExpression(values, expression); @@ -3439,7 +3293,6 @@ export class LuaTransformer { if (ts.isPropertyAssignment(element)) { const expression = this.transformExpression(element.initializer); properties.push(tstl.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); let identifier = this.createShorthandIdentifier(valueSymbol, element.name); @@ -3447,11 +3300,9 @@ export class LuaTransformer { identifier = this.createExportedIdentifier(identifier); } properties.push(tstl.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { const expression = this.transformFunctionExpression(element); properties.push(tstl.createTableFieldExpression(expression, name, element)); - } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); } @@ -3462,11 +3313,7 @@ export class LuaTransformer { public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { const lhs = this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression; - const assignment = tstl.createAssignmentStatement( - lhs, - tstl.createNilLiteral(), - expression - ); + const assignment = tstl.createAssignmentStatement(lhs, tstl.createNilLiteral(), expression); return this.createImmediatelyInvokedFunctionExpression( [assignment], @@ -3578,10 +3425,7 @@ export class LuaTransformer { return this.transformExpression(expression.expression); } - return tstl.createParenthesizedExpression( - this.transformExpression(expression.expression), - expression - ); + return tstl.createParenthesizedExpression(this.transformExpression(expression.expression), expression); } public transformSuperKeyword(expression: ts.SuperExpression): ExpressionVisitResult { @@ -3616,14 +3460,15 @@ export class LuaTransformer { let parameters: tstl.Expression[] = []; const isTupleReturn = tsHelper.isTupleReturnCall(expression, this.checker); - const isTupleReturnForward = expression.parent - && ts.isReturnStatement(expression.parent) - && tsHelper.isInTupleReturnFunction(expression, this.checker); + const isTupleReturnForward = + expression.parent && + ts.isReturnStatement(expression.parent) && + tsHelper.isInTupleReturnFunction(expression, this.checker); const isInDestructingAssignment = tsHelper.isInDestructingAssignment(expression); const isInSpread = expression.parent && ts.isSpreadElement(expression.parent); const returnValueIsUsed = expression.parent && !ts.isExpressionStatement(expression.parent); - const wrapResult = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment - && !isInSpread && returnValueIsUsed; + const wrapResult = + isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment && !isInSpread && returnValueIsUsed; if (ts.isPropertyAccessExpression(expression.expression)) { const result = this.transformPropertyCall(expression); @@ -3660,9 +3505,10 @@ export class LuaTransformer { const callPath = this.transformExpression(expression.expression); const signatureDeclaration = signature && signature.getDeclaration(); - if (signatureDeclaration - && tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void) - { + if ( + signatureDeclaration && + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void + ) { parameters = this.transformArguments(expression.arguments, signature); } else { const context = this.isStrict ? ts.createNull() : ts.createIdentifier("_G"); @@ -3742,13 +3588,10 @@ export class LuaTransformer { const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); if (classDecorators.has(DecoratorKind.LuaTable)) { - this.validateLuaTableCall( - node as ts.CallExpression & { expression: ts.PropertyAccessExpression }, - false - ); - return this.transformLuaTableCallExpression( - node as ts.CallExpression & { expression: ts.PropertyAccessExpression } - ); + this.validateLuaTableCall(node as ts.CallExpression & { expression: ts.PropertyAccessExpression }, false); + return this.transformLuaTableCallExpression(node as ts.CallExpression & { + expression: ts.PropertyAccessExpression; + }); } switch (ownerType.flags) { @@ -3763,8 +3606,10 @@ export class LuaTransformer { } // if ownerType inherits from an array, use array calls where appropriate - if (tsHelper.isArrayType(ownerType, this.checker, this.program) && - tsHelper.isDefaultArrayCallMethodName(node.expression.name.escapedText as string)) { + if ( + tsHelper.isArrayType(ownerType, this.checker, this.program) && + tsHelper.isDefaultArrayCallMethodName(node.expression.name.escapedText as string) + ) { return this.transformArrayCallExpression(node); } @@ -3776,10 +3621,7 @@ export class LuaTransformer { if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) parameters = this.transformArguments(node.arguments, signature, ts.createThis()); - return tstl.createCallExpression( - this.transformExpression(node.expression), - parameters - ); + return tstl.createCallExpression(this.transformExpression(node.expression), parameters); } else { // Replace last . with : here const name = node.expression.name.escapedText; @@ -3797,20 +3639,25 @@ export class LuaTransformer { const rawGetCall = tstl.createCallExpression(rawGetIdentifier, [expr, ...parameters]); return tstl.createParenthesizedExpression( tstl.createBinaryExpression( - rawGetCall, tstl.createNilLiteral(), tstl.SyntaxKind.InequalityOperator, node) - ); + rawGetCall, + tstl.createNilLiteral(), + tstl.SyntaxKind.InequalityOperator, + node + ) + ); } else { const parameters = this.transformArguments(node.arguments, signature); const table = this.transformExpression(node.expression.expression); const signatureDeclaration = signature && signature.getDeclaration(); - if (!signatureDeclaration - || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) - { - if (luaKeywords.has(node.expression.name.text) - || !tsHelper.isValidLuaIdentifier(node.expression.name.text)) - { + if ( + !signatureDeclaration || + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void + ) { + if ( + luaKeywords.has(node.expression.name.text) || + !tsHelper.isValidLuaIdentifier(node.expression.name.text) + ) { return this.transformElementCall(node); - } else { // table:name() return tstl.createMethodCallExpression( @@ -3842,8 +3689,10 @@ export class LuaTransformer { let parameters = this.transformArguments(node.arguments, signature); const signatureDeclaration = signature && signature.getDeclaration(); - if (!signatureDeclaration - || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void) { + if ( + !signatureDeclaration || + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void + ) { // Pass left-side as context const context = this.transformExpression(node.expression.expression); @@ -3881,8 +3730,7 @@ export class LuaTransformer { params: ts.NodeArray | ts.Expression[], sig?: ts.Signature, context?: T - ): tstl.Expression[] - { + ): tstl.Expression[] { const parameters: tstl.Expression[] = []; // Add context as first param if present @@ -3913,14 +3761,12 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStringType(type)) { return this.transformStringProperty(expression); - } else if (tsHelper.isArrayType(type, this.checker, this.program)) { const arrayPropertyAccess = this.transformArrayProperty(expression); if (arrayPropertyAccess) { return arrayPropertyAccess; } - - } else if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum)) { + } else if (type.symbol && type.symbol.flags & ts.SymbolFlags.ConstEnum) { return this.transformConstEnumValue(type, property, expression); } @@ -3983,8 +3829,7 @@ export class LuaTransformer { const expressionName = expression.name.escapedText as string; switch (expressionName) { // math.tan(x / y) - case "atan2": - { + case "atan2": { const math = tstl.createIdentifier("math"); const atan = tstl.createStringLiteral("atan"); const div = tstl.createBinaryExpression(params[0], params[1], tstl.SyntaxKind.DivisionOperator); @@ -3993,22 +3838,20 @@ export class LuaTransformer { // (math.log(x) / Math.LNe) case "log10": - case "log2": - { + case "log2": { const math = tstl.createIdentifier("math"); const log1 = tstl.createTableIndexExpression(math, tstl.createStringLiteral("log")); const logCall1 = tstl.createCallExpression(log1, params); const e = tstl.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); const div = tstl.createBinaryExpression(logCall1, e, tstl.SyntaxKind.DivisionOperator); return ts.isExpressionStatement(node.parent) - // if used as a stand-alone statement, needs to be a call expression to be valid lua - ? this.createImmediatelyInvokedFunctionExpression([], div, node) + ? // if used as a stand-alone statement, needs to be a call expression to be valid lua + this.createImmediatelyInvokedFunctionExpression([], div, node) : tstl.createParenthesizedExpression(div, node); } // math.log(1 + x) - case "log1p": - { + case "log1p": { const math = tstl.createIdentifier("math"); const log = tstl.createStringLiteral("log"); const one = tstl.createNumericLiteral(1); @@ -4017,8 +3860,7 @@ export class LuaTransformer { } // math.floor(x + 0.5) - case "round": - { + case "round": { const math = tstl.createIdentifier("math"); const floor = tstl.createStringLiteral("floor"); const half = tstl.createNumericLiteral(0.5); @@ -4041,8 +3883,7 @@ export class LuaTransformer { case "random": case "sin": case "sqrt": - case "tan": - { + case "tan": { const math = tstl.createIdentifier("math"); const method = tstl.createStringLiteral(expressionName); return tstl.createCallExpression(tstl.createTableIndexExpression(math, method), params, node); @@ -4091,9 +3932,11 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(expression.expression); - if (type.symbol && (type.symbol.flags & ts.SymbolFlags.ConstEnum) - && ts.isStringLiteral(expression.argumentExpression)) - { + if ( + type.symbol && + type.symbol.flags & ts.SymbolFlags.ConstEnum && + ts.isStringLiteral(expression.argumentExpression) + ) { return this.transformConstEnumValue(type, expression.argumentExpression.text, expression); } @@ -4117,8 +3960,7 @@ export class LuaTransformer { ): ExpressionVisitResult { // Assumption: the enum only has one declaration const enumDeclaration = enumType.symbol.declarations.find(d => ts.isEnumDeclaration(d)) as ts.EnumDeclaration; - const enumMember = enumDeclaration.members - .find(m => ts.isIdentifier(m.name) && m.name.text === memberName); + const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === memberName); if (enumMember) { if (enumMember.initializer) { @@ -4170,10 +4012,13 @@ export class LuaTransformer { node.arguments.length === 1 ? this.createStringCall("find", node, caller, params[0]) : this.createStringCall( - "find", node, caller, params[0], - this.expressionPlusOne(params[1]), - tstl.createBooleanLiteral(true) - ); + "find", + node, + caller, + params[0], + this.expressionPlusOne(params[1]), + tstl.createBooleanLiteral(true) + ); return tstl.createParenthesizedExpression( tstl.createBinaryExpression( @@ -4216,8 +4061,7 @@ export class LuaTransformer { case "slice": if (node.arguments.length === 0) { return caller; - } - else if (node.arguments.length === 1) { + } else if (node.arguments.length === 1) { const arg1 = this.expressionPlusOne(params[0]); return this.createStringCall("sub", node, caller, arg1); } else { @@ -4234,8 +4078,7 @@ export class LuaTransformer { case "charAt": const firstParamPlusOne = this.expressionPlusOne(params[0]); return this.createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); - case "charCodeAt": - { + case "charCodeAt": { const firstParamPlusOne = this.expressionPlusOne(params[0]); return this.createStringCall("byte", node, caller, firstParamPlusOne); } @@ -4290,8 +4133,7 @@ export class LuaTransformer { methodName: string, tsOriginal: ts.Node, ...params: tstl.Expression[] - ): tstl.CallExpression - { + ): tstl.CallExpression { const stringIdentifier = tstl.createIdentifier("string"); return tstl.createCallExpression( tstl.createTableIndexExpression(stringIdentifier, tstl.createStringLiteral(methodName)), @@ -4337,11 +4179,7 @@ export class LuaTransformer { case "values": return this.transformLuaLibFunction(LuaLibFeature.ObjectValues, expression, ...parameters); default: - throw TSTLErrors.UnsupportedForTarget( - `object property ${methodName}`, - this.luaTarget, - expression - ); + throw TSTLErrors.UnsupportedForTarget(`object property ${methodName}`, this.luaTarget, expression); } } @@ -4352,19 +4190,16 @@ export class LuaTransformer { switch (methodName) { case "log": - if (expression.arguments.length > 0 - && this.isStringFormatTemplate(expression.arguments[0])) { + if (expression.arguments.length > 0 && this.isStringFormatTemplate(expression.arguments[0])) { // print(string.format([arguments])) const stringFormatCall = tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("string"), - tstl.createStringLiteral("format")), + tstl.createStringLiteral("format") + ), this.transformArguments(expression.arguments, signature) ); - return tstl.createCallExpression( - tstl.createIdentifier("print"), - [stringFormatCall] - ); + return tstl.createCallExpression(tstl.createIdentifier("print"), [stringFormatCall]); } // print([arguments]) return tstl.createCallExpression( @@ -4373,63 +4208,49 @@ export class LuaTransformer { ); case "assert": const args = this.transformArguments(expression.arguments, signature); - if (expression.arguments.length > 1 - && this.isStringFormatTemplate(expression.arguments[1])) { + if (expression.arguments.length > 1 && this.isStringFormatTemplate(expression.arguments[1])) { // assert([condition], string.format([arguments])) const stringFormatCall = tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("string"), - tstl.createStringLiteral("format")), + tstl.createStringLiteral("format") + ), args.slice(1) ); - return tstl.createCallExpression( - tstl.createIdentifier("assert"), - [args[0], stringFormatCall] - ); + return tstl.createCallExpression(tstl.createIdentifier("assert"), [args[0], stringFormatCall]); } // assert() - return tstl.createCallExpression( - tstl.createIdentifier("assert"), - args - ); + return tstl.createCallExpression(tstl.createIdentifier("assert"), args); case "trace": - if (expression.arguments.length > 0 - && this.isStringFormatTemplate(expression.arguments[0])) { + if (expression.arguments.length > 0 && this.isStringFormatTemplate(expression.arguments[0])) { // print(debug.traceback(string.format([arguments]))) const stringFormatCall = tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("string"), - tstl.createStringLiteral("format")), + tstl.createStringLiteral("format") + ), this.transformArguments(expression.arguments, signature) ); const debugTracebackCall = tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("debug"), - tstl.createStringLiteral("traceback")), + tstl.createStringLiteral("traceback") + ), [stringFormatCall] ); - return tstl.createCallExpression( - tstl.createIdentifier("print"), - [debugTracebackCall] - ); + return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]); } // print(debug.traceback([arguments]))) const debugTracebackCall = tstl.createCallExpression( tstl.createTableIndexExpression( tstl.createIdentifier("debug"), - tstl.createStringLiteral("traceback")), + tstl.createStringLiteral("traceback") + ), this.transformArguments(expression.arguments, signature) ); - return tstl.createCallExpression( - tstl.createIdentifier("print"), - [debugTracebackCall] - ); + return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]); default: - throw TSTLErrors.UnsupportedForTarget( - `console property ${methodName}`, - this.luaTarget, - expression - ); + throw TSTLErrors.UnsupportedForTarget(`console property ${methodName}`, this.luaTarget, expression); } } @@ -4452,11 +4273,7 @@ export class LuaTransformer { const functionIdentifier = tstl.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); return tstl.createCallExpression(functionIdentifier, parameters, expression); default: - throw TSTLErrors.UnsupportedForTarget( - `symbol property ${methodName}`, - this.luaTarget, - expression - ); + throw TSTLErrors.UnsupportedForTarget(`symbol property ${methodName}`, this.luaTarget, expression); } } @@ -4472,11 +4289,7 @@ export class LuaTransformer { case "isFinite": return this.transformLuaLibFunction(LuaLibFeature.NumberIsFinite, expression, ...parameters); default: - throw TSTLErrors.UnsupportedForTarget( - `number property ${methodName}`, - this.luaTarget, - expression - ); + throw TSTLErrors.UnsupportedForTarget(`number property ${methodName}`, this.luaTarget, expression); } } @@ -4492,10 +4305,7 @@ export class LuaTransformer { switch (methodName) { case "get": if (expression.arguments.length !== 1) { - throw TSTLErrors.ForbiddenLuaTableUseException( - "One parameter is required for get().", - expression - ); + throw TSTLErrors.ForbiddenLuaTableUseException("One parameter is required for get().", expression); } break; case "set": @@ -4513,9 +4323,9 @@ export class LuaTransformer { } private transformLuaTableExpressionStatement( - node: ts.ExpressionStatement - & { expression: ts.CallExpression } - & { expression: { expression: ts.PropertyAccessExpression }} + node: ts.ExpressionStatement & { expression: ts.CallExpression } & { + expression: { expression: ts.PropertyAccessExpression }; + } ): tstl.VariableDeclarationStatement | tstl.AssignmentStatement { const methodName = node.expression.expression.name.escapedText; const signature = this.checker.getResolvedSignature(node.expression); @@ -4537,10 +4347,7 @@ export class LuaTransformer { node.expression ); default: - throw TSTLErrors.ForbiddenLuaTableUseException( - "Unsupported method.", - node.expression - ); + throw TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", node.expression); } } @@ -4558,10 +4365,7 @@ export class LuaTransformer { case "get": return tstl.createTableIndexExpression(luaTable, params[0], expression); default: - throw TSTLErrors.ForbiddenLuaTableUseException( - "Unsupported method.", - expression - ); + throw TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", expression); } } @@ -4609,9 +4413,8 @@ export class LuaTransformer { case "splice": return this.transformLuaLibFunction(LuaLibFeature.ArraySplice, node, caller, ...params); case "join": - const parameters = node.arguments.length === 0 - ? [caller, tstl.createStringLiteral(",")] - : [caller].concat(params); + const parameters = + node.arguments.length === 0 ? [caller, tstl.createStringLiteral(",")] : [caller].concat(params); return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("concat")), @@ -4680,12 +4483,7 @@ export class LuaTransformer { const andClause = tstl.createBinaryExpression(condition, objectString, tstl.SyntaxKind.AndOperator); return tstl.createParenthesizedExpression( - tstl.createBinaryExpression( - andClause, - tstl.cloneNode(typeCall), - tstl.SyntaxKind.OrOperator, - expression - ) + tstl.createBinaryExpression(andClause, tstl.cloneNode(typeCall), tstl.SyntaxKind.OrOperator, expression) ); } @@ -4747,10 +4545,8 @@ export class LuaTransformer { } }); - return parts.reduce((prev, current) => tstl.createBinaryExpression( - prev, - current, - tstl.SyntaxKind.ConcatOperator) + return parts.reduce((prev, current) => + tstl.createBinaryExpression(prev, current, tstl.SyntaxKind.ConcatOperator) ); } @@ -4773,10 +4569,11 @@ export class LuaTransformer { public transformIdentifier(identifier: ts.Identifier): tstl.Identifier { if (identifier.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { - return tstl.createIdentifier("nil"); // TODO this is a hack that allows use to keep Identifier - // as return time as changing that would break a lot of stuff. - // But this should be changed to return tstl.createNilLiteral() - // at some point. + // TODO this is a hack that allows use to keep Identifier + // as return time as changing that would break a lot of stuff. + // But this should be changed to return tstl.createNilLiteral() + // at some point. + return tstl.createIdentifier("nil"); } const text = this.hasUnsafeIdentifierName(identifier) @@ -4868,22 +4665,18 @@ export class LuaTransformer { } else { exportTable = this.transformIdentifier(this.currentNamespace.name as ts.Identifier); } - } else { exportTable = this.createExportsIdentifier(); } - return tstl.createTableIndexExpression( - exportTable, - tstl.createStringLiteral(identifier.text)); + return tstl.createTableIndexExpression(exportTable, tstl.createStringLiteral(identifier.text)); } protected transformLuaLibFunction( func: LuaLibFeature, tsParent?: ts.Expression, ...params: tstl.Expression[] - ): tstl.CallExpression - { + ): tstl.CallExpression { this.importLuaLibFeature(func); const functionIdentifier = tstl.createIdentifier(`__TS__${func}`); return tstl.createCallExpression(functionIdentifier, params, tsParent); @@ -4916,8 +4709,7 @@ export class LuaTransformer { statements: tstl.Statement[], result: tstl.Expression | tstl.Expression[], tsOriginal: ts.Node - ): tstl.CallExpression - { + ): tstl.CallExpression { const body = statements ? statements.slice(0) : []; body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result])); const flags = statements.length === 0 ? tstl.FunctionExpressionFlags.Inline : tstl.FunctionExpressionFlags.None; @@ -4962,12 +4754,13 @@ export class LuaTransformer { const absoluteImportPath = path.format(path.parse(this.getAbsoluteImportPath(relativePath))); const absoluteRootDirPath = path.format(path.parse(rootDir)); if (absoluteImportPath.includes(absoluteRootDirPath)) { - return this.formatPathToLuaPath( - absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); + return this.formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); } else { - throw TSTLErrors.UnresolvableRequirePath(node, + throw TSTLErrors.UnresolvableRequirePath( + node, `Cannot create require path. Module does not exist within --rootDir`, - relativePath); + relativePath + ); } } @@ -4975,13 +4768,9 @@ export class LuaTransformer { filePath = filePath.replace(/\.json$/, ""); if (process.platform === "win32") { // Windows can use backslashes - filePath = filePath - .replace(/\.\\/g, "") - .replace(/\\/g, "."); + filePath = filePath.replace(/\.\\/g, "").replace(/\\/g, "."); } - return filePath - .replace(/\.\//g, "") - .replace(/\//g, "."); + return filePath.replace(/\.\//g, "").replace(/\//g, "."); } protected shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { @@ -5008,8 +4797,7 @@ export class LuaTransformer { rhs?: tstl.Expression | tstl.Expression[], tsOriginal?: ts.Node, parent?: tstl.Node - ): tstl.Statement[] - { + ): tstl.Statement[] { let declaration: tstl.VariableDeclarationStatement | undefined; let assignment: tstl.AssignmentStatement | undefined; @@ -5026,7 +4814,6 @@ export class LuaTransformer { tsOriginal, parent ); - } else { assignment = tstl.createAssignmentStatement( this.createExportedIdentifier(lhs), @@ -5035,7 +4822,6 @@ export class LuaTransformer { parent ); } - } else { const insideFunction = this.findScope(ScopeType.Function) !== undefined; let isLetOrConst = false; @@ -5046,38 +4832,39 @@ export class LuaTransformer { } if ((this.isModule || this.currentNamespace || insideFunction || isLetOrConst) && isFirstDeclaration) { // local - const isPossibleWrappedFunction = !functionDeclaration - && tsOriginal - && ts.isVariableDeclaration(tsOriginal) - && tsOriginal.initializer - && tsHelper.isFunctionTypeAtLocation(tsOriginal.initializer, this.checker); + const isPossibleWrappedFunction = + !functionDeclaration && + tsOriginal && + ts.isVariableDeclaration(tsOriginal) && + tsOriginal.initializer && + tsHelper.isFunctionTypeAtLocation(tsOriginal.initializer, this.checker); if (isPossibleWrappedFunction) { // Split declaration and assignment for wrapped function types to allow recursion declaration = tstl.createVariableDeclarationStatement(lhs, undefined, tsOriginal, parent); assignment = tstl.createAssignmentStatement(lhs, rhs, tsOriginal, parent); - } else { declaration = tstl.createVariableDeclarationStatement(lhs, rhs, tsOriginal, parent); } if (!this.options.noHoisting) { // Remember local variable declarations for hoisting later - const scope = isLetOrConst || functionDeclaration - ? this.peekScope() - : this.findScope(ScopeType.Function | ScopeType.File); + const scope = + isLetOrConst || functionDeclaration + ? this.peekScope() + : this.findScope(ScopeType.Function | ScopeType.File); if (scope === undefined) { throw TSTLErrors.UndefinedScope(); } - if (!scope.variableDeclarations) { scope.variableDeclarations = []; } + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } scope.variableDeclarations.push(declaration); } - } else if (rhs) { // global assignment = tstl.createAssignmentStatement(lhs, rhs, tsOriginal, parent); - } else { return []; } @@ -5151,8 +4938,10 @@ export class LuaTransformer { return; } - if ((ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) - && (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode))) { + if ( + (ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && + (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode)) + ) { // Recurse into arrays/tuples const fromTypeArguments = (fromType as ts.TypeReference).typeArguments; const toTypeArguments = (toType as ts.TypeReference).typeArguments; @@ -5163,19 +4952,18 @@ export class LuaTransformer { const count = Math.min(fromTypeArguments.length, toTypeArguments.length); for (let i = 0; i < count; ++i) { - this.validateFunctionAssignment( - node, - fromTypeArguments[i], - toTypeArguments[i], - toName - ); + this.validateFunctionAssignment(node, fromTypeArguments[i], toTypeArguments[i], toName); } } - if ((toType.flags & ts.TypeFlags.Object) !== 0 - && ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0 - && toType.symbol && toType.symbol.members && fromType.symbol && fromType.symbol.members) - { + if ( + (toType.flags & ts.TypeFlags.Object) !== 0 && + ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0 && + toType.symbol && + toType.symbol.members && + fromType.symbol && + fromType.symbol.members + ) { // Recurse into interfaces toType.symbol.members.forEach((toMember, memberName) => { if (fromType.symbol.members) { @@ -5184,10 +4972,10 @@ export class LuaTransformer { const toMemberType = this.checker.getTypeOfSymbolAtLocation(toMember, node); const fromMemberType = this.checker.getTypeOfSymbolAtLocation(fromMember, node); this.validateFunctionAssignment( - node, fromMemberType, toMemberType, - toName - ? `${toName}.${memberName}` - : memberName.toString() + node, + fromMemberType, + toMemberType, + toName ? `${toName}.${memberName}` : memberName.toString() ); } } @@ -5228,10 +5016,11 @@ export class LuaTransformer { } protected wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { - if (tstl.isStringLiteral(expression) - || tstl.isNumericLiteral(expression) - || (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator)) - { + if ( + tstl.isStringLiteral(expression) || + tstl.isNumericLiteral(expression) || + (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator) + ) { return expression; } return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); @@ -5262,23 +5051,19 @@ export class LuaTransformer { protected createShorthandIdentifier( valueSymbol: ts.Symbol | undefined, propertyIdentifier: ts.Identifier - ): tstl.Expression - { + ): tstl.Expression { let name: string; if (valueSymbol !== undefined) { name = this.hasUnsafeSymbolName(valueSymbol, propertyIdentifier) ? this.createSafeName(valueSymbol.name) : valueSymbol.name; - } else { const propertyName = this.getIdentifierText(propertyIdentifier); if (luaKeywords.has(propertyName) || !tsHelper.isValidLuaIdentifier(propertyName)) { // Catch ambient declarations of identifiers with bad names throw TSTLErrors.InvalidAmbientIdentifierName(propertyIdentifier); } - name = this.hasUnsafeIdentifierName(propertyIdentifier) - ? this.createSafeName(propertyName) - : propertyName; + name = this.hasUnsafeIdentifierName(propertyIdentifier) ? this.createSafeName(propertyName) : propertyName; } const identifier = this.transformIdentifierExpression(ts.createIdentifier(name)); @@ -5331,10 +5116,9 @@ export class LuaTransformer { if (!this.symbolIds.has(symbol)) { symbolId = this.genSymbolIdCounter++; - const symbolInfo: SymbolInfo = {symbol, firstSeenAtPos: identifier.pos}; + const symbolInfo: SymbolInfo = { symbol, firstSeenAtPos: identifier.pos }; this.symbolIds.set(symbol, symbolId); this.symbolInfo.set(symbolId, symbolInfo); - } else { symbolId = this.symbolIds.get(symbol); } @@ -5345,7 +5129,6 @@ export class LuaTransformer { if (declaration && identifier.pos < declaration.pos) { throw TSTLErrors.ReferencedBeforeDeclaration(identifier); } - } else if (symbolId !== undefined) { //Mark symbol as seen in all current scopes for (const scope of this.scopeStack) { @@ -5360,7 +5143,10 @@ export class LuaTransformer { } protected findScope(scopeTypes: ScopeType): Scope | undefined { - return this.scopeStack.slice().reverse().find(s => (scopeTypes & s.type) !== 0); + return this.scopeStack + .slice() + .reverse() + .find(s => (scopeTypes & s.type) !== 0); } protected peekScope(): Scope | undefined { @@ -5403,11 +5189,12 @@ export class LuaTransformer { const { line, column } = tstl.getOriginalPos(functionDefinition.definition); if (line !== undefined && column !== undefined) { const definitionPos = ts.getPositionOfLineAndCharacter(this.currentSourceFile, line, column); - if (functionSymbolId !== symbolId // Don't recurse into self - && declaration.pos < definitionPos // Ignore functions before symbol declaration - && functionDefinition.referencedSymbols.has(symbolId) - && this.shouldHoist(functionSymbolId, scope)) - { + if ( + functionSymbolId !== symbolId && // Don't recurse into self + declaration.pos < definitionPos && // Ignore functions before symbol declaration + functionDefinition.referencedSymbols.has(symbolId) && + this.shouldHoist(functionSymbolId, scope) + ) { return true; } } @@ -5534,15 +5321,16 @@ export class LuaTransformer { initializer?: tstl.Expression, tsOriginal?: ts.Node, parent?: tstl.Node - ): tstl.AssignmentStatement | tstl.VariableDeclarationStatement - { + ): tstl.AssignmentStatement | tstl.VariableDeclarationStatement { const declaration = tstl.createVariableDeclarationStatement(identifier, initializer, tsOriginal, parent); if (!this.options.noHoisting && identifier.symbolId) { const scope = this.peekScope(); if (scope === undefined) { throw TSTLErrors.UndefinedScope(); } - if (!scope.variableDeclarations) { scope.variableDeclarations = []; } + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } scope.variableDeclarations.push(declaration); } return declaration; @@ -5564,7 +5352,8 @@ export class LuaTransformer { } protected filterUndefinedAndCast( - items: Array, cast: (item: TOriginal) => item is TCast + items: Array, + cast: (item: TOriginal) => item is TCast ): TCast[] { const filteredItems = items.filter(i => i !== undefined) as TOriginal[]; if (filteredItems.every(i => cast(i))) { @@ -5577,18 +5366,23 @@ export class LuaTransformer { private createConstructorDecorationStatement( declaration: ts.ClassLikeDeclaration ): tstl.AssignmentStatement | undefined { - const className = declaration.name !== undefined - ? this.addExportToIdentifier(this.transformIdentifier(declaration.name)) - : tstl.createAnonymousIdentifier(); + const className = + declaration.name !== undefined + ? this.addExportToIdentifier(this.transformIdentifier(declaration.name)) + : tstl.createAnonymousIdentifier(); const decorators = declaration.decorators; - if (!decorators) { return undefined; } + if (!decorators) { + return undefined; + } const decoratorExpressions = decorators.map(decorator => { const expression = decorator.expression; const type = this.checker.getTypeAtLocation(expression); const context = tsHelper.getFunctionContextType(type, this.checker); - if (context === ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } + if (context === ContextType.Void) { + throw TSTLErrors.InvalidDecoratorContext(decorator); + } return this.transformExpression(expression); }); @@ -5607,4 +5401,3 @@ export class LuaTransformer { ); } } - diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 8764f500f..ad63e2e19 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -30,8 +30,10 @@ const defaultArrayCallMethodNames = new Set([ ]); export class TSHelper { - public static getExtendedTypeNode(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): - ts.ExpressionWithTypeArguments | undefined { + public static getExtendedTypeNode( + node: ts.ClassLikeDeclarationBase, + checker: ts.TypeChecker + ): ts.ExpressionWithTypeArguments | undefined { if (node && node.heritageClauses) { for (const clause of node.heritageClauses) { if (clause.token === ts.SyntaxKind.ExtendsKeyword) { @@ -61,22 +63,37 @@ export class TSHelper { } if (ts.isVariableStatement(statement)) { return statement.declarationList.declarations.some( - declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0); + declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 + ); } - return TSHelper.isDeclaration(statement) - && ((ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0); + return ( + TSHelper.isDeclaration(statement) && + (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0 + ); } public static isDeclaration(node: ts.Node): node is ts.Declaration { - return ts.isEnumDeclaration(node) || ts.isClassDeclaration(node) || ts.isExportDeclaration(node) - || ts.isImportDeclaration(node) || ts.isMethodDeclaration(node) || ts.isModuleDeclaration(node) - || ts.isFunctionDeclaration(node) || ts.isVariableDeclaration(node) || ts.isInterfaceDeclaration(node) - || ts.isTypeAliasDeclaration(node) || ts.isNamespaceExportDeclaration(node); + return ( + ts.isEnumDeclaration(node) || + ts.isClassDeclaration(node) || + ts.isExportDeclaration(node) || + ts.isImportDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isModuleDeclaration(node) || + ts.isFunctionDeclaration(node) || + ts.isVariableDeclaration(node) || + ts.isInterfaceDeclaration(node) || + ts.isTypeAliasDeclaration(node) || + ts.isNamespaceExportDeclaration(node) + ); } public static isInDestructingAssignment(node: ts.Node): boolean { - return node.parent && ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || - (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))); + return ( + node.parent && + ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || + (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) + ); } // iterate over a type and its bases until the callback returns true. @@ -84,8 +101,7 @@ export class TSHelper { type: ts.Type, checker: ts.TypeChecker, predicate: (type: ts.Type) => boolean - ): boolean - { + ): boolean { if (predicate(type)) { return true; } @@ -112,13 +128,19 @@ export class TSHelper { } public static isStringType(type: ts.Type): boolean { - return (type.flags & ts.TypeFlags.String) !== 0 || (type.flags & ts.TypeFlags.StringLike) !== 0 || - (type.flags & ts.TypeFlags.StringLiteral) !== 0; + return ( + (type.flags & ts.TypeFlags.String) !== 0 || + (type.flags & ts.TypeFlags.StringLike) !== 0 || + (type.flags & ts.TypeFlags.StringLiteral) !== 0 + ); } public static isNumberType(type: ts.Type): boolean { - return (type.flags & ts.TypeFlags.Number) !== 0 || (type.flags & ts.TypeFlags.NumberLike) !== 0 || - (type.flags & ts.TypeFlags.NumberLiteral) !== 0; + return ( + (type.flags & ts.TypeFlags.Number) !== 0 || + (type.flags & ts.TypeFlags.NumberLike) !== 0 || + (type.flags & ts.TypeFlags.NumberLiteral) !== 0 + ); } public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { @@ -164,9 +186,11 @@ export class TSHelper { // Only check function type for directive if it is declared as an interface or type alias const declaration = signature.getDeclaration(); - const isInterfaceOrAlias = declaration && declaration.parent - && ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) - || ts.isTypeAliasDeclaration(declaration.parent)); + const isInterfaceOrAlias = + declaration && + declaration.parent && + ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || + ts.isTypeAliasDeclaration(declaration.parent)); if (!isInterfaceOrAlias) { return false; } @@ -174,7 +198,6 @@ export class TSHelper { const type = checker.getTypeAtLocation(node.expression); return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); - } else { return false; } @@ -200,15 +223,15 @@ export class TSHelper { // Check all overloads for directive const signatures = functionType.getCallSignatures(); - if (signatures && signatures.some( - s => TSHelper.getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn))) - { + if ( + signatures && + signatures.some(s => TSHelper.getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn)) + ) { return true; } const decorators = TSHelper.getCustomDecorators(functionType, checker); return decorators.has(DecoratorKind.TupleReturn); - } else { return false; } @@ -227,14 +250,14 @@ export class TSHelper { source: ts.Symbol | ts.Signature, checker: ts.TypeChecker, decMap: Map - ): void - { + ): void { const comments = source.getDocumentationComment(checker); - const decorators = comments.filter(comment => comment.kind === "text") - .map(comment => comment.text.split("\n")) - .reduce((a, b) => a.concat(b), []) - .map(line => line.trim()) - .filter(comment => comment[0] === "!"); + const decorators = comments + .filter(comment => comment.kind === "text") + .map(comment => comment.text.split("\n")) + .reduce((a, b) => a.concat(b), []) + .map(line => line.trim()) + .filter(comment => comment[0] === "!"); decorators.forEach(decStr => { const [decoratorName, ...decoratorArguments] = decStr.split(" "); @@ -242,8 +265,8 @@ export class TSHelper { const dec = new Decorator(decoratorName.substr(1), decoratorArguments); decMap.set(dec.kind, dec); console.warn( - `[Deprecated] Decorators with ! are being deprecated, ` + - `use @${decStr.substr(1)} instead`); + `[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead` + ); } else { console.warn(`Encountered unknown decorator ${decStr}.`); } @@ -282,9 +305,10 @@ export class TSHelper { return decMap; } - public static getCustomSignatureDirectives(signature: ts.Signature, checker: ts.TypeChecker) - : Map - { + public static getCustomSignatureDirectives( + signature: ts.Signature, + checker: ts.TypeChecker + ): Map { const directivesMap = new Map(); TSHelper.collectCustomDecorators(signature, checker, directivesMap); @@ -302,7 +326,8 @@ export class TSHelper { // Search up until finding a node satisfying the callback public static findFirstNodeAbove( - node: ts.Node, callback: (n: ts.Node) => n is T + node: ts.Node, + callback: (n: ts.Node) => n is T ): T | undefined { let current = node; while (current.parent) { @@ -357,11 +382,12 @@ export class TSHelper { node: ts.Expression, checker: ts.TypeChecker, program: ts.Program - ): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] - { - if (ts.isElementAccessExpression(node) && - (TSHelper.isExpressionWithEvaluationEffect(node.expression) - || TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression))) { + ): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] { + if ( + ts.isElementAccessExpression(node) && + (TSHelper.isExpressionWithEvaluationEffect(node.expression) || + TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression)) + ) { const type = checker.getTypeAtLocation(node.expression); if (TSHelper.isArrayType(type, checker, program)) { // Offset arrays by one @@ -386,15 +412,15 @@ export class TSHelper { signatureDeclaration: ts.SignatureDeclaration ): ts.ParameterDeclaration | undefined { return signatureDeclaration.parameters.find( - param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword); + param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword + ); } public static findInClassOrAncestor( classDeclaration: ts.ClassLikeDeclarationBase, callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, checker: ts.TypeChecker - ): ts.ClassLikeDeclarationBase | undefined - { + ): ts.ClassLikeDeclarationBase | undefined { if (callback(classDeclaration)) { return classDeclaration; } @@ -426,26 +452,28 @@ export class TSHelper { classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker - ): boolean - { - return TSHelper.findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isSetAccessor(m) && TSHelper.isStatic(m) === isStatic), - checker - ) !== undefined; + ): boolean { + return ( + TSHelper.findInClassOrAncestor( + classDeclaration, + c => c.members.some(m => ts.isSetAccessor(m) && TSHelper.isStatic(m) === isStatic), + checker + ) !== undefined + ); } public static hasGetAccessorInClassOrAncestor( classDeclaration: ts.ClassLikeDeclarationBase, isStatic: boolean, checker: ts.TypeChecker - ): boolean - { - return TSHelper.findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isGetAccessor(m) && TSHelper.isStatic(m) === isStatic), - checker - ) !== undefined; + ): boolean { + return ( + TSHelper.findInClassOrAncestor( + classDeclaration, + c => c.members.some(m => ts.isGetAccessor(m) && TSHelper.isStatic(m) === isStatic), + checker + ) !== undefined + ); } public static getPropertyName(propertyName: ts.PropertyName): string | number | undefined { @@ -466,22 +494,20 @@ export class TSHelper { element: ts.ClassElement, classDeclaration: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker - ): element is ts.GetAccessorDeclaration - { + ): element is ts.GetAccessorDeclaration { if (!ts.isGetAccessor(element) || TSHelper.isStatic(element)) { return false; } const hasInitializedField = (e: ts.ClassElement) => - ts.isPropertyDeclaration(e) - && e.initializer !== undefined - && TSHelper.isSamePropertyName(e.name, element.name); + ts.isPropertyDeclaration(e) && + e.initializer !== undefined && + TSHelper.isSamePropertyName(e.name, element.name); - return TSHelper.findInClassOrAncestor( - classDeclaration, - c => c.members.some(hasInitializedField), - checker - ) !== undefined; + return ( + TSHelper.findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !== + undefined + ); } public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { @@ -498,14 +524,14 @@ export class TSHelper { public static getSignatureDeclarations( signatures: readonly ts.Signature[], checker: ts.TypeChecker - ): ts.SignatureDeclaration[] - { + ): ts.SignatureDeclaration[] { const signatureDeclarations: ts.SignatureDeclaration[] = []; for (const signature of signatures) { const signatureDeclaration = signature.getDeclaration(); - if ((ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) - && !TSHelper.getExplicitThisParameter(signatureDeclaration)) - { + if ( + (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && + !TSHelper.getExplicitThisParameter(signatureDeclaration) + ) { // Infer type of function expressions/arrow functions const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); if (inferredType) { @@ -542,8 +568,7 @@ export class TSHelper { public static getDeclarationContextType( signatureDeclaration: ts.SignatureDeclaration, checker: ts.TypeChecker - ): ContextType - { + ): ContextType { const thisParameter = TSHelper.getExplicitThisParameter(signatureDeclaration); if (thisParameter) { // Explicit 'this' @@ -552,20 +577,19 @@ export class TSHelper { : ContextType.NonVoid; } - if (ts.isMethodSignature(signatureDeclaration) - || ts.isMethodDeclaration(signatureDeclaration) - || ts.isConstructSignatureDeclaration(signatureDeclaration) - || ts.isConstructorDeclaration(signatureDeclaration) - || (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) - || (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent))) - { + if ( + ts.isMethodSignature(signatureDeclaration) || + ts.isMethodDeclaration(signatureDeclaration) || + ts.isConstructSignatureDeclaration(signatureDeclaration) || + ts.isConstructorDeclaration(signatureDeclaration) || + (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || + (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) + ) { // Class/interface methods only respect @noSelf on their parent const scopeDeclaration = TSHelper.findFirstNodeAbove( signatureDeclaration, (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => - ts.isClassDeclaration(n) - || ts.isClassExpression(n) - || ts.isInterfaceDeclaration(n) + ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) ); if (scopeDeclaration === undefined) { @@ -608,9 +632,7 @@ export class TSHelper { } if (type.isUnion()) { - return TSHelper.reduceContextTypes( - type.types.map(t => TSHelper.getFunctionContextType(t, checker)) - ); + return TSHelper.reduceContextTypes(type.types.map(t => TSHelper.getFunctionContextType(t, checker))); } const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); @@ -619,15 +641,16 @@ export class TSHelper { } const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker); return TSHelper.reduceContextTypes( - signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker))); + signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker)) + ); } public static escapeString(text: string): string { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String const escapeSequences: Array<[RegExp, string]> = [ [/[\\]/g, "\\\\"], - [/[\']/g, "\\\'"], - [/[\"]/g, "\\\""], + [/[\']/g, "\\'"], + [/[\"]/g, '\\"'], [/[\n]/g, "\\n"], [/[\r]/g, "\\r"], [/[\v]/g, "\\v"], @@ -651,7 +674,14 @@ export class TSHelper { } public static fixInvalidLuaIdentifier(name: string): string { - return name.replace(/[^a-zA-Z0-9_]/g, c => `_${c.charCodeAt(0).toString(16).toUpperCase()}`); + return name.replace( + /[^a-zA-Z0-9_]/g, + c => + `_${c + .charCodeAt(0) + .toString(16) + .toUpperCase()}` + ); } // Checks that a name is valid for use in lua function declaration syntax: @@ -663,13 +693,14 @@ export class TSHelper { } public static isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { - const falsibleFlags = ts.TypeFlags.Boolean - | ts.TypeFlags.BooleanLiteral - | ts.TypeFlags.Undefined - | ts.TypeFlags.Null - | ts.TypeFlags.Never - | ts.TypeFlags.Void - | ts.TypeFlags.Any; + const falsibleFlags = + ts.TypeFlags.Boolean | + ts.TypeFlags.BooleanLiteral | + ts.TypeFlags.Undefined | + ts.TypeFlags.Null | + ts.TypeFlags.Never | + ts.TypeFlags.Void | + ts.TypeFlags.Any; if (type.flags & falsibleFlags) { return true; @@ -694,9 +725,7 @@ export class TSHelper { if (sourceFile) { declarations = declarations.filter(d => this.findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); } - return declarations.length > 0 - ? declarations.reduce((p, c) => p.pos < c.pos ? p : c) - : undefined; + return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; } public static isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean { @@ -710,18 +739,22 @@ export class TSHelper { public static isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean { const source = declaration.getSourceFile(); - if (!source) { return false; } + if (!source) { + return false; + } return program.isSourceFileDefaultLibrary(source); } public static isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean { const symbol = type.getSymbol(); - if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === '__type')) { + if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) { return false; } const declaration = symbol.valueDeclaration; - if(!declaration) { return true; } // assume to be lib function if no valueDeclaration exists + if (!declaration) { + return true; + } // assume to be lib function if no valueDeclaration exists return this.isStandardLibraryDeclaration(declaration, program); } @@ -745,15 +778,17 @@ export class TSHelper { } } - public static moduleHasEmittedBody(statement: ts.ModuleDeclaration) - : statement is ts.ModuleDeclaration & {body: ts.ModuleBlock | ts.ModuleDeclaration} - { + public static moduleHasEmittedBody( + statement: ts.ModuleDeclaration + ): statement is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { if (statement.body) { if (ts.isModuleBlock(statement.body)) { // Ignore if body has no emitted statements - return statement.body.statements.findIndex( - s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) - ) !== -1; + return ( + statement.body.statements.findIndex( + s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) + ) !== -1 + ); } else if (ts.isModuleDeclaration(statement.body)) { return true; } @@ -765,8 +800,7 @@ export class TSHelper { expression: ts.BinaryExpression, checker: ts.TypeChecker, program: ts.Program - ): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression; } - { + ): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression } { if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { return false; } @@ -781,7 +815,7 @@ export class TSHelper { } const name = ts.isPropertyAccessExpression(expression.left) - ? expression.left.name.escapedText as string + ? (expression.left.name.escapedText as string) : ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text; return name === "length"; diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 4f2b6e565..26d08d1ca 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -2,8 +2,7 @@ import * as ts from "typescript"; import { TranspileError } from "./TranspileError"; import { LuaTarget } from "./CompilerOptions"; -const getLuaTargetName = (version: LuaTarget) => - version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`; +const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export class TSTLErrors { public static CouldNotCast = (castName: string) => @@ -21,9 +20,11 @@ export class TSTLErrors { public static ForbiddenForIn = (node: ts.Node) => new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); - public static ForbiddenLuaTableSetExpression = (node: ts.Node) => new TranspileError( - `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, - node); + public static ForbiddenLuaTableSetExpression = (node: ts.Node) => + new TranspileError( + `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, + node + ); public static ForbiddenLuaTableNonDeclaration = (node: ts.Node) => new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); @@ -37,10 +38,12 @@ export class TSTLErrors { public static ForbiddenLuaTableUseException = (description: string, node: ts.Node) => new TranspileError(`Invalid @luaTable usage: ${description}`, node); - public static HeterogeneousEnum = (node: ts.Node) => new TranspileError( - `Invalid heterogeneous enum. Enums should either specify no member values, ` + - `or specify values (of the same type) for all members.`, - node); + public static HeterogeneousEnum = (node: ts.Node) => + new TranspileError( + `Invalid heterogeneous enum. Enums should either specify no member values, ` + + `or specify values (of the same type) for all members.`, + node + ); public static InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); @@ -66,8 +69,7 @@ export class TSTLErrors { public static InvalidInstanceOfExtension = (node: ts.Node) => new TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node); - public static InvalidJsonFileContent = (node: ts.Node) => - new TranspileError("Invalid JSON file content", node); + public static InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); public static InvalidPropertyCall = (node: ts.Node) => new TranspileError(`Tried to transpile a non-property call as property call.`, node); @@ -93,14 +95,12 @@ export class TSTLErrors { public static MissingMetaExtension = (node: ts.Node) => new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); - public static MissingSourceFile = () => - new Error("Expected transformer.sourceFile to be set, but it isn't."); + public static MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't."); public static UndefinedFunctionDefinition = (functionSymbolId: number) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); - public static UndefinedScope = () => - new Error("Expected to pop a scope, but found undefined."); + public static UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); public static UndefinedTypeNode = (node: ts.Node) => new TranspileError("Failed to resolve required type node.", node); @@ -111,8 +111,7 @@ export class TSTLErrors { public static UnsupportedDefaultExport = (node: ts.Node) => new TranspileError(`Default exports are not supported.`, node); - public static UnsupportedImportType = (node: ts.Node) => - new TranspileError(`Unsupported import type.`, node); + public static UnsupportedImportType = (node: ts.Node) => new TranspileError(`Unsupported import type.`, node); public static UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => new TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node); @@ -130,13 +129,15 @@ export class TSTLErrors { if (name) { return new TranspileError( `Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node); + `To fix, wrap in an arrow function, or declare with 'this: void'.`, + node + ); } else { return new TranspileError( `Unable to convert function with a 'this' parameter to function with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node); + `To fix, wrap in an arrow function, or declare with 'this: void'.`, + node + ); } }; @@ -144,13 +145,15 @@ export class TSTLErrors { if (name) { return new TranspileError( `Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node); + `To fix, wrap in an arrow function or declare with 'this: any'.`, + node + ); } else { return new TranspileError( `Unable to convert function with no 'this' parameter to function with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node); + `To fix, wrap in an arrow function or declare with 'this: any'.`, + node + ); } }; @@ -158,13 +161,15 @@ export class TSTLErrors { if (name) { return new TranspileError( `Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` + - `Overloads should all have the same type for 'this'.`, - node); + `Overloads should all have the same type for 'this'.`, + node + ); } else { return new TranspileError( `Unsupported assignment of function with different overloaded types for 'this'. ` + - `Overloads should all have the same type for 'this'.`, - node); + `Overloads should all have the same type for 'this'.`, + node + ); } }; @@ -173,20 +178,18 @@ export class TSTLErrors { "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " + "You must use a destructuring statement to catch results from a lua iterator with " + "the TupleReturn decorator.", - node); + node + ); }; public static UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => { - return new TranspileError( - `${reason}. ` + - `TypeScript path: ${path}.`, - node); + return new TranspileError(`${reason}. ` + `TypeScript path: ${path}.`, node); }; public static ReferencedBeforeDeclaration = (node: ts.Identifier) => { return new TranspileError( `Identifier "${node.text}" was referenced before it was declared. The declaration ` + - "must be moved before the identifier's use, or hoisting must be enabled.", + "must be moved before the identifier's use, or hoisting must be enabled.", node ); }; diff --git a/src/Transpile.ts b/src/Transpile.ts index a8df4c38e..cefebf463 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import { CompilerOptions } from "./CompilerOptions"; import { transpileError } from "./diagnostics"; -import { Block } from './LuaAST'; +import { Block } from "./LuaAST"; import { LuaPrinter } from "./LuaPrinter"; import { LuaTransformer } from "./LuaTransformer"; import { TranspileError } from "./TranspileError"; @@ -12,10 +12,7 @@ function getCustomTransformers( onSourceFile: (sourceFile: ts.SourceFile) => void ): ts.CustomTransformers { // TODO: https://github.com/Microsoft/TypeScript/issues/28310 - const forEachSourceFile = ( - node: ts.SourceFile, - callback: (sourceFile: ts.SourceFile) => ts.SourceFile - ) => + const forEachSourceFile = (node: ts.SourceFile, callback: (sourceFile: ts.SourceFile) => ts.SourceFile) => ts.isBundle(node) ? ((ts.updateBundle(node, node.sourceFiles.map(callback)) as unknown) as ts.SourceFile) : callback(node); @@ -28,11 +25,7 @@ function getCustomTransformers( return { afterDeclarations: customTransformers.afterDeclarations, - before: [ - ...(customTransformers.before || []), - ...(customTransformers.after || []), - luaTransformer, - ], + before: [...(customTransformers.before || []), ...(customTransformers.after || []), luaTransformer], }; } @@ -82,10 +75,7 @@ export function transpile({ }; if (options.noEmitOnError) { - const preEmitDiagnostics = [ - ...program.getOptionsDiagnostics(), - ...program.getGlobalDiagnostics(), - ]; + const preEmitDiagnostics = [...program.getOptionsDiagnostics(), ...program.getGlobalDiagnostics()]; if (targetSourceFiles) { for (const sourceFile of targetSourceFiles) { @@ -110,11 +100,7 @@ export function transpile({ try { const [luaAst, lualibFeatureSet] = transformer.transformSourceFile(sourceFile); if (!options.noEmit && !options.emitDeclarationOnly) { - const [lua, sourceMap] = printer.print( - luaAst, - lualibFeatureSet, - sourceFile.fileName - ); + const [lua, sourceMap] = printer.print(luaAst, lualibFeatureSet, sourceFile.fileName); updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap }); } } catch (err) { @@ -157,15 +143,11 @@ export function transpile({ if (isEmittableJsonFile(file)) { processSourceFile(file); } else { - diagnostics.push( - ...program.emit(file, writeFile, undefined, false, transformers).diagnostics - ); + diagnostics.push(...program.emit(file, writeFile, undefined, false, transformers).diagnostics); } } } else { - diagnostics.push( - ...program.emit(undefined, writeFile, undefined, false, transformers).diagnostics - ); + diagnostics.push(...program.emit(undefined, writeFile, undefined, false, transformers).diagnostics); // JSON files don't get through transformers and aren't written when outDir is the same as rootDir program diff --git a/src/TranspileError.ts b/src/TranspileError.ts index dc64f3da6..baeded940 100644 --- a/src/TranspileError.ts +++ b/src/TranspileError.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; export class TranspileError extends Error { - public name = 'TranspileError'; + public name = "TranspileError"; constructor(message: string, public node: ts.Node) { super(message); } diff --git a/src/diagnostics.ts b/src/diagnostics.ts index ddc8611c4..eb96ecb79 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -35,10 +35,9 @@ export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ : `Found ${errorCount} errors. Watching for file changes.`, }); -const createCommandLineError = ( - code: number, - getMessage: (...args: Args) => string -) => (...args: Args): ts.Diagnostic => ({ +const createCommandLineError = (code: number, getMessage: (...args: Args) => string) => ( + ...args: Args +): ts.Diagnostic => ({ file: undefined, start: undefined, length: undefined, diff --git a/src/index.ts b/src/index.ts index 76cacd36a..4da0e6639 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,10 +26,7 @@ export interface TranspileFilesResult { emitResult: OutputFile[]; } -export function transpileFiles( - rootNames: string[], - options: CompilerOptions = {} -): TranspileFilesResult { +export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult { const program = ts.createProgram(rootNames, options); const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); const emitResult = emitTranspiledFiles(program.getCompilerOptions(), transpiledFiles); @@ -42,10 +39,7 @@ export function transpileFiles( return { diagnostics: [...diagnostics], emitResult }; } -export function transpileProject( - configFileName: string, - optionsToExtend?: CompilerOptions -): TranspileFilesResult { +export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult { const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend); if (parseResult.errors.length > 0) { return { diagnostics: parseResult.errors, emitResult: [] }; @@ -57,10 +51,7 @@ export function transpileProject( const libCache: { [key: string]: ts.SourceFile } = {}; /** @internal */ -export function createVirtualProgram( - input: Record, - options: CompilerOptions = {} -): ts.Program { +export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { const compilerHost: ts.CompilerHost = { fileExists: () => true, getCanonicalFileName: fileName => fileName, @@ -73,12 +64,7 @@ export function createVirtualProgram( getSourceFile: filename => { if (filename in input) { - return ts.createSourceFile( - filename, - input[filename], - ts.ScriptTarget.Latest, - false - ); + return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); } if (filename.startsWith("lib.")) { @@ -87,12 +73,7 @@ export function createVirtualProgram( const filePath = path.join(typeScriptDir, filename); const content = fs.readFileSync(filePath, "utf8"); - libCache[filename] = ts.createSourceFile( - filename, - content, - ts.ScriptTarget.Latest, - false - ); + libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); return libCache[filename]; } @@ -102,16 +83,10 @@ export function createVirtualProgram( return ts.createProgram(Object.keys(input), options, compilerHost); } -export function transpileVirtualProject( - files: Record, - options: CompilerOptions = {} -): TranspileResult { +export function transpileVirtualProject(files: Record, options: CompilerOptions = {}): TranspileResult { const program = createVirtualProgram(files, options); const result = transpile({ program }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...result.diagnostics, - ]); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]); return { ...result, diagnostics: [...diagnostics] }; } @@ -121,10 +96,7 @@ export interface TranspileStringResult { file?: TranspiledFile; } -export function transpileString( - main: string, - options: CompilerOptions = {} -): TranspileStringResult { +export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult { const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") }; } diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index ee34e427b..a133bb97a 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -1,19 +1,19 @@ function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { - const out: any[] = []; - for (const val of arr1) { - out[out.length] = val; - } - for (const arg of args) { - // Hack because we don't have an isArray function - if (pcall(() => (arg as any[]).length) && type(arg) !== "string") { - const argAsArray = (arg as any[]); - for (const val of argAsArray) { - out[out.length] = val; + const out: any[] = []; + for (const val of arr1) { + out[out.length] = val; + } + for (const arg of args) { + // Hack because we don't have an isArray function + if (pcall(() => (arg as any[]).length) && type(arg) !== "string") { + const argAsArray = arg as any[]; + for (const val of argAsArray) { + out[out.length] = val; + } + } else { + out[out.length] = arg; } - } else { - out[out.length] = arg; } - } - return out; + return out; } diff --git a/src/lualib/ArrayEvery.ts b/src/lualib/ArrayEvery.ts index cc08c2fab..011dd9abe 100644 --- a/src/lualib/ArrayEvery.ts +++ b/src/lualib/ArrayEvery.ts @@ -1,6 +1,8 @@ -function __TS__ArrayEvery(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) - : boolean -{ +function __TS__ArrayEvery( + this: void, + arr: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean +): boolean { for (let i = 0; i < arr.length; i++) { if (!callbackfn(arr[i], i, arr)) { return false; diff --git a/src/lualib/ArrayFilter.ts b/src/lualib/ArrayFilter.ts index 2a64a7389..3d88ddffa 100644 --- a/src/lualib/ArrayFilter.ts +++ b/src/lualib/ArrayFilter.ts @@ -1,6 +1,8 @@ -function __TS__ArrayFilter(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) - : T[] -{ +function __TS__ArrayFilter( + this: void, + arr: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean +): T[] { const result: T[] = []; for (let i = 0; i < arr.length; i++) { if (callbackfn(arr[i], i, arr)) { diff --git a/src/lualib/ArrayForEach.ts b/src/lualib/ArrayForEach.ts index 6f6c931f7..96ac4a806 100644 --- a/src/lualib/ArrayForEach.ts +++ b/src/lualib/ArrayForEach.ts @@ -1,6 +1,8 @@ -function __TS__ArrayForEach(this: void, arr: T[], callbackFn: (value: T, index?: number, array?: any[]) => any) - : void -{ +function __TS__ArrayForEach( + this: void, + arr: T[], + callbackFn: (value: T, index?: number, array?: any[]) => any +): void { for (let i = 0; i < arr.length; i++) { callbackFn(arr[i], i, arr); } diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 2d6b0b87f..10132ff3e 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -1,9 +1,11 @@ function __TS__ArraySetLength(this: void, arr: T[], length: number): number { - if (length < 0 - || length !== length // NaN - || length === Infinity // Infinity - || Math.floor(length) !== length) // non-integer - { + if ( + length < 0 || + length !== length || // NaN + length === Infinity || // Infinity + Math.floor(length) !== length + ) { + // non-integer // tslint:disable-next-line:no-string-throw throw `invalid array length: ${length}`; } diff --git a/src/lualib/ArraySome.ts b/src/lualib/ArraySome.ts index 293e60c60..9122b1bbc 100644 --- a/src/lualib/ArraySome.ts +++ b/src/lualib/ArraySome.ts @@ -1,6 +1,8 @@ -function __TS__ArraySome(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean) - : boolean -{ +function __TS__ArraySome( + this: void, + arr: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean +): boolean { for (let i = 0; i < arr.length; i++) { if (callbackfn(arr[i], i, arr)) { return true; diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index a1e4e29c4..5e92837b1 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,10 +1,9 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: number, ...items: T[]): T[] { - const len = list.length; let actualStart; - if (start < 0) { + if (start < 0) { actualStart = Math.max(len + start, 0); } else { actualStart = Math.min(start, len); @@ -18,7 +17,7 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: actualDeleteCount = 0; } else if (!deleteCount) { actualDeleteCount = len - actualStart; - } else { + } else { actualDeleteCount = Math.min(Math.max(deleteCount, 0), len - actualStart); } @@ -47,7 +46,6 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: list[k - 1] = undefined; } } else if (itemCount > actualDeleteCount) { - for (let k = len - actualDeleteCount; k > actualStart; k--) { const from = k + actualDeleteCount - 1; const to = k + itemCount - 1; diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts index f12d6e913..95dc15b8f 100644 --- a/src/lualib/ArrayUnshift.ts +++ b/src/lualib/ArrayUnshift.ts @@ -1,4 +1,4 @@ -function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { +function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { for (let i = items.length - 1; i >= 0; --i) { table.insert(arr, 1, items[i]); } diff --git a/src/lualib/ClassNewIndex.ts b/src/lualib/ClassNewIndex.ts index 6447f9b8f..99205093c 100644 --- a/src/lualib/ClassNewIndex.ts +++ b/src/lualib/ClassNewIndex.ts @@ -11,8 +11,7 @@ function __TS__ClassNewIndex(this: void, classTable: LuaClass, key: any, val: an } tbl = rawget(tbl, "____super"); - } - while (tbl); + } while (tbl); rawset(classTable, key, val); } diff --git a/src/lualib/FunctionApply.ts b/src/lualib/FunctionApply.ts index 896e75978..294efdda9 100644 --- a/src/lualib/FunctionApply.ts +++ b/src/lualib/FunctionApply.ts @@ -1,9 +1,4 @@ -function __TS__FunctionApply( - this: void, - fn: (this: void, ...args: any[]) => any, - thisArg: any, - args?: any[] -): any { +function __TS__FunctionApply(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, args?: any[]): any { if (args) { return fn(thisArg, (unpack || table.unpack)(args)); } else { diff --git a/src/lualib/FunctionCall.ts b/src/lualib/FunctionCall.ts index 525086b58..e9b50fbbe 100644 --- a/src/lualib/FunctionCall.ts +++ b/src/lualib/FunctionCall.ts @@ -1,8 +1,3 @@ -function __TS__FunctionCall( - this: void, - fn: (this: void, ...args: any[]) => any, - thisArg: any, - ...args: any[] -): any { +function __TS__FunctionCall(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, ...args: any[]): any { return fn(thisArg, (unpack || table.unpack)(args)); } diff --git a/src/lualib/NewIndex.ts b/src/lualib/NewIndex.ts index 1c912fa6f..da0d4d12a 100644 --- a/src/lualib/NewIndex.ts +++ b/src/lualib/NewIndex.ts @@ -1,6 +1,4 @@ -function __TS__NewIndex(this: void, classProto: LuaObject) - : (this: void, tbl: LuaObject, key: any, val: any) => void -{ +function __TS__NewIndex(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: any, val: any) => void { return (tbl, key, val) => { let proto = classProto; while (true) { diff --git a/src/lualib/Number.ts b/src/lualib/Number.ts index c333c1ed1..0b19a1600 100644 --- a/src/lualib/Number.ts +++ b/src/lualib/Number.ts @@ -8,7 +8,7 @@ function __TS__Number(this: void, value: unknown): number { if (value === "Infinity") return Infinity; if (value === "-Infinity") return -Infinity; - const [stringWithoutSpaces] = string.gsub(value as string, '%s', ''); + const [stringWithoutSpaces] = string.gsub(value as string, "%s", ""); if (stringWithoutSpaces === "") return 0; return NaN; diff --git a/src/lualib/NumberIsFinite.ts b/src/lualib/NumberIsFinite.ts index 9338f2e34..98df30790 100644 --- a/src/lualib/NumberIsFinite.ts +++ b/src/lualib/NumberIsFinite.ts @@ -1,5 +1,3 @@ function __TS__NumberIsFinite(this: void, value: unknown): boolean { - return ( - typeof value === "number" && value === value && value !== Infinity && value !== -Infinity - ); + return typeof value === "number" && value === value && value !== Infinity && value !== -Infinity; } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 827ce7874..4aed661cc 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,6 +1,6 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. -function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: {[line: number]: number}): void { +function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [line: number]: number }): void { _G["__TS__sourcemap"] = _G["__TS__sourcemap"] || {}; _G["__TS__sourcemap"][fileName] = sourceMap; @@ -8,16 +8,12 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: {[lin _G.__TS__originalTraceback = debug.traceback; debug.traceback = (thread, message, level) => { const trace = _G["__TS__originalTraceback"](thread, message, level); - const [result] = string.gsub( - trace, - "(%S+).lua:(%d+)", - (file, line) => { - if (_G["__TS__sourcemap"][file + ".lua"] && _G["__TS__sourcemap"][file + ".lua"][line]) { - return `${file}.ts:${_G["__TS__sourcemap"][file + ".lua"][line]}`; - } - return `${file}.lua:${line}`; + const [result] = string.gsub(trace, "(%S+).lua:(%d+)", (file, line) => { + if (_G["__TS__sourcemap"][file + ".lua"] && _G["__TS__sourcemap"][file + ".lua"][line]) { + return `${file}.ts:${_G["__TS__sourcemap"][file + ".lua"][line]}`; } - ); + return `${file}.lua:${line}`; + }); return result; }; diff --git a/src/lualib/StringConcat.ts b/src/lualib/StringConcat.ts index ce3f6dd6e..e18a2e890 100644 --- a/src/lualib/StringConcat.ts +++ b/src/lualib/StringConcat.ts @@ -1,7 +1,7 @@ function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { - let out = str1; - for (const arg of args) { - out = out + arg; - } - return out; + let out = str1; + for (const arg of args) { + out = out + arg; + } + return out; } diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index c1fa21df5..93b19e9b7 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -2,7 +2,7 @@ const ____symbolRegistry: Record = {}; function __TS__SymbolRegistryFor(this: void, key: string): symbol { - if (!____symbolRegistry[key]) { + if (!____symbolRegistry[key]) { ____symbolRegistry[key] = __TS__Symbol(key); } diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index e3b08543d..cf93e3421 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -2,7 +2,7 @@ WeakMap = class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; - // Type of key is actually K + // Type of key is actually K private items: { [key: string]: V } = {}; constructor(entries?: Iterable | Array) { diff --git a/src/tstl.ts b/src/tstl.ts index 7a21449aa..4f3b974f5 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -46,9 +46,7 @@ function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefin if (ts.sys.fileExists(configFileName)) { return configFileName; } else { - reportDiagnostic( - cliDiagnostics.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project) - ); + reportDiagnostic(cliDiagnostics.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project)); ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } } else { @@ -97,10 +95,7 @@ function executeCommandLine(args: string[]): void { const configFileName = locateConfigFile(commandLine); const commandLineOptions = commandLine.options; if (configFileName) { - const configParseResult = CommandLineParser.parseConfigFileWithSystem( - configFileName, - commandLineOptions - ); + const configParseResult = CommandLineParser.parseConfigFileWithSystem(configFileName, commandLineOptions); updateReportDiagnostic(configParseResult.options); if (configParseResult.options.watch) { @@ -118,11 +113,7 @@ function executeCommandLine(args: string[]): void { if (commandLineOptions.watch) { createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions); } else { - performCompilation( - commandLine.fileNames, - commandLine.projectReferences, - commandLineOptions - ); + performCompilation(commandLine.fileNames, commandLine.projectReferences, commandLineOptions); } } } @@ -166,10 +157,7 @@ function performCompilation( return ts.sys.exit(exitCode); } -function createWatchOfConfigFile( - configFileName: string, - optionsToExtend: tstl.CompilerOptions -): void { +function createWatchOfConfigFile(configFileName: string, optionsToExtend: tstl.CompilerOptions): void { const watchCompilerHost = ts.createWatchCompilerHost( configFileName, optionsToExtend, @@ -183,10 +171,7 @@ function createWatchOfConfigFile( ts.createWatchProgram(watchCompilerHost); } -function createWatchOfFilesAndCompilerOptions( - rootFiles: string[], - options: tstl.CompilerOptions -): void { +function createWatchOfFilesAndCompilerOptions(rootFiles: string[], options: tstl.CompilerOptions): void { const watchCompilerHost = ts.createWatchCompilerHost( rootFiles, options, @@ -249,10 +234,7 @@ function updateWatchCompilationHost( } } - const { diagnostics: emitDiagnostics, transpiledFiles } = tstl.transpile({ - program, - sourceFiles, - }); + const { diagnostics: emitDiagnostics, transpiledFiles } = tstl.transpile({ program, sourceFiles }); const emitResult = tstl.emitTranspiledFiles(options, transpiledFiles); emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); @@ -272,11 +254,7 @@ function updateWatchCompilationHost( // do a full recompile after an error fullRecompile = errors.length > 0; - host.onWatchStatusChange!( - cliDiagnostics.watchErrorSummary(errors.length), - host.getNewLine(), - options - ); + host.onWatchStatusChange!(cliDiagnostics.watchErrorSummary(errors.length), host.getNewLine(), options); }; } diff --git a/test/setup.ts b/test/setup.ts index e1c041d8c..dff900cb9 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -47,9 +47,7 @@ expect.extend({ return ( matcherHint + "\n\n" + - (this.isNot - ? diagnosticMessages - : `Received: ${this.utils.printReceived(diagnostics)}\n`) + (this.isNot ? diagnosticMessages : `Received: ${this.utils.printReceived(diagnostics)}\n`) ); }, }; diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 877e58f50..458c14fec 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -24,7 +24,7 @@ test.each([ }; const { fileNames, options } = tstl.updateParsedConfigFile( - ts.parseJsonConfigFileContent(config, ts.sys, projectPath), + ts.parseJsonConfigFileContent(config, ts.sys, projectPath) ); const { diagnostics, emittedFiles } = buildVirtualProject(fileNames, options); diff --git a/test/transpile/run.ts b/test/transpile/run.ts index 57bbc8f6b..72afa7ca2 100644 --- a/test/transpile/run.ts +++ b/test/transpile/run.ts @@ -8,17 +8,12 @@ interface BuildVirtualProjectResult { emittedFiles: string[]; } -export function buildVirtualProject( - rootNames: string[], - options: tstl.CompilerOptions, -): BuildVirtualProjectResult { +export function buildVirtualProject(rootNames: string[], options: tstl.CompilerOptions): BuildVirtualProjectResult { options.skipLibCheck = true; options.types = []; const { diagnostics, emitResult } = tstl.transpileFiles(rootNames, options); - const emittedFiles = emitResult - .map(result => path.relative(__dirname, result.name).replace(/\\/g, "/")) - .sort(); + const emittedFiles = emitResult.map(result => path.relative(__dirname, result.name).replace(/\\/g, "/")).sort(); return { diagnostics, emitResult, emittedFiles }; } diff --git a/test/tsconfig.json b/test/tsconfig.json index 34b2ee7a4..b22f71bc9 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -12,11 +12,5 @@ "noEmit": true, "module": "commonjs" }, - "exclude": [ - "translation/transformation", - "cli/errors", - "cli/watch", - "transpile/directories", - "transpile/outFile" - ] + "exclude": ["translation/transformation", "cli/errors", "cli/watch", "transpile/directories", "transpile/outFile"] } diff --git a/test/tslint.json b/test/tslint.json deleted file mode 100644 index 2796d7894..000000000 --- a/test/tslint.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "rules": { - "array-type": [true, "array-simple"], - "arrow-return-shorthand": true, - "ban": [ - true, - { "name": "parseInt", "message": "tsstyle#type-coercion" }, - { "name": "parseFloat", "message": "tsstyle#type-coercion" }, - { "name": "Array", "message": "tsstyle#array-constructor" } - ], - "ban-types": [ - true, - ["Object", "Use {} instead."], - ["String", "Use 'string' instead."], - ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] - ], - "class-name": true, - "curly": [true, "ignore-same-line"], - "deprecation": true, - "forin": false, - "interface-name": [true, "never-prefix"], - "jsdoc-format": true, - "label-position": true, - "max-classes-per-file": [true, 1], - "member-access": true, - "no-angle-bracket-type-assertion": true, - "no-any": false, - "no-arg": true, - "no-conditional-assignment": true, - "no-construct": true, - "no-debugger": true, - "no-default-export": true, - "no-duplicate-switch-case": true, - "no-duplicate-variable": true, - "no-inferrable-types": true, - "no-namespace": [true, "allow-declarations"], - "no-null-keyword": true, - "no-reference": true, - "no-string-throw": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-shorthand": true, - "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], - "prefer-const": [true, { "destructuring": "all" }], - "radix": true, - "switch-default": false, - "triple-equals": [true, "allow-null-check"], - "typedef": [true, "call-signature", "property-declaration"], - "use-isnan": true, - "variable-name": [ - true, - "check-format", - "ban-keywords", - "allow-leading-underscore", - "allow-pascal-case" - ] - } -} diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index 85dde6455..44d3cb3d6 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -3,7 +3,7 @@ import * as util from "../util"; test("Array access", () => { const result = util.transpileAndExecute( `const arr: Array = [3,5,1]; - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -11,7 +11,7 @@ test("Array access", () => { test("ReadonlyArray access", () => { const result = util.transpileAndExecute( `const arr: ReadonlyArray = [3,5,1]; - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -19,7 +19,7 @@ test("ReadonlyArray access", () => { test("Array literal access", () => { const result = util.transpileAndExecute( `const arr: number[] = [3,5,1]; - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -27,7 +27,7 @@ test("Array literal access", () => { test("Readonly array literal access", () => { const result = util.transpileAndExecute( `const arr: readonly number[] = [3,5,1]; - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -36,7 +36,7 @@ test("Array union access", () => { const result = util.transpileAndExecute( `function makeArray(): number[] | string[] { return [3,5,1]; } const arr = makeArray(); - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -45,7 +45,7 @@ test("Array union access with empty tuple", () => { const result = util.transpileAndExecute( `function makeArray(): number[] | [] { return [3,5,1]; } const arr = makeArray(); - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -54,7 +54,7 @@ test("Array union length", () => { const result = util.transpileAndExecute( `function makeArray(): number[] | string[] { return [3,5,1]; } const arr = makeArray(); - return arr.length;`, + return arr.length;` ); expect(result).toBe(3); }); @@ -68,7 +68,7 @@ test("Array intersection access", () => { return (t as I); } const arr = makeArray(); - return arr[1];`, + return arr[1];` ); expect(result).toBe(5); }); @@ -82,7 +82,7 @@ test("Array intersection length", () => { return (t as I); } const arr = makeArray(); - return arr.length;`, + return arr.length;` ); expect(result).toBe(3); }); @@ -107,7 +107,7 @@ test.each([ return arr.${member};`, undefined, luaHeader, - typeScriptHeader, + typeScriptHeader ); expect(result).toBe(expected); @@ -117,7 +117,7 @@ test("Array delete", () => { const result = util.transpileAndExecute( `const myarray = [1,2,3,4]; delete myarray[2]; - return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` ); expect(result).toBe("1,2,nil,4"); @@ -127,7 +127,7 @@ test("Array delete return true", () => { const result = util.transpileAndExecute( `const myarray = [1,2,3,4]; const exists = delete myarray[2]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` ); expect(result).toBe("true:1,2,nil,4"); @@ -137,7 +137,7 @@ test("Array delete return false", () => { const result = util.transpileAndExecute( `const myarray = [1,2,3,4]; const exists = delete myarray[4]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;`, + return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` ); expect(result).toBe("true:1,2,3,4"); @@ -162,21 +162,20 @@ test.each([{ length: 0, result: 0 }, { length: 1, result: 1 }, { length: 7, resu return arr.length; `; expect(util.transpileAndExecute(code)).toBe(result); - }, + } ); -test.each([ - { length: 0, result: "0/0" }, - { length: 1, result: "1/1" }, - { length: 7, result: "7/3" }, -])("Array length set as expression", ({ length, result }) => { - const code = ` +test.each([{ length: 0, result: "0/0" }, { length: 1, result: "1/1" }, { length: 7, result: "7/3" }])( + "Array length set as expression", + ({ length, result }) => { + const code = ` const arr = [1, 2, 3]; const l = arr.length = ${length}; return \`\${l}/\${arr.length}\`; `; - expect(util.transpileAndExecute(code)).toBe(result); -}); + expect(util.transpileAndExecute(code)).toBe(result); + } +); test.each([ { length: -1, result: -1 }, diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index b6fd9350d..7eb8e5ecd 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -42,7 +42,7 @@ test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = und declaration => { const result = util.transpileAndExecute(declaration + " return myvar;"); expect(result).toBe(undefined); - }, + } ); test.each([ @@ -61,7 +61,7 @@ test.each([ test("Ellipsis binding pattern", () => { expect(() => util.transpileString("let [a,b,...c] = [1,2,3];")).toThrowExactError( - TSTLErrors.ForbiddenEllipsisDestruction(util.nodeStub), + TSTLErrors.ForbiddenEllipsisDestruction(util.nodeStub) ); }); diff --git a/test/unit/assignments/functionExpressionTypeInference.spec.ts b/test/unit/assignments/functionExpressionTypeInference.spec.ts index aa47a8c18..aefc24427 100644 --- a/test/unit/assignments/functionExpressionTypeInference.spec.ts +++ b/test/unit/assignments/functionExpressionTypeInference.spec.ts @@ -16,19 +16,18 @@ test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", no expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); }); -test.each([ - "(this: void, s: string) => string", - "(this: any, s: string) => string", - "(s: string) => string", -])("Function expression type inference in binary operator (%p)", funcType => { - const header = `declare const undefinedFunc: ${funcType};`; - const code = ` +test.each(["(this: void, s: string) => string", "(this: any, s: string) => string", "(s: string) => string"])( + "Function expression type inference in binary operator (%p)", + funcType => { + const header = `declare const undefinedFunc: ${funcType};`; + const code = ` let func: ${funcType} = s => s; func = undefinedFunc || (s => s); return func("foo"); `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); -}); + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + } +); test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { return s; })"])( "Function expression type inference in class (%p)", @@ -44,7 +43,7 @@ test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { re return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d"); `; expect(util.transpileAndExecute(code)).toBe("abcd"); - }, + } ); test.each([ @@ -85,19 +84,16 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "(s => s)" }, { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, -])( - "Function expression type inference in object literal (generic key) (%p)", - ({ assignTo, funcExp }) => { - const code = ` +])("Function expression type inference in object literal (generic key) (%p)", ({ assignTo, funcExp }) => { + const code = ` interface Foo { [f: string]: (this: void, s: string) => string; } ${assignTo} = {func: ${funcExp}}; return foo.func("foo"); `; - expect(util.transpileAndExecute(code)).toBe("foo"); - }, -); + expect(util.transpileAndExecute(code)).toBe("foo"); +}); test.each([ { @@ -218,23 +214,11 @@ test.each([ { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "s => s" }, { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "(s => s)" }, { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "function(s) { return s; }" }, - { - assignTo: "const meths: Method[]", - method: "meths[0]", - funcExp: "(function(s) { return s; })", - }, + { assignTo: "const meths: Method[]", method: "meths[0]", funcExp: "(function(s) { return s; })" }, { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "s => s" }, { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "(s => s)" }, - { - assignTo: "let meths: Method[]; meths", - method: "meths[0]", - funcExp: "function(s) { return s; }", - }, - { - assignTo: "let meths: Method[]; meths", - method: "meths[0]", - funcExp: "(function(s) { return s; })", - }, + { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "function(s) { return s; }" }, + { assignTo: "let meths: Method[]; meths", method: "meths[0]", funcExp: "(function(s) { return s; })" }, { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "s => s" }, { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "(s => s)" }, { assignTo: "const [meth]: Method[]", method: "meth", funcExp: "function(s) { return s; }" }, @@ -242,11 +226,7 @@ test.each([ { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "s => s" }, { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(s => s)" }, { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "function(s) { return s; }" }, - { - assignTo: "let meth: Method; [meth]", - method: "meth", - funcExp: "(function(s) { return s; })", - }, + { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in array (%p)", ({ assignTo, method, funcExp }) => { const code = ` interface Foo { diff --git a/test/unit/assignments/functionPermutations.ts b/test/unit/assignments/functionPermutations.ts index 45fbd52f1..cbbef188e 100644 --- a/test/unit/assignments/functionPermutations.ts +++ b/test/unit/assignments/functionPermutations.ts @@ -328,46 +328,18 @@ export const validTestFunctionCasts: TestFunctionCast[] = [ [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${selfTestFunctionType})`], [noSelfTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfTestFunctions[0].value})`], [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${noSelfTestFunctionType})`], - [ - noSelfInFileTestFunctions[0], - `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, - ], - [ - noSelfInFileTestFunctions[0], - `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`, - ], - [ - noSelfInFileTestFunctions[0], - `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, - ], - [ - noSelfInFileTestFunctions[0], - `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`, - ], + [noSelfInFileTestFunctions[0], `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`], + [noSelfInFileTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`], ]; export const invalidTestFunctionCasts: TestFunctionCast[] = [ [noSelfTestFunctions[0], `<${anonTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], - [ - noSelfTestFunctions[0], - `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, - false, - ], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, false], [noSelfTestFunctions[0], `<${selfTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], - [ - noSelfTestFunctions[0], - `(${noSelfTestFunctions[0].value}) as (${selfTestFunctionType})`, - false, - ], - [ - noSelfInFileTestFunctions[0], - `<${selfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, - false, - ], - [ - noSelfInFileTestFunctions[0], - `(${noSelfInFileTestFunctions[0].value}) as (${selfTestFunctionType})`, - false, - ], + [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${selfTestFunctionType})`, false], + [noSelfInFileTestFunctions[0], `<${selfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`, false], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${selfTestFunctionType})`, false], [selfTestFunctions[0], `<${noSelfTestFunctionType}>(${selfTestFunctions[0].value})`, true], [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${noSelfTestFunctionType})`, true], ]; @@ -388,24 +360,14 @@ export const validTestFunctionAssignments: TestFunctionAssignment[] = [ ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), - ...noSelfTestFunctionExpressions.map( - (f): TestFunctionAssignment => [f, noSelfTestFunctionType], - ), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ]; export const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ ...selfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), - ...noSelfInFileTestFunctions.map( - (f): TestFunctionAssignment => [f, selfTestFunctionType, true], - ), - ...selfTestFunctionExpressions.map( - (f): TestFunctionAssignment => [f, noSelfTestFunctionType, false], - ), - ...noSelfTestFunctionExpressions.map( - (f): TestFunctionAssignment => [f, anonTestFunctionType, true], - ), - ...noSelfTestFunctionExpressions.map( - (f): TestFunctionAssignment => [f, selfTestFunctionType, true], - ), + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), + ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), ]; diff --git a/test/unit/assignments/invalidFunctionAssignments.spec.ts b/test/unit/assignments/invalidFunctionAssignments.spec.ts index 3c8108c18..ea3de0d88 100644 --- a/test/unit/assignments/invalidFunctionAssignments.spec.ts +++ b/test/unit/assignments/invalidFunctionAssignments.spec.ts @@ -13,7 +13,7 @@ test.each(invalidTestFunctionAssignments)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionAssignments)( @@ -28,7 +28,7 @@ test.each(invalidTestFunctionAssignments)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionCasts)( @@ -43,7 +43,7 @@ test.each(invalidTestFunctionCasts)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionAssignments)( @@ -58,7 +58,7 @@ test.each(invalidTestFunctionAssignments)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test("Invalid lua lib function argument", () => { @@ -83,7 +83,7 @@ test.each(invalidTestFunctionCasts)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionAssignments)( @@ -98,7 +98,7 @@ test.each(invalidTestFunctionAssignments)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionAssignments)( @@ -114,7 +114,7 @@ test.each(invalidTestFunctionAssignments)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test.each(invalidTestFunctionCasts)( @@ -130,7 +130,7 @@ test.each(invalidTestFunctionCasts)( ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - }, + } ); test("Interface method assignment", () => { @@ -158,7 +158,7 @@ test("Invalid function tuple assignment", () => { let [i, f]: [number, Func] = getTuple(); `; expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub), + TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub) ); }); @@ -170,7 +170,7 @@ test("Invalid method tuple assignment", () => { let [i, f]: [number, Meth] = getTuple(); `; expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub), + TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) ); }); @@ -182,7 +182,7 @@ test("Invalid interface method assignment", () => { const b: B = a; `; expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"), + TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn") ); }); @@ -200,7 +200,5 @@ test.each([ declare const o: O; let f: ${assignType} = o; `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedOverloadAssignment(util.nodeStub), - ); + expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.UnsupportedOverloadAssignment(util.nodeStub)); }); diff --git a/test/unit/assignments/validFunctionAssignments.spec.ts b/test/unit/assignments/validFunctionAssignments.spec.ts index 86b4ce230..be553b956 100644 --- a/test/unit/assignments/validFunctionAssignments.spec.ts +++ b/test/unit/assignments/validFunctionAssignments.spec.ts @@ -14,57 +14,37 @@ import { TestFunction, } from "./functionPermutations"; -test.each(validTestFunctionAssignments)( - "Valid function variable declaration (%p)", - (testFunction, functionType) => { - const code = `const fn: ${functionType} = ${testFunction.value}; +test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { + const code = `const fn: ${functionType} = ${testFunction.value}; return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); -test.each(validTestFunctionAssignments)( - "Valid function assignment (%p)", - (testFunction, functionType) => { - const code = `let fn: ${functionType}; +test.each(validTestFunctionAssignments)("Valid function assignment (%p)", (testFunction, functionType) => { + const code = `let fn: ${functionType}; fn = ${testFunction.value}; return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); -test.each(validTestFunctionCasts)( - "Valid function assignment with cast (%p)", - (testFunction, castedFunction) => { - const code = ` +test.each(validTestFunctionCasts)("Valid function assignment with cast (%p)", (testFunction, castedFunction) => { + const code = ` let fn: typeof ${testFunction.value}; fn = ${castedFunction}; return fn("foobar"); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); -test.each(validTestFunctionAssignments)( - "Valid function argument (%p)", - (testFunction, functionType) => { - const code = ` +test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFunction, functionType) => { + const code = ` function takesFunction(fn: ${functionType}) { return fn("foobar"); } return takesFunction(${testFunction.value}); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); test("Valid lua lib function argument", () => { const code = `let result = ""; @@ -75,20 +55,15 @@ test("Valid lua lib function argument", () => { expect(util.transpileAndExecute(code)).toBe("foobar"); }); -test.each(validTestFunctionCasts)( - "Valid function argument with cast (%p)", - (testFunction, castedFunction) => { - const code = ` +test.each(validTestFunctionCasts)("Valid function argument with cast (%p)", (testFunction, castedFunction) => { + const code = ` function takesFunction(fn: typeof ${testFunction.value}) { return fn("foobar"); } return takesFunction(${castedFunction}); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); test.each([ // TODO: Fix function expression inference with generic types. The following should work, but doesn't: @@ -100,9 +75,7 @@ test.each([ ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), - ...noSelfTestFunctionExpressions.map( - (f): TestFunctionAssignment => [f, noSelfTestFunctionType], - ), + ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ])("Valid function generic argument (%p)", (testFunction, functionType) => { const code = ` function takesFunction(fn: T) { @@ -110,9 +83,7 @@ test.each([ } return takesFunction(${testFunction.value}); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); }); test.each([ @@ -126,40 +97,28 @@ test.each([ } return takesFunction(${testFunction.value}, ${args.join(", ")}); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); }); -test.each(validTestFunctionAssignments)( - "Valid function return (%p)", - (testFunction, functionType) => { - const code = ` +test.each(validTestFunctionAssignments)("Valid function return (%p)", (testFunction, functionType) => { + const code = ` function returnsFunction(): ${functionType} { return ${testFunction.value}; } const fn = returnsFunction(); return fn("foobar"); `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); -test.each(validTestFunctionCasts)( - "Valid function return with cast (%p)", - (testFunction, castedFunction) => { - const code = `function returnsFunction(): typeof ${testFunction.value} { +test.each(validTestFunctionCasts)("Valid function return with cast (%p)", (testFunction, castedFunction) => { + const code = `function returnsFunction(): typeof ${testFunction.value} { return ${castedFunction}; } const fn = returnsFunction(); return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe( - "foobar", - ); - }, -); + expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); +}); test("Interface method assignment", () => { const code = `class Foo { @@ -210,16 +169,8 @@ test("Valid interface method assignment", () => { test.each([ { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, - { - assignType: "(this: any, s1: string, s2: string) => string", - args: ["foo", "baz"], - expectResult: "foobaz", - }, - { - assignType: "{(this: any, s1: string, s2: string): string}", - args: ["foo", "baz"], - expectResult: "foobaz", - }, + { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"], expectResult: "foobaz" }, + { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"], expectResult: "foobaz" }, ])("Valid function overload assignment (%p)", ({ assignType, args, expectResult }) => { const code = `interface O { (s1: string, s2: string): string; diff --git a/test/unit/bindingpatterns.spec.ts b/test/unit/bindingpatterns.spec.ts index b7ed32de5..aad38661b 100644 --- a/test/unit/bindingpatterns.spec.ts +++ b/test/unit/bindingpatterns.spec.ts @@ -9,26 +9,10 @@ const testCases = [ { bindingString: "[[y, z]]", objectString: "[[false, true]]", returnVariable: "z" }, { bindingString: "{x, y}", objectString: "{x: false, y: true}", returnVariable: "y" }, { bindingString: "{x: foo, y}", objectString: "{x: true, y: false}", returnVariable: "foo" }, - { - bindingString: "{x: foo, y: bar}", - objectString: "{x: false, y: true}", - returnVariable: "bar", - }, - { - bindingString: "{x: {x, y}, z}", - objectString: "{x: {x: true, y: false}, z: false}", - returnVariable: "x", - }, - { - bindingString: "{x: {x, y}, z}", - objectString: "{x: {x: false, y: true}, z: false}", - returnVariable: "y", - }, - { - bindingString: "{x: {x, y}, z}", - objectString: "{x: {x: false, y: false}, z: true}", - returnVariable: "z", - }, + { bindingString: "{x: foo, y: bar}", objectString: "{x: false, y: true}", returnVariable: "bar" }, + { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: true, y: false}, z: false}", returnVariable: "x" }, + { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: false, y: true}, z: false}", returnVariable: "y" }, + { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: false, y: false}, z: true}", returnVariable: "z" }, ]; const testCasesDefault = [ @@ -38,11 +22,7 @@ const testCasesDefault = [ test.each([ { bindingString: "{x, y}, z", objectString: "{x: false, y: false}, true", returnVariable: "z" }, - { - bindingString: "{x, y}, {z}", - objectString: "{x: false, y: false}, {z: true}", - returnVariable: "z", - }, + { bindingString: "{x, y}, {z}", objectString: "{x: false, y: false}, {z: true}", returnVariable: "z" }, ...testCases, ...testCasesDefault, ])("Object bindings in functions (%p)", ({ bindingString, objectString, returnVariable }) => { @@ -63,7 +43,7 @@ test.each([...testCases, ...testCasesDefault])( return ${returnVariable}; `); expect(result).toBe(true); - }, + } ); test.each([...testCases, ...testCasesDefault])( @@ -71,10 +51,10 @@ test.each([...testCases, ...testCasesDefault])( ({ bindingString, objectString, returnVariable }) => { const result = util.transpileExecuteAndReturnExport( `export const ${bindingString} = ${objectString};`, - returnVariable, + returnVariable ); expect(result).toBe(true); - }, + } ); test.each(testCases)( @@ -88,24 +68,17 @@ test.each(testCases)( return ${returnVariable}; `); expect(result).toBe(true); - }, + } ); test.each([ { bindingString: "{x, y = true}", objectString: "{x: false, y: false}", returnVariable: "y" }, - { - bindingString: "{x, y: [z = true]}", - objectString: "{x: false, y: [false]}", - returnVariable: "z", - }, + { bindingString: "{x, y: [z = true]}", objectString: "{x: false, y: [false]}", returnVariable: "z" }, { bindingString: "[x = true]", objectString: "[false]", returnVariable: "x" }, -])( - "Binding patterns handle false correctly (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileExecuteAndReturnExport( - `export const ${bindingString} = ${objectString};`, - returnVariable, - ); - expect(result).toBe(false); - }, -); +])("Binding patterns handle false correctly (%p)", ({ bindingString, objectString, returnVariable }) => { + const result = util.transpileExecuteAndReturnExport( + `export const ${bindingString} = ${objectString};`, + returnVariable + ); + expect(result).toBe(false); +}); diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 42b575064..c4d2943bb 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -7,7 +7,7 @@ test("ClassFieldInitializer", () => { `class a { field: number = 4; } - return new a().field;`, + return new a().field;` ); expect(result).toBe(4); @@ -18,7 +18,7 @@ test("ClassNumericLiteralFieldInitializer", () => { `class a { 1: number = 4; } - return new a()[1];`, + return new a()[1];` ); expect(result).toBe(4); @@ -29,7 +29,7 @@ test("ClassStringLiteralFieldInitializer", () => { `class a { "field": number = 4; } - return new a()["field"];`, + return new a()["field"];` ); expect(result).toBe(4); @@ -41,7 +41,7 @@ test("ClassComputedFieldInitializer", () => { class a { [field]: number = 4; } - return new a()[field];`, + return new a()[field];` ); expect(result).toBe(4); @@ -55,7 +55,7 @@ test("ClassConstructor", () => { this.field = n * 2; } } - return new a(4).field;`, + return new a(4).field;` ); expect(result).toBe(8); @@ -64,7 +64,7 @@ test("ClassConstructor", () => { test("ClassConstructorAssignment", () => { const result = util.transpileAndExecute( `class a { constructor(public field: number) {} } - return new a(4).field;`, + return new a(4).field;` ); expect(result).toBe(4); @@ -73,7 +73,7 @@ test("ClassConstructorAssignment", () => { test("ClassConstructorDefaultParameter", () => { const result = util.transpileAndExecute( `class a { public field: number; constructor(f: number = 3) { this.field = f; } } - return new a().field;`, + return new a().field;` ); expect(result).toBe(3); @@ -82,7 +82,7 @@ test("ClassConstructorDefaultParameter", () => { test("ClassConstructorAssignmentDefault", () => { const result = util.transpileAndExecute( `class a { constructor(public field: number = 3) { } } - return new a().field;`, + return new a().field;` ); expect(result).toBe(3); @@ -95,7 +95,7 @@ test("ClassNewNoBrackets", () => { constructor() {} } let inst = new a; - return inst.field;`, + return inst.field;` ); expect(result).toBe(4); @@ -104,7 +104,7 @@ test("ClassNewNoBrackets", () => { test("ClassStaticFields", () => { const result = util.transpileAndExecute( `class a { static field: number = 4; } - return a.field;`, + return a.field;` ); expect(result).toBe(4); @@ -113,7 +113,7 @@ test("ClassStaticFields", () => { test("ClassStaticNumericLiteralFields", () => { const result = util.transpileAndExecute( `class a { static 1: number = 4; } - return a[1];`, + return a[1];` ); expect(result).toBe(4); @@ -122,7 +122,7 @@ test("ClassStaticNumericLiteralFields", () => { test("ClassStaticStringLiteralFields", () => { const result = util.transpileAndExecute( `class a { static "field": number = 4; } - return a["field"];`, + return a["field"];` ); expect(result).toBe(4); @@ -132,7 +132,7 @@ test("ClassStaticComputedFields", () => { const result = util.transpileAndExecute( `const field: "field" = "field"; class a { static [field]: number = 4; } - return a[field];`, + return a[field];` ); expect(result).toBe(4); @@ -142,7 +142,7 @@ test("classExtends", () => { const result = util.transpileAndExecute( `class a { field: number = 4; } class b extends a {} - return new b().field;`, + return new b().field;` ); expect(result).toBe(4); @@ -157,7 +157,7 @@ test("SubclassDefaultConstructor", () => { } } class b extends a {} - return new b(10).field;`, + return new b(10).field;` ); expect(result).toBe(10); @@ -173,7 +173,7 @@ test("SubsubclassDefaultConstructor", () => { } class b extends a {} class c extends b {} - return new c(10).field;`, + return new c(10).field;` ); expect(result).toBe(10); @@ -192,7 +192,7 @@ test("SubclassConstructor", () => { super(field + 1); } } - return new b(10).field;`, + return new b(10).field;` ); expect(result).toBe(11); @@ -211,7 +211,7 @@ test("classSuper", () => { super(5); } } - return new b().field;`, + return new b().field;` ); expect(result).toBe(5); @@ -235,7 +235,7 @@ test("classSuperSuper", () => { super(5); } } - return new c().field;`, + return new c().field;` ); expect(result).toBe(10); @@ -256,7 +256,7 @@ test("classSuperSkip", () => { super(5); } } - return new c().field;`, + return new c().field;` ); expect(result).toBe(5); @@ -278,7 +278,7 @@ test("renamedClassExtends", () => { const A = Classes.Base; class B extends A { constructor(){ super(); } - };`, + };` ); expect(result).toBe(3); @@ -292,7 +292,7 @@ test("ClassMethodCall", () => { } } let inst = new a(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -306,7 +306,7 @@ test("ClassNumericLiteralMethodCall", () => { } } let inst = new a(); - return inst[1]();`, + return inst[1]();` ); expect(result).toBe(4); @@ -320,7 +320,7 @@ test("ClassStringLiteralMethodCall", () => { } } let inst = new a(); - return inst["method"]();`, + return inst["method"]();` ); expect(result).toBe(4); @@ -335,7 +335,7 @@ test("ClassComputedMethodCall", () => { } } let inst = new a(); - return inst[method]();`, + return inst[method]();` ); expect(result).toBe(4); @@ -349,7 +349,7 @@ test("ClassToString", () => { } } let inst = new a(); - return inst.toString();`, + return inst.toString();` ); expect(result).toBe("instance of a"); @@ -363,7 +363,7 @@ test("HasOwnProperty true", () => { } let inst = new a(); inst["prop"] = 17; - return inst.hasOwnProperty("prop");`, + return inst.hasOwnProperty("prop");` ); expect(result).toBe(true); @@ -377,7 +377,7 @@ test("HasOwnProperty false", () => { } let inst = new a(); inst["prop"] = 17; - return inst.hasOwnProperty("test");`, + return inst.hasOwnProperty("test");` ); expect(result).toBe(false); @@ -398,7 +398,7 @@ test("CastClassMethodCall", () => { let result = {val : 0}; (inst as a).method(result); (inst as a).method(result); - return result.val;`, + return result.val;` ); expect(result).toBe(4); @@ -411,7 +411,7 @@ test("ClassPropertyFunctionThis", () => { public method: () => number = () => this.n; } let inst = new a(4); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -426,7 +426,7 @@ test("ClassInheritedMethodCall", () => { } class b extends a {} let inst = new b(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -442,7 +442,7 @@ test("ClassDoubleInheritedMethodCall", () => { class b extends a {} class c extends b {} let inst = new c(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -458,7 +458,7 @@ test("ClassInheritedMethodCall2", () => { } class c extends b {} let inst = new c(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -477,7 +477,7 @@ test("ClassMethodOverride", () => { } } let inst = new b(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(4); @@ -491,7 +491,7 @@ test("methodDefaultParameters", () => { } } let inst = new a(); - return inst.method(4);`, + return inst.method(4);` ); expect(result).toBe(9); @@ -500,9 +500,9 @@ test("methodDefaultParameters", () => { test("Class without name error", () => { const transformer = util.makeTestTransformer(); - expect(() => - transformer.transformClassDeclaration({} as ts.ClassDeclaration), - ).toThrowExactError(TSTLErrors.MissingClassName(util.nodeStub)); + expect(() => transformer.transformClassDeclaration({} as ts.ClassDeclaration)).toThrowExactError( + TSTLErrors.MissingClassName(util.nodeStub) + ); }); test("CallSuperMethodNoArgs", () => { @@ -525,7 +525,7 @@ test("CallSuperMethodNoArgs", () => { } } let inst = new b(6); - return inst.method();`, + return inst.method();` ); expect(result).toBe(6); @@ -551,7 +551,7 @@ test("CallSuperMethodArgs", () => { } } let inst = new b(6); - return inst.method(4);`, + return inst.method(4);` ); expect(result).toBe(10); @@ -575,7 +575,7 @@ test("CallSuperExpressionMethod", () => { inst.method(); inst.method(); inst.method(); - return i;`, + return i;` ); expect(result).toBe(1); @@ -609,7 +609,7 @@ test("CallSuperSuperMethod", () => { } } let inst = new c(6); - return inst.method();`, + return inst.method();` ); expect(result).toBe(6); @@ -628,7 +628,7 @@ test("classExpression", () => { } } let inst = new b(); - return inst.method();`, + return inst.method();` ); expect(result).toBe("instance of b"); @@ -642,7 +642,7 @@ test("Named Class Expression", () => { } } let inst = new a(); - return inst.method();`, + return inst.method();` ); expect(result).toBe("foo"); @@ -658,7 +658,7 @@ test("classExpressionBaseClassMethod", () => { const b = class extends a { } let inst = new b(); - return inst.method();`, + return inst.method();` ); expect(result).toBe(42); @@ -676,7 +676,7 @@ test("Class Method Runtime Override", () => { inst.method = () => { return 8; } - return inst.method();`, + return inst.method();` ); expect(result).toBe(8); @@ -709,7 +709,7 @@ test.each([{ input: "(new Foo())", expectResult: "foo" }, { input: "Foo", expect return ${input}.method(); `; expect(util.transpileAndExecute(code)).toBe(expectResult); - }, + } ); test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { @@ -719,9 +719,7 @@ test.each(["extension", "metaExtension"])("Class extends extension (%p)", extens class B extends A {} class C extends B {} `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.InvalidExtendsExtension(util.nodeStub), - ); + expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidExtendsExtension(util.nodeStub)); }); test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { @@ -732,7 +730,7 @@ test.each(["extension", "metaExtension"])("Class construct extension (%p)", exte const b = new B(); `; expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub), + TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub) ); }); @@ -830,7 +828,7 @@ test("Class cannot have static new method", () => { static new() {} }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -840,7 +838,7 @@ test("Class cannot have static new property", () => { static new = "foobar"; }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -850,7 +848,7 @@ test("Class cannot have static new get accessor", () => { static get new() { return "foobar" } }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -860,6 +858,6 @@ test("Class cannot have static new set accessor", () => { static set new(value: string) {} }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message, + TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); diff --git a/test/unit/classDecorator.spec.ts b/test/unit/classDecorator.spec.ts index 3575284df..8e9eff3d7 100644 --- a/test/unit/classDecorator.spec.ts +++ b/test/unit/classDecorator.spec.ts @@ -162,9 +162,7 @@ test("Class decorators are applied in order and executed in reverse order", () = `; const result = util.transpileAndExecute(source); - expect(result).toBe( - "eval fox eval jumped eval over dog execute over dog execute jumped execute fox", - ); + expect(result).toBe("eval fox eval jumped eval over dog execute over dog execute jumped execute fox"); }); test("Throws error if decorator function has void context", () => { @@ -184,9 +182,7 @@ test("Throws error if decorator function has void context", () => { return classInstance.decoratorBool; `; - expect(() => util.transpileAndExecute(source)).toThrowExactError( - TSTLErrors.InvalidDecoratorContext(util.nodeStub), - ); + expect(() => util.transpileAndExecute(source)).toThrowExactError(TSTLErrors.InvalidDecoratorContext(util.nodeStub)); }); test("Exported class decorator", () => { diff --git a/test/unit/commandLineParser.spec.ts b/test/unit/commandLineParser.spec.ts index 8572f7c58..0f4942d9c 100644 --- a/test/unit/commandLineParser.spec.ts +++ b/test/unit/commandLineParser.spec.ts @@ -136,9 +136,7 @@ describe("tsconfig", () => { const rootLevel = parseConfigFileContent({ noHeader: true }); const namespaced = parseConfigFileContent({ tstl: { noHeader: true } }); - expect(rootLevel.errors).toEqual([ - expect.objectContaining({ category: ts.DiagnosticCategory.Warning }), - ]); + expect(rootLevel.errors).toEqual([expect.objectContaining({ category: ts.DiagnosticCategory.Warning })]); expect(rootLevel.options).toEqual(namespaced.options); }); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index d09d54a7f..428066db6 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -8,36 +8,30 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("if (%p)", ({ inp, if (input === 0) { return 0; } - return 1;`, + return 1;` ); expect(result).toBe(expected); }); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])( - "ifelse (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("ifelse (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; if (input === 0) { return 0; } else { return 1; - }`, - ); + }` + ); - expect(result).toBe(expected); - }, -); + expect(result).toBe(expected); +}); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: 3 }, -])("ifelseif (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: 3 }])( + "ifelseif (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; if (input === 0) { return 0; } else if (input === 1){ @@ -45,20 +39,18 @@ test.each([ } else if (input === 2){ return 2; } - return 3;`, - ); + return 3;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: 3 }, -])("ifelseifelse (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: 3 }])( + "ifelseifelse (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let input: number = ${inp}; if (input === 0) { return 0; } else if (input === 1){ @@ -67,20 +59,18 @@ test.each([ return 2; } else { return 3; - }`, - ); + }` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -1 }, -])("switch (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( + "switch (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: @@ -93,20 +83,18 @@ test.each([ result = 2; break; } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -2 }, -])("switchdefault (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -2 }])( + "switchdefault (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: @@ -122,11 +110,12 @@ test.each([ result = -2; break; } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); test.each([ { inp: 0, expected: 1 }, @@ -163,20 +152,17 @@ test.each([ result = -2; break; } - return result;`, + return result;` ); expect(result).toBe(expected); }); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -2 }, -])("nestedSwitch (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -2 }])( + "nestedSwitch (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: @@ -202,11 +188,12 @@ test.each([ result = -2; break; } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 2 }, { inp: 2, expected: 2 }])( "switchLocalScope (%p)", @@ -230,21 +217,18 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 2 }, { inp: 2, expected: break; } } - return result;`, + return result;` ); expect(result).toBe(expected); - }, + } ); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -1 }, -])("switchReturn (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `const result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( + "switchReturn (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `const result: number = -1; switch (${inp}) { case 0: @@ -256,20 +240,18 @@ test.each([ return 2; break; } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -1 }, -])("switchWithBrackets (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( + "switchWithBrackets (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: { @@ -285,20 +267,18 @@ test.each([ break; } } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 0 }, - { inp: 1, expected: 1 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -1 }, -])("switchWithBracketsBreakInConditional (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( + "switchWithBracketsBreakInConditional (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: { @@ -315,20 +295,18 @@ test.each([ break; } } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); -test.each([ - { inp: 0, expected: 4 }, - { inp: 1, expected: 0 }, - { inp: 2, expected: 2 }, - { inp: 3, expected: -1 }, -])("switchWithBracketsBreakInInternalLoop (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([{ inp: 0, expected: 4 }, { inp: 1, expected: 0 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( + "switchWithBracketsBreakInInternalLoop (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let result: number = -1; switch (${inp}) { case 0: { @@ -351,11 +329,12 @@ test.each([ break; } } - return result;`, - ); + return result;` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); test("If dead code after return", () => { const result = util.transpileAndExecute(`if (true) { return 3; const b = 8; }`); @@ -365,16 +344,14 @@ test("If dead code after return", () => { test("switch dead code after return", () => { const result = util.transpileAndExecute( - `switch ("abc") { case "def": return 4; let abc = 4; case "abc": return 5; let def = 6; }`, + `switch ("abc") { case "def": return 4; let abc = 4; case "abc": return 5; let def = 6; }` ); expect(result).toBe(5); }); test("switch not allowed in 5.1", () => { - expect(() => - util.transpileString(`switch ("abc") {}`, { luaTarget: tstl.LuaTarget.Lua51 }), - ).toThrowExactError( - TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub), + expect(() => util.transpileString(`switch ("abc") {}`, { luaTarget: tstl.LuaTarget.Lua51 })).toThrowExactError( + TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub) ); }); diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts index 5734b6440..729a4440c 100644 --- a/test/unit/console.spec.ts +++ b/test/unit/console.spec.ts @@ -5,22 +5,22 @@ const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; test.each([ { inp: "console.log()", expected: "print()" }, { inp: 'console.log("Hello")', expected: 'print("Hello")' }, - { - inp: 'console.log("Hello %s", "there")', - expected: 'print(string.format("Hello %s", "there"))', - }, - { - inp: 'console.log("Hello %%s", "there")', - expected: 'print(string.format("Hello %%s", "there"))', - }, + { inp: 'console.log("Hello %s", "there")', expected: 'print(string.format("Hello %s", "there"))' }, + { inp: 'console.log("Hello %%s", "there")', expected: 'print(string.format("Hello %%s", "there"))' }, { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There")' }, ])("console.log (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); }); test.each([ - { inp: "console.trace()", expected: "print(debug.traceback())" }, - { inp: 'console.trace("message")', expected: 'print(debug.traceback("message"))' }, + { + inp: "console.trace()", + expected: "print(debug.traceback())", + }, + { + inp: 'console.trace("message")', + expected: 'print(debug.traceback("message"))', + }, { inp: 'console.trace("Hello %s", "there")', expected: 'print(debug.traceback(string.format("Hello %s", "there")))', @@ -38,8 +38,14 @@ test.each([ }); test.each([ - { inp: "console.assert(false)", expected: "assert(false)" }, - { inp: 'console.assert(false, "message")', expected: 'assert(false, "message")' }, + { + inp: "console.assert(false)", + expected: "assert(false)", + }, + { + inp: 'console.assert(false, "message")', + expected: 'assert(false, "message")', + }, { inp: 'console.assert(false, "message %s", "info")', expected: 'assert(false, string.format("message %s", "info"))', @@ -71,7 +77,7 @@ test("console.differentiation", () => { export const result = test(); `, "result", - compilerOptions, + compilerOptions ); expect(result).toBe(42); }); diff --git a/test/unit/curry.spec.ts b/test/unit/curry.spec.ts index 639336a47..b39d2f3c6 100644 --- a/test/unit/curry.spec.ts +++ b/test/unit/curry.spec.ts @@ -3,7 +3,7 @@ import * as util from "../util"; test.each([{ x: 2, y: 3 }, { x: 5, y: 4 }])("curryingAdd (%p)", ({ x, y }) => { const result = util.transpileAndExecute( `let add = (x: number) => (y: number) => x + y; - return add(${x})(${y})`, + return add(${x})(${y})` ); expect(result).toBe(x + y); diff --git a/test/unit/decoratorCustomConstructor.spec.ts b/test/unit/decoratorCustomConstructor.spec.ts index 9ff43c51d..71052406e 100644 --- a/test/unit/decoratorCustomConstructor.spec.ts +++ b/test/unit/decoratorCustomConstructor.spec.ts @@ -19,12 +19,7 @@ test("CustomCreate", () => { } `; - const result = util.transpileAndExecute( - `return new Point2D(1, 2).x;`, - undefined, - luaHeader, - tsHeader, - ); + const result = util.transpileAndExecute(`return new Point2D(1, 2).x;`, undefined, luaHeader, tsHeader); expect(result).toBe(1); }); @@ -41,7 +36,5 @@ test("IncorrectUsage", () => { } return new Point2D(1, 2).x; `); - }).toThrowExactError( - TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, util.nodeStub), - ); + }).toThrowExactError(TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, util.nodeStub)); }); diff --git a/test/unit/decoratorMetaExtension.spec.ts b/test/unit/decoratorMetaExtension.spec.ts index eb574cc62..6057fb202 100644 --- a/test/unit/decoratorMetaExtension.spec.ts +++ b/test/unit/decoratorMetaExtension.spec.ts @@ -19,7 +19,7 @@ test("MetaExtension", () => { `return debug.getregistry()["_LOADED"].test();`, undefined, undefined, - tsHeader, + tsHeader ); expect(result).toBe(5); diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index c067d04fb..ad063a6ba 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -85,7 +85,7 @@ test("Enum identifier value internal", () => { ghi = def, jkl, } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;`, + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` ); expect(result).toBe("0,1,1,2"); @@ -99,7 +99,7 @@ test("Enum identifier value internal recursive", () => { ghi = def, jkl = ghi, } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;`, + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` ); expect(result).toBe("0,1,1,1"); @@ -113,7 +113,7 @@ test("Enum identifier value external", () => { def, ghi = ext, } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi}\`;`, + return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi}\`;` ); expect(result).toBe("0,1,6"); @@ -126,7 +126,7 @@ test("Enum reverse mapping", () => { def, ghi } - return testEnum[testEnum.abc] + testEnum[testEnum.ghi]`, + return testEnum[testEnum.abc] + testEnum[testEnum.ghi]` ); expect(result).toBe("abcghi"); @@ -139,7 +139,7 @@ test("Const enum index", () => { def, ghi } - return testEnum["def"];`, + return testEnum["def"];` ); expect(result).toBe(1); @@ -153,7 +153,7 @@ test("Const enum index identifier value", () => { ghi, jkl = ghi } - return testEnum["jkl"];`, + return testEnum["jkl"];` ); expect(result).toBe(5); @@ -167,7 +167,7 @@ test("Const enum index identifier chain", () => { ghi = def, jkl = ghi, } - return testEnum["ghi"];`, + return testEnum["ghi"];` ); expect(result).toBe(4); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index e53407bc8..fe5eacf5e 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -42,7 +42,7 @@ test.each([{ i: 0, expected: "A" }, { i: 1, expected: "B" }, { i: 2, expected: " `; const result = util.transpileAndExecute(source); expect(result).toBe(expected); - }, + } ); test("re-throw (no catch var)", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 28f758a98..23d137f50 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -11,15 +11,9 @@ test.each([ { input: "!a", lua: "local ____ = not a" }, { input: "-a", lua: "local ____ = -a" }, { input: "+a", lua: "local ____ = a" }, - { - input: "let a = delete tbl['test']", - lua: "local a = (function()\n tbl.test = nil\n return true\nend)()", - }, + { input: "let a = delete tbl['test']", lua: "local a = (function()\n tbl.test = nil\n return true\nend)()" }, { input: "delete tbl['test']", lua: "tbl.test = nil" }, - { - input: "let a = delete tbl.test", - lua: "local a = (function()\n tbl.test = nil\n return true\nend)()", - }, + { input: "let a = delete tbl.test", lua: "local a = (function()\n tbl.test = nil\n return true\nend)()" }, { input: "delete tbl.test", lua: "tbl.test = nil" }, ])("Unary expressions basic (%p)", ({ input, lua }) => { expect(util.transpileString(input)).toBe(lua); @@ -56,17 +50,14 @@ test.each([ expect(result).toBe(expected); }); -test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])( - "Binary expression in (%p)", - input => { - const tsHeader = "declare var obj: any;"; - const tsSource = `return ${input}`; - const luaHeader = "obj = { existingKey = 1 }"; - const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); +test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Binary expression in (%p)", input => { + const tsHeader = "declare var obj: any;"; + const tsSource = `return ${input}`; + const luaHeader = "obj = { existingKey = 1 }"; + const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); - expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); - }, -); + expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); +}); test.each([ { input: "a+=b", expected: 5 + 3 }, @@ -101,7 +92,7 @@ test.each([ util.transpileString(input, { luaTarget: tstl.LuaTarget.Lua51, luaLibImport: tstl.LuaLibImportKind.None, - }), + }) ).toThrow(); }); @@ -165,13 +156,13 @@ test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { util.transpileString(input, { luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None, - }), + }) ).toThrowExactError( TSTLErrors.UnsupportedKind( "right shift operator (use >>> instead)", ts.SyntaxKind.GreaterThanGreaterThanToken, - util.nodeStub, - ), + util.nodeStub + ) ); }); @@ -225,26 +216,14 @@ test.each([ { input: "true ? maybeUndefinedValue : true" }, { input: "true ? maybeBooleanValue : true", expected: false }, { input: "true ? maybeUndefinedValue : true", options: { strictNullChecks: true } }, - { - input: "true ? maybeBooleanValue : true", - expected: false, - options: { strictNullChecks: true }, - }, + { input: "true ? maybeBooleanValue : true", expected: false, options: { strictNullChecks: true } }, { input: "true ? undefined : true", options: { strictNullChecks: true } }, { input: "true ? null : true", options: { strictNullChecks: true } }, { input: "true ? false : true", expected: false, options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "false ? false : true", expected: true, options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { - input: "true ? false : true", - expected: false, - options: { luaTarget: tstl.LuaTarget.LuaJIT }, - }, - { - input: "false ? false : true", - expected: true, - options: { luaTarget: tstl.LuaTarget.LuaJIT }, - }, + { input: "true ? false : true", expected: false, options: { luaTarget: tstl.LuaTarget.LuaJIT } }, + { input: "false ? false : true", expected: true, options: { luaTarget: tstl.LuaTarget.LuaJIT } }, { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, ])("Ternary operator (%p)", ({ input, expected, options }) => { const result = util.transpileAndExecute( @@ -253,7 +232,7 @@ test.each([ let maybeBooleanValue:string|boolean = false; let maybeUndefinedValue:string|undefined; return ${input};`, - options, + options ); expect(result).toBe(expected); @@ -352,7 +331,7 @@ test.each([ `class A{ get value(){ return this.v || 1; } set value(v){ this.v = v; } v: number; } class B{ get value(){ return this.v || 2; } set value(v){ this.v = v; } v: number; } let x: A|B = new A(); - ${expression}`, + ${expression}` ); expect(result).toBe(expected); @@ -385,7 +364,7 @@ test.each([{ expression: "x = y", expected: "y" }, { expression: "x += y", expec ({ expression, expected }) => { const result = util.transpileAndExecute(`let x = "x"; let y = "y"; return ${expression};`); expect(result).toBe(expected); - }, + } ); test.each([ @@ -399,7 +378,7 @@ test.each([ let y = "y"; let o = {p: "o"}; let a = ["a"]; - return ${expression};`, + return ${expression};` ); expect(result).toBe(expected); }); @@ -414,7 +393,7 @@ test.each([ `let x = "x"; let o = {p: "o"}; let a = ["a"]; - return ${expression};`, + return ${expression};` ); expect(result).toBe(expected); }); @@ -434,7 +413,7 @@ test.each([ /** @tupleReturn */ function tr(): [string, string] { return ["tr0", "tr1"] }; const r = ${expression}; - return \`\${r[0]},\${r[1]}\``, + return \`\${r[0]},\${r[1]}\`` ); expect(result).toBe(expected); }); @@ -462,13 +441,9 @@ test("Unknown unary postfix error", () => { }; expect(() => - transformer.transformPostfixUnaryExpression(mockExpression as ts.PostfixUnaryExpression), + transformer.transformPostfixUnaryExpression(mockExpression as ts.PostfixUnaryExpression) ).toThrowExactError( - TSTLErrors.UnsupportedKind( - "unary postfix operator", - ts.SyntaxKind.AsteriskToken, - util.nodeStub, - ), + TSTLErrors.UnsupportedKind("unary postfix operator", ts.SyntaxKind.AsteriskToken, util.nodeStub) ); }); @@ -481,45 +456,33 @@ test("Unknown unary postfix error", () => { }; expect(() => - transformer.transformPrefixUnaryExpression(mockExpression as ts.PrefixUnaryExpression), + transformer.transformPrefixUnaryExpression(mockExpression as ts.PrefixUnaryExpression) ).toThrowExactError( - TSTLErrors.UnsupportedKind( - "unary prefix operator", - ts.SyntaxKind.AsteriskToken, - util.nodeStub, - ), + TSTLErrors.UnsupportedKind("unary prefix operator", ts.SyntaxKind.AsteriskToken, util.nodeStub) ); }); test("Incompatible fromCodePoint expression error", () => { expect(() => util.transpileString("const abc = String.fromCodePoint(123);")).toThrowExactError( - TSTLErrors.UnsupportedForTarget( - "string property fromCodePoint", - tstl.LuaTarget.Lua53, - util.nodeStub, - ), + TSTLErrors.UnsupportedForTarget("string property fromCodePoint", tstl.LuaTarget.Lua53, util.nodeStub) ); }); test("Unknown string expression error", () => { expect(() => util.transpileString("const abc = String.abcd();")).toThrowExactError( - TSTLErrors.UnsupportedForTarget( - "string property abcd", - tstl.LuaTarget.Lua53, - util.nodeStub, - ), + TSTLErrors.UnsupportedForTarget("string property abcd", tstl.LuaTarget.Lua53, util.nodeStub) ); }); test("Unsupported array function error", () => { expect(() => util.transpileString("const abc = [].unknownFunction();")).toThrowExactError( - TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub), + TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub) ); }); test("Unsupported math property error", () => { expect(() => util.transpileString("const abc = Math.unknownProperty;")).toThrowExactError( - TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub), + TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub) ); }); @@ -535,14 +498,8 @@ test("Unsupported object literal element error", () => { ], }; - expect(() => - transformer.transformObjectLiteral(mockObject as ts.ObjectLiteralExpression), - ).toThrowExactError( - TSTLErrors.UnsupportedKind( - "object literal element", - ts.SyntaxKind.FalseKeyword, - util.nodeStub, - ), + expect(() => transformer.transformObjectLiteral(mockObject as ts.ObjectLiteralExpression)).toThrowExactError( + TSTLErrors.UnsupportedKind("object literal element", ts.SyntaxKind.FalseKeyword, util.nodeStub) ); }); diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 98aa48ca4..cbcd4ad87 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -14,9 +14,7 @@ test.each([ { lambda: "++i", expected: 15 }, { lambda: "--i", expected: 5 }, ])("Arrow function unary expression (%p)", ({ lambda, expected }) => { - const result = util.transpileAndExecute( - `let i = 10; [1,2,3,4,5].forEach(() => ${lambda}); return i;`, - ); + const result = util.transpileAndExecute(`let i = 10; [1,2,3,4,5].forEach(() => ${lambda}); return i;`); expect(result).toBe(expected); }); @@ -46,16 +44,14 @@ test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Arrow Default Values (% const result = util.transpileAndExecute( `let add = (a: number = 3, b: number = 4) => a+b; - return add(${callArgs});`, + return add(${callArgs});` ); expect(result).toBe(v1 + v2); }); test("Function Expression", () => { - const result = util.transpileAndExecute( - `let add = function(a, b) {return a+b}; return add(1,2);`, - ); + const result = util.transpileAndExecute(`let add = function(a, b) {return a+b}; return add(1,2);`); expect(result).toBe(3); }); @@ -75,24 +71,21 @@ test("Function default parameter", () => { expect(result).toBe("abcdef"); }); -test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])( - "Function Default Values (%p)", - ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; +test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { + // Default value is 3 for v1 + const v1 = inp.length > 0 ? inp[0] : 3; + // Default value is 4 for v2 + const v2 = inp.length > 1 ? inp[1] : 4; - const callArgs = inp.join(","); + const callArgs = inp.join(","); - const result = util.transpileAndExecute( - `let add = function(a: number = 3, b: number = 4) { return a+b; }; - return add(${callArgs});`, - ); + const result = util.transpileAndExecute( + `let add = function(a: number = 3, b: number = 4) { return a+b; }; + return add(${callArgs});` + ); - expect(result).toBe(v1 + v2); - }, -); + expect(result).toBe(v1 + v2); +}); test("Function default array binding parameter", () => { const code = ` @@ -231,22 +224,20 @@ test("Invalid property access call transpilation", () => { expression: ts.createLiteral("abc"), }; - expect(() => - transformer.transformPropertyCall(mockObject as ts.CallExpression), - ).toThrowExactError(TSTLErrors.InvalidPropertyCall(util.nodeStub)); + expect(() => transformer.transformPropertyCall(mockObject as ts.CallExpression)).toThrowExactError( + TSTLErrors.InvalidPropertyCall(util.nodeStub) + ); }); test("Function dead code after return", () => { - const result = util.transpileAndExecute( - `function abc() { return 3; const a = 5; } return abc();`, - ); + const result = util.transpileAndExecute(`function abc() { return 3; const a = 5; } return abc();`); expect(result).toBe(3); }); test("Method dead code after return", () => { const result = util.transpileAndExecute( - `class def { public static abc() { return 3; const a = 5; } } return def.abc();`, + `class def { public static abc() { return 3; const a = 5; } } return def.abc();` ); expect(result).toBe(3); @@ -267,7 +258,7 @@ test("Recursive function expression", () => { test("Wrapped recursive function expression", () => { const result = util.transpileAndExecute( `function wrap(fn: T) { return fn; } - let f = wrap(function() { return typeof f; }); return f();`, + let f = wrap(function() { return typeof f; }); return f();` ); expect(result).toBe("function"); @@ -282,7 +273,7 @@ test("Recursive arrow function", () => { test("Wrapped recursive arrow function", () => { const result = util.transpileAndExecute( `function wrap(fn: T) { return fn; } - let f = wrap(() => typeof f); return f();`, + let f = wrap(() => typeof f); return f();` ); expect(result).toBe("function"); @@ -290,16 +281,15 @@ test("Wrapped recursive arrow function", () => { test("Object method declaration", () => { const result = util.transpileAndExecute( - `let o = { v: 4, m(i: number): number { return this.v * i; } }; return o.m(3);`, + `let o = { v: 4, m(i: number): number { return this.v * i; } }; return o.m(3);` ); expect(result).toBe(12); }); -test.each([ - { args: ["bar"], expectResult: "foobar" }, - { args: ["baz", "bar"], expectResult: "bazbar" }, -])("Function overload (%p)", ({ args, expectResult }) => { - const code = ` +test.each([{ args: ["bar"], expectResult: "foobar" }, { args: ["baz", "bar"], expectResult: "bazbar" }])( + "Function overload (%p)", + ({ args, expectResult }) => { + const code = ` class O { prop = "foo"; method(s: string): string; @@ -314,9 +304,10 @@ test.each([ const o = new O(); return o.method(${args.map(a => '"' + a + '"').join(", ")}); `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); -}); + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); + } +); test("Nested Function", () => { const code = ` @@ -338,10 +329,8 @@ test("Nested Function", () => { expect(result).toBe("foobar"); }); -test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])( - "Dot vs Colon method call (%p)", - ({ s1, s2 }) => { - const result = util.transpileAndExecute(` +test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])("Dot vs Colon method call (%p)", ({ s1, s2 }) => { + const result = util.transpileAndExecute(` class MyClass { dotMethod(this: void, s: string) { return s; @@ -353,9 +342,8 @@ test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])( const inst = new MyClass(); return inst.dotMethod("${s1}") == inst.colonMethod("${s2}"); `); - expect(result).toBe(s1 === s2); - }, -); + expect(result).toBe(s1 === s2); +}); test("Element access call", () => { const code = ` @@ -442,7 +430,7 @@ test.each([{ iterations: 1, expectedResult: 1 }, { iterations: 2, expectedResult `; const result = util.transpileAndExecute(code); expect(result).toBe(expectedResult); - }, + } ); test.each([{ iterations: 1, expectedResult: false }, { iterations: 2, expectedResult: true }])( @@ -463,7 +451,7 @@ test.each([{ iterations: 1, expectedResult: false }, { iterations: 2, expectedRe `; const result = util.transpileAndExecute(code); expect(result).toBe(expectedResult); - }, + } ); test("Generator for..of", () => { diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 37d893335..cf07a7c15 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -116,11 +116,10 @@ test.each([ expect(result).toBe(expectResult); }); -test.each([ - { initializer: "", expectResult: "foofoo" }, - { initializer: ' = "bar"', expectResult: "barbar" }, -])("Var hoisting from child scope (%p)", ({ initializer, expectResult }) => { - const code = ` +test.each([{ initializer: "", expectResult: "foofoo" }, { initializer: ' = "bar"', expectResult: "barbar" }])( + "Var hoisting from child scope (%p)", + ({ initializer, expectResult }) => { + const code = ` foo = "foo"; let result: string; if (true) { @@ -129,9 +128,10 @@ test.each([ } return foo + result; `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); -}); + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); + } +); test("Hoisting due to reference from hoisted function", () => { const code = ` @@ -228,10 +228,7 @@ test.each([ { code: `const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, { code: `export const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, { code: `const foo = bar(); export function bar() { return "bar"; }`, identifier: "bar" }, - { - code: `function bar() { return NS.foo; } namespace NS { export let foo = "foo"; }`, - identifier: "NS", - }, + { code: `function bar() { return NS.foo; } namespace NS { export let foo = "foo"; }`, identifier: "NS" }, { code: `export namespace O { export function f() { return I.foo; } namespace I { export let foo = "foo"; } }`, identifier: "I", @@ -240,7 +237,7 @@ test.each([ { code: `function bar() { return E.A; } enum E { A = "foo" }`, identifier: "E" }, ])("No Hoisting (%p)", ({ code, identifier }) => { expect(() => util.transpileString(code, { noHoisting: true })).toThrowExactError( - TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)), + TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)) ); }); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 7191a986e..8aa2bc432 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -62,19 +62,16 @@ test.each(invalidLuaNames)("lua keyword or invalid identifier as method call (%p expect(util.transpileAndExecute(code)).toBe("foobar"); }); -test.each(invalidLuaNames)( - "lua keyword or invalid identifier as complex method call (%p)", - name => { - const code = ` +test.each(invalidLuaNames)("lua keyword or invalid identifier as complex method call (%p)", name => { + const code = ` const foo = { ${name}(arg: string) { return "foo" + arg; } }; function getFoo() { return foo; } return getFoo().${name}("bar");`; - expect(util.transpileAndExecute(code)).toBe("foobar"); - }, -); + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); test.each([ "var local: any;", @@ -92,7 +89,7 @@ test.each([ const foo = local;`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local")).message, + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local")).message ); }); @@ -112,7 +109,7 @@ test.each([ const foo = $$$;`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$")).message, + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$")).message ); }); @@ -124,38 +121,32 @@ test.each(validTsInvalidLuaNames)( const foo = { ${name} };`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message ); - }, + } ); -test.each(validTsInvalidLuaNames)( - "undeclared identifier must be a valid lua identifier (%p)", - name => { - expect(() => util.transpileString(`const foo = ${name};`)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, - ); - }, -); +test.each(validTsInvalidLuaNames)("undeclared identifier must be a valid lua identifier (%p)", name => { + expect(() => util.transpileString(`const foo = ${name};`)).toThrow( + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message + ); +}); test.each(validTsInvalidLuaNames)( "undeclared identifier must be a valid lua identifier (object literal shorthand) (%p)", name => { expect(() => util.transpileString(`const foo = { ${name} };`)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message, + TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message ); - }, + } ); -test.each(validTsInvalidLuaNames)( - "exported values with invalid lua identifier names (%p)", - name => { - const code = `export const ${name} = "foobar";`; - const lua = util.transpileString(code); - expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); - expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); - }, -); +test.each(validTsInvalidLuaNames)("exported values with invalid lua identifier names (%p)", name => { + const code = `export const ${name} = "foobar";`; + const lua = util.transpileString(code); + expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); + expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); +}); test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name property", name => { const code = ` @@ -339,9 +330,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow( - /^LUA ERROR: .+ foobar$/, - ); + expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow(/^LUA ERROR: .+ foobar$/); }); test("variable (debug)", () => { @@ -362,7 +351,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toMatch( - /^foobar\nstack traceback.+/, + /^foobar\nstack traceback.+/ ); }); @@ -597,21 +586,18 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); }); - test.each(["type", "type as type"])( - "re-exported variable with lua keyword as name (%p)", - importName => { - const code = ` + test.each(["type", "type as type"])("re-exported variable with lua keyword as name (%p)", importName => { + const code = ` export { ${importName} } from "someModule"`; - const lua = ` + const lua = ` package.loaded.someModule = {type = "foobar"} return (function() ${util.transpileString(code)} end)().type`; - expect(util.executeLua(lua)).toBe("foobar"); - }, - ); + expect(util.executeLua(lua)).toBe("foobar"); + }); test("class", () => { const code = ` @@ -678,9 +664,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const code = ` return typeof type.foo + "|" + type.foo`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe( - "string|foobar", - ); + expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("string|foobar"); }); test.each([ @@ -715,9 +699,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const t = new type(); return \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe( - "number|boolean|string|foo|bar", - ); + expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("number|boolean|string|foo|bar"); }); test.each([ diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index e651f71d6..d7064edcc 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -8,20 +8,17 @@ const jsonOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs, }; -test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } }'])( - "JSON (%p)", - json => { - const lua = util - .transpileString({ "main.json": json }, jsonOptions, false) - .replace(/^return ([\s\S]+)$/, "return JSONStringify($1)"); +test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } }'])("JSON (%p)", json => { + const lua = util + .transpileString({ "main.json": json }, jsonOptions, false) + .replace(/^return ([\s\S]+)$/, "return JSONStringify($1)"); - const result = util.executeLua(lua); - expect(JSON.parse(result)).toEqual(JSON.parse(json)); - }, -); + const result = util.executeLua(lua); + expect(JSON.parse(result)).toEqual(JSON.parse(json)); +}); test("Empty JSON", () => { expect(() => util.transpileString({ "main.json": "" }, jsonOptions, false)).toThrowExactError( - TSTLErrors.InvalidJsonFileContent(util.nodeStub), + TSTLErrors.InvalidJsonFileContent(util.nodeStub) ); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index b36ff10ff..6c2bae455 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -11,17 +11,15 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("while (%p)", ({ inp, arrTest[i] = arrTest[i] + 1; i++; } - return JSONStringify(arrTest);`, + return JSONStringify(arrTest);` ); expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( - "while with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])("while with continue (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i = 0; while (i < arrTest.length) { if (i % 2 == 0) { @@ -40,18 +38,15 @@ test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( i++; } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( - "dowhile with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])("dowhile with continue (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i = 0; do { if (i % 2 == 0) { @@ -70,12 +65,11 @@ test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])( i++; } while (i < arrTest.length) - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( @@ -83,31 +77,26 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for (%p)", ({ inp, e for (let i = 0; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, + return JSONStringify(arrTest);` ); expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( - "for with expression (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for with expression (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i: number; for (i = 0 * 1; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, - ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + return JSONStringify(arrTest);` + ); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( - "for with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])("for with continue (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; for (let i = 0; i < arrTest.length; i++) { if (i % 2 == 0) { continue; @@ -120,27 +109,23 @@ test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( arrTest[i] = j; } } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( - "forMirror (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forMirror (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; for (let i = 0; arrTest.length > i; i++) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); test.each([{ inp: [0, 1, 2, 3], expected: [0, 1, 2, 3] }])("forBreak (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( @@ -149,33 +134,28 @@ test.each([{ inp: [0, 1, 2, 3], expected: [0, 1, 2, 3] }])("forBreak (%p)", ({ i break; arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, + return JSONStringify(arrTest);` ); expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( - "forNoDeclarations (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoDeclarations (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i = 0; for (; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( - "forNoCondition (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoCondition (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i = 0; for (;; ++i) { if (i >= arrTest.length) { @@ -184,18 +164,15 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( - "forNoPostExpression (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoPostExpression (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; let i = 0; for (;;) { if (i >= arrTest.length) { @@ -206,49 +183,28 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])( i++; } - return JSONStringify(arrTest);`, - ); + return JSONStringify(arrTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); test.each([ { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; i < arrTest.length; i++" }, - { - inp: [0, 1, 2, 3], - expected: [1, 2, 3, 4], - header: "let i = 0; i <= arrTest.length - 1; i++", - }, + { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; i <= arrTest.length - 1; i++" }, { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; arrTest.length > i; i++" }, - { - inp: [0, 1, 2, 3], - expected: [1, 2, 3, 4], - header: "let i = 0; arrTest.length - 1 >= i; i++", - }, + { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; arrTest.length - 1 >= i; i++" }, { inp: [0, 1, 2, 3], expected: [1, 1, 3, 3], header: "let i = 0; i < arrTest.length; i += 2" }, - { - inp: [0, 1, 2, 3], - expected: [1, 2, 3, 4], - header: "let i = arrTest.length - 1; i >= 0; i--", - }, - { - inp: [0, 1, 2, 3], - expected: [0, 2, 2, 4], - header: "let i = arrTest.length - 1; i >= 0; i -= 2", - }, - { - inp: [0, 1, 2, 3], - expected: [0, 2, 2, 4], - header: "let i = arrTest.length - 1; i > 0; i -= 2", - }, + { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = arrTest.length - 1; i >= 0; i--" }, + { inp: [0, 1, 2, 3], expected: [0, 2, 2, 4], header: "let i = arrTest.length - 1; i >= 0; i -= 2" }, + { inp: [0, 1, 2, 3], expected: [0, 2, 2, 4], header: "let i = arrTest.length - 1; i > 0; i -= 2" }, ])("forheader (%p)", ({ inp, expected, header }) => { const result = util.transpileAndExecute( `let arrTest = ${JSON.stringify(inp)}; for (${header}) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);`, + return JSONStringify(arrTest);` ); expect(result).toBe(JSON.stringify(expected)); @@ -274,7 +230,7 @@ test.each([ for (let key in objTest) { objTest[key] = objTest[key] + 1; } - return JSONStringify(objTest);`, + return JSONStringify(objTest);` ); expect(JSON.parse(result)).toEqual(expected); @@ -286,8 +242,8 @@ test.each([{ inp: [1, 2, 3] }])("forin[Array] (%p)", ({ inp }) => { `let arrTest = ${JSON.stringify(inp)}; for (let key in arrTest) { arrTest[key]++; - }`, - ), + }` + ) ).toThrowExactError(TSTLErrors.ForbiddenForIn(util.nodeStub)); }); @@ -303,11 +259,11 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2 obj[i] = 0; } - return JSONStringify(obj);`, + return JSONStringify(obj);` ); expect(result).toBe(JSON.stringify(expected)); - }, + } ); test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expected }) => { @@ -317,44 +273,38 @@ test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expec for (let value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);`, + return JSONStringify(arrResultTest);` ); expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])( - "forof existing variable (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof existing variable (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; let value: number; for (value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);`, - ); + return JSONStringify(arrResultTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); -test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( - "forof destructing (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])("forof destructing (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; for (let [a,b] of objTest) { arrResultTest.push(a + b) } - return JSONStringify(arrResultTest);`, - ); + return JSONStringify(arrResultTest);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( "forof destructing with existing variables (%p)", @@ -367,18 +317,16 @@ test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( for ([a,b] of objTest) { arrResultTest.push(a + b) } - return JSONStringify(arrResultTest);`, + return JSONStringify(arrResultTest);` ); expect(result).toBe(JSON.stringify(expected)); - }, + } ); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( - "forof with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let testArr = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])("forof with continue (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let testArr = ${JSON.stringify(inp)}; let a = 0; for (let i of testArr) { if (i % 2 == 0) { @@ -394,12 +342,11 @@ test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])( } a++; } - return JSONStringify(testArr);`, - ); + return JSONStringify(testArr);` + ); - expect(result).toBe(JSON.stringify(expected)); - }, -); + expect(result).toBe(JSON.stringify(expected)); +}); test("forof with iterator", () => { const code = ` @@ -531,7 +478,7 @@ test.each([ for (${initializer} of arr) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message, + TSTLErrors.UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message ); }); @@ -728,7 +675,7 @@ test("forof lua iterator tuple-return single variable", () => { target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub), + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) ); }); @@ -747,7 +694,7 @@ test("forof lua iterator tuple-return single existing variable", () => { target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub), + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) ); }); @@ -820,11 +767,7 @@ test.each([ const luajit = { luaTarget: tstl.LuaTarget.LuaJIT }; expect(() => util.transpileString(loop, lua51)).toThrowExactError( - TSTLErrors.UnsupportedForTarget( - "Continue statement", - tstl.LuaTarget.Lua51, - ts.createContinue(), - ), + TSTLErrors.UnsupportedForTarget("Continue statement", tstl.LuaTarget.Lua51, ts.createContinue()) ); expect(util.transpileString(loop, lua52).indexOf("::__continue1::") !== -1).toBe(true); expect(util.transpileString(loop, lua53).indexOf("::__continue1::") !== -1).toBe(true); @@ -832,17 +775,13 @@ test.each([ }); test("for dead code after return", () => { - const result = util.transpileAndExecute( - `for (let i = 0; i < 10; i++) { return 3; const b = 8; }`, - ); + const result = util.transpileAndExecute(`for (let i = 0; i < 10; i++) { return 3; const b = 8; }`); expect(result).toBe(3); }); test("for..in dead code after return", () => { - const result = util.transpileAndExecute( - `for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`, - ); + const result = util.transpileAndExecute(`for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`); expect(result).toBe(3); }); diff --git a/test/unit/luaTable.spec.ts b/test/unit/luaTable.spec.ts index 1ea3d2f9b..aa15f32ac 100644 --- a/test/unit/luaTable.spec.ts +++ b/test/unit/luaTable.spec.ts @@ -26,34 +26,29 @@ declare let tbl: Table; `; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - expect(() => - util.transpileString(tableLib + `const table = new Table(true);`), - ).toThrowExactError( + expect(() => util.transpileString(tableLib + `const table = new Table(true);`)).toThrowExactError( TSTLErrors.ForbiddenLuaTableUseException( "No parameters are allowed when constructing a LuaTable object.", - util.nodeStub, - ), + util.nodeStub + ) ); }); -test.each([tableLibClass, tableLibInterface])( - "LuaTable set() cannot be used in an expression position", - tableLib => { - expect(() => - util.transpileString(tableLib + `const exp = tbl.set("value", 5)`), - ).toThrowExactError(TSTLErrors.ForbiddenLuaTableSetExpression(util.nodeStub)); - }, -); +test.each([tableLibClass, tableLibInterface])("LuaTable set() cannot be used in an expression position", tableLib => { + expect(() => util.transpileString(tableLib + `const exp = tbl.set("value", 5)`)).toThrowExactError( + TSTLErrors.ForbiddenLuaTableSetExpression(util.nodeStub) + ); +}); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { expect(() => util.transpileString(tableLib + `tbl.other()`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub), + TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub) ); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { expect(() => util.transpileString(tableLib + `let x = tbl.other()`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub), + TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub) ); }); @@ -70,10 +65,7 @@ test.each([tableLibClass])("LuaTable length", tableLib => { test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { expect(() => util.transpileString(tableLib + `tbl.length = 2;`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException( - "A LuaTable object's length cannot be re-assigned.", - util.nodeStub, - ), + TSTLErrors.ForbiddenLuaTableUseException("A LuaTable object's length cannot be re-assigned.", util.nodeStub) ); }); @@ -87,7 +79,7 @@ test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib [`tbl.set("field", ...[0, 1])`, "Arguments cannot be spread."], ])("Forbidden LuaTable use (%p)", (invalidCode, errorDescription) => { expect(() => util.transpileString(tableLib + invalidCode)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException(errorDescription, util.nodeStub), + TSTLErrors.ForbiddenLuaTableUseException(errorDescription, util.nodeStub) ); }); }); @@ -97,9 +89,9 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { "Cannot extend LuaTable class (%p)", code => { expect(() => util.transpileString(tableLib + code)).toThrowExactError( - TSTLErrors.InvalidExtendsLuaTable(util.nodeStub), + TSTLErrors.InvalidExtendsLuaTable(util.nodeStub) ); - }, + } ); }); @@ -109,14 +101,14 @@ test.each([ `/** @luaTable */ const c = class Table {}`, ])("LuaTable classes must be ambient (%p)", code => { expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableNonDeclaration(util.nodeStub), + TSTLErrors.ForbiddenLuaTableNonDeclaration(util.nodeStub) ); }); test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each([`tbl instanceof Table`])("Cannot use instanceof on a LuaTable class (%p)", code => { expect(() => util.transpileString(tableLib + code)).toThrowExactError( - TSTLErrors.InvalidInstanceOfLuaTable(util.nodeStub), + TSTLErrors.InvalidInstanceOfLuaTable(util.nodeStub) ); }); }); @@ -126,13 +118,8 @@ test.each([tableLibClass])("LuaTable functional tests", tableLib => { [`const t = new Table(); t.set("field", "value"); return t.get("field");`, "value"], [`const t = new Table(); t.set("field", 0); return t.get("field");`, 0], [`const t = new Table(); t.set(1, true); return t.length`, 1], - [ - `const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length`, - 2, - ], + [`const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length`, 2], ])("LuaTable test (%p)", (code, expectedReturnValue) => { - expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe( - expectedReturnValue, - ); + expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); }); }); diff --git a/test/unit/lualib/inlining.spec.ts b/test/unit/lualib/inlining.spec.ts index fcb5ba938..b7a73fc57 100644 --- a/test/unit/lualib/inlining.spec.ts +++ b/test/unit/lualib/inlining.spec.ts @@ -16,7 +16,7 @@ test("map foreach keys", () => { let count = 0; mymap.forEach((value, key) => { count += key; }); return count;`, - { luaLibImport: LuaLibImportKind.Inline }, + { luaLibImport: LuaLibImportKind.Inline } ); expect(result).toBe(18); @@ -25,7 +25,7 @@ test("map foreach keys", () => { test("set constructor", () => { const result = util.transpileAndExecute( `class abc {} let def = new abc(); let myset = new Set(); return myset.size;`, - { luaLibImport: LuaLibImportKind.Inline }, + { luaLibImport: LuaLibImportKind.Inline } ); expect(result).toBe(0); @@ -37,7 +37,7 @@ test("set foreach keys", () => { let count = 0; myset.forEach((value, key) => { count += key; }); return count;`, - { luaLibImport: LuaLibImportKind.Inline }, + { luaLibImport: LuaLibImportKind.Inline } ); expect(result).toBe(9); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index eaf54d1f8..f2b5db912 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -6,7 +6,7 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forEach (%p)", ({ in arrTest.forEach((elem, index) => { arrTest[index] = arrTest[index] + 1; }) - return JSONStringify(arrTest);`, + return JSONStringify(arrTest);` ); expect(result).toBe(JSON.stringify(expected)); @@ -21,25 +21,25 @@ test.each([ `let arrTest = ${JSON.stringify(inp)}; return JSONStringify(arrTest.findIndex((elem, index) => { return elem === ${searchEl}; - }));`, + }));` ); expect(result).toBe(expected); }); -test.each([ - { inp: [0, 2, 4, 8], expected: 3, value: 8 }, - { inp: [0, 2, 4, 8], expected: 1, value: 2 }, -])("array.findIndex[index] (%p)", ({ inp, expected, value }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 2, 4, 8], expected: 3, value: 8 }, { inp: [0, 2, 4, 8], expected: 1, value: 2 }])( + "array.findIndex[index] (%p)", + ({ inp, expected, value }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; return JSONStringify(arrTest.findIndex((elem, index, arr) => { return index === ${expected} && arr[${expected}] === ${value}; - }));`, - ); + }));` + ); - expect(result).toBe(expected); -}); + expect(result).toBe(expected); + } +); test.each([ { inp: [], func: "x => x" }, @@ -49,9 +49,7 @@ test.each([ { inp: [0, 1, 2, 3], func: "x => x+2" }, { inp: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, ])("array.map (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute( - `return JSONStringify([${inp.toString()}].map(${func}))`, - ); + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].map(${func}))`); expect(result).toBe(JSON.stringify(inp.map(eval(func)))); }); @@ -65,9 +63,7 @@ test.each([ { inp: [0, 1, 2, 3], func: "() => true" }, { inp: [0, 1, 2, 3], func: "() => false" }, ])("array.filter (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute( - `return JSONStringify([${inp.toString()}].filter(${func}))`, - ); + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].filter(${func}))`); expect(result).toBe(JSON.stringify(inp.filter(eval(func)))); }); @@ -78,9 +74,7 @@ test.each([ { inp: [false, true, false], func: "x => x" }, { inp: [true, true, true], func: "x => x" }, ])("array.every (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute( - `return JSONStringify([${inp.toString()}].every(${func}))`, - ); + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].every(${func}))`); expect(result).toBe(JSON.stringify(inp.every(eval(func)))); }); @@ -91,9 +85,7 @@ test.each([ { inp: [false, true, false], func: "x => x" }, { inp: [true, true, true], func: "x => x" }, ])("array.some (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute( - `return JSONStringify([${inp.toString()}].some(${func}))`, - ); + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].some(${func}))`); expect(result).toBe(JSON.stringify(inp.some(eval(func)))); }); @@ -107,9 +99,7 @@ test.each([ { inp: [0, 1, 2, 3, 4, 5], start: 1, end: 3 }, { inp: [0, 1, 2, 3, 4, 5], start: 3 }, ])("array.slice (%p)", ({ inp, start, end }) => { - const result = util.transpileAndExecute( - `return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`, - ); + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`); expect(result).toBe(JSON.stringify(inp.slice(start, end))); }); @@ -126,7 +116,7 @@ test.each([ const result = util.transpileAndExecute( `let spliceTestTable = [${inp.toString()}]; spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);`, + return JSONStringify(spliceTestTable);` ); inp.splice(start, deleteCount, ...newElements); @@ -147,13 +137,13 @@ test.each([ result = util.transpileAndExecute( `let spliceTestTable = [${inp.toString()}]; spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);`, + return JSONStringify(spliceTestTable);` ); } else { result = util.transpileAndExecute( `let spliceTestTable = [${inp.toString()}]; spliceTestTable.splice(${start}); - return JSONStringify(spliceTestTable);`, + return JSONStringify(spliceTestTable);` ); } @@ -182,7 +172,7 @@ test.each([ const result = util.transpileAndExecute( `let concatTestTable: any[] = ${JSON.stringify(arr)}; - return JSONStringify(concatTestTable.concat(${argStr}));`, + return JSONStringify(concatTestTable.concat(${argStr}));` ); const concatArr = arr.concat(...args); @@ -206,7 +196,7 @@ test.each([ } const result = util.transpileAndExecute( `let joinTestTable = ${JSON.stringify(inp)}; - return joinTestTable.join(${separatorLua});`, + return joinTestTable.join(${separatorLua});` ); const joinedInp = inp.join(separator); @@ -238,46 +228,46 @@ test.each([{ inp: [1, 2, 3], expected: 3 }, { inp: [1, 2, 3, 4, 5], expected: 3 ({ inp, expected }) => { const result = util.transpileAndExecute( `let [x, y, z] = ${JSON.stringify(inp)} - return z;`, + return z;` ); expect(result).toBe(expected); - }, + } ); test.each([{ inp: [1] }, { inp: [1, 2, 3] }])("array.push (%p)", ({ inp }) => { const result = util.transpileAndExecute( `let testArray = [0]; testArray.push(${inp.join(", ")}); - return JSONStringify(testArray);`, + return JSONStringify(testArray);` ); expect(result).toBe(JSON.stringify([0].concat(inp))); }); -test.each([ - { array: "[1, 2, 3]", expected: [3, 2] }, - { array: "[1, 2, 3, null]", expected: [3, 2] }, -])("array.pop (%p)", ({ array, expected }) => { - { - const result = util.transpileAndExecute( - `let testArray = ${array}; +test.each([{ array: "[1, 2, 3]", expected: [3, 2] }, { array: "[1, 2, 3, null]", expected: [3, 2] }])( + "array.pop (%p)", + ({ array, expected }) => { + { + const result = util.transpileAndExecute( + `let testArray = ${array}; let val = testArray.pop(); - return val`, - ); + return val` + ); - expect(result).toBe(expected[0]); - } - { - const result = util.transpileAndExecute( - `let testArray = ${array}; + expect(result).toBe(expected[0]); + } + { + const result = util.transpileAndExecute( + `let testArray = ${array}; testArray.pop(); - return testArray.length`, - ); + return testArray.length` + ); - expect(result).toBe(expected[1]); + expect(result).toBe(expected[1]); + } } -}); +); test.each([ { array: "[1, 2, 3]", expected: [3, 2, 1] }, @@ -289,7 +279,7 @@ test.each([ const result = util.transpileAndExecute( `let testArray = ${array}; let val = testArray.reverse(); - return JSONStringify(testArray)`, + return JSONStringify(testArray)` ); expect(result).toBe(JSON.stringify(expected)); }); @@ -305,7 +295,7 @@ test.each([ const result = util.transpileAndExecute( `let testArray = ${array}; let val = testArray.shift(); - return JSONStringify(testArray)`, + return JSONStringify(testArray)` ); expect(result).toBe(JSON.stringify(expectedArray)); } @@ -314,7 +304,7 @@ test.each([ const result = util.transpileAndExecute( `let testArray = ${array}; let val = testArray.shift(); - return val`, + return val` ); expect(result).toBe(expectedValue); @@ -331,7 +321,7 @@ test.each([ const result = util.transpileAndExecute( `let testArray = ${array}; testArray.unshift(${toUnshift}); - return JSONStringify(testArray)`, + return JSONStringify(testArray)` ); expect(result).toBe(JSON.stringify(expected)); @@ -346,14 +336,18 @@ test.each([ const result = util.transpileAndExecute( `let testArray = ${array}; testArray.sort(); - return JSONStringify(testArray)`, + return JSONStringify(testArray)` ); expect(result).toBe(JSON.stringify(expected)); }); test.each([ - { array: [1, 2, 3, 4, 5], compareStr: "a - b", compareFn: (a: any, b: any) => a - b }, + { + array: [1, 2, 3, 4, 5], + compareStr: "a - b", + compareFn: (a: any, b: any) => a - b, + }, { array: ["4", "5", "3", "2", "1"], compareStr: "tonumber(a) - tonumber(b)", @@ -371,7 +365,7 @@ test.each([ return JSONStringify(testArray)`, undefined, undefined, - `declare function tonumber(this: void, e: any): number`, + `declare function tonumber(this: void, e: any): number` ); expect(result).toBe(JSON.stringify(array.sort(compareFn))); @@ -429,7 +423,7 @@ test.each([ `let a = 3; let delay = () => ${condition} ? a + 3 : a + 5; a = 8; - return delay();`, + return delay();` ); expect(result).toBe(expected); @@ -533,7 +527,7 @@ test.each([ return JSONStringify(obj);`, undefined, undefined, - objectFromEntriesDeclaration, + objectFromEntriesDeclaration ); expect(JSON.parse(result)).toEqual(expected); @@ -546,7 +540,7 @@ test("Object.fromEntries (Map)", () => { return JSONStringify(obj);`, undefined, undefined, - objectFromEntriesDeclaration, + objectFromEntriesDeclaration ); expect(JSON.parse(result)).toEqual({ foo: "bar" }); diff --git a/test/unit/lualib/map.spec.ts b/test/unit/lualib/map.spec.ts index 149ee258f..fc989628c 100644 --- a/test/unit/lualib/map.spec.ts +++ b/test/unit/lualib/map.spec.ts @@ -9,7 +9,7 @@ test("map constructor", () => { test("map iterable constructor", () => { const result = util.transpileAndExecute( `let mymap = new Map([["a", "c"],["b", "d"]]); - return mymap.has("a") && mymap.has("b");`, + return mymap.has("a") && mymap.has("b");` ); expect(result).toBe(true); @@ -44,7 +44,7 @@ test("map entries", () => { `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (var [key, value] of mymap.entries()) { count += key + value; } - return count;`, + return count;` ); expect(result).toBe(27); }); @@ -54,7 +54,7 @@ test("map foreach", () => { `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); let count = 0; mymap.forEach(i => count += i); - return count;`, + return count;` ); expect(result).toBe(9); @@ -65,31 +65,25 @@ test("map foreach keys", () => { `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; mymap.forEach((value, key) => { count += key; }); - return count;`, + return count;` ); expect(result).toBe(18); }); test("map get", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");`, - ); + const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");`); expect(result).toBe("c"); }); test("map get missing", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");`, - ); + const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");`); expect(result).toBe(undefined); }); test("map has", () => { - const contains = util.transpileAndExecute( - `let mymap = new Map([["a", "c"]]); return mymap.has("a");`, - ); + const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has("a");`); expect(contains).toBe(true); }); @@ -99,9 +93,7 @@ test("map has false", () => { }); test("map has null", () => { - const contains = util.transpileAndExecute( - `let mymap = new Map([["a", "c"]]); return mymap.has(null);`, - ); + const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has(null);`); expect(contains).toBe(false); }); @@ -110,7 +102,7 @@ test("map keys", () => { `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (var key of mymap.keys()) { count += key; } - return count;`, + return count;` ); expect(result).toBe(18); @@ -130,7 +122,7 @@ test("map values", () => { `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (var value of mymap.values()) { count += value; } - return count;`, + return count;` ); expect(result).toBe(9); @@ -140,10 +132,6 @@ test("map size", () => { expect(util.transpileAndExecute(`let m = new Map(); return m.size;`)).toBe(0); expect(util.transpileAndExecute(`let m = new Map(); m.set(1,3); return m.size;`)).toBe(1); expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); return m.size;`)).toBe(2); - expect( - util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`), - ).toBe(0); - expect( - util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`), - ).toBe(1); + expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`)).toBe(0); + expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`)).toBe(1); }); diff --git a/test/unit/lualib/set.spec.ts b/test/unit/lualib/set.spec.ts index 1fce6ceb7..6018d42cf 100644 --- a/test/unit/lualib/set.spec.ts +++ b/test/unit/lualib/set.spec.ts @@ -9,7 +9,7 @@ test("set constructor", () => { test("set iterable constructor", () => { const result = util.transpileAndExecute( `let myset = new Set(["a", "b"]); - return myset.has("a") || myset.has("b");`, + return myset.has("a") || myset.has("b");` ); expect(result).toBe(true); @@ -18,16 +18,14 @@ test("set iterable constructor", () => { test("set iterable constructor set", () => { const result = util.transpileAndExecute( `let myset = new Set(new Set(["a", "b"])); - return myset.has("a") || myset.has("b");`, + return myset.has("a") || myset.has("b");` ); expect(result).toBe(true); }); test("set add", () => { - const has = util.transpileAndExecute( - `let myset = new Set(); myset.add("a"); return myset.has("a");`, - ); + const has = util.transpileAndExecute(`let myset = new Set(); myset.add("a"); return myset.has("a");`); expect(has).toBe(true); }); @@ -51,7 +49,7 @@ test("set entries", () => { `let myset = new Set([5, 6, 7]); let count = 0; for (var [key, value] of myset.entries()) { count += key + value; } - return count;`, + return count;` ); expect(result).toBe(36); @@ -62,7 +60,7 @@ test("set foreach", () => { `let myset = new Set([2, 3, 4]); let count = 0; myset.forEach(i => { count += i; }); - return count;`, + return count;` ); expect(result).toBe(9); }); @@ -72,16 +70,14 @@ test("set foreach keys", () => { `let myset = new Set([2, 3, 4]); let count = 0; myset.forEach((value, key) => { count += key; }); - return count;`, + return count;` ); expect(result).toBe(9); }); test("set has", () => { - const contains = util.transpileAndExecute( - `let myset = new Set(["a", "c"]); return myset.has("a");`, - ); + const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has("a");`); expect(contains).toBe(true); }); @@ -91,9 +87,7 @@ test("set has false", () => { }); test("set has null", () => { - const contains = util.transpileAndExecute( - `let myset = new Set(["a", "c"]); return myset.has(null);`, - ); + const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has(null);`); expect(contains).toBe(false); }); @@ -102,7 +96,7 @@ test("set keys", () => { `let myset = new Set([5, 6, 7]); let count = 0; for (var key of myset.keys()) { count += key; } - return count;`, + return count;` ); expect(result).toBe(18); @@ -113,7 +107,7 @@ test("set values", () => { `let myset = new Set([5, 6, 7]); let count = 0; for (var value of myset.values()) { count += value; } - return count;`, + return count;` ); expect(result).toBe(18); diff --git a/test/unit/lualib/symbol.spec.ts b/test/unit/lualib/symbol.spec.ts index 51be6c70e..857a9918a 100644 --- a/test/unit/lualib/symbol.spec.ts +++ b/test/unit/lualib/symbol.spec.ts @@ -1,26 +1,20 @@ import * as util from "../../util"; -test.each([{}, { description: 1 }, { description: "name" }])( - "symbol.toString() (%p)", - ({ description }) => { - const result = util.transpileAndExecute(` +test.each([{}, { description: 1 }, { description: "name" }])("symbol.toString() (%p)", ({ description }) => { + const result = util.transpileAndExecute(` return Symbol(${JSON.stringify(description)}).toString(); `); - expect(result).toBe(`Symbol(${description || ""})`); - }, -); + expect(result).toBe(`Symbol(${description || ""})`); +}); -test.each([{}, { description: 1 }, { description: "name" }])( - "symbol.description (%p)", - ({ description }) => { - const result = util.transpileAndExecute(` +test.each([{}, { description: 1 }, { description: "name" }])("symbol.description (%p)", ({ description }) => { + const result = util.transpileAndExecute(` return Symbol(${JSON.stringify(description)}).description; `); - expect(result).toBe(description); - }, -); + expect(result).toBe(description); +}); test("symbol uniqueness", () => { const result = util.transpileAndExecute(` diff --git a/test/unit/lualib/weakMap.spec.ts b/test/unit/lualib/weakMap.spec.ts index 51b5df8d8..71cabdbe1 100644 --- a/test/unit/lualib/weakMap.spec.ts +++ b/test/unit/lualib/weakMap.spec.ts @@ -118,5 +118,5 @@ test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakMap has no map features (%p)", call => { expect(() => util.transpileAndExecute(`(new WeakMap() as any).${call}`)).toThrow(); - }, + } ); diff --git a/test/unit/lualib/weakSet.spec.ts b/test/unit/lualib/weakSet.spec.ts index 1b50a4756..1b86e960c 100644 --- a/test/unit/lualib/weakSet.spec.ts +++ b/test/unit/lualib/weakSet.spec.ts @@ -75,5 +75,5 @@ test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakSet has no set features (%p)", call => { expect(() => util.transpileAndExecute(`(new WeakSet() as any).${call}`)).toThrow(); - }, + } ); diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index 46c23b0f4..9ff3442f7 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -18,15 +18,12 @@ test.each([ expect(lua).toBe(expected); }); -test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])( - "Math constant (%p)", - constant => { - const epsilon = 0.000001; - const jsValue: number = (Math as Math & { [key: string]: any })[constant]; - const code = `return Math.abs(Math.${constant} - ${jsValue}) <= ${epsilon}`; - expect(util.transpileAndExecute(code)).toBe(true); - }, -); +test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math constant (%p)", constant => { + const epsilon = 0.000001; + const jsValue: number = (Math as Math & { [key: string]: any })[constant]; + const code = `return Math.abs(Math.${constant} - ${jsValue}) <= ${epsilon}`; + expect(util.transpileAndExecute(code)).toBe(true); +}); test.each([ { statement: "++x", expected: "x=4;y=6" }, @@ -49,7 +46,7 @@ test.each([ `let x = 3; let y = 6; ${statement}; - return \`x=\${x};y=\${y}\``, + return \`x=\${x};y=\${y}\`` ); expect(result).toBe(expected); }); @@ -75,7 +72,7 @@ test.each([ `let o = {p: 3}; let a = [6]; ${statement}; - return \`o=\${o.p};a=\${a[0]}\``, + return \`o=\${o.p};a=\${a[0]}\`` ); expect(result).toBe(expected); }); @@ -101,7 +98,7 @@ test.each([ `let o = {p: {d: 3}}; let a = [[6,11], [7,13]]; ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}]\``, + return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}]\`` ); expect(result).toBe(expected); }); @@ -130,7 +127,7 @@ test.each([ function af() { return a; } function i() { return 0; } ${statement}; - return \`o=\${o.p};a=\${a[0]}\``, + return \`o=\${o.p};a=\${a[0]}\`` ); expect(result).toBe(expected); }); @@ -160,7 +157,7 @@ test.each([ let _i = 0; function i() { return _i++; } ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}];i=\${_i}\``, + return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}];i=\${_i}\`` ); expect(result).toBe(expected); }); @@ -189,7 +186,7 @@ test.each([ `let x = 3; let y = 6; const r = ${expression}; - return \`\${r};x=\${x};y=\${y}\``, + return \`\${r};x=\${x};y=\${y}\`` ); expect(result).toBe(expected); }); @@ -218,7 +215,7 @@ test.each([ `let o = {p: 3}; let a = [6]; const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\``, + return \`\${r};o=\${o.p};a=\${a[0]}\`` ); expect(result).toBe(expected); }); @@ -250,7 +247,7 @@ test.each([ function af() { return a; } function i() { return 0; } const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\``, + return \`\${r};o=\${o.p};a=\${a[0]}\`` ); expect(result).toBe(expected); }); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 3869beadd..c47409707 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -11,11 +11,7 @@ describe("module import/export elision", () => { `; const expectToElideImport = (code: string) => { - const lua = util.transpileString( - { "module.d.ts": moduleDeclaration, "main.ts": code }, - undefined, - false, - ); + const lua = util.transpileString({ "module.d.ts": moduleDeclaration, "main.ts": code }, undefined, false); expect(() => util.executeLua(lua)).not.toThrow(); }; @@ -60,7 +56,7 @@ test.each([ "export { default as x } from '...';", ])("Export default keyword disallowed (%p)", exportStatement => { expect(() => util.transpileString(exportStatement)).toThrowExactError( - TSTLErrors.UnsupportedDefaultExport(util.nodeStub), + TSTLErrors.UnsupportedDefaultExport(util.nodeStub) ); }); @@ -78,7 +74,7 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ return foo;`; expect(util.executeLua(lua)).toBe("bar"); - }, + } ); test("defaultImport", () => { @@ -110,21 +106,20 @@ test("Non-exported module", () => { "return g.test();", undefined, undefined, - "module g { export function test() { return 3; } }", + "module g { export function test() { return 3; } }" ); expect(result).toBe(3); }); -test.each([ - tstl.LuaLibImportKind.Inline, - tstl.LuaLibImportKind.None, - tstl.LuaLibImportKind.Require, -])("LuaLib no uses? No code (%p)", luaLibImport => { - const lua = util.transpileString(``, { luaLibImport }); +test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( + "LuaLib no uses? No code (%p)", + luaLibImport => { + const lua = util.transpileString(``, { luaLibImport }); - expect(lua).toBe(``); -}); + expect(lua).toBe(``); + } +); test("Nested module with dot in name", () => { const code = `module a.b { diff --git a/test/unit/numbers.spec.ts b/test/unit/numbers.spec.ts index e3f78ff10..ecda5d93a 100644 --- a/test/unit/numbers.spec.ts +++ b/test/unit/numbers.spec.ts @@ -19,14 +19,10 @@ test("NaN reassignment", () => { expect(result).toBe(NaN); }); -test.each([ - "Infinity", - "Infinity - Infinity", - "Infinity / -1", - "Infinity * -1", - "Infinity + 1", - "Infinity - 1", -])("%s", code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code))); +test.each(["Infinity", "Infinity - Infinity", "Infinity / -1", "Infinity * -1", "Infinity + 1", "Infinity - 1"])( + "%s", + code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code)) +); test("Infinity reassignment", () => { const result = util.transpileAndExecute(`const Infinity = 1; return Infinity`); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index b199d3bf5..54323e528 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -34,7 +34,7 @@ describe("property shorthand", () => { `return ({ _G })._G.foobar;`, undefined, `foobar = "foobar"`, - "declare const _G: any;", + "declare const _G: any;" ); expect(result).toBe("foobar"); diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index 482cdd089..f911eeb2f 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -11,7 +11,7 @@ test("overload function1", () => { return def; } } - return abc(3);`, + return abc(3);` ); expect(result).toBe("jkl9"); @@ -28,7 +28,7 @@ test("overload function2", () => { return def; } } - return abc("ghj");`, + return abc("ghj");` ); expect(result).toBe("ghj"); @@ -47,7 +47,7 @@ test("overload method1", () => { } } } - return myclass.abc(3);`, + return myclass.abc(3);` ); expect(result).toBe("jkl9"); @@ -66,7 +66,7 @@ test("overload method2", () => { } } } - return myclass.abc("ghj");`, + return myclass.abc("ghj");` ); expect(result).toBe("ghj"); @@ -89,7 +89,7 @@ test("constructor1", () => { } } const inst = new myclass(3); - return inst.num`, + return inst.num` ); expect(result).toBe(3); @@ -112,7 +112,7 @@ test("constructor2", () => { } } const inst = new myclass("ghj"); - return inst.str`, + return inst.str` ); expect(result).toBe("ghj"); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index 183bac892..bb9903a1b 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -86,13 +86,10 @@ test.each([ expect(match[1]).toBe(expectedPath); } } - }, + } ); -test.each([ - { comment: "", expectedPath: "src.fake" }, - { comment: "/** @noResolution */", expectedPath: "fake" }, -])( +test.each([{ comment: "", expectedPath: "src.fake" }, { comment: "/** @noResolution */", expectedPath: "fake" }])( "noResolution on ambient modules causes no path alterations (%p)", ({ comment, expectedPath }) => { const lua = util.transpileString({ @@ -105,5 +102,5 @@ test.each([ if (util.expectToBeDefined(match)) { expect(match[1]).toBe(expectedPath); } - }, + } ); diff --git a/test/unit/semicolons.spec.ts b/test/unit/semicolons.spec.ts index 7142fe548..2cbe3ecb6 100644 --- a/test/unit/semicolons.spec.ts +++ b/test/unit/semicolons.spec.ts @@ -1,17 +1,15 @@ import * as util from "../util"; -test.each([ - "const a = 1; const b = a;", - "const a = 1; let b: number; b = a;", - "{}", - "function bar() {} bar();", -])("semicolon insertion (%p)", leadingStatement => { - const code = ` +test.each(["const a = 1; const b = a;", "const a = 1; let b: number; b = a;", "{}", "function bar() {} bar();"])( + "semicolon insertion (%p)", + leadingStatement => { + const code = ` let result = ""; function foo() { result = "foo"; } ${leadingStatement} (foo)(); return result; `; - expect(util.transpileAndExecute(code)).toEqual("foo"); -}); + expect(util.transpileAndExecute(code)).toEqual("foo"); + } +); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index 5d571f0d2..94cf8aca1 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -181,7 +181,7 @@ test("sourceMapTraceback saves sourcemap in _G", () => { typeScriptSource, options, undefined, - "declare const _G: {__TS__sourcemap: any};", + "declare const _G: {__TS__sourcemap: any};" ); // Assert @@ -225,9 +225,7 @@ test("Inline sourcemaps", () => { const { file } = util.transpileStringResult(typeScriptSource, compilerOptions); if (!util.expectToBeDefined(file.lua)) return; - const inlineSourceMapMatch = file.lua.match( - /--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/, - ); + const inlineSourceMapMatch = file.lua.match(/--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/); if (util.expectToBeDefined(inlineSourceMapMatch)) { const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index ad50137ef..1177ff262 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -1,15 +1,12 @@ import * as tstl from "../../src"; import * as util from "../util"; -test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])( - "Spread Element Push (%p)", - ({ inp }) => { - const result = util.transpileAndExecute( - `return JSONStringify(([] as Array).push(...${JSON.stringify(inp)}));`, - ); - expect(result).toBe(([] as Array).push(...inp)); - }, -); +test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])("Spread Element Push (%p)", ({ inp }) => { + const result = util.transpileAndExecute( + `return JSONStringify(([] as Array).push(...${JSON.stringify(inp)}));` + ); + expect(result).toBe(([] as Array).push(...inp)); +}); test("Spread Element Lua 5.1", () => { // Cant test functional because our VM doesn't run on 5.1 diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 17a340975..910303891 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -4,19 +4,12 @@ import * as util from "../util"; test("Unsuported string function", () => { expect(() => { util.transpileString(`return "test".testThisIsNoMember()`); - }).toThrowExactError( - TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub), - ); + }).toThrowExactError(TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); }); test("Suported lua string function", () => { expect( - util.transpileAndExecute( - `return "test".upper()`, - undefined, - undefined, - `interface String { upper(): string; }`, - ), + util.transpileAndExecute(`return "test".upper()`, undefined, undefined, `interface String { upper(): string; }`) ).toBe("TEST"); }); @@ -26,7 +19,7 @@ test.each([{ inp: [] }, { inp: [65] }, { inp: [65, 66] }, { inp: [65, 66, 67] }] const result = util.transpileAndExecute(`return String.fromCharCode(${inp.toString()})`); expect(result).toBe(String.fromCharCode(...inp)); - }, + } ); test.each([ @@ -99,9 +92,7 @@ test.each([ ])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { const replaceValueString = typeof replaceValue === "string" ? JSON.stringify(replaceValue) : replaceValue.toString(); - const result = util.transpileAndExecute( - `return "${inp}".replace("${searchValue}", ${replaceValueString});`, - ); + const result = util.transpileAndExecute(`return "${inp}".replace("${searchValue}", ${replaceValueString});`); // https://github.com/Microsoft/TypeScript/issues/22378 if (typeof replaceValue === "string") { @@ -158,16 +149,14 @@ test.each([ expect(result).toBe(inp.indexOf(searchValue, offset)); }); -test.each([ - { inp: "hello test", searchValue: "t", x: 4, y: 3 }, - { inp: "hello test", searchValue: "h", x: 3, y: 4 }, -])("string.indexOf with offset expression (%p)", ({ inp, searchValue, x, y }) => { - const result = util.transpileAndExecute( - `return "${inp}".indexOf("${searchValue}", 2 > 1 && ${x} || ${y})`, - ); - - expect(result).toBe(inp.indexOf(searchValue, x)); -}); +test.each([{ inp: "hello test", searchValue: "t", x: 4, y: 3 }, { inp: "hello test", searchValue: "h", x: 3, y: 4 }])( + "string.indexOf with offset expression (%p)", + ({ inp, searchValue, x, y }) => { + const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}", 2 > 1 && ${x} || ${y})`); + + expect(result).toBe(inp.indexOf(searchValue, x)); + } +); test.each([ { inp: "hello test" }, @@ -194,15 +183,15 @@ test.each([ expect(result).toBe(inp.substring(start, end)); }); -test.each([ - { inp: "hello test", start: 1, ignored: 0 }, - { inp: "hello test", start: 3, ignored: 0, end: 5 }, -])("string.substring with expression (%p)", ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); +test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 5 }])( + "string.substring with expression (%p)", + ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); - expect(result).toBe(inp.substring(start, end)); -}); + expect(result).toBe(inp.substring(start, end)); + } +); test.each([ { inp: "hello test", start: 0 }, @@ -216,15 +205,15 @@ test.each([ expect(result).toBe(inp.substr(start, end)); }); -test.each([ - { inp: "hello test", start: 1, ignored: 0 }, - { inp: "hello test", start: 3, ignored: 0, end: 2 }, -])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); +test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 2 }])( + "string.substr with expression (%p)", + ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - expect(result).toBe(inp.substr(start, end)); -}); + expect(result).toBe(inp.substr(start, end)); + } +); test.each(["", "h", "hello"])("string.length (%p)", input => { const result = util.transpileAndExecute(`return "${input}".length`); @@ -269,15 +258,14 @@ test.each([ expect(result).toBe(inp.charAt(index)); }); -test.each([ - { inp: "hello test", index: 1 }, - { inp: "hello test", index: 2 }, - { inp: "hello test", index: 3 }, -])("string.charCodeAt (%p)", ({ inp, index }) => { - const result = util.transpileAndExecute(`return "${inp}".charCodeAt(${index})`); +test.each([{ inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }])( + "string.charCodeAt (%p)", + ({ inp, index }) => { + const result = util.transpileAndExecute(`return "${inp}".charCodeAt(${index})`); - expect(result).toBe(inp.charCodeAt(index)); -}); + expect(result).toBe(inp.charCodeAt(index)); + } +); test.each([ { inp: "hello test", index: 1, ignored: 0 }, @@ -285,9 +273,7 @@ test.each([ { inp: "hello test", index: 3, ignored: 2 }, { inp: "hello test", index: 3, ignored: 99 }, ])("string.charAt with expression (%p)", ({ inp, index, ignored }) => { - const result = util.transpileAndExecute( - `return "${inp}".charAt(2 > 1 && ${index} || ${ignored})`, - ); + const result = util.transpileAndExecute(`return "${inp}".charAt(2 > 1 && ${index} || ${ignored})`); expect(result).toBe(inp.charAt(index)); }); diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 08fbad709..0f6aa6a39 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -5,7 +5,7 @@ test("Tuple loop", () => { `const tuple: [number, number, number] = [3,5,1]; let count = 0; for (const value of tuple) { count += value; } - return count;`, + return count;` ); expect(result).toBe(9); @@ -16,7 +16,7 @@ test("Tuple foreach", () => { `const tuple: [number, number, number] = [3,5,1]; let count = 0; tuple.forEach(v => count += v); - return count;`, + return count;` ); expect(result).toBe(9); @@ -25,7 +25,7 @@ test("Tuple foreach", () => { test("Tuple access", () => { const result = util.transpileAndExecute( `const tuple: [number, number, number] = [3,5,1]; - return tuple[1];`, + return tuple[1];` ); expect(result).toBe(5); @@ -35,7 +35,7 @@ test("Tuple union access", () => { const result = util.transpileAndExecute( `function makeTuple(): [number, number, number] | [string, string, string] { return [3,5,1]; } const tuple = makeTuple(); - return tuple[1];`, + return tuple[1];` ); expect(result).toBe(5); }); @@ -49,7 +49,7 @@ test("Tuple intersection access", () => { return (t as I); } const tuple = makeTuple(); - return tuple[1];`, + return tuple[1];` ); expect(result).toBe(5); }); @@ -58,7 +58,7 @@ test("Tuple Destruct", () => { const result = util.transpileAndExecute( `function tuple(): [number, number, number] { return [3,5,1]; } const [a,b,c] = tuple(); - return b;`, + return b;` ); expect(result).toBe(5); @@ -91,7 +91,7 @@ test("Tuple Destruct Array Literal Extra Values", () => { test("Tuple length", () => { const result = util.transpileAndExecute( `const tuple: [number, number, number] = [3,5,1]; - return tuple.length;`, + return tuple.length;` ); expect(result).toBe(3); diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index 8088994b0..3d5014336 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -26,9 +26,7 @@ test.each(["{}", "[]"])("typeof object literal (%p)", inp => { }); test("typeof class instance", () => { - const result = util.transpileAndExecute( - `class myClass {} let inst = new myClass(); return typeof inst;`, - ); + const result = util.transpileAndExecute(`class myClass {} let inst = new myClass(); return typeof inst;`); expect(result).toBe("object"); }); @@ -47,7 +45,7 @@ test.each(["null", "undefined"])("typeof undefined (%p)", inp => { test("instanceof", () => { const result = util.transpileAndExecute( - "class myClass {} let inst = new myClass(); return inst instanceof myClass;", + "class myClass {} let inst = new myClass(); return inst instanceof myClass;" ); expect(result).toBe(true); @@ -98,9 +96,7 @@ test("instanceof undefined", () => { }); test("null instanceof Class", () => { - const result = util.transpileAndExecute( - "class myClass {} return (null as any) instanceof myClass;", - ); + const result = util.transpileAndExecute("class myClass {} return (null as any) instanceof myClass;"); expect(result).toBe(false); }); @@ -113,9 +109,7 @@ test.each(["extension", "metaExtension"])("instanceof extension (%p)", extension declare const foo: any; const result = foo instanceof B; `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.InvalidInstanceOfExtension(util.nodeStub), - ); + expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidInstanceOfExtension(util.nodeStub)); }); test("instanceof export", () => { @@ -123,7 +117,7 @@ test("instanceof export", () => { `export class myClass {} let inst = new myClass(); export const result = inst instanceof myClass;`, - "result", + "result" ); expect(result).toBe(true); diff --git a/test/util.ts b/test/util.ts index 43b748907..3da13b395 100644 --- a/test/util.ts +++ b/test/util.ts @@ -9,7 +9,7 @@ export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); export function transpileString( str: string | { [filename: string]: string }, options: tstl.CompilerOptions = {}, - ignoreDiagnostics = true, + ignoreDiagnostics = true ): string { const { diagnostics, file } = transpileStringResult(str, options); if (!expectToBeDefined(file) || !expectToBeDefined(file.lua)) return ""; @@ -22,7 +22,7 @@ export function transpileString( export function transpileStringResult( input: string | Record, - options: tstl.CompilerOptions = {}, + options: tstl.CompilerOptions = {} ): Required { const optionsWithDefaults = { luaTarget: tstl.LuaTarget.Lua53, @@ -36,7 +36,7 @@ export function transpileStringResult( const { diagnostics, transpiledFiles } = tstl.transpileVirtualProject( typeof input === "string" ? { "main.ts": input } : input, - optionsWithDefaults, + optionsWithDefaults ); const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); @@ -47,10 +47,7 @@ export function transpileStringResult( return { diagnostics, file }; } -const lualibContent = fs.readFileSync( - path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), - "utf8", -); +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; export function executeLua(luaStr: string, withLib = true): any { luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); @@ -73,10 +70,7 @@ export function executeLua(luaStr: string, withLib = true): any { } else if (lua.lua_isstring(L, -1)) { return lua.lua_tojsstring(L, -1); } else { - throw new Error( - "Unsupported lua return type: " + - to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))), - ); + throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); } } else { // If the lua VM did not terminate with status code LUA_OK an error occurred. @@ -96,7 +90,7 @@ export function transpileAndExecute( tsStr: string, compilerOptions?: tstl.CompilerOptions, luaHeader?: string, - tsHeader?: string, + tsHeader?: string ): any { const wrappedTsString = `${tsHeader ? tsHeader : ""} declare function JSONStringify(this: void, p: any): string; @@ -113,7 +107,7 @@ export function transpileExecuteAndReturnExport( tsStr: string, returnExport: string, compilerOptions?: tstl.CompilerOptions, - luaHeader?: string, + luaHeader?: string ): any { const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; ${tsStr}`; @@ -128,7 +122,7 @@ export function transpileExecuteAndReturnExport( export function parseTypeScript( typescript: string, - target: tstl.LuaTarget = tstl.LuaTarget.Lua53, + target: tstl.LuaTarget = tstl.LuaTarget.Lua53 ): [ts.SourceFile, ts.TypeChecker] { const program = tstl.createVirtualProgram({ "main.ts": typescript }, { luaTarget: target }); const sourceFile = program.getSourceFile("main.ts"); @@ -140,10 +134,7 @@ export function parseTypeScript( return [sourceFile, program.getTypeChecker()]; } -export function findFirstChild( - node: ts.Node, - predicate: (node: ts.Node) => boolean, -): ts.Node | undefined { +export function findFirstChild(node: ts.Node, predicate: (node: ts.Node) => boolean): ts.Node | undefined { for (const child of node.getChildren()) { if (predicate(child)) { return child; diff --git a/tslint.json b/tslint.json index 178f3066d..2bf168c59 100644 --- a/tslint.json +++ b/tslint.json @@ -1,30 +1,53 @@ { - "extends": "./test/tslint.json", "rules": { - "arrow-parens": [true, "ban-single-arg-parens"], - "import-spacing": true, - "max-line-length": [true, 120], - "new-parens": true, - "no-trailing-whitespace": true, - "semicolon": [true, "always", "ignore-bound-class-methods"], - "trailing-comma": [ + "array-type": [true, "array-simple"], + "arrow-return-shorthand": true, + "ban": [ true, - { - "multiline": { - "objects": "always", - "arrays": "always", - "functions": "never", - "typeLiterals": "always" - }, - "esSpecCompliant": true - } + { "name": "parseInt", "message": "tsstyle#type-coercion" }, + { "name": "parseFloat", "message": "tsstyle#type-coercion" }, + { "name": "Array", "message": "tsstyle#array-constructor" } ], - "whitespace": [ + "ban-types": [ true, - "check-type-operator", - "check-decl", - "check-rest-spread", - "check-typecast" - ] + ["Object", "Use {} instead."], + ["String", "Use 'string' instead."], + ["Number", "Use 'number' instead."], + ["Boolean", "Use 'boolean' instead."] + ], + "class-name": true, + "curly": [true, "ignore-same-line"], + "deprecation": true, + "forin": false, + "interface-name": [true, "never-prefix"], + "jsdoc-format": true, + "label-position": true, + "max-classes-per-file": [true, 1], + "member-access": true, + "no-angle-bracket-type-assertion": true, + "no-any": false, + "no-arg": true, + "no-conditional-assignment": true, + "no-construct": true, + "no-debugger": true, + "no-default-export": true, + "no-duplicate-switch-case": true, + "no-duplicate-variable": true, + "no-inferrable-types": true, + "no-namespace": [true, "allow-declarations"], + "no-null-keyword": true, + "no-reference": true, + "no-string-throw": true, + "no-unused-expression": true, + "no-var-keyword": true, + "object-literal-shorthand": true, + "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], + "prefer-const": [true, { "destructuring": "all" }], + "radix": true, + "switch-default": false, + "triple-equals": [true, "allow-null-check"], + "typedef": [true, "call-signature", "property-declaration"], + "use-isnan": true, + "variable-name": [true, "check-format", "ban-keywords", "allow-leading-underscore", "allow-pascal-case"] } } From 440ef2776a95963a7f077575dbb1bed7becb2ed5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 27 May 2019 21:27:29 +0200 Subject: [PATCH 096/764] Added array.reduce (#604) * Added array.reduce * Removed unused import * Update src/lualib/ArrayReduce.ts Co-Authored-By: ark120202 * Fixed error test * Updated tests * Added undefined deleteCount test --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 2 + src/lualib/ArrayReduce.ts | 28 ++ src/lualib/ArraySlice.ts | 10 +- test/unit/lualib/array.spec.ts | 458 ++++++++++++++++++++++++++++++++ test/unit/lualib/lualib.spec.ts | 403 ---------------------------- 6 files changed, 495 insertions(+), 407 deletions(-) create mode 100644 src/lualib/ArrayReduce.ts create mode 100644 test/unit/lualib/array.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 70799e090..658664488 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -10,6 +10,7 @@ export enum LuaLibFeature { ArrayIndexOf = "ArrayIndexOf", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", + ArrayReduce = "ArrayReduce", ArrayReverse = "ArrayReverse", ArrayShift = "ArrayShift", ArrayUnshift = "ArrayUnshift", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2cd7db45c..2319f7548 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4404,6 +4404,8 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.ArrayMap, node, caller, ...params); case "filter": return this.transformLuaLibFunction(LuaLibFeature.ArrayFilter, node, caller, ...params); + case "reduce": + return this.transformLuaLibFunction(LuaLibFeature.ArrayReduce, node, caller, ...params); case "some": return this.transformLuaLibFunction(LuaLibFeature.ArraySome, node, caller, ...params); case "every": diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts new file mode 100644 index 000000000..9122afa68 --- /dev/null +++ b/src/lualib/ArrayReduce.ts @@ -0,0 +1,28 @@ +// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce +function __TS__ArrayReduce( + this: void, + arr: T[], + callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, + initial?: T +): T { + const len = arr.length; + + if (len === 0 && initial === undefined) { + // tslint:disable-next-line: no-string-throw + throw "Reduce of empty array with no initial value"; + } + + let k = 0; + let accumulator = initial; + if (initial === undefined) { + accumulator = arr[0]; + k++; + } + + while (k < len) { + accumulator = callbackFn(accumulator, arr[k], k, arr); + k = k + 1; + } + + return accumulator; +} diff --git a/src/lualib/ArraySlice.ts b/src/lualib/ArraySlice.ts index 8005e9afc..d38d96006 100644 --- a/src/lualib/ArraySlice.ts +++ b/src/lualib/ArraySlice.ts @@ -1,12 +1,14 @@ -// https://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf 22.1.3.23 +// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.slice function __TS__ArraySlice(this: void, list: T[], first: number, last: number): T[] { const len = list.length; + const relativeStart = first || 0; + let k: number; - if (first < 0) { - k = Math.max(len + first, 0); + if (relativeStart < 0) { + k = Math.max(len + relativeStart, 0); } else { - k = Math.min(first, len); + k = Math.min(relativeStart, len); } let relativeEnd = last; diff --git a/test/unit/lualib/array.spec.ts b/test/unit/lualib/array.spec.ts new file mode 100644 index 000000000..ad8c64db2 --- /dev/null +++ b/test/unit/lualib/array.spec.ts @@ -0,0 +1,458 @@ +import * as util from "../../util"; + +test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forEach (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + arrTest.forEach((elem, index) => { + arrTest[index] = arrTest[index] + 1; + }) + return JSONStringify(arrTest);` + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { inp: [], searchEl: 3, expected: -1 }, + { inp: [0, 2, 4, 8], searchEl: 10, expected: -1 }, + { inp: [0, 2, 4, 8], searchEl: 8, expected: 3 }, +])("array.findIndex[value] (%p)", ({ inp, searchEl, expected }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index) => { + return elem === ${searchEl}; + }));` + ); + + expect(result).toEqual(expected); +}); + +test.each([{ inp: [0, 2, 4, 8], expected: 3, value: 8 }, { inp: [0, 2, 4, 8], expected: 1, value: 2 }])( + "array.findIndex[index] (%p)", + ({ inp, expected, value }) => { + const result = util.transpileAndExecute( + `let arrTest = ${JSON.stringify(inp)}; + return JSONStringify(arrTest.findIndex((elem, index, arr) => { + return index === ${expected} && arr[${expected}] === ${value}; + }));` + ); + + expect(result).toEqual(expected); + } +); + +test.each([ + { inp: [], func: "x => x" }, + { inp: [0, 1, 2, 3], func: "x => x" }, + { inp: [0, 1, 2, 3], func: "x => x*2" }, + { inp: [1, 2, 3, 4], func: "x => -x" }, + { inp: [0, 1, 2, 3], func: "x => x+2" }, + { inp: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, +])("array.map (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].map(${func}))`); + + expect(JSON.parse(result)).toEqual(inp.map(eval(func))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x < 3" }, + { inp: [0, 1, 2, 3], func: "x => x < 0" }, + { inp: [0, -1, -2, -3], func: "x => x < 0" }, + { inp: [0, 1, 2, 3], func: "() => true" }, + { inp: [0, 1, 2, 3], func: "() => false" }, +])("array.filter (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].filter(${func}))`); + + expect(JSON.parse(result)).toEqual(inp.filter(eval(func))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [false, true, false], func: "x => x" }, + { inp: [true, true, true], func: "x => x" }, +])("array.every (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].every(${func}))`); + + expect(JSON.parse(result)).toEqual(inp.every(eval(func))); +}); + +test.each([ + { inp: [], func: "x => x > 1" }, + { inp: [0, 1, 2, 3], func: "x => x > 1" }, + { inp: [false, true, false], func: "x => x" }, + { inp: [true, true, true], func: "x => x" }, +])("array.some (%p)", ({ inp, func }) => { + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].some(${func}))`); + + expect(JSON.parse(result)).toEqual(inp.some(eval(func))); +}); + +test.each([ + { inp: [], start: 1, end: 2 }, + { inp: [0, 1, 2, 3], start: 1, end: 2 }, + { inp: [0, 1, 2, 3], start: 1, end: 1 }, + { inp: [0, 1, 2, 3], start: 1, end: -1 }, + { inp: [0, 1, 2, 3], start: -3, end: -1 }, + { inp: [0, 1, 2, 3, 4, 5], start: 1, end: 3 }, + { inp: [0, 1, 2, 3, 4, 5], start: 3 }, +])("array.slice (%p)", ({ inp, start, end }) => { + const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`); + + expect(JSON.parse(result)).toEqual(inp.slice(start, end)); +}); + +test("array.slice no argument", () => { + const input = [2, 3, 4, 5]; + const result = util.transpileAndExecute(`return JSONStringify(${JSON.stringify(input)}.slice())`); + + expect(JSON.parse(result)).toEqual(input); +}); + +test.each([ + { inp: [], start: 0, deleteCount: 0, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 1, deleteCount: 0, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 2, deleteCount: 2, newElements: [9, 10, 11] }, + { inp: [0, 1, 2, 3], start: 4, deleteCount: 1, newElements: [8, 9] }, + { inp: [0, 1, 2, 3], start: 4, deleteCount: 0, newElements: [8, 9] }, + { inp: [0, 1, 2, 3], start: -2, deleteCount: 0, newElements: [8, 9] }, + { inp: [0, 1, 2, 3], start: -3, deleteCount: 0, newElements: [8, 9] }, + { inp: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, + { inp: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, +])("array.splice[Insert] (%p)", ({ inp, start, deleteCount, newElements }) => { + const result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); + return JSONStringify(spliceTestTable);` + ); + + inp.splice(start, deleteCount, ...newElements); + expect(JSON.parse(result)).toEqual(inp); +}); + +test.each([ + { inp: [], start: 1, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 1, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 10, deleteCount: 1 }, + { inp: [0, 1, 2, 3], start: 1, deleteCount: undefined }, + { inp: [0, 1, 2, 3], start: 4 }, + { inp: [0, 1, 2, 3, 4, 5], start: 3 }, + { inp: [0, 1, 2, 3, 4, 5], start: -3 }, + { inp: [0, 1, 2, 3, 4, 5], start: -2 }, + { inp: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, + { inp: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, +])("array.splice[Remove] (%p)", ({ inp, start, deleteCount, newElements = [] }) => { + let result; + if (deleteCount) { + result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); + return JSONStringify(spliceTestTable);` + ); + } else { + result = util.transpileAndExecute( + `let spliceTestTable = [${inp.toString()}]; + spliceTestTable.splice(${start}); + return JSONStringify(spliceTestTable);` + ); + } + + if (deleteCount) { + inp.splice(start, deleteCount, ...newElements); + expect(JSON.parse(result)).toEqual(inp); + } else { + inp.splice(start); + expect(JSON.parse(result)).toEqual(inp); + } +}); + +test.each([ + { arr: [], args: [[]] }, + { arr: [1, 2, 3], args: [[]] }, + { arr: [1, 2, 3], args: [[4]] }, + { arr: [1, 2, 3], args: [[4, 5]] }, + { arr: [1, 2, 3], args: [[4, 5]] }, + { arr: [1, 2, 3], args: [4, [5]] }, + { arr: [1, 2, 3], args: [4, [5, 6]] }, + { arr: [1, 2, 3], args: [4, [5, 6], 7] }, + { arr: [1, 2, 3], args: ["test", [5, 6], 7, ["test1", "test2"]] }, + { arr: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, +])("array.concat (%p)", ({ arr, args }: { arr: any[]; args: any[] }) => { + const argStr = args.map(arg => JSON.stringify(arg)).join(","); + + const result = util.transpileAndExecute( + `let concatTestTable: any[] = ${JSON.stringify(arr)}; + return JSONStringify(concatTestTable.concat(${argStr}));` + ); + + const concatArr = arr.concat(...args); + expect(JSON.parse(result)).toEqual(concatArr); +}); + +test.each([ + { inp: [] }, + { inp: ["test1"] }, + { inp: ["test1", "test2"] }, + { inp: ["test1", "test2"], separator: ";" }, + { inp: ["test1", "test2"], separator: "" }, +])("array.join (%p)", ({ inp, separator }) => { + let separatorLua; + if (separator === "") { + separatorLua = '""'; + } else if (separator) { + separatorLua = '"' + separator + '"'; + } else { + separatorLua = ""; + } + const result = util.transpileAndExecute( + `let joinTestTable = ${JSON.stringify(inp)}; + return joinTestTable.join(${separatorLua});` + ); + + expect(result).toEqual(inp.join(separator)); +}); + +test.each([ + { inp: [], element: "test1" }, + { inp: ["test1"], element: "test1" }, + { inp: ["test1", "test2"], element: "test2" }, + { inp: ["test1", "test2", "test3"], element: "test3", fromIndex: 1 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 2 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: -2 }, + { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 12 }, +])("array.indexOf (%p)", ({ inp, element, fromIndex }) => { + let str = `return ${JSON.stringify(inp)}.indexOf("${element}");`; + if (fromIndex) { + str = `return ${JSON.stringify(inp)}.indexOf("${element}", ${fromIndex});`; + } + + const result = util.transpileAndExecute(str); + + // Account for lua indexing (-1) + expect(result).toEqual(inp.indexOf(element, fromIndex)); +}); + +test.each([{ inp: [1, 2, 3], expected: 3 }, { inp: [1, 2, 3, 4, 5], expected: 3 }])( + "array.destructuring.simple (%p)", + ({ inp, expected }) => { + const result = util.transpileAndExecute( + `let [x, y, z] = ${JSON.stringify(inp)} + return z;` + ); + + expect(result).toEqual(expected); + } +); + +test.each([{ inp: [1] }, { inp: [1, 2, 3] }])("array.push (%p)", ({ inp }) => { + const result = util.transpileAndExecute( + `let testArray = [0]; + testArray.push(${inp.join(", ")}); + return JSONStringify(testArray);` + ); + + expect(JSON.parse(result)).toEqual([0].concat(inp)); +}); + +test.each([{ array: "[1, 2, 3]", expected: [3, 2] }, { array: "[1, 2, 3, null]", expected: [3, 2] }])( + "array.pop (%p)", + ({ array, expected }) => { + { + const result = util.transpileAndExecute( + `let testArray = ${array}; + let val = testArray.pop(); + return val` + ); + + expect(result).toEqual(expected[0]); + } + { + const result = util.transpileAndExecute( + `let testArray = ${array}; + testArray.pop(); + return testArray.length` + ); + + expect(result).toEqual(expected[1]); + } + } +); + +test.each([ + { array: "[1, 2, 3]", expected: [3, 2, 1] }, + { array: "[1, 2, 3, null]", expected: [3, 2, 1] }, + { array: "[1, 2, 3, 4]", expected: [4, 3, 2, 1] }, + { array: "[1]", expected: [1] }, + { array: "[]", expected: [] }, +])("array.reverse (%p)", ({ array, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + let val = testArray.reverse(); + return JSONStringify(testArray)` + ); + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { array: "[1, 2, 3]", expectedArray: [2, 3], expectedValue: 1 }, + { array: "[1]", expectedArray: [], expectedValue: 1 }, + { array: "[]", expectedArray: [], expectedValue: undefined }, +])("array.shift (%p)", ({ array, expectedArray, expectedValue }) => { + { + // test array mutation + { + const result = util.transpileAndExecute( + `let testArray = ${array}; + let val = testArray.shift(); + return JSONStringify(testArray)` + ); + expect(JSON.parse(result)).toEqual(expectedArray); + } + // test return value + { + const result = util.transpileAndExecute( + `let testArray = ${array}; + let val = testArray.shift(); + return val` + ); + + expect(result).toEqual(expectedValue); + } + } +}); + +test.each([ + { array: "[3, 4, 5]", toUnshift: [1, 2], expected: [1, 2, 3, 4, 5] }, + { array: "[]", toUnshift: [], expected: [] }, + { array: "[1]", toUnshift: [], expected: [1] }, + { array: "[]", toUnshift: [1], expected: [1] }, +])("array.unshift (%p)", ({ array, toUnshift, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + testArray.unshift(${toUnshift}); + return JSONStringify(testArray)` + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { array: "[4, 5, 3, 2, 1]", expected: [1, 2, 3, 4, 5] }, + { array: "[1]", expected: [1] }, + { array: "[1, null]", expected: [1] }, + { array: "[]", expected: [] }, +])("array.sort (%p)", ({ array, expected }) => { + const result = util.transpileAndExecute( + `let testArray = ${array}; + testArray.sort(); + return JSONStringify(testArray)` + ); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { array: [1, 2, 3, 4, 5], compareStr: "a - b", compareFn: (a: any, b: any) => a - b }, + { + array: ["4", "5", "3", "2", "1"], + compareStr: "tonumber(a) - tonumber(b)", + compareFn: (a: any, b: any) => Number(a) - Number(b), + }, + { + array: ["4", "5", "3", "2", "1"], + compareStr: "tonumber(b) - tonumber(a)", + compareFn: (a: any, b: any) => Number(b) - Number(a), + }, +])("array.sort with compare function (%p)", ({ array, compareStr, compareFn }) => { + const result = util.transpileAndExecute( + `let testArray = ${JSON.stringify(array)}; + testArray.sort((a, b) => ${compareStr}); + return JSONStringify(testArray)`, + undefined, + undefined, + `declare function tonumber(this: void, e: any): number` + ); + + expect(JSON.parse(result)).toEqual(array.sort(compareFn)); +}); + +test.each([ + { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, + { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, + { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, + { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, +])("array.flat (%p)", ({ array, depth, expected }) => { + // TODO: Remove once `Infinity` would be implemented + const luaDepth = depth === Infinity ? "1 / 0" : depth; + const result = util.transpileAndExecute(` + return JSONStringify(${JSON.stringify(array)}.flat(${luaDepth})) + `); + + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, + { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, + { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, +])("array.flatMap (%p)", ({ array, map, expected }) => { + const result = util.transpileAndExecute(` + const array = ${JSON.stringify(array)}; + const result = array.flatMap(${map.toString()}); + return JSONStringify(result); + `); + + // TODO(node 12): array.flatMap(map) + expect(JSON.parse(result)).toEqual(expected); +}); + +test.each([ + (total: number, currentItem: number) => total + currentItem, + (total: number, currentItem: number) => total * currentItem, +])("array reduce (%p)", reducer => { + const array = [1, 3, 5, 7]; + + const result = util.transpileAndExecute(` + const myArray = ${JSON.stringify(array)}; + return myArray.reduce(${reducer.toString()}); + `); + + expect(result).toEqual(array.reduce(reducer)); +}); + +test.each([ + (total: number, currentItem: number) => total + currentItem, + (total: number, currentItem: number) => total * currentItem, +])("array reduce with initial value (%p)", reducer => { + const array = [1, 3, 5, 7]; + const initial = 10; + + const result = util.transpileAndExecute(` + const myArray = ${JSON.stringify(array)}; + return myArray.reduce(${reducer.toString()}, ${initial}); + `); + + expect(result).toEqual(array.reduce(reducer, initial)); +}); + +test("array reduce index & array arguments (%p)", () => { + const array = [1, 3, 5, 7]; + const reducer = (total: number, _: number, index: number, array: number[]) => total + array[index]; + + const result = util.transpileAndExecute(` + const myArray = ${JSON.stringify(array)}; + return myArray.reduce(${reducer.toString()}); + `); + + expect(result).toEqual(array.reduce(reducer)); +}); + +test("array reduce index & array arguments (%p)", () => { + expect(() => { + util.transpileAndExecute("return [].reduce((a, b) => a + b);"); + }).toThrow("Reduce of empty array with no initial value"); +}); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index f2b5db912..f7f2b5538 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -1,408 +1,5 @@ import * as util from "../../util"; -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forEach (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - arrTest.forEach((elem, index) => { - arrTest[index] = arrTest[index] + 1; - }) - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); -}); - -test.each([ - { inp: [], searchEl: 3, expected: -1 }, - { inp: [0, 2, 4, 8], searchEl: 10, expected: -1 }, - { inp: [0, 2, 4, 8], searchEl: 8, expected: 3 }, -])("array.findIndex[value] (%p)", ({ inp, searchEl, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index) => { - return elem === ${searchEl}; - }));` - ); - - expect(result).toBe(expected); -}); - -test.each([{ inp: [0, 2, 4, 8], expected: 3, value: 8 }, { inp: [0, 2, 4, 8], expected: 1, value: 2 }])( - "array.findIndex[index] (%p)", - ({ inp, expected, value }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index, arr) => { - return index === ${expected} && arr[${expected}] === ${value}; - }));` - ); - - expect(result).toBe(expected); - } -); - -test.each([ - { inp: [], func: "x => x" }, - { inp: [0, 1, 2, 3], func: "x => x" }, - { inp: [0, 1, 2, 3], func: "x => x*2" }, - { inp: [1, 2, 3, 4], func: "x => -x" }, - { inp: [0, 1, 2, 3], func: "x => x+2" }, - { inp: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, -])("array.map (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].map(${func}))`); - - expect(result).toBe(JSON.stringify(inp.map(eval(func)))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x < 3" }, - { inp: [0, 1, 2, 3], func: "x => x < 0" }, - { inp: [0, -1, -2, -3], func: "x => x < 0" }, - { inp: [0, 1, 2, 3], func: "() => true" }, - { inp: [0, 1, 2, 3], func: "() => false" }, -])("array.filter (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].filter(${func}))`); - - expect(result).toBe(JSON.stringify(inp.filter(eval(func)))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [false, true, false], func: "x => x" }, - { inp: [true, true, true], func: "x => x" }, -])("array.every (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].every(${func}))`); - - expect(result).toBe(JSON.stringify(inp.every(eval(func)))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [false, true, false], func: "x => x" }, - { inp: [true, true, true], func: "x => x" }, -])("array.some (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].some(${func}))`); - - expect(result).toBe(JSON.stringify(inp.some(eval(func)))); -}); - -test.each([ - { inp: [], start: 1, end: 2 }, - { inp: [0, 1, 2, 3], start: 1, end: 2 }, - { inp: [0, 1, 2, 3], start: 1, end: 1 }, - { inp: [0, 1, 2, 3], start: 1, end: -1 }, - { inp: [0, 1, 2, 3], start: -3, end: -1 }, - { inp: [0, 1, 2, 3, 4, 5], start: 1, end: 3 }, - { inp: [0, 1, 2, 3, 4, 5], start: 3 }, -])("array.slice (%p)", ({ inp, start, end }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`); - - expect(result).toBe(JSON.stringify(inp.slice(start, end))); -}); - -test.each([ - { inp: [], start: 0, deleteCount: 0, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 1, deleteCount: 0, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 2, deleteCount: 2, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 4, deleteCount: 1, newElements: [8, 9] }, - { inp: [0, 1, 2, 3], start: 4, deleteCount: 0, newElements: [8, 9] }, - { inp: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, - { inp: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, -])("array.splice[Insert] (%p)", ({ inp, start, deleteCount, newElements }) => { - const result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` - ); - - inp.splice(start, deleteCount, ...newElements); - expect(result).toBe(JSON.stringify(inp)); -}); - -test.each([ - { inp: [], start: 1, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 1, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 10, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 4 }, - { inp: [0, 1, 2, 3, 4, 5], start: 3 }, - { inp: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, - { inp: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, -])("array.splice[Remove] (%p)", ({ inp, start, deleteCount, newElements = [] }) => { - let result; - if (deleteCount) { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` - ); - } else { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}); - return JSONStringify(spliceTestTable);` - ); - } - - if (deleteCount) { - inp.splice(start, deleteCount, ...newElements); - expect(result).toBe(JSON.stringify(inp)); - } else { - inp.splice(start); - expect(result).toBe(JSON.stringify(inp)); - } -}); - -test.each([ - { arr: [], args: [[]] }, - { arr: [1, 2, 3], args: [[]] }, - { arr: [1, 2, 3], args: [[4]] }, - { arr: [1, 2, 3], args: [[4, 5]] }, - { arr: [1, 2, 3], args: [[4, 5]] }, - { arr: [1, 2, 3], args: [4, [5]] }, - { arr: [1, 2, 3], args: [4, [5, 6]] }, - { arr: [1, 2, 3], args: [4, [5, 6], 7] }, - { arr: [1, 2, 3], args: ["test", [5, 6], 7, ["test1", "test2"]] }, - { arr: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, -])("array.concat (%p)", ({ arr, args }: { arr: any[]; args: any[] }) => { - const argStr = args.map(arg => JSON.stringify(arg)).join(","); - - const result = util.transpileAndExecute( - `let concatTestTable: any[] = ${JSON.stringify(arr)}; - return JSONStringify(concatTestTable.concat(${argStr}));` - ); - - const concatArr = arr.concat(...args); - expect(result).toBe(JSON.stringify(concatArr)); -}); - -test.each([ - { inp: [] }, - { inp: ["test1"] }, - { inp: ["test1", "test2"] }, - { inp: ["test1", "test2"], separator: ";" }, - { inp: ["test1", "test2"], separator: "" }, -])("array.join (%p)", ({ inp, separator }) => { - let separatorLua; - if (separator === "") { - separatorLua = '""'; - } else if (separator) { - separatorLua = '"' + separator + '"'; - } else { - separatorLua = ""; - } - const result = util.transpileAndExecute( - `let joinTestTable = ${JSON.stringify(inp)}; - return joinTestTable.join(${separatorLua});` - ); - - const joinedInp = inp.join(separator); - expect(result).toBe(joinedInp); -}); - -test.each([ - { inp: [], element: "test1" }, - { inp: ["test1"], element: "test1" }, - { inp: ["test1", "test2"], element: "test2" }, - { inp: ["test1", "test2", "test3"], element: "test3", fromIndex: 1 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 2 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: -2 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 12 }, -])("array.indexOf (%p)", ({ inp, element, fromIndex }) => { - let str = `return ${JSON.stringify(inp)}.indexOf("${element}");`; - if (fromIndex) { - str = `return ${JSON.stringify(inp)}.indexOf("${element}", ${fromIndex});`; - } - - const result = util.transpileAndExecute(str); - - // Account for lua indexing (-1) - expect(result).toBe(inp.indexOf(element, fromIndex)); -}); - -test.each([{ inp: [1, 2, 3], expected: 3 }, { inp: [1, 2, 3, 4, 5], expected: 3 }])( - "array.destructuring.simple (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let [x, y, z] = ${JSON.stringify(inp)} - return z;` - ); - - expect(result).toBe(expected); - } -); - -test.each([{ inp: [1] }, { inp: [1, 2, 3] }])("array.push (%p)", ({ inp }) => { - const result = util.transpileAndExecute( - `let testArray = [0]; - testArray.push(${inp.join(", ")}); - return JSONStringify(testArray);` - ); - - expect(result).toBe(JSON.stringify([0].concat(inp))); -}); - -test.each([{ array: "[1, 2, 3]", expected: [3, 2] }, { array: "[1, 2, 3, null]", expected: [3, 2] }])( - "array.pop (%p)", - ({ array, expected }) => { - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.pop(); - return val` - ); - - expect(result).toBe(expected[0]); - } - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.pop(); - return testArray.length` - ); - - expect(result).toBe(expected[1]); - } - } -); - -test.each([ - { array: "[1, 2, 3]", expected: [3, 2, 1] }, - { array: "[1, 2, 3, null]", expected: [3, 2, 1] }, - { array: "[1, 2, 3, 4]", expected: [4, 3, 2, 1] }, - { array: "[1]", expected: [1] }, - { array: "[]", expected: [] }, -])("array.reverse (%p)", ({ array, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.reverse(); - return JSONStringify(testArray)` - ); - expect(result).toBe(JSON.stringify(expected)); -}); - -test.each([ - { array: "[1, 2, 3]", expectedArray: [2, 3], expectedValue: 1 }, - { array: "[1]", expectedArray: [], expectedValue: 1 }, - { array: "[]", expectedArray: [], expectedValue: undefined }, -])("array.shift (%p)", ({ array, expectedArray, expectedValue }) => { - { - // test array mutation - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return JSONStringify(testArray)` - ); - expect(result).toBe(JSON.stringify(expectedArray)); - } - // test return value - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return val` - ); - - expect(result).toBe(expectedValue); - } - } -}); - -test.each([ - { array: "[3, 4, 5]", toUnshift: [1, 2], expected: [1, 2, 3, 4, 5] }, - { array: "[]", toUnshift: [], expected: [] }, - { array: "[1]", toUnshift: [], expected: [1] }, - { array: "[]", toUnshift: [1], expected: [1] }, -])("array.unshift (%p)", ({ array, toUnshift, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.unshift(${toUnshift}); - return JSONStringify(testArray)` - ); - - expect(result).toBe(JSON.stringify(expected)); -}); - -test.each([ - { array: "[4, 5, 3, 2, 1]", expected: [1, 2, 3, 4, 5] }, - { array: "[1]", expected: [1] }, - { array: "[1, null]", expected: [1] }, - { array: "[]", expected: [] }, -])("array.sort (%p)", ({ array, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.sort(); - return JSONStringify(testArray)` - ); - - expect(result).toBe(JSON.stringify(expected)); -}); - -test.each([ - { - array: [1, 2, 3, 4, 5], - compareStr: "a - b", - compareFn: (a: any, b: any) => a - b, - }, - { - array: ["4", "5", "3", "2", "1"], - compareStr: "tonumber(a) - tonumber(b)", - compareFn: (a: any, b: any) => Number(a) - Number(b), - }, - { - array: ["4", "5", "3", "2", "1"], - compareStr: "tonumber(b) - tonumber(a)", - compareFn: (a: any, b: any) => Number(b) - Number(a), - }, -])("array.sort with compare function (%p)", ({ array, compareStr, compareFn }) => { - const result = util.transpileAndExecute( - `let testArray = ${JSON.stringify(array)}; - testArray.sort((a, b) => ${compareStr}); - return JSONStringify(testArray)`, - undefined, - undefined, - `declare function tonumber(this: void, e: any): number` - ); - - expect(result).toBe(JSON.stringify(array.sort(compareFn))); -}); - -test.each([ - { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, - { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, - { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, - { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, -])("array.flat (%p)", ({ array, depth, expected }) => { - // TODO: Remove once `Infinity` would be implemented - const luaDepth = depth === Infinity ? "1 / 0" : depth; - const result = util.transpileAndExecute(` - return JSONStringify(${JSON.stringify(array)}.flat(${luaDepth})) - `); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, - { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, - { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, -])("array.flatMap (%p)", ({ array, map, expected }) => { - const result = util.transpileAndExecute(` - const array = ${JSON.stringify(array)}; - const result = array.flatMap(${map.toString()}); - return JSONStringify(result); - `); - - // TODO(node 12): array.flatMap(map) - expect(JSON.parse(result)).toEqual(expected); -}); - test.each([ { condition: "true", lhs: "4", rhs: "5", expected: 4 }, { condition: "false", lhs: "4", rhs: "5", expected: 5 }, From 8a7b31b6f912b0f501c3c728507141679dcac115 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 27 May 2019 21:37:31 +0200 Subject: [PATCH 097/764] Added support for importequals declaration (#598) * Added support for importequals declaration * made importequalsdeclaration hoistable * Got rid of a visitor method and used getIdentifierText * Changed transformIdentifier to transformIdentifierExpression * Added test with import equals and require * Prettier format --- src/LuaTransformer.ts | 36 ++++++++++++++++++++++++- test/unit/declarations.spec.ts | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 2319f7548..cd88c9553 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -159,6 +159,8 @@ export class LuaTransformer { return this.transformExportDeclaration(node as ts.ExportDeclaration); case ts.SyntaxKind.ImportDeclaration: return this.transformImportDeclaration(node as ts.ImportDeclaration); + case ts.SyntaxKind.ImportEqualsDeclaration: + return this.transformImportEqualsDeclaration(node as ts.ImportEqualsDeclaration); case ts.SyntaxKind.ClassDeclaration: return this.transformClassDeclaration(node as ts.ClassDeclaration); case ts.SyntaxKind.ModuleDeclaration: @@ -458,6 +460,38 @@ export class LuaTransformer { } } + public transformImportEqualsDeclaration(declaration: ts.ImportEqualsDeclaration): StatementVisitResult { + const name = this.transformIdentifier(declaration.name); + const expression = ts.isExternalModuleReference(declaration.moduleReference) + ? this.transformExternalModuleReference(declaration.moduleReference) + : this.transformEntityName(declaration.moduleReference); + + return this.createHoistableVariableDeclarationStatement(name, expression, declaration); + } + + public transformExternalModuleReference( + externalModuleReference: ts.ExternalModuleReference + ): ExpressionVisitResult { + return tstl.createCallExpression( + tstl.createIdentifier("require"), + [this.transformExpression(externalModuleReference.expression)], + externalModuleReference + ); + } + + private transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { + return ts.isQualifiedName(entityName) + ? this.transformQualifiedName(entityName) + : this.transformIdentifierExpression(entityName); + } + + public transformQualifiedName(qualifiedName: ts.QualifiedName): ExpressionVisitResult { + const right = tstl.createStringLiteral(this.getIdentifierText(qualifiedName.right), qualifiedName.right); + const left = this.transformEntityName(qualifiedName.left); + + return tstl.createTableIndexExpression(left, right, qualifiedName); + } + public transformClassDeclaration( statement: ts.ClassLikeDeclaration, nameOverride?: tstl.Identifier @@ -3755,7 +3789,7 @@ export class LuaTransformer { } public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = expression.name.text; + const property = this.getIdentifierText(expression.name); // Check for primitive types to override const type = this.checker.getTypeAtLocation(expression.expression); diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts index a4181b009..d0245dae0 100644 --- a/test/unit/declarations.spec.ts +++ b/test/unit/declarations.spec.ts @@ -92,3 +92,51 @@ test("Declaration instance function callback", () => { const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); expect(result).toBe(20); }); + +test("ImportEquals declaration", () => { + const header = ` + namespace outerNamespace { + export namespace innerNamespace { + export function func() { return "foo" } + } + }; + + import importedFunc = outerNamespace.innerNamespace.func; + `; + + const execution = `return importedFunc();`; + + const result = util.transpileAndExecute(execution, undefined, undefined, header); + expect(result).toEqual("foo"); +}); + +test("ImportEquals declaration ambient", () => { + const header = ` + declare namespace outerNamespace { + namespace innerNamespace { + function func(): string; + } + }; + + import importedFunc = outerNamespace.innerNamespace.func; + `; + + const luaHeader = `outerNamespace = { + innerNamespace = { + func = function() return "foo" end + } + } + `; + + const execution = `return importedFunc();`; + + const result = util.transpileAndExecute(execution, undefined, luaHeader, header); + expect(result).toEqual("foo"); +}); + +test("ImportEquals declaration require", () => { + const source = `import foo = require("bar");`; + + const result = util.transpileString(source); + expect(result.includes(`local foo = require("bar")`)).toBeTruthy(); +}); From 4b92ad50f7a71512e0c7e48f13592e2a98ff7bb1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 27 May 2019 21:41:51 +0200 Subject: [PATCH 098/764] 0.21.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a7dbc4de9..e673e458e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.20.0", + "version": "0.21.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index aaa0e27b8..79b743d3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.20.0", + "version": "0.21.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 3ec89e46fd455b3332b80a5e19b54101b42db2bc Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 27 May 2019 21:56:13 +0200 Subject: [PATCH 099/764] Update CHANGELOG.md 0.21.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e7eab90af..de02da036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.21.0 + +- Imports/exports that are ambient (declarations, types, interfaces, etc) or are not used in value positions no longer generate `require` statements. +- For ... of loops are now translated using `ipairs`. +- Added support for `array.reduce`. +- Added support for `import foo = bar.baz;` statements. + +- Fixed some issues with binding pattern parameter default values. +- Fixed some issues with variable naming. +- Enabled prettier on the entire codebase. + ## 0.20.0 - Added support for `string.repeat`, `string.padStart` and `string.padEnd`. From cc5c472ea0ac59ab187a38a3e634f252e211df45 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 29 May 2019 18:01:48 +0500 Subject: [PATCH 100/764] Improve `import =` require behavior (#608) --- src/LuaTransformer.ts | 34 ++++++++++++++++++++++++++-------- test/unit/declarations.spec.ts | 15 ++++----------- test/unit/modules.spec.ts | 14 +++++++++++++- test/unit/require.spec.ts | 19 +++++++++++++++---- 4 files changed, 58 insertions(+), 24 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index cd88c9553..bb269d570 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -42,6 +42,7 @@ interface Scope { export interface EmitResolver { isValueAliasDeclaration(node: ts.Node): boolean; isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; + isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; } @@ -462,9 +463,29 @@ export class LuaTransformer { public transformImportEqualsDeclaration(declaration: ts.ImportEqualsDeclaration): StatementVisitResult { const name = this.transformIdentifier(declaration.name); - const expression = ts.isExternalModuleReference(declaration.moduleReference) - ? this.transformExternalModuleReference(declaration.moduleReference) - : this.transformEntityName(declaration.moduleReference); + let expression: tstl.Expression; + if (ts.isExternalModuleReference(declaration.moduleReference)) { + if (!this.resolver.isReferencedAliasDeclaration(declaration)) { + return undefined; + } + + expression = this.transformExternalModuleReference(declaration.moduleReference); + } else { + if (this.currentSourceFile === undefined) { + throw TSTLErrors.MissingSourceFile(); + } + + const shouldEmit = + this.resolver.isReferencedAliasDeclaration(declaration) || + (!ts.isExternalModule(this.currentSourceFile) && + this.resolver.isTopLevelValueImportEqualsWithEntityName(declaration)); + + if (!shouldEmit) { + return undefined; + } + + expression = this.transformEntityName(declaration.moduleReference); + } return this.createHoistableVariableDeclarationStatement(name, expression, declaration); } @@ -472,11 +493,8 @@ export class LuaTransformer { public transformExternalModuleReference( externalModuleReference: ts.ExternalModuleReference ): ExpressionVisitResult { - return tstl.createCallExpression( - tstl.createIdentifier("require"), - [this.transformExpression(externalModuleReference.expression)], - externalModuleReference - ); + // TODO: Should `externalModuleReference` be original node? + return this.createModuleRequire(externalModuleReference.expression as ts.StringLiteral); } private transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts index d0245dae0..415153e2c 100644 --- a/test/unit/declarations.spec.ts +++ b/test/unit/declarations.spec.ts @@ -100,7 +100,7 @@ test("ImportEquals declaration", () => { export function func() { return "foo" } } }; - + import importedFunc = outerNamespace.innerNamespace.func; `; @@ -117,12 +117,12 @@ test("ImportEquals declaration ambient", () => { function func(): string; } }; - + import importedFunc = outerNamespace.innerNamespace.func; `; - const luaHeader = `outerNamespace = { - innerNamespace = { + const luaHeader = `outerNamespace = { + innerNamespace = { func = function() return "foo" end } } @@ -133,10 +133,3 @@ test("ImportEquals declaration ambient", () => { const result = util.transpileAndExecute(execution, undefined, luaHeader, header); expect(result).toEqual("foo"); }); - -test("ImportEquals declaration require", () => { - const source = `import foo = require("bar");`; - - const result = util.transpileString(source); - expect(result.includes(`local foo = require("bar")`)).toBeTruthy(); -}); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index c47409707..2c60c7e7a 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -1,3 +1,4 @@ +import * as ts from "typescript"; import * as tstl from "../../src"; import { TSTLErrors } from "../../src/TSTLErrors"; import * as util from "../util"; @@ -11,7 +12,11 @@ describe("module import/export elision", () => { `; const expectToElideImport = (code: string) => { - const lua = util.transpileString({ "module.d.ts": moduleDeclaration, "main.ts": code }, undefined, false); + const lua = util.transpileString( + { "module.d.ts": moduleDeclaration, "main.ts": code }, + { module: ts.ModuleKind.CommonJS }, + false + ); expect(() => util.executeLua(lua)).not.toThrow(); }; @@ -37,6 +42,13 @@ describe("module import/export elision", () => { `); }); + test("should elide `import =` declarations", () => { + expectToElideImport(` + import module = require("module"); + const foo: module.Type = "bar"; + `); + }); + test("should elide type exports", () => { const code = ` declare const _G: any; diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index bb9903a1b..b6db8f877 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -1,5 +1,8 @@ +import * as ts from "typescript"; import * as util from "../util"; +const requireRegex = /require\("(.*?)"\)/; + test.each([ { filePath: "main.ts", @@ -79,8 +82,7 @@ test.each([ expect(() => util.transpileString(input, options)).toThrow(); } else { const lua = util.transpileString(input, options); - const regex = /require\("(.*?)"\)/; - const match = regex.exec(lua); + const match = requireRegex.exec(lua); if (util.expectToBeDefined(match)) { expect(match[1]).toBe(expectedPath); @@ -96,11 +98,20 @@ test.each([{ comment: "", expectedPath: "src.fake" }, { comment: "/** @noResolut "src/main.ts": `import * as fake from "fake"; fake;`, "module.d.ts": `${comment} declare module "fake" {}`, }); - const regex = /require\("(.*?)"\)/; - const match = regex.exec(lua); + const match = requireRegex.exec(lua); if (util.expectToBeDefined(match)) { expect(match[1]).toBe(expectedPath); } } ); + +test("ImportEquals declaration require", () => { + const input = `import foo = require("./foo/bar"); foo;`; + + const lua = util.transpileString(input, { module: ts.ModuleKind.CommonJS }); + const match = requireRegex.exec(lua); + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe("foo.bar"); + } +}); From 6db5684b8a19f5a0f5bd6226caf91ac9799facb1 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 1 Jun 2019 05:53:15 -0600 Subject: [PATCH 101/764] Handling exports referenced in different scopes (#618) * Handling exports referenced in different scopes fixes #617 Exported identifiers referenced in other places were not checking what scope they were declared in when prepending their export table. This led to a notable amount of refactoring to clean up the situation. * simplified transformModuleDeclaration further --- src/LuaTransformer.ts | 201 ++++++++++++++++------------------ src/TSHelper.ts | 8 ++ test/unit/identifiers.spec.ts | 47 ++++++++ 3 files changed, 150 insertions(+), 106 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index bb269d570..8a5fac2ea 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -544,7 +544,7 @@ export class LuaTransformer { throw TSTLErrors.InvalidExtensionMetaExtension(statement); } - if ((isExtension || isMetaExtension) && this.isIdentifierExported(className)) { + if ((isExtension || isMetaExtension) && this.getIdentifierExportScope(className) !== undefined) { // Cannot export extension classes throw TSTLErrors.InvalidExportsExtension(statement); } @@ -772,12 +772,13 @@ export class LuaTransformer { const classVar = this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); result.push(...classVar); - if (this.isIdentifierExported(className)) { + const exportScope = this.getIdentifierExportScope(className); + if (exportScope) { // local localClassName = ____exports.className result.push( tstl.createVariableDeclarationStatement( localClassName, - this.addExportToIdentifier(tstl.cloneIdentifier(className)) + this.createExportedIdentifier(tstl.cloneIdentifier(className), exportScope) ) ); } @@ -1500,9 +1501,7 @@ export class LuaTransformer { : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); if (element.initializer) { - const identifier = this.shouldExportIdentifier(variableName) - ? this.createExportedIdentifier(variableName) - : variableName; + const identifier = this.addExportToIdentifier(variableName); result.push( tstl.createIfStatement( tstl.createBinaryExpression( @@ -1561,57 +1560,23 @@ export class LuaTransformer { const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); if (isFirstDeclaration) { - const isExported = (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; - if (isExported && this.currentNamespace) { - // outerNS.innerNS = {} - const namespaceDeclaration = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createModuleLocalNameIdentifier(this.currentNamespace), - tstl.createStringLiteral(nameIdentifier.text) - ), - tstl.createTableExpression() - ); - - result.push(namespaceDeclaration); - - if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { - // local innerNS = outerNS.innerNS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - this.createModuleLocalNameIdentifier(statement), - tstl.createTableIndexExpression( - this.createModuleLocalNameIdentifier(this.currentNamespace), - tstl.createStringLiteral(nameIdentifier.text) - ) - ); - - result.push(localDeclaration); - } - } else if (isExported && !this.currentNamespace && this.isModule) { - // exports.NS = {} - const namespaceDeclaration = tstl.createAssignmentStatement( - this.createExportedIdentifier(nameIdentifier), - tstl.createTableExpression() - ); - - result.push(namespaceDeclaration); + // local NS = {} or exportTable.NS = {} + const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( + nameIdentifier, + tstl.createTableExpression() + ); - if (hasExports && tsHelper.moduleHasEmittedBody(statement)) { - // local NS = exports.NS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - this.createModuleLocalNameIdentifier(statement), - this.createExportedIdentifier(tstl.cloneIdentifier(nameIdentifier, statement.name)) - ); + result.push(...localDeclaration); - result.push(localDeclaration); - } - } else { - // local NS = {} - const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( + const exportScope = this.getIdentifierExportScope(nameIdentifier); + if (exportScope && hasExports && tsHelper.moduleHasEmittedBody(statement)) { + // local NS = exportTable.NS + const localDeclaration = this.createHoistableVariableDeclarationStatement( this.createModuleLocalNameIdentifier(statement), - tstl.createTableExpression() + this.createExportedIdentifier(nameIdentifier, exportScope) ); - result.push(...localDeclaration); + result.push(localDeclaration); } } @@ -1985,9 +1950,7 @@ export class LuaTransformer { statement.name.elements.forEach(element => { if (!ts.isOmittedExpression(element) && element.initializer) { const variableName = this.transformIdentifier(element.name as ts.Identifier); - const identifier = this.shouldExportIdentifier(variableName) - ? this.createExportedIdentifier(variableName) - : variableName; + const identifier = this.addExportToIdentifier(variableName); statements.push( tstl.createIfStatement( tstl.createBinaryExpression( @@ -3347,10 +3310,7 @@ export class LuaTransformer { properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); - let identifier = this.createShorthandIdentifier(valueSymbol, element.name); - if (tstl.isIdentifier(identifier) && valueSymbol !== undefined && this.isSymbolExported(valueSymbol)) { - identifier = this.createExportedIdentifier(identifier); - } + const identifier = this.createShorthandIdentifier(valueSymbol, element.name); properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { const expression = this.transformFunctionExpression(element); @@ -4640,8 +4600,10 @@ export class LuaTransformer { private transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { const identifier = this.transformIdentifier(expression); - if (this.isIdentifierExported(identifier)) { - return this.createExportedIdentifier(identifier); + + const exportScope = this.getIdentifierExportScope(identifier); + if (exportScope) { + return this.createExportedIdentifier(identifier, exportScope); } switch (this.getIdentifierText(expression)) { @@ -4664,28 +4626,44 @@ export class LuaTransformer { return identifier; } - protected isIdentifierExported(identifier: tstl.Identifier): boolean { - const symbolInfo = identifier.symbolId && this.symbolInfo.get(identifier.symbolId); - if (!symbolInfo) { - return false; + protected getSymbolFromIdentifier(identifier: tstl.Identifier): ts.Symbol | undefined { + if (identifier.symbolId !== undefined) { + const symbolInfo = this.symbolInfo.get(identifier.symbolId); + if (symbolInfo !== undefined) { + return symbolInfo.symbol; + } + } + return undefined; + } + + protected getIdentifierExportScope(identifier: tstl.Identifier): ts.SourceFile | ts.ModuleDeclaration | undefined { + const symbol = this.getSymbolFromIdentifier(identifier); + if (!symbol) { + return undefined; } - return this.isSymbolExported(symbolInfo.symbol); + return this.getSymbolExportScope(symbol); } protected isSymbolExported(symbol: ts.Symbol): boolean { - if (!this.isModule && !this.currentNamespace) { + if (tsHelper.getExportedSymbolDeclaration(symbol) !== undefined) { + return true; + } else if (this.currentSourceFile) { + // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') + return this.isSymbolExportedFromScope(symbol, this.currentSourceFile); + } else { return false; } + } - const currentScope = this.currentNamespace ? this.currentNamespace : this.currentSourceFile; - if (currentScope === undefined) { - throw TSTLErrors.UndefinedScope(); + protected isSymbolExportedFromScope(symbol: ts.Symbol, scope: ts.SourceFile | ts.ModuleDeclaration): boolean { + if (ts.isSourceFile(scope) && !tsHelper.isFileModule(scope)) { + return false; } - let scopeSymbol = this.checker.getSymbolAtLocation(currentScope); + let scopeSymbol = this.checker.getSymbolAtLocation(scope); if (scopeSymbol === undefined) { - scopeSymbol = this.checker.getTypeAtLocation(currentScope).getSymbol(); + scopeSymbol = this.checker.getTypeAtLocation(scope).getSymbol(); } if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { @@ -4705,25 +4683,43 @@ export class LuaTransformer { } protected addExportToIdentifier(identifier: tstl.Identifier): tstl.AssignmentLeftHandSideExpression { - if (this.isIdentifierExported(identifier)) { - return this.createExportedIdentifier(identifier); + const exportScope = this.getIdentifierExportScope(identifier); + if (exportScope) { + return this.createExportedIdentifier(identifier, exportScope); } return identifier; } - protected createExportedIdentifier(identifier: tstl.Identifier): tstl.TableIndexExpression { - let exportTable: tstl.Identifier; - if (this.currentNamespace !== undefined) { - if (this.isUnsafeName(this.currentNamespace.name.text)) { - exportTable = this.createModuleLocalNameIdentifier(this.currentNamespace); - } else { - exportTable = this.transformIdentifier(this.currentNamespace.name as ts.Identifier); - } - } else { - exportTable = this.createExportsIdentifier(); + protected createExportedIdentifier( + identifier: tstl.Identifier, + exportScope?: ts.SourceFile | ts.ModuleDeclaration + ): tstl.AssignmentLeftHandSideExpression { + const exportTable = + exportScope && ts.isModuleDeclaration(exportScope) + ? this.createModuleLocalNameIdentifier(exportScope) + : this.createExportsIdentifier(); + return tstl.createTableIndexExpression(exportTable, tstl.createStringLiteral(identifier.text)); + } + + protected getSymbolExportScope(symbol: ts.Symbol): ts.SourceFile | ts.ModuleDeclaration | undefined { + const exportedDeclaration = tsHelper.getExportedSymbolDeclaration(symbol); + if (!exportedDeclaration) { + return undefined; } - return tstl.createTableIndexExpression(exportTable, tstl.createStringLiteral(identifier.text)); + const scope = tsHelper.findFirstNodeAbove( + exportedDeclaration, + (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) + ); + if (!scope) { + return undefined; + } + + if (!this.isSymbolExportedFromScope(symbol, scope)) { + return undefined; + } + + return scope; } protected transformLuaLibFunction( @@ -4827,17 +4823,6 @@ export class LuaTransformer { return filePath.replace(/\.\//g, "").replace(/\//g, "."); } - protected shouldExportIdentifier(identifier: tstl.Identifier | tstl.Identifier[]): boolean { - if (!this.isModule && !this.currentNamespace) { - return false; - } - if (Array.isArray(identifier)) { - return identifier.some(i => this.isIdentifierExported(i)); - } else { - return this.isIdentifierExported(identifier); - } - } - protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { return tstl.createIdentifier("self", tsOriginal); } @@ -4857,20 +4842,19 @@ export class LuaTransformer { const functionDeclaration = tsOriginal && ts.isFunctionDeclaration(tsOriginal) ? tsOriginal : undefined; - if (this.shouldExportIdentifier(lhs)) { + const identifiers = Array.isArray(lhs) ? lhs : [lhs]; + if (identifiers.length === 0) { + return []; + } + + const exportScope = this.getIdentifierExportScope(identifiers[0]); + if (exportScope) { // exported if (!rhs) { return []; - } else if (Array.isArray(lhs)) { - assignment = tstl.createAssignmentStatement( - lhs.map(i => this.createExportedIdentifier(i)), - rhs, - tsOriginal, - parent - ); } else { assignment = tstl.createAssignmentStatement( - this.createExportedIdentifier(lhs), + identifiers.map(i => this.createExportedIdentifier(i, exportScope)), rhs, tsOriginal, parent @@ -5120,10 +5104,15 @@ export class LuaTransformer { name = this.hasUnsafeIdentifierName(propertyIdentifier) ? this.createSafeName(propertyName) : propertyName; } - const identifier = this.transformIdentifierExpression(ts.createIdentifier(name)); + let identifier = this.transformIdentifierExpression(ts.createIdentifier(name)); tstl.setNodeOriginal(identifier, propertyIdentifier); if (valueSymbol !== undefined && tstl.isIdentifier(identifier)) { identifier.symbolId = this.symbolIds.get(valueSymbol); + + const exportScope = this.getSymbolExportScope(valueSymbol); + if (exportScope) { + identifier = this.createExportedIdentifier(identifier, exportScope); + } } return identifier; } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index ad63e2e19..8d701512b 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -72,6 +72,14 @@ export class TSHelper { ); } + public static getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { + const declarations = symbol.getDeclarations(); + if (declarations) { + return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0); + } + return undefined; + } + public static isDeclaration(node: ts.Node): node is ts.Declaration { return ( ts.isEnumDeclaration(node) || diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 8aa2bc432..e4677c5dc 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -148,6 +148,53 @@ test.each(validTsInvalidLuaNames)("exported values with invalid lua identifier n expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); }); +test("exported identifiers referenced in namespace (%p)", () => { + const code = ` + export const foo = "foobar"; + namespace NS { + export const bar = foo; + } + export const baz = NS.bar;`; + expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); +}); + +test("exported namespace identifiers referenced in different namespace (%p)", () => { + const tsHeader = ` + namespace A { + export const foo = "foobar"; + namespace B { + export const bar = foo; + } + export const baz = B.bar; + }`; + expect(util.transpileAndExecute("return A.baz", undefined, undefined, tsHeader)).toBe("foobar"); +}); + +test("exported identifiers referenced in nested scope (%p)", () => { + const code = ` + export const foo = "foobar"; + namespace A { + export namespace B { + export const bar = foo; + } + } + export const baz = A.B.bar;`; + expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); +}); + +test.each(validTsInvalidLuaNames)( + "exported values with invalid lua identifier names referenced in different scope (%p)", + name => { + const code = ` + export const ${name} = "foobar"; + namespace NS { + export const foo = ${name}; + } + export const bar = NS.foo;`; + expect(util.transpileExecuteAndReturnExport(code, "bar")).toBe("foobar"); + } +); + test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name property", name => { const code = ` class ${name} {} From 25891d517c266d91c1a704273b9f9fd375da05f2 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 2 Jun 2019 06:43:40 -0600 Subject: [PATCH 102/764] fix for parenthesis stripping (#620) * fix for parenthesis-stripping - logic moved to printer - decision to strip is now explicit based on inner expression type to avoid surprises fixes #619 * not operator precedence test --- src/LuaPrinter.ts | 19 +++++- src/LuaTransformer.ts | 5 -- .../__snapshots__/transformation.spec.ts.snap | 4 +- test/unit/expressions.spec.ts | 63 +++++++++++++++++++ 4 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 0792cb7bc..5b1d8a8c4 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -610,8 +610,25 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } + private canStripParenthesis(expression: tstl.Expression): boolean { + return ( + tstl.isParenthesizedExpression(expression) || + tstl.isTableIndexExpression(expression) || + tstl.isCallExpression(expression) || + tstl.isMethodCallExpression(expression) || + tstl.isIdentifier(expression) || + tstl.isNilLiteral(expression) || + tstl.isNumericLiteral(expression) || + tstl.isBooleanLiteral(expression) + ); + } + public printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { - return this.createSourceNode(expression, ["(", this.printExpression(expression.innerExpression), ")"]); + const innerExpression = this.printExpression(expression.innerExpression); + if (this.canStripParenthesis(expression.innerExpression)) { + return this.createSourceNode(expression, innerExpression); + } + return this.createSourceNode(expression, ["(", innerExpression, ")"]); } public printCallExpression(expression: tstl.CallExpression): SourceNode { diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 8a5fac2ea..9f430f290 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3432,11 +3432,6 @@ export class LuaTransformer { } public transformParenthesizedExpression(expression: ts.ParenthesizedExpression): ExpressionVisitResult { - if (ts.isAssertionExpression(expression.expression)) { - // Strip parenthesis from casts - return this.transformExpression(expression.expression); - } - return tstl.createParenthesizedExpression(this.transformExpression(expression.expression), expression); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index ca2e7e42b..448f18106 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -580,7 +580,7 @@ exports[`Transformation (tryCatch) 1`] = ` local ____TS_try, er = pcall(function() local a = 42 end) - if not (____TS_try) then + if not ____TS_try then local b = \\"fail\\" end end" @@ -591,7 +591,7 @@ exports[`Transformation (tryCatchFinally) 1`] = ` local ____TS_try, er = pcall(function() local a = 42 end) - if not (____TS_try) then + if not ____TS_try then local b = \\"fail\\" end do diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 23d137f50..b19d029c9 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -527,3 +527,66 @@ test.each([ `; expect(util.transpileAndExecute(code)).toBe(1); }); + +test("binary expression with 'as' type assertion wrapped in parenthesis", () => { + expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); +}); + +test.each([ + "(x as any).foo;", + "(y.x as any).foo;", + "(y['x'] as any).foo;", + "(z() as any).foo;", + "(y.z() as any).foo;", + "(x).foo;", + "(y.x).foo;", + "(y['x']).foo;", + "(z()).foo;", + "(y.z()).foo;", + "(x as unknown as any).foo;", + "(x as any).foo;", + "((x as unknown) as any).foo;", + "((x) as any).foo;", +])("'as' type assertion should strip parenthesis (%p)", expression => { + const code = ` + declare let x: unknown; + declare let y: { x: unknown; z(this: void): unknown; }; + declare function z(this: void): unknown; + ${expression}`; + + const lua = util.transpileString(code, undefined, false); + expect(lua).not.toMatch(/\(.+\)/); +}); + +test.each([ + "(x + 1 as any).foo;", + "(!x as any).foo;", + "(x ** 2 as any).foo;", + "(x < 2 as any).foo;", + "(x in y as any).foo;", + "(x + 1).foo;", + "(!x).foo;", + "(x + 1 as unknown as any).foo;", + "((x + 1 as unknown) as any).foo;", + "(!x as unknown as any).foo;", + "((!x as unknown) as any).foo;", + "(!x as any).foo;", + "((!x) as any).foo;", +])("'as' type assertion should not strip parenthesis (%p)", expression => { + const code = ` + declare let x: number; + declare let y: {}; + ${expression}`; + + const lua = util.transpileString(code, undefined, false); + expect(lua).toMatch(/\(.+\)/); +}); + +test("not operator precedence (%p)", () => { + const code = ` + const a = true; + const b = false; + return !a && b;`; + + expect(util.transpileAndExecute(code)).toBe(false); +}); From 9a58560ced85b35acee0048dfd5bb8df75e397de Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 2 Jun 2019 14:49:27 +0200 Subject: [PATCH 103/764] 0.21.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e673e458e..d2b7cc9f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.21.0", + "version": "0.21.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 79b743d3d..a893caeaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.21.0", + "version": "0.21.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From cc5c0a0723f48613373d6ff8d9e3436f61426eb9 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 3 Jun 2019 03:17:23 -0600 Subject: [PATCH 104/764] removing tstl header from lib functions (#622) fixes #610 --- src/lualib/tsconfig.json | 3 ++- test/unit/lualib/lualib.spec.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index 350f34824..a9ca1cb4d 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -11,6 +11,7 @@ }, "tstl": { "luaLibImport": "none", - "luaTarget": "5.1" + "luaTarget": "5.1", + "noHeader": true } } diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index f7f2b5538..7cb051b35 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -142,3 +142,11 @@ test("Object.fromEntries (Map)", () => { expect(JSON.parse(result)).toEqual({ foo: "bar" }); }); + +test("lualibs should not include tstl header", () => { + const code = ` + const arr = [1, 2, 3]; + arr.push(4);`; + + expect(util.transpileString(code)).not.toMatch("Generated with"); +}); From d30f7edcd82762b9148777d6a058d0d565aa648d Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 4 Jun 2019 22:00:03 +0500 Subject: [PATCH 105/764] Load custom transformers from tsconfig (#552) * Load custom transformers from tsconfig * Rename diagnostics imported namespace to diagnosticFactories * Tests * Add diagnostic when transformer could not be resolved * Rename "transform" to "name" * Validate name and when transformer options * Resolve ts-node from module location instead of base dir * Make .js files have higher priority during transformer resolution * Rename variable * Add ts-node as an optional peer dependency * Add compatibility with ttypescript and support more transformer types * Remove old option tests * Use original source file node in getEmitResolver * Move transformer loading code to a separate file * Check for "transform" property existence instead of "name" non-existence * Remove ts-node optional peer dependency --- package-lock.json | 25 ++-- package.json | 2 + src/CommandLineParser.ts | 35 ++--- src/CompilerOptions.ts | 23 +++- src/LuaTransformer.ts | 7 +- src/TSTransformers.ts | 205 ++++++++++++++++++++++++++++++ src/Transpile.ts | 30 +---- src/diagnostics.ts | 49 ++++++- src/tstl.ts | 13 +- test/unit/transformers.spec.ts | 87 +++++++++++++ test/unit/transformers/import.ts | 9 ++ test/unit/transformers/resolve.js | 11 ++ test/unit/transformers/resolve.ts | 9 ++ test/unit/transformers/types.ts | 42 ++++++ test/unit/transformers/utils.ts | 6 + 15 files changed, 492 insertions(+), 61 deletions(-) create mode 100644 src/TSTransformers.ts create mode 100644 test/unit/transformers.spec.ts create mode 100644 test/unit/transformers/import.ts create mode 100644 test/unit/transformers/resolve.js create mode 100644 test/unit/transformers/resolve.ts create mode 100644 test/unit/transformers/types.ts create mode 100644 test/unit/transformers/utils.ts diff --git a/package-lock.json b/package-lock.json index d2b7cc9f9..92ae2ed14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1366,6 +1366,15 @@ "integrity": "sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng==", "dev": true }, + "@types/resolve": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", + "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", @@ -7024,10 +7033,9 @@ "dev": true }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-type": { "version": "3.0.0", @@ -7326,12 +7334,11 @@ "dev": true }, "resolve": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", - "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", - "dev": true, + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", + "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", "requires": { - "path-parse": "^1.0.5" + "path-parse": "^1.0.6" } }, "resolve-cwd": { diff --git a/package.json b/package.json index a893caeaa..ebb6e2591 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "node": ">=8.5.0" }, "dependencies": { + "resolve": "^1.10.1", "source-map": "^0.7.3", "typescript": "^3.4.5" }, @@ -46,6 +47,7 @@ "@types/glob": "^7.1.1", "@types/jest": "^24.0.12", "@types/node": "^11.13.0", + "@types/resolve": "0.0.8", "fengari": "^0.1.4", "jest": "^24.8.0", "jest-circus": "^24.8.0", diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index c2fb5b975..fdb3fa573 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; -import * as diagnostics from "./diagnostics"; +import * as diagnosticFactories from "./diagnostics"; export interface ParsedCommandLine extends ts.ParsedCommandLine { options: CompilerOptions; @@ -10,7 +10,7 @@ export interface ParsedCommandLine extends ts.ParsedCommandLine { interface CommandLineOptionBase { name: string; aliases?: string[]; - describe: string; + description: string; } interface CommandLineOptionOfEnum extends CommandLineOptionBase { @@ -23,33 +23,34 @@ interface CommandLineOptionOfBoolean extends CommandLineOptionBase { } type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean; + const optionDeclarations: CommandLineOption[] = [ { name: "luaLibImport", - describe: "Specifies how js standard features missing in lua are imported.", + description: "Specifies how js standard features missing in lua are imported.", type: "enum", choices: Object.values(LuaLibImportKind), }, { name: "luaTarget", aliases: ["lt"], - describe: "Specify Lua target version.", + description: "Specify Lua target version.", type: "enum", choices: Object.values(LuaTarget), }, { name: "noHeader", - describe: "Specify if a header will be added to compiled files.", + description: "Specify if a header will be added to compiled files.", type: "boolean", }, { name: "noHoisting", - describe: "Disables hoisting.", + description: "Disables hoisting.", type: "boolean", }, { name: "sourceMapTraceback", - describe: "Applies the source map to show source TS files and lines in error tracebacks.", + description: "Applies the source map to show source TS files and lines in error tracebacks.", type: "boolean", }, ]; @@ -78,7 +79,7 @@ export function getHelpString(): string { const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; const spacing = " ".repeat(Math.max(1, 45 - optionString.length - valuesHint.length)); - result += `\n ${optionString} <${valuesHint}>${spacing}${option.describe}\n`; + result += `\n ${optionString} <${valuesHint}>${spacing}${option.description}\n`; } return result; @@ -97,13 +98,15 @@ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): if (parsedConfigFile.raw.tstl) { if (hasRootLevelOptions) { - parsedConfigFile.errors.push(diagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl)); + parsedConfigFile.errors.push( + diagnosticFactories.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl) + ); } for (const key in parsedConfigFile.raw.tstl) { const option = optionDeclarations.find(option => option.name === key); if (!option) { - parsedConfigFile.errors.push(diagnostics.unknownCompilerOption(key)); + parsedConfigFile.errors.push(diagnosticFactories.unknownCompilerOption(key)); continue; } @@ -167,9 +170,11 @@ function readCommandLineArgument(option: CommandLineOption, value: any): Command // Set boolean arguments without supplied value to true return { value: true, increment: 0 }; } - } else if (value === undefined) { + } + + if (value === undefined) { return { - error: diagnostics.compilerOptionExpectsAnArgument(option.name), + error: diagnosticFactories.compilerOptionExpectsAnArgument(option.name), value: undefined, increment: 0, }; @@ -191,7 +196,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (typeof value !== "boolean") { return { value: undefined, - error: diagnostics.compilerOptionRequiresAValueOfType(option.name, "boolean"), + error: diagnosticFactories.compilerOptionRequiresAValueOfType(option.name, "boolean"), }; } @@ -202,7 +207,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (typeof value !== "string") { return { value: undefined, - error: diagnostics.compilerOptionRequiresAValueOfType(option.name, "string"), + error: diagnosticFactories.compilerOptionRequiresAValueOfType(option.name, "string"), }; } @@ -211,7 +216,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { const optionChoices = option.choices.join(", "); return { value: undefined, - error: diagnostics.argumentForOptionMustBe(`--${option.name}`, optionChoices), + error: diagnosticFactories.argumentForOptionMustBe(`--${option.name}`, optionChoices), }; } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 01d0211c3..b429790b3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,12 +1,31 @@ import * as ts from "typescript"; -export interface CompilerOptions extends ts.CompilerOptions { +type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { + [_ in keyof T]: infer U +} + ? U + : never; + +type OmitIndexSignature> = Pick>; + +export interface TransformerImport { + transform: string; + import?: string; + after?: boolean; + afterDeclarations?: boolean; + type?: "program" | "config" | "checker" | "raw" | "compilerOptions"; + [option: string]: any; +} + +export type CompilerOptions = OmitIndexSignature & { noHeader?: boolean; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; noHoisting?: boolean; sourceMapTraceback?: boolean; -} + plugins?: Array; + [option: string]: ts.CompilerOptions[string] | Array; +}; export enum LuaLibImportKind { None = "none", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9f430f290..09317db82 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -108,7 +108,12 @@ export class LuaTransformer { this.setupState(); this.currentSourceFile = node; - this.resolver = this.checker.getEmitResolver(node); + + // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. + // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` + // and would try to re-analyze the file, which would fail because of replaced nodes. + const originalSourceFile = ts.getParseTreeNode(node, ts.isSourceFile) || node; + this.resolver = this.checker.getEmitResolver(originalSourceFile); let statements: tstl.Statement[] = []; if (node.flags & ts.NodeFlags.JsonFile) { diff --git a/src/TSTransformers.ts b/src/TSTransformers.ts new file mode 100644 index 000000000..720fc98cd --- /dev/null +++ b/src/TSTransformers.ts @@ -0,0 +1,205 @@ +import * as path from "path"; +import * as resolve from "resolve"; +import * as ts from "typescript"; +import { CompilerOptions, TransformerImport } from "./CompilerOptions"; +import * as diagnosticFactories from "./diagnostics"; + +export function getCustomTransformers( + program: ts.Program, + diagnostics: ts.Diagnostic[], + customTransformers: ts.CustomTransformers, + onSourceFile: (sourceFile: ts.SourceFile) => void +): ts.CustomTransformers { + // TODO: https://github.com/Microsoft/TypeScript/issues/28310 + const forEachSourceFile = (node: ts.SourceFile, callback: (sourceFile: ts.SourceFile) => ts.SourceFile) => + ts.isBundle(node) + ? ((ts.updateBundle(node, node.sourceFiles.map(callback)) as unknown) as ts.SourceFile) + : callback(node); + + const luaTransformer: ts.TransformerFactory = () => node => + forEachSourceFile(node, sourceFile => { + onSourceFile(sourceFile); + return ts.createSourceFile(sourceFile.fileName, "", ts.ScriptTarget.ESNext); + }); + + const transformersFromOptions = loadTransformersFromOptions(program, diagnostics); + return { + afterDeclarations: [ + ...(transformersFromOptions.afterDeclarations || []), + ...(customTransformers.afterDeclarations || []), + ], + before: [ + ...(customTransformers.before || []), + ...(transformersFromOptions.before || []), + + ...(transformersFromOptions.after || []), + ...(customTransformers.after || []), + luaTransformer, + ], + }; +} + +function loadTransformersFromOptions(program: ts.Program, allDiagnostics: ts.Diagnostic[]): ts.CustomTransformers { + const customTransformers: Required = { + before: [], + after: [], + afterDeclarations: [], + }; + + const options = program.getCompilerOptions() as CompilerOptions; + if (!options.plugins) return customTransformers; + + const configFileName = options.configFilePath as string | undefined; + const basedir = configFileName ? path.dirname(configFileName) : process.cwd(); + + for (const [index, transformerImport] of options.plugins.entries()) { + if (!("transform" in transformerImport)) continue; + const optionName = `compilerOptions.plugins[${index}]`; + + const { error: resolveError, factory } = resolveTransformerFactory(basedir, optionName, transformerImport); + if (resolveError) allDiagnostics.push(resolveError); + if (factory === undefined) continue; + + const { error: loadError, transformer } = loadTransformer(optionName, program, factory, transformerImport); + if (loadError) allDiagnostics.push(loadError); + if (transformer === undefined) continue; + + if (transformer.before) { + customTransformers.before.push(transformer.before); + } + + if (transformer.after) { + customTransformers.after.push(transformer.after); + } + + if (transformer.afterDeclarations) { + customTransformers.afterDeclarations.push(transformer.afterDeclarations); + } + } + + return customTransformers; +} + +type ProgramTransformerFactory = (program: ts.Program, options: Record) => Transformer; +type ConfigTransformerFactory = (options: Record) => Transformer; +type CompilerOptionsTransformerFactory = ( + compilerOptions: CompilerOptions, + options: Record +) => Transformer; +type TypeCheckerTransformerFactory = (typeChecker: ts.TypeChecker, options: Record) => Transformer; +type RawTransformerFactory = Transformer; +type TransformerFactory = + | ProgramTransformerFactory + | ConfigTransformerFactory + | CompilerOptionsTransformerFactory + | TypeCheckerTransformerFactory + | RawTransformerFactory; + +type Transformer = GroupTransformer | ts.TransformerFactory; +interface GroupTransformer { + before?: ts.TransformerFactory; + after?: ts.TransformerFactory; + afterDeclarations?: ts.TransformerFactory; +} + +function resolveTransformerFactory( + basedir: string, + transformerOptionPath: string, + { transform, import: importName = "default" }: TransformerImport +): { error?: ts.Diagnostic; factory?: TransformerFactory } { + if (typeof transform !== "string") { + const optionName = `${transformerOptionPath}.transform`; + return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "string") }; + } + + let resolved: string; + try { + resolved = resolve.sync(transform, { basedir, extensions: [".js", ".ts", ".tsx"] }); + } catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + return { error: diagnosticFactories.couldNotResolveTransformerFrom(transform, basedir) }; + } + + // tslint:disable-next-line: deprecation + const hasNoRequireHook = require.extensions[".ts"] === undefined; + if (hasNoRequireHook && (resolved.endsWith(".ts") || resolved.endsWith(".tsx"))) { + try { + const tsNode: typeof import("ts-node") = require("ts-node"); + tsNode.register({ transpileOnly: true }); + } catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + return { error: diagnosticFactories.toLoadTransformerItShouldBeTranspiled(transform) }; + } + } + + const factory: TransformerFactory = require(resolved)[importName]; + if (factory === undefined) { + return { error: diagnosticFactories.transformerShouldHaveAExport(transform, importName) }; + } + + return { factory }; +} + +function loadTransformer( + transformerOptionPath: string, + program: ts.Program, + factory: TransformerFactory, + { transform, after = false, afterDeclarations = false, type = "program", ...extraOptions }: TransformerImport +): { error?: ts.Diagnostic; transformer?: GroupTransformer } { + let transformer: Transformer; + switch (type) { + case "program": + transformer = (factory as ProgramTransformerFactory)(program, extraOptions); + break; + case "config": + transformer = (factory as ConfigTransformerFactory)(extraOptions); + break; + case "checker": + transformer = (factory as TypeCheckerTransformerFactory)(program.getTypeChecker(), extraOptions); + break; + case "raw": + transformer = factory as RawTransformerFactory; + break; + case "compilerOptions": + transformer = (factory as CompilerOptionsTransformerFactory)(program.getCompilerOptions(), extraOptions); + break; + default: { + const optionName = `--${transformerOptionPath}.type`; + return { error: diagnosticFactories.argumentForOptionMustBe(optionName, "program") }; + } + } + + if (typeof after !== "boolean") { + const optionName = `${transformerOptionPath}.after`; + return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "boolean") }; + } + + if (typeof afterDeclarations !== "boolean") { + const optionName = `${transformerOptionPath}.afterDeclarations`; + return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "boolean") }; + } + + if (typeof transformer === "function") { + let wrappedTransformer: GroupTransformer; + + if (after) { + wrappedTransformer = { after: transformer }; + } else if (afterDeclarations) { + wrappedTransformer = { afterDeclarations: transformer as ts.TransformerFactory }; + } else { + wrappedTransformer = { before: transformer }; + } + + return { transformer: wrappedTransformer }; + } else { + const isValidGroupTransformer = + typeof transformer === "object" && + (transformer.before || transformer.after || transformer.afterDeclarations); + + if (!isValidGroupTransformer) { + return { error: diagnosticFactories.transformerShouldBeATsTransformerFactory(transform) }; + } + } + + return { transformer }; +} diff --git a/src/Transpile.ts b/src/Transpile.ts index cefebf463..f02810b78 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -1,33 +1,11 @@ import * as ts from "typescript"; import { CompilerOptions } from "./CompilerOptions"; -import { transpileError } from "./diagnostics"; +import * as diagnosticFactories from "./diagnostics"; import { Block } from "./LuaAST"; import { LuaPrinter } from "./LuaPrinter"; import { LuaTransformer } from "./LuaTransformer"; import { TranspileError } from "./TranspileError"; - -function getCustomTransformers( - _program: ts.Program, - customTransformers: ts.CustomTransformers, - onSourceFile: (sourceFile: ts.SourceFile) => void -): ts.CustomTransformers { - // TODO: https://github.com/Microsoft/TypeScript/issues/28310 - const forEachSourceFile = (node: ts.SourceFile, callback: (sourceFile: ts.SourceFile) => ts.SourceFile) => - ts.isBundle(node) - ? ((ts.updateBundle(node, node.sourceFiles.map(callback)) as unknown) as ts.SourceFile) - : callback(node); - - const luaTransformer: ts.TransformerFactory = () => node => - forEachSourceFile(node, sourceFile => { - onSourceFile(sourceFile); - return ts.createSourceFile(sourceFile.fileName, "", ts.ScriptTarget.ESNext); - }); - - return { - afterDeclarations: customTransformers.afterDeclarations, - before: [...(customTransformers.before || []), ...(customTransformers.after || []), luaTransformer], - }; -} +import { getCustomTransformers } from "./TSTransformers"; export interface TranspiledFile { fileName: string; @@ -106,7 +84,7 @@ export function transpile({ } catch (err) { if (!(err instanceof TranspileError)) throw err; - diagnostics.push(transpileError(err)); + diagnostics.push(diagnosticFactories.transpileError(err)); updateTranspiledFile(sourceFile.fileName, { lua: `error(${JSON.stringify(err.message)})\n`, @@ -115,7 +93,7 @@ export function transpile({ } }; - const transformers = getCustomTransformers(program, customTransformers, processSourceFile); + const transformers = getCustomTransformers(program, diagnostics, customTransformers, processSourceFile); const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { for (const sourceFile of sourceFiles) { diff --git a/src/diagnostics.ts b/src/diagnostics.ts index eb96ecb79..2f052d272 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import { TranspileError } from "./TranspileError"; -export const transpileError = (error: TranspileError) => ({ +export const transpileError = (error: TranspileError): ts.Diagnostic => ({ file: error.node.getSourceFile(), start: error.node.getStart(), length: error.node.getWidth(), @@ -11,7 +11,7 @@ export const transpileError = (error: TranspileError) => ({ messageText: error.message, }); -export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record) => ({ +export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record): ts.Diagnostic => ({ file: undefined, start: undefined, length: undefined, @@ -23,6 +23,46 @@ export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record) = `"tstl": ${JSON.stringify(tstl, undefined, 4)}`, }); +export const toLoadTransformerItShouldBeTranspiled = (transform: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: `To load "${transform}" transformer it should be transpiled or "ts-node" should be installed`, +}); + +export const couldNotResolveTransformerFrom = (transform: string, base: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: `Could not resolve "${transform}" transformer from "${base}".`, +}); + +export const transformerShouldHaveAExport = (transform: string, importName: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: `"${transform}" transformer should have a "${importName}" export`, +}); + +export const transformerShouldBeATsTransformerFactory = (transform: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: `"${transform}" transformer should be a ts.TransformerFactory or an object with ts.TransformerFactory values`, +}); + export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ file: undefined, start: undefined, @@ -81,6 +121,11 @@ export const argumentForOptionMustBe = createCommandLineError( (name: string, values: string) => `Argument for '${name}' option must be: ${values}.` ); +export const optionCanOnlyBeSpecifiedInTsconfigJsonFile = createCommandLineError( + 6064, + (name: string) => `Option '${name}' can only be specified in 'tsconfig.json' file.` +); + export const optionBuildMustBeFirstCommandLineArgument = createCommandLineError( 6369, () => "Option '--build' must be the first command line argument." diff --git a/src/tstl.ts b/src/tstl.ts index 4f3b974f5..8860b8929 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -3,7 +3,7 @@ import * as path from "path"; import * as ts from "typescript"; import * as tstl from "."; import * as CommandLineParser from "./CommandLineParser"; -import * as cliDiagnostics from "./diagnostics"; +import * as diagnosticFactories from "./diagnostics"; function createWatchStatusReporter(options?: ts.CompilerOptions): ts.WatchStatusReporter { return (ts as any).createWatchStatusReporter(ts.sys, shouldBePretty(options)); @@ -31,7 +31,7 @@ function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefin } if (commandLine.fileNames.length !== 0) { - reportDiagnostic(cliDiagnostics.optionProjectCannotBeMixedWithSourceFilesOnACommandLine()); + reportDiagnostic(diagnosticFactories.optionProjectCannotBeMixedWithSourceFilesOnACommandLine()); ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); return; } @@ -46,14 +46,15 @@ function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefin if (ts.sys.fileExists(configFileName)) { return configFileName; } else { - reportDiagnostic(cliDiagnostics.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project)); + reportDiagnostic(diagnosticFactories.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project)); + ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } } else { if (ts.sys.fileExists(fileOrDirectory)) { return fileOrDirectory; } else { - reportDiagnostic(cliDiagnostics.theSpecifiedPathDoesNotExist(project)); + reportDiagnostic(diagnosticFactories.theSpecifiedPathDoesNotExist(project)); ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } } @@ -70,7 +71,7 @@ function executeCommandLine(args: string[]): void { const commandLine = CommandLineParser.parseCommandLine(args); if (commandLine.options.build) { - reportDiagnostic(cliDiagnostics.optionBuildMustBeFirstCommandLineArgument()); + reportDiagnostic(diagnosticFactories.optionBuildMustBeFirstCommandLineArgument()); return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } @@ -254,7 +255,7 @@ function updateWatchCompilationHost( // do a full recompile after an error fullRecompile = errors.length > 0; - host.onWatchStatusChange!(cliDiagnostics.watchErrorSummary(errors.length), host.getNewLine(), options); + host.onWatchStatusChange!(diagnosticFactories.watchErrorSummary(errors.length), host.getNewLine(), options); }; } diff --git a/test/unit/transformers.spec.ts b/test/unit/transformers.spec.ts new file mode 100644 index 000000000..cb7f143fe --- /dev/null +++ b/test/unit/transformers.spec.ts @@ -0,0 +1,87 @@ +import * as path from "path"; +import * as tstl from "../../src"; +import * as util from "../util"; + +const optionsOfTransformer = (transformer: tstl.TransformerImport): tstl.CompilerOptions => ({ + plugins: [transformer], +}); + +test("should ignore language service plugins", () => { + const options: tstl.CompilerOptions = { + plugins: [{ name: path.join(__dirname, "transformers/resolve.ts") }], + }; + + expect(util.transpileAndExecute("return", options)).toBe(undefined); +}); + +describe("resolution", () => { + const testTransform = (transformer: tstl.TransformerImport) => { + const options = optionsOfTransformer(transformer); + expect(util.transpileAndExecute("return", options)).toBe(true); + }; + + test("should resolve relative transformer paths", () => { + jest.spyOn(process, "cwd").mockReturnValue(__dirname); + testTransform({ transform: "./transformers/resolve.ts" }); + }); + + test("should load js transformers", () => { + testTransform({ transform: path.join(__dirname, "transformers/resolve.js") }); + }); + + test("should load ts transformers", () => { + testTransform({ transform: path.join(__dirname, "transformers/resolve.ts") }); + }); + + test('should support "import" option', () => { + testTransform({ + transform: path.join(__dirname, "transformers/import.ts"), + import: "transformer", + }); + }); + + test("should error if transformer could not be resolved", () => { + const transform = path.join(__dirname, "transformers/error.ts"); + const options = optionsOfTransformer({ transform }); + const { diagnostics } = util.transpileStringResult("", options); + expect(diagnostics).toHaveDiagnostics(); + }); +}); + +describe("factory types", () => { + const value = "foo"; + const getOptions = (options: Partial) => + optionsOfTransformer({ + transform: path.join(__dirname, "transformers/types.ts"), + ...options, + }); + + test('should support "program" type', () => { + const options = getOptions({ type: "program", import: "program", value }); + expect(util.transpileAndExecute("return false", options)).toBe(value); + }); + + test('should support "config" type', () => { + const options = getOptions({ type: "config", import: "config", value }); + expect(util.transpileAndExecute("return", options)).toBe(value); + }); + + test('should support "checker" type', () => { + const options = getOptions({ type: "checker", import: "checker", value }); + expect(util.transpileAndExecute("return false", options)).toBe(value); + }); + + test('should support "raw" type', () => { + const options = getOptions({ type: "raw", import: "raw" }); + expect(util.transpileAndExecute("return", options)).toBe(true); + }); + + test('should support "compilerOptions" type', () => { + const options: tstl.CompilerOptions = { + ...getOptions({ type: "compilerOptions", import: "compilerOptions" }), + luaTarget: tstl.LuaTarget.LuaJIT, + }; + + expect(util.transpileAndExecute("return", options)).toBe(true); + }); +}); diff --git a/test/unit/transformers/import.ts b/test/unit/transformers/import.ts new file mode 100644 index 000000000..8dafa5886 --- /dev/null +++ b/test/unit/transformers/import.ts @@ -0,0 +1,9 @@ +import * as ts from "typescript"; +import { visitAndReplace } from "./utils"; + +// tslint:disable-next-line: no-default-export +export const transformer = (): ts.TransformerFactory => context => file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(true)); + }); diff --git a/test/unit/transformers/resolve.js b/test/unit/transformers/resolve.js new file mode 100644 index 000000000..3ba87c73f --- /dev/null +++ b/test/unit/transformers/resolve.js @@ -0,0 +1,11 @@ +const ts = require("typescript"); + +module.exports.default = () => context => file => { + const replaceNode = node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(true)); + }; + + const visit = node => replaceNode(node) || ts.visitEachChild(node, visit, context); + return ts.visitNode(file, visit); +}; diff --git a/test/unit/transformers/resolve.ts b/test/unit/transformers/resolve.ts new file mode 100644 index 000000000..8b0aacff7 --- /dev/null +++ b/test/unit/transformers/resolve.ts @@ -0,0 +1,9 @@ +import * as ts from "typescript"; +import { visitAndReplace } from "./utils"; + +// tslint:disable-next-line: no-default-export +export default (): ts.TransformerFactory => context => file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(true)); + }); diff --git a/test/unit/transformers/types.ts b/test/unit/transformers/types.ts new file mode 100644 index 000000000..dc8ecf71c --- /dev/null +++ b/test/unit/transformers/types.ts @@ -0,0 +1,42 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; +import { visitAndReplace } from "./utils"; + +export const program = (program: ts.Program, options: { value: any }): ts.TransformerFactory => + checker(program.getTypeChecker(), options); + +export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(value)); + }); + +export const checker = ( + checker: ts.TypeChecker, + { value }: { value: any } +): ts.TransformerFactory => context => file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || !node.expression) return; + const type = checker.getTypeAtLocation(node.expression); + if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; + return ts.updateReturn(node, ts.createLiteral(value)); + }); + +export const raw: ts.TransformerFactory = context => file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(true)); + }); + +export const compilerOptions = ({ + luaTarget, +}: tstl.CompilerOptions): ts.TransformerFactory => context => file => { + if (luaTarget !== tstl.LuaTarget.LuaJIT) { + throw new Error("Transformer supports only LuaJIT target"); + } + + return visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || node.expression) return; + return ts.updateReturn(node, ts.createLiteral(true)); + }); +}; diff --git a/test/unit/transformers/utils.ts b/test/unit/transformers/utils.ts new file mode 100644 index 000000000..603248dc3 --- /dev/null +++ b/test/unit/transformers/utils.ts @@ -0,0 +1,6 @@ +import * as ts from "typescript"; + +export function visitAndReplace(context: ts.TransformationContext, node: T, visitor: ts.Visitor): T { + const visit: ts.Visitor = node => visitor(node) || ts.visitEachChild(node, visit, context); + return ts.visitNode(node, visit); +} From 59acb583abd5d5724f4aa9c802b06c4c78ce8ade Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 6 Jun 2019 20:21:03 +0200 Subject: [PATCH 106/764] Replaced all private properties with protected (#621) --- src/LuaTransformer.ts | 138 +++++++++++++++++++++--------------------- 1 file changed, 70 insertions(+), 68 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 09317db82..707e01f2a 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -51,32 +51,32 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { } export class LuaTransformer { - private isStrict: boolean; - private luaTarget: LuaTarget; + protected isStrict: boolean; + protected luaTarget: LuaTarget; - private checker: DiagnosticsProducingTypeChecker; + protected checker: DiagnosticsProducingTypeChecker; protected options: CompilerOptions; // Resolver is lazy-initialized in transformSourceFile to avoid type-checking all files - private resolver!: EmitResolver; + protected resolver!: EmitResolver; - private isModule = false; - private currentSourceFile?: ts.SourceFile; + protected isModule = false; + protected currentSourceFile?: ts.SourceFile; - private currentNamespace: ts.ModuleDeclaration | undefined; - private classStack: ts.ClassLikeDeclaration[] = []; + protected currentNamespace: ts.ModuleDeclaration | undefined; + protected classStack: ts.ClassLikeDeclaration[] = []; - private scopeStack: Scope[] = []; - private genVarCounter = 0; + protected scopeStack: Scope[] = []; + protected genVarCounter = 0; - private luaLibFeatureSet = new Set(); + protected luaLibFeatureSet = new Set(); - private symbolInfo = new Map(); - private symbolIds = new Map(); + protected symbolInfo = new Map(); + protected symbolIds = new Map(); - private genSymbolIdCounter = 0; + protected genSymbolIdCounter = 0; - private readonly typeValidationCache: Map> = new Map>(); + protected readonly typeValidationCache: Map> = new Map>(); public constructor(protected program: ts.Program) { this.checker = (program as any).getDiagnosticsProducingTypeChecker(); @@ -91,7 +91,7 @@ export class LuaTransformer { this.setupState(); } - private setupState(): void { + protected setupState(): void { this.genVarCounter = 0; this.currentSourceFile = undefined; this.isModule = false; @@ -103,7 +103,6 @@ export class LuaTransformer { this.genSymbolIdCounter = 1; } - // TODO make all other methods private??? public transformSourceFile(node: ts.SourceFile): [tstl.Block, Set] { this.setupState(); @@ -218,7 +217,7 @@ export class LuaTransformer { } /** Converts an array of ts.Statements into an array of tstl.Statements */ - private transformStatements(statements: readonly ts.Statement[]): tstl.Statement[] { + protected transformStatements(statements: readonly ts.Statement[]): tstl.Statement[] { const tstlStatements: tstl.Statement[] = []; (statements as ts.Statement[]).forEach(statement => { tstlStatements.push(...this.statementVisitResultToArray(this.transformStatement(statement))); @@ -450,7 +449,7 @@ export class LuaTransformer { } } - private createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { + protected createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { const modulePathString = resolveModule ? this.getImportPath(moduleSpecifier.text.replace(new RegExp('"', "g"), ""), moduleSpecifier) : moduleSpecifier.text; @@ -458,7 +457,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); } - private validateClassElement(element: ts.ClassElement): void { + protected validateClassElement(element: ts.ClassElement): void { if (element.name && (ts.isStringLiteral(element.name) || ts.isIdentifier(element.name))) { if (tsHelper.isStatic(element) && element.name.text === "new") { throw TSTLErrors.ForbiddenStaticClassPropertyName(element, element.name.text); @@ -502,7 +501,7 @@ export class LuaTransformer { return this.createModuleRequire(externalModuleReference.expression as ts.StringLiteral); } - private transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { + protected transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { return ts.isQualifiedName(entityName) ? this.transformQualifiedName(entityName) : this.transformIdentifierExpression(entityName); @@ -762,7 +761,7 @@ export class LuaTransformer { return result; } - private createClassCreationMethods( + protected createClassCreationMethods( statement: ts.ClassLikeDeclarationBase, className: tstl.Identifier, localClassName: tstl.Identifier, @@ -1094,7 +1093,7 @@ export class LuaTransformer { return result; } - private transformClassInstanceFields( + protected transformClassInstanceFields( classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): tstl.Statement[] { @@ -1137,14 +1136,14 @@ export class LuaTransformer { return statements; } - private createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { + protected createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { return tstl.createTableIndexExpression( tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")), tstl.createStringLiteral("____constructor") ); } - private transformConstructorDeclaration( + protected transformConstructorDeclaration( statement: ts.ConstructorDeclaration, className: tstl.Identifier, instanceFields: ts.PropertyDeclaration[], @@ -1349,7 +1348,7 @@ export class LuaTransformer { ); } - private transformParameters( + protected transformParameters( parameters: ts.NodeArray, context?: tstl.Identifier ): [tstl.Identifier[], tstl.DotsLiteral | undefined, tstl.Identifier | undefined] { @@ -1389,7 +1388,7 @@ export class LuaTransformer { return [paramNames, dotsLiteral, restParamName]; } - private transformFunctionBody( + protected transformFunctionBody( parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier @@ -1442,7 +1441,7 @@ export class LuaTransformer { return [headerStatements.concat(bodyStatements), scope]; } - private transformParameterDefaultValueDeclaration( + protected transformParameterDefaultValueDeclaration( parameterName: tstl.Identifier, value?: ts.Expression, tsOriginal?: ts.Node @@ -1706,7 +1705,7 @@ export class LuaTransformer { }); } - private transformGeneratorFunction( + protected transformGeneratorFunction( parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier @@ -2189,7 +2188,7 @@ export class LuaTransformer { return tstl.createDoStatement(result, statement); } - private transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { + protected transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); @@ -2245,13 +2244,13 @@ export class LuaTransformer { return baseResult; } - private transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { + protected transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { return ts.isBlock(statement) ? this.transformStatements(statement.statements) : this.statementVisitResultToArray(this.transformStatement(statement)); } - private transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + protected transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { let valueVariable: tstl.Identifier; if (ts.isVariableDeclarationList(statement.initializer)) { // Declaration of new variable @@ -2280,7 +2279,10 @@ export class LuaTransformer { ); } - private transformForOfLuaIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + protected transformForOfLuaIteratorStatement( + statement: ts.ForOfStatement, + block: tstl.Block + ): StatementVisitResult { const luaIterator = this.transformExpression(statement.expression); const type = this.checker.getTypeAtLocation(statement.expression); const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); @@ -2349,7 +2351,7 @@ export class LuaTransformer { } } - private transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { + protected transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { const iterable = this.transformExpression(statement.expression); if ( ts.isVariableDeclarationList(statement.initializer) && @@ -2740,7 +2742,7 @@ export class LuaTransformer { } } - private transformAssignment(lhs: ts.Expression, right?: tstl.Expression): tstl.Statement { + protected transformAssignment(lhs: ts.Expression, right?: tstl.Expression): tstl.Statement { return tstl.createAssignmentStatement( this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression, right, @@ -2748,7 +2750,7 @@ export class LuaTransformer { ); } - private transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { + protected transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { // Validate assignment const rightType = this.checker.getTypeAtLocation(expression.right); const leftType = this.checker.getTypeAtLocation(expression.left); @@ -2793,7 +2795,7 @@ export class LuaTransformer { } } - private transformAssignmentExpression( + protected transformAssignmentExpression( expression: ts.BinaryExpression ): tstl.CallExpression | tstl.MethodCallExpression { // Validate assignment @@ -2887,7 +2889,7 @@ export class LuaTransformer { } } - private transformCompoundAssignmentExpression( + protected transformCompoundAssignmentExpression( expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, @@ -3056,7 +3058,7 @@ export class LuaTransformer { ); } - private transformCompoundAssignmentStatement( + protected transformCompoundAssignmentStatement( node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, @@ -3097,7 +3099,7 @@ export class LuaTransformer { } } - private transformUnaryBitLibOperation( + protected transformUnaryBitLibOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator, @@ -3118,7 +3120,7 @@ export class LuaTransformer { ); } - private transformUnaryBitOperation( + protected transformUnaryBitOperation( node: ts.Node, expression: tstl.Expression, operator: tstl.UnaryBitwiseOperator @@ -3138,7 +3140,7 @@ export class LuaTransformer { } } - private transformBinaryBitLibOperation( + protected transformBinaryBitLibOperation( node: ts.Node, left: tstl.Expression, right: tstl.Expression, @@ -3175,7 +3177,7 @@ export class LuaTransformer { ); } - private transformBinaryBitOperation( + protected transformBinaryBitOperation( node: ts.Node, left: tstl.Expression, right: tstl.Expression, @@ -3197,7 +3199,7 @@ export class LuaTransformer { } } - private transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { + protected transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { const condition = this.transformExpression(expression.condition); const val1 = this.transformExpression(expression.whenTrue); const val2 = this.transformExpression(expression.whenFalse); @@ -3531,7 +3533,7 @@ export class LuaTransformer { return wrapResult ? this.wrapInTable(callExpression) : callExpression; } - private transformGlobalFunctionCall(node: ts.CallExpression): tstl.Expression | undefined { + protected transformGlobalFunctionCall(node: ts.CallExpression): tstl.Expression | undefined { const signature = this.checker.getResolvedSignature(node); const parameters = this.transformArguments(node.arguments, signature); @@ -3738,7 +3740,7 @@ export class LuaTransformer { } } - private transformArguments( + protected transformArguments( params: ts.NodeArray | ts.Expression[], sig?: ts.Signature, context?: T @@ -3811,7 +3813,7 @@ export class LuaTransformer { } // Transpile a Math._ property - private transformMathExpression(identifier: ts.Identifier): tstl.Expression { + protected transformMathExpression(identifier: ts.Identifier): tstl.Expression { const name = identifier.escapedText as string; switch (name) { case "PI": @@ -3834,7 +3836,7 @@ export class LuaTransformer { } // Transpile a Math._ property - private transformMathCallExpression(node: ts.CallExpression): tstl.Expression { + protected transformMathCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); @@ -3907,7 +3909,7 @@ export class LuaTransformer { } // Transpile access of string properties, only supported properties are allowed - private transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { + protected transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": const expression = this.transformExpression(node.expression); @@ -3918,7 +3920,7 @@ export class LuaTransformer { } // Transpile access of array properties, only supported properties are allowed - private transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { + protected transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { switch (node.name.escapedText) { case "length": const expression = this.transformExpression(node.expression); @@ -3928,7 +3930,7 @@ export class LuaTransformer { } } - private transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { + protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": const propertyAccessExpression = this.transformExpression(node.expression); @@ -3965,7 +3967,7 @@ export class LuaTransformer { } } - private transformConstEnumValue( + protected transformConstEnumValue( enumType: ts.EnumType, memberName: string, tsOriginal: ts.Node @@ -4007,7 +4009,7 @@ export class LuaTransformer { throw TSTLErrors.CouldNotFindEnumMember(enumDeclaration, memberName, tsOriginal); } - private transformStringCallExpression(node: ts.CallExpression): tstl.Expression { + protected transformStringCallExpression(node: ts.CallExpression): tstl.Expression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); @@ -4141,7 +4143,7 @@ export class LuaTransformer { } } - private createStringCall( + protected createStringCall( methodName: string, tsOriginal: ts.Node, ...params: tstl.Expression[] @@ -4155,7 +4157,7 @@ export class LuaTransformer { } // Transpile a String._ property - private transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { + protected transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { const identifierString = identifier.escapedText as string; switch (identifierString) { @@ -4174,7 +4176,7 @@ export class LuaTransformer { } // Transpile an Object._ property - private transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { + protected transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const parameters = this.transformArguments(expression.arguments); const methodName = method.name.escapedText; @@ -4195,7 +4197,7 @@ export class LuaTransformer { } } - private transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { + protected transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const methodName = method.name.escapedText; const signature = this.checker.getResolvedSignature(expression); @@ -4266,12 +4268,12 @@ export class LuaTransformer { } } - private isStringFormatTemplate(expression: ts.Expression): boolean { + protected isStringFormatTemplate(expression: ts.Expression): boolean { return ts.isStringLiteral(expression) && expression.text.match(/\%/g) !== null; } // Transpile a Symbol._ property - private transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { + protected transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments, signature); @@ -4290,7 +4292,7 @@ export class LuaTransformer { } // Transpile a Number._ property - private transformNumberCallExpression(expression: ts.CallExpression): tstl.CallExpression { + protected transformNumberCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; const parameters = this.transformArguments(expression.arguments); const methodName = method.name.escapedText; @@ -4305,7 +4307,7 @@ export class LuaTransformer { } } - private validateLuaTableCall( + protected validateLuaTableCall( expression: ts.CallExpression & { expression: ts.PropertyAccessExpression }, isWithinExpressionStatement: boolean ): void { @@ -4334,7 +4336,7 @@ export class LuaTransformer { } } - private transformLuaTableExpressionStatement( + protected transformLuaTableExpressionStatement( node: ts.ExpressionStatement & { expression: ts.CallExpression } & { expression: { expression: ts.PropertyAccessExpression }; } @@ -4363,7 +4365,7 @@ export class LuaTransformer { } } - private transformLuaTableCallExpression( + protected transformLuaTableCallExpression( expression: ts.CallExpression & { expression: ts.PropertyAccessExpression } ): tstl.Expression { const method = expression.expression; @@ -4381,7 +4383,7 @@ export class LuaTransformer { } } - private transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { + protected transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); @@ -4444,7 +4446,7 @@ export class LuaTransformer { } } - private transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { + protected transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { @@ -4598,7 +4600,7 @@ export class LuaTransformer { return tstl.createIdentifier(text, identifier, symbolId); } - private transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { + protected transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { const identifier = this.transformIdentifier(expression); const exportScope = this.getIdentifierExportScope(identifier); @@ -5204,7 +5206,7 @@ export class LuaTransformer { this.genVarCounter++; } - private shouldHoist(symbolId: tstl.SymbolId, scope: Scope): boolean { + protected shouldHoist(symbolId: tstl.SymbolId, scope: Scope): boolean { const symbolInfo = this.symbolInfo.get(symbolId); if (!symbolInfo) { return false; @@ -5406,7 +5408,7 @@ export class LuaTransformer { } } - private createConstructorDecorationStatement( + protected createConstructorDecorationStatement( declaration: ts.ClassLikeDeclaration ): tstl.AssignmentStatement | undefined { const className = From 2835c51b77b69a004c3c6879261a69377421caff Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 6 Jun 2019 13:49:01 -0600 Subject: [PATCH 107/764] typeof improvements (#625) * typeof now uses lib function, with optimized path for comparisons * simplified tests * refactored transformBinaryExpression a bit --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 80 ++++++++++++++++++++++++---------- src/lualib/TypeOf.ts | 12 +++++ test/unit/typechecking.spec.ts | 43 +++++++++++++++++- 4 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 src/lualib/TypeOf.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 658664488..23a9711ad 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -55,6 +55,7 @@ export enum LuaLibFeature { StringStartsWith = "StringStartsWith", Symbol = "Symbol", SymbolRegistry = "SymbolRegistry", + TypeOf = "TypeOf", } const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 707e01f2a..0da4e9b84 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2657,10 +2657,42 @@ export class LuaTransformer { } } + protected transformTypeOfLiteralComparison( + typeOfExpression: ts.TypeOfExpression, + comparedExpression: tstl.StringLiteral, + operator: ts.BinaryOperator, + tsOriginal: ts.Node + ): ExpressionVisitResult { + if (comparedExpression.value === "object") { + comparedExpression.value = "table"; + } else if (comparedExpression.value === "undefined") { + comparedExpression.value = "nil"; + } + const innerExpression = this.transformExpression(typeOfExpression.expression); + const typeCall = tstl.createCallExpression(tstl.createIdentifier("type"), [innerExpression], typeOfExpression); + return this.transformBinaryOperation(typeCall, comparedExpression, operator, tsOriginal); + } + + protected transformComparisonExpression(expression: ts.BinaryExpression): ExpressionVisitResult { + const left = this.transformExpression(expression.left); + const right = this.transformExpression(expression.right); + const operator = expression.operatorToken.kind; + + // Custom handling for 'typeof(foo) === "type"' + if (ts.isTypeOfExpression(expression.left) && tstl.isStringLiteral(right)) { + return this.transformTypeOfLiteralComparison(expression.left, right, operator, expression); + } else if (ts.isTypeOfExpression(expression.right) && tstl.isStringLiteral(left)) { + return this.transformTypeOfLiteralComparison(expression.right, left, operator, expression); + } + + return this.transformBinaryOperation(left, right, operator, expression); + } + public transformBinaryExpression(expression: ts.BinaryExpression): ExpressionVisitResult { - // Check if this is an assignment token, then handle accordingly + const operator = expression.operatorToken.kind; - const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(expression.operatorToken.kind); + // Check if this is an assignment token, then handle accordingly + const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(operator); if (isCompound && replacementOperator) { return this.transformCompoundAssignmentExpression( expression, @@ -2671,18 +2703,14 @@ export class LuaTransformer { ); } - const lhs = this.transformExpression(expression.left); - const rhs = this.transformExpression(expression.right); - // Transpile operators - switch (expression.operatorToken.kind) { + switch (operator) { case ts.SyntaxKind.AmpersandToken: case ts.SyntaxKind.BarToken: case ts.SyntaxKind.CaretToken: case ts.SyntaxKind.LessThanLessThanToken: case ts.SyntaxKind.GreaterThanGreaterThanToken: case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return this.transformBinaryBitOperation(expression, lhs, rhs, expression.operatorToken.kind); case ts.SyntaxKind.PlusToken: case ts.SyntaxKind.AmpersandAmpersandToken: case ts.SyntaxKind.BarBarToken: @@ -2690,7 +2718,12 @@ export class LuaTransformer { case ts.SyntaxKind.AsteriskToken: case ts.SyntaxKind.AsteriskAsteriskToken: case ts.SyntaxKind.SlashToken: - case ts.SyntaxKind.PercentToken: + case ts.SyntaxKind.PercentToken: { + const lhs = this.transformExpression(expression.left); + const rhs = this.transformExpression(expression.right); + return this.transformBinaryOperation(lhs, rhs, operator, expression); + } + case ts.SyntaxKind.GreaterThanToken: case ts.SyntaxKind.GreaterThanEqualsToken: case ts.SyntaxKind.LessThanToken: @@ -2699,10 +2732,14 @@ export class LuaTransformer { case ts.SyntaxKind.EqualsEqualsEqualsToken: case ts.SyntaxKind.ExclamationEqualsToken: case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return this.transformBinaryOperation(lhs, rhs, expression.operatorToken.kind, expression); + return this.transformComparisonExpression(expression); + case ts.SyntaxKind.EqualsToken: return this.transformAssignmentExpression(expression); - case ts.SyntaxKind.InKeyword: + + case ts.SyntaxKind.InKeyword: { + const lhs = this.transformExpression(expression.left); + const rhs = this.transformExpression(expression.right); const indexExpression = tstl.createTableIndexExpression(rhs, lhs); return tstl.createBinaryExpression( indexExpression, @@ -2710,8 +2747,11 @@ export class LuaTransformer { tstl.SyntaxKind.InequalityOperator, expression ); + } - case ts.SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.InstanceOfKeyword: { + const lhs = this.transformExpression(expression.left); + const rhs = this.transformExpression(expression.right); const rhsType = this.checker.getTypeAtLocation(expression.right); const decorators = tsHelper.getCustomDecorators(rhsType, this.checker); @@ -2729,16 +2769,19 @@ export class LuaTransformer { } return this.transformLuaLibFunction(LuaLibFeature.InstanceOf, expression, lhs, rhs); + } - case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: { + const rhs = this.transformExpression(expression.right); return this.createImmediatelyInvokedFunctionExpression( this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)), rhs, expression ); + } default: - throw TSTLErrors.UnsupportedKind("binary operator", expression.operatorToken.kind, expression); + throw TSTLErrors.UnsupportedKind("binary operator", operator, expression); } } @@ -4491,16 +4534,7 @@ export class LuaTransformer { public transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult { const innerExpression = this.transformExpression(expression.expression); - const typeFunctionIdentifier = tstl.createIdentifier("type"); - const typeCall = tstl.createCallExpression(typeFunctionIdentifier, [innerExpression]); - const tableString = tstl.createStringLiteral("table"); - const objectString = tstl.createStringLiteral("object"); - const condition = tstl.createBinaryExpression(typeCall, tableString, tstl.SyntaxKind.EqualityOperator); - const andClause = tstl.createBinaryExpression(condition, objectString, tstl.SyntaxKind.AndOperator); - - return tstl.createParenthesizedExpression( - tstl.createBinaryExpression(andClause, tstl.cloneNode(typeCall), tstl.SyntaxKind.OrOperator, expression) - ); + return this.transformLuaLibFunction(LuaLibFeature.TypeOf, expression, innerExpression); } public transformSpreadElement(expression: ts.SpreadElement): ExpressionVisitResult { diff --git a/src/lualib/TypeOf.ts b/src/lualib/TypeOf.ts new file mode 100644 index 000000000..af531d732 --- /dev/null +++ b/src/lualib/TypeOf.ts @@ -0,0 +1,12 @@ +declare function type(this: void, value: unknown): string; + +function __TS__TypeOf(this: void, value: unknown): string { + const luaType = type(value); + if (luaType === "table") { + return "object"; + } else if (luaType === "nil") { + return "undefined"; + } else { + return luaType; + } +} diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index 3d5014336..166921e92 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -40,7 +40,7 @@ test("typeof function", () => { test.each(["null", "undefined"])("typeof undefined (%p)", inp => { const result = util.transpileAndExecute(`return typeof ${inp};`); - expect(result).toBe("nil"); + expect(result).toBe("undefined"); }); test("instanceof", () => { @@ -140,3 +140,44 @@ test("instanceof Symbol.hasInstance", () => { expect(result).toBe(true); }); + +test.each([ + { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, + { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, + { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, + { expression: "1", operator: "===", compareTo: "number", expectResult: true }, + { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, + { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, +])("typeof literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { + const code = ` + let val = ${expression}; + return typeof val ${operator} "${compareTo}";`; + + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); + +test.each([ + { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, + { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, + { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, + { expression: "1", operator: "===", compareTo: "number", expectResult: true }, + { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, + { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, +])("typeof non-literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { + const code = ` + let val = ${expression}; + let compareTo = "${compareTo}"; + return typeof val ${operator} compareTo;`; + + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); From 46482c7e984b13c9584406d5799ab00d8cac105b Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 10 Jun 2019 03:44:21 -0600 Subject: [PATCH 108/764] Preventing __TS__TypeOf lib function from being output if it is not used. (#627) --- src/LuaTransformer.ts | 24 ++++++++++++++++++------ test/unit/typechecking.spec.ts | 2 ++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 0da4e9b84..02e837a6e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2674,17 +2674,29 @@ export class LuaTransformer { } protected transformComparisonExpression(expression: ts.BinaryExpression): ExpressionVisitResult { - const left = this.transformExpression(expression.left); - const right = this.transformExpression(expression.right); + let left: tstl.Expression | undefined; + let right: tstl.Expression | undefined; const operator = expression.operatorToken.kind; // Custom handling for 'typeof(foo) === "type"' - if (ts.isTypeOfExpression(expression.left) && tstl.isStringLiteral(right)) { - return this.transformTypeOfLiteralComparison(expression.left, right, operator, expression); - } else if (ts.isTypeOfExpression(expression.right) && tstl.isStringLiteral(left)) { - return this.transformTypeOfLiteralComparison(expression.right, left, operator, expression); + if (ts.isTypeOfExpression(expression.left)) { + right = this.transformExpression(expression.right); + if (tstl.isStringLiteral(right)) { + return this.transformTypeOfLiteralComparison(expression.left, right, operator, expression); + } + } else if (ts.isTypeOfExpression(expression.right)) { + left = this.transformExpression(expression.left); + if (tstl.isStringLiteral(left)) { + return this.transformTypeOfLiteralComparison(expression.right, left, operator, expression); + } } + if (!left) { + left = this.transformExpression(expression.left); + } + if (!right) { + right = this.transformExpression(expression.right); + } return this.transformBinaryOperation(left, right, operator, expression); } diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index 166921e92..9cc6ed9d8 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -158,6 +158,7 @@ test.each([ let val = ${expression}; return typeof val ${operator} "${compareTo}";`; + expect(util.transpileString(code)).not.toMatch("__TS__TypeOf"); expect(util.transpileAndExecute(code)).toBe(expectResult); }); @@ -179,5 +180,6 @@ test.each([ let compareTo = "${compareTo}"; return typeof val ${operator} compareTo;`; + expect(util.transpileString(code)).toMatch("__TS__TypeOf"); expect(util.transpileAndExecute(code)).toBe(expectResult); }); From a940c71abd1a24427a81e46af7a0563a964dd031 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 13 Jun 2019 14:39:14 -0600 Subject: [PATCH 109/764] @forRange directive (#626) * @forRange directive * throwing error on all references to @forRange function outside for...of expression --- src/Decorator.ts | 3 ++ src/LuaTransformer.ts | 60 +++++++++++++++++++++- src/TSHelper.ts | 5 ++ src/TSTLErrors.ts | 4 ++ test/unit/loops.spec.ts | 109 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 1 deletion(-) diff --git a/src/Decorator.ts b/src/Decorator.ts index b8a4f3ad3..653c6218a 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -29,6 +29,8 @@ export class Decorator { return DecoratorKind.NoSelf; case "noselfinfile": return DecoratorKind.NoSelfInFile; + case "forrange": + return DecoratorKind.ForRange; } return undefined; @@ -61,4 +63,5 @@ export enum DecoratorKind { LuaTable = "LuaTable", NoSelf = "NoSelf", NoSelfInFile = "NoSelfInFile", + ForRange = "ForRange", } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 02e837a6e..3e8d88209 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2379,11 +2379,59 @@ export class LuaTransformer { } } + protected transformForRangeStatement(statement: ts.ForOfStatement, body: tstl.Block): StatementVisitResult { + if (!ts.isCallExpression(statement.expression)) { + throw TSTLErrors.InvalidForRangeCall(statement.expression, "Expression must be a call expression."); + } + + if (statement.expression.arguments.length < 2 || statement.expression.arguments.length > 3) { + throw TSTLErrors.InvalidForRangeCall( + statement.expression, + "@forRange function must take 2 or 3 arguments." + ); + } + + if (statement.expression.arguments.some(a => !tsHelper.isNumberType(this.checker.getTypeAtLocation(a)))) { + throw TSTLErrors.InvalidForRangeCall(statement.expression, "@forRange arguments must be number types."); + } + + if (!ts.isVariableDeclarationList(statement.initializer)) { + throw TSTLErrors.InvalidForRangeCall( + statement.initializer, + "@forRange loop must declare its own control variable." + ); + } + + const controlDeclaration = statement.initializer.declarations[0]; + if (!ts.isIdentifier(controlDeclaration.name)) { + throw TSTLErrors.InvalidForRangeCall(statement.initializer, "@forRange loop cannot use destructuring."); + } + + const controlType = this.checker.getTypeAtLocation(controlDeclaration); + if (controlType && !tsHelper.isNumberType(controlType)) { + throw TSTLErrors.InvalidForRangeCall( + statement.expression, + "@forRange function must return Iterable or Array." + ); + } + + const control = this.transformIdentifier(controlDeclaration.name); + const signature = this.checker.getResolvedSignature(statement.expression); + const [start, limit, step] = this.transformArguments(statement.expression.arguments, signature); + return tstl.createForStatement(body, control, start, limit, step, statement); + } + public transformForOfStatement(statement: ts.ForOfStatement): StatementVisitResult { // Transpile body const body = tstl.createBlock(this.transformLoopBody(statement)); - if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { + if ( + ts.isCallExpression(statement.expression) && + tsHelper.isForRangeType(statement.expression.expression, this.checker) + ) { + // ForRange + return this.transformForRangeStatement(statement, body); + } else if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { // LuaIterators return this.transformForOfLuaIteratorStatement(statement, body); } else if ( @@ -4638,6 +4686,16 @@ export class LuaTransformer { return tstl.createIdentifier("nil"); } + if (tsHelper.isForRangeType(identifier, this.checker)) { + const callExpression = tsHelper.findFirstNodeAbove(identifier, ts.isCallExpression); + if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { + throw TSTLErrors.InvalidForRangeCall( + identifier, + "@forRange function can only be used as an iterable in a for...of loop." + ); + } + } + const text = this.hasUnsafeIdentifierName(identifier) ? this.createSafeName(this.getIdentifierText(identifier)) : this.getIdentifierText(identifier); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 8d701512b..60ef5e17e 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -184,6 +184,11 @@ export class TSHelper { return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); } + public static isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.ForRange); + } + public static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { if (ts.isCallExpression(node)) { const signature = checker.getResolvedSignature(node); diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 26d08d1ca..fbe3d6a54 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -204,4 +204,8 @@ export class TSTLErrors { node ); }; + + public static InvalidForRangeCall = (node: ts.Node, message: string) => { + return new TranspileError(`Invalid @forRange call: ${message}`, node); + }; } diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 6c2bae455..96d4df6ee 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -797,3 +797,112 @@ test("while dead code after return", () => { expect(result).toBe(3); }); + +test.each([ + { args: [1, 10], expectResult: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, + { args: [1, 10, 2], expectResult: [1, 3, 5, 7, 9] }, + { args: [10, 1, -1], expectResult: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, + { args: [10, 1, -2], expectResult: [10, 8, 6, 4, 2] }, +])("@forRange loop", ({ args, expectResult }) => { + const tsHeader = "/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];"; + const code = ` + const results: number[] = []; + for (const i of luaRange(${args})) { + results.push(i); + } + return JSONStringify(results);`; + + const result = util.transpileAndExecute(code, undefined, undefined, tsHeader); + expect(JSON.parse(result)).toEqual(expectResult); +}); + +test("invalid non-ambient @forRange function", () => { + const code = ` + /** @forRange **/ function luaRange(i: number, j: number, k?: number): number[] { return []; } + for (const i of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function can only be used as an iterable in a for...of loop." + ).message + ); +}); + +test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => { + const code = ` + /** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; } + for (const i of luaRange(${args})) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.") + .message + ); +}); + +test("invalid @forRange control variable", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; + let i: number; + for (i of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange loop must declare its own control variable." + ).message + ); +}); + +test("invalid @forRange argument type", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: string, j: number): number[] { return []; } + for (const i of luaRange("foo", 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message + ); +}); + +test("invalid @forRange destructuring", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[][]; + for (const [i] of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message + ); +}); + +test("invalid @forRange return type", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): string[]; + for (const i of luaRange(1, 10)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function must return Iterable or Array." + ).message + ); +}); + +test.each([ + "const range = luaRange(1, 10);", + "console.log(luaRange);", + "luaRange.call(null, 0, 0, 0);", + "let array = [0, luaRange, 1];", + "const call: any; call(luaRange);", + "for (const i of [...luaRange(1, 10)]) {}", +])("invalid @forRange reference (%p)", statement => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; + ${statement}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function can only be used as an iterable in a for...of loop." + ).message + ); +}); From acd036bde57cf899b9902928f425a4010dcbfb9d Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 13 Jun 2019 14:58:13 -0600 Subject: [PATCH 110/764] @varArg directive (#630) * preventing pack/unpack of rest parameters referenced with spread operators * fixed referencing rest parameters in nested functions * moved some general logic into a helper * @elipsisForward directive to replace implicit optimization * fixed reference tracking when noHoisting is set * Allowing @elipsisForward to take no args so it can be used to access global elipsis * updated to use @varArg type instead of @elipsisForward function * removing unused error * Changed case in vararg --- src/Decorator.ts | 3 + src/LuaTransformer.ts | 48 ++++++-- src/TSHelper.ts | 17 +++ .../__snapshots__/transformation.spec.ts.snap | 2 +- .../transformation/functionRestArguments.ts | 4 +- test/unit/functions.spec.ts | 106 ++++++++++++++++++ 6 files changed, 167 insertions(+), 13 deletions(-) diff --git a/src/Decorator.ts b/src/Decorator.ts index 653c6218a..799f792c4 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -29,6 +29,8 @@ export class Decorator { return DecoratorKind.NoSelf; case "noselfinfile": return DecoratorKind.NoSelfInFile; + case "vararg": + return DecoratorKind.Vararg; case "forrange": return DecoratorKind.ForRange; } @@ -63,5 +65,6 @@ export enum DecoratorKind { LuaTable = "LuaTable", NoSelf = "NoSelf", NoSelfInFile = "NoSelfInFile", + Vararg = "Vararg", ForRange = "ForRange", } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 3e8d88209..8353de9b6 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -25,14 +25,14 @@ interface SymbolInfo { } interface FunctionDefinitionInfo { - referencedSymbols: Set; + referencedSymbols: Map; definition?: tstl.VariableDeclarationStatement | tstl.AssignmentStatement; } interface Scope { type: ScopeType; id: number; - referencedSymbols?: Set; + referencedSymbols?: Map; variableDeclarations?: tstl.VariableDeclarationStatement[]; functionDefinitions?: Map; importStatements?: tstl.Statement[]; @@ -1388,12 +1388,31 @@ export class LuaTransformer { return [paramNames, dotsLiteral, restParamName]; } + protected isRestParameterReferenced(identifier: tstl.Identifier, scope: Scope): boolean { + if (!identifier.symbolId) { + return true; + } + if (scope.referencedSymbols === undefined) { + return false; + } + const references = scope.referencedSymbols.get(identifier.symbolId); + if (!references) { + return false; + } + // Ignore references to @vararg types in spread elements + return references.some( + r => !r.parent || !ts.isSpreadElement(r.parent) || !tsHelper.isVarArgType(r, this.checker) + ); + } + protected transformFunctionBody( parameters: ts.NodeArray, body: ts.Block, spreadIdentifier?: tstl.Identifier ): [tstl.Statement[], Scope] { this.pushScope(ScopeType.Function); + const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); + const scope = this.popScope(); const headerStatements = []; @@ -1426,7 +1445,7 @@ export class LuaTransformer { } // Push spread operator here - if (spreadIdentifier) { + if (spreadIdentifier && this.isRestParameterReferenced(spreadIdentifier, scope)) { const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -1434,10 +1453,6 @@ export class LuaTransformer { // Binding pattern statements need to be after spread table is declared headerStatements.push(...bindingPatternDeclarations); - const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); - - const scope = this.popScope(); - return [headerStatements.concat(bodyStatements), scope]; } @@ -1844,7 +1859,7 @@ export class LuaTransformer { if (!scope.functionDefinitions) { scope.functionDefinitions = new Map(); } - const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Set() }; + const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Map() }; scope.functionDefinitions.set(name.symbolId, functionInfo); } return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); @@ -4603,6 +4618,10 @@ export class LuaTransformer { return innerExpression; } + if (ts.isIdentifier(expression.expression) && tsHelper.isVarArgType(expression.expression, this.checker)) { + return tstl.createDotsLiteral(expression); + } + const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isArrayType(type, this.checker, this.program)) { return this.createUnpackCall(innerExpression, expression); @@ -5278,13 +5297,20 @@ export class LuaTransformer { if (declaration && identifier.pos < declaration.pos) { throw TSTLErrors.ReferencedBeforeDeclaration(identifier); } - } else if (symbolId !== undefined) { + } + + if (symbolId !== undefined) { //Mark symbol as seen in all current scopes for (const scope of this.scopeStack) { if (!scope.referencedSymbols) { - scope.referencedSymbols = new Set(); + scope.referencedSymbols = new Map(); + } + let references = scope.referencedSymbols.get(symbolId); + if (!references) { + references = []; + scope.referencedSymbols.set(symbolId, references); } - scope.referencedSymbols.add(symbolId); + references.push(identifier); } } } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 60ef5e17e..eeb6373e1 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -184,6 +184,23 @@ export class TSHelper { return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); } + public static isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean { + const symbol = checker.getSymbolAtLocation(node); + if (!symbol) { + return false; + } + const declarations = symbol.getDeclarations(); + if (!declarations) { + return false; + } + return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined); + } + + public static isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return type !== undefined && TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.Vararg); + } + public static isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean { const type = checker.getTypeAtLocation(node); return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.ForRange); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 448f18106..58e99b895 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -256,6 +256,7 @@ end" exports[`Transformation (functionRestArguments) 1`] = ` "function varargsFunction(self, a, ...) local b = ({...}) + local c = b end" `; @@ -319,7 +320,6 @@ end function MyClass.prototype.____constructor(self) end function MyClass.prototype.varargsFunction(self, a, ...) - local b = ({...}) end" `; diff --git a/test/translation/transformation/functionRestArguments.ts b/test/translation/transformation/functionRestArguments.ts index 3b015a4d6..63649f09b 100644 --- a/test/translation/transformation/functionRestArguments.ts +++ b/test/translation/transformation/functionRestArguments.ts @@ -1 +1,3 @@ -function varargsFunction(a: string, ...b: string[]): void {} +function varargsFunction(a: string, ...b: string[]): void { + const c = b; +} diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index cbcd4ad87..9d4a9be13 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -504,3 +504,109 @@ test("Function rest binding pattern", () => { expect(result).toBe("defxyzabc"); }); + +test.each([{}, { noHoisting: true }])("Function rest parameter", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + return b.join(""); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function nested rest parameter", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + function bar() { + return b.join(""); + } + return bar(); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function nested rest spread", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + function bar() { + const c = [...b]; + return c.join(""); + } + return bar(); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function rest parameter (unreferenced)", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + return "foobar"; + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileString(code, compilerOptions)).not.toMatch("b = ({...})"); + expect(util.transpileAndExecute(code, compilerOptions)).toBe("foobar"); +}); + +test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + function foo(a: unknown, ...b: LuaVarArg) { + const c = [...b]; + return c.join(""); + } + function bar(a: unknown, ...b: LuaVarArg) { + return foo(a, ...b); + } + return bar("A", "B", "C", "D"); + `; + + const lua = util.transpileString(code, compilerOptions); + expect(lua).not.toMatch("b = ({...})"); + expect(lua).not.toMatch("unpack"); + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("@vararg array access", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + function foo(a: unknown, ...b: LuaVarArg) { + const c = [...b]; + return c.join("") + b[0]; + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCDB"); +}); + +test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + declare const arg: LuaVarArg; + const arr = [...arg]; + const result = arr.join(""); + `; + + const luaBody = util.transpileString(code, compilerOptions, false); + expect(luaBody).not.toMatch("unpack"); + + const lua = ` + function test(...) + ${luaBody} + return result + end + return test("A", "B", "C", "D") + `; + + expect(util.executeLua(lua)).toBe("ABCD"); +}); From 4ff68194b3f7ea4be07e1f8b13881197ded5161d Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 14 Jun 2019 21:51:50 +0500 Subject: [PATCH 111/764] Simplify const enum transform (#623) * Simplify const enum transform * Rename getConstEnumValue to tryGetConstEnumValue --- src/LuaTransformer.ts | 66 +++++++++++-------------------------------- src/TSTLErrors.ts | 3 -- 2 files changed, 17 insertions(+), 52 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 8353de9b6..a4144e126 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3889,6 +3889,11 @@ export class LuaTransformer { public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { const property = this.getIdentifierText(expression.name); + const constEnumValue = this.tryGetConstEnumValue(expression); + if (constEnumValue) { + return constEnumValue; + } + // Check for primitive types to override const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStringType(type)) { @@ -3898,8 +3903,6 @@ export class LuaTransformer { if (arrayPropertyAccess) { return arrayPropertyAccess; } - } else if (type.symbol && type.symbol.flags & ts.SymbolFlags.ConstEnum) { - return this.transformConstEnumValue(type, property, expression); } this.checkForLuaLibType(type); @@ -4062,16 +4065,12 @@ export class LuaTransformer { const table = this.transformExpression(expression.expression); const index = this.transformExpression(expression.argumentExpression); - const type = this.checker.getTypeAtLocation(expression.expression); - - if ( - type.symbol && - type.symbol.flags & ts.SymbolFlags.ConstEnum && - ts.isStringLiteral(expression.argumentExpression) - ) { - return this.transformConstEnumValue(type, expression.argumentExpression.text, expression); + const constEnumValue = this.tryGetConstEnumValue(expression); + if (constEnumValue) { + return constEnumValue; } + const type = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isArrayType(type, this.checker, this.program)) { return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), expression); } else if (tsHelper.isStringType(type)) { @@ -4085,46 +4084,15 @@ export class LuaTransformer { } } - protected transformConstEnumValue( - enumType: ts.EnumType, - memberName: string, - tsOriginal: ts.Node - ): ExpressionVisitResult { - // Assumption: the enum only has one declaration - const enumDeclaration = enumType.symbol.declarations.find(d => ts.isEnumDeclaration(d)) as ts.EnumDeclaration; - const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === memberName); - - if (enumMember) { - if (enumMember.initializer) { - if (ts.isIdentifier(enumMember.initializer)) { - const [isEnumMember, valueName] = tsHelper.isEnumMember(enumDeclaration, enumMember.initializer); - if (isEnumMember && valueName) { - if (ts.isIdentifier(valueName)) { - return this.transformConstEnumValue(enumType, valueName.text, tsOriginal); - } - } else { - return tstl.setNodeOriginal(this.transformExpression(enumMember.initializer), tsOriginal); - } - } else { - return tstl.setNodeOriginal(this.transformExpression(enumMember.initializer), tsOriginal); - } - } else { - let enumValue = 0; - for (const member of enumDeclaration.members) { - if (member === enumMember) { - return tstl.createNumericLiteral(enumValue, tsOriginal); - } - if (member.initializer === undefined) { - enumValue++; - } else if (ts.isNumericLiteral(member.initializer)) { - enumValue = Number(member.initializer.text) + 1; - } - } - - throw TSTLErrors.CouldNotFindEnumMember(enumDeclaration, memberName, tsOriginal); - } + private tryGetConstEnumValue( + node: ts.PropertyAccessExpression | ts.ElementAccessExpression + ): tstl.Expression | undefined { + const value = this.checker.getConstantValue(node); + if (typeof value === "string") { + return tstl.createStringLiteral(value, node); + } else if (typeof value === "number") { + return tstl.createNumericLiteral(value, node); } - throw TSTLErrors.CouldNotFindEnumMember(enumDeclaration, memberName, tsOriginal); } protected transformStringCallExpression(node: ts.CallExpression): tstl.Expression { diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index fbe3d6a54..8b2051fcd 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -8,9 +8,6 @@ export class TSTLErrors { public static CouldNotCast = (castName: string) => new Error(`Failed to cast all elements to expected type using ${castName}.`); - public static CouldNotFindEnumMember = (enumDeclaration: ts.EnumDeclaration, enumMember: string, node: ts.Node) => - new TranspileError(`Could not find ${enumMember} in ${enumDeclaration.name.text}`, node); - public static DefaultImportsNotSupported = (node: ts.Node) => new TranspileError(`Default Imports are not supported, please use named imports instead!`, node); From 2c04d6a0a5fdf5d140594160587fa4cbb2d9564b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 16 Jun 2019 22:28:34 +0200 Subject: [PATCH 112/764] 0.22.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 92ae2ed14..6f96ba7a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.21.1", + "version": "0.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ebb6e2591..3831b6213 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.21.1", + "version": "0.22.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 0e40fe93ca16697ba525dcc304252250521e7e94 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 16 Jun 2019 22:34:13 +0200 Subject: [PATCH 113/764] Updated some packages --- package-lock.json | 56 +++++++++++++++++++++--------------------- package.json | 14 +++++------ src/CompilerOptions.ts | 2 +- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6f96ba7a0..d61fd9683 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1340,9 +1340,9 @@ } }, "@types/jest": { - "version": "24.0.12", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.12.tgz", - "integrity": "sha512-60sjqMhat7i7XntZckcSGV8iREJyXXI6yFHZkSZvCPUeOnEJ/VP1rU/WpEWQ56mvoh8NhC+sfKAuJRTyGtCOow==", + "version": "24.0.15", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.15.tgz", + "integrity": "sha512-MU1HIvWUme74stAoc3mgAi+aMlgKOudgEvQDIm1v4RkrDudBh1T+NFp5sftpBAdXdx1J0PbdpJ+M2EsSOi1djA==", "dev": true, "requires": { "@types/jest-diff": "*" @@ -1361,9 +1361,9 @@ "dev": true }, "@types/node": { - "version": "11.13.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.0.tgz", - "integrity": "sha512-rx29MMkRdVmzunmiA4lzBYJNnXsW/PhG4kMBy2ATsYaDjGGR75dCFEVVROKpNwlVdcUX3xxlghKQOeDPBJobng==", + "version": "11.13.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.14.tgz", + "integrity": "sha512-9NjFOB6UUGjJLNANmyIouuaN8YPsPgC4DCOd5lU+DL7HSX/RCfzz0JOtHlspEJq1Ll/JUu/8Cm4wzxpZ8w5sjQ==", "dev": true }, "@types/resolve": { @@ -2327,9 +2327,9 @@ "dev": true }, "diff": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.4.0.tgz", - "integrity": "sha512-QpVuMTEoJMF7cKzi6bvWhRulU1fZqZnvyVQgNhPaxxuTYwyjn/j1v9falseQ/uXWwPnO56RBfwtg4h/EQXmucA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "diff-sequences": { @@ -7095,9 +7095,9 @@ "dev": true }, "prettier": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.17.0.tgz", - "integrity": "sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw==", + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", "dev": true }, "pretty-format": { @@ -7334,9 +7334,9 @@ "dev": true }, "resolve": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz", - "integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", + "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "requires": { "path-parse": "^1.0.6" } @@ -8024,9 +8024,9 @@ } }, "ts-node": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.0.tgz", - "integrity": "sha512-klJsfswHP0FuOLsvBZ/zzCfUvakOSSxds78mVeK7I+qP76YWtxf16hEZsp3U+b0kIo82R5UatGFeblYMqabb2Q==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", + "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", "dev": true, "requires": { "arrify": "^1.0.0", @@ -8040,15 +8040,15 @@ } }, "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", "dev": true }, "tslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz", - "integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==", + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", + "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -8057,7 +8057,7 @@ "commander": "^2.12.1", "diff": "^3.2.0", "glob": "^7.1.1", - "js-yaml": "^3.13.0", + "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "resolve": "^1.3.2", @@ -8100,9 +8100,9 @@ } }, "typescript": { - "version": "3.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.4.5.tgz", - "integrity": "sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==" + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", + "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==" }, "uglify-js": { "version": "3.5.10", diff --git a/package.json b/package.json index 3831b6213..8bd18dd40 100644 --- a/package.json +++ b/package.json @@ -39,21 +39,21 @@ "node": ">=8.5.0" }, "dependencies": { - "resolve": "^1.10.1", + "resolve": "^1.11.0", "source-map": "^0.7.3", - "typescript": "^3.4.5" + "typescript": "^3.5.2" }, "devDependencies": { "@types/glob": "^7.1.1", - "@types/jest": "^24.0.12", - "@types/node": "^11.13.0", + "@types/jest": "^24.0.15", + "@types/node": "^11.13.14", "@types/resolve": "0.0.8", "fengari": "^0.1.4", "jest": "^24.8.0", "jest-circus": "^24.8.0", - "prettier": "^1.17.0", + "prettier": "^1.18.2", "ts-jest": "^24.0.2", - "ts-node": "^7.0.0", - "tslint": "^5.16.0" + "ts-node": "^7.0.1", + "tslint": "^5.17.0" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index b429790b3..ca09566d0 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { - [_ in keyof T]: infer U + [_ in keyof T]: infer U; } ? U : never; From f18c6a1c95d691912d61473f6b1aec7d282ed16d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 16 Jun 2019 22:40:05 +0200 Subject: [PATCH 114/764] 0.22.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index d61fd9683..20af9473f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.22.0", + "version": "0.22.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 8bd18dd40..6f8d6a888 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.22.0", + "version": "0.22.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 3c418920ea3a61a42b99a6b2cc64430615f74ccf Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 16 Jun 2019 22:46:24 +0200 Subject: [PATCH 115/764] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index de02da036..1afd5d2e7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.22.0 + +- Added the [@vararg](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#vararg) directive. +- Added the [@forRange](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#forRange) directive. +- Custom ts transformers can now be loaded from tsconfig. + +- Fixed default tstl header incorrectly showing up above lualib functions. +- Some improvements to typeof expressions. + ## 0.21.0 - Imports/exports that are ambient (declarations, types, interfaces, etc) or are not used in value positions no longer generate `require` statements. From 2535f39d319b2ebe97f58003da505c6be98e0481 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 19 Jun 2019 12:22:14 -0600 Subject: [PATCH 116/764] using full form of 'super' call when base is an exported identfier (#637) --- src/LuaTransformer.ts | 12 ++++++++---- test/unit/class.spec.ts | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index a4144e126..0c46cd7c5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3568,11 +3568,15 @@ export class LuaTransformer { } const extendsExpression = typeNode.expression; - let baseClassName: tstl.AssignmentLeftHandSideExpression; + let baseClassName: tstl.AssignmentLeftHandSideExpression | undefined; if (ts.isIdentifier(extendsExpression)) { - // Use "baseClassName" if base is a simple identifier - baseClassName = this.transformIdentifier(extendsExpression); - } else { + const symbol = this.checker.getSymbolAtLocation(extendsExpression); + if (symbol && !this.isSymbolExported(symbol)) { + // Use "baseClassName" if base is a simple identifier + baseClassName = this.transformIdentifier(extendsExpression); + } + } + if (!baseClassName) { if (classDeclaration.name === undefined) { throw TSTLErrors.MissingClassName(expression); } diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index c4d2943bb..6fff9ecb9 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -198,6 +198,27 @@ test("SubclassConstructor", () => { expect(result).toBe(11); }); +test("Subclass constructor across merged namespace", () => { + const tsHeader = ` + namespace NS { + export class Super { + prop: string; + constructor() { + this.prop = "foo"; + } + } + } + namespace NS { + export class Sub extends Super { + constructor() { + super(); + } + } + }`; + + expect(util.transpileAndExecute("return (new NS.Sub()).prop", undefined, undefined, tsHeader)).toBe("foo"); +}); + test("classSuper", () => { const result = util.transpileAndExecute( `class a { From bccecc57c40ddfe4085cf2055ff75777eca5d3bd Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Thu, 20 Jun 2019 17:29:49 +1000 Subject: [PATCH 117/764] Fix noResolution for named imports (#636) * Fix noResolution for named imports * Fix no element imports and use alternate symbol resolution solution * Use collectCustomDecorators and remove isNonNamespaceModuleDeclaration * Change decorator map abbreviation --- src/LuaTransformer.ts | 18 +++++--- test/unit/require.spec.ts | 96 ++++++++++++++++++++++++++++++++++----- 2 files changed, 96 insertions(+), 18 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 0c46cd7c5..7b14c972c 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "./CompilerOptions"; -import { DecoratorKind } from "./Decorator"; +import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import { LuaLibFeature } from "./LuaLib"; import { ContextType, TSHelper as tsHelper } from "./TSHelper"; @@ -357,11 +357,21 @@ export class LuaTransformer { scope.importStatements = []; } + let shouldResolve = true; + const moduleOwnerSymbol = this.checker.getSymbolAtLocation(statement.moduleSpecifier); + if (moduleOwnerSymbol) { + const decorators = new Map(); + tsHelper.collectCustomDecorators(moduleOwnerSymbol, this.checker, decorators); + if (decorators.has(DecoratorKind.NoResolution)) { + shouldResolve = false; + } + } + const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; const importPath = moduleSpecifier.text.replace(new RegExp('"', "g"), ""); + const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); if (!statement.importClause) { - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); result.push(tstl.createExpressionStatement(requireCall)); if (scope.importStatements) { scope.importStatements.push(...result); @@ -376,10 +386,6 @@ export class LuaTransformer { throw TSTLErrors.UnsupportedImportType(statement.importClause); } - const type = this.checker.getTypeAtLocation(imports); - const shouldResolve = !tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.NoResolution); - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); - if (ts.isNamedImports(imports)) { const filteredElements = imports.elements.filter(e => { const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index b6db8f877..3f864b3fc 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -91,20 +91,92 @@ test.each([ } ); -test.each([{ comment: "", expectedPath: "src.fake" }, { comment: "/** @noResolution */", expectedPath: "fake" }])( - "noResolution on ambient modules causes no path alterations (%p)", - ({ comment, expectedPath }) => { - const lua = util.transpileString({ - "src/main.ts": `import * as fake from "fake"; fake;`, - "module.d.ts": `${comment} declare module "fake" {}`, - }); - const match = requireRegex.exec(lua); +test.each([ + { + declarationStatement: ` + declare module 'fake' {} + `, + mainCode: "import * as fake from 'fake'; fake;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' {} + `, + mainCode: "import * as fake from 'fake'; fake;", + expectedPath: "fake", + }, + { + declarationStatement: ` + declare module 'fake' { + export const x: number; + } + `, + mainCode: "import { x } from 'fake'; x;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' { + export const x: number; + } + `, + mainCode: "import { x } from 'fake'; x;", + expectedPath: "fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' { + export const x: number; + } + declare module 'fake' { + export const y: number; + } + `, + mainCode: "import { y } from 'fake'; y;", + expectedPath: "fake", + }, + { + declarationStatement: ` + declare module 'fake' { + export const x: number; + } + declare module 'fake' { + export const y: number; + } + `, + mainCode: "import { y } from 'fake'; y;", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + declare module 'fake' {} + `, + mainCode: "import 'fake';", + expectedPath: "src.fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module 'fake' {} + `, + mainCode: "import 'fake';", + expectedPath: "fake", + }, +])("noResolution prevents any module path resolution behaviour", ({ declarationStatement, mainCode, expectedPath }) => { + const lua = util.transpileString({ + "src/main.ts": mainCode, + "module.d.ts": declarationStatement, + }); + const match = requireRegex.exec(lua); - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe(expectedPath); - } + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe(expectedPath); } -); +}); test("ImportEquals declaration require", () => { const input = `import foo = require("./foo/bar"); foo;`; From d5f644c0bdba23878455d853e330f10454f2a420 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 20 Jun 2019 07:30:32 -0600 Subject: [PATCH 118/764] More source map stuff (#633) * source-mapping function 'end' * support for name mapping in sourcemaps * mapping class new and generated constuctors to declaration * clarification comment for constructor original node * clarifying generated constructor check better --- src/LuaAST.ts | 5 +++- src/LuaPrinter.ts | 28 ++++++++++++-------- src/LuaTransformer.ts | 32 +++++++++++++++-------- test/unit/sourcemaps.spec.ts | 50 +++++++++++++++++++++++++++++++++++- 4 files changed, 93 insertions(+), 22 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 7616177e4..111bf8aa2 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -830,6 +830,7 @@ export function createMethodCallExpression( export interface Identifier extends Expression { kind: SyntaxKind.Identifier; text: string; + originalName?: string; symbolId?: SymbolId; } @@ -841,16 +842,18 @@ export function createIdentifier( text: string | ts.__String, tsOriginal?: ts.Node, symbolId?: SymbolId, + originalName?: string, parent?: Node ): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; expression.text = text as string; expression.symbolId = symbolId; + expression.originalName = originalName; return expression; } export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): Identifier { - return createIdentifier(identifier.text, tsOriginal, identifier.symbolId); + return createIdentifier(identifier.text, tsOriginal, identifier.symbolId, identifier.originalName); } export function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 5b1d8a8c4..50be8ebbf 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -157,12 +157,12 @@ export class LuaPrinter { return this.concatNodes(this.currentIndent, input); } - protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[]): SourceNode { + protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode { const originalPos = tstl.getOriginalPos(node); return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined - ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks) - : new SourceNode(null, null, this.sourceFile, chunks); // tslint:disable-line:no-null-keyword + ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks, name) + : new SourceNode(null, null, this.sourceFile, chunks, name); // tslint:disable-line:no-null-keyword } protected concatNodes(...chunks: SourceChunk[]): SourceNode { @@ -274,7 +274,7 @@ export class LuaPrinter { } } - return this.concatNodes(...chunks); + return this.createSourceNode(statement, chunks); } public printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { @@ -516,13 +516,13 @@ export class LuaPrinter { ...this.joinChunks(", ", returnStatement.expressions.map(e => this.printExpression(e))), ]; chunks.push(this.createSourceNode(returnStatement, returnNode)); - chunks.push(" end"); + chunks.push(this.createSourceNode(expression, " end")); } else { chunks.push("\n"); this.pushIndent(); chunks.push(this.printBlock(expression.body)); this.popIndent(); - chunks.push(this.indent("end")); + chunks.push(this.indent(this.createSourceNode(expression, "end"))); } return this.createSourceNode(expression, chunks); @@ -541,7 +541,7 @@ export class LuaPrinter { this.pushIndent(); chunks.push(this.printBlock(expression.body)); this.popIndent(); - chunks.push(this.indent("end")); + chunks.push(this.indent(this.createSourceNode(statement, "end"))); return this.createSourceNode(expression, chunks); } @@ -661,7 +661,11 @@ export class LuaPrinter { } public printIdentifier(expression: tstl.Identifier): SourceNode { - return this.createSourceNode(expression, expression.text); + return this.createSourceNode( + expression, + expression.text, + expression.originalName !== expression.text ? expression.originalName : undefined + ); } public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { @@ -734,12 +738,15 @@ export class LuaPrinter { } if ( currentMapping.generated.line === generatedLine && - currentMapping.generated.column === generatedColumn + currentMapping.generated.column === generatedColumn && + currentMapping.name === sourceNode.name ) { return false; } return ( - currentMapping.original.line !== sourceNode.line || currentMapping.original.column !== sourceNode.column + currentMapping.original.line !== sourceNode.line || + currentMapping.original.column !== sourceNode.column || + currentMapping.name !== sourceNode.name ); }; @@ -749,6 +756,7 @@ export class LuaPrinter { source: sourceNode.source, original: { line: sourceNode.line, column: sourceNode.column }, generated: { line: generatedLine, column: generatedColumn }, + name: sourceNode.name, }; map.addMapping(currentMapping); } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7b14c972c..11e79fb8d 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -631,7 +631,12 @@ export class LuaTransformer { let localClassName: tstl.Identifier; if (this.isUnsafeName(className.text)) { - localClassName = tstl.createIdentifier(this.createSafeName(className.text), undefined, className.symbolId); + localClassName = tstl.createIdentifier( + this.createSafeName(className.text), + undefined, + className.symbolId, + className.text + ); tstl.setNodePosition(localClassName, className); } else { localClassName = className; @@ -1066,7 +1071,8 @@ export class LuaTransformer { tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ tstl.createTableExpression(), createClassPrototype(), - ]) + ]), + statement ); newFuncStatements.push(assignSelf); @@ -1074,12 +1080,13 @@ export class LuaTransformer { const callConstructor = tstl.createExpressionStatement( tstl.createMethodCallExpression(this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [ tstl.createDotsLiteral(), - ]) + ]), + statement ); newFuncStatements.push(callConstructor); // return self - const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()]); + const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()], statement); newFuncStatements.push(returnSelf); // function localClassName.new(construct, ...) ... end @@ -1092,7 +1099,8 @@ export class LuaTransformer { tstl.createDotsLiteral(), undefined, tstl.FunctionExpressionFlags.Declaration - ) + ), + statement ); result.push(newFunc); @@ -1134,7 +1142,8 @@ export class LuaTransformer { this.createSelfIdentifier(), getterName, tstl.createNilLiteral(), - ]) + ]), + classDeclaration.members.find(ts.isConstructorDeclaration) || classDeclaration ); statements.push(resetGetter); } @@ -1226,6 +1235,8 @@ export class LuaTransformer { const block: tstl.Block = tstl.createBlock(bodyWithFieldInitializers); + const constructorWasGenerated = statement.pos === -1; + const result = tstl.createAssignmentStatement( this.createConstructorName(className), tstl.createFunctionExpression( @@ -1235,7 +1246,7 @@ export class LuaTransformer { restParamName, tstl.FunctionExpressionFlags.Declaration ), - statement + constructorWasGenerated ? classDeclaration : statement ); return result; @@ -1556,7 +1567,8 @@ export class LuaTransformer { return tstl.createIdentifier( this.createSafeName(declaration.name.text), declaration.name, - moduleSymbol && this.symbolIds.get(moduleSymbol) + moduleSymbol && this.symbolIds.get(moduleSymbol), + declaration.name.text ); } return this.transformIdentifier(declaration.name as ts.Identifier); @@ -4698,7 +4710,7 @@ export class LuaTransformer { : this.getIdentifierText(identifier); const symbolId = this.getIdentifierSymbolId(identifier); - return tstl.createIdentifier(text, identifier, symbolId); + return tstl.createIdentifier(text, identifier, symbolId, this.getIdentifierText(identifier)); } protected transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { @@ -4927,7 +4939,7 @@ export class LuaTransformer { } protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { - return tstl.createIdentifier("self", tsOriginal); + return tstl.createIdentifier("self", tsOriginal, undefined, "this"); } protected createExportsIdentifier(): tstl.Identifier { diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/sourcemaps.spec.ts index 94cf8aca1..51d01bbc8 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/sourcemaps.spec.ts @@ -33,6 +33,7 @@ test.each([ { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, { luaPattern: "function def(", typeScriptPattern: "function def() {" }, { luaPattern: "return abc(", typeScriptPattern: "return abc(" }, + { luaPattern: "end", typeScriptPattern: "function def() {" }, ], }, { @@ -69,7 +70,11 @@ test.each([ }, { typeScriptSource: ` - class Bar extends Foo {} + class Bar extends Foo { + constructor() { + super(); + } + } `, assertPatterns: [ @@ -82,8 +87,27 @@ test.each([ { luaPattern: "Bar.____super = Foo", typeScriptPattern: "Foo {" }, { luaPattern: "setmetatable(Bar,", typeScriptPattern: "Foo {" }, { luaPattern: "setmetatable(Bar.prototype,", typeScriptPattern: "Foo {" }, + { luaPattern: "function Bar.new", typeScriptPattern: "class Bar" }, + { luaPattern: "function Bar.prototype.____constructor", typeScriptPattern: "constructor" }, ], }, + { + typeScriptSource: ` + class Foo { + } + `, + + assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }], + }, + { + typeScriptSource: ` + class Foo { + bar = "baz"; + } + `, + + assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }], + }, { typeScriptSource: ` declare const arr: string[]; @@ -161,6 +185,30 @@ test("Source map has correct source root", async () => { expect(sourceMap.sourceRoot).toBe("."); }); +test.each([ + { code: `const type = "foobar";`, name: "type" }, + { code: `const and = "foobar";`, name: "and" }, + { code: `const $$$ = "foobar";`, name: "$$$" }, + { code: `const foo = { bar() { console.log(this); } };`, name: "this" }, + { code: `function foo($$$: unknown) {}`, name: "$$$" }, + { code: `class $$$ {}`, name: "$$$" }, + { code: `namespace $$$ { const foo = "bar"; }`, name: "$$$" }, +])("Source map has correct name mappings (%p)", async ({ code, name }) => { + const { file } = util.transpileStringResult(code); + + if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + + const consumer = await new SourceMapConsumer(file.sourceMap); + const typescriptPosition = lineAndColumnOf(code, name); + let mappedName: string | undefined; + consumer.eachMapping(mapping => { + if (mapping.originalLine === typescriptPosition.line && mapping.originalColumn === typescriptPosition.column) { + mappedName = mapping.name; + } + }); + expect(mappedName).toBe(name); +}); + test("sourceMapTraceback saves sourcemap in _G", () => { // Arrange const typeScriptSource = ` From d9a996fcd523306aff3f05ac0d3c5c59785dcee8 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 23 Jun 2019 17:33:06 +0500 Subject: [PATCH 119/764] Make utils regular functions instead of utility classes (#640) --- src/LuaPrinter.ts | 10 +- src/LuaTransformer.ts | 54 +- src/TSHelper.ts | 1342 ++++++++--------- src/TSTLErrors.ts | 304 ++-- test/unit/assignments/assignments.spec.ts | 2 +- .../invalidFunctionAssignments.spec.ts | 2 +- test/unit/class.spec.ts | 2 +- test/unit/classDecorator.spec.ts | 2 +- test/unit/conditionals.spec.ts | 2 +- test/unit/decoratorCustomConstructor.spec.ts | 2 +- test/unit/decoratorMetaExtension.spec.ts | 2 +- test/unit/enum.spec.ts | 2 +- test/unit/error.spec.ts | 2 +- test/unit/expressions.spec.ts | 2 +- test/unit/functions.spec.ts | 2 +- test/unit/hoisting.spec.ts | 2 +- test/unit/identifiers.spec.ts | 2 +- test/unit/json.spec.ts | 2 +- test/unit/loops.spec.ts | 2 +- test/unit/luaTable.spec.ts | 2 +- test/unit/modules.spec.ts | 2 +- test/unit/string.spec.ts | 2 +- test/unit/tshelper.spec.ts | 2 +- test/unit/typechecking.spec.ts | 2 +- 24 files changed, 866 insertions(+), 884 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 50be8ebbf..f2b9b4870 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,12 +1,10 @@ import * as path from "path"; - -import { Mapping, SourceNode, SourceMapGenerator } from "source-map"; - -import * as tstl from "./LuaAST"; +import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; -import { LuaLib, LuaLibFeature } from "./LuaLib"; -import { TSHelper as tsHelper } from "./TSHelper"; +import * as tstl from "./LuaAST"; import { luaKeywords } from "./LuaKeywords"; +import { LuaLib, LuaLibFeature } from "./LuaLib"; +import * as tsHelper from "./TSHelper"; type SourceChunk = string | SourceNode; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 11e79fb8d..d1fd6226e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4,8 +4,8 @@ import { CompilerOptions, LuaTarget } from "./CompilerOptions"; import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import { LuaLibFeature } from "./LuaLib"; -import { ContextType, TSHelper as tsHelper } from "./TSHelper"; -import { TSTLErrors } from "./TSTLErrors"; +import * as tsHelper from "./TSHelper"; +import * as TSTLErrors from "./TSTLErrors"; import { luaKeywords, luaBuiltins } from "./LuaKeywords"; export type StatementVisitResult = tstl.Statement | tstl.Statement[] | undefined; @@ -465,7 +465,7 @@ export class LuaTransformer { protected validateClassElement(element: ts.ClassElement): void { if (element.name && (ts.isStringLiteral(element.name) || ts.isIdentifier(element.name))) { - if (tsHelper.isStatic(element) && element.name.text === "new") { + if (tsHelper.isStaticNode(element) && element.name.text === "new") { throw TSTLErrors.ForbiddenStaticClassPropertyName(element, element.name.text); } } @@ -579,7 +579,7 @@ export class LuaTransformer { } // LuaTable classes must be ambient - if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isAmbient(statement)) { + if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isAmbientNode(statement)) { throw TSTLErrors.ForbiddenLuaTableNonDeclaration(statement); } @@ -587,8 +587,8 @@ export class LuaTransformer { const properties = statement.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); // Divide properties into static and non-static - const staticFields = properties.filter(tsHelper.isStatic); - const instanceFields = properties.filter(prop => !tsHelper.isStatic(prop)); + const staticFields = properties.filter(tsHelper.isStaticNode); + const instanceFields = properties.filter(prop => !tsHelper.isStaticNode(prop)); const result: tstl.Statement[] = []; @@ -808,7 +808,7 @@ export class LuaTransformer { ); // localClassName.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStatic(m))) { + if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStaticNode(m))) { const classGetters = tstl.createTableIndexExpression( tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("____getters") @@ -836,7 +836,7 @@ export class LuaTransformer { result.push(assignClassIndex); // localClassName.____setters = {} - if (statement.members.some(m => ts.isSetAccessor(m) && tsHelper.isStatic(m))) { + if (statement.members.some(m => ts.isSetAccessor(m) && tsHelper.isStaticNode(m))) { const classSetters = tstl.createTableIndexExpression( tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("____setters") @@ -866,7 +866,7 @@ export class LuaTransformer { result.push(assignClassPrototype); // localClassName.prototype.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStatic(m))) { + if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStaticNode(m))) { const classPrototypeGetters = tstl.createTableIndexExpression( createClassPrototype(), tstl.createStringLiteral("____getters") @@ -901,7 +901,7 @@ export class LuaTransformer { result.push(assignClassPrototypeIndex); } - if (statement.members.some(m => ts.isSetAccessor(m) && !tsHelper.isStatic(m))) { + if (statement.members.some(m => ts.isSetAccessor(m) && !tsHelper.isStaticNode(m))) { // localClassName.prototype.____setters = {} const classPrototypeSetters = tstl.createTableIndexExpression( createClassPrototype(), @@ -1273,7 +1273,7 @@ export class LuaTransformer { tstl.FunctionExpressionFlags.Declaration ); - const methodTable = tsHelper.isStatic(getAccessor) + const methodTable = tsHelper.isStaticNode(getAccessor) ? tstl.cloneIdentifier(className) : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); @@ -1306,7 +1306,7 @@ export class LuaTransformer { tstl.FunctionExpressionFlags.Declaration ); - const methodTable = tsHelper.isStatic(setAccessor) + const methodTable = tsHelper.isStaticNode(setAccessor) ? tstl.cloneIdentifier(className) : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); @@ -1335,7 +1335,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(node); const context = - tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void ? this.createSelfIdentifier() : undefined; const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); @@ -1351,7 +1351,7 @@ export class LuaTransformer { ); const methodTable = - tsHelper.isStatic(node) || noPrototype + tsHelper.isStaticNode(node) || noPrototype ? tstl.cloneIdentifier(className) : tstl.createTableIndexExpression( tstl.cloneIdentifier(className), @@ -1847,7 +1847,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(functionDeclaration); const context = - tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void + tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void ? this.createSelfIdentifier() : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); @@ -3481,7 +3481,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(node); let context: tstl.Identifier | undefined; - if (tsHelper.getFunctionContextType(type, this.checker) !== ContextType.Void) { + if (tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void) { if (ts.isArrowFunction(node)) { // dummy context for arrow functions with parameters if (node.parameters.length > 0) { @@ -3661,7 +3661,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); if ( signatureDeclaration && - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === tsHelper.ContextType.Void ) { parameters = this.transformArguments(expression.arguments, signature); } else { @@ -3805,7 +3805,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); if ( !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void ) { if ( luaKeywords.has(node.expression.name.text) || @@ -3845,7 +3845,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); if ( !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void ) { // Pass left-side as context @@ -4557,7 +4557,7 @@ export class LuaTransformer { protected transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.getFunctionContextType(callerType, this.checker) === ContextType.Void) { + if (tsHelper.getFunctionContextType(callerType, this.checker) === tsHelper.ContextType.Void) { throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } const signature = this.checker.getResolvedSignature(node); @@ -5075,10 +5075,14 @@ export class LuaTransformer { const fromContext = tsHelper.getFunctionContextType(fromType, this.checker); const toContext = tsHelper.getFunctionContextType(toType, this.checker); - if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { + if (fromContext === tsHelper.ContextType.Mixed || toContext === tsHelper.ContextType.Mixed) { throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); - } else if (fromContext !== toContext && fromContext !== ContextType.None && toContext !== ContextType.None) { - if (toContext === ContextType.Void) { + } else if ( + fromContext !== toContext && + fromContext !== tsHelper.ContextType.None && + toContext !== tsHelper.ContextType.None + ) { + if (toContext === tsHelper.ContextType.Void) { throw TSTLErrors.UnsupportedNoSelfFunctionConversion(node, toName); } else { throw TSTLErrors.UnsupportedSelfFunctionConversion(node, toName); @@ -5239,7 +5243,7 @@ export class LuaTransformer { protected hasUnsafeSymbolName(symbol: ts.Symbol, tsOriginal?: ts.Identifier): boolean { const isLuaKeyword = luaKeywords.has(symbol.name); const isInvalidIdentifier = !tsHelper.isValidLuaIdentifier(symbol.name); - const isAmbient = symbol.declarations.some(d => tsHelper.isAmbient(d)); + const isAmbient = symbol.declarations.some(d => tsHelper.isAmbientNode(d)); if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { // Catch ambient declarations of identifiers with bad names throw TSTLErrors.InvalidAmbientIdentifierName(tsOriginal || ts.createIdentifier(symbol.name)); @@ -5545,7 +5549,7 @@ export class LuaTransformer { const expression = decorator.expression; const type = this.checker.getTypeAtLocation(expression); const context = tsHelper.getFunctionContextType(type, this.checker); - if (context === ContextType.Void) { + if (context === tsHelper.ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } return this.transformExpression(expression); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index eeb6373e1..aa21e8698 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -29,825 +29,809 @@ const defaultArrayCallMethodNames = new Set([ "flatMap", ]); -export class TSHelper { - public static getExtendedTypeNode( - node: ts.ClassLikeDeclarationBase, - checker: ts.TypeChecker - ): ts.ExpressionWithTypeArguments | undefined { - if (node && node.heritageClauses) { - for (const clause of node.heritageClauses) { - if (clause.token === ts.SyntaxKind.ExtendsKeyword) { - const superType = checker.getTypeAtLocation(clause.types[0]); - const decorators = TSHelper.getCustomDecorators(superType, checker); - if (!decorators.has(DecoratorKind.PureAbstract)) { - return clause.types[0]; - } +export function getExtendedTypeNode( + node: ts.ClassLikeDeclarationBase, + checker: ts.TypeChecker +): ts.ExpressionWithTypeArguments | undefined { + if (node && node.heritageClauses) { + for (const clause of node.heritageClauses) { + if (clause.token === ts.SyntaxKind.ExtendsKeyword) { + const superType = checker.getTypeAtLocation(clause.types[0]); + const decorators = getCustomDecorators(superType, checker); + if (!decorators.has(DecoratorKind.PureAbstract)) { + return clause.types[0]; } } } - return undefined; } + return undefined; +} - public static getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined { - const extendedTypeNode = TSHelper.getExtendedTypeNode(node, checker); - return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode); - } +export function getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined { + const extendedTypeNode = getExtendedTypeNode(node, checker); + return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode); +} - public static isFileModule(sourceFile: ts.SourceFile): boolean { - return sourceFile.statements.some(TSHelper.isStatementExported); - } +export function isFileModule(sourceFile: ts.SourceFile): boolean { + return sourceFile.statements.some(isStatementExported); +} - public static isStatementExported(statement: ts.Statement): boolean { - if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { - return true; - } - if (ts.isVariableStatement(statement)) { - return statement.declarationList.declarations.some( - declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 - ); - } - return ( - TSHelper.isDeclaration(statement) && - (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0 +export function isStatementExported(statement: ts.Statement): boolean { + if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { + return true; + } + if (ts.isVariableStatement(statement)) { + return statement.declarationList.declarations.some( + declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 ); } + return isDeclaration(statement) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; +} - public static getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { - const declarations = symbol.getDeclarations(); - if (declarations) { - return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0); - } - return undefined; +export function getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { + const declarations = symbol.getDeclarations(); + if (declarations) { + return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0); } + return undefined; +} - public static isDeclaration(node: ts.Node): node is ts.Declaration { - return ( - ts.isEnumDeclaration(node) || - ts.isClassDeclaration(node) || - ts.isExportDeclaration(node) || - ts.isImportDeclaration(node) || - ts.isMethodDeclaration(node) || - ts.isModuleDeclaration(node) || - ts.isFunctionDeclaration(node) || - ts.isVariableDeclaration(node) || - ts.isInterfaceDeclaration(node) || - ts.isTypeAliasDeclaration(node) || - ts.isNamespaceExportDeclaration(node) - ); - } +export function isDeclaration(node: ts.Node): node is ts.Declaration { + return ( + ts.isEnumDeclaration(node) || + ts.isClassDeclaration(node) || + ts.isExportDeclaration(node) || + ts.isImportDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isModuleDeclaration(node) || + ts.isFunctionDeclaration(node) || + ts.isVariableDeclaration(node) || + ts.isInterfaceDeclaration(node) || + ts.isTypeAliasDeclaration(node) || + ts.isNamespaceExportDeclaration(node) + ); +} - public static isInDestructingAssignment(node: ts.Node): boolean { - return ( - node.parent && - ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || - (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) - ); - } +export function isInDestructingAssignment(node: ts.Node): boolean { + return ( + node.parent && + ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || + (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) + ); +} - // iterate over a type and its bases until the callback returns true. - public static forTypeOrAnySupertype( - type: ts.Type, - checker: ts.TypeChecker, - predicate: (type: ts.Type) => boolean - ): boolean { - if (predicate(type)) { - return true; - } - if (!type.isClassOrInterface() && type.symbol) { - type = checker.getDeclaredTypeOfSymbol(type.symbol); - } - const superTypes = type.getBaseTypes(); - if (superTypes) { - for (const superType of superTypes) { - if (TSHelper.forTypeOrAnySupertype(superType, checker, predicate)) { - return true; - } +// iterate over a type and its bases until the callback returns true. +export function forTypeOrAnySupertype( + type: ts.Type, + checker: ts.TypeChecker, + predicate: (type: ts.Type) => boolean +): boolean { + if (predicate(type)) { + return true; + } + if (!type.isClassOrInterface() && type.symbol) { + type = checker.getDeclaredTypeOfSymbol(type.symbol); + } + const superTypes = type.getBaseTypes(); + if (superTypes) { + for (const superType of superTypes) { + if (forTypeOrAnySupertype(superType, checker, predicate)) { + return true; } } - return false; - } - - public static isAmbient(node: ts.Declaration): boolean { - return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0); - } - - public static isStatic(node: ts.Node): boolean { - return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); } + return false; +} - public static isStringType(type: ts.Type): boolean { - return ( - (type.flags & ts.TypeFlags.String) !== 0 || - (type.flags & ts.TypeFlags.StringLike) !== 0 || - (type.flags & ts.TypeFlags.StringLiteral) !== 0 - ); - } +export function isAmbientNode(node: ts.Declaration): boolean { + return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0); +} - public static isNumberType(type: ts.Type): boolean { - return ( - (type.flags & ts.TypeFlags.Number) !== 0 || - (type.flags & ts.TypeFlags.NumberLike) !== 0 || - (type.flags & ts.TypeFlags.NumberLiteral) !== 0 - ); - } +export function isStaticNode(node: ts.Node): boolean { + return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); +} - public static isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - if (type.isUnionOrIntersection()) { - return type.types.some(t => TSHelper.isExplicitArrayType(t, checker, program)); - } +export function isStringType(type: ts.Type): boolean { + return ( + (type.flags & ts.TypeFlags.String) !== 0 || + (type.flags & ts.TypeFlags.StringLike) !== 0 || + (type.flags & ts.TypeFlags.StringLiteral) !== 0 + ); +} - if (TSHelper.isStandardLibraryType(type, "ReadonlyArray", program)) { - return true; - } +export function isNumberType(type: ts.Type): boolean { + return ( + (type.flags & ts.TypeFlags.Number) !== 0 || + (type.flags & ts.TypeFlags.NumberLike) !== 0 || + (type.flags & ts.TypeFlags.NumberLiteral) !== 0 + ); +} - const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; - const typeNode = checker.typeToTypeNode(type, undefined, flags); - return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); +export function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + if (type.isUnionOrIntersection()) { + return type.types.some(t => isExplicitArrayType(t, checker, program)); } - public static isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { - const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); + if (isStandardLibraryType(type, "ReadonlyArray", program)) { + return true; } - public static isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return TSHelper.isFunctionType(type, checker); - } + const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; + const typeNode = checker.typeToTypeNode(type, undefined, flags); + return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); +} - public static isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - return TSHelper.forTypeOrAnySupertype(type, checker, t => TSHelper.isExplicitArrayType(t, checker, program)); - } +export function isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { + const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); + return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); +} - public static isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); - } +export function isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return isFunctionType(type, checker); +} - public static isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean { - const symbol = checker.getSymbolAtLocation(node); - if (!symbol) { - return false; - } - const declarations = symbol.getDeclarations(); - if (!declarations) { - return false; - } - return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined); - } +export function isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + return forTypeOrAnySupertype(type, checker, t => isExplicitArrayType(t, checker, program)); +} - public static isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return type !== undefined && TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.Vararg); - } +export function isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); +} - public static isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.ForRange); +export function isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean { + const symbol = checker.getSymbolAtLocation(node); + if (!symbol) { + return false; } - - public static isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { - if (ts.isCallExpression(node)) { - const signature = checker.getResolvedSignature(node); - if (signature) { - if (TSHelper.getCustomSignatureDirectives(signature, checker).has(DecoratorKind.TupleReturn)) { - return true; - } - - // Only check function type for directive if it is declared as an interface or type alias - const declaration = signature.getDeclaration(); - const isInterfaceOrAlias = - declaration && - declaration.parent && - ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || - ts.isTypeAliasDeclaration(declaration.parent)); - if (!isInterfaceOrAlias) { - return false; - } - } - - const type = checker.getTypeAtLocation(node.expression); - return TSHelper.getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); - } else { - return false; - } + const declarations = symbol.getDeclarations(); + if (!declarations) { + return false; } + return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined); +} - public static isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { - const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); - if (declaration) { - let functionType: ts.Type | undefined; - if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = TSHelper.inferAssignedType(declaration, checker); - } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { - // Manually lookup type for object literal properties declared with method syntax - const interfaceType = TSHelper.inferAssignedType(declaration.parent, checker); - const propertySymbol = interfaceType.getProperty(declaration.name.getText()); - if (propertySymbol) { - functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); - } - } - if (functionType === undefined) { - functionType = checker.getTypeAtLocation(declaration); - } +export function isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return type !== undefined && getCustomDecorators(type, checker).has(DecoratorKind.Vararg); +} + +export function isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean { + const type = checker.getTypeAtLocation(node); + return getCustomDecorators(type, checker).has(DecoratorKind.ForRange); +} - // Check all overloads for directive - const signatures = functionType.getCallSignatures(); - if ( - signatures && - signatures.some(s => TSHelper.getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn)) - ) { +export function isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { + if (ts.isCallExpression(node)) { + const signature = checker.getResolvedSignature(node); + if (signature) { + if (getCustomSignatureDirectives(signature, checker).has(DecoratorKind.TupleReturn)) { return true; } - const decorators = TSHelper.getCustomDecorators(functionType, checker); - return decorators.has(DecoratorKind.TupleReturn); - } else { - return false; + // Only check function type for directive if it is declared as an interface or type alias + const declaration = signature.getDeclaration(); + const isInterfaceOrAlias = + declaration && + declaration.parent && + ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || + ts.isTypeAliasDeclaration(declaration.parent)); + if (!isInterfaceOrAlias) { + return false; + } } - } - public static getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined { - const declaration = TSHelper.findFirstNodeAbove(node, ts.isFunctionLike); - if (declaration) { - const signature = checker.getSignatureFromDeclaration(declaration); - return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature); - } - return undefined; + const type = checker.getTypeAtLocation(node.expression); + return getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); + } else { + return false; } +} - public static collectCustomDecorators( - source: ts.Symbol | ts.Signature, - checker: ts.TypeChecker, - decMap: Map - ): void { - const comments = source.getDocumentationComment(checker); - const decorators = comments - .filter(comment => comment.kind === "text") - .map(comment => comment.text.split("\n")) - .reduce((a, b) => a.concat(b), []) - .map(line => line.trim()) - .filter(comment => comment[0] === "!"); - - decorators.forEach(decStr => { - const [decoratorName, ...decoratorArguments] = decStr.split(" "); - if (Decorator.isValid(decoratorName.substr(1))) { - const dec = new Decorator(decoratorName.substr(1), decoratorArguments); - decMap.set(dec.kind, dec); - console.warn( - `[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead` - ); - } else { - console.warn(`Encountered unknown decorator ${decStr}.`); - } - }); - source.getJsDocTags().forEach(tag => { - if (Decorator.isValid(tag.name)) { - const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []); - decMap.set(dec.kind, dec); +export function isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (declaration) { + let functionType: ts.Type | undefined; + if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { + functionType = inferAssignedType(declaration, checker); + } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { + // Manually lookup type for object literal properties declared with method syntax + const interfaceType = inferAssignedType(declaration.parent, checker); + const propertySymbol = interfaceType.getProperty(declaration.name.getText()); + if (propertySymbol) { + functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); } - }); - } - - public static getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map { - const decMap = new Map(); - if (type.symbol) { - TSHelper.collectCustomDecorators(type.symbol, checker, decMap); - } - if (type.aliasSymbol) { - TSHelper.collectCustomDecorators(type.aliasSymbol, checker, decMap); } - return decMap; - } - - public static getCustomFileDirectives(file: ts.SourceFile): Map { - const decMap = new Map(); - if (file.statements.length > 0) { - const tags = ts.getJSDocTags(file.statements[0]); - for (const tag of tags) { - const tagName = tag.tagName.escapedText as string; - if (Decorator.isValid(tagName)) { - const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); - decMap.set(dec.kind, dec); - } - } + if (functionType === undefined) { + functionType = checker.getTypeAtLocation(declaration); } - return decMap; - } - - public static getCustomSignatureDirectives( - signature: ts.Signature, - checker: ts.TypeChecker - ): Map { - const directivesMap = new Map(); - TSHelper.collectCustomDecorators(signature, checker, directivesMap); - - // Function properties on interfaces have the JSDoc tags on the parent PropertySignature - const declaration = signature.getDeclaration(); - if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { - const symbol = checker.getSymbolAtLocation(declaration.parent.name); - if (symbol) { - TSHelper.collectCustomDecorators(symbol, checker, directivesMap); - } + + // Check all overloads for directive + const signatures = functionType.getCallSignatures(); + if ( + signatures && + signatures.some(s => getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn)) + ) { + return true; } - return directivesMap; + const decorators = getCustomDecorators(functionType, checker); + return decorators.has(DecoratorKind.TupleReturn); + } else { + return false; } +} - // Search up until finding a node satisfying the callback - public static findFirstNodeAbove( - node: ts.Node, - callback: (n: ts.Node) => n is T - ): T | undefined { - let current = node; - while (current.parent) { - if (callback(current.parent)) { - return current.parent; - } else { - current = current.parent; - } - } - return undefined; +export function getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (declaration) { + const signature = checker.getSignatureFromDeclaration(declaration); + return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature); } + return undefined; +} - public static isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined] { - switch (token) { - case ts.SyntaxKind.BarEqualsToken: - return [true, ts.SyntaxKind.BarToken]; - case ts.SyntaxKind.PlusEqualsToken: - return [true, ts.SyntaxKind.PlusToken]; - case ts.SyntaxKind.CaretEqualsToken: - return [true, ts.SyntaxKind.CaretToken]; - case ts.SyntaxKind.MinusEqualsToken: - return [true, ts.SyntaxKind.MinusToken]; - case ts.SyntaxKind.SlashEqualsToken: - return [true, ts.SyntaxKind.SlashToken]; - case ts.SyntaxKind.PercentEqualsToken: - return [true, ts.SyntaxKind.PercentToken]; - case ts.SyntaxKind.AsteriskEqualsToken: - return [true, ts.SyntaxKind.AsteriskToken]; - case ts.SyntaxKind.AmpersandEqualsToken: - return [true, ts.SyntaxKind.AmpersandToken]; - case ts.SyntaxKind.AsteriskAsteriskEqualsToken: - return [true, ts.SyntaxKind.AsteriskAsteriskToken]; - case ts.SyntaxKind.LessThanLessThanEqualsToken: - return [true, ts.SyntaxKind.LessThanLessThanToken]; - case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: - return [true, ts.SyntaxKind.GreaterThanGreaterThanToken]; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]; +export function collectCustomDecorators( + source: ts.Symbol | ts.Signature, + checker: ts.TypeChecker, + decMap: Map +): void { + const comments = source.getDocumentationComment(checker); + const decorators = comments + .filter(comment => comment.kind === "text") + .map(comment => comment.text.split("\n")) + .reduce((a, b) => a.concat(b), []) + .map(line => line.trim()) + .filter(comment => comment[0] === "!"); + + decorators.forEach(decStr => { + const [decoratorName, ...decoratorArguments] = decStr.split(" "); + if (Decorator.isValid(decoratorName.substr(1))) { + const dec = new Decorator(decoratorName.substr(1), decoratorArguments); + decMap.set(dec.kind, dec); + console.warn(`[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead`); + } else { + console.warn(`Encountered unknown decorator ${decStr}.`); } + }); + source.getJsDocTags().forEach(tag => { + if (Decorator.isValid(tag.name)) { + const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []); + decMap.set(dec.kind, dec); + } + }); +} - return [false, undefined]; +export function getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map { + const decMap = new Map(); + if (type.symbol) { + collectCustomDecorators(type.symbol, checker, decMap); } - - // Returns true for expressions that may have effects when evaluated - public static isExpressionWithEvaluationEffect(node: ts.Expression): boolean { - return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); + if (type.aliasSymbol) { + collectCustomDecorators(type.aliasSymbol, checker, decMap); } + return decMap; +} - // If expression is property/element access with possible effects from being evaluated, returns true along with the - // separated object and index expressions. - public static isAccessExpressionWithEvaluationEffects( - node: ts.Expression, - checker: ts.TypeChecker, - program: ts.Program - ): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] { - if ( - ts.isElementAccessExpression(node) && - (TSHelper.isExpressionWithEvaluationEffect(node.expression) || - TSHelper.isExpressionWithEvaluationEffect(node.argumentExpression)) - ) { - const type = checker.getTypeAtLocation(node.expression); - if (TSHelper.isArrayType(type, checker, program)) { - // Offset arrays by one - const oneLit = ts.createNumericLiteral("1"); - const exp = ts.createParen(node.argumentExpression); - const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); - return [true, node.expression, addExp]; - } else { - return [true, node.expression, node.argumentExpression]; +export function getCustomFileDirectives(file: ts.SourceFile): Map { + const decMap = new Map(); + if (file.statements.length > 0) { + const tags = ts.getJSDocTags(file.statements[0]); + for (const tag of tags) { + const tagName = tag.tagName.escapedText as string; + if (Decorator.isValid(tagName)) { + const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); + decMap.set(dec.kind, dec); } - } else if (ts.isPropertyAccessExpression(node) && TSHelper.isExpressionWithEvaluationEffect(node.expression)) { - return [true, node.expression, ts.createStringLiteral(node.name.text)]; } - return [false, undefined, undefined]; } + return decMap; +} - public static isDefaultArrayCallMethodName(methodName: string): boolean { - return defaultArrayCallMethodNames.has(methodName); - } +export function getCustomSignatureDirectives( + signature: ts.Signature, + checker: ts.TypeChecker +): Map { + const directivesMap = new Map(); + collectCustomDecorators(signature, checker, directivesMap); - public static getExplicitThisParameter( - signatureDeclaration: ts.SignatureDeclaration - ): ts.ParameterDeclaration | undefined { - return signatureDeclaration.parameters.find( - param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword - ); + // Function properties on interfaces have the JSDoc tags on the parent PropertySignature + const declaration = signature.getDeclaration(); + if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { + const symbol = checker.getSymbolAtLocation(declaration.parent.name); + if (symbol) { + collectCustomDecorators(symbol, checker, directivesMap); + } } - public static findInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, - checker: ts.TypeChecker - ): ts.ClassLikeDeclarationBase | undefined { - if (callback(classDeclaration)) { - return classDeclaration; - } + return directivesMap; +} - const extendsType = TSHelper.getExtendedType(classDeclaration, checker); - if (!extendsType) { - return undefined; +// Search up until finding a node satisfying the callback +export function findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined { + let current = node; + while (current.parent) { + if (callback(current.parent)) { + return current.parent; + } else { + current = current.parent; } + } + return undefined; +} - const symbol = extendsType.getSymbol(); - if (symbol === undefined) { - return undefined; - } +export function isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined] { + switch (token) { + case ts.SyntaxKind.BarEqualsToken: + return [true, ts.SyntaxKind.BarToken]; + case ts.SyntaxKind.PlusEqualsToken: + return [true, ts.SyntaxKind.PlusToken]; + case ts.SyntaxKind.CaretEqualsToken: + return [true, ts.SyntaxKind.CaretToken]; + case ts.SyntaxKind.MinusEqualsToken: + return [true, ts.SyntaxKind.MinusToken]; + case ts.SyntaxKind.SlashEqualsToken: + return [true, ts.SyntaxKind.SlashToken]; + case ts.SyntaxKind.PercentEqualsToken: + return [true, ts.SyntaxKind.PercentToken]; + case ts.SyntaxKind.AsteriskEqualsToken: + return [true, ts.SyntaxKind.AsteriskToken]; + case ts.SyntaxKind.AmpersandEqualsToken: + return [true, ts.SyntaxKind.AmpersandToken]; + case ts.SyntaxKind.AsteriskAsteriskEqualsToken: + return [true, ts.SyntaxKind.AsteriskAsteriskToken]; + case ts.SyntaxKind.LessThanLessThanEqualsToken: + return [true, ts.SyntaxKind.LessThanLessThanToken]; + case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: + return [true, ts.SyntaxKind.GreaterThanGreaterThanToken]; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: + return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]; + } + + return [false, undefined]; +} - const symbolDeclarations = symbol.getDeclarations(); - if (symbolDeclarations === undefined) { - return undefined; - } +// Returns true for expressions that may have effects when evaluated +export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { + return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); +} - const declaration = symbolDeclarations.find(ts.isClassLike); - if (!declaration) { - return undefined; +// If expression is property/element access with possible effects from being evaluated, returns true along with the +// separated object and index expressions. +export function isAccessExpressionWithEvaluationEffects( + node: ts.Expression, + checker: ts.TypeChecker, + program: ts.Program +): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] { + if ( + ts.isElementAccessExpression(node) && + (isExpressionWithEvaluationEffect(node.expression) || isExpressionWithEvaluationEffect(node.argumentExpression)) + ) { + const type = checker.getTypeAtLocation(node.expression); + if (isArrayType(type, checker, program)) { + // Offset arrays by one + const oneLit = ts.createNumericLiteral("1"); + const exp = ts.createParen(node.argumentExpression); + const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); + return [true, node.expression, addExp]; + } else { + return [true, node.expression, node.argumentExpression]; } + } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { + return [true, node.expression, ts.createStringLiteral(node.name.text)]; + } + return [false, undefined, undefined]; +} + +export function isDefaultArrayCallMethodName(methodName: string): boolean { + return defaultArrayCallMethodNames.has(methodName); +} + +export function getExplicitThisParameter( + signatureDeclaration: ts.SignatureDeclaration +): ts.ParameterDeclaration | undefined { + return signatureDeclaration.parameters.find( + param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword + ); +} - return TSHelper.findInClassOrAncestor(declaration, callback, checker); +export function findInClassOrAncestor( + classDeclaration: ts.ClassLikeDeclarationBase, + callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, + checker: ts.TypeChecker +): ts.ClassLikeDeclarationBase | undefined { + if (callback(classDeclaration)) { + return classDeclaration; } - public static hasSetAccessorInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - isStatic: boolean, - checker: ts.TypeChecker - ): boolean { - return ( - TSHelper.findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isSetAccessor(m) && TSHelper.isStatic(m) === isStatic), - checker - ) !== undefined - ); + const extendsType = getExtendedType(classDeclaration, checker); + if (!extendsType) { + return undefined; } - public static hasGetAccessorInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - isStatic: boolean, - checker: ts.TypeChecker - ): boolean { - return ( - TSHelper.findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isGetAccessor(m) && TSHelper.isStatic(m) === isStatic), - checker - ) !== undefined - ); + const symbol = extendsType.getSymbol(); + if (symbol === undefined) { + return undefined; } - public static getPropertyName(propertyName: ts.PropertyName): string | number | undefined { - if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { - return propertyName.text; - } else { - return undefined; // TODO: how to handle computed property names? - } + const symbolDeclarations = symbol.getDeclarations(); + if (symbolDeclarations === undefined) { + return undefined; } - public static isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { - const aName = TSHelper.getPropertyName(a); - const bName = TSHelper.getPropertyName(b); - return aName !== undefined && aName === bName; + const declaration = symbolDeclarations.find(ts.isClassLike); + if (!declaration) { + return undefined; } - public static isGetAccessorOverride( - element: ts.ClassElement, - classDeclaration: ts.ClassLikeDeclarationBase, - checker: ts.TypeChecker - ): element is ts.GetAccessorDeclaration { - if (!ts.isGetAccessor(element) || TSHelper.isStatic(element)) { - return false; - } + return findInClassOrAncestor(declaration, callback, checker); +} + +export function hasSetAccessorInClassOrAncestor( + classDeclaration: ts.ClassLikeDeclarationBase, + isStatic: boolean, + checker: ts.TypeChecker +): boolean { + return ( + findInClassOrAncestor( + classDeclaration, + c => c.members.some(m => ts.isSetAccessor(m) && isStaticNode(m) === isStatic), + checker + ) !== undefined + ); +} - const hasInitializedField = (e: ts.ClassElement) => - ts.isPropertyDeclaration(e) && - e.initializer !== undefined && - TSHelper.isSamePropertyName(e.name, element.name); +export function hasGetAccessorInClassOrAncestor( + classDeclaration: ts.ClassLikeDeclarationBase, + isStatic: boolean, + checker: ts.TypeChecker +): boolean { + return ( + findInClassOrAncestor( + classDeclaration, + c => c.members.some(m => ts.isGetAccessor(m) && isStaticNode(m) === isStatic), + checker + ) !== undefined + ); +} - return ( - TSHelper.findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !== - undefined - ); +export function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { + if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { + return propertyName.text; + } else { + return undefined; // TODO: how to handle computed property names? } +} - public static inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { - return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); +export function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { + const aName = getPropertyName(a); + const bName = getPropertyName(b); + return aName !== undefined && aName === bName; +} + +export function isGetAccessorOverride( + element: ts.ClassElement, + classDeclaration: ts.ClassLikeDeclarationBase, + checker: ts.TypeChecker +): element is ts.GetAccessorDeclaration { + if (!ts.isGetAccessor(element) || isStaticNode(element)) { + return false; } - public static getAllCallSignatures(type: ts.Type): ReadonlyArray { - if (type.isUnion()) { - return type.types.map(t => TSHelper.getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); - } - return type.getCallSignatures(); - } - - public static getSignatureDeclarations( - signatures: readonly ts.Signature[], - checker: ts.TypeChecker - ): ts.SignatureDeclaration[] { - const signatureDeclarations: ts.SignatureDeclaration[] = []; - for (const signature of signatures) { - const signatureDeclaration = signature.getDeclaration(); - if ( - (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && - !TSHelper.getExplicitThisParameter(signatureDeclaration) - ) { - // Infer type of function expressions/arrow functions - const inferredType = TSHelper.inferAssignedType(signatureDeclaration, checker); - if (inferredType) { - const inferredSignatures = TSHelper.getAllCallSignatures(inferredType); - if (inferredSignatures.length > 0) { - signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration())); - continue; - } + const hasInitializedField = (e: ts.ClassElement) => + ts.isPropertyDeclaration(e) && e.initializer !== undefined && isSamePropertyName(e.name, element.name); + + return findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !== undefined; +} + +export function inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { + return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); +} + +export function getAllCallSignatures(type: ts.Type): ReadonlyArray { + if (type.isUnion()) { + return type.types.map(t => getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); + } + return type.getCallSignatures(); +} + +export function getSignatureDeclarations( + signatures: readonly ts.Signature[], + checker: ts.TypeChecker +): ts.SignatureDeclaration[] { + const signatureDeclarations: ts.SignatureDeclaration[] = []; + for (const signature of signatures) { + const signatureDeclaration = signature.getDeclaration(); + if ( + (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && + !getExplicitThisParameter(signatureDeclaration) + ) { + // Infer type of function expressions/arrow functions + const inferredType = inferAssignedType(signatureDeclaration, checker); + if (inferredType) { + const inferredSignatures = getAllCallSignatures(inferredType); + if (inferredSignatures.length > 0) { + signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration())); + continue; } } - signatureDeclarations.push(signatureDeclaration); } - return signatureDeclarations; + signatureDeclarations.push(signatureDeclaration); } + return signatureDeclarations; +} - public static hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean { - const scopeDeclaration = TSHelper.findFirstNodeAbove( - declaration, - (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) - ); - if (!scopeDeclaration) { - return false; - } - if (ts.isSourceFile(scopeDeclaration)) { - return TSHelper.getCustomFileDirectives(scopeDeclaration).has(DecoratorKind.NoSelfInFile); - } - const scopeType = checker.getTypeAtLocation(scopeDeclaration); - if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { - return true; - } - return TSHelper.hasNoSelfAncestor(scopeDeclaration, checker); - } - - public static getDeclarationContextType( - signatureDeclaration: ts.SignatureDeclaration, - checker: ts.TypeChecker - ): ContextType { - const thisParameter = TSHelper.getExplicitThisParameter(signatureDeclaration); - if (thisParameter) { - // Explicit 'this' - return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword - ? ContextType.Void - : ContextType.NonVoid; - } - - if ( - ts.isMethodSignature(signatureDeclaration) || - ts.isMethodDeclaration(signatureDeclaration) || - ts.isConstructSignatureDeclaration(signatureDeclaration) || - ts.isConstructorDeclaration(signatureDeclaration) || - (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || - (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) - ) { - // Class/interface methods only respect @noSelf on their parent - const scopeDeclaration = TSHelper.findFirstNodeAbove( - signatureDeclaration, - (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => - ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) - ); +export function hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean { + const scopeDeclaration = findFirstNodeAbove( + declaration, + (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) + ); + if (!scopeDeclaration) { + return false; + } + if (ts.isSourceFile(scopeDeclaration)) { + return getCustomFileDirectives(scopeDeclaration).has(DecoratorKind.NoSelfInFile); + } + const scopeType = checker.getTypeAtLocation(scopeDeclaration); + if (scopeType && getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { + return true; + } + return hasNoSelfAncestor(scopeDeclaration, checker); +} - if (scopeDeclaration === undefined) { - return ContextType.NonVoid; - } +export function getDeclarationContextType( + signatureDeclaration: ts.SignatureDeclaration, + checker: ts.TypeChecker +): ContextType { + const thisParameter = getExplicitThisParameter(signatureDeclaration); + if (thisParameter) { + // Explicit 'this' + return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword + ? ContextType.Void + : ContextType.NonVoid; + } + + if ( + ts.isMethodSignature(signatureDeclaration) || + ts.isMethodDeclaration(signatureDeclaration) || + ts.isConstructSignatureDeclaration(signatureDeclaration) || + ts.isConstructorDeclaration(signatureDeclaration) || + (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || + (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) + ) { + // Class/interface methods only respect @noSelf on their parent + const scopeDeclaration = findFirstNodeAbove( + signatureDeclaration, + (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => + ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) + ); - const scopeType = checker.getTypeAtLocation(scopeDeclaration); - if (scopeType && TSHelper.getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { - return ContextType.Void; - } + if (scopeDeclaration === undefined) { return ContextType.NonVoid; } - // Walk up to find @noSelf or @noSelfOnFile - if (TSHelper.hasNoSelfAncestor(signatureDeclaration, checker)) { + const scopeType = checker.getTypeAtLocation(scopeDeclaration); + if (scopeType && getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { return ContextType.Void; } - return ContextType.NonVoid; } - public static reduceContextTypes(contexts: ContextType[]): ContextType { - const reducer = (a: ContextType, b: ContextType) => { - if (a === ContextType.None) { - return b; - } else if (b === ContextType.None) { - return a; - } else if (a !== b) { - return ContextType.Mixed; - } else { - return a; - } - }; - return contexts.reduce(reducer, ContextType.None); + // Walk up to find @noSelf or @noSelfOnFile + if (hasNoSelfAncestor(signatureDeclaration, checker)) { + return ContextType.Void; } - public static getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType { - if (type.isTypeParameter()) { - type = type.getConstraint() || type; - } + return ContextType.NonVoid; +} - if (type.isUnion()) { - return TSHelper.reduceContextTypes(type.types.map(t => TSHelper.getFunctionContextType(t, checker))); +export function reduceContextTypes(contexts: ContextType[]): ContextType { + const reducer = (a: ContextType, b: ContextType) => { + if (a === ContextType.None) { + return b; + } else if (b === ContextType.None) { + return a; + } else if (a !== b) { + return ContextType.Mixed; + } else { + return a; } + }; + return contexts.reduce(reducer, ContextType.None); +} - const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); - if (signatures.length === 0) { - return ContextType.None; - } - const signatureDeclarations = TSHelper.getSignatureDeclarations(signatures, checker); - return TSHelper.reduceContextTypes( - signatureDeclarations.map(s => TSHelper.getDeclarationContextType(s, checker)) - ); +export function getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType { + if (type.isTypeParameter()) { + type = type.getConstraint() || type; } - public static escapeString(text: string): string { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String - const escapeSequences: Array<[RegExp, string]> = [ - [/[\\]/g, "\\\\"], - [/[\']/g, "\\'"], - [/[\"]/g, '\\"'], - [/[\n]/g, "\\n"], - [/[\r]/g, "\\r"], - [/[\v]/g, "\\v"], - [/[\t]/g, "\\t"], - [/[\b]/g, "\\b"], - [/[\f]/g, "\\f"], - [/[\0]/g, "\\0"], - ]; - - if (text.length > 0) { - for (const [regex, replacement] of escapeSequences) { - text = text.replace(regex, replacement); - } - } - return text; + if (type.isUnion()) { + return reduceContextTypes(type.types.map(t => getFunctionContextType(t, checker))); } - public static isValidLuaIdentifier(str: string): boolean { - const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/); - return match !== undefined && match !== null && match[0] === str; + const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); + if (signatures.length === 0) { + return ContextType.None; } + const signatureDeclarations = getSignatureDeclarations(signatures, checker); + return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(s, checker))); +} - public static fixInvalidLuaIdentifier(name: string): string { - return name.replace( - /[^a-zA-Z0-9_]/g, - c => - `_${c - .charCodeAt(0) - .toString(16) - .toUpperCase()}` - ); - } +export function escapeString(text: string): string { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String + const escapeSequences: Array<[RegExp, string]> = [ + [/[\\]/g, "\\\\"], + [/[\']/g, "\\'"], + [/[\"]/g, '\\"'], + [/[\n]/g, "\\n"], + [/[\r]/g, "\\r"], + [/[\v]/g, "\\v"], + [/[\t]/g, "\\t"], + [/[\b]/g, "\\b"], + [/[\f]/g, "\\f"], + [/[\0]/g, "\\0"], + ]; + + if (text.length > 0) { + for (const [regex, replacement] of escapeSequences) { + text = text.replace(regex, replacement); + } + } + return text; +} - // Checks that a name is valid for use in lua function declaration syntax: - // 'foo.bar' => passes ('function foo.bar()' is valid) - // 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) - public static isValidLuaFunctionDeclarationName(str: string): boolean { - const match = str.match(/[a-zA-Z0-9_\.]+/); - return match !== undefined && match !== null && match[0] === str; - } +export function isValidLuaIdentifier(str: string): boolean { + const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/); + return match !== undefined && match !== null && match[0] === str; +} - public static isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { - const falsibleFlags = - ts.TypeFlags.Boolean | - ts.TypeFlags.BooleanLiteral | - ts.TypeFlags.Undefined | - ts.TypeFlags.Null | - ts.TypeFlags.Never | - ts.TypeFlags.Void | - ts.TypeFlags.Any; +export function fixInvalidLuaIdentifier(name: string): string { + return name.replace( + /[^a-zA-Z0-9_]/g, + c => + `_${c + .charCodeAt(0) + .toString(16) + .toUpperCase()}` + ); +} - if (type.flags & falsibleFlags) { - return true; - } else if (!strictNullChecks && !type.isLiteral()) { - return true; - } else if (type.isUnion()) { - for (const subType of type.types) { - if (TSHelper.isFalsible(subType, strictNullChecks)) { - return true; - } +// Checks that a name is valid for use in lua function declaration syntax: +// 'foo.bar' => passes ('function foo.bar()' is valid) +// 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) +export function isValidLuaFunctionDeclarationName(str: string): boolean { + const match = str.match(/[a-zA-Z0-9_\.]+/); + return match !== undefined && match !== null && match[0] === str; +} + +export function isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { + const falsibleFlags = + ts.TypeFlags.Boolean | + ts.TypeFlags.BooleanLiteral | + ts.TypeFlags.Undefined | + ts.TypeFlags.Null | + ts.TypeFlags.Never | + ts.TypeFlags.Void | + ts.TypeFlags.Any; + + if (type.flags & falsibleFlags) { + return true; + } else if (!strictNullChecks && !type.isLiteral()) { + return true; + } else if (type.isUnion()) { + for (const subType of type.types) { + if (isFalsible(subType, strictNullChecks)) { + return true; } } + } + + return false; +} + +export function getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFile): ts.Declaration | undefined { + let declarations = symbol.getDeclarations(); + if (!declarations) { + return undefined; + } + if (sourceFile) { + declarations = declarations.filter(d => findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); + } + return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; +} +export function isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean { + const symbol = checker.getSymbolAtLocation(node.name); + if (!symbol) { return false; } + const firstDeclaration = getFirstDeclaration(symbol); + return firstDeclaration === node; +} - public static getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFile): ts.Declaration | undefined { - let declarations = symbol.getDeclarations(); - if (!declarations) { - return undefined; - } - if (sourceFile) { - declarations = declarations.filter(d => this.findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); - } - return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; +export function isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean { + const source = declaration.getSourceFile(); + if (!source) { + return false; } + return program.isSourceFileDefaultLibrary(source); +} - public static isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean { - const symbol = checker.getSymbolAtLocation(node.name); - if (!symbol) { - return false; - } - const firstDeclaration = this.getFirstDeclaration(symbol); - return firstDeclaration === node; +export function isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean { + const symbol = type.getSymbol(); + if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) { + return false; } - public static isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean { - const source = declaration.getSourceFile(); - if (!source) { - return false; - } - return program.isSourceFileDefaultLibrary(source); + const declaration = symbol.valueDeclaration; + if (!declaration) { + return true; } - public static isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean { - const symbol = type.getSymbol(); - if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) { - return false; - } + // assume to be lib function if no valueDeclaration exists + return isStandardLibraryDeclaration(declaration, program); +} - const declaration = symbol.valueDeclaration; - if (!declaration) { - return true; - } // assume to be lib function if no valueDeclaration exists - return this.isStandardLibraryDeclaration(declaration, program); - } - - public static isEnumMember( - enumDeclaration: ts.EnumDeclaration, - value: ts.Expression - ): [true, ts.PropertyName] | [false, undefined] { - if (ts.isIdentifier(value)) { - const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text); - if (enumMember !== undefined) { - if (enumMember.initializer && ts.isIdentifier(enumMember.initializer)) { - return this.isEnumMember(enumDeclaration, enumMember.initializer); - } else { - return [true, enumMember.name]; - } +export function isEnumMember( + enumDeclaration: ts.EnumDeclaration, + value: ts.Expression +): [true, ts.PropertyName] | [false, undefined] { + if (ts.isIdentifier(value)) { + const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text); + if (enumMember !== undefined) { + if (enumMember.initializer && ts.isIdentifier(enumMember.initializer)) { + return isEnumMember(enumDeclaration, enumMember.initializer); } else { - return [false, undefined]; + return [true, enumMember.name]; } } else { return [false, undefined]; } + } else { + return [false, undefined]; } +} - public static moduleHasEmittedBody( - statement: ts.ModuleDeclaration - ): statement is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { - if (statement.body) { - if (ts.isModuleBlock(statement.body)) { - // Ignore if body has no emitted statements - return ( - statement.body.statements.findIndex( - s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) - ) !== -1 - ); - } else if (ts.isModuleDeclaration(statement.body)) { - return true; - } +export function moduleHasEmittedBody( + statement: ts.ModuleDeclaration +): statement is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { + if (statement.body) { + if (ts.isModuleBlock(statement.body)) { + // Ignore if body has no emitted statements + return ( + statement.body.statements.findIndex( + s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) + ) !== -1 + ); + } else if (ts.isModuleDeclaration(statement.body)) { + return true; } - return false; } + return false; +} - public static isArrayLengthAssignment( - expression: ts.BinaryExpression, - checker: ts.TypeChecker, - program: ts.Program - ): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression } { - if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { - return false; - } +export function isArrayLengthAssignment( + expression: ts.BinaryExpression, + checker: ts.TypeChecker, + program: ts.Program +): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression } { + if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { + return false; + } - if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) { - return false; - } + if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) { + return false; + } - const type = checker.getTypeAtLocation(expression.left.expression); - if (!TSHelper.isArrayType(type, checker, program)) { - return false; - } + const type = checker.getTypeAtLocation(expression.left.expression); + if (!isArrayType(type, checker, program)) { + return false; + } - const name = ts.isPropertyAccessExpression(expression.left) - ? (expression.left.name.escapedText as string) - : ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text; + const name = ts.isPropertyAccessExpression(expression.left) + ? (expression.left.name.escapedText as string) + : ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text; - return name === "length"; - } + return name === "length"; } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 8b2051fcd..a00d6faeb 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -1,208 +1,204 @@ import * as ts from "typescript"; -import { TranspileError } from "./TranspileError"; import { LuaTarget } from "./CompilerOptions"; +import { TranspileError } from "./TranspileError"; const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); -export class TSTLErrors { - public static CouldNotCast = (castName: string) => - new Error(`Failed to cast all elements to expected type using ${castName}.`); - - public static DefaultImportsNotSupported = (node: ts.Node) => - new TranspileError(`Default Imports are not supported, please use named imports instead!`, node); +export const CouldNotCast = (castName: string) => + new Error(`Failed to cast all elements to expected type using ${castName}.`); - public static ForbiddenEllipsisDestruction = (node: ts.Node) => - new TranspileError(`Ellipsis destruction is not allowed.`, node); +export const DefaultImportsNotSupported = (node: ts.Node) => + new TranspileError(`Default Imports are not supported, please use named imports instead!`, node); - public static ForbiddenForIn = (node: ts.Node) => - new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); +export const ForbiddenEllipsisDestruction = (node: ts.Node) => + new TranspileError(`Ellipsis destruction is not allowed.`, node); - public static ForbiddenLuaTableSetExpression = (node: ts.Node) => - new TranspileError( - `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, - node - ); +export const ForbiddenForIn = (node: ts.Node) => + new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); - public static ForbiddenLuaTableNonDeclaration = (node: ts.Node) => - new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); +export const ForbiddenLuaTableSetExpression = (node: ts.Node) => + new TranspileError( + `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, + node + ); - public static InvalidExtendsLuaTable = (node: ts.Node) => - new TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node); +export const ForbiddenLuaTableNonDeclaration = (node: ts.Node) => + new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); - public static InvalidInstanceOfLuaTable = (node: ts.Node) => - new TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node); +export const InvalidExtendsLuaTable = (node: ts.Node) => + new TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node); - public static ForbiddenLuaTableUseException = (description: string, node: ts.Node) => - new TranspileError(`Invalid @luaTable usage: ${description}`, node); +export const InvalidInstanceOfLuaTable = (node: ts.Node) => + new TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node); - public static HeterogeneousEnum = (node: ts.Node) => - new TranspileError( - `Invalid heterogeneous enum. Enums should either specify no member values, ` + - `or specify values (of the same type) for all members.`, - node - ); +export const ForbiddenLuaTableUseException = (description: string, node: ts.Node) => + new TranspileError(`Invalid @luaTable usage: ${description}`, node); - public static InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => - new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); +export const HeterogeneousEnum = (node: ts.Node) => + new TranspileError( + `Invalid heterogeneous enum. Enums should either specify no member values, ` + + `or specify values (of the same type) for all members.`, + node + ); - public static InvalidDecoratorContext = (node: ts.Node) => - new TranspileError(`Decorator function cannot have 'this: void'.`, node); +export const InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => + new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); - public static InvalidExtensionMetaExtension = (node: ts.Node) => - new TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node); +export const InvalidDecoratorContext = (node: ts.Node) => + new TranspileError(`Decorator function cannot have 'this: void'.`, node); - public static InvalidNewExpressionOnExtension = (node: ts.Node) => - new TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node); +export const InvalidExtensionMetaExtension = (node: ts.Node) => + new TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node); - public static InvalidExportDeclaration = (declaration: ts.ExportDeclaration) => - new TranspileError("Encountered invalid export declaration without exports and without module.", declaration); +export const InvalidNewExpressionOnExtension = (node: ts.Node) => + new TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node); - public static InvalidExtendsExtension = (node: ts.Node) => - new TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node); +export const InvalidExportDeclaration = (declaration: ts.ExportDeclaration) => + new TranspileError("Encountered invalid export declaration without exports and without module.", declaration); - public static InvalidExportsExtension = (node: ts.Node) => - new TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node); +export const InvalidExtendsExtension = (node: ts.Node) => + new TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node); - public static InvalidInstanceOfExtension = (node: ts.Node) => - new TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node); +export const InvalidExportsExtension = (node: ts.Node) => + new TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node); - public static InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); +export const InvalidInstanceOfExtension = (node: ts.Node) => + new TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node); - public static InvalidPropertyCall = (node: ts.Node) => - new TranspileError(`Tried to transpile a non-property call as property call.`, node); +export const InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); - public static InvalidElementCall = (node: ts.Node) => - new TranspileError(`Tried to transpile a non-element call as an element call.`, node); +export const InvalidPropertyCall = (node: ts.Node) => + new TranspileError(`Tried to transpile a non-property call as property call.`, node); - public static InvalidThrowExpression = (node: ts.Node) => - new TranspileError(`Invalid throw expression, only strings can be thrown.`, node); +export const InvalidElementCall = (node: ts.Node) => + new TranspileError(`Tried to transpile a non-element call as an element call.`, node); - public static ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => - new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); +export const InvalidThrowExpression = (node: ts.Node) => + new TranspileError(`Invalid throw expression, only strings can be thrown.`, node); - public static MissingClassName = (node: ts.Node) => - new TranspileError(`Class declarations must have a name.`, node); +export const ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => + new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); - public static MissingForOfVariables = (node: ts.Node) => - new TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node); +export const MissingClassName = (node: ts.Node) => new TranspileError(`Class declarations must have a name.`, node); - public static MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => - new TranspileError("Unsupported function declaration without name.", declaration); +export const MissingForOfVariables = (node: ts.Node) => + new TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node); - public static MissingMetaExtension = (node: ts.Node) => - new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); +export const MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => + new TranspileError("Unsupported function declaration without name.", declaration); - public static MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't."); +export const MissingMetaExtension = (node: ts.Node) => + new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); - public static UndefinedFunctionDefinition = (functionSymbolId: number) => - new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); +export const MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't."); - public static UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); +export const UndefinedFunctionDefinition = (functionSymbolId: number) => + new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); - public static UndefinedTypeNode = (node: ts.Node) => - new TranspileError("Failed to resolve required type node.", node); +export const UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); - public static UnknownSuperType = (node: ts.Node) => - new TranspileError("Unable to resolve type of super expression.", node); +export const UndefinedTypeNode = (node: ts.Node) => new TranspileError("Failed to resolve required type node.", node); - public static UnsupportedDefaultExport = (node: ts.Node) => - new TranspileError(`Default exports are not supported.`, node); +export const UnknownSuperType = (node: ts.Node) => + new TranspileError("Unable to resolve type of super expression.", node); - public static UnsupportedImportType = (node: ts.Node) => new TranspileError(`Unsupported import type.`, node); +export const UnsupportedDefaultExport = (node: ts.Node) => + new TranspileError(`Default exports are not supported.`, node); - public static UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => - new TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node); +export const UnsupportedImportType = (node: ts.Node) => new TranspileError(`Unsupported import type.`, node); - public static UnsupportedProperty = (parentName: string, property: string, node: ts.Node) => - new TranspileError(`Unsupported property on ${parentName}: ${property}`, node); +export const UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => + new TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node); - public static UnsupportedForTarget = (functionality: string, version: LuaTarget, node: ts.Node) => - new TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node); +export const UnsupportedProperty = (parentName: string, property: string, node: ts.Node) => + new TranspileError(`Unsupported property on ${parentName}: ${property}`, node); - public static UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) => - new TranspileError("Functions with undefined bodies are not supported.", node); +export const UnsupportedForTarget = (functionality: string, version: LuaTarget, node: ts.Node) => + new TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node); - public static UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node - ); - } else { - return new TranspileError( - `Unable to convert function with a 'this' parameter to function with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node - ); - } - }; +export const UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) => + new TranspileError("Functions with undefined bodies are not supported.", node); - public static UnsupportedSelfFunctionConversion = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node - ); - } else { - return new TranspileError( - `Unable to convert function with no 'this' parameter to function with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node - ); - } - }; - - public static UnsupportedOverloadAssignment = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` + - `Overloads should all have the same type for 'this'.`, - node - ); - } else { - return new TranspileError( - `Unsupported assignment of function with different overloaded types for 'this'. ` + - `Overloads should all have the same type for 'this'.`, - node - ); - } - }; - - public static UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => { +export const UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { + if (name) { return new TranspileError( - "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " + - "You must use a destructuring statement to catch results from a lua iterator with " + - "the TupleReturn decorator.", + `Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.`, node ); - }; - - public static UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => { - return new TranspileError(`${reason}. ` + `TypeScript path: ${path}.`, node); - }; - - public static ReferencedBeforeDeclaration = (node: ts.Identifier) => { + } else { return new TranspileError( - `Identifier "${node.text}" was referenced before it was declared. The declaration ` + - "must be moved before the identifier's use, or hoisting must be enabled.", + `Unable to convert function with a 'this' parameter to function with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.`, node ); - }; - - public static UnsupportedObjectDestructuringInForOf = (node: ts.Node) => { - return new TranspileError(`Unsupported object destructuring in for...of statement.`, node); - }; + } +}; - public static InvalidAmbientIdentifierName = (node: ts.Identifier) => { +export const UnsupportedSelfFunctionConversion = (node: ts.Node, name?: string) => { + if (name) { return new TranspileError( - `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, + `Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` + + `To fix, wrap in an arrow function or declare with 'this: any'.`, node ); - }; + } else { + return new TranspileError( + `Unable to convert function with no 'this' parameter to function with 'this'. ` + + `To fix, wrap in an arrow function or declare with 'this: any'.`, + node + ); + } +}; - public static InvalidForRangeCall = (node: ts.Node, message: string) => { - return new TranspileError(`Invalid @forRange call: ${message}`, node); - }; -} +export const UnsupportedOverloadAssignment = (node: ts.Node, name?: string) => { + if (name) { + return new TranspileError( + `Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` + + `Overloads should all have the same type for 'this'.`, + node + ); + } else { + return new TranspileError( + `Unsupported assignment of function with different overloaded types for 'this'. ` + + `Overloads should all have the same type for 'this'.`, + node + ); + } +}; + +export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => { + return new TranspileError( + "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " + + "You must use a destructuring statement to catch results from a lua iterator with " + + "the TupleReturn decorator.", + node + ); +}; + +export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => { + return new TranspileError(`${reason}. ` + `TypeScript path: ${path}.`, node); +}; + +export const ReferencedBeforeDeclaration = (node: ts.Identifier) => { + return new TranspileError( + `Identifier "${node.text}" was referenced before it was declared. The declaration ` + + "must be moved before the identifier's use, or hoisting must be enabled.", + node + ); +}; + +export const UnsupportedObjectDestructuringInForOf = (node: ts.Node) => { + return new TranspileError(`Unsupported object destructuring in for...of statement.`, node); +}; + +export const InvalidAmbientIdentifierName = (node: ts.Identifier) => { + return new TranspileError( + `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, + node + ); +}; + +export const InvalidForRangeCall = (node: ts.Node, message: string) => { + return new TranspileError(`Invalid @forRange call: ${message}`, node); +}; diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index 7eb8e5ecd..33541283e 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../../src/TSTLErrors"; +import * as TSTLErrors from "../../../src/TSTLErrors"; import * as util from "../../util"; test.each([ diff --git a/test/unit/assignments/invalidFunctionAssignments.spec.ts b/test/unit/assignments/invalidFunctionAssignments.spec.ts index ea3de0d88..97002fd7d 100644 --- a/test/unit/assignments/invalidFunctionAssignments.spec.ts +++ b/test/unit/assignments/invalidFunctionAssignments.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../../src/TSTLErrors"; +import * as TSTLErrors from "../../../src/TSTLErrors"; import * as util from "../../util"; import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; diff --git a/test/unit/class.spec.ts b/test/unit/class.spec.ts index 6fff9ecb9..37f1db79a 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/class.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("ClassFieldInitializer", () => { diff --git a/test/unit/classDecorator.spec.ts b/test/unit/classDecorator.spec.ts index 8e9eff3d7..8d7afd8fa 100644 --- a/test/unit/classDecorator.spec.ts +++ b/test/unit/classDecorator.spec.ts @@ -1,5 +1,5 @@ +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; -import { TSTLErrors } from "../../src/TSTLErrors"; test("Class decorator with no parameters", () => { const source = ` diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 428066db6..04a285457 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,5 @@ import * as tstl from "../../src"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("if (%p)", ({ inp, expected }) => { diff --git a/test/unit/decoratorCustomConstructor.spec.ts b/test/unit/decoratorCustomConstructor.spec.ts index 71052406e..126c44e4f 100644 --- a/test/unit/decoratorCustomConstructor.spec.ts +++ b/test/unit/decoratorCustomConstructor.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("CustomCreate", () => { diff --git a/test/unit/decoratorMetaExtension.spec.ts b/test/unit/decoratorMetaExtension.spec.ts index 6057fb202..20bf7fb4d 100644 --- a/test/unit/decoratorMetaExtension.spec.ts +++ b/test/unit/decoratorMetaExtension.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("MetaExtension", () => { diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index ad063a6ba..383d9708f 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("Declare const enum", () => { diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index fe5eacf5e..5002e29f3 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("throwString", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index b19d029c9..559ff3606 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test.each([ diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 9d4a9be13..455b6d70d 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("Arrow Function Expression", () => { diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index cf07a7c15..1d91e3684 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("Var Hoisting", () => { diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index e4677c5dc..7936de507 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as util from "../util"; import { luaKeywords } from "../../src/LuaKeywords"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; const invalidLuaCharNames = ["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"]; const validTsInvalidLuaKeywordNames = [ diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index d7064edcc..642243155 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; import * as ts from "typescript"; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 96d4df6ee..79d19b2f5 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("while (%p)", ({ inp, expected }) => { diff --git a/test/unit/luaTable.spec.ts b/test/unit/luaTable.spec.ts index aa15f32ac..ddc5f81a3 100644 --- a/test/unit/luaTable.spec.ts +++ b/test/unit/luaTable.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; const tableLibClass = ` diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 2c60c7e7a..8b52cfc1c 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; describe("module import/export elision", () => { diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 910303891..1f502d211 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("Unsuported string function", () => { diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 681c0a1b3..7202ff2e4 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import { DecoratorKind } from "../../src/Decorator"; -import { TSHelper as tsHelper } from "../../src/TSHelper"; +import * as tsHelper from "../../src/TSHelper"; import * as util from "../util"; test("GetCustomDecorators single", () => { diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts index 9cc6ed9d8..500e4e094 100644 --- a/test/unit/typechecking.spec.ts +++ b/test/unit/typechecking.spec.ts @@ -1,4 +1,4 @@ -import { TSTLErrors } from "../../src/TSTLErrors"; +import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test.each(["0", "30", "30_000", "30.00"])("typeof number (%p)", inp => { From 51a125e200e730a6149ee21252bc7a1c052f9ee2 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 29 Jun 2019 08:09:38 -0600 Subject: [PATCH 120/764] updated call & table expression formatting (#639) * updated call/table expression formatting Arguments/fields will now only be split into multiple lines if one or more has evaluation side-effects that would be beneficial for a debugger to step on. * moved isSimpleExpression to tsHelper --- src/LuaAST.ts | 2 +- src/LuaPrinter.ts | 63 ++++++++------ src/TSHelper.ts | 37 ++++++++ .../__snapshots__/transformation.spec.ts.snap | 85 ++++++++++--------- test/unit/assignmentDestructuring.spec.ts | 6 +- test/unit/assignments/assignments.spec.ts | 14 +-- test/unit/console.spec.ts | 18 ++-- test/unit/objectLiteral.spec.ts | 10 +-- test/unit/spreadElement.spec.ts | 8 +- 9 files changed, 150 insertions(+), 93 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 111bf8aa2..b8402d808 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -677,7 +677,7 @@ export function createTableFieldExpression( tsOriginal?: ts.Node, parent?: Node ): TableFieldExpression { - const expression = createNode(SyntaxKind.TableExpression, tsOriginal, parent) as TableFieldExpression; + const expression = createNode(SyntaxKind.TableFieldExpression, tsOriginal, parent) as TableFieldExpression; setParent(value, expression); expression.value = value; setParent(key, expression); diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index f2b9b4870..ebac13788 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -571,17 +571,8 @@ export class LuaPrinter { chunks.push("{"); - if (expression.fields && expression.fields.length > 0) { - if (expression.fields.length === 1) { - // Inline tables with only one entry - chunks.push(this.printTableFieldExpression(expression.fields[0])); - } else { - chunks.push("\n"); - this.pushIndent(); - expression.fields.forEach(f => chunks.push(this.indent(), this.printTableFieldExpression(f), ",\n")); - this.popIndent(); - chunks.push(this.indent()); - } + if (expression.fields) { + chunks.push(...this.printExpressionList(expression.fields)); } chunks.push("}"); @@ -632,30 +623,33 @@ export class LuaPrinter { public printCallExpression(expression: tstl.CallExpression): SourceNode { const chunks = []; - const parameterChunks = - expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : []; + chunks.push(this.printExpression(expression.expression), "("); - chunks.push(this.printExpression(expression.expression), "(", ...this.joinChunks(", ", parameterChunks), ")"); + if (expression.params) { + chunks.push(...this.printExpressionList(expression.params)); + } + + chunks.push(")"); return this.createSourceNode(expression, chunks); } public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { - const prefix = this.printExpression(expression.prefixExpression); + const chunks = []; - const parameterChunks = - expression.params !== undefined ? expression.params.map(e => this.printExpression(e)) : []; + const prefix = this.printExpression(expression.prefixExpression); const name = this.printIdentifier(expression.name); - return this.createSourceNode(expression, [ - prefix, - ":", - name, - "(", - ...this.joinChunks(", ", parameterChunks), - ")", - ]); + chunks.push(prefix, ":", name, "("); + + if (expression.params) { + chunks.push(...this.printExpressionList(expression.params)); + } + + chunks.push(")"); + + return this.createSourceNode(expression, chunks); } public printIdentifier(expression: tstl.Identifier): SourceNode { @@ -715,6 +709,25 @@ export class LuaPrinter { return result; } + protected printExpressionList(expressions: tstl.Expression[]): SourceChunk[] { + const chunks: SourceChunk[] = []; + + if (expressions.every(e => tsHelper.isSimpleExpression(e))) { + chunks.push(...this.joinChunks(", ", expressions.map(e => this.printExpression(e)))); + } else { + chunks.push("\n"); + this.pushIndent(); + expressions.forEach((p, i) => { + const tail = i < expressions.length - 1 ? ",\n" : "\n"; + chunks.push(this.indent(), this.printExpression(p), tail); + }); + this.popIndent(); + chunks.push(this.indent()); + } + + return chunks; + } + // The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column // will not generate 'empty' mappings in the source map that point to nothing in the original TS. private buildSourceMap(sourceFile: string, sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index aa21e8698..e5ebb14af 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import { Decorator, DecoratorKind } from "./Decorator"; +import * as tstl from "./LuaAST"; export enum ContextType { None, @@ -835,3 +836,39 @@ export function isArrayLengthAssignment( return name === "length"; } + +// Returns true if expression contains no function calls +export function isSimpleExpression(expression: tstl.Expression): boolean { + switch (expression.kind) { + case tstl.SyntaxKind.CallExpression: + case tstl.SyntaxKind.MethodCallExpression: + case tstl.SyntaxKind.FunctionExpression: + return false; + + case tstl.SyntaxKind.TableExpression: + const tableExpression = expression as tstl.TableExpression; + return !tableExpression.fields || tableExpression.fields.every(e => isSimpleExpression(e)); + + case tstl.SyntaxKind.TableFieldExpression: + const fieldExpression = expression as tstl.TableFieldExpression; + return ( + (!fieldExpression.key || isSimpleExpression(fieldExpression.key)) && + isSimpleExpression(fieldExpression.value) + ); + + case tstl.SyntaxKind.TableIndexExpression: + const indexExpression = expression as tstl.TableIndexExpression; + return isSimpleExpression(indexExpression.table) && isSimpleExpression(indexExpression.index); + + case tstl.SyntaxKind.UnaryExpression: + return isSimpleExpression((expression as tstl.UnaryExpression).operand); + + case tstl.SyntaxKind.BinaryExpression: + const binaryExpression = expression as tstl.BinaryExpression; + return isSimpleExpression(binaryExpression.left) && isSimpleExpression(binaryExpression.right); + + case tstl.SyntaxKind.ParenthesizedExpression: + return isSimpleExpression((expression as tstl.ParenthesizedExpression).innerExpression); + } + return true; +} diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 58e99b895..add5eab21 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -228,28 +228,12 @@ end" `; exports[`Transformation (forIn) 1`] = ` -"for i in pairs({ - a = 1, - b = 2, - c = 3, - d = 4, -}) do +"for i in pairs({a = 1, b = 2, c = 3, d = 4}) do end" `; exports[`Transformation (forOf) 1`] = ` -"for ____, i in ipairs({ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, -}) do +"for ____, i in ipairs({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) do end" `; @@ -577,9 +561,11 @@ f = function(____, x) return ({x = x}) end" exports[`Transformation (tryCatch) 1`] = ` "do - local ____TS_try, er = pcall(function() - local a = 42 - end) + local ____TS_try, er = pcall( + function() + local a = 42 + end + ) if not ____TS_try then local b = \\"fail\\" end @@ -588,9 +574,11 @@ end" exports[`Transformation (tryCatchFinally) 1`] = ` "do - local ____TS_try, er = pcall(function() - local a = 42 - end) + local ____TS_try, er = pcall( + function() + local a = 42 + end + ) if not ____TS_try then local b = \\"fail\\" end @@ -602,9 +590,11 @@ end" exports[`Transformation (tryFinally) 1`] = ` "do - pcall(function() - local a = 42 - end) + pcall( + function() + local a = 42 + end + ) do local b = \\"finally\\" end @@ -618,30 +608,47 @@ end tupleReturn(_G) noTupleReturn(_G) local a, b = tupleReturn(_G) -local c, d = table.unpack(noTupleReturn(_G)) +local c, d = table.unpack( + noTupleReturn(_G) +) a, b = tupleReturn(_G) -c, d = table.unpack(noTupleReturn(_G)) -local e = ({tupleReturn(_G)}) +c, d = table.unpack( + noTupleReturn(_G) +) +local e = ({ + tupleReturn(_G) +}) local f = noTupleReturn(_G) -e = ({tupleReturn(_G)}) +e = ({ + tupleReturn(_G) +}) f = noTupleReturn(_G) -foo(_G, ({tupleReturn(_G)})) -foo(_G, noTupleReturn(_G)) +foo( + _G, + ({ + tupleReturn(_G) + }) +) +foo( + _G, + noTupleReturn(_G) +) function tupleReturnFromVar(self) - local r = { - 1, - \\"baz\\", - } + local r = {1, \\"baz\\"} return table.unpack(r) end function tupleReturnForward(self) return tupleReturn(_G) end function tupleNoForward(self) - return ({tupleReturn(_G)}) + return ({ + tupleReturn(_G) + }) end function tupleReturnUnpack(self) - return table.unpack(tupleNoForward(_G)) + return table.unpack( + tupleNoForward(_G) + ) end" `; diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts index 0aeca594d..908a4eac9 100644 --- a/test/unit/assignmentDestructuring.spec.ts +++ b/test/unit/assignmentDestructuring.spec.ts @@ -10,7 +10,7 @@ test("Assignment destructuring [5.1]", () => { luaTarget: tstl.LuaTarget.Lua51, luaLibImport: tstl.LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = unpack(myFunc())`); + expect(lua).toBe(`local a, b = unpack(\n myFunc()\n)`); }); test("Assignment destructuring [5.2]", () => { @@ -18,7 +18,7 @@ test("Assignment destructuring [5.2]", () => { luaTarget: tstl.LuaTarget.Lua52, luaLibImport: tstl.LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = table.unpack(myFunc())`); + expect(lua).toBe(`local a, b = table.unpack(\n myFunc()\n)`); }); test("Assignment destructuring [JIT]", () => { @@ -26,7 +26,7 @@ test("Assignment destructuring [JIT]", () => { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.None, }); - expect(lua).toBe(`local a, b = unpack(myFunc())`); + expect(lua).toBe(`local a, b = unpack(\n myFunc()\n)`); }); test.each([ diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts index 33541283e..c5da9beff 100644 --- a/test/unit/assignments/assignments.spec.ts +++ b/test/unit/assignments/assignments.spec.ts @@ -4,10 +4,10 @@ import * as util from "../../util"; test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, ])("Const assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`const myvar = ${inp}`); expect(lua).toBe(`local myvar = ${out}`); @@ -16,10 +16,10 @@ test.each([ test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, ])("Let assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`let myvar = ${inp}`); expect(lua).toBe(`local myvar = ${out}`); @@ -28,10 +28,10 @@ test.each([ test.each([ { inp: `"abc"`, out: `"abc"` }, { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{\n 1,\n 2,\n 3,\n}" }, + { inp: "[1,2,3]", out: "{1, 2, 3}" }, { inp: "true", out: "true" }, { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{\n a = 3,\n b = "4",\n}` }, + { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, ])("Var assignment (%p)", ({ inp, out }) => { const lua = util.transpileString(`var myvar = ${inp}`); expect(lua).toBe(`myvar = ${out}`); @@ -95,7 +95,7 @@ test("TupleReturn Single assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local a = ({abc()})\na = ({abc()})"); + expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); }); test("TupleReturn interface assignment", () => { diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts index 729a4440c..e82c23b04 100644 --- a/test/unit/console.spec.ts +++ b/test/unit/console.spec.ts @@ -5,8 +5,8 @@ const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; test.each([ { inp: "console.log()", expected: "print()" }, { inp: 'console.log("Hello")', expected: 'print("Hello")' }, - { inp: 'console.log("Hello %s", "there")', expected: 'print(string.format("Hello %s", "there"))' }, - { inp: 'console.log("Hello %%s", "there")', expected: 'print(string.format("Hello %%s", "there"))' }, + { inp: 'console.log("Hello %s", "there")', expected: 'print(\n string.format("Hello %s", "there")\n)' }, + { inp: 'console.log("Hello %%s", "there")', expected: 'print(\n string.format("Hello %%s", "there")\n)' }, { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There")' }, ])("console.log (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); @@ -15,23 +15,23 @@ test.each([ test.each([ { inp: "console.trace()", - expected: "print(debug.traceback())", + expected: "print(\n debug.traceback()\n)", }, { inp: 'console.trace("message")', - expected: 'print(debug.traceback("message"))', + expected: 'print(\n debug.traceback("message")\n)', }, { inp: 'console.trace("Hello %s", "there")', - expected: 'print(debug.traceback(string.format("Hello %s", "there")))', + expected: 'print(\n debug.traceback(\n string.format("Hello %s", "there")\n )\n)', }, { inp: 'console.trace("Hello %%s", "there")', - expected: 'print(debug.traceback(string.format("Hello %%s", "there")))', + expected: 'print(\n debug.traceback(\n string.format("Hello %%s", "there")\n )\n)', }, { inp: 'console.trace("Hello", "there")', - expected: 'print(debug.traceback("Hello", "there"))', + expected: 'print(\n debug.traceback("Hello", "there")\n)', }, ])("console.trace (%p)", ({ inp, expected }) => { expect(util.transpileString(inp, compilerOptions)).toBe(expected); @@ -48,11 +48,11 @@ test.each([ }, { inp: 'console.assert(false, "message %s", "info")', - expected: 'assert(false, string.format("message %s", "info"))', + expected: 'assert(\n false,\n string.format("message %s", "info")\n)', }, { inp: 'console.assert(false, "message %%s", "info")', - expected: 'assert(false, string.format("message %%s", "info"))', + expected: 'assert(\n false,\n string.format("message %%s", "info")\n)', }, { inp: 'console.assert(false, "message", "more")', diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 54323e528..2d71a9fe8 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -1,11 +1,11 @@ import * as util from "../util"; test.each([ - { inp: `{a:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, - { inp: `{"a":3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, - { inp: `{["a"]:3,b:"4"}`, out: '{\n a = 3,\n b = "4",\n}' }, - { inp: `{["a"+123]:3,b:"4"}`, out: '{\n ["a" .. 123] = 3,\n b = "4",\n}' }, - { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4",\n}' }, + { inp: `{a:3,b:"4"}`, out: '{a = 3, b = "4"}' }, + { inp: `{"a":3,b:"4"}`, out: '{a = 3, b = "4"}' }, + { inp: `{["a"]:3,b:"4"}`, out: '{a = 3, b = "4"}' }, + { inp: `{["a"+123]:3,b:"4"}`, out: '{["a" .. 123] = 3, b = "4"}' }, + { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4"\n}' }, { inp: `{x}`, out: `{x = x}` }, ])("Object Literal (%p)", ({ inp, out }) => { const lua = util.transpileString(`const myvar = ${inp};`); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 1177ff262..28201f12e 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -15,7 +15,7 @@ test("Spread Element Lua 5.1", () => { luaLibImport: tstl.LuaLibImportKind.None, }; const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); - expect(lua).toBe("__TS__ArrayPush({}, unpack({\n 1,\n 2,\n 3,\n}))"); + expect(lua).toBe("__TS__ArrayPush(\n {},\n unpack({1, 2, 3})\n)"); }); test("Spread Element Lua 5.2", () => { @@ -24,7 +24,7 @@ test("Spread Element Lua 5.2", () => { luaLibImport: tstl.LuaLibImportKind.None, }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); + expect(lua).toBe("local ____ = {\n table.unpack({0, 1, 2})\n}"); }); test("Spread Element Lua 5.3", () => { @@ -33,7 +33,7 @@ test("Spread Element Lua 5.3", () => { luaLibImport: tstl.LuaLibImportKind.None, }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {table.unpack({\n 0,\n 1,\n 2,\n})}"); + expect(lua).toBe("local ____ = {\n table.unpack({0, 1, 2})\n}"); }); test("Spread Element Lua JIT", () => { @@ -42,7 +42,7 @@ test("Spread Element Lua JIT", () => { luaLibImport: tstl.LuaLibImportKind.None, }; const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})}"); + expect(lua).toBe("local ____ = {\n unpack({0, 1, 2})\n}"); }); test("Spread Element Iterable", () => { From 3fa2065ac064702addb9336a32f532c7b59b3535 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sun, 30 Jun 2019 00:10:58 +1000 Subject: [PATCH 121/764] Omitted expression support (#643) * Omitted expression support * Add test for result of omitted expression * Check the contents of the same array * Neaten up test * Support OmittedExpressions in array binding assignments * Make transformOmittedExpression context aware and use transformBindingExpression --- src/LuaTransformer.ts | 17 ++++++++++++++--- src/TSHelper.ts | 13 +++++++++++++ test/unit/array.spec.ts | 19 +++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index d1fd6226e..e13a9a831 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2683,6 +2683,8 @@ export class LuaTransformer { return this.transformArrayLiteral(expression as ts.ArrayLiteralExpression); case ts.SyntaxKind.ObjectLiteralExpression: return this.transformObjectLiteral(expression as ts.ObjectLiteralExpression); + case ts.SyntaxKind.OmittedExpression: + return this.transformOmittedExpression(expression as ts.OmittedExpression); case ts.SyntaxKind.DeleteExpression: return this.transformDeleteExpression(expression as ts.DeleteExpression); case ts.SyntaxKind.FunctionExpression: @@ -2909,7 +2911,7 @@ export class LuaTransformer { // Destructuring assignment const left = expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformExpression(e)) + ? expression.left.elements.map(e => this.transformArrayBindingExpression(e)) : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { @@ -3466,6 +3468,11 @@ export class LuaTransformer { return tstl.createTableExpression(properties, expression); } + public transformOmittedExpression(node: ts.OmittedExpression): ExpressionVisitResult { + const isWithinBindingAssignmentStatement = tsHelper.isWithinLiteralAssignmentStatement(node); + return isWithinBindingAssignmentStatement ? tstl.createAnonymousIdentifier() : tstl.createNilLiteral(node); + } + public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { const lhs = this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression; const assignment = tstl.createAssignmentStatement(lhs, tstl.createNilLiteral(), expression); @@ -4577,14 +4584,18 @@ export class LuaTransformer { } public transformArrayBindingElement(name: ts.ArrayBindingElement): ExpressionVisitResult { + return this.transformArrayBindingExpression(name as ts.Expression); + } + + public transformArrayBindingExpression(name: ts.Expression): ExpressionVisitResult { if (ts.isOmittedExpression(name)) { - return tstl.createIdentifier("__", name); + return this.transformOmittedExpression(name); } else if (ts.isIdentifier(name)) { return this.transformIdentifier(name); } else if (ts.isBindingElement(name) && ts.isIdentifier(name.name)) { return this.transformIdentifier(name.name); } else { - throw TSTLErrors.UnsupportedKind("array binding element", name.kind, name); + throw TSTLErrors.UnsupportedKind("array binding expression", name.kind, name); } } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index e5ebb14af..c8216b567 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -794,6 +794,19 @@ export function isEnumMember( } } +export function isWithinLiteralAssignmentStatement(node: ts.Node): boolean { + if (!node.parent) { + return false; + } + if (ts.isArrayLiteralExpression(node.parent) || ts.isObjectLiteralExpression(node.parent)) { + return isWithinLiteralAssignmentStatement(node.parent); + } else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { + return true; + } else { + return false; + } +} + export function moduleHasEmittedBody( statement: ts.ModuleDeclaration ): statement is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index 44d3cb3d6..d3949620f 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -191,3 +191,22 @@ test.each([ `; expect(() => util.transpileAndExecute(code)).toThrowError(`invalid array length: ${result}`); }); + +test.each([0, 1, 2])("Array with OmittedExpression", index => { + const result = util.transpileAndExecute( + `const myarray = [1, , 2]; + return myarray[${index}];` + ); + + expect(result).toBe([1, , 2][index]); +}); + +test("OmittedExpression in Array Binding Assignment Statement", () => { + const result = util.transpileAndExecute( + `let a, c; + [a, , c] = [1, 2, 3]; + return a + c;` + ); + + expect(result).toBe(4); +}); From 95da8fe37d86817f2f9632f11bf1b738d30361d2 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 2 Jul 2019 13:19:19 -0600 Subject: [PATCH 122/764] Non-module namespace merge (#646) * Fixed non-module namespace merging * cleanup and comments --- src/LuaTransformer.ts | 43 ++++++++++++++----- .../__snapshots__/transformation.spec.ts.snap | 7 +-- test/unit/modules.spec.ts | 20 +++++++++ test/util.ts | 17 +++++--- 4 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e13a9a831..9ee2b490a 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1585,6 +1585,13 @@ export class LuaTransformer { const symbol = this.checker.getSymbolAtLocation(statement.name); const hasExports = symbol !== undefined && this.checker.getExportsOfModule(symbol).length > 0; + const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); + const exportScope = this.getIdentifierExportScope(nameIdentifier); + + // Non-module namespace could be merged if: + // - is top level + // - is nested and exported + const isNonModuleMergeable = !this.isModule && (!this.currentNamespace || exportScope); // This is NOT the first declaration if: // - declared as a module before this (ignore interfaces with same name) @@ -1594,9 +1601,19 @@ export class LuaTransformer { (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 && statement === symbol.declarations.find(ts.isModuleDeclaration)); - const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); + if (isNonModuleMergeable) { + // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' + const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( + nameIdentifier, + tstl.createBinaryExpression( + this.addExportToIdentifier(nameIdentifier), + tstl.createTableExpression(), + tstl.SyntaxKind.OrOperator + ) + ); - if (isFirstDeclaration) { + result.push(...localDeclaration); + } else if (isFirstDeclaration) { // local NS = {} or exportTable.NS = {} const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( nameIdentifier, @@ -1604,17 +1621,21 @@ export class LuaTransformer { ); result.push(...localDeclaration); + } - const exportScope = this.getIdentifierExportScope(nameIdentifier); - if (exportScope && hasExports && tsHelper.moduleHasEmittedBody(statement)) { - // local NS = exportTable.NS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - this.createModuleLocalNameIdentifier(statement), - this.createExportedIdentifier(nameIdentifier, exportScope) - ); + if ( + (isNonModuleMergeable || isFirstDeclaration) && + exportScope && + hasExports && + tsHelper.moduleHasEmittedBody(statement) + ) { + // local NS = exportTable.NS + const localDeclaration = this.createHoistableVariableDeclarationStatement( + this.createModuleLocalNameIdentifier(statement), + this.createExportedIdentifier(nameIdentifier, exportScope) + ); - result.push(localDeclaration); - } + result.push(localDeclaration); } // Set current namespace for nested NS diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index add5eab21..dfc23372a 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -455,7 +455,7 @@ end return ____exports" `; -exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = {}"`; +exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {}"`; exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` "local ____exports = {} @@ -487,7 +487,7 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\""`; exports[`Transformation (namespace) 1`] = ` -"myNamespace = {} +"myNamespace = myNamespace or {} do local function nsMember(self) end @@ -521,6 +521,7 @@ function MergedClass.prototype.methodB(self) self:methodA() self:propertyFunc() end +MergedClass = MergedClass or {} do function MergedClass.namespaceFunc(self) end @@ -533,7 +534,7 @@ MergedClass:namespaceFunc()" `; exports[`Transformation (namespaceNested) 1`] = ` -"myNamespace = {} +"myNamespace = myNamespace or {} do local myNestedNamespace = {} do diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 8b52cfc1c..5134067b7 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -160,3 +160,23 @@ test("Module merged with interface", () => { const code = `return Foo.bar();`; expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); }); + +test("module merged across files", () => { + const testA = ` + namespace NS { + export namespace Inner { + export const foo = "foo"; + } + } + `; + const testB = ` + namespace NS { + export namespace Inner { + export const bar = "bar"; + } + } + `; + const { transpiledFiles } = util.transpileStringsAsProject({ "testA.ts": testA, "testB.ts": testB }); + const lua = transpiledFiles.map(f => f.lua).join("\n") + "\nreturn NS.Inner.foo .. NS.Inner.bar"; + expect(util.executeLua(lua)).toBe("foobar"); +}); diff --git a/test/util.ts b/test/util.ts index 3da13b395..6c314780b 100644 --- a/test/util.ts +++ b/test/util.ts @@ -20,10 +20,10 @@ export function transpileString( return file.lua.trim(); } -export function transpileStringResult( - input: string | Record, +export function transpileStringsAsProject( + input: Record, options: tstl.CompilerOptions = {} -): Required { +): tstl.TranspileResult { const optionsWithDefaults = { luaTarget: tstl.LuaTarget.Lua53, noHeader: true, @@ -34,9 +34,16 @@ export function transpileStringResult( ...options, }; - const { diagnostics, transpiledFiles } = tstl.transpileVirtualProject( + return tstl.transpileVirtualProject(input, optionsWithDefaults); +} + +export function transpileStringResult( + input: string | Record, + options: tstl.CompilerOptions = {} +): Required { + const { diagnostics, transpiledFiles } = transpileStringsAsProject( typeof input === "string" ? { "main.ts": input } : input, - optionsWithDefaults + options ); const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); From eb7ae08ae9129e23765a7b721246dfcf84d06c73 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 3 Jul 2019 06:30:19 +1000 Subject: [PATCH 123/764] Tagged template literals support (#638) * Implement Tagged Template Literals * Add unicode escape test * Keep track of raw strings * Improve raw string preservation and use type narrowing * Simplfy method using TypeScript's example * Fix ContextType reference * Remove unnecessary check * Reduce checks and use filterUndefinedAndCast * Add transformContextualCallExpression to transform call expression left hand side --- src/LuaTransformer.ts | 132 +++++++++++++++++------ src/TSHelper.ts | 9 ++ test/unit/taggedTemplateLiterals.spec.ts | 123 +++++++++++++++++++++ 3 files changed, 231 insertions(+), 33 deletions(-) create mode 100644 test/unit/taggedTemplateLiterals.spec.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9ee2b490a..dcc43dd48 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2683,6 +2683,8 @@ export class LuaTransformer { case ts.SyntaxKind.StringLiteral: case ts.SyntaxKind.NoSubstitutionTemplateLiteral: return this.transformStringLiteral(expression as ts.StringLiteral); + case ts.SyntaxKind.TaggedTemplateExpression: + return this.transformTaggedTemplateExpression(expression as ts.TaggedTemplateExpression); case ts.SyntaxKind.TemplateExpression: return this.transformTemplateExpression(expression as ts.TemplateExpression); case ts.SyntaxKind.NumericLiteral: @@ -3835,20 +3837,8 @@ export class LuaTransformer { !signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void ) { - if ( - luaKeywords.has(node.expression.name.text) || - !tsHelper.isValidLuaIdentifier(node.expression.name.text) - ) { - return this.transformElementCall(node); - } else { - // table:name() - return tstl.createMethodCallExpression( - table, - this.transformIdentifier(node.expression.name), - parameters, - node - ); - } + // table:name() + return this.transformContextualCallExpression(node, parameters); } else { // table.name() const callPath = tstl.createTableIndexExpression( @@ -3868,43 +3858,67 @@ export class LuaTransformer { } const signature = this.checker.getResolvedSignature(node); - let parameters = this.transformArguments(node.arguments, signature); - const signatureDeclaration = signature && signature.getDeclaration(); + const parameters = this.transformArguments(node.arguments, signature); if ( !signatureDeclaration || tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void ) { - // Pass left-side as context + // A contextual parameter must be given to this call expression + return this.transformContextualCallExpression(node, parameters); + } else { + // No context + const expression = this.transformExpression(node.expression); + return tstl.createCallExpression(expression, parameters); + } + } - const context = this.transformExpression(node.expression.expression); - if (tsHelper.isExpressionWithEvaluationEffect(node.expression.expression)) { + public transformContextualCallExpression( + node: ts.CallExpression | ts.TaggedTemplateExpression, + transformedArguments: tstl.Expression[] + ): ExpressionVisitResult { + const left = ts.isCallExpression(node) ? node.expression : node.tag; + const leftHandSideExpression = this.transformExpression(left); + if ( + ts.isPropertyAccessExpression(left) && + !luaKeywords.has(left.name.text) && + tsHelper.isValidLuaIdentifier(left.name.text) + ) { + // table:name() + const table = this.transformExpression(left.expression); + return tstl.createMethodCallExpression( + table, + this.transformIdentifier(left.name), + transformedArguments, + node + ); + } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { + const context = this.transformExpression(left.expression); + if (tsHelper.isExpressionWithEvaluationEffect(left.expression)) { // Inject context parameter - if (node.arguments.length > 0) { - parameters.unshift(tstl.createIdentifier("____TS_self")); - } else { - parameters = [tstl.createIdentifier("____TS_self")]; - } + transformedArguments.unshift(tstl.createIdentifier("____TS_self")); // Cache left-side if it has effects //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() - const argumentExpression = ts.isElementAccessExpression(node.expression) - ? node.expression.argumentExpression - : ts.createStringLiteral(node.expression.name.text); + const argumentExpression = ts.isElementAccessExpression(left) + ? left.argumentExpression + : ts.createStringLiteral(left.name.text); const argument = this.transformExpression(argumentExpression); const selfIdentifier = tstl.createIdentifier("____TS_self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); - const callExpression = tstl.createCallExpression(index, parameters); + const callExpression = tstl.createCallExpression(index, transformedArguments); return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); } else { - const expression = this.transformExpression(node.expression); - return tstl.createCallExpression(expression, [context, ...parameters]); + const expression = this.transformExpression(left); + return tstl.createCallExpression(expression, [context, ...transformedArguments]); } + } else if (ts.isIdentifier(left)) { + const context = this.isStrict ? tstl.createNilLiteral() : tstl.createIdentifier("_G"); + transformedArguments.unshift(context); + return tstl.createCallExpression(leftHandSideExpression, transformedArguments, node); } else { - // No context - const expression = this.transformExpression(node.expression); - return tstl.createCallExpression(expression, parameters); + throw TSTLErrors.UnsupportedKind("Left Hand Side Call Expression", left.kind, left); } } @@ -4678,6 +4692,58 @@ export class LuaTransformer { return this.createSelfIdentifier(thisKeyword); } + public transformTaggedTemplateExpression(expression: ts.TaggedTemplateExpression): ExpressionVisitResult { + const strings: string[] = []; + const rawStrings: string[] = []; + const expressions: ts.Expression[] = []; + + if (ts.isTemplateExpression(expression.template)) { + // Expressions are in the string. + strings.push(expression.template.head.text); + rawStrings.push(tsHelper.getRawLiteral(expression.template.head)); + strings.push(...expression.template.templateSpans.map(span => span.literal.text)); + rawStrings.push(...expression.template.templateSpans.map(span => tsHelper.getRawLiteral(span.literal))); + expressions.push(...expression.template.templateSpans.map(span => span.expression)); + } else { + // No expressions are in the string. + strings.push(expression.template.text); + rawStrings.push(tsHelper.getRawLiteral(expression.template)); + } + + // Construct table with strings and literal strings + const stringTableLiteral = tstl.createTableExpression( + strings.map(partialString => tstl.createTableFieldExpression(tstl.createStringLiteral(partialString))) + ); + if (stringTableLiteral.fields) { + const rawStringArray = tstl.createTableExpression( + rawStrings.map(stringLiteral => + tstl.createTableFieldExpression(tstl.createStringLiteral(stringLiteral)) + ) + ); + stringTableLiteral.fields.push( + tstl.createTableFieldExpression(rawStringArray, tstl.createStringLiteral("raw")) + ); + } + + // Evaluate if there is a self parameter to be used. + const signature = this.checker.getResolvedSignature(expression); + const signatureDeclaration = signature && signature.getDeclaration(); + const useSelfParameter = + signatureDeclaration && + tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void; + + // Argument evaluation. + const callArguments = this.transformArguments(expressions, signature); + callArguments.unshift(stringTableLiteral); + + if (useSelfParameter) { + return this.transformContextualCallExpression(expression, callArguments); + } + + const leftHandSideExpression = this.transformExpression(expression.tag); + return tstl.createCallExpression(leftHandSideExpression, callArguments); + } + public transformTemplateExpression(expression: ts.TemplateExpression): ExpressionVisitResult { const parts: tstl.Expression[] = []; diff --git a/src/TSHelper.ts b/src/TSHelper.ts index c8216b567..b587f99e9 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -742,6 +742,15 @@ export function getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFil return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; } +export function getRawLiteral(node: ts.LiteralLikeNode): string { + let text = node.getText(); + const isLast = + node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === ts.SyntaxKind.TemplateTail; + text = text.substring(1, text.length - (isLast ? 1 : 2)); + text = text.replace(/\r\n?/g, "\n").replace(/\\/g, "\\\\"); + return text; +} + export function isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean { const symbol = checker.getSymbolAtLocation(node.name); if (!symbol) { diff --git a/test/unit/taggedTemplateLiterals.spec.ts b/test/unit/taggedTemplateLiterals.spec.ts new file mode 100644 index 000000000..6ab4e68cd --- /dev/null +++ b/test/unit/taggedTemplateLiterals.spec.ts @@ -0,0 +1,123 @@ +import * as util from "../util"; + +const testCases = [ + { + callExpression: "func``", + joinAllResult: "", + joinRawResult: "", + }, + { + callExpression: "func`hello`", + joinAllResult: "hello", + joinRawResult: "hello", + }, + { + callExpression: "func`hello ${1} ${2} ${3}`", + joinAllResult: "hello 1 2 3", + joinRawResult: "hello ", + }, + { + callExpression: "func`hello ${(() => 'iife')()}`", + joinAllResult: "hello iife", + joinRawResult: "hello ", + }, + { + callExpression: "func`hello ${1 + 2 + 3} arithmetic`", + joinAllResult: "hello 6 arithmetic", + joinRawResult: "hello arithmetic", + }, + { + callExpression: "func`begin ${'middle'} end`", + joinAllResult: "begin middle end", + joinRawResult: "begin end", + }, + { + callExpression: "func`hello ${func`hello`}`", + joinAllResult: "hello hello", + joinRawResult: "hello ", + }, + { + callExpression: "func`hello \\u00A9`", + joinAllResult: "hello ©", + joinRawResult: "hello \\u00A9", + }, + { + callExpression: "func`hello $ { }`", + joinAllResult: "hello $ { }", + joinRawResult: "hello $ { }", + }, + { + callExpression: "func`hello { ${'brackets'} }`", + joinAllResult: "hello { brackets }", + joinRawResult: "hello { }", + }, + { + callExpression: "func`hello \\``", + joinAllResult: "hello `", + joinRawResult: "hello \\`", + }, + { + callExpression: "obj.func`hello ${'propertyAccessExpression'}`", + joinAllResult: "hello propertyAccessExpression", + joinRawResult: "hello ", + }, + { + callExpression: "obj['func']`hello ${'elementAccessExpression'}`", + joinAllResult: "hello elementAccessExpression", + joinRawResult: "hello ", + }, +]; + +test.each(testCases)("TaggedTemplateLiteral call (%p)", ({ callExpression, joinAllResult }) => { + const result = util.transpileAndExecute(` + function func(strings: TemplateStringsArray, ...expressions: any[]) { + const toJoin = []; + for (let i = 0; i < strings.length; ++i) { + if (strings[i]) { + toJoin.push(strings[i]); + } + if (expressions[i]) { + toJoin.push(expressions[i]); + } + } + return toJoin.join(""); + } + const obj = { + func + }; + return ${callExpression}; + `); + + expect(result).toBe(joinAllResult); +}); + +test.each(testCases)("TaggedTemplateLiteral raw preservation (%p)", ({ callExpression, joinRawResult }) => { + const result = util.transpileAndExecute(` + function func(strings: TemplateStringsArray, ...expressions: any[]) { + return strings.raw.join(""); + } + const obj = { + func + }; + return ${callExpression}; + `); + + expect(result).toBe(joinRawResult); +}); + +test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`noSelfParameter`"])( + "TaggedTemplateLiteral no self parameter", + callExpression => { + const result = util.transpileAndExecute(` + function func(this: void, strings: TemplateStringsArray, ...expressions: any[]) { + return strings.join(""); + } + const obj = { + func + }; + return ${callExpression}; + `); + + expect(result).toBe("noSelfParameter"); + } +); From 548fda967ec1d37a1451097e5c659bd8089fd5f2 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 3 Jul 2019 21:31:21 +0200 Subject: [PATCH 124/764] Feature/emit host (#647) * Added EmitHost * Fixed build failing * Use ts.sys.readFile as default instead of fs.readFile * Made emithost default ts.sys, removed it being passed in without use. * Use method syntax for emithost readFile --- build_lualib.ts | 6 +++++- src/Emit.ts | 17 +++++++++++++---- src/LuaLib.ts | 11 ++++++++--- src/LuaPrinter.ts | 8 ++++++-- src/Transpile.ts | 8 +++++++- 5 files changed, 39 insertions(+), 11 deletions(-) diff --git a/build_lualib.ts b/build_lualib.ts index a620df2ac..330a3ef04 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -16,4 +16,8 @@ if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } -fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature))); +const emitHost = { + readFile: (path: string) => fs.readFileSync(path, "utf-8"), + writeFile: fs.writeFileSync, +}; +fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature), emitHost)); diff --git a/src/Emit.ts b/src/Emit.ts index e2004b0f9..50d5c1fdf 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -1,7 +1,7 @@ -import * as fs from "fs"; import * as path from "path"; +import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; -import { TranspiledFile } from "./Transpile"; +import { TranspiledFile, EmitHost } from "./Transpile"; const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); @@ -12,7 +12,11 @@ export interface OutputFile { } let lualibContent: string; -export function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: TranspiledFile[]): OutputFile[] { +export function emitTranspiledFiles( + options: CompilerOptions, + transpiledFiles: TranspiledFile[], + emitHost: EmitHost = ts.sys +): OutputFile[] { let { rootDir, outDir, outFile, luaLibImport } = options; const configFileName = options.configFilePath as string | undefined; @@ -57,7 +61,12 @@ export function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: T if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) { if (lualibContent === undefined) { - lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); + const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); + if (lualibBundle !== undefined) { + lualibContent = lualibBundle; + } else { + throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua"); + } } let outPath = path.resolve(rootDir, "lualib_bundle.lua"); diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 23a9711ad..d611a28bb 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,5 +1,5 @@ -import * as fs from "fs"; import * as path from "path"; +import { EmitHost } from "./Transpile"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -73,7 +73,7 @@ const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { }; export class LuaLib { - public static loadFeatures(features: Iterable): string { + public static loadFeatures(features: Iterable, emitHost: EmitHost): string { let result = ""; const loadedFeatures = new Set(); @@ -86,7 +86,12 @@ export class LuaLib { dependencies.forEach(load); } const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - result += fs.readFileSync(featureFile).toString() + "\n"; + const luaLibFeature = emitHost.readFile(featureFile); + if (luaLibFeature !== undefined) { + result += luaLibFeature.toString() + "\n"; + } else { + throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`); + } } } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index ebac13788..e5058cbf5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -5,6 +5,7 @@ import * as tstl from "./LuaAST"; import { luaKeywords } from "./LuaKeywords"; import { LuaLib, LuaLibFeature } from "./LuaLib"; import * as tsHelper from "./TSHelper"; +import { EmitHost } from "./Transpile"; type SourceChunk = string | SourceNode; @@ -38,12 +39,15 @@ export class LuaPrinter { }; private options: CompilerOptions; + private emitHost: EmitHost; + private currentIndent: string; private sourceFile = ""; - public constructor(options: CompilerOptions) { + public constructor(options: CompilerOptions, emitHost: EmitHost) { this.options = options; + this.emitHost = emitHost; this.currentIndent = ""; } @@ -128,7 +132,7 @@ export class LuaPrinter { // Inline lualib features else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { header += "-- Lua Library inline imports\n"; - header += LuaLib.loadFeatures(luaLibFeatures); + header += LuaLib.loadFeatures(luaLibFeatures, this.emitHost); } } diff --git a/src/Transpile.ts b/src/Transpile.ts index f02810b78..b0d0d4c0a 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -27,14 +27,20 @@ export interface TranspileOptions { customTransformers?: ts.CustomTransformers; transformer?: LuaTransformer; printer?: LuaPrinter; + emitHost?: EmitHost; +} + +export interface EmitHost { + readFile(path: string): string | undefined; } export function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, + emitHost = ts.sys, transformer = new LuaTransformer(program), - printer = new LuaPrinter(program.getCompilerOptions()), + printer = new LuaPrinter(program.getCompilerOptions(), emitHost), }: TranspileOptions): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; From 318d1a2a5a344aeed859df0b666a017c9c9c660a Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 3 Jul 2019 21:58:20 +0200 Subject: [PATCH 125/764] 0.23.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 20af9473f..d65fdef5c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.22.1", + "version": "0.23.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 6f8d6a888..97a3f3ac7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.22.1", + "version": "0.23.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 8fd1175ca39d0fb70a64c3b5af8f437d985c4b5f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 3 Jul 2019 22:13:01 +0200 Subject: [PATCH 126/764] Update CHANGELOG.md --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1afd5d2e7..631d0bb8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.23.0 + +- Added support for OmittedExpression in array literals and array binding patterns. +- Added support for [tagged template literals](https://basarat.gitbooks.io/typescript/docs/template-strings.html#tagged-templates). +- Changed output lua formatting to be more debugger-friendly. +- Various improvements to source maps. + +- Fixed an issue with the interaction of super calls and exported classes. +- Fixed `@noResolution` not working on named modules. +- Fixed namespace merging not working due to an earlier change. + +- Some refactoring and plumbing for the website. + ## 0.22.0 - Added the [@vararg](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#vararg) directive. From 85050fdd35f11fab9d3fa93e2b92b2223ae892e4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 4 Jul 2019 15:08:24 -0600 Subject: [PATCH 127/764] Handling return from try and catch (#642) * handling return from try and catch * tupleReturn+finally tests * clarifying some comments --- src/LuaTransformer.ts | 155 ++++++++++++++++++++------ test/unit/error.spec.ts | 236 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 359 insertions(+), 32 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index dcc43dd48..450ad6af5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -17,6 +17,8 @@ export enum ScopeType { Loop = 0x8, Conditional = 0x10, Block = 0x20, + Try = 0x40, + Catch = 0x80, } interface SymbolInfo { @@ -37,6 +39,7 @@ interface Scope { functionDefinitions?: Map; importStatements?: tstl.Statement[]; loopContinued?: boolean; + functionReturned?: boolean; } export interface EmitResolver { @@ -2132,23 +2135,33 @@ export class LuaTransformer { } public transformReturnStatement(statement: ts.ReturnStatement): StatementVisitResult { + // Bubble up explicit return flag and check if we're inside a try/catch block + let insideTryCatch = false; + for (let i = this.scopeStack.length - 1; i >= 0; --i) { + const scope = this.scopeStack[i]; + scope.functionReturned = true; + + if (scope.type === ScopeType.Function) { + break; + } + + insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; + } + + let results: tstl.Expression[]; + if (statement.expression) { + const expressionType = this.checker.getTypeAtLocation(statement.expression); const returnType = tsHelper.getContainingFunctionReturnType(statement, this.checker); if (returnType) { - const expressionType = this.checker.getTypeAtLocation(statement.expression); this.validateFunctionAssignment(statement, expressionType, returnType); } if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(statement.expression)) { // If return expression is an array literal, leave out brackets. - return tstl.createReturnStatement( - statement.expression.elements.map(elem => this.transformExpression(elem)) - ); - } - - const expressionType = this.checker.getTypeAtLocation(statement.expression); - if ( + results = statement.expression.elements.map(elem => this.transformExpression(elem)); + } else if ( !tsHelper.isTupleReturnCall(statement.expression, this.checker) && tsHelper.isArrayType(expressionType, this.checker, this.program) ) { @@ -2157,15 +2170,28 @@ export class LuaTransformer { this.transformExpression(statement.expression), statement.expression ); - return tstl.createReturnStatement([expression]); + results = [expression]; + } else { + results = [this.transformExpression(statement.expression)]; } + + // Wrap tupleReturn results when returning inside try/catch + if (insideTryCatch) { + results = [this.wrapInTable(...results)]; + } + } else { + results = [this.transformExpression(statement.expression)]; } - const returnExpressions = [this.transformExpression(statement.expression)]; - return tstl.createReturnStatement(returnExpressions, statement); } else { // Empty return - return tstl.createReturnStatement([], statement); + results = []; } + + if (insideTryCatch) { + results.unshift(tstl.createBooleanLiteral(true)); + } + + return tstl.createReturnStatement(results, statement); } public transformIfStatement(statement: ts.IfStatement): StatementVisitResult { @@ -2592,39 +2618,104 @@ export class LuaTransformer { } } + protected transformScopeBlock(block: ts.Block, scopeType: ScopeType): [tstl.Block, Scope] { + this.pushScope(scopeType); + const statements = this.performHoisting(this.transformStatements(block.statements)); + const scope = this.popScope(); + return [tstl.createBlock(statements, block), scope]; + } + public transformTryStatement(statement: ts.TryStatement): StatementVisitResult { - const pCall = tstl.createIdentifier("pcall"); - const tryBlock = this.transformBlock(statement.tryBlock); - const tryCall = tstl.createCallExpression(pCall, [tstl.createFunctionExpression(tryBlock)]); + const [tryBlock, tryScope] = this.transformScopeBlock(statement.tryBlock, ScopeType.Try); + + const tryResultIdentfier = tstl.createIdentifier("____TS_try"); + const returnValueIdentifier = tstl.createIdentifier("____TS_returnValue"); const result: tstl.Statement[] = []; - if (statement.catchClause) { - const tryResult = tstl.createIdentifier("____TS_try"); + let returnedIdentifier: tstl.Identifier | undefined; + let returnCondition: tstl.Expression | undefined; - const returnVariables = - statement.catchClause && statement.catchClause.variableDeclaration - ? [ - tryResult, - this.transformIdentifier(statement.catchClause.variableDeclaration.name as ts.Identifier), - ] - : [tryResult]; + const pCall = tstl.createIdentifier("pcall"); + const tryCall = tstl.createCallExpression(pCall, [tstl.createFunctionExpression(tryBlock)]); - const catchAssignment = tstl.createVariableDeclarationStatement(returnVariables, tryCall); + if (statement.catchClause && statement.catchClause.block.statements.length > 0) { + // try with catch + let [catchBlock, catchScope] = this.transformScopeBlock(statement.catchClause.block, ScopeType.Catch); + if (statement.catchClause.variableDeclaration) { + // Replace ____TS_returned with catch variable + returnedIdentifier = this.transformIdentifier(statement.catchClause.variableDeclaration + .name as ts.Identifier); + } else if (tryScope.functionReturned || catchScope.functionReturned) { + returnedIdentifier = tstl.createIdentifier("____TS_returned"); + } - result.push(catchAssignment); + const tryReturnIdentifiers = [tryResultIdentfier]; // ____TS_try + if (returnedIdentifier) { + tryReturnIdentifiers.push(returnedIdentifier); // ____TS_returned or catch variable + if (tryScope.functionReturned || catchScope.functionReturned) { + tryReturnIdentifiers.push(returnValueIdentifier); // ____TS_returnValue + returnCondition = tstl.cloneIdentifier(returnedIdentifier); + } + } + result.push(tstl.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); - const notTryResult = tstl.createUnaryExpression( - tstl.createParenthesizedExpression(tryResult), + if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { + // Wrap catch in function if try or catch has return + const catchCall = tstl.createCallExpression( + tstl.createParenthesizedExpression(tstl.createFunctionExpression(catchBlock)) + ); + const catchAssign = tstl.createAssignmentStatement( + [tstl.cloneIdentifier(returnedIdentifier), tstl.cloneIdentifier(returnValueIdentifier)], + catchCall + ); + catchBlock = tstl.createBlock([catchAssign]); + } + const notTryCondition = tstl.createUnaryExpression( + tstl.createParenthesizedExpression(tryResultIdentfier), tstl.SyntaxKind.NotOperator ); - result.push(tstl.createIfStatement(notTryResult, this.transformBlock(statement.catchClause.block))); + result.push(tstl.createIfStatement(notTryCondition, catchBlock)); + } else if (tryScope.functionReturned) { + // try with return, but no catch + returnedIdentifier = tstl.createIdentifier("____TS_returned"); + const returnedVariables = [tryResultIdentfier, returnedIdentifier, returnValueIdentifier]; + result.push(tstl.createVariableDeclarationStatement(returnedVariables, tryCall)); + + // change return condition from '____TS_returned' to '____TS_try and ____TS_returned' + returnCondition = tstl.createBinaryExpression( + tstl.cloneIdentifier(tryResultIdentfier), + returnedIdentifier, + tstl.SyntaxKind.AndOperator + ); } else { + // try without return or catch result.push(tstl.createExpressionStatement(tryCall)); } - if (statement.finallyBlock) { - result.push(tstl.createDoStatement(this.transformBlock(statement.finallyBlock).statements)); + if (statement.finallyBlock && statement.finallyBlock.statements.length > 0) { + result.push(...this.statementVisitResultToArray(this.transformBlockAsDoStatement(statement.finallyBlock))); + } + + if (returnCondition && returnedIdentifier) { + // With catch clause: + // if ____TS_returned then return ____TS_returnValue end + // No catch clause: + // if ____TS_try and ____TS_returned then return ____TS_returnValue end + const returnValues: tstl.Expression[] = []; + const parentTryCatch = this.findScope(ScopeType.Function | ScopeType.Try | ScopeType.Catch); + if (parentTryCatch && parentTryCatch.type !== ScopeType.Function) { + // Nested try/catch needs to prefix a 'true' return value + returnValues.push(tstl.createBooleanLiteral(true)); + } + if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { + returnValues.push(this.createUnpackCall(tstl.cloneIdentifier(returnValueIdentifier))); + } else { + returnValues.push(tstl.cloneIdentifier(returnValueIdentifier)); + } + const returnStatement = tstl.createReturnStatement(returnValues); + const ifReturnedStatement = tstl.createIfStatement(returnCondition, tstl.createBlock([returnStatement])); + result.push(ifReturnedStatement); } return tstl.createDoStatement(result, statement); @@ -4980,7 +5071,7 @@ export class LuaTransformer { return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); } - protected createUnpackCall(expression: tstl.Expression | undefined, tsOriginal: ts.Node): tstl.Expression { + protected createUnpackCall(expression: tstl.Expression | undefined, tsOriginal?: ts.Node): tstl.Expression { switch (this.luaTarget) { case LuaTarget.Lua51: case LuaTarget.LuaJIT: diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 5002e29f3..5f0ec7df6 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -62,3 +62,239 @@ test("re-throw (no catch var)", () => { const result = util.transpileAndExecute(source); expect(result).toBe("z"); }); + +test("return from try", () => { + const code = ` + function foobar() { + try { + return "foobar"; + } catch { + } + } + return foobar(); + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("return nil from try", () => { + const code = ` + let x = "unset"; + function foobar() { + try { + return; + } catch { + } + x = "set"; + } + foobar(); + return x; + `; + expect(util.transpileAndExecute(code)).toBe("unset"); +}); + +test("tuple return from try", () => { + const code = ` + /** @tupleReturn */ + function foobar() { + try { + return ["foo", "bar"]; + } catch { + } + } + const [foo, bar] = foobar(); + return foo + bar; + `; + expect(util.transpileString(code)).not.toMatch("unpack(foobar"); + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("return from catch", () => { + const code = ` + function foobar() { + try { + throw "foobar"; + } catch (e) { + return e + " catch"; + } + } + return foobar(); + `; + expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); +}); + +test("return nil from catch", () => { + const code = ` + let x = "unset"; + function foobar() { + try { + throw "foobar"; + } catch (e) { + return; + } + x = "set"; + } + foobar(); + return x; + `; + expect(util.transpileAndExecute(code)).toBe("unset"); +}); + +test("tuple return from catch", () => { + const code = ` + /** @tupleReturn */ + function foobar(): [string, string] { + try { + throw "foobar"; + } catch (e) { + return [e.toString(), " catch"]; + } + } + const [foo, bar] = foobar(); + return foo + bar; + `; + expect(util.transpileString(code)).not.toMatch("unpack(foobar"); + expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); +}); + +test("return from nested try", () => { + const code = ` + function foobar() { + try { + try { + return "foobar"; + } catch { + } + } catch { + } + } + return foobar(); + `; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); + +test("return from nested catch", () => { + const code = ` + function foobar() { + try { + throw "foobar"; + } catch (e) { + try { + throw e + " catch1"; + } catch (f) { + return f + " catch2"; + } + } + } + return foobar(); + `; + const result = util.transpileAndExecute(code); + expect(result).toMatch("catch1"); + expect(result).toMatch("catch2"); + expect(result).toMatch("foobar"); +}); + +test("return from try->finally", () => { + const code = ` + let x = "unevaluated"; + function evaluate(arg: unknown) { + x = "evaluated"; + return arg; + } + function foobar() { + try { + return evaluate("foobar"); + } catch { + } finally { + return "finally"; + } + } + return foobar() + " " + x; + `; + expect(util.transpileAndExecute(code)).toBe("finally evaluated"); +}); + +test("return from catch->finally", () => { + const code = ` + let x = "unevaluated"; + function evaluate(arg: unknown) { + x = "evaluated"; + return arg; + } + function foobar() { + try { + throw "foobar"; + } catch (e) { + return evaluate(e); + } finally { + return "finally"; + } + } + return foobar() + " " + x; + `; + expect(util.transpileAndExecute(code)).toBe("finally evaluated"); +}); + +test("tuple return from try->finally", () => { + const code = ` + let x = "unevaluated"; + function evaluate(arg: string) { + x = "evaluated"; + return arg; + } + /** @tupleReturn */ + function foobar() { + try { + return [evaluate("foo"), "bar"]; + } catch { + } finally { + return ["final", "ly"]; + } + } + const [foo, bar] = foobar(); + return foo + bar + " " + x; + `; + expect(util.transpileAndExecute(code)).toBe("finally evaluated"); +}); + +test("tuple return from catch->finally", () => { + const code = ` + let x = "unevaluated"; + function evaluate(arg: string) { + x = "evaluated"; + return arg; + } + /** @tupleReturn */ + function foobar() { + try { + throw "foo"; + } catch (e) { + return [evaluate(e), "bar"]; + } finally { + return ["final", "ly"]; + } + } + const [foo, bar] = foobar(); + return foo + bar + " " + x; + `; + expect(util.transpileAndExecute(code)).toBe("finally evaluated"); +}); + +test("return from nested finally", () => { + const code = ` + let x = ""; + function foobar() { + try { + try { + } finally { + x += "A"; + return "foobar"; + } + } finally { + x += "B"; + return "finally"; + } + } + return foobar() + " " + x; + `; + expect(util.transpileAndExecute(code)).toBe("finally AB"); +}); From 3d056c8ba345d6b91b882988c1cb39b697a05c58 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 7 Jul 2019 14:47:11 +0200 Subject: [PATCH 128/764] globalThis to _G (#631) * globalThis to _G Closes #592 * moved globalThis check to transformIdentifierExpression * support for "typeof globalThis" WIP * Removed is standard lib test * globalThis transformation only for identifier name not identifier type. * fixed prettier * Fixed prettier script * Changed transpile -> execute to transpileAndExecute where possible * readd symbol.declaration check * Fixed prettier version inconsistency (1.17.x / 1.18.x) --- package-lock.json | 41 ++++++----------------- package.json | 4 +-- src/LuaTransformer.ts | 18 +++++----- test/unit/identifiers.spec.ts | 63 +++++++++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/package-lock.json b/package-lock.json index d65fdef5c..5514235ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2769,8 +2769,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -2791,14 +2790,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2813,20 +2810,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -2943,8 +2937,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -2956,7 +2949,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2971,7 +2963,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2979,14 +2970,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3005,7 +2994,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3086,8 +3074,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3099,7 +3086,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3185,8 +3171,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3222,7 +3207,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3242,7 +3226,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3286,14 +3269,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/package.json b/package.json index 97a3f3ac7..251f81ee6 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", - "lint:prettier": "prettier --check **/*.{js,ts,yml,json,md} || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", + "lint:prettier": "prettier --check \"**/*.{js,ts,yml,json,md}\" || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:tslint": "tslint -p . && tslint -p test && tslint -p src/lualib", - "fix:prettier": "prettier --check --write **/*.{js,ts,yml,json,md}", + "fix:prettier": "prettier --check --write \"**/*.{js,ts,yml,json,md}\"", "release-major": "npm version major", "release-minor": "npm version minor", "release-patch": "npm version patch", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 450ad6af5..07c82680e 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4876,14 +4876,6 @@ export class LuaTransformer { } public transformIdentifier(identifier: ts.Identifier): tstl.Identifier { - if (identifier.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { - // TODO this is a hack that allows use to keep Identifier - // as return time as changing that would break a lot of stuff. - // But this should be changed to return tstl.createNilLiteral() - // at some point. - return tstl.createIdentifier("nil"); - } - if (tsHelper.isForRangeType(identifier, this.checker)) { const callExpression = tsHelper.findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { @@ -4910,6 +4902,10 @@ export class LuaTransformer { return this.createExportedIdentifier(identifier, exportScope); } + if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + return tstl.createNilLiteral(); + } + switch (this.getIdentifierText(expression)) { case "NaN": return tstl.createParenthesizedExpression( @@ -4925,6 +4921,9 @@ export class LuaTransformer { const math = tstl.createIdentifier("math"); const huge = tstl.createStringLiteral("huge"); return tstl.createTableIndexExpression(math, huge, expression); + + case "globalThis": + return tstl.createIdentifier("_G", expression, this.getIdentifierSymbolId(expression)); } return identifier; @@ -5432,7 +5431,8 @@ export class LuaTransformer { protected hasUnsafeSymbolName(symbol: ts.Symbol, tsOriginal?: ts.Identifier): boolean { const isLuaKeyword = luaKeywords.has(symbol.name); const isInvalidIdentifier = !tsHelper.isValidLuaIdentifier(symbol.name); - const isAmbient = symbol.declarations.some(d => tsHelper.isAmbientNode(d)); + // TODO rework once microsoft/TypeScript#24706 is fixed and remove check for symbol.declarations + const isAmbient = symbol.declarations && symbol.declarations.some(d => tsHelper.isAmbientNode(d)); if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { // Catch ambient declarations of identifiers with bad names throw TSTLErrors.InvalidAmbientIdentifierName(tsOriginal || ts.createIdentifier(symbol.name)); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 7936de507..d8b00733f 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -788,3 +788,66 @@ test("exported variable with lua keyword as name is not renamed", () => { expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); }); + +describe("globalThis translation", () => { + test("globalThis to _G (expression)", () => { + const code = ` + var foo = "bar"; + return globalThis.foo;`; + + const lua = util.transpileString(code); + + expect(util.executeLua(lua)).toBe("bar"); + }); + + test("globalThis to _G (assign)", () => { + const code = ` + globalThis.foo = "bar"; + return globalThis.foo;`; + + expect(util.transpileAndExecute(code)).toBe("bar"); + }); + + test("globalThis to _G (reassign)", () => { + const code = ` + globalThis.foo = "bar"; + globalThis.foo = "baz"; + return globalThis.foo;`; + + expect(util.transpileAndExecute(code)).toBe("baz"); + }); + + test("globalThis to _G (function)", () => { + const code = ` + globalThis.foo = () => "bar"; + return globalThis.foo();`; + + expect(util.transpileAndExecute(code)).toBe("bar"); + }); + + test("globalThis to _G (assign + noImplicitAny)", () => { + const code = ` + (globalThis).foo = "bar"; + return (globalThis).foo;`; + + expect(util.transpileAndExecute(code)).toBe("bar"); + }); + + test("globalThis to _G (var)", () => { + const code = ` + var globalFoo = "bar"; + return globalThis.globalFoo;`; + + const lua = util.transpileString(code); + + expect(util.executeLua(lua)).toBe("bar"); + }); + + test("globalThis to _G (let)", () => { + const code = ` + let NotAGlobalFoo = "bar"; + return (globalThis).NotAGlobalFoo;`; + + expect(util.transpileAndExecute(code)).toBe(undefined); + }); +}); From 44fdccf467c8234cc84a8a7192ef6b31a0da2369 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 7 Jul 2019 07:18:42 -0600 Subject: [PATCH 129/764] Fix for property access on string and array literals (#650) fixes #644 Also addressed a couple other things which came up: - Element call expressions were not adding one to array index - Indexing strings and arrays with types other than numbers created invalid lua code when attempting to add one --- src/LuaTransformer.ts | 73 ++++++++++++++++++++++----------- src/lualib/ArrayIndexOf.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- test/unit/array.spec.ts | 16 ++++++++ test/unit/objectLiteral.spec.ts | 9 ++++ test/unit/string.spec.ts | 9 ++++ 6 files changed, 85 insertions(+), 26 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 07c82680e..b1d54826d 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3118,12 +3118,7 @@ export class LuaTransformer { indexExpression = tstl.createStringLiteral(expression.left.name.text); } else { // Element access - indexExpression = this.transformExpression(expression.left.argumentExpression); - const argType = this.checker.getTypeAtLocation(expression.left.expression); - if (tsHelper.isArrayType(argType, this.checker, this.program)) { - // Array access needs a +1 - indexExpression = this.expressionPlusOne(indexExpression); - } + indexExpression = this.transformElementAccessArgument(expression.left); } const args = [objExpression, indexExpression, this.transformExpression(expression.right)]; @@ -3922,7 +3917,10 @@ export class LuaTransformer { ); } else { const parameters = this.transformArguments(node.arguments, signature); - const table = this.transformExpression(node.expression.expression); + let table = this.transformExpression(node.expression.expression); + if (tstl.isTableExpression(table)) { + table = tstl.createParenthesizedExpression(table); + } const signatureDeclaration = signature && signature.getDeclaration(); if ( !signatureDeclaration || @@ -3959,7 +3957,10 @@ export class LuaTransformer { return this.transformContextualCallExpression(node, parameters); } else { // No context - const expression = this.transformExpression(node.expression); + let expression = this.transformExpression(node.expression); + if (tstl.isTableExpression(expression)) { + expression = tstl.createParenthesizedExpression(expression); + } return tstl.createCallExpression(expression, parameters); } } @@ -3976,7 +3977,10 @@ export class LuaTransformer { tsHelper.isValidLuaIdentifier(left.name.text) ) { // table:name() - const table = this.transformExpression(left.expression); + let table = this.transformExpression(left.expression); + if (tstl.isTableExpression(table)) { + table = tstl.createParenthesizedExpression(table); + } return tstl.createMethodCallExpression( table, this.transformIdentifier(left.name), @@ -3991,10 +3995,9 @@ export class LuaTransformer { // Cache left-side if it has effects //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() - const argumentExpression = ts.isElementAccessExpression(left) - ? left.argumentExpression - : ts.createStringLiteral(left.name.text); - const argument = this.transformExpression(argumentExpression); + const argument = ts.isElementAccessExpression(left) + ? this.transformElementAccessArgument(left) + : tstl.createStringLiteral(left.name.text); const selfIdentifier = tstl.createIdentifier("____TS_self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); @@ -4084,7 +4087,10 @@ export class LuaTransformer { } } - const callPath = this.transformExpression(expression.expression); + let callPath = this.transformExpression(expression.expression); + if (tstl.isTableExpression(callPath)) { + callPath = tstl.createParenthesizedExpression(callPath); + } return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression); } @@ -4188,7 +4194,10 @@ export class LuaTransformer { protected transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { switch (node.name.escapedText) { case "length": - const expression = this.transformExpression(node.expression); + let expression = this.transformExpression(node.expression); + if (ts.isTemplateExpression(node.expression)) { + expression = tstl.createParenthesizedExpression(expression); + } return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: throw TSTLErrors.UnsupportedProperty("string", node.name.escapedText as string, node); @@ -4199,7 +4208,10 @@ export class LuaTransformer { protected transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { switch (node.name.escapedText) { case "length": - const expression = this.transformExpression(node.expression); + let expression = this.transformExpression(node.expression); + if (tstl.isTableExpression(expression)) { + expression = tstl.createParenthesizedExpression(expression); + } return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: return undefined; @@ -4216,27 +4228,40 @@ export class LuaTransformer { } } - public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { - const table = this.transformExpression(expression.expression); + protected transformElementAccessArgument(expression: ts.ElementAccessExpression): tstl.Expression { const index = this.transformExpression(expression.argumentExpression); + const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); + const type = this.checker.getTypeAtLocation(expression.expression); + if (tsHelper.isNumberType(argumentType) && tsHelper.isArrayType(type, this.checker, this.program)) { + return this.expressionPlusOne(index); + } else { + return index; + } + } + + public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { + let table = this.transformExpression(expression.expression); + if (tstl.isTableExpression(table)) { + table = tstl.createParenthesizedExpression(table); + } const constEnumValue = this.tryGetConstEnumValue(expression); if (constEnumValue) { return constEnumValue; } + const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isArrayType(type, this.checker, this.program)) { - return tstl.createTableIndexExpression(table, this.expressionPlusOne(index), expression); - } else if (tsHelper.isStringType(type)) { + if (tsHelper.isNumberType(argumentType) && tsHelper.isStringType(type)) { + const index = this.transformExpression(expression.argumentExpression); return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")), [table, this.expressionPlusOne(index), this.expressionPlusOne(index)], expression ); - } else { - return tstl.createTableIndexExpression(table, index, expression); } + + return tstl.createTableIndexExpression(table, this.transformElementAccessArgument(expression), expression); } private tryGetConstEnumValue( @@ -4369,7 +4394,7 @@ export class LuaTransformer { case "upper": // Allow lua's string instance methods let stringVariable = this.transformExpression(expression.expression); - if (ts.isStringLiteral(expression.expression)) { + if (ts.isStringLiteralLike(expression.expression)) { // "foo":method() needs to be ("foo"):method() stringVariable = tstl.createParenthesizedExpression(stringVariable); } diff --git a/src/lualib/ArrayIndexOf.ts b/src/lualib/ArrayIndexOf.ts index a2eb5ebf0..e91a1a5dc 100644 --- a/src/lualib/ArrayIndexOf.ts +++ b/src/lualib/ArrayIndexOf.ts @@ -13,7 +13,7 @@ function __TS__ArrayIndexOf(this: void, arr: T[], searchElement: T, fromIndex return -1; } - let k; + let k: number; if (n >= 0) { k = n; } else { diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 5e92837b1..bb2527583 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,7 +1,7 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: number, ...items: T[]): T[] { const len = list.length; - let actualStart; + let actualStart: number; if (start < 0) { actualStart = Math.max(len + start, 0); diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index d3949620f..d0496ab56 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -210,3 +210,19 @@ test("OmittedExpression in Array Binding Assignment Statement", () => { expect(result).toBe(4); }); + +test("array access call", () => { + const code = ` + const arr = [() => "foo", () => "bar"]; + return arr[1]();`; + expect(util.transpileAndExecute(code)).toBe("bar"); +}); + +test.each([`["foo", "bar"].length`, `["foo", "bar"][0]`, `[() => "foo", () => "bar"][0]()`])( + "array literal property access (%p)", + expression => { + const code = `return ${expression}`; + const expectResult = eval(expression); + expect(util.transpileAndExecute(code)).toBe(expectResult); + } +); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 2d71a9fe8..b4bcb3d4e 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -55,3 +55,12 @@ test("undefined as object key", () => { return foo.undefined;`; expect(util.transpileAndExecute(code)).toBe("foo"); }); + +test.each([`({x: "foobar"}.x)`, `({x: "foobar"}["x"])`, `({x: () => "foobar"}.x())`, `({x: () => "foobar"}["x"]())`])( + "object literal property access (%p)", + expression => { + const code = `return ${expression}`; + const expectResult = eval(expression); + expect(util.transpileAndExecute(code)).toBe(expectResult); + } +); diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 1f502d211..6c47ddb52 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -339,3 +339,12 @@ test.each(padCases)("string.padEnd (%p)", ({ inp, maxLength, fillString }) => { expect(result).toBe(inp.padEnd(maxLength, fillString)); }); + +test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`foo${'bar'}`.repeat(2)"])( + "string literal property access (%p)", + expression => { + const code = `return ${expression}`; + const expectResult = eval(expression); + expect(util.transpileAndExecute(code)).toBe(expectResult); + } +); From d4f4f52936be279a8b39f360a6de09db0924cc33 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 9 Jul 2019 00:48:49 +0500 Subject: [PATCH 130/764] Separate transformer run method (#655) * Separate transformer run method * Address feedback --- src/LuaPrinter.ts | 12 +---- src/LuaTransformer.ts | 108 ++++++++++++++++++------------------------ src/TSHelper.ts | 15 +++--- src/TSTLErrors.ts | 2 - src/Transpile.ts | 2 +- 5 files changed, 57 insertions(+), 82 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e5058cbf5..3a12194bd 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -38,18 +38,10 @@ export class LuaPrinter { [tstl.SyntaxKind.BitwiseNotOperator]: "~", }; - private options: CompilerOptions; - private emitHost: EmitHost; - - private currentIndent: string; - + private currentIndent = ""; private sourceFile = ""; - public constructor(options: CompilerOptions, emitHost: EmitHost) { - this.options = options; - this.emitHost = emitHost; - this.currentIndent = ""; - } + public constructor(private options: CompilerOptions, private emitHost: EmitHost) {} public print(block: tstl.Block, luaLibFeatures?: Set, sourceFile = ""): [string, string] { // Add traceback lualib if sourcemap traceback option is enabled diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index b1d54826d..81a435f3c 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -54,85 +54,81 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { } export class LuaTransformer { - protected isStrict: boolean; - protected luaTarget: LuaTarget; + protected readonly typeValidationCache = new Map>(); + protected currentNamespace?: ts.ModuleDeclaration; protected checker: DiagnosticsProducingTypeChecker; protected options: CompilerOptions; - // Resolver is lazy-initialized in transformSourceFile to avoid type-checking all files - protected resolver!: EmitResolver; - - protected isModule = false; - protected currentSourceFile?: ts.SourceFile; - - protected currentNamespace: ts.ModuleDeclaration | undefined; - protected classStack: ts.ClassLikeDeclaration[] = []; - - protected scopeStack: Scope[] = []; - protected genVarCounter = 0; - - protected luaLibFeatureSet = new Set(); - - protected symbolInfo = new Map(); - protected symbolIds = new Map(); - - protected genSymbolIdCounter = 0; - - protected readonly typeValidationCache: Map> = new Map>(); + protected luaTarget: LuaTarget; + protected isStrict: boolean; public constructor(protected program: ts.Program) { this.checker = (program as any).getDiagnosticsProducingTypeChecker(); this.options = program.getCompilerOptions(); + + this.luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; this.isStrict = this.options.alwaysStrict !== undefined || (this.options.strict !== undefined && this.options.alwaysStrict !== false) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); - this.luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; - this.setupState(); } - protected setupState(): void { + protected genVarCounter!: number; + protected luaLibFeatureSet!: Set; + + protected scopeStack!: Scope[]; + protected classStack!: ts.ClassLikeDeclaration[]; + + protected symbolInfo!: Map; + protected symbolIds!: Map; + protected genSymbolIdCounter!: number; + + private setupState(): void { this.genVarCounter = 0; - this.currentSourceFile = undefined; - this.isModule = false; + this.luaLibFeatureSet = new Set(); + this.scopeStack = []; this.classStack = []; - this.luaLibFeatureSet = new Set(); - this.symbolIds = new Map(); + this.symbolInfo = new Map(); + this.symbolIds = new Map(); this.genSymbolIdCounter = 1; } - public transformSourceFile(node: ts.SourceFile): [tstl.Block, Set] { - this.setupState(); + protected currentSourceFile!: ts.SourceFile; + protected isModule!: boolean; + protected resolver!: EmitResolver; - this.currentSourceFile = node; + /** @internal */ + public transform(sourceFile: ts.SourceFile): [tstl.Block, Set] { + this.setupState(); + this.currentSourceFile = sourceFile; + this.isModule = tsHelper.isFileModule(sourceFile); // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` // and would try to re-analyze the file, which would fail because of replaced nodes. - const originalSourceFile = ts.getParseTreeNode(node, ts.isSourceFile) || node; + const originalSourceFile = ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; this.resolver = this.checker.getEmitResolver(originalSourceFile); - let statements: tstl.Statement[] = []; - if (node.flags & ts.NodeFlags.JsonFile) { - this.isModule = false; + return [this.transformSourceFile(sourceFile), this.luaLibFeatureSet]; + } - const statement = node.statements[0]; + public transformSourceFile(sourceFile: ts.SourceFile): tstl.Block { + let statements: tstl.Statement[] = []; + if (sourceFile.flags & ts.NodeFlags.JsonFile) { + const statement = sourceFile.statements[0]; if (!statement || !ts.isExpressionStatement(statement)) { - throw TSTLErrors.InvalidJsonFileContent(node); + throw TSTLErrors.InvalidJsonFileContent(sourceFile); } statements.push(tstl.createReturnStatement([this.transformExpression(statement.expression)])); } else { this.pushScope(ScopeType.File); - - this.isModule = tsHelper.isFileModule(node); - statements = this.performHoisting(this.transformStatements(node.statements)); - + statements = this.performHoisting(this.transformStatements(sourceFile.statements)); this.popScope(); if (this.isModule) { @@ -149,7 +145,7 @@ export class LuaTransformer { } } - return [tstl.createBlock(statements, node), this.luaLibFeatureSet]; + return tstl.createBlock(statements, sourceFile); } public transformStatement(node: ts.Statement): StatementVisitResult { @@ -484,10 +480,6 @@ export class LuaTransformer { expression = this.transformExternalModuleReference(declaration.moduleReference); } else { - if (this.currentSourceFile === undefined) { - throw TSTLErrors.MissingSourceFile(); - } - const shouldEmit = this.resolver.isReferencedAliasDeclaration(declaration) || (!ts.isExternalModule(this.currentSourceFile) && @@ -4974,14 +4966,11 @@ export class LuaTransformer { } protected isSymbolExported(symbol: ts.Symbol): boolean { - if (tsHelper.getExportedSymbolDeclaration(symbol) !== undefined) { - return true; - } else if (this.currentSourceFile) { + return ( + tsHelper.getExportedSymbolDeclaration(symbol) !== undefined || // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') - return this.isSymbolExportedFromScope(symbol, this.currentSourceFile); - } else { - return false; - } + this.isSymbolExportedFromScope(symbol, this.currentSourceFile) + ); } protected isSymbolExportedFromScope(symbol: ts.Symbol, scope: ts.SourceFile | ts.ModuleDeclaration): boolean { @@ -5120,10 +5109,6 @@ export class LuaTransformer { return path.resolve(this.options.baseUrl, relativePath); } - if (this.currentSourceFile === undefined) { - throw TSTLErrors.MissingSourceFile(); - } - return path.resolve(path.dirname(this.currentSourceFile.fileName), relativePath); } @@ -5194,7 +5179,8 @@ export class LuaTransformer { let isFirstDeclaration = true; // var can have multiple declarations for the same variable :/ if (tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.parent) { isLetOrConst = (tsOriginal.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0; - isFirstDeclaration = isLetOrConst || tsHelper.isFirstDeclaration(tsOriginal, this.checker); + isFirstDeclaration = + isLetOrConst || tsHelper.isFirstDeclaration(tsOriginal, this.checker, this.currentSourceFile); } if ((this.isModule || this.currentNamespace || insideFunction || isLetOrConst) && isFirstDeclaration) { // local @@ -5560,10 +5546,6 @@ export class LuaTransformer { } if (scope.functionDefinitions) { - if (this.currentSourceFile === undefined) { - throw TSTLErrors.MissingSourceFile(); - } - for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { if (functionDefinition.definition === undefined) { throw TSTLErrors.UndefinedFunctionDefinition(functionSymbolId); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index b587f99e9..b50858be5 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -731,14 +731,12 @@ export function isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { return false; } -export function getFirstDeclaration(symbol: ts.Symbol, sourceFile?: ts.SourceFile): ts.Declaration | undefined { +export function getFirstDeclaration(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { let declarations = symbol.getDeclarations(); if (!declarations) { return undefined; } - if (sourceFile) { - declarations = declarations.filter(d => findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); - } + declarations = declarations.filter(d => findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; } @@ -751,12 +749,17 @@ export function getRawLiteral(node: ts.LiteralLikeNode): string { return text; } -export function isFirstDeclaration(node: ts.VariableDeclaration, checker: ts.TypeChecker): boolean { +export function isFirstDeclaration( + node: ts.VariableDeclaration, + checker: ts.TypeChecker, + sourceFile: ts.SourceFile +): boolean { const symbol = checker.getSymbolAtLocation(node.name); if (!symbol) { return false; } - const firstDeclaration = getFirstDeclaration(symbol); + + const firstDeclaration = getFirstDeclaration(symbol, sourceFile); return firstDeclaration === node; } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index a00d6faeb..cc351f2b7 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -90,8 +90,6 @@ export const MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => export const MissingMetaExtension = (node: ts.Node) => new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); -export const MissingSourceFile = () => new Error("Expected transformer.sourceFile to be set, but it isn't."); - export const UndefinedFunctionDefinition = (functionSymbolId: number) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); diff --git a/src/Transpile.ts b/src/Transpile.ts index b0d0d4c0a..b0a83d3e7 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -82,7 +82,7 @@ export function transpile({ const processSourceFile = (sourceFile: ts.SourceFile) => { try { - const [luaAst, lualibFeatureSet] = transformer.transformSourceFile(sourceFile); + const [luaAst, lualibFeatureSet] = transformer.transform(sourceFile); if (!options.noEmit && !options.emitDeclarationOnly) { const [lua, sourceMap] = printer.print(luaAst, lualibFeatureSet, sourceFile.fileName); updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap }); From 8626036e736adf6cdddbecb8664595521f22cb51 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 10 Jul 2019 12:45:33 +0500 Subject: [PATCH 131/764] Small improvements (#656) * Remove duplication in decorator name finding * Make TableExpression.fields not optional * Remove unsound cast * Remove use of escapedText and __String * Remove getIdentifierText * Remove function assignment validation in type assertion * Make LuaLib.loadFeatures a regular function * Remove TODOs for old TS upgrades * Use globalThis instead of _G * Remove TS prefix from 4-underscore-prefixed identifiers * Revert "Remove function assignment validation in type assertion" This reverts commit f17da36e6c32aded58fc1f95ce8ee489f09bc078. * Add line break before constructor * Replace __TSTL_ with 4 underscores * Remove outdated `Building & Tests` group from readme --- README.md | 10 - build_lualib.ts | 8 +- src/Decorator.ts | 39 +--- src/LuaAST.ts | 10 +- src/LuaLib.ts | 44 ++-- src/LuaPrinter.ts | 18 +- src/LuaTransformer.ts | 216 ++++++++---------- src/TSHelper.ts | 2 +- src/TSTransformers.ts | 15 +- src/Transpile.ts | 2 - src/lualib/SourceMapTraceBack.ts | 15 +- src/lualib/declarations/global.d.ts | 10 +- .../__snapshots__/transformation.spec.ts.snap | 70 +++--- 13 files changed, 189 insertions(+), 270 deletions(-) diff --git a/README.md b/README.md index 024e3ca3e..5fff008ac 100644 --- a/README.md +++ b/README.md @@ -65,16 +65,6 @@ The real power of this transpiler is usage together with good declarations for t - [Defold Game Engine Scripting](https://github.com/dasannikov/DefoldTypeScript/blob/master/defold.d.ts) - [LÖVE 2D Game Development](https://github.com/hazzard993/love-typescript-definitions) -## Building & Tests - -`npm run build` to build the project. - -`npm run test` to run tests. - -`npm run test-threaded` runs test in parallel, faster but less detailed output. - -`npm run coverage` or `npm run coverage-html` to generate a coverage report. - ## Sublime Text integration This compiler works great in combination with the [Sublime Text Typescript plugin](https://github.com/Microsoft/TypeScript-Sublime-Plugin) (available through the package manager as `TypeScript`). diff --git a/build_lualib.ts b/build_lualib.ts index 330a3ef04..1f6897f0d 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -2,7 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; import * as tstl from "./src"; -import { LuaLib } from "./src/LuaLib"; +import { loadLuaLibFeatures } from "./src/LuaLib"; const configFileName = path.resolve(__dirname, "src/lualib/tsconfig.json"); const { emitResult, diagnostics } = tstl.transpileProject(configFileName); @@ -16,8 +16,4 @@ if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } -const emitHost = { - readFile: (path: string) => fs.readFileSync(path, "utf-8"), - writeFile: fs.writeFileSync, -}; -fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature), emitHost)); +fs.writeFileSync(bundlePath, loadLuaLibFeatures(Object.values(tstl.LuaLibFeature), ts.sys)); diff --git a/src/Decorator.ts b/src/Decorator.ts index 799f792c4..107676b0d 100644 --- a/src/Decorator.ts +++ b/src/Decorator.ts @@ -4,51 +4,20 @@ export class Decorator { } public static getDecoratorKind(decoratorKindString: string): DecoratorKind | undefined { - switch (decoratorKindString.toLowerCase()) { - case "extension": - return DecoratorKind.Extension; - case "metaextension": - return DecoratorKind.MetaExtension; - case "customconstructor": - return DecoratorKind.CustomConstructor; - case "compilemembersonly": - return DecoratorKind.CompileMembersOnly; - case "noresolution": - return DecoratorKind.NoResolution; - case "pureabstract": - return DecoratorKind.PureAbstract; - case "phantom": - return DecoratorKind.Phantom; - case "tuplereturn": - return DecoratorKind.TupleReturn; - case "luaiterator": - return DecoratorKind.LuaIterator; - case "luatable": - return DecoratorKind.LuaTable; - case "noself": - return DecoratorKind.NoSelf; - case "noselfinfile": - return DecoratorKind.NoSelfInFile; - case "vararg": - return DecoratorKind.Vararg; - case "forrange": - return DecoratorKind.ForRange; - } - - return undefined; + return Object.values(DecoratorKind).find( + decoratorKind => decoratorKind.toLowerCase() === decoratorKindString.toLowerCase() + ); } public kind: DecoratorKind; - public args: string[]; - constructor(name: string, args: string[]) { + constructor(name: string, public args: string[]) { const kind = Decorator.getDecoratorKind(name); if (kind === undefined) { throw new Error(`Failed to parse decorator '${name}'`); } this.kind = kind; - this.args = args; } } diff --git a/src/LuaAST.ts b/src/LuaAST.ts index b8402d808..ee6c8002b 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -614,7 +614,7 @@ export function isStringLiteral(node: Node): node is StringLiteral { return node.kind === SyntaxKind.StringLiteral; } -export function createStringLiteral(value: string | ts.__String, tsOriginal?: ts.Node, parent?: Node): StringLiteral { +export function createStringLiteral(value: string, tsOriginal?: ts.Node, parent?: Node): StringLiteral { const expression = createNode(SyntaxKind.StringLiteral, tsOriginal, parent) as StringLiteral; expression.value = value as string; return expression; @@ -687,7 +687,7 @@ export function createTableFieldExpression( export interface TableExpression extends Expression { kind: SyntaxKind.TableExpression; - fields?: TableFieldExpression[]; + fields: TableFieldExpression[]; } export function isTableExpression(node: Node): node is TableExpression { @@ -695,7 +695,7 @@ export function isTableExpression(node: Node): node is TableExpression { } export function createTableExpression( - fields?: TableFieldExpression[], + fields: TableFieldExpression[] = [], tsOriginal?: ts.Node, parent?: Node ): TableExpression { @@ -839,14 +839,14 @@ export function isIdentifier(node: Node): node is Identifier { } export function createIdentifier( - text: string | ts.__String, + text: string, tsOriginal?: ts.Node, symbolId?: SymbolId, originalName?: string, parent?: Node ): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; - expression.text = text as string; + expression.text = text; expression.symbolId = symbolId; expression.originalName = originalName; return expression; diff --git a/src/LuaLib.ts b/src/LuaLib.ts index d611a28bb..aa7c3e432 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -72,32 +72,32 @@ const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { SymbolRegistry: [LuaLibFeature.Symbol], }; -export class LuaLib { - public static loadFeatures(features: Iterable, emitHost: EmitHost): string { - let result = ""; +export function loadLuaLibFeatures(features: Iterable, emitHost: EmitHost): string { + let result = ""; - const loadedFeatures = new Set(); + const loadedFeatures = new Set(); - function load(feature: LuaLibFeature): void { - if (!loadedFeatures.has(feature)) { - loadedFeatures.add(feature); - const dependencies = luaLibDependencies[feature]; - if (dependencies) { - dependencies.forEach(load); - } - const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - const luaLibFeature = emitHost.readFile(featureFile); - if (luaLibFeature !== undefined) { - result += luaLibFeature.toString() + "\n"; - } else { - throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`); - } - } + function load(feature: LuaLibFeature): void { + if (loadedFeatures.has(feature)) return; + loadedFeatures.add(feature); + + const dependencies = luaLibDependencies[feature]; + if (dependencies) { + dependencies.forEach(load); } - for (const feature of features) { - load(feature); + const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); + const luaLibFeature = emitHost.readFile(featureFile); + if (luaLibFeature !== undefined) { + result += luaLibFeature + "\n"; + } else { + throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`); } - return result; } + + for (const feature of features) { + load(feature); + } + + return result; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 3a12194bd..48ea0e752 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -3,9 +3,9 @@ import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import * as tstl from "./LuaAST"; import { luaKeywords } from "./LuaKeywords"; -import { LuaLib, LuaLibFeature } from "./LuaLib"; -import * as tsHelper from "./TSHelper"; +import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { EmitHost } from "./Transpile"; +import * as tsHelper from "./TSHelper"; type SourceChunk = string | SourceNode; @@ -124,7 +124,7 @@ export class LuaPrinter { // Inline lualib features else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { header += "-- Lua Library inline imports\n"; - header += LuaLib.loadFeatures(luaLibFeatures, this.emitHost); + header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); } } @@ -563,17 +563,7 @@ export class LuaPrinter { } public printTableExpression(expression: tstl.TableExpression): SourceNode { - const chunks: SourceChunk[] = []; - - chunks.push("{"); - - if (expression.fields) { - chunks.push(...this.printExpressionList(expression.fields)); - } - - chunks.push("}"); - - return this.createSourceNode(expression, chunks); + return this.createSourceNode(expression, ["{", ...this.printExpressionList(expression.fields), "}"]); } public printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 81a435f3c..5eee26168 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -315,7 +315,7 @@ export class LuaTransformer { } const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); - const tempModuleIdentifier = tstl.createIdentifier("__TSTL_export"); + const tempModuleIdentifier = tstl.createIdentifier("____export"); const declaration = tstl.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); @@ -400,7 +400,7 @@ export class LuaTransformer { return undefined; } - const tstlIdentifier = (name: string) => "__TSTL_" + tsHelper.fixInvalidLuaIdentifier(name); + const tstlIdentifier = (name: string) => "____" + tsHelper.fixInvalidLuaIdentifier(name); const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename(importPath))); const requireStatement = tstl.createVariableDeclarationStatement( tstl.createIdentifier(tstlIdentifier(path.basename(importPath))), @@ -509,7 +509,7 @@ export class LuaTransformer { } public transformQualifiedName(qualifiedName: ts.QualifiedName): ExpressionVisitResult { - const right = tstl.createStringLiteral(this.getIdentifierText(qualifiedName.right), qualifiedName.right); + const right = tstl.createStringLiteral(qualifiedName.right.text, qualifiedName.right); const left = this.transformEntityName(qualifiedName.left); return tstl.createTableIndexExpression(left, right, qualifiedName); @@ -777,7 +777,7 @@ export class LuaTransformer { const result: tstl.Statement[] = []; // [____exports.]className = {} - const classTable: tstl.Expression = tstl.createTableExpression([]); + const classTable: tstl.Expression = tstl.createTableExpression(); const classVar = this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); result.push(...classVar); @@ -879,7 +879,7 @@ export class LuaTransformer { tstl.createStringLiteral("__index") ); if (tsHelper.hasGetAccessorInClassOrAncestor(statement, false, this.checker)) { - // localClassName.prototype.__index = __TS_Index(localClassName.prototype) + // localClassName.prototype.__index = __TS__Index(localClassName.prototype) const assignClassPrototypeIndex = tstl.createAssignmentStatement( classPrototypeIndex, this.transformLuaLibFunction(LuaLibFeature.Index, undefined, createClassPrototype()), @@ -911,7 +911,7 @@ export class LuaTransformer { } if (tsHelper.hasSetAccessorInClassOrAncestor(statement, false, this.checker)) { - // localClassName.prototype.__newindex = __TS_NewIndex(localClassName.prototype) + // localClassName.prototype.__newindex = __TS__NewIndex(localClassName.prototype) const classPrototypeNewIndex = tstl.createTableIndexExpression( createClassPrototype(), tstl.createStringLiteral("__newindex") @@ -1380,11 +1380,11 @@ export class LuaTransformer { continue; } - // Binding patterns become ____TS_bindingPattern0, ____TS_bindingPattern1, etc as function parameters + // Binding patterns become ____bindingPattern0, ____bindingPattern1, etc as function parameters // See transformFunctionBody for how these values are destructured const paramName = ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) - ? tstl.createIdentifier(`____TS_bindingPattern${identifierIndex++}`) + ? tstl.createIdentifier(`____bindingPattern${identifierIndex++}`) : this.transformIdentifier(param.name as ts.Identifier); // This parameter is a spread parameter (...param) @@ -1433,7 +1433,7 @@ export class LuaTransformer { let bindPatternIndex = 0; for (const declaration of parameters) { if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) { - const identifier = tstl.createIdentifier(`____TS_bindingPattern${bindPatternIndex++}`); + const identifier = tstl.createIdentifier(`____bindingPattern${bindPatternIndex++}`); if (declaration.initializer !== undefined) { // Default binding parameter headerStatements.push( @@ -2328,14 +2328,14 @@ export class LuaTransformer { // Declaration of new variable const variables = statement.initializer.declarations[0].name; if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { - valueVariable = tstl.createIdentifier("____TS_values"); + valueVariable = tstl.createIdentifier("____values"); block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); } else { valueVariable = this.transformIdentifier(variables); } } else { // Assignment to existing variable - valueVariable = tstl.createIdentifier("____TS_value"); + valueVariable = tstl.createIdentifier("____value"); block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); } @@ -2379,12 +2379,10 @@ export class LuaTransformer { } } else { // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____TS_value0 in ${iterable} do - // ${initializer} = ____TS_value0 + // for ____value0 in ${iterable} do + // ${initializer} = ____value0 if (ts.isArrayLiteralExpression(statement.initializer)) { - const tmps = statement.initializer.elements.map((_, i) => - tstl.createIdentifier(`____TS_value${i}`) - ); + const tmps = statement.initializer.elements.map((_, i) => tstl.createIdentifier(`____value${i}`)); const assign = tstl.createAssignmentStatement( statement.initializer.elements.map( e => this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression @@ -2413,9 +2411,9 @@ export class LuaTransformer { ); } else { // Destructuring or variable NOT declared in for loop - // for ____TS_value in ${iterator} do - // local ${initializer} = unpack(____TS_value) - const valueVariable = tstl.createIdentifier("____TS_value"); + // for ____value in ${iterator} do + // local ${initializer} = unpack(____value) + const valueVariable = tstl.createIdentifier("____value"); const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); block.statements.splice(0, 0, initializer); return tstl.createForInStatement(block, [valueVariable], [luaIterator]); @@ -2438,9 +2436,9 @@ export class LuaTransformer { ); } else { // Destructuring or variable NOT declared in for loop - // for ____TS_value in __TS__iterator(${iterator}) do - // local ${initializer} = ____TS_value - const valueVariable = tstl.createIdentifier("____TS_value"); + // for ____value in __TS__iterator(${iterator}) do + // local ${initializer} = ____value + const valueVariable = tstl.createIdentifier("____value"); const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); block.statements.splice(0, 0, initializer); return tstl.createForInStatement( @@ -2548,7 +2546,7 @@ export class LuaTransformer { if (scope === undefined) { throw TSTLErrors.UndefinedScope(); } - const switchName = `____TS_switch${scope.id}`; + const switchName = `____switch${scope.id}`; const expression = this.transformExpression(statement.expression); const switchVariable = tstl.createIdentifier(switchName); @@ -2604,7 +2602,7 @@ export class LuaTransformer { } if (breakableScope.type === ScopeType.Switch) { - return tstl.createGotoStatement(`____TS_switch${breakableScope.id}_end`); + return tstl.createGotoStatement(`____switch${breakableScope.id}_end`); } else { return tstl.createBreakStatement(breakStatement); } @@ -2620,8 +2618,8 @@ export class LuaTransformer { public transformTryStatement(statement: ts.TryStatement): StatementVisitResult { const [tryBlock, tryScope] = this.transformScopeBlock(statement.tryBlock, ScopeType.Try); - const tryResultIdentfier = tstl.createIdentifier("____TS_try"); - const returnValueIdentifier = tstl.createIdentifier("____TS_returnValue"); + const tryResultIdentifier = tstl.createIdentifier("____try"); + const returnValueIdentifier = tstl.createIdentifier("____returnValue"); const result: tstl.Statement[] = []; @@ -2635,18 +2633,18 @@ export class LuaTransformer { // try with catch let [catchBlock, catchScope] = this.transformScopeBlock(statement.catchClause.block, ScopeType.Catch); if (statement.catchClause.variableDeclaration) { - // Replace ____TS_returned with catch variable + // Replace ____returned with catch variable returnedIdentifier = this.transformIdentifier(statement.catchClause.variableDeclaration .name as ts.Identifier); } else if (tryScope.functionReturned || catchScope.functionReturned) { - returnedIdentifier = tstl.createIdentifier("____TS_returned"); + returnedIdentifier = tstl.createIdentifier("____returned"); } - const tryReturnIdentifiers = [tryResultIdentfier]; // ____TS_try + const tryReturnIdentifiers = [tryResultIdentifier]; // ____try if (returnedIdentifier) { - tryReturnIdentifiers.push(returnedIdentifier); // ____TS_returned or catch variable + tryReturnIdentifiers.push(returnedIdentifier); // ____returned or catch variable if (tryScope.functionReturned || catchScope.functionReturned) { - tryReturnIdentifiers.push(returnValueIdentifier); // ____TS_returnValue + tryReturnIdentifiers.push(returnValueIdentifier); // ____returnValue returnCondition = tstl.cloneIdentifier(returnedIdentifier); } } @@ -2664,19 +2662,19 @@ export class LuaTransformer { catchBlock = tstl.createBlock([catchAssign]); } const notTryCondition = tstl.createUnaryExpression( - tstl.createParenthesizedExpression(tryResultIdentfier), + tstl.createParenthesizedExpression(tryResultIdentifier), tstl.SyntaxKind.NotOperator ); result.push(tstl.createIfStatement(notTryCondition, catchBlock)); } else if (tryScope.functionReturned) { // try with return, but no catch - returnedIdentifier = tstl.createIdentifier("____TS_returned"); - const returnedVariables = [tryResultIdentfier, returnedIdentifier, returnValueIdentifier]; + returnedIdentifier = tstl.createIdentifier("____returned"); + const returnedVariables = [tryResultIdentifier, returnedIdentifier, returnValueIdentifier]; result.push(tstl.createVariableDeclarationStatement(returnedVariables, tryCall)); - // change return condition from '____TS_returned' to '____TS_try and ____TS_returned' + // change return condition from '____returned' to '____try and ____returned' returnCondition = tstl.createBinaryExpression( - tstl.cloneIdentifier(tryResultIdentfier), + tstl.cloneIdentifier(tryResultIdentifier), returnedIdentifier, tstl.SyntaxKind.AndOperator ); @@ -2691,9 +2689,9 @@ export class LuaTransformer { if (returnCondition && returnedIdentifier) { // With catch clause: - // if ____TS_returned then return ____TS_returnValue end + // if ____returned then return ____returnValue end // No catch clause: - // if ____TS_try and ____TS_returned then return ____TS_returnValue end + // if ____try and ____returned then return ____returnValue end const returnValues: tstl.Expression[] = []; const parentTryCatch = this.findScope(ScopeType.Function | ScopeType.Try | ScopeType.Catch); if (parentTryCatch && parentTryCatch.type !== ScopeType.Function) { @@ -3017,7 +3015,7 @@ export class LuaTransformer { // Destructuring assignment const left = expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformArrayBindingExpression(e)) + ? expression.left.elements.map(e => this.transformArrayBindingElement(e)) : [tstl.createAnonymousIdentifier(expression.left)]; let right: tstl.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { @@ -3075,7 +3073,7 @@ export class LuaTransformer { } else { right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; } - const tmps = left.map((_, i) => tstl.createIdentifier(`____TS_tmp${i}`)); + const tmps = left.map((_, i) => tstl.createIdentifier(`____tmp${i}`)); const statements: tstl.Statement[] = [ tstl.createVariableDeclarationStatement(tmps, right), tstl.createAssignmentStatement(left as tstl.AssignmentLeftHandSideExpression[], tmps), @@ -3145,28 +3143,28 @@ export class LuaTransformer { ); if (hasEffects && objExpression && indexExpression) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects - // local __TS_obj, __TS_index = ${objExpression}, ${indexExpression}; - const obj = tstl.createIdentifier("____TS_obj"); - const index = tstl.createIdentifier("____TS_index"); + // local __obj, __index = ${objExpression}, ${indexExpression}; + const obj = tstl.createIdentifier("____obj"); + const index = tstl.createIdentifier("____index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( [obj, index], [this.transformExpression(objExpression), this.transformExpression(indexExpression)] ); const accessExpression = tstl.createTableIndexExpression(obj, index); - const tmp = tstl.createIdentifier("____TS_tmp"); + const tmp = tstl.createIdentifier("____tmp"); right = tstl.createParenthesizedExpression(right); let tmpDeclaration: tstl.VariableDeclarationStatement; let assignStatement: tstl.AssignmentStatement; if (isPostfix) { - // local ____TS_tmp = ____TS_obj[____TS_index]; - // ____TS_obj[____TS_index] = ____TS_tmp ${replacementOperator} ${right}; + // local ____tmp = ____obj[____index]; + // ____obj[____index] = ____tmp ${replacementOperator} ${right}; tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, accessExpression); const operatorExpression = this.transformBinaryOperation(tmp, right, replacementOperator, expression); assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); } else { - // local ____TS_tmp = ____TS_obj[____TS_index] ${replacementOperator} ${right}; - // ____TS_obj[____TS_index] = ____TS_tmp; + // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; + // ____obj[____index] = ____tmp; const operatorExpression = this.transformBinaryOperation( accessExpression, right, @@ -3176,7 +3174,7 @@ export class LuaTransformer { tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, operatorExpression); assignStatement = tstl.createAssignmentStatement(accessExpression, tmp); } - // return ____TS_tmp + // return ____tmp return this.createImmediatelyInvokedFunctionExpression( [objAndIndexDeclaration, tmpDeclaration, assignStatement], tmp, @@ -3184,10 +3182,10 @@ export class LuaTransformer { ); } else if (isPostfix) { // Postfix expressions need to cache original value in temp - // local ____TS_tmp = ${left}; - // ${left} = ____TS_tmp ${replacementOperator} ${right}; - // return ____TS_tmp - const tmpIdentifier = tstl.createIdentifier("____TS_tmp"); + // local ____tmp = ${left}; + // ${left} = ____tmp ${replacementOperator} ${right}; + // return ____tmp + const tmpIdentifier = tstl.createIdentifier("____tmp"); const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, left); const operatorExpression = this.transformBinaryOperation( tmpIdentifier, @@ -3203,10 +3201,10 @@ export class LuaTransformer { ); } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation - // local ____TS_tmp = ${left} ${replacementOperator} ${right}; - // ${left} = ____TS_tmp; - // return ____TS_tmp - const tmpIdentifier = tstl.createIdentifier("____TS_tmp"); + // local ____tmp = ${left} ${replacementOperator} ${right}; + // ${left} = ____tmp; + // return ____tmp + const tmpIdentifier = tstl.createIdentifier("____tmp"); const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, expression); const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatement = this.transformAssignment(lhs, tmpIdentifier); @@ -3313,10 +3311,10 @@ export class LuaTransformer { ); if (hasEffects && objExpression && indexExpression) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects - // local __TS_obj, __TS_index = ${objExpression}, ${indexExpression}; - // ____TS_obj[____TS_index] = ____TS_obj[____TS_index] ${replacementOperator} ${right}; - const obj = tstl.createIdentifier("____TS_obj"); - const index = tstl.createIdentifier("____TS_index"); + // local __obj, __index = ${objExpression}, ${indexExpression}; + // ____obj[____index] = ____obj[____index] ${replacementOperator} ${right}; + const obj = tstl.createIdentifier("____obj"); + const index = tstl.createIdentifier("____index"); const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( [obj, index], [this.transformExpression(objExpression), this.transformExpression(indexExpression)] @@ -3870,7 +3868,7 @@ export class LuaTransformer { // if ownerType inherits from an array, use array calls where appropriate if ( tsHelper.isArrayType(ownerType, this.checker, this.program) && - tsHelper.isDefaultArrayCallMethodName(node.expression.name.escapedText as string) + tsHelper.isDefaultArrayCallMethodName(node.expression.name.text) ) { return this.transformArrayCallExpression(node); } @@ -3886,7 +3884,7 @@ export class LuaTransformer { return tstl.createCallExpression(this.transformExpression(node.expression), parameters); } else { // Replace last . with : here - const name = node.expression.name.escapedText; + const name = node.expression.name.text; if (name === "toString") { const toStringIdentifier = tstl.createIdentifier("tostring"); return tstl.createCallExpression( @@ -3983,14 +3981,14 @@ export class LuaTransformer { const context = this.transformExpression(left.expression); if (tsHelper.isExpressionWithEvaluationEffect(left.expression)) { // Inject context parameter - transformedArguments.unshift(tstl.createIdentifier("____TS_self")); + transformedArguments.unshift(tstl.createIdentifier("____self")); // Cache left-side if it has effects - //(function() local ____TS_self = context; return ____TS_self[argument](parameters); end)() + //(function() local ____self = context; return ____self[argument](parameters); end)() const argument = ts.isElementAccessExpression(left) ? this.transformElementAccessArgument(left) : tstl.createStringLiteral(left.name.text); - const selfIdentifier = tstl.createIdentifier("____TS_self"); + const selfIdentifier = tstl.createIdentifier("____self"); const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); const index = tstl.createTableIndexExpression(selfIdentifier, argument); const callExpression = tstl.createCallExpression(index, transformedArguments); @@ -4037,7 +4035,7 @@ export class LuaTransformer { } public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = this.getIdentifierText(expression.name); + const property = expression.name.text; const constEnumValue = this.tryGetConstEnumValue(expression); if (constEnumValue) { @@ -4088,7 +4086,7 @@ export class LuaTransformer { // Transpile a Math._ property protected transformMathExpression(identifier: ts.Identifier): tstl.Expression { - const name = identifier.escapedText as string; + const name = identifier.text; switch (name) { case "PI": const property = tstl.createStringLiteral("pi"); @@ -4114,7 +4112,7 @@ export class LuaTransformer { const expression = node.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); - const expressionName = expression.name.escapedText as string; + const expressionName = expression.name.text; switch (expressionName) { // math.tan(x / y) case "atan2": { @@ -4184,7 +4182,7 @@ export class LuaTransformer { // Transpile access of string properties, only supported properties are allowed protected transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { - switch (node.name.escapedText) { + switch (node.name.text) { case "length": let expression = this.transformExpression(node.expression); if (ts.isTemplateExpression(node.expression)) { @@ -4192,13 +4190,13 @@ export class LuaTransformer { } return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); default: - throw TSTLErrors.UnsupportedProperty("string", node.name.escapedText as string, node); + throw TSTLErrors.UnsupportedProperty("string", node.name.text, node); } } // Transpile access of array properties, only supported properties are allowed protected transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { - switch (node.name.escapedText) { + switch (node.name.text) { case "length": let expression = this.transformExpression(node.expression); if (tstl.isTableExpression(expression)) { @@ -4211,12 +4209,12 @@ export class LuaTransformer { } protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { - switch (node.name.escapedText) { + switch (node.name.text) { case "length": const propertyAccessExpression = this.transformExpression(node.expression); return tstl.createUnaryExpression(propertyAccessExpression, tstl.SyntaxKind.LengthOperator, node); default: - throw TSTLErrors.UnsupportedProperty("LuaTable", node.name.escapedText as string, node); + throw TSTLErrors.UnsupportedProperty("LuaTable", node.name.text, node); } } @@ -4273,7 +4271,7 @@ export class LuaTransformer { const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); - const expressionName = expression.name.escapedText as string; + const expressionName = expression.name.text; switch (expressionName) { case "replace": return this.transformLuaLibFunction(LuaLibFeature.StringReplace, node, caller, ...params); @@ -4416,7 +4414,7 @@ export class LuaTransformer { // Transpile a String._ property protected transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { - const identifierString = identifier.escapedText as string; + const identifierString = identifier.text; switch (identifierString) { case "fromCharCode": @@ -4437,7 +4435,7 @@ export class LuaTransformer { protected transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; const parameters = this.transformArguments(expression.arguments); - const methodName = method.name.escapedText; + const methodName = method.name.text; switch (methodName) { case "assign": @@ -4457,7 +4455,7 @@ export class LuaTransformer { protected transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { const method = expression.expression as ts.PropertyAccessExpression; - const methodName = method.name.escapedText; + const methodName = method.name.text; const signature = this.checker.getResolvedSignature(expression); switch (methodName) { @@ -4535,7 +4533,7 @@ export class LuaTransformer { const method = expression.expression as ts.PropertyAccessExpression; const signature = this.checker.getResolvedSignature(expression); const parameters = this.transformArguments(expression.arguments, signature); - const methodName = method.name.escapedText; + const methodName = method.name.text; switch (methodName) { case "for": @@ -4553,7 +4551,7 @@ export class LuaTransformer { protected transformNumberCallExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; const parameters = this.transformArguments(expression.arguments); - const methodName = method.name.escapedText; + const methodName = method.name.text; switch (methodName) { case "isNaN": @@ -4569,7 +4567,7 @@ export class LuaTransformer { expression: ts.CallExpression & { expression: ts.PropertyAccessExpression }, isWithinExpressionStatement: boolean ): void { - const methodName = expression.expression.name.escapedText; + const methodName = expression.expression.name.text; if (expression.arguments.some(argument => ts.isSpreadElement(argument))) { throw TSTLErrors.ForbiddenLuaTableUseException("Arguments cannot be spread.", expression); } @@ -4599,9 +4597,9 @@ export class LuaTransformer { expression: { expression: ts.PropertyAccessExpression }; } ): tstl.VariableDeclarationStatement | tstl.AssignmentStatement { - const methodName = node.expression.expression.name.escapedText; + const methodName = node.expression.expression.name.text; const signature = this.checker.getResolvedSignature(node.expression); - const tableName = (node.expression.expression.expression as ts.Identifier).escapedText; + const tableName = (node.expression.expression.expression as ts.Identifier).text; const luaTable = tstl.createIdentifier(tableName); const params = this.transformArguments((node.expression as ts.CallExpression).arguments, signature); @@ -4627,9 +4625,9 @@ export class LuaTransformer { expression: ts.CallExpression & { expression: ts.PropertyAccessExpression } ): tstl.Expression { const method = expression.expression; - const methodName = method.name.escapedText; + const methodName = method.name.text; const signature = this.checker.getResolvedSignature(expression); - const tableName = (method.expression as ts.Identifier).escapedText; + const tableName = (method.expression as ts.Identifier).text; const luaTable = tstl.createIdentifier(tableName); const params = this.transformArguments(expression.arguments, signature); @@ -4646,7 +4644,7 @@ export class LuaTransformer { const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); - const expressionName = expression.name.escapedText; + const expressionName = expression.name.text; switch (expressionName) { case "concat": return this.transformLuaLibFunction(LuaLibFeature.ArrayConcat, node, caller, ...params); @@ -4700,7 +4698,7 @@ export class LuaTransformer { case "flatMap": return this.transformLuaLibFunction(LuaLibFeature.ArrayFlatMap, node, caller, ...params); default: - throw TSTLErrors.UnsupportedProperty("array", expressionName as string, node); + throw TSTLErrors.UnsupportedProperty("array", expressionName, node); } } @@ -4713,7 +4711,7 @@ export class LuaTransformer { const signature = this.checker.getResolvedSignature(node); const params = this.transformArguments(node.arguments, signature); const caller = this.transformExpression(expression.expression); - const expressionName = expression.name.escapedText; + const expressionName = expression.name.text; switch (expressionName) { case "apply": return this.transformLuaLibFunction(LuaLibFeature.FunctionApply, node, caller, ...params); @@ -4722,15 +4720,11 @@ export class LuaTransformer { case "call": return this.transformLuaLibFunction(LuaLibFeature.FunctionCall, node, caller, ...params); default: - throw TSTLErrors.UnsupportedProperty("function", expressionName as string, node); + throw TSTLErrors.UnsupportedProperty("function", expressionName, node); } } - public transformArrayBindingElement(name: ts.ArrayBindingElement): ExpressionVisitResult { - return this.transformArrayBindingExpression(name as ts.Expression); - } - - public transformArrayBindingExpression(name: ts.Expression): ExpressionVisitResult { + public transformArrayBindingElement(name: ts.ArrayBindingElement | ts.Expression): ExpressionVisitResult { if (ts.isOmittedExpression(name)) { return this.transformOmittedExpression(name); } else if (ts.isIdentifier(name)) { @@ -4822,16 +4816,12 @@ export class LuaTransformer { const stringTableLiteral = tstl.createTableExpression( strings.map(partialString => tstl.createTableFieldExpression(tstl.createStringLiteral(partialString))) ); - if (stringTableLiteral.fields) { - const rawStringArray = tstl.createTableExpression( - rawStrings.map(stringLiteral => - tstl.createTableFieldExpression(tstl.createStringLiteral(stringLiteral)) - ) - ); - stringTableLiteral.fields.push( - tstl.createTableFieldExpression(rawStringArray, tstl.createStringLiteral("raw")) - ); - } + const rawStringArray = tstl.createTableExpression( + rawStrings.map(stringLiteral => tstl.createTableFieldExpression(tstl.createStringLiteral(stringLiteral))) + ); + stringTableLiteral.fields.push( + tstl.createTableFieldExpression(rawStringArray, tstl.createStringLiteral("raw")) + ); // Evaluate if there is a self parameter to be used. const signature = this.checker.getResolvedSignature(expression); @@ -4884,14 +4874,10 @@ export class LuaTransformer { const value = Number(propertyName.text); return tstl.createNumericLiteral(value, propertyName); } else { - return tstl.createStringLiteral(this.getIdentifierText(propertyName)); + return tstl.createStringLiteral(propertyName.text); } } - protected getIdentifierText(identifier: ts.Identifier): string { - return ts.idText(identifier); - } - public transformIdentifier(identifier: ts.Identifier): tstl.Identifier { if (tsHelper.isForRangeType(identifier, this.checker)) { const callExpression = tsHelper.findFirstNodeAbove(identifier, ts.isCallExpression); @@ -4903,12 +4889,10 @@ export class LuaTransformer { } } - const text = this.hasUnsafeIdentifierName(identifier) - ? this.createSafeName(this.getIdentifierText(identifier)) - : this.getIdentifierText(identifier); + const text = this.hasUnsafeIdentifierName(identifier) ? this.createSafeName(identifier.text) : identifier.text; const symbolId = this.getIdentifierSymbolId(identifier); - return tstl.createIdentifier(text, identifier, symbolId, this.getIdentifierText(identifier)); + return tstl.createIdentifier(text, identifier, symbolId, identifier.text); } protected transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { @@ -4923,7 +4907,7 @@ export class LuaTransformer { return tstl.createNilLiteral(); } - switch (this.getIdentifierText(expression)) { + switch (expression.text) { case "NaN": return tstl.createParenthesizedExpression( tstl.createBinaryExpression( @@ -5344,7 +5328,7 @@ export class LuaTransformer { const leftType = this.checker.getTypeAtLocation(node.left.expression); const decorators = tsHelper.getCustomDecorators(leftType, this.checker); if (decorators.has(DecoratorKind.LuaTable)) { - switch (node.left.name.escapedText as string) { + switch (node.left.name.text) { case "length": throw TSTLErrors.ForbiddenLuaTableUseException( `A LuaTable object's length cannot be re-assigned.`, @@ -5414,7 +5398,7 @@ export class LuaTransformer { ? this.createSafeName(valueSymbol.name) : valueSymbol.name; } else { - const propertyName = this.getIdentifierText(propertyIdentifier); + const propertyName = propertyIdentifier.text; if (luaKeywords.has(propertyName) || !tsHelper.isValidLuaIdentifier(propertyName)) { // Catch ambient declarations of identifiers with bad names throw TSTLErrors.InvalidAmbientIdentifierName(propertyIdentifier); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index b50858be5..a26c89343 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -872,7 +872,7 @@ export function isSimpleExpression(expression: tstl.Expression): boolean { case tstl.SyntaxKind.TableExpression: const tableExpression = expression as tstl.TableExpression; - return !tableExpression.fields || tableExpression.fields.every(e => isSimpleExpression(e)); + return tableExpression.fields.every(e => isSimpleExpression(e)); case tstl.SyntaxKind.TableFieldExpression: const fieldExpression = expression as tstl.TableFieldExpression; diff --git a/src/TSTransformers.ts b/src/TSTransformers.ts index 720fc98cd..81241810c 100644 --- a/src/TSTransformers.ts +++ b/src/TSTransformers.ts @@ -10,17 +10,10 @@ export function getCustomTransformers( customTransformers: ts.CustomTransformers, onSourceFile: (sourceFile: ts.SourceFile) => void ): ts.CustomTransformers { - // TODO: https://github.com/Microsoft/TypeScript/issues/28310 - const forEachSourceFile = (node: ts.SourceFile, callback: (sourceFile: ts.SourceFile) => ts.SourceFile) => - ts.isBundle(node) - ? ((ts.updateBundle(node, node.sourceFiles.map(callback)) as unknown) as ts.SourceFile) - : callback(node); - - const luaTransformer: ts.TransformerFactory = () => node => - forEachSourceFile(node, sourceFile => { - onSourceFile(sourceFile); - return ts.createSourceFile(sourceFile.fileName, "", ts.ScriptTarget.ESNext); - }); + const luaTransformer: ts.TransformerFactory = () => sourceFile => { + onSourceFile(sourceFile); + return ts.createSourceFile(sourceFile.fileName, "", ts.ScriptTarget.ESNext); + }; const transformersFromOptions = loadTransformersFromOptions(program, diagnostics); return { diff --git a/src/Transpile.ts b/src/Transpile.ts index b0a83d3e7..28a6282a9 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -47,8 +47,6 @@ export function transpile({ const diagnostics: ts.Diagnostic[] = []; let transpiledFiles: TranspiledFile[] = []; - // TODO: Included in TS3.5 - type Omit = Pick>; const updateTranspiledFile = (fileName: string, update: Omit) => { const file = transpiledFiles.find(f => f.fileName === fileName); if (file) { diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 4aed661cc..374f52b10 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,16 +1,17 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [line: number]: number }): void { - _G["__TS__sourcemap"] = _G["__TS__sourcemap"] || {}; - _G["__TS__sourcemap"][fileName] = sourceMap; + globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; + globalThis.__TS__sourcemap[fileName] = sourceMap; - if (_G.__TS__originalTraceback === undefined) { - _G.__TS__originalTraceback = debug.traceback; + if (globalThis.__TS__originalTraceback === undefined) { + globalThis.__TS__originalTraceback = debug.traceback; debug.traceback = (thread, message, level) => { - const trace = _G["__TS__originalTraceback"](thread, message, level); + const trace = globalThis.__TS__originalTraceback(thread, message, level); const [result] = string.gsub(trace, "(%S+).lua:(%d+)", (file, line) => { - if (_G["__TS__sourcemap"][file + ".lua"] && _G["__TS__sourcemap"][file + ".lua"][line]) { - return `${file}.ts:${_G["__TS__sourcemap"][file + ".lua"][line]}`; + const fileSourceMap = globalThis.__TS__sourcemap[file + ".lua"]; + if (fileSourceMap && fileSourceMap[line]) { + return `${file}.ts:${fileSourceMap[line]}`; } return `${file}.lua:${line}`; }); diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index b34b857f4..e27b9ecea 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,11 +1,9 @@ /** @noSelfInFile */ -// TODO: TS3.4: typeof globalThis -declare const _G: { - // Required? - __TS__originalTraceback(this: void, thread?: any, message?: string, level?: number): string; - [key: string]: any; -}; +declare var __TS__sourcemap: Record | undefined; +declare var __TS__originalTraceback: + | ((this: void, thread?: any, message?: string, level?: number) => string) + | undefined; declare function tonumber(value: any, base?: number): number | undefined; declare function type( diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index dfc23372a..c77a614ca 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -198,21 +198,21 @@ local xyz = 4 ____exports.xyz = xyz ____exports.uwv = xyz do - local __TSTL_export = require(\\"xyz\\") - for ____exportKey, ____exportValue in pairs(__TSTL_export) do + local ____export = require(\\"xyz\\") + for ____exportKey, ____exportValue in pairs(____export) do ____exports[____exportKey] = ____exportValue end end do - local __TSTL_xyz = require(\\"xyz\\") - local abc = __TSTL_xyz.abc - local def = __TSTL_xyz.def + local ____xyz = require(\\"xyz\\") + local abc = ____xyz.abc + local def = ____xyz.def ____exports.abc = abc ____exports.def = def end do - local __TSTL_xyz = require(\\"xyz\\") - local def = __TSTL_xyz.abc + local ____xyz = require(\\"xyz\\") + local def = ____xyz.abc ____exports.def = def end return ____exports" @@ -371,22 +371,22 @@ local ____ = Test" `; exports[`Transformation (modulesImportNamed) 1`] = ` -"local __TSTL_test = require(\\"test\\") -local TestClass = __TSTL_test.TestClass +"local ____test = require(\\"test\\") +local TestClass = ____test.TestClass local ____ = TestClass" `; exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` -"local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") -local TestClass1 = __TSTL_kebab_2Dmodule.TestClass1 -local __TSTL_dollar_24module = require(\\"dollar$module\\") -local TestClass2 = __TSTL_dollar_24module.TestClass2 -local __TSTL_singlequote_27module = require(\\"singlequote'module\\") -local TestClass3 = __TSTL_singlequote_27module.TestClass3 -local __TSTL_hash_23module = require(\\"hash#module\\") -local TestClass4 = __TSTL_hash_23module.TestClass4 -local __TSTL_space_20module = require(\\"space module\\") -local TestClass5 = __TSTL_space_20module.TestClass5 +"local ____kebab_2Dmodule = require(\\"kebab-module\\") +local TestClass1 = ____kebab_2Dmodule.TestClass1 +local ____dollar_24module = require(\\"dollar$module\\") +local TestClass2 = ____dollar_24module.TestClass2 +local ____singlequote_27module = require(\\"singlequote'module\\") +local TestClass3 = ____singlequote_27module.TestClass3 +local ____hash_23module = require(\\"hash#module\\") +local TestClass4 = ____hash_23module.TestClass4 +local ____space_20module = require(\\"space module\\") +local TestClass5 = ____space_20module.TestClass5 local ____ = TestClass1 local ____ = TestClass2 local ____ = TestClass3 @@ -395,22 +395,22 @@ local ____ = TestClass5" `; exports[`Transformation (modulesImportRenamed) 1`] = ` -"local __TSTL_test = require(\\"test\\") -local RenamedClass = __TSTL_test.TestClass +"local ____test = require(\\"test\\") +local RenamedClass = ____test.TestClass local ____ = RenamedClass" `; exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` -"local __TSTL_kebab_2Dmodule = require(\\"kebab-module\\") -local RenamedClass1 = __TSTL_kebab_2Dmodule.TestClass -local __TSTL_dollar_24module = require(\\"dollar$module\\") -local RenamedClass2 = __TSTL_dollar_24module.TestClass -local __TSTL_singlequote_27module = require(\\"singlequote'module\\") -local RenamedClass3 = __TSTL_singlequote_27module.TestClass -local __TSTL_hash_23module = require(\\"hash#module\\") -local RenamedClass4 = __TSTL_hash_23module.TestClass -local __TSTL_space_20module = require(\\"space module\\") -local RenamedClass5 = __TSTL_space_20module.TestClass +"local ____kebab_2Dmodule = require(\\"kebab-module\\") +local RenamedClass1 = ____kebab_2Dmodule.TestClass +local ____dollar_24module = require(\\"dollar$module\\") +local RenamedClass2 = ____dollar_24module.TestClass +local ____singlequote_27module = require(\\"singlequote'module\\") +local RenamedClass3 = ____singlequote_27module.TestClass +local ____hash_23module = require(\\"hash#module\\") +local RenamedClass4 = ____hash_23module.TestClass +local ____space_20module = require(\\"space module\\") +local RenamedClass5 = ____space_20module.TestClass local ____ = RenamedClass1 local ____ = RenamedClass2 local ____ = RenamedClass3 @@ -562,12 +562,12 @@ f = function(____, x) return ({x = x}) end" exports[`Transformation (tryCatch) 1`] = ` "do - local ____TS_try, er = pcall( + local ____try, er = pcall( function() local a = 42 end ) - if not ____TS_try then + if not ____try then local b = \\"fail\\" end end" @@ -575,12 +575,12 @@ end" exports[`Transformation (tryCatchFinally) 1`] = ` "do - local ____TS_try, er = pcall( + local ____try, er = pcall( function() local a = 42 end ) - if not ____TS_try then + if not ____try then local b = \\"fail\\" end do From 60582246138e4a46de1d0c5735e4801645f2a14c Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Wed, 10 Jul 2019 16:03:00 -0600 Subject: [PATCH 132/764] Fixed empty destructuring declarations/assignments in for...of loops (#658) * Fixed empty destructuring declarations/assignments in for...of loops fixes #607 * consolidated tests * removing erroneous tab * re-ran prettier --- src/LuaTransformer.ts | 72 ++++++++++++++++++++++++++------------- test/unit/loops.spec.ts | 75 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 23 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 5eee26168..7c7160f67 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2260,11 +2260,18 @@ export class LuaTransformer { return tstl.createDoStatement(result, statement); } - protected transformForOfInitializer(initializer: ts.ForInitializer, expression: tstl.Expression): tstl.Statement { + protected transformForOfInitializer( + initializer: ts.ForInitializer, + expression: tstl.Expression + ): tstl.Statement | undefined { if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { + if (initializer.declarations[0].name.elements.length === 0) { + // Ignore empty destructuring assignment + return undefined; + } expression = this.createUnpackCall(expression, initializer); } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); @@ -2284,10 +2291,15 @@ export class LuaTransformer { // Assignment to existing variable let variables: tstl.AssignmentLeftHandSideExpression | tstl.AssignmentLeftHandSideExpression[]; if (ts.isArrayLiteralExpression(initializer)) { - expression = this.createUnpackCall(expression, initializer); - variables = initializer.elements.map(e => - this.transformExpression(e) - ) as tstl.AssignmentLeftHandSideExpression[]; + if (initializer.elements.length > 0) { + expression = this.createUnpackCall(expression, initializer); + variables = initializer.elements.map(e => + this.transformExpression(e) + ) as tstl.AssignmentLeftHandSideExpression[]; + } else { + // Ignore empty destructring assignment + return undefined; + } } else if (ts.isObjectLiteralExpression(initializer)) { throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); } else { @@ -2329,14 +2341,20 @@ export class LuaTransformer { const variables = statement.initializer.declarations[0].name; if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { valueVariable = tstl.createIdentifier("____values"); - block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); + const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); + if (initializer) { + block.statements.unshift(initializer); + } } else { valueVariable = this.transformIdentifier(variables); } } else { // Assignment to existing variable valueVariable = tstl.createIdentifier("____value"); - block.statements.unshift(this.transformForOfInitializer(statement.initializer, valueVariable)); + const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); + if (initializer) { + block.statements.unshift(initializer); + } } const ipairsCall = tstl.createCallExpression(tstl.createIdentifier("ipairs"), [ @@ -2365,14 +2383,14 @@ export class LuaTransformer { // for ${initializer} in ${iterable} do const initializerVariable = statement.initializer.declarations[0].name; if (ts.isArrayBindingPattern(initializerVariable)) { - return tstl.createForInStatement( - block, - this.filterUndefinedAndCast( - initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), - tstl.isIdentifier - ), - [luaIterator] + const identifiers = this.filterUndefinedAndCast( + initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), + tstl.isIdentifier ); + if (identifiers.length === 0) { + identifiers.push(tstl.createAnonymousIdentifier()); + } + return tstl.createForInStatement(block, identifiers, [luaIterator]); } else { // Single variable is not allowed throw TSTLErrors.UnsupportedNonDestructuringLuaIterator(statement.initializer); @@ -2383,13 +2401,17 @@ export class LuaTransformer { // ${initializer} = ____value0 if (ts.isArrayLiteralExpression(statement.initializer)) { const tmps = statement.initializer.elements.map((_, i) => tstl.createIdentifier(`____value${i}`)); - const assign = tstl.createAssignmentStatement( - statement.initializer.elements.map( - e => this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression - ), - tmps - ); - block.statements.splice(0, 0, assign); + if (tmps.length > 0) { + const assign = tstl.createAssignmentStatement( + statement.initializer.elements.map( + e => this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression + ), + tmps + ); + block.statements.splice(0, 0, assign); + } else { + tmps.push(tstl.createAnonymousIdentifier()); + } return tstl.createForInStatement(block, tmps, [luaIterator]); } else { // Single variable is not allowed @@ -2415,7 +2437,9 @@ export class LuaTransformer { // local ${initializer} = unpack(____value) const valueVariable = tstl.createIdentifier("____value"); const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - block.statements.splice(0, 0, initializer); + if (initializer) { + block.statements.splice(0, 0, initializer); + } return tstl.createForInStatement(block, [valueVariable], [luaIterator]); } } @@ -2440,7 +2464,9 @@ export class LuaTransformer { // local ${initializer} = ____value const valueVariable = tstl.createIdentifier("____value"); const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - block.statements.splice(0, 0, initializer); + if (initializer) { + block.statements.splice(0, 0, initializer); + } return tstl.createForInStatement( block, [valueVariable], diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 79d19b2f5..38b16a7e0 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -754,6 +754,81 @@ test("forof forwarded lua iterator with tupleReturn", () => { expect(result).toBe("0a1b2c"); }); +describe("for...of empty destructuring", () => { + const declareTests = (destructuringPrefix: string) => { + test("array", () => { + const code = ` + const arr = [["a"], ["b"], ["c"]]; + let i = 0; + for (${destructuringPrefix}[] of arr) { + ++i; + } + return i; + `; + expect(util.transpileAndExecute(code)).toBe(3); + }); + + test("iterable", () => { + const code = ` + const iter: Iterable = [["a"], ["b"], ["c"]]; + let i = 0; + for (${destructuringPrefix}[] of iter) { + ++i; + } + return i; + `; + expect(util.transpileAndExecute(code)).toBe(3); + }); + + test("luaIterator", () => { + const code = ` + const arr = [["a"], ["b"], ["c"]]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let it = 0; + return (() => arr[it++]) as any; + } + let i = 0; + for (${destructuringPrefix}[] of luaIter()) { + ++i; + } + return i; + `; + expect(util.transpileAndExecute(code)).toBe(3); + }); + + test("luaIterator+tupleReturn", () => { + const code = ` + const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let it = 0; + /** @tupleReturn */ + function iter() { + const e = arr[it++]; + if (e) { + return e; + } + } + return iter as any; + } + let i = 0; + for (${destructuringPrefix}[] of luaIter()) { + ++i; + } + return i; + `; + expect(util.transpileAndExecute(code)).toBe(3); + }); + }; + + describe("declaration", () => declareTests("const ")); + describe("assignment", () => declareTests("")); +}); + test.each([ "while (a < b) { i++; continue; }", "do { i++; continue; } while (a < b)", From 1850e6c75a96e44920ad7313c610be8f7dbb85f4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 13 Jul 2019 10:12:41 -0600 Subject: [PATCH 133/764] Fix for repeat...until scoping (#661) fixes #657 Also added a small optimization to prevent double-negation in until-condition --- src/LuaTransformer.ts | 17 +++++---- .../__snapshots__/transformation.spec.ts.snap | 4 ++- test/unit/loops.spec.ts | 36 +++++++++++++++++++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 7c7160f67..1e0686e41 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2216,14 +2216,17 @@ export class LuaTransformer { } public transformDoStatement(statement: ts.DoStatement): StatementVisitResult { - return tstl.createRepeatStatement( - tstl.createBlock(this.transformLoopBody(statement)), - tstl.createUnaryExpression( - tstl.createParenthesizedExpression(this.transformExpression(statement.expression)), + const body = tstl.createDoStatement(this.transformLoopBody(statement)); + let condition = this.transformExpression(statement.expression); + if (tstl.isUnaryExpression(condition) && condition.operator === tstl.SyntaxKind.NotOperator) { + condition = condition.operand; + } else { + condition = tstl.createUnaryExpression( + tstl.createParenthesizedExpression(condition), tstl.SyntaxKind.NotOperator - ), - statement - ); + ); + } + return tstl.createRepeatStatement(tstl.createBlock([body]), condition, statement); } public transformForStatement(statement: ts.ForStatement): StatementVisitResult { diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index c77a614ca..7e5ae77f0 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -150,7 +150,9 @@ end" exports[`Transformation (do) 1`] = ` "local e = 10 repeat - e = e - 1 + do + e = e - 1 + end until not (e > 0)" `; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 38b16a7e0..57cd5cc11 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -981,3 +981,39 @@ test.each([ ).message ); }); + +test("do...while", () => { + const code = ` + let result = 0; + do { + ++result; + } while (result < 2); + return result; + `; + expect(util.transpileAndExecute(code)).toBe(2); +}); + +test("do...while scoping", () => { + const code = ` + let x = 0; + let result = 0; + do { + let x = 1; + ++result; + } while (x === 0 && result < 2); + return result; + `; + expect(util.transpileAndExecute(code)).toBe(2); +}); + +test("do...while double-negation", () => { + const code = ` + let result = 0; + do { + ++result; + } while (!(result >= 2)); + return result; + `; + expect(util.transpileString(code)).not.toMatch("not"); + expect(util.transpileAndExecute(code)).toBe(2); +}); From 082e4939c6570be748467d55e17efe709ee6082b Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Jul 2019 14:49:14 +0200 Subject: [PATCH 134/764] Fix compileMembersOnly ignoring preceding variable path (#662) --- src/LuaTransformer.ts | 31 ++++++++++++++++++++++++++----- test/unit/lualib/lualib.spec.ts | 17 +++++++++++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 1e0686e41..856791188 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1675,16 +1675,27 @@ export class LuaTransformer { for (const enumMember of this.computeEnumMembers(enumDeclaration)) { const memberName = this.transformPropertyName(enumMember.name); if (membersOnly) { + const enumSymbol = this.checker.getSymbolAtLocation(enumDeclaration.name); + const exportScope = enumSymbol ? this.getSymbolExportScope(enumSymbol) : undefined; + if (tstl.isIdentifier(memberName)) { result.push( - ...this.createLocalOrExportedOrGlobalDeclaration(memberName, enumMember.value, enumDeclaration) + ...this.createLocalOrExportedOrGlobalDeclaration( + memberName, + enumMember.value, + enumDeclaration, + undefined, + exportScope + ) ); } else { result.push( ...this.createLocalOrExportedOrGlobalDeclaration( tstl.createIdentifier(enumMember.name.getText(), enumMember.name), enumMember.value, - enumDeclaration + enumDeclaration, + undefined, + exportScope ) ); } @@ -4087,7 +4098,16 @@ export class LuaTransformer { const decorators = tsHelper.getCustomDecorators(type, this.checker); // Do not output path for member only enums if (decorators.has(DecoratorKind.CompileMembersOnly)) { - return tstl.createIdentifier(property, expression); + if (ts.isPropertyAccessExpression(expression.expression)) { + // in case of ...x.enum.y transform to ...x.y + return tstl.createTableIndexExpression( + this.transformExpression(expression.expression.expression), + tstl.createStringLiteral(property), + expression + ); + } else { + return tstl.createIdentifier(property, expression); + } } if (decorators.has(DecoratorKind.LuaTable)) { @@ -5161,7 +5181,8 @@ export class LuaTransformer { lhs: tstl.Identifier | tstl.Identifier[], rhs?: tstl.Expression | tstl.Expression[], tsOriginal?: ts.Node, - parent?: tstl.Node + parent?: tstl.Node, + overrideExportScope?: ts.SourceFile | ts.ModuleDeclaration ): tstl.Statement[] { let declaration: tstl.VariableDeclarationStatement | undefined; let assignment: tstl.AssignmentStatement | undefined; @@ -5173,7 +5194,7 @@ export class LuaTransformer { return []; } - const exportScope = this.getIdentifierExportScope(identifiers[0]); + const exportScope = overrideExportScope || this.getIdentifierExportScope(identifiers[0]); if (exportScope) { // exported if (!rhs) { diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts index 7cb051b35..5ff9e45de 100644 --- a/test/unit/lualib/lualib.spec.ts +++ b/test/unit/lualib/lualib.spec.ts @@ -150,3 +150,20 @@ test("lualibs should not include tstl header", () => { expect(util.transpileString(code)).not.toMatch("Generated with"); }); + +test("compileMembersOnly in namespace", () => { + const header = ` + namespace wifi { + /** @compileMembersOnly */ + export enum WifiMode { + NULLMODE = 0, + STATION = 1, + SOFTAP = 2 + } + }`; + const code = ` + return wifi.WifiMode.STATION; + `; + + expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe(1); +}); From 4a86dc1201a82515176f2a5e7ed60de39d693d45 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 14 Jul 2019 20:06:46 +0200 Subject: [PATCH 135/764] 0.24.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5514235ca..14c205293 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.23.0", + "version": "0.24.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 251f81ee6..f55c8be76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.23.0", + "version": "0.24.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From c0bf63dfbd55f0ebe2c3d1e468b656b7c55ba8a5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Jul 2019 20:24:44 +0200 Subject: [PATCH 136/764] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 631d0bb8e..8e12357af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.24.0 + +- Returns in try/catch statements now properly return from the current function. +- TypeScript's `globalThis` is now translated to lua's `_G`. Lualib functions were updated where relevant. + +- Fixed issue where string/table literals were missing parentheses and caused lua syntax errors. +- Various improvements/refactorings across the codebase. +- Fixed syntax error in for...of loops with empty destructuring argument. +- Fixed issue with `do ... while` scope. +- Fixed a bug with [@combileMembersOnly](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#compilemembersonly) where it would ignore anything before the enum name. + ## 0.23.0 - Added support for OmittedExpression in array literals and array binding patterns. From 781bccfb5e91ad92c2d88839c99e54a777fa712a Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 17 Jul 2019 02:40:44 +1000 Subject: [PATCH 137/764] Constrained generic fixes (#668) * Fix generic array constrained detection * Fix generic string constrained detection * Remove unnecessary conditional change * Add more generic array tests and check potential generic array type first --- src/LuaTransformer.ts | 11 +++++++---- src/TSHelper.ts | 16 +++++++++++++++- test/unit/array.spec.ts | 35 +++++++++++++++++++++++++++++++++++ test/unit/string.spec.ts | 13 +++++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 856791188..027892887 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2757,7 +2757,7 @@ export class LuaTransformer { } const type = this.checker.getTypeAtLocation(statement.expression); - if (tsHelper.isStringType(type)) { + if (tsHelper.isStringType(type, this.checker, this.program)) { const error = tstl.createIdentifier("error"); return tstl.createExpressionStatement( tstl.createCallExpression(error, [this.transformExpression(statement.expression)]), @@ -3289,7 +3289,10 @@ export class LuaTransformer { // Check is we need to use string concat operator const typeLeft = this.checker.getTypeAtLocation(node.left); const typeRight = this.checker.getTypeAtLocation(node.right); - if (tsHelper.isStringType(typeLeft) || tsHelper.isStringType(typeRight)) { + if ( + tsHelper.isStringType(typeLeft, this.checker, this.program) || + tsHelper.isStringType(typeRight, this.checker, this.program) + ) { return tstl.SyntaxKind.ConcatOperator; } } @@ -4084,7 +4087,7 @@ export class LuaTransformer { // Check for primitive types to override const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isStringType(type)) { + if (tsHelper.isStringType(type, this.checker, this.program)) { return this.transformStringProperty(expression); } else if (tsHelper.isArrayType(type, this.checker, this.program)) { const arrayPropertyAccess = this.transformArrayProperty(expression); @@ -4291,7 +4294,7 @@ export class LuaTransformer { const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isNumberType(argumentType) && tsHelper.isStringType(type)) { + if (tsHelper.isNumberType(argumentType) && tsHelper.isStringType(type, this.checker, this.program)) { const index = this.transformExpression(expression.argumentExpression); return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")), diff --git a/src/TSHelper.ts b/src/TSHelper.ts index a26c89343..6a9dc5a32 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -132,7 +132,14 @@ export function isStaticNode(node: ts.Node): boolean { return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); } -export function isStringType(type: ts.Type): boolean { +export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + if (type.symbol) { + const baseConstraint = checker.getBaseConstraintOfType(type); + if (baseConstraint) { + return isStringType(baseConstraint, checker, program); + } + } + return ( (type.flags & ts.TypeFlags.String) !== 0 || (type.flags & ts.TypeFlags.StringLike) !== 0 || @@ -149,6 +156,13 @@ export function isNumberType(type: ts.Type): boolean { } export function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + if (type.symbol) { + const baseConstraint = checker.getBaseConstraintOfType(type); + if (baseConstraint) { + return isExplicitArrayType(baseConstraint, checker, program); + } + } + if (type.isUnionOrIntersection()) { return type.types.some(t => isExplicitArrayType(t, checker, program)); } diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts index d0496ab56..6b1b653a9 100644 --- a/test/unit/array.spec.ts +++ b/test/unit/array.spec.ts @@ -226,3 +226,38 @@ test.each([`["foo", "bar"].length`, `["foo", "bar"][0]`, `[() => "foo", () => "b expect(util.transpileAndExecute(code)).toBe(expectResult); } ); + +const genericChecks = [ + "function generic(array: T)", + "function generic(array: T)", + "function generic(array: T[])", + "type ArrayType = number[]; function generic(array: T)", + "function generic(array: T & {})", + "function generic(array: T)", +]; + +test.each(genericChecks)("array constrained generic foreach (%p)", signature => { + const code = ` + ${signature}: number { + let sum = 0; + array.forEach(item => { + if (typeof item === "number") { + sum += item; + } + }); + return sum; + } + return generic([1, 2, 3]); + `; + expect(util.transpileAndExecute(code)).toBe(6); +}); + +test.each(genericChecks)("array constrained generic length (%p)", signature => { + const code = ` + ${signature}: number { + return array.length; + } + return generic([1, 2, 3]); + `; + expect(util.transpileAndExecute(code)).toBe(3); +}); diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 6c47ddb52..3d6fc3c9f 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -348,3 +348,16 @@ test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`fo expect(util.transpileAndExecute(code)).toBe(expectResult); } ); + +test.each([ + "function generic(string: T)", + "type StringType = string; function generic(string: T)", +])("string constrained generic foreach (%p)", signature => { + const code = ` + ${signature}: number { + return string.length; + } + return generic("string"); + `; + expect(util.transpileAndExecute(code)).toBe(6); +}); From 9376ea5ea1b9e6b48fc6e2ae7bbb1cd6a8c1f9a9 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 18 Jul 2019 10:26:31 -0600 Subject: [PATCH 138/764] Fixed referencing named function expressions (#671) * Fixed referencing named function expressions fixes #669 * checking symbolId against undefined * added some comments --- src/LuaTransformer.ts | 24 +++++++++++++++++++++--- test/unit/functions.spec.ts | 9 +++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 027892887..4751f8dbc 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3664,9 +3664,9 @@ export class LuaTransformer { flags |= tstl.FunctionExpressionFlags.Inline; } - const [transformedBody] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); + const [transformedBody, scope] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); - return tstl.createFunctionExpression( + const functionExpression = tstl.createFunctionExpression( tstl.createBlock(transformedBody), paramNames, dotsLiteral, @@ -3674,6 +3674,24 @@ export class LuaTransformer { flags, node ); + + //Handle named function expressions which reference themselves + if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) { + const symbol = this.checker.getSymbolAtLocation(node.name); + if (symbol) { + const symbolId = this.symbolIds.get(symbol); + //Only wrap if the name is actually referenced inside the function + if (symbolId !== undefined && scope.referencedSymbols.has(symbolId)) { + const nameIdentifier = this.transformIdentifier(node.name); + return this.createImmediatelyInvokedFunctionExpression( + [tstl.createVariableDeclarationStatement(nameIdentifier, functionExpression)], + tstl.cloneIdentifier(nameIdentifier) + ); + } + } + } + + return functionExpression; } public transformNewExpression(node: ts.NewExpression): ExpressionVisitResult { @@ -5111,7 +5129,7 @@ export class LuaTransformer { protected createImmediatelyInvokedFunctionExpression( statements: tstl.Statement[], result: tstl.Expression | tstl.Expression[], - tsOriginal: ts.Node + tsOriginal?: ts.Node ): tstl.CallExpression { const body = statements ? statements.slice(0) : []; body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result])); diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 455b6d70d..41d55e5af 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -610,3 +610,12 @@ test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => { expect(util.executeLua(lua)).toBe("ABCD"); }); + +test("named function expression reference", () => { + const code = ` + const y = function x(inp: string) { + return inp + typeof x; + }; + return y("foo-");`; + expect(util.transpileAndExecute(code)).toBe("foo-function"); +}); From b071a92fe89aacbf85fee1a6b492de8d31884873 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 18 Jul 2019 12:22:09 -0600 Subject: [PATCH 139/764] Tracking object literal shorthand identifier references (#666) Fixes bug where hoisting wouldn't occur for variables referenced only in object literal shorthand assignments. Also fixes #663 --- src/LuaTransformer.ts | 70 ++++++++++++++++++++----------------- test/unit/functions.spec.ts | 12 +++++++ test/unit/hoisting.spec.ts | 11 ++++++ 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4751f8dbc..8ddaa24d3 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3597,6 +3597,9 @@ export class LuaTransformer { properties.push(tstl.createTableFieldExpression(expression, name, element)); } else if (ts.isShorthandPropertyAssignment(element)) { const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + this.trackSymbolReference(valueSymbol, element.name); + } const identifier = this.createShorthandIdentifier(valueSymbol, element.name); properties.push(tstl.createTableFieldExpression(identifier, name, element)); } else if (ts.isMethodDeclaration(element)) { @@ -5525,47 +5528,50 @@ export class LuaTransformer { return "____" + tsHelper.fixInvalidLuaIdentifier(name); } - protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { - const symbol = this.checker.getSymbolAtLocation(identifier); - let symbolId: tstl.SymbolId | undefined; - if (symbol) { - // Track first time symbols are seen - if (!this.symbolIds.has(symbol)) { - symbolId = this.genSymbolIdCounter++; + protected trackSymbolReference(symbol: ts.Symbol, identifier: ts.Identifier): tstl.SymbolId | undefined { + // Track first time symbols are seen + let symbolId = this.symbolIds.get(symbol); + if (!symbolId) { + symbolId = this.genSymbolIdCounter++; - const symbolInfo: SymbolInfo = { symbol, firstSeenAtPos: identifier.pos }; - this.symbolIds.set(symbol, symbolId); - this.symbolInfo.set(symbolId, symbolInfo); - } else { - symbolId = this.symbolIds.get(symbol); - } + const symbolInfo: SymbolInfo = { symbol, firstSeenAtPos: identifier.pos }; + this.symbolIds.set(symbol, symbolId); + this.symbolInfo.set(symbolId, symbolInfo); + } - if (this.options.noHoisting) { - // Check for reference-before-declaration - const declaration = tsHelper.getFirstDeclaration(symbol, this.currentSourceFile); - if (declaration && identifier.pos < declaration.pos) { - throw TSTLErrors.ReferencedBeforeDeclaration(identifier); - } + if (this.options.noHoisting) { + // Check for reference-before-declaration + const declaration = tsHelper.getFirstDeclaration(symbol, this.currentSourceFile); + if (declaration && identifier.pos < declaration.pos) { + throw TSTLErrors.ReferencedBeforeDeclaration(identifier); } + } - if (symbolId !== undefined) { - //Mark symbol as seen in all current scopes - for (const scope of this.scopeStack) { - if (!scope.referencedSymbols) { - scope.referencedSymbols = new Map(); - } - let references = scope.referencedSymbols.get(symbolId); - if (!references) { - references = []; - scope.referencedSymbols.set(symbolId, references); - } - references.push(identifier); - } + //Mark symbol as seen in all current scopes + for (const scope of this.scopeStack) { + if (!scope.referencedSymbols) { + scope.referencedSymbols = new Map(); + } + let references = scope.referencedSymbols.get(symbolId); + if (!references) { + references = []; + scope.referencedSymbols.set(symbolId, references); } + references.push(identifier); } + return symbolId; } + protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { + const symbol = this.checker.getSymbolAtLocation(identifier); + if (symbol) { + return this.trackSymbolReference(symbol, identifier); + } else { + return undefined; + } + } + protected findScope(scopeTypes: ScopeType): Scope | undefined { return this.scopeStack .slice() diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts index 41d55e5af..b8558a3cd 100644 --- a/test/unit/functions.spec.ts +++ b/test/unit/functions.spec.ts @@ -557,6 +557,18 @@ test.each([{}, { noHoisting: true }])("Function rest parameter (unreferenced)", expect(util.transpileAndExecute(code, compilerOptions)).toBe("foobar"); }); +test.each([{}, { noHoisting: true }])("Function rest parameter (referenced in property shorthand)", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + const c = { b }; + return c.b.join(""); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { const code = ` /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 1d91e3684..c5ad0a1c9 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -235,6 +235,7 @@ test.each([ }, { code: `function makeFoo() { return new Foo(); } class Foo {}`, identifier: "Foo" }, { code: `function bar() { return E.A; } enum E { A = "foo" }`, identifier: "E" }, + { code: `function setBar() { const bar = { foo }; } let foo = "foo";`, identifier: "foo" }, ])("No Hoisting (%p)", ({ code, identifier }) => { expect(() => util.transpileString(code, { noHoisting: true })).toThrowExactError( TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)) @@ -292,3 +293,13 @@ test("Import hoisted before function", () => { const code = "return bar;"; expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); }); + +test("Hoisting Shorthand Property", () => { + const code = ` + function foo() { + return { bar }.bar; + } + let bar = "foobar"; + return foo();`; + expect(util.transpileAndExecute(code)).toBe("foobar"); +}); From dee4e40bb8cf689649fcf31c736a0685cb2121c0 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 19 Jul 2019 23:24:58 +0500 Subject: [PATCH 140/764] Fix contextual function call transform cubic complexity (#673) --- src/LuaTransformer.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 8ddaa24d3..4d43d0348 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3971,10 +3971,6 @@ export class LuaTransformer { ); } else { const parameters = this.transformArguments(node.arguments, signature); - let table = this.transformExpression(node.expression.expression); - if (tstl.isTableExpression(table)) { - table = tstl.createParenthesizedExpression(table); - } const signatureDeclaration = signature && signature.getDeclaration(); if ( !signatureDeclaration || @@ -3983,6 +3979,11 @@ export class LuaTransformer { // table:name() return this.transformContextualCallExpression(node, parameters); } else { + let table = this.transformExpression(node.expression.expression); + if (tstl.isTableExpression(table)) { + table = tstl.createParenthesizedExpression(table); + } + // table.name() const callPath = tstl.createTableIndexExpression( table, @@ -4024,7 +4025,6 @@ export class LuaTransformer { transformedArguments: tstl.Expression[] ): ExpressionVisitResult { const left = ts.isCallExpression(node) ? node.expression : node.tag; - const leftHandSideExpression = this.transformExpression(left); if ( ts.isPropertyAccessExpression(left) && !luaKeywords.has(left.name.text) && @@ -4064,7 +4064,8 @@ export class LuaTransformer { } else if (ts.isIdentifier(left)) { const context = this.isStrict ? tstl.createNilLiteral() : tstl.createIdentifier("_G"); transformedArguments.unshift(context); - return tstl.createCallExpression(leftHandSideExpression, transformedArguments, node); + const expression = this.transformExpression(left); + return tstl.createCallExpression(expression, transformedArguments, node); } else { throw TSTLErrors.UnsupportedKind("Left Hand Side Call Expression", left.kind, left); } From bd5977fb0263837acba12e0993d81c7b0a5d7914 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 19 Jul 2019 23:25:46 +0500 Subject: [PATCH 141/764] Fix readonly tuple detection (#674) --- src/TSHelper.ts | 8 ++++---- test/unit/tuples.spec.ts | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 6a9dc5a32..0d8276aa9 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -167,12 +167,12 @@ export function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, prog return type.types.some(t => isExplicitArrayType(t, checker, program)); } - if (isStandardLibraryType(type, "ReadonlyArray", program)) { - return true; + const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; + let typeNode = checker.typeToTypeNode(type, undefined, flags); + if (typeNode && ts.isTypeOperatorNode(typeNode) && typeNode.operator === ts.SyntaxKind.ReadonlyKeyword) { + typeNode = typeNode.type; } - const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; - const typeNode = checker.typeToTypeNode(type, undefined, flags); return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); } diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 0f6aa6a39..4f527f29f 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -31,6 +31,15 @@ test("Tuple access", () => { expect(result).toBe(5); }); +test("Readonly Tuple access", () => { + const result = util.transpileAndExecute( + `const tuple: readonly [number, number, number] = [3,5,1]; + return tuple[1];` + ); + + expect(result).toBe(5); +}); + test("Tuple union access", () => { const result = util.transpileAndExecute( `function makeTuple(): [number, number, number] | [string, string, string] { return [3,5,1]; } From 6b9aeec5a18ee5a664a616fcbd5d0679b9af1c5f Mon Sep 17 00:00:00 2001 From: Martin Jesper Low Madsen Date: Mon, 22 Jul 2019 09:45:46 +0200 Subject: [PATCH 142/764] Process a union or intersection type of all strings as a string (#675) --- src/LuaTransformer.ts | 6 ++---- src/TSHelper.ts | 8 ++++++++ test/unit/string.spec.ts | 16 ++++++++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4d43d0348..4138f2af2 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3918,10 +3918,8 @@ export class LuaTransformer { }); } - switch (ownerType.flags) { - case ts.TypeFlags.String: - case ts.TypeFlags.StringLiteral: - return this.transformStringCallExpression(node); + if (tsHelper.isStringType(ownerType, this.checker, this.program)) { + return this.transformStringCallExpression(node); } // if ownerType is a array, use only supported functions diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 0d8276aa9..13ff34e5a 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -140,6 +140,14 @@ export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts } } + if (type.isUnion()) { + return type.types.every(t => isStringType(t, checker, program)); + } + + if (type.isIntersection()) { + return type.types.some(t => isStringType(t, checker, program)); + } + return ( (type.flags & ts.TypeFlags.String) !== 0 || (type.flags & ts.TypeFlags.StringLike) !== 0 || diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 3d6fc3c9f..8768818cf 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -349,6 +349,22 @@ test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`fo } ); +test("scoped string-union inference", () => { + const inp = "foo"; + + const result = util.transpileAndExecute(` + const union: string = "${inp}"; + + if (union === "foo" || union === "bar") { + return union.length; + } + + return 0; + `); + + expect(result).toBe(inp.length); +}); + test.each([ "function generic(string: T)", "type StringType = string; function generic(string: T)", From 0e7fd93ef5b6dee15eaec42beb7bd29447e18da1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 22 Jul 2019 20:45:35 +0200 Subject: [PATCH 143/764] Updated package-lock --- package-lock.json | 3325 +++------------------------------------------ 1 file changed, 204 insertions(+), 3121 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14c205293..358e7eea7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -102,6 +102,12 @@ "to-fast-properties": "^2.0.0" } }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -408,306 +414,6 @@ "realpath-native": "^1.1.0", "rimraf": "^2.5.4", "strip-ansi": "^5.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" - } - }, - "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@jest/environment": { @@ -762,257 +468,44 @@ "string-length": "^2.0.0" }, "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@jest/source-map": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", - "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - }, - "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/source-map": { + "version": "24.3.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", + "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.1.15", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", + "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/types": "^24.8.0", + "@types/istanbul-lib-coverage": "^2.0.0" + }, + "dependencies": { "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", @@ -1031,179 +524,6 @@ "jest-haste-map": "^24.8.0", "jest-runner": "^24.8.0", "jest-runtime": "^24.8.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@jest/transform": { @@ -1257,9 +577,9 @@ } }, "@types/babel__core": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.1.tgz", - "integrity": "sha512-+hjBtgcFPYyCTo0A15+nxrCVJL7aC6Acg87TXd5OW3QhHswdrOLoles+ldL2Uk8q++7yIfl4tURtztccdeeyOw==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz", + "integrity": "sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -1289,9 +609,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.6.tgz", - "integrity": "sha512-XYVgHF2sQ0YblLRMLNPB3CkFMewzFmlDsH/TneZFHUXDlABQgh88uOxuez7ZcXxayLFrqLwtDH1t+FmlFwNZxw==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", + "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -1410,23 +730,23 @@ }, "dependencies": { "acorn": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", + "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", "dev": true } } }, "acorn-walk": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", + "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -1442,9 +762,9 @@ "dev": true }, "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "ansi-styles": { @@ -1589,202 +909,6 @@ "babel-preset-jest": "^24.6.0", "chalk": "^2.4.2", "slash": "^2.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "babel-plugin-istanbul": { @@ -2074,12 +1198,6 @@ "wrap-ansi": "^2.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -2129,9 +1247,9 @@ "dev": true }, "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -2190,15 +1308,15 @@ } }, "cssom": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, "cssstyle": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", - "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", + "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", "dev": true, "requires": { "cssom": "0.3.x" @@ -2769,7 +1887,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -2790,12 +1909,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2810,17 +1931,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -2937,7 +2061,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -2949,6 +2074,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -2963,6 +2089,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -2970,12 +2097,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -2994,6 +2123,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -3074,7 +2204,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -3086,6 +2217,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -3171,7 +2303,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -3207,6 +2340,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3226,6 +2360,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3269,12 +2404,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -3799,9 +2936,9 @@ } }, "istanbul-reports": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.4.tgz", - "integrity": "sha512-QCHGyZEK0bfi9GR215QSm+NJwFKEShbtc7tfbUdLAEzn3kKhLDDZqvljn8rPZM9v8CEOhzL1nlYoO4r1ryl67w==", + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", + "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, "requires": { "handlebars": "^4.1.2" @@ -3817,76 +2954,6 @@ "jest-cli": "^24.8.0" }, "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, "jest-cli": { "version": "24.8.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.8.0.tgz", @@ -3907,66 +2974,6 @@ "realpath-native": "^1.1.0", "yargs": "^12.0.2" } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } } } }, @@ -3979,25 +2986,6 @@ "@jest/types": "^24.8.0", "execa": "^1.0.0", "throat": "^4.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - } } }, "jest-circus": { @@ -4047,175 +3035,6 @@ "micromatch": "^3.1.10", "pretty-format": "^24.8.0", "realpath-native": "^1.1.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-diff": { @@ -4264,214 +3083,6 @@ "jest-mock": "^24.8.0", "jest-util": "^24.8.0", "jsdom": "^11.5.1" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-environment-node": { @@ -4485,214 +3096,6 @@ "@jest/types": "^24.8.0", "jest-mock": "^24.8.0", "jest-util": "^24.8.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-get-type": { @@ -4743,322 +3146,6 @@ "jest-util": "^24.8.0", "pretty-format": "^24.8.0", "throat": "^4.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" - } - }, - "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-each": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz", - "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-leak-detector": { @@ -5068,52 +3155,6 @@ "dev": true, "requires": { "pretty-format": "^24.8.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - } } }, "jest-matcher-utils": { @@ -5187,187 +3228,6 @@ "@jest/types": "^24.8.0", "jest-regex-util": "^24.3.0", "jest-snapshot": "^24.8.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" - } - }, - "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-runner": { @@ -5387,583 +3247,45 @@ "jest-docblock": "^24.3.0", "jest-haste-map": "^24.8.0", "jest-jasmine2": "^24.8.0", - "jest-leak-detector": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "source-map-support": "^0.5.6", - "throat": "^4.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "jest-runtime": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz", - "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/yargs": "^12.0.2", - "chalk": "^2.0.1", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^12.0.2" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", - "dev": true, - "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", - "micromatch": "^3.1.10", - "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" - } - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "anymatch": "^2.0.0", - "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", - "micromatch": "^3.1.10", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", - "dev": true, - "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", - "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", - "dev": true, - "requires": { - "merge-stream": "^1.0.1", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "jest-leak-detector": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-resolve": "^24.8.0", + "jest-runtime": "^24.8.0", + "jest-util": "^24.8.0", + "jest-worker": "^24.6.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + } + }, + "jest-runtime": { + "version": "24.8.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz", + "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==", + "dev": true, + "requires": { + "@jest/console": "^24.7.1", + "@jest/environment": "^24.8.0", + "@jest/source-map": "^24.3.0", + "@jest/transform": "^24.8.0", + "@jest/types": "^24.8.0", + "@types/yargs": "^12.0.2", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "jest-config": "^24.8.0", + "jest-haste-map": "^24.8.0", + "jest-message-util": "^24.8.0", + "jest-mock": "^24.8.0", + "jest-regex-util": "^24.3.0", + "jest-resolve": "^24.8.0", + "jest-snapshot": "^24.8.0", + "jest-util": "^24.8.0", + "jest-validate": "^24.8.0", + "realpath-native": "^1.1.0", + "slash": "^2.0.0", + "strip-bom": "^3.0.0", + "yargs": "^12.0.2" } }, "jest-serializer": { @@ -6032,78 +3354,6 @@ "jest-get-type": "^24.8.0", "leven": "^2.1.0", "pretty-format": "^24.8.0" - }, - "dependencies": { - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", - "dev": true - }, - "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-watcher": { @@ -6119,138 +3369,6 @@ "chalk": "^2.0.1", "jest-util": "^24.8.0", "string-length": "^2.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", - "dev": true, - "requires": { - "@jest/source-map": "^24.3.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" - } - }, - "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" - } - }, - "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", - "@types/istanbul-lib-coverage": "^2.0.0" - } - }, - "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", - "dev": true, - "requires": { - "@jest/types": "^24.8.0" - } - }, - "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "jest-worker": { @@ -6447,9 +3565,9 @@ } }, "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash.sortby": { @@ -6608,9 +3726,9 @@ "dev": true }, "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "requires": { "for-in": "^1.0.2", @@ -6684,9 +3802,9 @@ "dev": true }, "neo-async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.0.tgz", - "integrity": "sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, "nice-try": { @@ -7108,9 +4226,9 @@ "dev": true }, "prompts": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.0.4.tgz", - "integrity": "sha512-HTzM3UWp/99A0gk51gAegwo1QRYA7xjcZufMNe33rCclFszUYAuHe1fIN/3ZmiHeGPkUsNaRyQm1hHOfM0PKxA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", + "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", "dev": true, "requires": { "kleur": "^3.0.2", @@ -7118,9 +4236,9 @@ } }, "psl": { - "version": "1.1.31", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", + "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", "dev": true }, "pump": { @@ -7265,9 +4383,9 @@ "dev": true }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", "dev": true }, "tough-cookie": { @@ -7356,22 +4474,6 @@ "dev": true, "requires": { "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } } }, "rsvp": { @@ -7437,9 +4539,9 @@ "dev": true }, "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -7487,9 +4589,9 @@ "dev": true }, "sisteransi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.0.tgz", - "integrity": "sha512-N+z4pHB4AmUv0SjveWRd6q1Nj5w62m5jodv+GD8lvmbY/83T/rpbJGZOnK5T149OldDj4Db07BSv9xY4K6NTPQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz", + "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==", "dev": true }, "slash": { @@ -7775,12 +4877,6 @@ "strip-ansi": "^4.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -7802,12 +4898,6 @@ "strip-ansi": "^4.0.0" }, "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -7829,12 +4919,20 @@ } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + } } }, "strip-bom": { @@ -7859,9 +4957,9 @@ } }, "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, "test-exclude": { @@ -8086,9 +5184,9 @@ "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==" }, "uglify-js": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.5.10.tgz", - "integrity": "sha512-/GTF0nosyPLbdJBd+AwYiZ+Hu5z8KXWnO0WCGt1BQ/u9Iamhejykqmz5o1OHJ53+VAk6xVxychonnApDjuqGsw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", + "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, "optional": true, "requires": { @@ -8096,13 +5194,6 @@ "source-map": "~0.6.1" }, "dependencies": { - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true, - "optional": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -8113,38 +5204,15 @@ } }, "union-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, "requires": { "arr-union": "^3.1.0", "get-value": "^2.0.6", "is-extendable": "^0.1.1", - "set-value": "^0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" - } - } + "set-value": "^2.0.1" } }, "unset-value": { @@ -8332,6 +5400,12 @@ "strip-ansi": "^3.0.1" }, "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", @@ -8351,6 +5425,15 @@ "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } } } }, From bb015cb5a6fea873e1d8de5c22897529c3f48f79 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 22 Jul 2019 20:47:20 +0200 Subject: [PATCH 144/764] 0.25.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 358e7eea7..ce9752f4b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.24.0", + "version": "0.25.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f55c8be76..669b8997f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.24.0", + "version": "0.25.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From d2fad97452913771e2fc3662e8ac9749b0293ff1 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 22 Jul 2019 20:58:54 +0200 Subject: [PATCH 145/764] Update CHANGELOG.md 0.25.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e12357af..78322e78f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.25.0 + +- Added support for named function assignments, i.e. `const myFunc = function x(n) { ...; return x(n - 1); }` + +- Made detection of string methods more robust. +- Fixed issue regarding readonly tuple detection. +- Fixed a nasty issue causing exponential complexity on chained properties/method expressions. +- Improved handling of constrained generic types related to string and array detection. + ## 0.24.0 - Returns in try/catch statements now properly return from the current function. From f7cb2a2b084deb64291aecfb6d14bbf7ca2e3f4b Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 23 Jul 2019 12:58:16 -0600 Subject: [PATCH 146/764] fixed crashes from recursive base constraints (#681) fixes #680 --- src/TSHelper.ts | 4 ++-- test/unit/enum.spec.ts | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 13ff34e5a..85a6a08ef 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -135,7 +135,7 @@ export function isStaticNode(node: ts.Node): boolean { export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { if (type.symbol) { const baseConstraint = checker.getBaseConstraintOfType(type); - if (baseConstraint) { + if (baseConstraint && baseConstraint !== type) { return isStringType(baseConstraint, checker, program); } } @@ -166,7 +166,7 @@ export function isNumberType(type: ts.Type): boolean { export function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { if (type.symbol) { const baseConstraint = checker.getBaseConstraintOfType(type); - if (baseConstraint) { + if (baseConstraint && baseConstraint !== type) { return isExplicitArrayType(baseConstraint, checker, program); } } diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 383d9708f..bd40f2619 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -172,3 +172,27 @@ test("Const enum index identifier chain", () => { expect(result).toBe(4); }); + +test("enum toString", () => { + const code = ` + enum TestEnum { + A, + B, + C, + } + let test = TestEnum.A; + return test.toString();`; + expect(util.transpileAndExecute(code)).toBe(0); +}); + +test("enum concat", () => { + const code = ` + enum TestEnum { + A, + B, + C, + } + let test = TestEnum.A; + return test + "_foobar";`; + expect(util.transpileAndExecute(code)).toBe("0_foobar"); +}); From f9f5fd7f784bb9e420a2e8483a1c467da7667a4e Mon Sep 17 00:00:00 2001 From: lightrabbit Date: Wed, 24 Jul 2019 15:34:26 +0800 Subject: [PATCH 147/764] Fix transform `string.indexOf` with out `plain` parameter. (#679) * Add edge test case. That makes unit test for `string.indexOf` failure. * Fix transform `string.indexOf` with out `plain` parameter. * Fix make two expressions collapsed to a single call --- src/LuaTransformer.ts | 19 ++++++++----------- test/unit/string.spec.ts | 1 + 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 4138f2af2..ac8f49578 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4350,17 +4350,14 @@ export class LuaTransformer { case "concat": return this.transformLuaLibFunction(LuaLibFeature.StringConcat, node, caller, ...params); case "indexOf": - const stringExpression = - node.arguments.length === 1 - ? this.createStringCall("find", node, caller, params[0]) - : this.createStringCall( - "find", - node, - caller, - params[0], - this.expressionPlusOne(params[1]), - tstl.createBooleanLiteral(true) - ); + const stringExpression = this.createStringCall( + "find", + node, + caller, + params[0], + params[1] ? this.expressionPlusOne(params[1]) : tstl.createNilLiteral(), + tstl.createBooleanLiteral(true) + ); return tstl.createParenthesizedExpression( tstl.createBinaryExpression( diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts index 8768818cf..9590c478d 100644 --- a/test/unit/string.spec.ts +++ b/test/unit/string.spec.ts @@ -132,6 +132,7 @@ test.each([ { inp: "hello test", searchValue: "t" }, { inp: "hello test", searchValue: "h" }, { inp: "hello test", searchValue: "invalid" }, + { inp: "hello.test", searchValue: "." }, ])("string.indexOf (%p)", ({ inp, searchValue }) => { const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}")`); From 17412868183b6dd6037ccf216f06f7554038e6e3 Mon Sep 17 00:00:00 2001 From: Martin Jesper Low Madsen Date: Thu, 25 Jul 2019 22:14:38 +0200 Subject: [PATCH 148/764] Support omitted declarations for destructured tuples (#682) --- src/LuaTransformer.ts | 12 ++++++++++-- src/TSHelper.ts | 8 +++++++- test/unit/tuples.spec.ts | 2 +- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ac8f49578..c5135c801 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1943,7 +1943,9 @@ export class LuaTransformer { // For nested bindings and object bindings, fall back to transformBindingPattern if ( ts.isObjectBindingPattern(statement.name) || - statement.name.elements.some(elem => !ts.isBindingElement(elem) || !ts.isIdentifier(elem.name)) + statement.name.elements.some( + elem => (!ts.isBindingElement(elem) || !ts.isIdentifier(elem.name)) && !ts.isOmittedExpression(elem) + ) ) { const statements = []; let table: tstl.Identifier; @@ -1968,7 +1970,13 @@ export class LuaTransformer { } // Disallow ellipsis destruction - if (statement.name.elements.some(elem => !ts.isBindingElement(elem) || elem.dotDotDotToken !== undefined)) { + if ( + statement.name.elements.some( + elem => + (!ts.isBindingElement(elem) || elem.dotDotDotToken !== undefined) && + !ts.isOmittedExpression(elem) + ) + ) { throw TSTLErrors.ForbiddenEllipsisDestruction(statement); } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 85a6a08ef..53a594dc3 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -832,8 +832,14 @@ export function isWithinLiteralAssignmentStatement(node: ts.Node): boolean { if (!node.parent) { return false; } - if (ts.isArrayLiteralExpression(node.parent) || ts.isObjectLiteralExpression(node.parent)) { + if ( + ts.isArrayLiteralExpression(node.parent) || + ts.isArrayBindingPattern(node.parent) || + ts.isObjectLiteralExpression(node.parent) + ) { return isWithinLiteralAssignmentStatement(node.parent); + } else if (isInDestructingAssignment(node)) { + return true; } else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { return true; } else { diff --git a/test/unit/tuples.spec.ts b/test/unit/tuples.spec.ts index 4f527f29f..779bd8666 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/tuples.spec.ts @@ -122,7 +122,7 @@ test("Tuple Return Destruct Declaration", () => { const code = ` /** @tupleReturn */ function tuple(): [number, number, number] { return [3,5,1]; } - const [a,b,c] = tuple(); + const [,b,c] = tuple(); return b;`; const lua = util.transpileString(code); From 26d7338a8a730d292ba0100819f01181db411ba6 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 26 Jul 2019 01:17:40 +0500 Subject: [PATCH 149/764] Wrap expression statements based on transformed node (#688) --- src/LuaTransformer.ts | 19 ++++++------------- test/unit/expressions.spec.ts | 29 +++++++++++++++-------------- test/unit/math.spec.ts | 4 ++-- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index c5135c801..e1d48fc46 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2112,14 +2112,6 @@ export class LuaTransformer { ); } - if (!ts.isCallLikeExpression(expression)) { - // Assign expression statements to dummy to make sure they're legal lua - return tstl.createVariableDeclarationStatement( - tstl.createAnonymousIdentifier(), - this.transformExpression(expression) - ); - } - if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { const ownerType = this.checker.getTypeAtLocation(expression.expression.expression); const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); @@ -2134,7 +2126,11 @@ export class LuaTransformer { } } - return tstl.createExpressionStatement(this.transformExpression(expression)); + const result = this.transformExpression(expression); + return tstl.isCallExpression(result) || tstl.isMethodCallExpression(result) + ? tstl.createExpressionStatement(result) + : // Assign expression statements to dummy to make sure they're legal Lua + tstl.createVariableDeclarationStatement(tstl.createAnonymousIdentifier(), result); } public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { @@ -4210,10 +4206,7 @@ export class LuaTransformer { const logCall1 = tstl.createCallExpression(log1, params); const e = tstl.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); const div = tstl.createBinaryExpression(logCall1, e, tstl.SyntaxKind.DivisionOperator); - return ts.isExpressionStatement(node.parent) - ? // if used as a stand-alone statement, needs to be a call expression to be valid lua - this.createImmediatelyInvokedFunctionExpression([], div, node) - : tstl.createParenthesizedExpression(div, node); + return tstl.createParenthesizedExpression(div, node); } // math.log(1 + x) diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 559ff3606..a2e902352 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -97,18 +97,18 @@ test.each([ }); test.each([ - { input: "~a", lua: "local ____ = bit.bnot(a)" }, - { input: "a&b", lua: "local ____ = bit.band(a, b)" }, + { input: "~a", lua: "bit.bnot(a)" }, + { input: "a&b", lua: "bit.band(a, b)" }, { input: "a&=b", lua: "a = bit.band(a, b)" }, - { input: "a|b", lua: "local ____ = bit.bor(a, b)" }, + { input: "a|b", lua: "bit.bor(a, b)" }, { input: "a|=b", lua: "a = bit.bor(a, b)" }, - { input: "a^b", lua: "local ____ = bit.bxor(a, b)" }, + { input: "a^b", lua: "bit.bxor(a, b)" }, { input: "a^=b", lua: "a = bit.bxor(a, b)" }, - { input: "a<>b", lua: "local ____ = bit.arshift(a, b)" }, + { input: "a>>b", lua: "bit.arshift(a, b)" }, { input: "a>>=b", lua: "a = bit.arshift(a, b)" }, - { input: "a>>>b", lua: "local ____ = bit.rshift(a, b)" }, + { input: "a>>>b", lua: "bit.rshift(a, b)" }, { input: "a>>>=b", lua: "a = bit.rshift(a, b)" }, ])("Bitop [JIT] (%p)", ({ input, lua }) => { const options = { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.None }; @@ -116,18 +116,18 @@ test.each([ }); test.each([ - { input: "~a", lua: "local ____ = bit32.bnot(a)" }, - { input: "a&b", lua: "local ____ = bit32.band(a, b)" }, + { input: "~a", lua: "bit32.bnot(a)" }, + { input: "a&b", lua: "bit32.band(a, b)" }, { input: "a&=b", lua: "a = bit32.band(a, b)" }, - { input: "a|b", lua: "local ____ = bit32.bor(a, b)" }, + { input: "a|b", lua: "bit32.bor(a, b)" }, { input: "a|=b", lua: "a = bit32.bor(a, b)" }, - { input: "a^b", lua: "local ____ = bit32.bxor(a, b)" }, + { input: "a^b", lua: "bit32.bxor(a, b)" }, { input: "a^=b", lua: "a = bit32.bxor(a, b)" }, - { input: "a<>b", lua: "local ____ = bit32.arshift(a, b)" }, + { input: "a>>b", lua: "bit32.arshift(a, b)" }, { input: "a>>=b", lua: "a = bit32.arshift(a, b)" }, - { input: "a>>>b", lua: "local ____ = bit32.rshift(a, b)" }, + { input: "a>>>b", lua: "bit32.rshift(a, b)" }, { input: "a>>>=b", lua: "a = bit32.rshift(a, b)" }, ])("Bitop [5.2] (%p)", ({ input, lua }) => { const options = { luaTarget: tstl.LuaTarget.Lua52, luaLibImport: tstl.LuaLibImportKind.None }; @@ -518,6 +518,7 @@ test.each([ "foo as Function", "Math.log2(2)", "Math.log10(2)", + '"".indexOf("")', ])("Expression statements (%p)", input => { const code = ` function foo() { return 17; } diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts index 9ff3442f7..84b1b071f 100644 --- a/test/unit/math.spec.ts +++ b/test/unit/math.spec.ts @@ -5,8 +5,8 @@ test.each([ { inp: "Math.sin()", expected: "math.sin()" }, { inp: "Math.min()", expected: "math.min()" }, { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3)" }, - { inp: "Math.log2(3)", expected: `(function() return math.log(3) / ${Math.LN2} end)()` }, - { inp: "Math.log10(3)", expected: `(function() return math.log(3) / ${Math.LN10} end)()` }, + { inp: "Math.log2(3)", expected: `local ____ = (math.log(3) / ${Math.LN2})` }, + { inp: "Math.log10(3)", expected: `local ____ = (math.log(3) / ${Math.LN10})` }, { inp: "const x = Math.log2(3)", expected: `local x = (math.log(3) / ${Math.LN2})` }, { inp: "const x = Math.log10(3)", expected: `local x = (math.log(3) / ${Math.LN10})` }, { inp: "Math.log1p(3)", expected: "math.log(1 + 3)" }, From 19db39c93cfc1a7b79c594d696f66aa7b4d5e439 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 26 Jul 2019 07:09:39 -0600 Subject: [PATCH 150/764] isNumberType union recursion (#692) fixes #687 This updates `isNumberType` to match the behavior of `isStringType`, recursing into unions and intersections. This fixes issues where enum values were not seen as numeric types when used as array indexes. --- src/LuaTransformer.ts | 20 +++++++++++++++----- src/TSHelper.ts | 37 ++++++++++++++++++++++++------------- test/unit/enum.spec.ts | 31 +++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e1d48fc46..bef4e0a1a 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2505,7 +2505,11 @@ export class LuaTransformer { ); } - if (statement.expression.arguments.some(a => !tsHelper.isNumberType(this.checker.getTypeAtLocation(a)))) { + if ( + statement.expression.arguments.some( + a => !tsHelper.isNumberType(this.checker.getTypeAtLocation(a), this.checker, this.program) + ) + ) { throw TSTLErrors.InvalidForRangeCall(statement.expression, "@forRange arguments must be number types."); } @@ -2522,7 +2526,7 @@ export class LuaTransformer { } const controlType = this.checker.getTypeAtLocation(controlDeclaration); - if (controlType && !tsHelper.isNumberType(controlType)) { + if (controlType && !tsHelper.isNumberType(controlType, this.checker, this.program)) { throw TSTLErrors.InvalidForRangeCall( statement.expression, "@forRange function must return Iterable or Array." @@ -3860,7 +3864,7 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.Number, node, ...parameters); case "isNaN": case "isFinite": - const numberParameters = tsHelper.isNumberType(expressionType) + const numberParameters = tsHelper.isNumberType(expressionType, this.checker, this.program) ? parameters : [this.transformLuaLibFunction(LuaLibFeature.Number, undefined, ...parameters)]; @@ -4295,7 +4299,10 @@ export class LuaTransformer { const index = this.transformExpression(expression.argumentExpression); const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isNumberType(argumentType) && tsHelper.isArrayType(type, this.checker, this.program)) { + if ( + tsHelper.isNumberType(argumentType, this.checker, this.program) && + tsHelper.isArrayType(type, this.checker, this.program) + ) { return this.expressionPlusOne(index); } else { return index; @@ -4315,7 +4322,10 @@ export class LuaTransformer { const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isNumberType(argumentType) && tsHelper.isStringType(type, this.checker, this.program)) { + if ( + tsHelper.isNumberType(argumentType, this.checker, this.program) && + tsHelper.isStringType(type, this.checker, this.program) + ) { const index = this.transformExpression(expression.argumentExpression); return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")), diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 53a594dc3..d616ed6c6 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -132,34 +132,45 @@ export function isStaticNode(node: ts.Node): boolean { return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); } -export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { +export function isTypeWithFlags( + type: ts.Type, + flags: ts.TypeFlags, + checker: ts.TypeChecker, + program: ts.Program +): boolean { if (type.symbol) { const baseConstraint = checker.getBaseConstraintOfType(type); if (baseConstraint && baseConstraint !== type) { - return isStringType(baseConstraint, checker, program); + return isTypeWithFlags(baseConstraint, flags, checker, program); } } if (type.isUnion()) { - return type.types.every(t => isStringType(t, checker, program)); + return type.types.every(t => isTypeWithFlags(t, flags, checker, program)); } if (type.isIntersection()) { - return type.types.some(t => isStringType(t, checker, program)); + return type.types.some(t => isTypeWithFlags(t, flags, checker, program)); } - return ( - (type.flags & ts.TypeFlags.String) !== 0 || - (type.flags & ts.TypeFlags.StringLike) !== 0 || - (type.flags & ts.TypeFlags.StringLiteral) !== 0 + return (type.flags & flags) !== 0; +} + +export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + return isTypeWithFlags( + type, + ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral, + checker, + program ); } -export function isNumberType(type: ts.Type): boolean { - return ( - (type.flags & ts.TypeFlags.Number) !== 0 || - (type.flags & ts.TypeFlags.NumberLike) !== 0 || - (type.flags & ts.TypeFlags.NumberLiteral) !== 0 +export function isNumberType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { + return isTypeWithFlags( + type, + ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral, + checker, + program ); } diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index bd40f2619..219927f41 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -196,3 +196,34 @@ test("enum concat", () => { return test + "_foobar";`; expect(util.transpileAndExecute(code)).toBe("0_foobar"); }); + +test("enum value as array index", () => { + const code = ` + enum TestEnum { + A, + B, + C, + } + const arr = ["a", "b", "c"]; + let i = TestEnum.A; + return arr[i];`; + expect(util.transpileAndExecute(code)).toBe("a"); +}); + +test("enum property value as array index", () => { + const code = ` + enum TestEnum { + A, + B, + C, + } + + class Foo { + i = TestEnum.A; + } + const foo = new Foo(); + + const arr = ["a", "b", "c"]; + return arr[foo.i];`; + expect(util.transpileAndExecute(code)).toBe("a"); +}); From ef7e0276baff74c4a1500a22af2110e7dd417608 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 26 Jul 2019 11:02:19 -0600 Subject: [PATCH 151/764] @noSelf changed to not affect merged namespaces (#689) --- src/TSHelper.ts | 32 +++++++++++-------- test/unit/assignments/functionPermutations.ts | 32 +++++++++++++++++++ 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/src/TSHelper.ts b/src/TSHelper.ts index d616ed6c6..10306e332 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -348,19 +348,25 @@ export function getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map return decMap; } +export function getCustomNodeDirectives(node: ts.Node): Map { + const directivesMap = new Map(); + + ts.getJSDocTags(node).forEach(tag => { + const tagName = tag.tagName.escapedText as string; + if (Decorator.isValid(tagName)) { + const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); + directivesMap.set(dec.kind, dec); + } + }); + + return directivesMap; +} + export function getCustomFileDirectives(file: ts.SourceFile): Map { - const decMap = new Map(); if (file.statements.length > 0) { - const tags = ts.getJSDocTags(file.statements[0]); - for (const tag of tags) { - const tagName = tag.tagName.escapedText as string; - if (Decorator.isValid(tagName)) { - const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); - decMap.set(dec.kind, dec); - } - } + return getCustomNodeDirectives(file.statements[0]); } - return decMap; + return new Map(); } export function getCustomSignatureDirectives( @@ -607,8 +613,7 @@ export function hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeC if (ts.isSourceFile(scopeDeclaration)) { return getCustomFileDirectives(scopeDeclaration).has(DecoratorKind.NoSelfInFile); } - const scopeType = checker.getTypeAtLocation(scopeDeclaration); - if (scopeType && getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { + if (getCustomNodeDirectives(scopeDeclaration).has(DecoratorKind.NoSelf)) { return true; } return hasNoSelfAncestor(scopeDeclaration, checker); @@ -645,8 +650,7 @@ export function getDeclarationContextType( return ContextType.NonVoid; } - const scopeType = checker.getTypeAtLocation(scopeDeclaration); - if (scopeType && getCustomDecorators(scopeType, checker).has(DecoratorKind.NoSelf)) { + if (getCustomNodeDirectives(scopeDeclaration).has(DecoratorKind.NoSelf)) { return ContextType.Void; } return ContextType.NonVoid; diff --git a/test/unit/assignments/functionPermutations.ts b/test/unit/assignments/functionPermutations.ts index cbbef188e..2602e2ba7 100644 --- a/test/unit/assignments/functionPermutations.ts +++ b/test/unit/assignments/functionPermutations.ts @@ -133,6 +133,22 @@ export const selfTestFunctions: TestFunction[] = [ } const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();`, }, + { + value: "anonMethodClassMergedNoSelfNS.method", + definition: `class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();`, + }, + { + value: "AnonFuncNSMergedNoSelfClass.nsFunc", + definition: `/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }`, + }, + { + value: "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf", + definition: `namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }`, + }, ]; export const noSelfTestFunctions: TestFunction[] = [ @@ -263,6 +279,22 @@ export const noSelfTestFunctions: TestFunction[] = [ const anonFunctionNestedInClassInNoSelfNs = (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();`, }, + { + value: "noSelfAnonMethodClassMergedNS.method", + definition: `/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();`, + }, + { + value: "NoSelfAnonFuncNSMergedClass.nsFunc", + definition: `class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }`, + }, + { + value: "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf", + definition: `namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }`, + }, ]; const noSelfInFileTestFunctions: TestFunction[] = [ From d7f76fb633453f1b5113eb4f84a4eed51d4ad4ba Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sat, 27 Jul 2019 22:15:44 +1000 Subject: [PATCH 152/764] Assignment binding patterns (#677) * Binding pattern assigment support * Optimize destructuring for flat arrays * Move assignment destructure rhs transform down * Remove unnessessary assignment array length check * Add default destructure array assignment test * Add destructure non-default destructure array test * Add non-default destructure binary expression test * Add tsHelper.isAssignmentPattern * Revert transformExpressionStatement change * Revert whitespace change in transformExpressionStatement --- src/LuaTransformer.ts | 350 +++++++++++++++++++++++++----- src/TSHelper.ts | 48 +++- src/TSTLErrors.ts | 3 + test/unit/bindingpatterns.spec.ts | 107 +++++++++ 4 files changed, 443 insertions(+), 65 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index bef4e0a1a..ca398ba4c 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3032,7 +3032,18 @@ export class LuaTransformer { } } - protected transformAssignment(lhs: ts.Expression, right?: tstl.Expression): tstl.Statement { + protected transformAssignment(lhs: ts.Expression, right: tstl.Expression, parent?: ts.Expression): tstl.Statement { + if (tsHelper.isArrayLength(lhs, this.checker, this.program)) { + return tstl.createExpressionStatement( + this.transformLuaLibFunction( + LuaLibFeature.ArraySetLength, + parent, + this.transformExpression(lhs.expression), + right + ) + ); + } + return tstl.createAssignmentStatement( this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression, right, @@ -3047,44 +3058,283 @@ export class LuaTransformer { this.validateFunctionAssignment(expression.right, rightType, leftType); this.validatePropertyAssignment(expression); - if (tsHelper.isArrayLengthAssignment(expression, this.checker, this.program)) { - // array.length = x - return tstl.createExpressionStatement( - this.transformLuaLibFunction( - LuaLibFeature.ArraySetLength, - expression, - this.transformExpression(expression.left.expression), - this.transformExpression(expression.right) - ) + if (tsHelper.isAssignmentPattern(expression.left)) { + // Destructuring assignment + const flattenable = tsHelper.isValidFlattenableDestructuringAssignmentLeftHandSide( + expression as ts.DestructuringAssignment, + this.checker, + this.program ); - } - if (ts.isArrayLiteralExpression(expression.left)) { - // Destructuring assignment - const left = - expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformArrayBindingElement(e)) - : [tstl.createAnonymousIdentifier(expression.left)]; - let right: tstl.Expression[]; - if (ts.isArrayLiteralExpression(expression.right)) { - if (expression.right.elements.length > 0) { - const visitResults = expression.right.elements.map(e => this.transformExpression(e)); - right = this.filterUndefined(visitResults); - } else { - right = [tstl.createNilLiteral()]; + if (flattenable) { + const expressionType = this.checker.getTypeAtLocation(expression.right); + let right = this.transformExpression(expression.right); + + if ( + !tsHelper.isTupleReturnCall(expression.right, this.checker) && + tsHelper.isArrayType(expressionType, this.checker, this.program) + ) { + right = this.createUnpackCall(right, expression.right); } - } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = [this.transformExpression(expression.right)]; - } else { - right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; + + return this.transformFlattenableDestructuringAssignment( + expression as ts.DestructuringAssignment, + right + ); + } + + let right = this.transformExpression(expression.right); + const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); + + if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { + right = this.wrapInTable(right); } - return tstl.createAssignmentStatement(left as tstl.AssignmentLeftHandSideExpression[], right, expression); + + const rootDeclaration = tstl.createVariableDeclarationStatement(rootIdentifier, right); + + const statements = this.transformDestructuringAssignment( + expression as ts.DestructuringAssignment, + rootIdentifier + ); + statements.unshift(rootDeclaration); + + return statements; } else { // Simple assignment return this.transformAssignment(expression.left, this.transformExpression(expression.right)); } } + protected transformFlattenableDestructuringAssignment( + node: ts.DestructuringAssignment, + right: tstl.Expression | tstl.Expression[] + ): tstl.Statement { + if (ts.isArrayLiteralExpression(node.left)) { + const left: tstl.AssignmentLeftHandSideExpression[] = node.left.elements.map( + element => this.transformExpression(element) as tstl.AssignmentLeftHandSideExpression + ); + return tstl.createAssignmentStatement(left, right, node); + } + + throw TSTLErrors.NonFlattenableDestructure(node); + } + + protected transformDestructuringAssignment( + node: ts.DestructuringAssignment, + root: tstl.Expression + ): tstl.Statement[] { + switch (node.left.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: + return this.transformObjectDestructuringAssignment(node as ts.ObjectDestructuringAssignment, root); + case ts.SyntaxKind.ArrayLiteralExpression: + return this.transformArrayDestructuringAssignment(node as ts.ArrayDestructuringAssignment, root); + } + } + + protected transformObjectDestructuringAssignment( + node: ts.ObjectDestructuringAssignment, + root: tstl.Expression + ): tstl.Statement[] { + return this.transformObjectLiteralAssignmentPattern(node.left, root); + } + + protected transformArrayDestructuringAssignment( + node: ts.ArrayDestructuringAssignment, + root: tstl.Expression + ): tstl.Statement[] { + return this.transformArrayLiteralAssignmentPattern(node.left, root); + } + + protected transformShorthandPropertyAssignment( + node: ts.ShorthandPropertyAssignment, + root: tstl.Expression + ): tstl.Statement[] { + const result: tstl.Statement[] = []; + const assignmentVariableName = this.transformIdentifier(node.name); + const extractionIndex = tstl.createStringLiteral(node.name.text); + const variableExtractionAssignmentStatement = tstl.createAssignmentStatement( + assignmentVariableName, + tstl.createTableIndexExpression(root, extractionIndex) + ); + + result.push(variableExtractionAssignmentStatement); + + const defaultInitializer = node.objectAssignmentInitializer + ? this.transformExpression(node.objectAssignmentInitializer) + : undefined; + + if (defaultInitializer) { + const nilCondition = tstl.createBinaryExpression( + assignmentVariableName, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ); + + const assignment = tstl.createAssignmentStatement(assignmentVariableName, defaultInitializer); + + const ifBlock = tstl.createBlock([assignment]); + + result.push(tstl.createIfStatement(nilCondition, ifBlock, undefined, node)); + } + + return result; + } + + protected transformObjectLiteralAssignmentPattern( + node: ts.ObjectLiteralExpression, + root: tstl.Expression + ): tstl.Statement[] { + const result: tstl.Statement[] = []; + + for (const property of node.properties) { + switch (property.kind) { + case ts.SyntaxKind.ShorthandPropertyAssignment: + result.push(...this.transformShorthandPropertyAssignment(property, root)); + break; + case ts.SyntaxKind.PropertyAssignment: + result.push(...this.transformPropertyAssignment(property, root)); + break; + case ts.SyntaxKind.SpreadAssignment: + throw TSTLErrors.ForbiddenEllipsisDestruction(property); + default: + throw TSTLErrors.UnsupportedKind("Object Destructure Property", property.kind, property); + } + } + + return result; + } + + protected transformArrayLiteralAssignmentPattern( + node: ts.ArrayLiteralExpression, + root: tstl.Expression + ): tstl.Statement[] { + const result: tstl.Statement[] = []; + + node.elements.forEach((element, index) => { + const indexedRoot = tstl.createTableIndexExpression( + root as tstl.Expression, + tstl.createNumericLiteral(index + 1), + element + ); + + switch (element.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: + result.push( + ...this.transformObjectLiteralAssignmentPattern( + element as ts.ObjectLiteralExpression, + indexedRoot + ) + ); + break; + case ts.SyntaxKind.ArrayLiteralExpression: + result.push( + ...this.transformArrayLiteralAssignmentPattern( + element as ts.ArrayLiteralExpression, + indexedRoot + ) + ); + break; + case ts.SyntaxKind.BinaryExpression: + const assignedVariable = tstl.createIdentifier("____bindingAssignmentValue"); + + const assignedVariableDeclaration = tstl.createVariableDeclarationStatement( + assignedVariable, + indexedRoot + ); + + const nilCondition = tstl.createBinaryExpression( + assignedVariable, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ); + + const defaultAssignmentStatement = this.transformAssignment( + (element as ts.BinaryExpression).left, + this.transformExpression((element as ts.BinaryExpression).right) + ); + + const elseAssignmentStatement = this.transformAssignment( + (element as ts.BinaryExpression).left, + assignedVariable + ); + + const ifBlock = tstl.createBlock([defaultAssignmentStatement]); + + const elseBlock = tstl.createBlock([elseAssignmentStatement]); + + const ifStatement = tstl.createIfStatement(nilCondition, ifBlock, elseBlock, node); + + result.push(assignedVariableDeclaration); + result.push(ifStatement); + break; + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + const assignmentStatement = this.transformAssignment(element, indexedRoot); + + result.push(assignmentStatement); + break; + case ts.SyntaxKind.OmittedExpression: + break; + default: + throw TSTLErrors.UnsupportedKind("Array Destructure Assignment Element", element.kind, element); + } + }); + + return result; + } + + protected transformPropertyAssignment(node: ts.PropertyAssignment, root: tstl.Expression): tstl.Statement[] { + const result: tstl.Statement[] = []; + + if (tsHelper.isAssignmentPattern(node.initializer)) { + const propertyAccessString = this.transformPropertyName(node.name); + const newRootAccess = tstl.createTableIndexExpression(root, propertyAccessString); + + if (ts.isObjectLiteralExpression(node.initializer)) { + return this.transformObjectLiteralAssignmentPattern(node.initializer, newRootAccess); + } + + if (ts.isArrayLiteralExpression(node.initializer)) { + return this.transformArrayLiteralAssignmentPattern(node.initializer, newRootAccess); + } + } + + let leftExpression: ts.Expression; + if (ts.isBinaryExpression(node.initializer)) { + leftExpression = node.initializer.left; + } else { + leftExpression = node.initializer; + } + + const variableToExtract = this.transformPropertyName(node.name); + const extractingExpression = tstl.createTableIndexExpression(root, variableToExtract); + + const destructureAssignmentStatement = this.transformAssignment(leftExpression, extractingExpression); + + result.push(destructureAssignmentStatement); + + if (ts.isBinaryExpression(node.initializer)) { + const assignmentLeftHandSide = this.transformExpression(node.initializer.left); + + const nilCondition = tstl.createBinaryExpression( + assignmentLeftHandSide, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ); + + const assignmentStatements = this.statementVisitResultToArray( + this.transformAssignmentStatement(node.initializer) + ); + + const ifBlock = tstl.createBlock(assignmentStatements); + + result.push(tstl.createIfStatement(nilCondition, ifBlock, undefined, node)); + } + + return result; + } + protected transformAssignmentExpression( expression: ts.BinaryExpression ): tstl.CallExpression | tstl.MethodCallExpression { @@ -3093,7 +3343,7 @@ export class LuaTransformer { const leftType = this.checker.getTypeAtLocation(expression.left); this.validateFunctionAssignment(expression.right, rightType, leftType); - if (tsHelper.isArrayLengthAssignment(expression, this.checker, this.program)) { + if (tsHelper.isArrayLength(expression.left, this.checker, this.program)) { // array.length = x return this.transformLuaLibFunction( LuaLibFeature.ArraySetLength, @@ -3103,34 +3353,24 @@ export class LuaTransformer { ); } - if (ts.isArrayLiteralExpression(expression.left)) { + if (tsHelper.isAssignmentPattern(expression.left)) { // Destructuring assignment - // (function() local ${tmps} = ${right}; ${left} = ${tmps}; return {${tmps}} end)() - const left = - expression.left.elements.length > 0 - ? expression.left.elements.map(e => this.transformExpression(e)) - : [tstl.createAnonymousIdentifier(expression.left)]; - let right: tstl.Expression[]; - if (ts.isArrayLiteralExpression(expression.right)) { - right = - expression.right.elements.length > 0 - ? expression.right.elements.map(e => this.transformExpression(e)) - : [tstl.createNilLiteral()]; - } else if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = [this.transformExpression(expression.right)]; - } else { - right = [this.createUnpackCall(this.transformExpression(expression.right), expression.right)]; + const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); + + let right = this.transformExpression(expression.right); + if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { + right = this.wrapInTable(right); } - const tmps = left.map((_, i) => tstl.createIdentifier(`____tmp${i}`)); - const statements: tstl.Statement[] = [ - tstl.createVariableDeclarationStatement(tmps, right), - tstl.createAssignmentStatement(left as tstl.AssignmentLeftHandSideExpression[], tmps), - ]; - return this.createImmediatelyInvokedFunctionExpression( - statements, - tstl.createTableExpression(tmps.map(t => tstl.createTableFieldExpression(t))), - expression + + const rootDeclaration = tstl.createVariableDeclarationStatement(rootIdentifier, right); + + const statements = this.transformDestructuringAssignment( + expression as ts.DestructuringAssignment, + rootIdentifier ); + statements.unshift(rootDeclaration); + + return this.createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 10306e332..d6819007f 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -53,6 +53,10 @@ export function getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.T return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode); } +export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { + return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); +} + export function isFileModule(sourceFile: ts.SourceFile): boolean { return sourceFile.statements.some(isStatementExported); } @@ -880,27 +884,51 @@ export function moduleHasEmittedBody( return false; } -export function isArrayLengthAssignment( - expression: ts.BinaryExpression, +export function isValidFlattenableDestructuringAssignmentLeftHandSide( + node: ts.DestructuringAssignment, checker: ts.TypeChecker, program: ts.Program -): expression is ts.BinaryExpression & { left: ts.PropertyAccessExpression | ts.ElementAccessExpression } { - if (expression.operatorToken.kind !== ts.SyntaxKind.EqualsToken) { - return false; +): boolean { + if (ts.isArrayLiteralExpression(node.left)) { + if (node.left.elements.length > 0) { + return !node.left.elements.some(element => { + switch (element.kind) { + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: + if (isArrayLength(element, checker, program)) { + return true; + } + case ts.SyntaxKind.ElementAccessExpression: + // Can be on the left hand side of a Lua assignment statement + return false; + default: + // Cannot be + return true; + } + }); + } } - if (!ts.isPropertyAccessExpression(expression.left) && !ts.isElementAccessExpression(expression.left)) { + return false; +} + +export function isArrayLength( + expression: ts.Expression, + checker: ts.TypeChecker, + program: ts.Program +): expression is ts.PropertyAccessExpression | ts.ElementAccessExpression { + if (!ts.isPropertyAccessExpression(expression) && !ts.isElementAccessExpression(expression)) { return false; } - const type = checker.getTypeAtLocation(expression.left.expression); + const type = checker.getTypeAtLocation(expression.expression); if (!isArrayType(type, checker, program)) { return false; } - const name = ts.isPropertyAccessExpression(expression.left) - ? (expression.left.name.escapedText as string) - : ts.isStringLiteral(expression.left.argumentExpression) && expression.left.argumentExpression.text; + const name = ts.isPropertyAccessExpression(expression) + ? (expression.name.escapedText as string) + : ts.isStringLiteral(expression.argumentExpression) && expression.argumentExpression.text; return name === "length"; } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index cc351f2b7..054c89425 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -90,6 +90,9 @@ export const MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => export const MissingMetaExtension = (node: ts.Node) => new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); +export const NonFlattenableDestructure = (node: ts.Node) => + new TranspileError(`This node cannot be destructured using a standard Lua assignment statement.`, node); + export const UndefinedFunctionDefinition = (functionSymbolId: number) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); diff --git a/test/unit/bindingpatterns.spec.ts b/test/unit/bindingpatterns.spec.ts index aad38661b..39684ae50 100644 --- a/test/unit/bindingpatterns.spec.ts +++ b/test/unit/bindingpatterns.spec.ts @@ -18,6 +18,8 @@ const testCases = [ const testCasesDefault = [ { bindingString: "{x = true}", objectString: "{}", returnVariable: "x" }, { bindingString: "{x, y = true}", objectString: "{x: false}", returnVariable: "y" }, + { bindingString: "[x = true, y = false]", objectString: "[undefined, undefined]", returnVariable: "x" }, + { bindingString: "[x = false, y = false]", objectString: "[false, true]", returnVariable: "y" }, ]; test.each([ @@ -82,3 +84,108 @@ test.each([ ); expect(result).toBe(false); }); + +const assignmentBindingPatterns = [ + { bindingString: "{x: obj.prop}", objectString: "{x: true}", returnVariable: "obj.prop" }, + { + bindingString: "{x: obj.prop = true}", + objectString: "{x: undefined}", + returnVariable: "obj.prop", + }, + { bindingString: "[{x: obj.prop}]", objectString: "[{x: true}]", returnVariable: "obj.prop" }, + { + bindingString: "{obj: {prop: obj.prop}}", + objectString: "{obj: {prop: true}}", + returnVariable: "obj.prop", + }, + { bindingString: "{x = true}", objectString: "{}", returnVariable: "x" }, + { + bindingString: "{x: {[2 + 1]: y}}", + objectString: "{x: {[2 + 1]: true}}", + returnVariable: "y", + }, +]; + +test.each([...assignmentBindingPatterns, ...testCases])( + "Binding pattern expressions (%p)", + ({ bindingString, objectString, returnVariable }) => { + const result = util.transpileAndExecute(` + let x, y, z, foo, bar, obj: { prop: boolean }; + obj = { prop: false }; + (${bindingString} = ${objectString}) + return ${returnVariable}; + `); + expect(result).toBe(true); + } +); + +test.each([...assignmentBindingPatterns, ...testCases])( + "Binding patterns expressions pass conditional checks (%p)", + ({ bindingString, objectString, returnVariable }) => { + const result = util.transpileAndExecute(` + let x, y, z, foo, bar, obj: { prop: boolean }; + obj = { prop: false }; + if (${bindingString} = ${objectString}) { + return ${returnVariable}; + } + `); + expect(result).toBe(true); + } +); + +test.each([ + { bindingString: "{ x: x.prop = true } = {}", returnValue: "x.prop", expectedResult: true }, + { + bindingString: "{ x: x.prop = true } = {}", + returnValue: "typeof y === 'object'", + expectedResult: true, + }, + { + bindingString: "{ x: x.prop = false } = { x: true }", + returnValue: "x.prop", + expectedResult: true, + }, +])("Binding pattern assignment pass-through (%p)", ({ bindingString, returnValue, expectedResult }) => { + const result = util.transpileAndExecute(` + let x: any = {}, y: any = {}; + y = ${bindingString}; + return ${returnValue}; + `); + expect(result).toBe(expectedResult); +}); + +test("Array binding pattern to assign array length (%p)", () => { + const result = util.transpileAndExecute(` + let x = [0, 1, 2]; + [x.length] = [0]; + return x.length; + `); + expect(result).toBe(0); +}); + +test("Nested array binding pattern to assign array length (%p)", () => { + const result = util.transpileAndExecute(` + let x = [0, 1, 2]; + [[x.length]] = [[0]]; + return x.length; + `); + expect(result).toBe(0); +}); + +test("Object binding pattern to assign array length (%p)", () => { + const result = util.transpileAndExecute(` + let x = [0, 1, 2]; + ({ x: x.length } = { x: 0 }); + return x.length; + `); + expect(result).toBe(0); +}); + +test("Nested object binding pattern to assign array length (%p)", () => { + const result = util.transpileAndExecute(` + let x = [0, 1, 2]; + ({ x: { x: x.length } } = { x: { x: 0 } }); + return x.length; + `); + expect(result).toBe(0); +}); From 2c47c3ba32ca850c19f0f7fba27152cd2eebce7c Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 29 Jul 2019 02:12:30 +1000 Subject: [PATCH 153/764] Export default and export equals (#670) * Fix import and export bugs * Fix spelling mistake * Add full import and export support * Remove exportedIdentifier stringliteral change * Fix export default from use case * Move default export modifier checking to tsHelper * Remove duplicate test * Add export equals test, fix require test formatting * Fix hasDefaultExportModifier return type * Enable export default to work on name-less classes * Fix public and protected method signatures for import and export methods * Make default class declaration expressions use default as name * Make export equals transform to a local statement * Add undefined condition if export equals is ellidable * Inline isExportable with getExportable * Move visitedExportEquals to setupState * Merge class tests and ensure classes retain their names * Change transformExportSpecifier to protected * Make importSpecifier protected and use if statement instead of nested ternary --- src/LuaTransformer.ts | 538 ++++++++++-------- src/TSHelper.ts | 96 ++++ src/TSTLErrors.ts | 6 - .../__snapshots__/transformation.spec.ts.snap | 10 + .../transformation/exportEquals.ts | 1 + .../unusedDefaultWithNamespaceImport.ts | 2 + test/unit/modules.spec.ts | 17 - test/unit/require.spec.ts | 145 +++++ test/util.ts | 41 ++ 9 files changed, 599 insertions(+), 257 deletions(-) create mode 100644 test/translation/transformation/exportEquals.ts create mode 100644 test/translation/transformation/unusedDefaultWithNamespaceImport.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index ca398ba4c..9343b3447 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "./CompilerOptions"; -import { Decorator, DecoratorKind } from "./Decorator"; +import { DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import { LuaLibFeature } from "./LuaLib"; import * as tsHelper from "./TSHelper"; @@ -79,6 +79,8 @@ export class LuaTransformer { protected genVarCounter!: number; protected luaLibFeatureSet!: Set; + protected visitedExportEquals!: boolean; + protected scopeStack!: Scope[]; protected classStack!: ts.ClassLikeDeclaration[]; @@ -90,6 +92,8 @@ export class LuaTransformer { this.genVarCounter = 0; this.luaLibFeatureSet = new Set(); + this.visitedExportEquals = false; + this.scopeStack = []; this.classStack = []; @@ -132,13 +136,16 @@ export class LuaTransformer { this.popScope(); if (this.isModule) { + // If export equals was not used. Create the exports table. // local exports = {} - statements.unshift( - tstl.createVariableDeclarationStatement( - this.createExportsIdentifier(), - tstl.createTableExpression() - ) - ); + if (!this.visitedExportEquals) { + statements.unshift( + tstl.createVariableDeclarationStatement( + this.createExportsIdentifier(), + tstl.createTableExpression() + ) + ); + } // return exports statements.push(tstl.createReturnStatement([this.createExportsIdentifier()])); @@ -159,6 +166,8 @@ export class LuaTransformer { case ts.SyntaxKind.Block: return this.transformBlockAsDoStatement(node as ts.Block); // Declaration Statements + case ts.SyntaxKind.ExportAssignment: + return this.transformExportAssignment(node as ts.ExportAssignment); case ts.SyntaxKind.ExportDeclaration: return this.transformExportDeclaration(node as ts.ExportDeclaration); case ts.SyntaxKind.ImportDeclaration: @@ -238,140 +247,163 @@ export class LuaTransformer { return tstl.createDoStatement(statements, block); } + public transformExportAssignment(statement: ts.ExportAssignment): StatementVisitResult { + if (!this.resolver.isValueAliasDeclaration(statement)) { + return undefined; + } + + // export = [expression]; + // ____exports = [expression]; + if (statement.isExportEquals) { + // Stop the creation of the exports table. + // This should be the only export of the module. + this.visitedExportEquals = true; + + return tstl.createVariableDeclarationStatement( + this.createExportsIdentifier(), + this.transformExpression(statement.expression), + statement + ); + } + + // export default [expression]; + // ____exports.default = [expression]; + const defaultIdentifier = this.createDefaultExportStringLiteral(statement); + return tstl.createAssignmentStatement( + tstl.createTableIndexExpression(this.createExportsIdentifier(), defaultIdentifier), + this.transformExpression(statement.expression), + statement + ); + } + public transformExportDeclaration(statement: ts.ExportDeclaration): StatementVisitResult { if (statement.exportClause) { - if ( - statement.exportClause.elements.some( - e => - (e.name !== undefined && e.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || - (e.propertyName !== undefined && - e.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) - ) - ) { - throw TSTLErrors.UnsupportedDefaultExport(statement); - } - if (!this.resolver.isValueAliasDeclaration(statement)) { return undefined; } - const exportSpecifiers = statement.exportClause.elements.filter(e => - this.resolver.isValueAliasDeclaration(e) - ); + const exportSpecifiers = tsHelper.getExportable(statement.exportClause, this.resolver); + // export { ... }; if (statement.moduleSpecifier === undefined) { - return exportSpecifiers.map(specifier => { - let exportedIdentifier: tstl.Expression | undefined; - if (specifier.propertyName !== undefined) { - exportedIdentifier = this.transformIdentifier(specifier.propertyName); - } else { - const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(specifier); - exportedIdentifier = this.createShorthandIdentifier(exportedSymbol, specifier.name); - } - - return tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(specifier.name)), - exportedIdentifier - ); - }); + return exportSpecifiers.map(exportSpecifier => this.transformExportSpecifier(exportSpecifier)); } - // First transpile as import clause - const importClause = ts.createImportClause( - undefined, - ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) - ); - - const importDeclaration = ts.createImportDeclaration( - statement.decorators, - statement.modifiers, - importClause, - statement.moduleSpecifier - ); - - // Wrap in block to prevent imports from hoisting out of `do` statement - const block = ts.createBlock([importDeclaration]); - const result = this.transformBlock(block).statements; + // export { ... } from "..."; + return this.transformExportSpecifiersFrom(statement, statement.moduleSpecifier, exportSpecifiers); + } else { + // export * from "..."; + return this.transformExportAllFrom(statement); + } + } - // Now the module is imported, add the imports to the export table - for (const specifier of exportSpecifiers) { - result.push( - tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(specifier.name)), - this.transformIdentifier(specifier.name) - ) - ); - } + protected transformExportSpecifier(node: ts.ExportSpecifier): tstl.AssignmentStatement { + const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(node); + const exportedIdentifier = node.propertyName ? node.propertyName : node.name; + const exportedExpression = this.createShorthandIdentifier(exportedSymbol, exportedIdentifier); - // Wrap this in a DoStatement to prevent polluting the scope. - return tstl.createDoStatement(this.filterUndefined(result), statement); - } else { - if (statement.moduleSpecifier === undefined) { - throw TSTLErrors.InvalidExportDeclaration(statement); - } + const isDefault = tsHelper.isDefaultExportSpecifier(node); + const identifierToExport = isDefault + ? this.createDefaultExportIdentifier(node) + : this.transformIdentifier(node.name); + const exportAssignmentLeftHandSide = this.createExportedIdentifier(identifierToExport); - if (!this.resolver.moduleExportsSomeValue(statement.moduleSpecifier)) { - return undefined; - } + return tstl.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); + } - const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); - const tempModuleIdentifier = tstl.createIdentifier("____export"); + protected transformExportSpecifiersFrom( + statement: ts.ExportDeclaration, + moduleSpecifier: ts.Expression, + exportSpecifiers: ts.ExportSpecifier[] + ): tstl.Statement { + // First transpile as import clause + const importClause = ts.createImportClause( + undefined, + ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) + ); - const declaration = tstl.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + const importDeclaration = ts.createImportDeclaration( + statement.decorators, + statement.modifiers, + importClause, + moduleSpecifier + ); - const forKey = tstl.createIdentifier("____exportKey"); - const forValue = tstl.createIdentifier("____exportValue"); + // Wrap in block to prevent imports from hoisting out of `do` statement + const block = ts.createBlock([importDeclaration]); + const result = this.transformBlock(block).statements; - const body = tstl.createBlock([ + // Now the module is imported, add the imports to the export table + for (const specifier of exportSpecifiers) { + result.push( tstl.createAssignmentStatement( - tstl.createTableIndexExpression(this.createExportsIdentifier(), forKey), - forValue - ), - ]); - - const pairsIdentifier = tstl.createIdentifier("pairs"); - const forIn = tstl.createForInStatement( - body, - [tstl.cloneIdentifier(forKey), tstl.cloneIdentifier(forValue)], - [tstl.createCallExpression(pairsIdentifier, [tstl.cloneIdentifier(tempModuleIdentifier)])] + this.createExportedIdentifier(this.transformIdentifier(specifier.name)), + this.transformIdentifier(specifier.name) + ) ); - - // Wrap this in a DoStatement to prevent polluting the scope. - return tstl.createDoStatement([declaration, forIn], statement); } + + // Wrap this in a DoStatement to prevent polluting the scope. + return tstl.createDoStatement(this.filterUndefined(result), statement); } - public transformImportDeclaration(statement: ts.ImportDeclaration): StatementVisitResult { - if (statement.importClause && !statement.importClause.namedBindings) { - throw TSTLErrors.DefaultImportsNotSupported(statement); + protected transformExportAllFrom(statement: ts.ExportDeclaration): tstl.Statement | undefined { + if (statement.moduleSpecifier === undefined) { + throw TSTLErrors.InvalidExportDeclaration(statement); } - const result: tstl.Statement[] = []; + if (!this.resolver.moduleExportsSomeValue(statement.moduleSpecifier)) { + return undefined; + } + + const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); + const tempModuleIdentifier = tstl.createIdentifier("____export"); + + const declaration = tstl.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + const forKey = tstl.createIdentifier("____exportKey"); + const forValue = tstl.createIdentifier("____exportValue"); + + const body = tstl.createBlock([ + tstl.createAssignmentStatement( + tstl.createTableIndexExpression(this.createExportsIdentifier(), forKey), + forValue + ), + ]); + + const pairsIdentifier = tstl.createIdentifier("pairs"); + const forIn = tstl.createForInStatement( + body, + [tstl.cloneIdentifier(forKey), tstl.cloneIdentifier(forValue)], + [tstl.createCallExpression(pairsIdentifier, [tstl.cloneIdentifier(tempModuleIdentifier)])] + ); + + // Wrap this in a DoStatement to prevent polluting the scope. + return tstl.createDoStatement([declaration, forIn], statement); + } + + public transformImportDeclaration(statement: ts.ImportDeclaration): StatementVisitResult { const scope = this.peekScope(); if (scope === undefined) { throw TSTLErrors.UndefinedScope(); } + if (!this.options.noHoisting && !scope.importStatements) { scope.importStatements = []; } - let shouldResolve = true; - const moduleOwnerSymbol = this.checker.getSymbolAtLocation(statement.moduleSpecifier); - if (moduleOwnerSymbol) { - const decorators = new Map(); - tsHelper.collectCustomDecorators(moduleOwnerSymbol, this.checker, decorators); - if (decorators.has(DecoratorKind.NoResolution)) { - shouldResolve = false; - } - } - + const shouldResolve = tsHelper.shouldResolveModulePath(statement.moduleSpecifier, this.checker); const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; const importPath = moduleSpecifier.text.replace(new RegExp('"', "g"), ""); const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); - if (!statement.importClause) { + const result: tstl.Statement[] = []; + + // import "./module"; + // require("module") + if (statement.importClause === undefined) { result.push(tstl.createExpressionStatement(requireCall)); + if (scope.importStatements) { scope.importStatements.push(...result); return undefined; @@ -380,83 +412,103 @@ export class LuaTransformer { } } - const imports = statement.importClause.namedBindings; - if (imports === undefined) { - throw TSTLErrors.UnsupportedImportType(statement.importClause); - } + // Create the require statement to extract values. + // local ____module = require("module") + const tstlIdentifier = (name: string) => "____" + tsHelper.fixInvalidLuaIdentifier(name); + const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename(importPath))); + const requireStatement = tstl.createVariableDeclarationStatement( + tstl.createIdentifier(tstlIdentifier(path.basename(importPath))), + requireCall, + statement + ); - if (ts.isNamedImports(imports)) { - const filteredElements = imports.elements.filter(e => { - const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(e), this.checker); - return ( - this.resolver.isReferencedAliasDeclaration(e) && - !decorators.has(DecoratorKind.Extension) && - !decorators.has(DecoratorKind.MetaExtension) + let usingRequireStatement = false; + + // import defaultValue from "./module"; + // local defaultValue = __module.default + if (statement.importClause.name) { + if (tsHelper.shouldBeImported(statement.importClause, this.checker, this.resolver)) { + const propertyName = this.createDefaultExportStringLiteral(statement.importClause.name); + const defaultImportAssignmentStatement = tstl.createVariableDeclarationStatement( + this.transformIdentifier(statement.importClause.name), + tstl.createTableIndexExpression(importUniqueName, propertyName), + statement.importClause.name ); - }); - // Elide import if all imported types are extension classes - if (filteredElements.length === 0) { - return undefined; + result.push(defaultImportAssignmentStatement); + usingRequireStatement = true; } + } - const tstlIdentifier = (name: string) => "____" + tsHelper.fixInvalidLuaIdentifier(name); - const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename(importPath))); - const requireStatement = tstl.createVariableDeclarationStatement( - tstl.createIdentifier(tstlIdentifier(path.basename(importPath))), - requireCall, - statement - ); - result.push(requireStatement); - - filteredElements.forEach(importSpecifier => { - if (importSpecifier.propertyName) { - const propertyName = this.transformPropertyName(importSpecifier.propertyName); - const renamedImport = tstl.createVariableDeclarationStatement( - this.transformIdentifier(importSpecifier.name), - tstl.createTableIndexExpression(importUniqueName, propertyName), - importSpecifier - ); - result.push(renamedImport); - } else { - const name = tstl.createStringLiteral(importSpecifier.name.text); - const namedImport = tstl.createVariableDeclarationStatement( - this.transformIdentifier(importSpecifier.name), - tstl.createTableIndexExpression(importUniqueName, name), - importSpecifier - ); - result.push(namedImport); - } - }); - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; - } - } else if (ts.isNamespaceImport(imports)) { - if (!this.resolver.isReferencedAliasDeclaration(imports)) { - return undefined; + // import * as module from "./module"; + // local module = require("module") + if (statement.importClause.namedBindings && ts.isNamespaceImport(statement.importClause.namedBindings)) { + if (this.resolver.isReferencedAliasDeclaration(statement.importClause.namedBindings)) { + const requireStatement = tstl.createVariableDeclarationStatement( + this.transformIdentifier(statement.importClause.namedBindings.name), + requireCall, + statement + ); + + result.push(requireStatement); } + } - const requireStatement = tstl.createVariableDeclarationStatement( - this.transformIdentifier(imports.name), - requireCall, - statement - ); - result.push(requireStatement); - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; + // import { a, b, c } from "./module"; + // local a = __module.a + // local b = __module.b + // local c = __module.c + if (statement.importClause.namedBindings && ts.isNamedImports(statement.importClause.namedBindings)) { + const assignmentStatements = statement.importClause.namedBindings.elements + .filter(importSpecifier => tsHelper.shouldBeImported(importSpecifier, this.checker, this.resolver)) + .map(importSpecifier => this.transformImportSpecifier(importSpecifier, importUniqueName)); + + if (assignmentStatements.length > 0) { + usingRequireStatement = true; } + result.push(...assignmentStatements); + } + + if (result.length === 0) { + return undefined; + } + + if (usingRequireStatement) { + result.unshift(requireStatement); } + + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } + } + + protected transformImportSpecifier( + importSpecifier: ts.ImportSpecifier, + moduleTableName: tstl.Identifier + ): tstl.VariableDeclarationStatement { + const leftIdentifier = this.transformIdentifier(importSpecifier.name); + const propertyName = this.transformPropertyName( + importSpecifier.propertyName ? importSpecifier.propertyName : importSpecifier.name + ); + + return tstl.createVariableDeclarationStatement( + leftIdentifier, + tstl.createTableIndexExpression(moduleTableName, propertyName), + importSpecifier + ); } protected createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { const modulePathString = resolveModule - ? this.getImportPath(moduleSpecifier.text.replace(new RegExp('"', "g"), ""), moduleSpecifier) + ? tsHelper.getImportPath( + this.currentSourceFile.fileName, + moduleSpecifier.text.replace(new RegExp('"', "g"), ""), + moduleSpecifier, + this.options + ) : moduleSpecifier.text; const modulePath = tstl.createStringLiteral(modulePathString); return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); @@ -521,10 +573,6 @@ export class LuaTransformer { ): StatementVisitResult { this.classStack.push(statement); - if (statement.name === undefined && nameOverride === undefined) { - throw TSTLErrors.MissingClassName(statement); - } - let className: tstl.Identifier; let classNameText: string; if (nameOverride !== undefined) { @@ -534,7 +582,15 @@ export class LuaTransformer { className = this.transformIdentifier(statement.name); classNameText = statement.name.text; } else { - throw TSTLErrors.MissingClassName(statement); + const isDefaultExport = tsHelper.hasDefaultExportModifier(statement.modifiers); + if (isDefaultExport) { + const left = this.createExportedIdentifier(this.createDefaultExportIdentifier(statement)); + const right = this.transformClassExpression(statement); + + return tstl.createAssignmentStatement(left, right, statement); + } else { + throw TSTLErrors.MissingClassName(statement); + } } const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); @@ -779,18 +835,35 @@ export class LuaTransformer { // [____exports.]className = {} const classTable: tstl.Expression = tstl.createTableExpression(); - const classVar = this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); + const isDefaultExport = tsHelper.hasDefaultExportModifier(statement.modifiers); + + const defaultExportLeftHandSide = isDefaultExport + ? tstl.createTableIndexExpression( + this.createExportsIdentifier(), + this.createDefaultExportStringLiteral(statement) + ) + : undefined; + + const classVar = defaultExportLeftHandSide + ? [tstl.createAssignmentStatement(defaultExportLeftHandSide, classTable, statement)] + : this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); + result.push(...classVar); - const exportScope = this.getIdentifierExportScope(className); - if (exportScope) { - // local localClassName = ____exports.className - result.push( - tstl.createVariableDeclarationStatement( - localClassName, - this.createExportedIdentifier(tstl.cloneIdentifier(className), exportScope) - ) - ); + if (defaultExportLeftHandSide) { + // local localClassName = ____exports.default + result.push(tstl.createVariableDeclarationStatement(localClassName, defaultExportLeftHandSide)); + } else { + const exportScope = this.getIdentifierExportScope(className); + if (exportScope) { + // local localClassName = ____exports.className + result.push( + tstl.createVariableDeclarationStatement( + localClassName, + this.createExportedIdentifier(tstl.cloneIdentifier(className), exportScope) + ) + ); + } } // localClassName.name = className @@ -1879,11 +1952,6 @@ export class LuaTransformer { : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); - if (functionDeclaration.name === undefined) { - throw TSTLErrors.MissingFunctionName(functionDeclaration); - } - - const name = this.transformIdentifier(functionDeclaration.name); const [body, functionScope] = functionDeclaration.asteriskToken ? this.transformGeneratorFunction(functionDeclaration.parameters, functionDeclaration.body, restParamName) : this.transformFunctionBody(functionDeclaration.parameters, functionDeclaration.body, restParamName); @@ -1895,18 +1963,38 @@ export class LuaTransformer { restParamName, tstl.FunctionExpressionFlags.Declaration ); - // Remember symbols referenced in this function for hoisting later - if (!this.options.noHoisting && name.symbolId !== undefined) { - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - if (!scope.functionDefinitions) { - scope.functionDefinitions = new Map(); + + const name = functionDeclaration.name ? this.transformIdentifier(functionDeclaration.name) : undefined; + + if (name) { + // Remember symbols referenced in this function for hoisting later + if (!this.options.noHoisting && name.symbolId !== undefined) { + const scope = this.peekScope(); + if (scope === undefined) { + throw TSTLErrors.UndefinedScope(); + } + if (!scope.functionDefinitions) { + scope.functionDefinitions = new Map(); + } + const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Map() }; + scope.functionDefinitions.set(name.symbolId, functionInfo); } - const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Map() }; - scope.functionDefinitions.set(name.symbolId, functionInfo); } + + const isDefaultExport = tsHelper.hasDefaultExportModifier(functionDeclaration.modifiers); + + if (isDefaultExport) { + return tstl.createAssignmentStatement( + tstl.createTableIndexExpression( + this.createExportsIdentifier(), + this.createDefaultExportStringLiteral(functionDeclaration) + ), + this.transformFunctionExpression(functionDeclaration) + ); + } else if (!name) { + throw TSTLErrors.MissingFunctionName(functionDeclaration); + } + return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); } @@ -3572,11 +3660,17 @@ export class LuaTransformer { } } - public transformClassExpression(expression: ts.ClassExpression): ExpressionVisitResult { - const className = - expression.name !== undefined - ? this.transformIdentifier(expression.name) - : tstl.createAnonymousIdentifier(); + public transformClassExpression(expression: ts.ClassLikeDeclaration): ExpressionVisitResult { + const isDefaultExport = tsHelper.hasDefaultExportModifier(expression.modifiers); + + let className: tstl.Identifier; + if (expression.name) { + className = this.transformIdentifier(expression.name); + } else if (isDefaultExport) { + className = this.createDefaultExportIdentifier(expression); + } else { + className = tstl.createAnonymousIdentifier(); + } const classDeclaration = this.transformClassDeclaration(expression, className); return this.createImmediatelyInvokedFunctionExpression( @@ -5322,6 +5416,14 @@ export class LuaTransformer { return tstl.createTableIndexExpression(exportTable, tstl.createStringLiteral(identifier.text)); } + protected createDefaultExportIdentifier(original: ts.Node): tstl.Identifier { + return tstl.createIdentifier("default", original); + } + + protected createDefaultExportStringLiteral(original: ts.Node): tstl.StringLiteral { + return tstl.createStringLiteral("default", original); + } + protected getSymbolExportScope(symbol: ts.Symbol): ts.SourceFile | ts.ModuleDeclaration | undefined { const exportedDeclaration = tsHelper.getExportedSymbolDeclaration(symbol); if (!exportedDeclaration) { @@ -5408,38 +5510,6 @@ export class LuaTransformer { } } - protected getAbsoluteImportPath(relativePath: string): string { - if (relativePath.charAt(0) !== "." && this.options.baseUrl) { - return path.resolve(this.options.baseUrl, relativePath); - } - - return path.resolve(path.dirname(this.currentSourceFile.fileName), relativePath); - } - - protected getImportPath(relativePath: string, node: ts.Node): string { - const rootDir = this.options.rootDir ? path.resolve(this.options.rootDir) : path.resolve("."); - const absoluteImportPath = path.format(path.parse(this.getAbsoluteImportPath(relativePath))); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - if (absoluteImportPath.includes(absoluteRootDirPath)) { - return this.formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); - } else { - throw TSTLErrors.UnresolvableRequirePath( - node, - `Cannot create require path. Module does not exist within --rootDir`, - relativePath - ); - } - } - - protected formatPathToLuaPath(filePath: string): string { - filePath = filePath.replace(/\.json$/, ""); - if (process.platform === "win32") { - // Windows can use backslashes - filePath = filePath.replace(/\.\\/g, "").replace(/\\/g, "."); - } - return filePath.replace(/\.\//g, "").replace(/\//g, "."); - } - protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { return tstl.createIdentifier("self", tsOriginal, undefined, "this"); } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index d6819007f..cbb250e77 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -1,6 +1,9 @@ import * as ts from "typescript"; +import * as path from "path"; import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; +import * as TSTLErrors from "./TSTLErrors"; +import { EmitResolver } from "./LuaTransformer"; export enum ContextType { None, @@ -57,6 +60,47 @@ export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); } +export function getExportable(exportSpecifiers: ts.NamedExports, resolver: EmitResolver): ts.ExportSpecifier[] { + return exportSpecifiers.elements.filter(exportSpecifier => resolver.isValueAliasDeclaration(exportSpecifier)); +} + +export function isDefaultExportSpecifier(node: ts.ExportSpecifier): boolean { + return ( + (node.name !== undefined && node.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || + (node.propertyName !== undefined && node.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) + ); +} + +export function hasDefaultExportModifier(modifiers?: ts.NodeArray): boolean { + return modifiers ? modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword) : false; +} + +export function shouldResolveModulePath(moduleSpecifier: ts.Expression, checker: ts.TypeChecker): boolean { + const moduleOwnerSymbol = checker.getSymbolAtLocation(moduleSpecifier); + if (moduleOwnerSymbol) { + const decorators = new Map(); + collectCustomDecorators(moduleOwnerSymbol, checker, decorators); + if (decorators.has(DecoratorKind.NoResolution)) { + return false; + } + } + return true; +} + +export function shouldBeImported( + importNode: ts.ImportClause | ts.ImportSpecifier, + checker: ts.TypeChecker, + resolver: EmitResolver +): boolean { + const decorators = getCustomDecorators(checker.getTypeAtLocation(importNode), checker); + + return ( + resolver.isReferencedAliasDeclaration(importNode) && + !decorators.has(DecoratorKind.Extension) && + !decorators.has(DecoratorKind.MetaExtension) + ); +} + export function isFileModule(sourceFile: ts.SourceFile): boolean { return sourceFile.statements.some(isStatementExported); } @@ -968,3 +1012,55 @@ export function isSimpleExpression(expression: tstl.Expression): boolean { } return true; } + +export function getAbsoluteImportPath( + relativePath: string, + directoryPath: string, + options: ts.CompilerOptions +): string { + if (relativePath.charAt(0) !== "." && options.baseUrl) { + return path.resolve(options.baseUrl, relativePath); + } + + return path.resolve(directoryPath, relativePath); +} + +export function getImportPath( + fileName: string, + relativePath: string, + node: ts.Node, + options: ts.CompilerOptions +): string { + const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); + + const absoluteImportPath = path.format( + path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) + ); + const absoluteRootDirPath = path.format(path.parse(rootDir)); + if (absoluteImportPath.includes(absoluteRootDirPath)) { + return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); + } else { + throw TSTLErrors.UnresolvableRequirePath( + node, + `Cannot create require path. Module does not exist within --rootDir`, + relativePath + ); + } +} + +export function getExportPath(fileName: string, options: ts.CompilerOptions): string { + const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); + + const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); + const absoluteRootDirPath = path.format(path.parse(rootDir)); + return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); +} + +export function formatPathToLuaPath(filePath: string): string { + filePath = filePath.replace(/\.json$/, ""); + if (process.platform === "win32") { + // Windows can use backslashes + filePath = filePath.replace(/\.\\/g, "").replace(/\\/g, "."); + } + return filePath.replace(/\.\//g, "").replace(/\//g, "."); +} diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 054c89425..0e53dd713 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -7,9 +7,6 @@ const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? export const CouldNotCast = (castName: string) => new Error(`Failed to cast all elements to expected type using ${castName}.`); -export const DefaultImportsNotSupported = (node: ts.Node) => - new TranspileError(`Default Imports are not supported, please use named imports instead!`, node); - export const ForbiddenEllipsisDestruction = (node: ts.Node) => new TranspileError(`Ellipsis destruction is not allowed.`, node); @@ -103,9 +100,6 @@ export const UndefinedTypeNode = (node: ts.Node) => new TranspileError("Failed t export const UnknownSuperType = (node: ts.Node) => new TranspileError("Unable to resolve type of super expression.", node); -export const UnsupportedDefaultExport = (node: ts.Node) => - new TranspileError(`Default exports are not supported.`, node); - export const UnsupportedImportType = (node: ts.Node) => new TranspileError(`Unsupported import type.`, node); export const UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 7e5ae77f0..b292e6b6c 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -194,6 +194,11 @@ TestEnum.val3 = \\"baz\\" TestEnum.baz = \\"val3\\"" `; +exports[`Transformation (exportEquals) 1`] = ` +"local ____exports = true +return ____exports" +`; + exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 @@ -660,6 +665,11 @@ exports[`Transformation (typeAssert) 1`] = ` local test2 = 10" `; +exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` +"local x = require(\\"module\\") +local ____ = x" +`; + exports[`Transformation (while) 1`] = ` "local d = 10 while d > 0 do diff --git a/test/translation/transformation/exportEquals.ts b/test/translation/transformation/exportEquals.ts new file mode 100644 index 000000000..ba27c6482 --- /dev/null +++ b/test/translation/transformation/exportEquals.ts @@ -0,0 +1 @@ +export = true; diff --git a/test/translation/transformation/unusedDefaultWithNamespaceImport.ts b/test/translation/transformation/unusedDefaultWithNamespaceImport.ts new file mode 100644 index 000000000..5b66a4b22 --- /dev/null +++ b/test/translation/transformation/unusedDefaultWithNamespaceImport.ts @@ -0,0 +1,2 @@ +import def, * as x from "module"; +x; diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts index 5134067b7..53674df46 100644 --- a/test/unit/modules.spec.ts +++ b/test/unit/modules.spec.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; describe("module import/export elision", () => { @@ -62,16 +61,6 @@ describe("module import/export elision", () => { }); }); -test.each([ - "export { default } from '...'", - "export { x as default } from '...';", - "export { default as x } from '...';", -])("Export default keyword disallowed (%p)", exportStatement => { - expect(() => util.transpileString(exportStatement)).toThrowExactError( - TSTLErrors.UnsupportedDefaultExport(util.nodeStub) - ); -}); - test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( "Import module names with invalid lua identifier characters (%p)", name => { @@ -89,12 +78,6 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ } ); -test("defaultImport", () => { - expect(() => { - util.transpileString(`import TestClass from "test"`); - }).toThrowExactError(TSTLErrors.DefaultImportsNotSupported(util.nodeStub)); -}); - test("lualibRequire", () => { const lua = util.transpileString(`let a = b instanceof c;`, { luaLibImport: tstl.LuaLibImportKind.Require, diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts index 3f864b3fc..216f8fbc6 100644 --- a/test/unit/require.spec.ts +++ b/test/unit/require.spec.ts @@ -187,3 +187,148 @@ test("ImportEquals declaration require", () => { expect(match[1]).toBe("foo.bar"); } }); + +test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + export { default } from "./module"; + `, + "module.ts": ` + export const value = true; + ${exportStatement}; + `, + }, + "default" + ); + + expect(result).toBe(true); +}); + +test("Default Import and Export Expression", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport; + `, + "module.ts": ` + export default 1 + 2 + 3; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Import and Export Assignment", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import * as m from "./module"; + export const value = m; + `, + "module.ts": ` + export = true; + `, + }, + "value" + ); + + expect(result).toBe(true); +}); + +test("Mixed Exports, Default and Named Imports", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport, { a, b, c } from "./module"; + export const value = defaultExport + b + c; + `, + "module.ts": ` + export const a = 1; + export default a; + export const b = 2; + export const c = 3; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Mixed Exports, Default and Namespace Import", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport, * as ns from "./module"; + export const value = defaultExport + ns.b + ns.c; + `, + "module.ts": ` + export const a = 1; + export default a; + export const b = 2; + export const c = 3; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Export Default Function", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport(); + `, + "module.ts": ` + export default function() { + return true; + } + `, + }, + "value" + ); + + expect(result).toBe(true); +}); + +test.each([ + ["Test", "export default class Test { static method() { return true; } }"], + ["default", "export default class { static method() { return true; } }"], +])("Export Default Class Name (%p)", (expectedClassName, classDeclarationStatement) => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport.name; + `, + "module.ts": classDeclarationStatement, + }, + "value" + ); + + expect(result).toBe(expectedClassName); +}); + +test("Export Equals", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import * as module from "./module"; + export const value = module; + `, + "module.ts": ` + export = true; + `, + }, + "value" + ); + + expect(result).toBe(true); +}); diff --git a/test/util.ts b/test/util.ts index 6c314780b..f12f81d5a 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,3 +1,4 @@ +import * as tsHelper from "../src/TSHelper"; import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; import * as path from "path"; @@ -110,6 +111,46 @@ export function transpileAndExecute( return executeLua(lua); } +export function transpileAndExecuteProjectReturningMainExport( + typeScriptFiles: Record, + exportName: string, + options: tstl.CompilerOptions = {} +): [any, string] { + const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); + if (!mainFile) { + throw new Error("An entry point file needs to be specified. This should be called main.ts"); + } + + const joinedTranspiledFiles = Object.keys(typeScriptFiles) + .filter(typeScriptFileName => typeScriptFileName !== "main.ts") + .map(typeScriptFileName => { + const modulePath = tsHelper.getExportPath(typeScriptFileName, options); + const tsCode = typeScriptFiles[typeScriptFileName]; + const luaCode = transpileString(tsCode, options); + return `package.preload["${modulePath}"] = function() + ${luaCode} + end`; + }) + .join("\n"); + + const luaCode = `return (function() + ${joinedTranspiledFiles} + ${transpileString(typeScriptFiles[mainFile])} + end)().${exportName}`; + + try { + return [executeLua(luaCode), luaCode]; + } catch (err) { + throw new Error(` + Encountered an error when executing the following Lua code: + + ${luaCode} + + ${err} + `); + } +} + export function transpileExecuteAndReturnExport( tsStr: string, returnExport: string, From c11ba34254b416ae7ed8c4fd20709c864a52608a Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 31 Jul 2019 17:39:08 +1000 Subject: [PATCH 154/764] SpreadAssignment support (#693) * Support spreading strings * Support SpreadAssignment * Fix SpreadAssignment * Use for loop for spreading strings * Use Object.assign not MergeObjects * Remove string declaration * Avoid adding an empty table in SpreadElement table lists * Avoid mutating the first SpreadAssignment value * Remove JSON.parse in spreadElement test. Not needed * Add spreadElement destructure and multiple properties * Allow arrays to be spread * Add a comment to SpreadAssignment algorithm * Use if else in SpreadAssignment element * Remove unnecessary tests --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 39 ++++++++++++++- src/lualib/ArrayToObject.ts | 7 +++ src/lualib/Spread.ts | 14 ++++-- .../__snapshots__/transformation.spec.ts.snap | 7 +++ .../transformation/spreadAssignment.ts | 3 ++ test/unit/spreadElement.spec.ts | 48 +++++++++++++++++++ 7 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 src/lualib/ArrayToObject.ts create mode 100644 test/translation/transformation/spreadAssignment.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index aa7c3e432..25cd83268 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -18,6 +18,7 @@ export enum LuaLibFeature { ArraySlice = "ArraySlice", ArraySome = "ArraySome", ArraySplice = "ArraySplice", + ArrayToObject = "ArrayToObject", ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9343b3447..819c5f2df 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3930,7 +3930,8 @@ export class LuaTransformer { } public transformObjectLiteral(expression: ts.ObjectLiteralExpression): ExpressionVisitResult { - const properties: tstl.TableFieldExpression[] = []; + let properties: tstl.TableFieldExpression[] = []; + const tableExpressions: tstl.Expression[] = []; // Add all property assignments expression.properties.forEach(element => { const name = element.name ? this.transformPropertyName(element.name) : undefined; @@ -3947,12 +3948,46 @@ export class LuaTransformer { } else if (ts.isMethodDeclaration(element)) { const expression = this.transformFunctionExpression(element); properties.push(tstl.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (properties.length > 0) { + const tableExpression = tstl.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + } + properties = []; + + const type = this.checker.getTypeAtLocation(element.expression); + let tableExpression: tstl.Expression; + if (type && tsHelper.isArrayType(type, this.checker, this.program)) { + tableExpression = this.transformLuaLibFunction( + LuaLibFeature.ArrayToObject, + element.expression, + this.transformExpression(element.expression) + ); + } else { + tableExpression = this.transformExpression(element.expression); + } + tableExpressions.push(tableExpression); } else { throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); } }); - return tstl.createTableExpression(properties, expression); + if (tableExpressions.length === 0) { + return tstl.createTableExpression(properties, expression); + } else { + if (properties.length > 0) { + const tableExpression = tstl.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + } + + if (tableExpressions[0].kind !== tstl.SyntaxKind.TableExpression) { + tableExpressions.unshift(tstl.createTableExpression(undefined, expression)); + } + + return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...tableExpressions); + } } public transformOmittedExpression(node: ts.OmittedExpression): ExpressionVisitResult { diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts new file mode 100644 index 000000000..385906f0a --- /dev/null +++ b/src/lualib/ArrayToObject.ts @@ -0,0 +1,7 @@ +function __TS__ArrayToObject(this: void, array: any[]): object { + const object: Record = {}; + for (let i = 0; i < array.length; i += 1) { + object[i] = array[i]; + } + return object; +} diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index aee6ac66b..8f88053d2 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,7 +1,13 @@ -function __TS__Spread(this: void, iterable: Iterable): T[] { - const arr: T[] = []; - for (const item of iterable) { - arr[arr.length] = item; +function __TS__Spread(this: void, iterable: string | Iterable): T[] { + const arr = []; + if (typeof iterable === "string") { + for (let i = 0; i < iterable.length; i += 1) { + arr[arr.length] = iterable[i]; + } + } else { + for (const item of iterable) { + arr[arr.length] = item; + } } return (table.unpack || unpack)(arr); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index b292e6b6c..381a7b987 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -567,6 +567,13 @@ exports[`Transformation (shorthandPropertyAssignment) 1`] = ` f = function(____, x) return ({x = x}) end" `; +exports[`Transformation (spreadAssignment) 1`] = ` +"require(\\"lualib_bundle\\"); +local xy = __TS__ObjectAssign({x = 0, y = 1}) +local xyz = __TS__ObjectAssign({x = 0, y = 1}, {z = 2}) +local xyz2 = __TS__ObjectAssign({z = 2}, {x = 0, y = 1})" +`; + exports[`Transformation (tryCatch) 1`] = ` "do local ____try, er = pcall( diff --git a/test/translation/transformation/spreadAssignment.ts b/test/translation/transformation/spreadAssignment.ts new file mode 100644 index 000000000..0ad87be82 --- /dev/null +++ b/test/translation/transformation/spreadAssignment.ts @@ -0,0 +1,3 @@ +const xy = { ...{ x: 0, y: 1 } }; +const xyz = { ...{ x: 0, y: 1 }, z: 2 }; +const xyz2 = { z: 2, ...{ x: 0, y: 1 } }; diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts index 28201f12e..13e528102 100644 --- a/test/unit/spreadElement.spec.ts +++ b/test/unit/spreadElement.spec.ts @@ -64,3 +64,51 @@ test("Spread Element Iterable", () => { return JSONStringify(arr)`; expect(JSON.parse(util.transpileAndExecute(code))).toEqual([1, 2, 4, 8, 16, 32, 64, 128, 256]); }); + +test.each(["", "string", "string with spaces", "string 1 2 3"])('Spread Element String "%s"', str => { + const code = ` + const arr = [..."${str}"]; + return JSONStringify(arr)`; + expect(JSON.parse(util.transpileAndExecute(code))).toEqual([...str]); +}); + +test.each([ + "{ value: false, ...{ value: true } }", + "{ ...{ value: false }, value: true }", + "{ ...{ value: false }, value: false, ...{ value: true } }", + "{ ...{ x: true, y: true } }", + "{ x: true, ...{ y: true, z: true } }", + "{ ...{ x: true }, ...{ y: true, z: true } }", +])('SpreadAssignment "%s"', expression => { + const code = `return JSONStringify(${expression});`; + expect(JSON.parse(util.transpileAndExecute(code))).toEqual(eval(`(${expression})`)); +}); + +test("SpreadAssignment Destructure", () => { + const code = `let obj = { x: 0, y: 1, z: 2 };`; + const luaCode = ` + ${code} + return JSONStringify({ a: 0, ...obj, b: 1, c: 2 });`; + const jsCode = ` + ${code} + ({ a: 0, ...obj, b: 1, c: 2 })`; + expect(JSON.parse(util.transpileAndExecute(luaCode))).toStrictEqual(eval(jsCode)); +}); + +test("SpreadAssignment No Mutation", () => { + const code = ` + const obj: { x: number, y: number, z?: number } = { x: 0, y: 1 }; + const merge = { ...obj, z: 2 }; + return obj.z;`; + expect(util.transpileAndExecute(code)).toBe(undefined); +}); + +test.each([ + "function spread() { return [0, 1, 2] } const object = { ...spread() };", + "const object = { ...[0, 1, 2] };", +])('SpreadAssignment Array "%s"', expressionToCreateObject => { + const code = ` + ${expressionToCreateObject} + return JSONStringify([object[0], object[1], object[2]]);`; + expect(JSON.parse(util.transpileAndExecute(code))).toEqual([0, 1, 2]); +}); From 0ed6fe38c03c838457f56f8691c49171918faddf Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 31 Jul 2019 23:26:56 +0500 Subject: [PATCH 155/764] Add test builder (#609) * Add new test builder and convert few tests * Rename fn and mod to testFunction and testModule * Transform some more tests * Transform some more tests * Transform some more tests * Update require tests * Fix tests on node 8.5.0 * Change float precision in json test util * Transform some more tests * Revert "Change float precision in json test util" This reverts commit 90cc57fe1edb7dd5ec2aa4091c348f3905eaeede. * Transform some more tests * Move serialize to separate template functions * Rename some builder methods * numbers.spec.ts * Serialize NaN and Infinity test results * math.spec.ts * console.spec.ts * Merge array.spec.ts files * Move some math tests to lualib * Move around some lualib tests * Move numbers.spec.ts to lualib tests * Move inlining tests to other luaLibImport tests * Fix node 8 tests * Merge curry.spec.ts into functions.spec.ts * Fix object tests * Refactor array tests * Move custom decorator tests to separate directory * Merge tagged template literal and simple template literal tests * Update globalThis tests * Move and remove some tests from expressions.spec.ts * Move class-related tests to a directory * Move namespace tests from modules * Move modules tests to a subdirectory * Transform tagged template literals tests * Transform sourcemaps tests * Move string tests to lualib directory * Refactor spread.spec.ts * Refactor bindingpatterns.spec.ts * Merge and refactor destructuring tests * Fix expressions tests * Fix declared namespace function call test * Remove/move to other files tuples tests * Move transformers.spec.ts to subdirectory * Move some tests to printer subdirectory * Remove declarations.spec.ts * Split typechecking into instanceof and typeof * Rename lualib tests to builtins * Move parenthesis removal tests to printer subdirectory * Remove some translation tests * Move around assignments and expressions * Fix loading tests * enum.spec.ts * globalThis.spec.ts * Rearrange some enum tests * Refactor some tests * Fix enum tests * Remove todos for #663 * Move enum array index tests to array.spec.ts * Remove some translation tests * Fix nested namespace test * Fix as const cast creating diagnostics * Address feedback * Refactor new spread tests * Remove spreadAssignment translation test --- src/LuaTransformer.ts | 31 +- test/json.lua | 13 +- test/legacy-utils.ts | 162 +++++ .../__snapshots__/transformation.spec.ts.snap | 404 ----------- test/translation/transformation.spec.ts | 6 +- .../transformation/callNamespace.ts | 4 - test/translation/transformation/continue.ts | 5 - .../transformation/continueConcurrent.ts | 9 - .../transformation/continueNested.ts | 11 - .../continueNestedConcurrent.ts | 15 - test/translation/transformation/do.ts | 4 - test/translation/transformation/enum.ts | 5 - .../transformation/enumHeterogeneous.ts | 5 - .../transformation/enumMembersOnly.ts | 9 - test/translation/transformation/enumString.ts | 5 - .../transformation/exportEquals.ts | 1 - test/translation/transformation/for.ts | 1 - test/translation/transformation/forIn.ts | 7 - test/translation/transformation/forOf.ts | 2 - .../transformation/functionRestArguments.ts | 3 - .../transformation/getSetAccessors.ts | 14 - .../transformation/interfaceIndex.ts | 6 - test/translation/transformation/luaTable.ts | 23 - .../modulesNamespaceExportEnum.ts | 6 - test/translation/transformation/namespace.ts | 3 - .../transformation/namespaceMerge.ts | 24 - .../transformation/namespaceNested.ts | 5 - .../shorthandPropertyAssignment.ts | 1 - .../transformation/spreadAssignment.ts | 3 - test/translation/transformation/tryCatch.ts | 5 - .../transformation/tryCatchFinally.ts | 7 - test/translation/transformation/tryFinally.ts | 5 - .../translation/transformation/tupleReturn.ts | 34 - test/translation/transformation/typeAssert.ts | 2 - test/translation/transformation/while.ts | 4 - test/tsconfig.json | 1 + .../__snapshots__/expressions.spec.ts.snap | 404 +++++++++++ test/unit/array.spec.ts | 263 -------- test/unit/assignmentDestructuring.spec.ts | 53 -- test/unit/assignments.spec.ts | 292 ++++++++ test/unit/assignments/assignments.spec.ts | 186 ----- test/unit/bindingpatterns.spec.ts | 191 ------ .../__snapshots__/console.spec.ts.snap | 145 ++++ .../builtins/__snapshots__/math.spec.ts.snap | 89 +++ test/unit/builtins/array.spec.ts | 522 +++++++++++++++ test/unit/builtins/console.spec.ts | 58 ++ test/unit/builtins/globalThis.spec.ts | 32 + test/unit/builtins/loading.spec.ts | 53 ++ test/unit/{lualib => builtins}/map.spec.ts | 0 test/unit/builtins/math.spec.ts | 26 + test/unit/builtins/numbers.spec.ts | 57 ++ test/unit/builtins/object.spec.ts | 35 + test/unit/builtins/set.spec.ts | 122 ++++ test/unit/builtins/string.spec.ts | 264 ++++++++ test/unit/builtins/symbol.spec.ts | 38 ++ .../unit/{lualib => builtins}/weakMap.spec.ts | 0 .../unit/{lualib => builtins}/weakSet.spec.ts | 0 test/unit/classDecorator.spec.ts | 199 ------ test/unit/{ => classes}/accessors.spec.ts | 148 ++-- .../classes.spec.ts} | 26 +- test/unit/classes/decorators.spec.ts | 127 ++++ test/unit/classes/instanceof.spec.ts | 76 +++ test/unit/conditionals.spec.ts | 321 ++++----- test/unit/console.spec.ts | 83 --- test/unit/curry.spec.ts | 10 - test/unit/declarations.spec.ts | 135 ---- .../decorators/compileMembersOnly.spec.ts | 34 + .../customConstructor.spec.ts} | 4 +- test/unit/decorators/extension.spec.ts | 34 + test/unit/decorators/forRange.spec.ts | 112 ++++ test/unit/decorators/luaIterator.spec.ts | 262 ++++++++ test/unit/{ => decorators}/luaTable.spec.ts | 4 +- .../metaExtension.spec.ts} | 4 +- .../tupleReturn.spec.ts} | 585 ++++++++-------- test/unit/decorators/vararg.spec.ts | 55 ++ test/unit/destructuring.spec.ts | 123 ++++ test/unit/enum.spec.ts | 285 +++----- test/unit/error.spec.ts | 64 +- test/unit/expressions.spec.ts | 629 +++-------------- test/unit/functions.spec.ts | 633 ------------------ test/unit/functions/functions.spec.ts | 514 ++++++++++++++ .../functionExpressionTypeInference.spec.ts | 2 +- .../validation}/functionPermutations.ts | 0 .../invalidFunctionAssignments.spec.ts | 4 +- .../validFunctionAssignments.spec.ts | 18 +- test/unit/identifiers.spec.ts | 172 ++--- test/unit/json.spec.ts | 19 +- test/unit/loops.spec.ts | 461 +------------ test/unit/lualib/array.spec.ts | 458 ------------- test/unit/lualib/inlining.spec.ts | 44 -- test/unit/lualib/lualib.spec.ts | 169 ----- test/unit/lualib/set.spec.ts | 124 ---- test/unit/lualib/symbol.spec.ts | 60 -- test/unit/math.spec.ts | 253 ------- test/unit/modules.spec.ts | 165 ----- test/unit/modules/modules.spec.ts | 211 ++++++ test/unit/modules/resolution.spec.ts | 143 ++++ test/unit/namespaces.spec.ts | 121 ++++ test/unit/numbers.spec.ts | 69 -- test/unit/printer/deadCodeAfterReturn.spec.ts | 61 ++ test/unit/printer/parenthesis.spec.ts | 64 ++ test/unit/{ => printer}/semicolons.spec.ts | 14 +- test/unit/{ => printer}/sourcemaps.spec.ts | 148 ++-- test/unit/require.spec.ts | 334 --------- test/unit/spread.spec.ts | 89 +++ test/unit/spreadElement.spec.ts | 114 ---- test/unit/string.spec.ts | 380 ----------- test/unit/taggedTemplateLiterals.spec.ts | 123 ---- test/unit/templateLiterals.spec.ts | 62 ++ .../{ => transformers}/transformers.spec.ts | 18 +- test/unit/typechecking.spec.ts | 185 ----- test/unit/typeof.spec.ts | 76 +++ test/util.ts | 574 +++++++++++----- tslint.json | 1 - 114 files changed, 5878 insertions(+), 7000 deletions(-) create mode 100644 test/legacy-utils.ts delete mode 100644 test/translation/transformation/callNamespace.ts delete mode 100644 test/translation/transformation/continue.ts delete mode 100644 test/translation/transformation/continueConcurrent.ts delete mode 100644 test/translation/transformation/continueNested.ts delete mode 100644 test/translation/transformation/continueNestedConcurrent.ts delete mode 100644 test/translation/transformation/do.ts delete mode 100644 test/translation/transformation/enum.ts delete mode 100644 test/translation/transformation/enumHeterogeneous.ts delete mode 100644 test/translation/transformation/enumMembersOnly.ts delete mode 100644 test/translation/transformation/enumString.ts delete mode 100644 test/translation/transformation/exportEquals.ts delete mode 100644 test/translation/transformation/for.ts delete mode 100644 test/translation/transformation/forIn.ts delete mode 100644 test/translation/transformation/forOf.ts delete mode 100644 test/translation/transformation/functionRestArguments.ts delete mode 100644 test/translation/transformation/getSetAccessors.ts delete mode 100644 test/translation/transformation/interfaceIndex.ts delete mode 100644 test/translation/transformation/luaTable.ts delete mode 100644 test/translation/transformation/modulesNamespaceExportEnum.ts delete mode 100644 test/translation/transformation/namespace.ts delete mode 100644 test/translation/transformation/namespaceMerge.ts delete mode 100644 test/translation/transformation/namespaceNested.ts delete mode 100644 test/translation/transformation/shorthandPropertyAssignment.ts delete mode 100644 test/translation/transformation/spreadAssignment.ts delete mode 100644 test/translation/transformation/tryCatch.ts delete mode 100644 test/translation/transformation/tryCatchFinally.ts delete mode 100644 test/translation/transformation/tryFinally.ts delete mode 100644 test/translation/transformation/tupleReturn.ts delete mode 100644 test/translation/transformation/typeAssert.ts delete mode 100644 test/translation/transformation/while.ts create mode 100644 test/unit/__snapshots__/expressions.spec.ts.snap delete mode 100644 test/unit/array.spec.ts delete mode 100644 test/unit/assignmentDestructuring.spec.ts create mode 100644 test/unit/assignments.spec.ts delete mode 100644 test/unit/assignments/assignments.spec.ts delete mode 100644 test/unit/bindingpatterns.spec.ts create mode 100644 test/unit/builtins/__snapshots__/console.spec.ts.snap create mode 100644 test/unit/builtins/__snapshots__/math.spec.ts.snap create mode 100644 test/unit/builtins/array.spec.ts create mode 100644 test/unit/builtins/console.spec.ts create mode 100644 test/unit/builtins/globalThis.spec.ts create mode 100644 test/unit/builtins/loading.spec.ts rename test/unit/{lualib => builtins}/map.spec.ts (100%) create mode 100644 test/unit/builtins/math.spec.ts create mode 100644 test/unit/builtins/numbers.spec.ts create mode 100644 test/unit/builtins/object.spec.ts create mode 100644 test/unit/builtins/set.spec.ts create mode 100644 test/unit/builtins/string.spec.ts create mode 100644 test/unit/builtins/symbol.spec.ts rename test/unit/{lualib => builtins}/weakMap.spec.ts (100%) rename test/unit/{lualib => builtins}/weakSet.spec.ts (100%) delete mode 100644 test/unit/classDecorator.spec.ts rename test/unit/{ => classes}/accessors.spec.ts (76%) rename test/unit/{class.spec.ts => classes/classes.spec.ts} (96%) create mode 100644 test/unit/classes/decorators.spec.ts create mode 100644 test/unit/classes/instanceof.spec.ts delete mode 100644 test/unit/console.spec.ts delete mode 100644 test/unit/curry.spec.ts delete mode 100644 test/unit/declarations.spec.ts create mode 100644 test/unit/decorators/compileMembersOnly.spec.ts rename test/unit/{decoratorCustomConstructor.spec.ts => decorators/customConstructor.spec.ts} (91%) create mode 100644 test/unit/decorators/extension.spec.ts create mode 100644 test/unit/decorators/forRange.spec.ts create mode 100644 test/unit/decorators/luaIterator.spec.ts rename test/unit/{ => decorators}/luaTable.spec.ts (98%) rename test/unit/{decoratorMetaExtension.spec.ts => decorators/metaExtension.spec.ts} (93%) rename test/unit/{tuples.spec.ts => decorators/tupleReturn.spec.ts} (52%) create mode 100644 test/unit/decorators/vararg.spec.ts create mode 100644 test/unit/destructuring.spec.ts delete mode 100644 test/unit/functions.spec.ts create mode 100644 test/unit/functions/functions.spec.ts rename test/unit/{assignments => functions/validation}/functionExpressionTypeInference.spec.ts (99%) rename test/unit/{assignments => functions/validation}/functionPermutations.ts (100%) rename test/unit/{assignments => functions/validation}/invalidFunctionAssignments.spec.ts (98%) rename test/unit/{assignments => functions/validation}/validFunctionAssignments.spec.ts (99%) delete mode 100644 test/unit/lualib/array.spec.ts delete mode 100644 test/unit/lualib/inlining.spec.ts delete mode 100644 test/unit/lualib/lualib.spec.ts delete mode 100644 test/unit/lualib/set.spec.ts delete mode 100644 test/unit/lualib/symbol.spec.ts delete mode 100644 test/unit/math.spec.ts delete mode 100644 test/unit/modules.spec.ts create mode 100644 test/unit/modules/modules.spec.ts create mode 100644 test/unit/modules/resolution.spec.ts create mode 100644 test/unit/namespaces.spec.ts delete mode 100644 test/unit/numbers.spec.ts create mode 100644 test/unit/printer/deadCodeAfterReturn.spec.ts create mode 100644 test/unit/printer/parenthesis.spec.ts rename test/unit/{ => printer}/semicolons.spec.ts (56%) rename test/unit/{ => printer}/sourcemaps.spec.ts (70%) delete mode 100644 test/unit/require.spec.ts create mode 100644 test/unit/spread.spec.ts delete mode 100644 test/unit/spreadElement.spec.ts delete mode 100644 test/unit/string.spec.ts delete mode 100644 test/unit/taggedTemplateLiterals.spec.ts create mode 100644 test/unit/templateLiterals.spec.ts rename test/unit/{ => transformers}/transformers.spec.ts (81%) delete mode 100644 test/unit/typechecking.spec.ts create mode 100644 test/unit/typeof.spec.ts diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 819c5f2df..a8a5cdd35 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4552,7 +4552,7 @@ export class LuaTransformer { return tstl.createNumericLiteral(Math[name], identifier); default: - throw TSTLErrors.UnsupportedProperty("math", name, identifier); + throw TSTLErrors.UnsupportedProperty("Math", name, identifier); } } @@ -4622,7 +4622,7 @@ export class LuaTransformer { } default: - throw TSTLErrors.UnsupportedProperty("math", expressionName, expression); + throw TSTLErrors.UnsupportedProperty("Math", expressionName, expression); } } @@ -4872,11 +4872,7 @@ export class LuaTransformer { tstl.createStringLiteral("char") ); default: - throw TSTLErrors.UnsupportedForTarget( - `string property ${identifierString}`, - this.luaTarget, - identifier - ); + throw TSTLErrors.UnsupportedProperty("String", identifierString, identifier); } } @@ -4898,7 +4894,7 @@ export class LuaTransformer { case "values": return this.transformLuaLibFunction(LuaLibFeature.ObjectValues, expression, ...parameters); default: - throw TSTLErrors.UnsupportedForTarget(`object property ${methodName}`, this.luaTarget, expression); + throw TSTLErrors.UnsupportedProperty("Object", methodName, expression); } } @@ -4969,7 +4965,7 @@ export class LuaTransformer { ); return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]); default: - throw TSTLErrors.UnsupportedForTarget(`console property ${methodName}`, this.luaTarget, expression); + throw TSTLErrors.UnsupportedProperty("console", methodName, expression); } } @@ -4992,7 +4988,7 @@ export class LuaTransformer { const functionIdentifier = tstl.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); return tstl.createCallExpression(functionIdentifier, parameters, expression); default: - throw TSTLErrors.UnsupportedForTarget(`symbol property ${methodName}`, this.luaTarget, expression); + throw TSTLErrors.UnsupportedProperty("Symbol", methodName, expression); } } @@ -5008,7 +5004,7 @@ export class LuaTransformer { case "isFinite": return this.transformLuaLibFunction(LuaLibFeature.NumberIsFinite, expression, ...parameters); default: - throw TSTLErrors.UnsupportedForTarget(`number property ${methodName}`, this.luaTarget, expression); + throw TSTLErrors.UnsupportedProperty("Number", methodName, expression); } } @@ -5186,11 +5182,14 @@ export class LuaTransformer { } public transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult { - this.validateFunctionAssignment( - expression, - this.checker.getTypeAtLocation(expression.expression), - this.checker.getTypeAtLocation(expression.type) - ); + if (!ts.isConstTypeReference(expression.type)) { + this.validateFunctionAssignment( + expression, + this.checker.getTypeAtLocation(expression.expression), + this.checker.getTypeAtLocation(expression.type) + ); + } + return this.transformExpression(expression.expression); } diff --git a/test/json.lua b/test/json.lua index 6dafe9fe4..e41c3798a 100644 --- a/test/json.lua +++ b/test/json.lua @@ -112,11 +112,15 @@ end local function encode_number(val) - -- Check for NaN, -inf and inf - if val ~= val or val <= -math.huge or val >= math.huge then - error("unexpected number value '" .. tostring(val) .. "'") + if val ~= val then + return "NaN" + elseif val == math.huge then + return "Infinity" + elseif val == -math.huge then + return "-Infinity" + else + return string.format("%.17g", val) end - return string.format("%.14g", val) end @@ -139,6 +143,7 @@ encode = function(val, stack) end +-- TODO: Since it supports NaN and Infinity it is considered a superset of JSON, so it probably should be renamed function JSONStringify(val) return ( encode(val) ) end diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts new file mode 100644 index 000000000..4b9815d17 --- /dev/null +++ b/test/legacy-utils.ts @@ -0,0 +1,162 @@ +import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; +import * as fs from "fs"; +import * as path from "path"; +import * as ts from "typescript"; +import * as tstl from "../src"; +import * as tsHelper from "../src/TSHelper"; + +export function transpileString( + str: string | { [filename: string]: string }, + options: tstl.CompilerOptions = {}, + ignoreDiagnostics = true +): string { + const { diagnostics, file } = transpileStringResult(str, options); + expect(file.lua).toBeDefined(); + + const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); + expect(errors).not.toHaveDiagnostics(); + + return file.lua!.trim(); +} + +export function transpileStringsAsProject( + input: Record, + options: tstl.CompilerOptions = {} +): tstl.TranspileResult { + const optionsWithDefaults = { + luaTarget: tstl.LuaTarget.Lua53, + noHeader: true, + skipLibCheck: true, + target: ts.ScriptTarget.ESNext, + lib: ["lib.esnext.d.ts"], + experimentalDecorators: true, + ...options, + }; + + return tstl.transpileVirtualProject(input, optionsWithDefaults); +} + +export function transpileStringResult( + input: string | Record, + options: tstl.CompilerOptions = {} +): Required { + const { diagnostics, transpiledFiles } = transpileStringsAsProject( + typeof input === "string" ? { "main.ts": input } : input, + options + ); + + const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); + if (file === undefined) { + throw new Error('Program should have a file named "main"'); + } + + return { diagnostics, file }; +} + +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; +export function executeLua(luaStr: string, withLib = true): any { + luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); + if (withLib) { + luaStr = minimalTestLib + luaStr; + } + + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); + + if (status === lua.LUA_OK) { + // Read the return value from stack depending on its type. + if (lua.lua_isboolean(L, -1)) { + return lua.lua_toboolean(L, -1); + } else if (lua.lua_isnil(L, -1)) { + return undefined; + } else if (lua.lua_isnumber(L, -1)) { + return lua.lua_tonumber(L, -1); + } else if (lua.lua_isstring(L, -1)) { + return lua.lua_tojsstring(L, -1); + } else { + throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); + } + } else { + // If the lua VM did not terminate with status code LUA_OK an error occurred. + // Throw a JS error with the message, retrieved by reading a string from the stack. + + // Filter control characters out of string which are in there because ???? + throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20))); + } +} + +export function transpileAndExecute( + tsStr: string, + compilerOptions?: tstl.CompilerOptions, + luaHeader?: string, + tsHeader?: string +): any { + const wrappedTsString = `${tsHeader ? tsHeader : ""} + declare function JSONStringify(this: void, p: any): string; + function __runTest(this: void): any {${tsStr}}`; + + const lua = `${luaHeader ? luaHeader : ""} + ${transpileString(wrappedTsString, compilerOptions, false)} + return __runTest();`; + + return executeLua(lua); +} + +export function transpileAndExecuteProjectReturningMainExport( + typeScriptFiles: Record, + exportName: string, + options: tstl.CompilerOptions = {} +): [any, string] { + const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); + if (!mainFile) { + throw new Error("An entry point file needs to be specified. This should be called main.ts"); + } + + const joinedTranspiledFiles = Object.keys(typeScriptFiles) + .filter(typeScriptFileName => typeScriptFileName !== "main.ts") + .map(typeScriptFileName => { + const modulePath = tsHelper.getExportPath(typeScriptFileName, options); + const tsCode = typeScriptFiles[typeScriptFileName]; + const luaCode = transpileString(tsCode, options); + return `package.preload["${modulePath}"] = function() + ${luaCode} + end`; + }) + .join("\n"); + + const luaCode = `return (function() + ${joinedTranspiledFiles} + ${transpileString(typeScriptFiles[mainFile])} + end)().${exportName}`; + + try { + return [executeLua(luaCode), luaCode]; + } catch (err) { + throw new Error(` + Encountered an error when executing the following Lua code: + + ${luaCode} + + ${err} + `); + } +} + +export function transpileExecuteAndReturnExport( + tsStr: string, + returnExport: string, + compilerOptions?: tstl.CompilerOptions, + luaHeader?: string +): any { + const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; + ${tsStr}`; + + const lua = `return (function() + ${luaHeader ? luaHeader : ""} + ${transpileString(wrappedTsString, compilerOptions, false)} + end)().${returnExport}`; + + return executeLua(lua); +} diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 381a7b987..044e1bf82 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,7 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Transformation (callNamespace) 1`] = `"Namespace:myFunction()"`; - exports[`Transformation (characterEscapeSequence) 1`] = ` "local quoteInDoubleQuotes = \\"\\\\' \\\\' \\\\'\\" local quoteInTemplateString = \\"\\\\' \\\\' \\\\'\\" @@ -57,148 +55,6 @@ function ClassB.prototype.____constructor(self) end" `; -exports[`Transformation (continue) 1`] = ` -"do - local i = 0 - while i < 10 do - do - if i < 5 then - goto __continue1 - end - end - ::__continue1:: - i = i + 1 - end -end" -`; - -exports[`Transformation (continueConcurrent) 1`] = ` -"do - local i = 0 - while i < 10 do - do - if i < 5 then - goto __continue1 - end - if i == 7 then - goto __continue1 - end - end - ::__continue1:: - i = i + 1 - end -end" -`; - -exports[`Transformation (continueNested) 1`] = ` -"do - local i = 0 - while i < 5 do - do - if i % 2 == 0 then - goto __continue1 - end - do - local j = 0 - while j < 2 do - do - if j == 1 then - goto __continue3 - end - end - ::__continue3:: - j = j + 1 - end - end - end - ::__continue1:: - i = i + 1 - end -end" -`; - -exports[`Transformation (continueNestedConcurrent) 1`] = ` -"do - local i = 0 - while i < 5 do - do - if i % 2 == 0 then - goto __continue1 - end - do - local j = 0 - while j < 2 do - do - if j == 1 then - goto __continue3 - end - end - ::__continue3:: - j = j + 1 - end - end - if i == 4 then - goto __continue1 - end - end - ::__continue1:: - i = i + 1 - end -end" -`; - -exports[`Transformation (do) 1`] = ` -"local e = 10 -repeat - do - e = e - 1 - end -until not (e > 0)" -`; - -exports[`Transformation (enum) 1`] = ` -"TestEnum = {} -TestEnum.val1 = 0 -TestEnum[0] = \\"val1\\" -TestEnum.val2 = 2 -TestEnum[2] = \\"val2\\" -TestEnum.val3 = 3 -TestEnum[3] = \\"val3\\"" -`; - -exports[`Transformation (enumHeterogeneous) 1`] = ` -"TestEnum = {} -TestEnum.val1 = 0 -TestEnum[0] = \\"val1\\" -TestEnum.val2 = 3 -TestEnum[3] = \\"val2\\" -TestEnum.val3 = \\"baz\\" -TestEnum.baz = \\"val3\\"" -`; - -exports[`Transformation (enumMembersOnly) 1`] = ` -"val1 = 0 -val2 = 2 -val3 = 3 -val4 = \\"bye\\" -local a = val1" -`; - -exports[`Transformation (enumString) 1`] = ` -"TestEnum = {} -TestEnum.val1 = \\"foo\\" -TestEnum.foo = \\"val1\\" -TestEnum.val2 = \\"bar\\" -TestEnum.bar = \\"val2\\" -TestEnum.val3 = \\"baz\\" -TestEnum.baz = \\"val3\\"" -`; - -exports[`Transformation (exportEquals) 1`] = ` -"local ____exports = true -return ____exports" -`; - exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 @@ -225,77 +81,6 @@ end return ____exports" `; -exports[`Transformation (for) 1`] = ` -"do - local i = 1 - while i <= 100 do - i = i + 1 - end -end" -`; - -exports[`Transformation (forIn) 1`] = ` -"for i in pairs({a = 1, b = 2, c = 3, d = 4}) do -end" -`; - -exports[`Transformation (forOf) 1`] = ` -"for ____, i in ipairs({1, 2, 3, 4, 5, 6, 7, 8, 9, 10}) do -end" -`; - -exports[`Transformation (functionRestArguments) 1`] = ` -"function varargsFunction(self, a, ...) - local b = ({...}) - local c = b -end" -`; - -exports[`Transformation (getSetAccessors) 1`] = ` -"require(\\"lualib_bundle\\"); -MyClass = {} -MyClass.name = \\"MyClass\\" -MyClass.__index = MyClass -MyClass.prototype = {} -MyClass.prototype.____getters = {} -MyClass.prototype.__index = __TS__Index(MyClass.prototype) -MyClass.prototype.____setters = {} -MyClass.prototype.__newindex = __TS__NewIndex(MyClass.prototype) -MyClass.prototype.constructor = MyClass -function MyClass.new(...) - local self = setmetatable({}, MyClass.prototype) - self:____constructor(...) - return self -end -function MyClass.prototype.____constructor(self) -end -function MyClass.prototype.____getters.field(self) - return self._field + 4 -end -function MyClass.prototype.____setters.field(self, v) - self._field = v * 2 -end -local instance = MyClass.new() -instance.field = 4 -local b = instance.field -local c = (4 + instance.field) * 3" -`; - -exports[`Transformation (interfaceIndex) 1`] = ` -"local a = {} -a.abc = \\"def\\"" -`; - -exports[`Transformation (luaTable) 1`] = ` -"tbl = {} -tbl.value = 5 -local value = tbl.value -local tblLength = #tbl -itbl.value = 5 -local ivalue = itbl.value -local ilength = #tbl" -`; - exports[`Transformation (methodRestArguments) 1`] = ` "MyClass = {} MyClass.name = \\"MyClass\\" @@ -433,20 +218,6 @@ ____exports.TestSpace = {} return ____exports" `; -exports[`Transformation (modulesNamespaceExportEnum) 1`] = ` -"local ____exports = {} -____exports.test = {} -local test = ____exports.test -do - test.TestEnum = {} - test.TestEnum.foo = \\"foo\\" - test.TestEnum.foo = \\"foo\\" - test.TestEnum.bar = \\"bar\\" - test.TestEnum.bar = \\"bar\\" -end -return ____exports" -`; - exports[`Transformation (modulesNamespaceNestedWithMemberExport) 1`] = ` "local ____exports = {} ____exports.TestSpace = {} @@ -493,64 +264,6 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\""`; -exports[`Transformation (namespace) 1`] = ` -"myNamespace = myNamespace or {} -do - local function nsMember(self) - end -end" -`; - -exports[`Transformation (namespaceMerge) 1`] = ` -"MergedClass = {} -MergedClass.name = \\"MergedClass\\" -MergedClass.__index = MergedClass -MergedClass.prototype = {} -MergedClass.prototype.__index = MergedClass.prototype -MergedClass.prototype.constructor = MergedClass -function MergedClass.new(...) - local self = setmetatable({}, MergedClass.prototype) - self:____constructor(...) - return self -end -function MergedClass.prototype.____constructor(self) - self.propertyFunc = function() - end -end -function MergedClass.staticMethodA(self) -end -function MergedClass.staticMethodB(self) - self:staticMethodA() -end -function MergedClass.prototype.methodA(self) -end -function MergedClass.prototype.methodB(self) - self:methodA() - self:propertyFunc() -end -MergedClass = MergedClass or {} -do - function MergedClass.namespaceFunc(self) - end -end -local mergedClass = MergedClass.new() -mergedClass:methodB() -mergedClass:propertyFunc() -MergedClass:staticMethodB() -MergedClass:namespaceFunc()" -`; - -exports[`Transformation (namespaceNested) 1`] = ` -"myNamespace = myNamespace or {} -do - local myNestedNamespace = {} - do - local function nsMember(self) - end - end -end" -`; - exports[`Transformation (namespacePhantom) 1`] = ` "function nsMember(self) end" @@ -562,124 +275,7 @@ exports[`Transformation (returnDefault) 1`] = ` end" `; -exports[`Transformation (shorthandPropertyAssignment) 1`] = ` -"local f -f = function(____, x) return ({x = x}) end" -`; - -exports[`Transformation (spreadAssignment) 1`] = ` -"require(\\"lualib_bundle\\"); -local xy = __TS__ObjectAssign({x = 0, y = 1}) -local xyz = __TS__ObjectAssign({x = 0, y = 1}, {z = 2}) -local xyz2 = __TS__ObjectAssign({z = 2}, {x = 0, y = 1})" -`; - -exports[`Transformation (tryCatch) 1`] = ` -"do - local ____try, er = pcall( - function() - local a = 42 - end - ) - if not ____try then - local b = \\"fail\\" - end -end" -`; - -exports[`Transformation (tryCatchFinally) 1`] = ` -"do - local ____try, er = pcall( - function() - local a = 42 - end - ) - if not ____try then - local b = \\"fail\\" - end - do - local c = \\"finally\\" - end -end" -`; - -exports[`Transformation (tryFinally) 1`] = ` -"do - pcall( - function() - local a = 42 - end - ) - do - local b = \\"finally\\" - end -end" -`; - -exports[`Transformation (tupleReturn) 1`] = ` -"function tupleReturn(self) - return 0, \\"foobar\\" -end -tupleReturn(_G) -noTupleReturn(_G) -local a, b = tupleReturn(_G) -local c, d = table.unpack( - noTupleReturn(_G) -) -a, b = tupleReturn(_G) -c, d = table.unpack( - noTupleReturn(_G) -) -local e = ({ - tupleReturn(_G) -}) -local f = noTupleReturn(_G) -e = ({ - tupleReturn(_G) -}) -f = noTupleReturn(_G) -foo( - _G, - ({ - tupleReturn(_G) - }) -) -foo( - _G, - noTupleReturn(_G) -) -function tupleReturnFromVar(self) - local r = {1, \\"baz\\"} - return table.unpack(r) -end -function tupleReturnForward(self) - return tupleReturn(_G) -end -function tupleNoForward(self) - return ({ - tupleReturn(_G) - }) -end -function tupleReturnUnpack(self) - return table.unpack( - tupleNoForward(_G) - ) -end" -`; - -exports[`Transformation (typeAssert) 1`] = ` -"local test1 = 10 -local test2 = 10" -`; - exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` "local x = require(\\"module\\") local ____ = x" `; - -exports[`Transformation (while) 1`] = ` -"local d = 10 -while d > 0 do - d = d - 1 -end" -`; diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index d7467a78f..7a5088fcb 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -11,6 +11,8 @@ const fixtures = fs .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); test.each(fixtures)("Transformation (%s)", (_name, content) => { - const result = util.transpileString(content, { luaLibImport: tstl.LuaLibImportKind.Require }); - expect(result).toMatchSnapshot(); + util.testModule(content) + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); }); diff --git a/test/translation/transformation/callNamespace.ts b/test/translation/transformation/callNamespace.ts deleted file mode 100644 index 43ed32d6d..000000000 --- a/test/translation/transformation/callNamespace.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare namespace Namespace { - function myFunction(); -} -Namespace.myFunction(); diff --git a/test/translation/transformation/continue.ts b/test/translation/transformation/continue.ts deleted file mode 100644 index 64830718d..000000000 --- a/test/translation/transformation/continue.ts +++ /dev/null @@ -1,5 +0,0 @@ -for (let i = 0; i < 10; i++) { - if (i < 5) { - continue; - } -} diff --git a/test/translation/transformation/continueConcurrent.ts b/test/translation/transformation/continueConcurrent.ts deleted file mode 100644 index ef1b20c68..000000000 --- a/test/translation/transformation/continueConcurrent.ts +++ /dev/null @@ -1,9 +0,0 @@ -for (let i = 0; i < 10; i++) { - if (i < 5) { - continue; - } - - if (i === 7) { - continue; - } -} diff --git a/test/translation/transformation/continueNested.ts b/test/translation/transformation/continueNested.ts deleted file mode 100644 index 563b7d0f1..000000000 --- a/test/translation/transformation/continueNested.ts +++ /dev/null @@ -1,11 +0,0 @@ -for (let i = 0; i < 5; i++) { - if (i % 2 === 0) { - continue; - } - - for (let j = 0; j < 2; j++) { - if (j === 1) { - continue; - } - } -} diff --git a/test/translation/transformation/continueNestedConcurrent.ts b/test/translation/transformation/continueNestedConcurrent.ts deleted file mode 100644 index fe0bd0966..000000000 --- a/test/translation/transformation/continueNestedConcurrent.ts +++ /dev/null @@ -1,15 +0,0 @@ -for (let i = 0; i < 5; i++) { - if (i % 2 === 0) { - continue; - } - - for (let j = 0; j < 2; j++) { - if (j === 1) { - continue; - } - } - - if (i === 4) { - continue; - } -} diff --git a/test/translation/transformation/do.ts b/test/translation/transformation/do.ts deleted file mode 100644 index c17e3d1aa..000000000 --- a/test/translation/transformation/do.ts +++ /dev/null @@ -1,4 +0,0 @@ -let e = 10; -do { - e--; -} while (e > 0); diff --git a/test/translation/transformation/enum.ts b/test/translation/transformation/enum.ts deleted file mode 100644 index 3d48fbcfb..000000000 --- a/test/translation/transformation/enum.ts +++ /dev/null @@ -1,5 +0,0 @@ -enum TestEnum { - val1 = 0, - val2 = 2, - val3, -} diff --git a/test/translation/transformation/enumHeterogeneous.ts b/test/translation/transformation/enumHeterogeneous.ts deleted file mode 100644 index d4e69f10b..000000000 --- a/test/translation/transformation/enumHeterogeneous.ts +++ /dev/null @@ -1,5 +0,0 @@ -enum TestEnum { - val1, - val2 = 3, - val3 = "baz", -} diff --git a/test/translation/transformation/enumMembersOnly.ts b/test/translation/transformation/enumMembersOnly.ts deleted file mode 100644 index 9d384dc6c..000000000 --- a/test/translation/transformation/enumMembersOnly.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** @compileMembersOnly */ -enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", -} - -const a = TestEnum.val1; diff --git a/test/translation/transformation/enumString.ts b/test/translation/transformation/enumString.ts deleted file mode 100644 index 3d7d29747..000000000 --- a/test/translation/transformation/enumString.ts +++ /dev/null @@ -1,5 +0,0 @@ -enum TestEnum { - val1 = "foo", - val2 = "bar", - val3 = "baz", -} diff --git a/test/translation/transformation/exportEquals.ts b/test/translation/transformation/exportEquals.ts deleted file mode 100644 index ba27c6482..000000000 --- a/test/translation/transformation/exportEquals.ts +++ /dev/null @@ -1 +0,0 @@ -export = true; diff --git a/test/translation/transformation/for.ts b/test/translation/transformation/for.ts deleted file mode 100644 index a9dd48620..000000000 --- a/test/translation/transformation/for.ts +++ /dev/null @@ -1 +0,0 @@ -for (let i = 1; i <= 100; i++) {} diff --git a/test/translation/transformation/forIn.ts b/test/translation/transformation/forIn.ts deleted file mode 100644 index 8d1bff356..000000000 --- a/test/translation/transformation/forIn.ts +++ /dev/null @@ -1,7 +0,0 @@ -for (let i in { - a: 1, - b: 2, - c: 3, - d: 4, -}) { -} diff --git a/test/translation/transformation/forOf.ts b/test/translation/transformation/forOf.ts deleted file mode 100644 index c017d5c0c..000000000 --- a/test/translation/transformation/forOf.ts +++ /dev/null @@ -1,2 +0,0 @@ -for (let i of [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) { -} diff --git a/test/translation/transformation/functionRestArguments.ts b/test/translation/transformation/functionRestArguments.ts deleted file mode 100644 index 63649f09b..000000000 --- a/test/translation/transformation/functionRestArguments.ts +++ /dev/null @@ -1,3 +0,0 @@ -function varargsFunction(a: string, ...b: string[]): void { - const c = b; -} diff --git a/test/translation/transformation/getSetAccessors.ts b/test/translation/transformation/getSetAccessors.ts deleted file mode 100644 index d61f592a2..000000000 --- a/test/translation/transformation/getSetAccessors.ts +++ /dev/null @@ -1,14 +0,0 @@ -class MyClass { - private _field: number; - public get field(): number { - return this._field + 4; - } - public set field(v: number) { - this._field = v * 2; - } -} - -let instance = new MyClass(); -instance.field = 4; -const b = instance.field; -const c = (4 + instance.field) * 3; diff --git a/test/translation/transformation/interfaceIndex.ts b/test/translation/transformation/interfaceIndex.ts deleted file mode 100644 index f209e153e..000000000 --- a/test/translation/transformation/interfaceIndex.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare interface Dictionary { - [index: string]: T; -} - -let a: Dictionary = {}; -a["abc"] = "def"; diff --git a/test/translation/transformation/luaTable.ts b/test/translation/transformation/luaTable.ts deleted file mode 100644 index 06bd03cd2..000000000 --- a/test/translation/transformation/luaTable.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** @luaTable */ -declare class Table { - public readonly length: number; - public set(key: K, value: V): void; - public get(key: K): V; -} -declare let tbl: Table; -tbl = new Table(); -tbl.set("value", 5); -const value = tbl.get("value"); -const tblLength = tbl.length; - -/** @luaTable */ -declare interface InterfaceTable { - readonly length: number; - set(key: K, value: V): void; - get(key: K): V; -} - -declare const itbl: InterfaceTable; -itbl.set("value", 5); -const ivalue = itbl.get("value"); -const ilength = tbl.length; diff --git a/test/translation/transformation/modulesNamespaceExportEnum.ts b/test/translation/transformation/modulesNamespaceExportEnum.ts deleted file mode 100644 index 0c85b6872..000000000 --- a/test/translation/transformation/modulesNamespaceExportEnum.ts +++ /dev/null @@ -1,6 +0,0 @@ -export namespace test { - export enum TestEnum { - foo = "foo", - bar = "bar", - } -} diff --git a/test/translation/transformation/namespace.ts b/test/translation/transformation/namespace.ts deleted file mode 100644 index 24f4a78e0..000000000 --- a/test/translation/transformation/namespace.ts +++ /dev/null @@ -1,3 +0,0 @@ -namespace myNamespace { - function nsMember() {} -} diff --git a/test/translation/transformation/namespaceMerge.ts b/test/translation/transformation/namespaceMerge.ts deleted file mode 100644 index b6905def9..000000000 --- a/test/translation/transformation/namespaceMerge.ts +++ /dev/null @@ -1,24 +0,0 @@ -class MergedClass { - public static staticMethodA(): void {} - public static staticMethodB(): void { - this.staticMethodA(); - } - - public propertyFunc: () => void = () => {}; - - public methodA(): void {} - public methodB(): void { - this.methodA(); - this.propertyFunc(); - } -} - -namespace MergedClass { - export function namespaceFunc(): void {} -} - -const mergedClass = new MergedClass(); -mergedClass.methodB(); -mergedClass.propertyFunc(); -MergedClass.staticMethodB(); -MergedClass.namespaceFunc(); diff --git a/test/translation/transformation/namespaceNested.ts b/test/translation/transformation/namespaceNested.ts deleted file mode 100644 index 85869547f..000000000 --- a/test/translation/transformation/namespaceNested.ts +++ /dev/null @@ -1,5 +0,0 @@ -namespace myNamespace { - namespace myNestedNamespace { - function nsMember() {} - } -} diff --git a/test/translation/transformation/shorthandPropertyAssignment.ts b/test/translation/transformation/shorthandPropertyAssignment.ts deleted file mode 100644 index 4b2aa7e82..000000000 --- a/test/translation/transformation/shorthandPropertyAssignment.ts +++ /dev/null @@ -1 +0,0 @@ -const f = x => ({ x }); diff --git a/test/translation/transformation/spreadAssignment.ts b/test/translation/transformation/spreadAssignment.ts deleted file mode 100644 index 0ad87be82..000000000 --- a/test/translation/transformation/spreadAssignment.ts +++ /dev/null @@ -1,3 +0,0 @@ -const xy = { ...{ x: 0, y: 1 } }; -const xyz = { ...{ x: 0, y: 1 }, z: 2 }; -const xyz2 = { z: 2, ...{ x: 0, y: 1 } }; diff --git a/test/translation/transformation/tryCatch.ts b/test/translation/transformation/tryCatch.ts deleted file mode 100644 index d5e2f1310..000000000 --- a/test/translation/transformation/tryCatch.ts +++ /dev/null @@ -1,5 +0,0 @@ -try { - let a = 42; -} catch (er) { - let b = "fail"; -} diff --git a/test/translation/transformation/tryCatchFinally.ts b/test/translation/transformation/tryCatchFinally.ts deleted file mode 100644 index dfbd57c7f..000000000 --- a/test/translation/transformation/tryCatchFinally.ts +++ /dev/null @@ -1,7 +0,0 @@ -try { - let a = 42; -} catch (er) { - let b = "fail"; -} finally { - let c = "finally"; -} diff --git a/test/translation/transformation/tryFinally.ts b/test/translation/transformation/tryFinally.ts deleted file mode 100644 index d33f4b95a..000000000 --- a/test/translation/transformation/tryFinally.ts +++ /dev/null @@ -1,5 +0,0 @@ -try { - let a = 42; -} finally { - let b = "finally"; -} diff --git a/test/translation/transformation/tupleReturn.ts b/test/translation/transformation/tupleReturn.ts deleted file mode 100644 index 75b7fbf01..000000000 --- a/test/translation/transformation/tupleReturn.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** @tupleReturn */ -function tupleReturn(): [number, string] { - return [0, "foobar"]; -} -declare function noTupleReturn(): [number, string]; -declare function foo(a: [number, string]): void; -tupleReturn(); -noTupleReturn(); -let [a, b] = tupleReturn(); -let [c, d] = noTupleReturn(); -[a, b] = tupleReturn(); -[c, d] = noTupleReturn(); -let e = tupleReturn(); -let f = noTupleReturn(); -e = tupleReturn(); -f = noTupleReturn(); -foo(tupleReturn()); -foo(noTupleReturn()); -/** @tupleReturn */ -function tupleReturnFromVar(): [number, string] { - const r: [number, string] = [1, "baz"]; - return r; -} -/** @tupleReturn */ -function tupleReturnForward(): [number, string] { - return tupleReturn(); -} -function tupleNoForward(): [number, string] { - return tupleReturn(); -} -/** @tupleReturn */ -function tupleReturnUnpack(): [number, string] { - return tupleNoForward(); -} diff --git a/test/translation/transformation/typeAssert.ts b/test/translation/transformation/typeAssert.ts deleted file mode 100644 index 4b654d851..000000000 --- a/test/translation/transformation/typeAssert.ts +++ /dev/null @@ -1,2 +0,0 @@ -const test1 = 10; -const test2 = 10 as number; diff --git a/test/translation/transformation/while.ts b/test/translation/transformation/while.ts deleted file mode 100644 index 4014a4add..000000000 --- a/test/translation/transformation/while.ts +++ /dev/null @@ -1,4 +0,0 @@ -let d = 10; -while (d > 0) { - d--; -} diff --git a/test/tsconfig.json b/test/tsconfig.json index b22f71bc9..700c9d291 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -8,6 +8,7 @@ "target": "es2017", "lib": ["es2017"], "types": ["node", "jest"], + "experimentalDecorators": true, "noEmit": true, "module": "commonjs" diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap new file mode 100644 index 000000000..db8863e35 --- /dev/null +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -0,0 +1,404 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Binary expressions ordering parentheses ("-1+1") 1`] = ` +"local ____exports = {} +____exports.__result = -1 + 1 +return ____exports" +`; + +exports[`Binary expressions ordering parentheses ("1*(3+4)") 1`] = ` +"local ____exports = {} +____exports.__result = 1 * (3 + 4) +return ____exports" +`; + +exports[`Binary expressions ordering parentheses ("1*(3+4*2)") 1`] = ` +"local ____exports = {} +____exports.__result = 1 * (3 + 4 * 2) +return ____exports" +`; + +exports[`Binary expressions ordering parentheses ("1*30+4") 1`] = ` +"local ____exports = {} +____exports.__result = 1 * 30 + 4 +return ____exports" +`; + +exports[`Binary expressions ordering parentheses ("1+1") 1`] = ` +"local ____exports = {} +____exports.__result = 1 + 1 +return ____exports" +`; + +exports[`Binary expressions ordering parentheses ("10-(4+5)") 1`] = ` +"local ____exports = {} +____exports.__result = 10 - (4 + 5) +return ____exports" +`; + +exports[`Bitop [5.2] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.bnot(a) +return ____exports" +`; + +exports[`Bitop [5.2] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.band(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.band(a, b) +return ____exports" +`; + +exports[`Bitop [5.2] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.lshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a<>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.arshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a>>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.rshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.rshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.2] ("a>>b") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.arshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.2] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.bxor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.bxor(a, b) +return ____exports" +`; + +exports[`Bitop [5.2] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit32.bor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.2] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = bit32.bor(a, b) +return ____exports" +`; + +exports[`Bitop [5.3] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = ~a +return ____exports" +`; + +exports[`Bitop [5.3] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a & b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.3] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = a & b +return ____exports" +`; + +exports[`Bitop [5.3] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a << b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.3] ("a<>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.3] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Bitop [5.3] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a ~ b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.3] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = a ~ b +return ____exports" +`; + +exports[`Bitop [5.3] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a | b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.3] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = a | b +return ____exports" +`; + +exports[`Bitop [JIT] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = bit.bnot(a) +return ____exports" +`; + +exports[`Bitop [JIT] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.band(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = bit.band(a, b) +return ____exports" +`; + +exports[`Bitop [JIT] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.lshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a<>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.arshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a>>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.rshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = bit.rshift(a, b) +return ____exports" +`; + +exports[`Bitop [JIT] ("a>>b") 1`] = ` +"local ____exports = {} +____exports.__result = bit.arshift(a, b) +return ____exports" +`; + +exports[`Bitop [JIT] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.bxor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = bit.bxor(a, b) +return ____exports" +`; + +exports[`Bitop [JIT] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.bor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [JIT] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = bit.bor(a, b) +return ____exports" +`; + +exports[`Unary expressions basic ("!a") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = not a +end +return ____exports" +`; + +exports[`Unary expressions basic ("++i") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + i = i + 1 +end +return ____exports" +`; + +exports[`Unary expressions basic ("+a") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = a +end +return ____exports" +`; + +exports[`Unary expressions basic ("--i") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + i = i - 1 +end +return ____exports" +`; + +exports[`Unary expressions basic ("-a") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = -a +end +return ____exports" +`; + +exports[`Unary expressions basic ("delete tbl.test") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + tbl.test = nil +end +return ____exports" +`; + +exports[`Unary expressions basic ("delete tbl['test']") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + tbl.test = nil +end +return ____exports" +`; + +exports[`Unary expressions basic ("i++") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + i = i + 1 +end +return ____exports" +`; + +exports[`Unary expressions basic ("i--") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + i = i - 1 +end +return ____exports" +`; + +exports[`Unary expressions basic ("let a = delete tbl.test") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local a = (function() + tbl.test = nil + return true + end)() +end +return ____exports" +`; + +exports[`Unary expressions basic ("let a = delete tbl['test']") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local a = (function() + tbl.test = nil + return true + end)() +end +return ____exports" +`; diff --git a/test/unit/array.spec.ts b/test/unit/array.spec.ts deleted file mode 100644 index 6b1b653a9..000000000 --- a/test/unit/array.spec.ts +++ /dev/null @@ -1,263 +0,0 @@ -import * as util from "../util"; - -test("Array access", () => { - const result = util.transpileAndExecute( - `const arr: Array = [3,5,1]; - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("ReadonlyArray access", () => { - const result = util.transpileAndExecute( - `const arr: ReadonlyArray = [3,5,1]; - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Array literal access", () => { - const result = util.transpileAndExecute( - `const arr: number[] = [3,5,1]; - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Readonly array literal access", () => { - const result = util.transpileAndExecute( - `const arr: readonly number[] = [3,5,1]; - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Array union access", () => { - const result = util.transpileAndExecute( - `function makeArray(): number[] | string[] { return [3,5,1]; } - const arr = makeArray(); - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Array union access with empty tuple", () => { - const result = util.transpileAndExecute( - `function makeArray(): number[] | [] { return [3,5,1]; } - const arr = makeArray(); - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Array union length", () => { - const result = util.transpileAndExecute( - `function makeArray(): number[] | string[] { return [3,5,1]; } - const arr = makeArray(); - return arr.length;` - ); - expect(result).toBe(3); -}); - -test("Array intersection access", () => { - const result = util.transpileAndExecute( - `type I = number[] & {foo: string}; - function makeArray(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const arr = makeArray(); - return arr[1];` - ); - expect(result).toBe(5); -}); - -test("Array intersection length", () => { - const result = util.transpileAndExecute( - `type I = number[] & {foo: string}; - function makeArray(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const arr = makeArray(); - return arr.length;` - ); - expect(result).toBe(3); -}); - -test.each([ - { member: "firstElement()", expected: 3 }, - { member: "name", expected: "array" }, - { member: "length", expected: 1 }, -])("Derived array access (%p)", ({ member, expected }) => { - const luaHeader = `local arr = {name="array", firstElement=function(self) return self[1]; end};`; - const typeScriptHeader = ` - interface CustomArray extends Array{ - name:string, - firstElement():number; - }; - declare const arr: CustomArray; - `; - - const result = util.transpileAndExecute( - ` - arr[0] = 3; - return arr.${member};`, - undefined, - luaHeader, - typeScriptHeader - ); - - expect(result).toBe(expected); -}); - -test("Array delete", () => { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - delete myarray[2]; - return \`\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - expect(result).toBe("1,2,nil,4"); -}); - -test("Array delete return true", () => { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - const exists = delete myarray[2]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - expect(result).toBe("true:1,2,nil,4"); -}); - -test("Array delete return false", () => { - const result = util.transpileAndExecute( - `const myarray = [1,2,3,4]; - const exists = delete myarray[4]; - return \`\${exists}:\${myarray[0]},\${myarray[1]},\${myarray[2]},\${myarray[3]}\`;` - ); - - expect(result).toBe("true:1,2,3,4"); -}); - -test("Array property access", () => { - const code = ` - type A = number[] & {foo?: string}; - const a: A = [1,2,3]; - a.foo = "bar"; - return \`\${a.foo}\${a[0]}\${a[1]}\${a[2]}\`; - `; - expect(util.transpileAndExecute(code)).toBe("bar123"); -}); - -test.each([{ length: 0, result: 0 }, { length: 1, result: 1 }, { length: 7, result: 3 }])( - "Array length set", - ({ length, result }) => { - const code = ` - const arr = [1, 2, 3]; - arr.length = ${length}; - return arr.length; - `; - expect(util.transpileAndExecute(code)).toBe(result); - } -); - -test.each([{ length: 0, result: "0/0" }, { length: 1, result: "1/1" }, { length: 7, result: "7/3" }])( - "Array length set as expression", - ({ length, result }) => { - const code = ` - const arr = [1, 2, 3]; - const l = arr.length = ${length}; - return \`\${l}/\${arr.length}\`; - `; - expect(util.transpileAndExecute(code)).toBe(result); - } -); - -test.each([ - { length: -1, result: -1 }, - { length: -7, result: -7 }, - { length: 0.1, result: 0.1 }, - { length: "0 / 0", result: "NaN" }, - { length: "1 / 0", result: "Infinity" }, - { length: "-1 / 0", result: "-Infinity" }, -])("Invalid array length set", ({ length, result }) => { - const code = ` - const arr = [1, 2, 3]; - arr.length = ${length}; - `; - expect(() => util.transpileAndExecute(code)).toThrowError(`invalid array length: ${result}`); -}); - -test.each([0, 1, 2])("Array with OmittedExpression", index => { - const result = util.transpileAndExecute( - `const myarray = [1, , 2]; - return myarray[${index}];` - ); - - expect(result).toBe([1, , 2][index]); -}); - -test("OmittedExpression in Array Binding Assignment Statement", () => { - const result = util.transpileAndExecute( - `let a, c; - [a, , c] = [1, 2, 3]; - return a + c;` - ); - - expect(result).toBe(4); -}); - -test("array access call", () => { - const code = ` - const arr = [() => "foo", () => "bar"]; - return arr[1]();`; - expect(util.transpileAndExecute(code)).toBe("bar"); -}); - -test.each([`["foo", "bar"].length`, `["foo", "bar"][0]`, `[() => "foo", () => "bar"][0]()`])( - "array literal property access (%p)", - expression => { - const code = `return ${expression}`; - const expectResult = eval(expression); - expect(util.transpileAndExecute(code)).toBe(expectResult); - } -); - -const genericChecks = [ - "function generic(array: T)", - "function generic(array: T)", - "function generic(array: T[])", - "type ArrayType = number[]; function generic(array: T)", - "function generic(array: T & {})", - "function generic(array: T)", -]; - -test.each(genericChecks)("array constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - let sum = 0; - array.forEach(item => { - if (typeof item === "number") { - sum += item; - } - }); - return sum; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(6); -}); - -test.each(genericChecks)("array constrained generic length (%p)", signature => { - const code = ` - ${signature}: number { - return array.length; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(3); -}); diff --git a/test/unit/assignmentDestructuring.spec.ts b/test/unit/assignmentDestructuring.spec.ts deleted file mode 100644 index 908a4eac9..000000000 --- a/test/unit/assignmentDestructuring.spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -import * as tstl from "../../src"; -import * as util from "../util"; - -const assignmentDestruturingTs = ` - declare function myFunc(this: void): [number, string]; - let [a, b] = myFunc();`; - -test("Assignment destructuring [5.1]", () => { - const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: tstl.LuaTarget.Lua51, - luaLibImport: tstl.LuaLibImportKind.None, - }); - expect(lua).toBe(`local a, b = unpack(\n myFunc()\n)`); -}); - -test("Assignment destructuring [5.2]", () => { - const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: tstl.LuaTarget.Lua52, - luaLibImport: tstl.LuaLibImportKind.None, - }); - expect(lua).toBe(`local a, b = table.unpack(\n myFunc()\n)`); -}); - -test("Assignment destructuring [JIT]", () => { - const lua = util.transpileString(assignmentDestruturingTs, { - luaTarget: tstl.LuaTarget.LuaJIT, - luaLibImport: tstl.LuaLibImportKind.None, - }); - expect(lua).toBe(`local a, b = unpack(\n myFunc()\n)`); -}); - -test.each([ - "function foo(): [] { return []; }; let [] = foo();", - "let [] = ['a', 'b', 'c'];", - "let [] = [];", - "let [] = [] = [];", - "function foo(): [] { return []; }; [] = foo();", - "[] = ['a', 'b', 'c'];", - "[] = [];", - "[] = [] = [];", -])("Empty destructuring (%p)", code => { - expect(() => util.transpileAndExecute(code)).not.toThrow(); -}); - -test("Union destructuring", () => { - const code = ` - function foo(): [string] | [] { return ["bar"]; } - let x: string; - [x] = foo(); - return x; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); -}); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts new file mode 100644 index 000000000..9bb53c78c --- /dev/null +++ b/test/unit/assignments.spec.ts @@ -0,0 +1,292 @@ +import * as util from "../util"; + +test("Const assignment (%p)", () => { + const lua = util.transpileString(`const foo = true;`); + expect(lua).toBe(`local foo = true`); +}); + +test("Let assignment (%p)", () => { + const lua = util.transpileString(`let foo = true;`); + expect(lua).toBe(`local foo = true`); +}); + +test("Var assignment (%p)", () => { + const lua = util.transpileString(`var foo = true;`); + expect(lua).toBe(`foo = true`); +}); + +test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = undefined;"])( + "Null assignments (%p)", + declaration => { + const result = util.transpileAndExecute(declaration + " return myvar;"); + expect(result).toBe(undefined); + } +); + +test.each(["x = y", "x += y"])("Assignment expressions (%p)", expression => { + util.testFunction` + let x = "x"; + let y = "y"; + return ${expression}; + `.expectToMatchJsResult(); +}); + +test.each(["x = o.p", "x = a[0]", "x = y = o.p", "x = o.p"])("Assignment expressions using temp (%p)", expression => { + util.testFunction` + let x = "x"; + let y = "y"; + let o = {p: "o"}; + let a = ["a"]; + return ${expression}; + `.expectToMatchJsResult(); +}); + +test.each(["o.p = x", "a[0] = x", "o.p = a[0]", "o.p = a[0] = x"])( + "Property assignment expressions (%p)", + expression => { + util.testFunction` + let x = "x"; + let o = {p: "o"}; + let a = ["a"]; + return ${expression}; + `.expectToMatchJsResult(); + } +); + +test.each([ + "x = t()", + "x = tr()", + "[x[1], x[0]] = t()", + "[x[1], x[0]] = tr()", + "x = [y[1], y[0]]", + "[x[0], x[1]] = [y[1], y[0]]", +])("Tuple assignment expressions (%p)", expression => { + util.testFunction` + let x: [string, string] = ["x0", "x1"]; + let y: [string, string] = ["y0", "y1"]; + function t(): [string, string] { return ["t0", "t1"] }; + /** @tupleReturn */ + function tr(): [string, string] { return ["tr0", "tr1"] }; + const r = ${expression}; + return \`\${r[0]},\${r[1]}\` + `.expectToMatchJsResult(); +}); + +test.each([ + "++x", + "x++", + "--x", + "x--", + "x += y", + "x -= y", + "x *= y", + "y /= x", + "y %= x", + "y **= x", + "x |= y", + "x &= y", + "x ^= y", + "x <<= y", + "x >>>= y", +])("Operator assignment statements (%p)", statement => { + util.testFunction` + let x = 3; + let y = 6; + ${statement}; + return { x, y }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++o.p", + "o.p++", + "--o.p", + "o.p--", + "o.p += a[0]", + "o.p -= a[0]", + "o.p *= a[0]", + "a[0] /= o.p", + "a[0] %= o.p", + "a[0] **= o.p", + "o.p |= a[0]", + "o.p &= a[0]", + "o.p ^= a[0]", + "o.p <<= a[0]", + "o.p >>>= a[0]", +])("Operator assignment to simple property statements (%p)", statement => { + util.testFunction` + let o = { p: 3 }; + let a = [6]; + ${statement}; + return { o, a }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++o.p.d", + "o.p.d++", + "--o.p.d", + "o.p.d--", + "o.p.d += a[0][0]", + "o.p.d -= a[0][0]", + "o.p.d *= a[0][0]", + "a[0][0] /= o.p.d", + "a[0][0] %= o.p.d", + "a[0][0] **= o.p.d", + "o.p.d |= a[0][0]", + "o.p.d &= a[0][0]", + "o.p.d ^= a[0][0]", + "o.p.d <<= a[0][0]", + "o.p.d >>>= a[0][0]", +])("Operator assignment to deep property statements (%p)", statement => { + util.testFunction` + let o = { p: { d: 3 } }; + let a = [[6,11], [7,13]]; + ${statement}; + return { o, a }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++of().p", + "of().p++", + "--of().p", + "of().p--", + "of().p += af()[i()]", + "of().p -= af()[i()]", + "of().p *= af()[i()]", + "af()[i()] /= of().p", + "af()[i()] %= of().p", + "af()[i()] **= of().p", + "of().p |= af()[i()]", + "of().p &= af()[i()]", + "of().p ^= af()[i()]", + "of().p <<= af()[i()]", + "of().p >>>= af()[i()]", +])("Operator assignment to complex property statements (%p)", statement => { + util.testFunction` + let o = { p: 3 }; + let a = [6]; + function of() { return o; } + function af() { return a; } + function i() { return 0; } + ${statement}; + return { o, a }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++of().p.d", + "of().p.d++", + "--of().p.d", + "of().p.d--", + "of().p.d += af()[i()][i()]", + "of().p.d -= af()[i()][i()]", + "of().p.d *= af()[i()][i()]", + "af()[i()][i()] /= of().p.d", + "af()[i()][i()] %= of().p.d", + "af()[i()][i()] **= of().p.d", + "of().p.d |= af()[i()][i()]", + "of().p.d &= af()[i()][i()]", + "of().p.d ^= af()[i()][i()]", + "of().p.d <<= af()[i()][i()]", + "of().p.d >>>= af()[i()][i()]", +])("Operator assignment to complex deep property statements (%p)", statement => { + util.testFunction` + let o = { p: { d: 3 } }; + let a = [[7, 6], [11, 13]]; + function of() { return o; } + function af() { return a; } + let _i = 0; + function i() { return _i++; } + ${statement}; + return { o, a, _i }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++x", + "x++", + "--x", + "x--", + "x += y", + "x -= y", + "x *= y", + "y /= x", + "y %= x", + "y **= x", + "x |= y", + "x &= y", + "x ^= y", + "x <<= y", + "x >>>= y", + "x + (y += 7)", + "x + (y += 7)", + "x++ + (y += 7)", +])("Operator assignment expressions (%p)", expression => { + util.testFunction` + let x = 3; + let y = 6; + const r = ${expression}; + return { r, x, y }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++o.p", + "o.p++", + "--o.p", + "o.p--", + "o.p += a[0]", + "o.p -= a[0]", + "o.p *= a[0]", + "a[0] /= o.p", + "a[0] %= o.p", + "a[0] **= o.p", + "o.p |= a[0]", + "o.p &= a[0]", + "o.p ^= a[0]", + "o.p <<= a[0]", + "o.p >>>= a[0]", + "o.p + (a[0] += 7)", + "o.p += (a[0] += 7)", + "o.p++ + (a[0] += 7)", +])("Operator assignment to simple property expressions (%p)", expression => { + util.testFunction` + let o = { p: 3 }; + let a = [6]; + const r = ${expression}; + return { r, o, a }; + `.expectToMatchJsResult(); +}); + +test.each([ + "++of().p", + "of().p++", + "--of().p", + "of().p--", + "of().p += af()[i()]", + "of().p -= af()[i()]", + "of().p *= af()[i()]", + "af()[i()] /= of().p", + "af()[i()] %= of().p", + "af()[i()] **= of().p", + "of().p |= af()[i()]", + "of().p &= af()[i()]", + "of().p ^= af()[i()]", + "of().p <<= af()[i()]", + "of().p >>>= af()[i()]", + "of().p + (af()[i()] += 7)", + "of().p += (af()[i()] += 7)", + "of().p++ + (af()[i()] += 7)", +])("Operator assignment to complex property expressions (%p)", expression => { + util.testFunction` + let o = { p: 3 }; + let a = [6]; + function of() { return o; } + function af() { return a; } + function i() { return 0; } + const r = ${expression}; + return { r, o, a }; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/assignments/assignments.spec.ts b/test/unit/assignments/assignments.spec.ts deleted file mode 100644 index c5da9beff..000000000 --- a/test/unit/assignments/assignments.spec.ts +++ /dev/null @@ -1,186 +0,0 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; -import * as util from "../../util"; - -test.each([ - { inp: `"abc"`, out: `"abc"` }, - { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, - { inp: "true", out: "true" }, - { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, -])("Const assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`const myvar = ${inp}`); - expect(lua).toBe(`local myvar = ${out}`); -}); - -test.each([ - { inp: `"abc"`, out: `"abc"` }, - { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, - { inp: "true", out: "true" }, - { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, -])("Let assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`let myvar = ${inp}`); - expect(lua).toBe(`local myvar = ${out}`); -}); - -test.each([ - { inp: `"abc"`, out: `"abc"` }, - { inp: "3", out: "3" }, - { inp: "[1,2,3]", out: "{1, 2, 3}" }, - { inp: "true", out: "true" }, - { inp: "false", out: "false" }, - { inp: `{a:3,b:"4"}`, out: `{a = 3, b = "4"}` }, -])("Var assignment (%p)", ({ inp, out }) => { - const lua = util.transpileString(`var myvar = ${inp}`); - expect(lua).toBe(`myvar = ${out}`); -}); - -test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = undefined;"])( - "Null assignments (%p)", - declaration => { - const result = util.transpileAndExecute(declaration + " return myvar;"); - expect(result).toBe(undefined); - } -); - -test.each([ - { input: ["a", "b"], values: ["e", "f"] }, - { input: ["a", "b"], values: ["e", "f", "g"] }, - { input: ["a", "b", "c"], values: ["e", "f", "g"] }, -])("Binding pattern assignment (%p)", ({ input, values }) => { - const pattern = input.join(","); - const initializer = values.map(v => `"${v}"`).join(","); - - const tsCode = `const [${pattern}] = [${initializer}]; return [${pattern}].join("-");`; - const result = util.transpileAndExecute(tsCode); - - expect(result).toBe(values.slice(0, input.length).join("-")); -}); - -test("Ellipsis binding pattern", () => { - expect(() => util.transpileString("let [a,b,...c] = [1,2,3];")).toThrowExactError( - TSTLErrors.ForbiddenEllipsisDestruction(util.nodeStub) - ); -}); - -test("Tuple Assignment", () => { - const code = ` - function abc(): [number, number] { return [1, 2]; }; - let t: [number, number] = abc(); - return t[0] + t[1]; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(3); -}); - -test("TupleReturn assignment", () => { - const code = ` - /** @tupleReturn */ - declare function abc(this: void): number[] - let [a,b] = abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = abc()"); -}); - -test("TupleReturn Single assignment", () => { - const code = ` - /** @tupleReturn */ - declare function abc(this: void): [number, string]; - let a = abc(); - a = abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); -}); - -test("TupleReturn interface assignment", () => { - const code = ` - interface def { - /** @tupleReturn */ - abc(); - } declare const jkl : def; - let [a,b] = jkl.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = jkl:abc()"); -}); - -test("TupleReturn namespace assignment", () => { - const code = ` - declare namespace def { - /** @tupleReturn */ - function abc(this: void) {} - } - let [a,b] = def.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = def.abc()"); -}); - -test("TupleReturn method assignment", () => { - const code = ` - declare class def { - /** @tupleReturn */ - abc() { return [1,2,3]; } - } const jkl = new def(); - let [a,b] = jkl.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); -}); - -test("TupleReturn functional", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const [a, b] = abc(); - return b + a; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); - -test("TupleReturn single", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const res = abc(); - return res.length - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe(2); -}); - -test("TupleReturn in expression", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - return abc()[1] + abc()[0]; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); - -test("String table access", () => { - const code = ` - const dict : {[key:string]:any} = {}; - dict["a b"] = 3; - return dict["a b"]; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(3); -}); diff --git a/test/unit/bindingpatterns.spec.ts b/test/unit/bindingpatterns.spec.ts deleted file mode 100644 index 39684ae50..000000000 --- a/test/unit/bindingpatterns.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import * as util from "../util"; - -const testCases = [ - { bindingString: "{x}", objectString: "{x: true}", returnVariable: "x" }, - { bindingString: "[x, y]", objectString: "[false, true]", returnVariable: "y" }, - { bindingString: "{x: [y, z]}", objectString: "{x: [false, true]}", returnVariable: "z" }, - { bindingString: "{x: [, z]}", objectString: "{x: [false, true]}", returnVariable: "z" }, - { bindingString: "{x: [{y}]}", objectString: "{x: [{y: true}]}", returnVariable: "y" }, - { bindingString: "[[y, z]]", objectString: "[[false, true]]", returnVariable: "z" }, - { bindingString: "{x, y}", objectString: "{x: false, y: true}", returnVariable: "y" }, - { bindingString: "{x: foo, y}", objectString: "{x: true, y: false}", returnVariable: "foo" }, - { bindingString: "{x: foo, y: bar}", objectString: "{x: false, y: true}", returnVariable: "bar" }, - { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: true, y: false}, z: false}", returnVariable: "x" }, - { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: false, y: true}, z: false}", returnVariable: "y" }, - { bindingString: "{x: {x, y}, z}", objectString: "{x: {x: false, y: false}, z: true}", returnVariable: "z" }, -]; - -const testCasesDefault = [ - { bindingString: "{x = true}", objectString: "{}", returnVariable: "x" }, - { bindingString: "{x, y = true}", objectString: "{x: false}", returnVariable: "y" }, - { bindingString: "[x = true, y = false]", objectString: "[undefined, undefined]", returnVariable: "x" }, - { bindingString: "[x = false, y = false]", objectString: "[false, true]", returnVariable: "y" }, -]; - -test.each([ - { bindingString: "{x, y}, z", objectString: "{x: false, y: false}, true", returnVariable: "z" }, - { bindingString: "{x, y}, {z}", objectString: "{x: false, y: false}, {z: true}", returnVariable: "z" }, - ...testCases, - ...testCasesDefault, -])("Object bindings in functions (%p)", ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileAndExecute(` - function test(${bindingString}) { - return ${returnVariable}; - } - return test(${objectString}); - `); - expect(result).toBe(true); -}); - -test.each([...testCases, ...testCasesDefault])( - "testBindingPatternDeclarations (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileAndExecute(` - let ${bindingString} = ${objectString}; - return ${returnVariable}; - `); - expect(result).toBe(true); - } -); - -test.each([...testCases, ...testCasesDefault])( - "testBindingPatternExportDeclarations (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileExecuteAndReturnExport( - `export const ${bindingString} = ${objectString};`, - returnVariable - ); - expect(result).toBe(true); - } -); - -test.each(testCases)( - "Object bindings with call expressions (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileAndExecute(` - function call() { - return ${objectString}; - } - let ${bindingString} = call(); - return ${returnVariable}; - `); - expect(result).toBe(true); - } -); - -test.each([ - { bindingString: "{x, y = true}", objectString: "{x: false, y: false}", returnVariable: "y" }, - { bindingString: "{x, y: [z = true]}", objectString: "{x: false, y: [false]}", returnVariable: "z" }, - { bindingString: "[x = true]", objectString: "[false]", returnVariable: "x" }, -])("Binding patterns handle false correctly (%p)", ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileExecuteAndReturnExport( - `export const ${bindingString} = ${objectString};`, - returnVariable - ); - expect(result).toBe(false); -}); - -const assignmentBindingPatterns = [ - { bindingString: "{x: obj.prop}", objectString: "{x: true}", returnVariable: "obj.prop" }, - { - bindingString: "{x: obj.prop = true}", - objectString: "{x: undefined}", - returnVariable: "obj.prop", - }, - { bindingString: "[{x: obj.prop}]", objectString: "[{x: true}]", returnVariable: "obj.prop" }, - { - bindingString: "{obj: {prop: obj.prop}}", - objectString: "{obj: {prop: true}}", - returnVariable: "obj.prop", - }, - { bindingString: "{x = true}", objectString: "{}", returnVariable: "x" }, - { - bindingString: "{x: {[2 + 1]: y}}", - objectString: "{x: {[2 + 1]: true}}", - returnVariable: "y", - }, -]; - -test.each([...assignmentBindingPatterns, ...testCases])( - "Binding pattern expressions (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileAndExecute(` - let x, y, z, foo, bar, obj: { prop: boolean }; - obj = { prop: false }; - (${bindingString} = ${objectString}) - return ${returnVariable}; - `); - expect(result).toBe(true); - } -); - -test.each([...assignmentBindingPatterns, ...testCases])( - "Binding patterns expressions pass conditional checks (%p)", - ({ bindingString, objectString, returnVariable }) => { - const result = util.transpileAndExecute(` - let x, y, z, foo, bar, obj: { prop: boolean }; - obj = { prop: false }; - if (${bindingString} = ${objectString}) { - return ${returnVariable}; - } - `); - expect(result).toBe(true); - } -); - -test.each([ - { bindingString: "{ x: x.prop = true } = {}", returnValue: "x.prop", expectedResult: true }, - { - bindingString: "{ x: x.prop = true } = {}", - returnValue: "typeof y === 'object'", - expectedResult: true, - }, - { - bindingString: "{ x: x.prop = false } = { x: true }", - returnValue: "x.prop", - expectedResult: true, - }, -])("Binding pattern assignment pass-through (%p)", ({ bindingString, returnValue, expectedResult }) => { - const result = util.transpileAndExecute(` - let x: any = {}, y: any = {}; - y = ${bindingString}; - return ${returnValue}; - `); - expect(result).toBe(expectedResult); -}); - -test("Array binding pattern to assign array length (%p)", () => { - const result = util.transpileAndExecute(` - let x = [0, 1, 2]; - [x.length] = [0]; - return x.length; - `); - expect(result).toBe(0); -}); - -test("Nested array binding pattern to assign array length (%p)", () => { - const result = util.transpileAndExecute(` - let x = [0, 1, 2]; - [[x.length]] = [[0]]; - return x.length; - `); - expect(result).toBe(0); -}); - -test("Object binding pattern to assign array length (%p)", () => { - const result = util.transpileAndExecute(` - let x = [0, 1, 2]; - ({ x: x.length } = { x: 0 }); - return x.length; - `); - expect(result).toBe(0); -}); - -test("Nested object binding pattern to assign array length (%p)", () => { - const result = util.transpileAndExecute(` - let x = [0, 1, 2]; - ({ x: { x: x.length } } = { x: { x: 0 } }); - return x.length; - `); - expect(result).toBe(0); -}); diff --git a/test/unit/builtins/__snapshots__/console.spec.ts.snap b/test/unit/builtins/__snapshots__/console.spec.ts.snap new file mode 100644 index 000000000..64baea0f4 --- /dev/null +++ b/test/unit/builtins/__snapshots__/console.spec.ts.snap @@ -0,0 +1,145 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`console.assert ("console.assert(false)") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + assert(false) +end +return ____exports" +`; + +exports[`console.assert ("console.assert(false, \\"message %%s\\", \\"info\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + assert( + false, + string.format(\\"message %%s\\", \\"info\\") + ) +end +return ____exports" +`; + +exports[`console.assert ("console.assert(false, \\"message %s\\", \\"info\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + assert( + false, + string.format(\\"message %s\\", \\"info\\") + ) +end +return ____exports" +`; + +exports[`console.assert ("console.assert(false, \\"message\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + assert(false, \\"message\\") +end +return ____exports" +`; + +exports[`console.assert ("console.assert(false, \\"message\\", \\"more\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + assert(false, \\"message\\", \\"more\\") +end +return ____exports" +`; + +exports[`console.log ("console.log()") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print() +end +return ____exports" +`; + +exports[`console.log ("console.log(\\"Hello %%s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %%s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.log ("console.log(\\"Hello %s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.log ("console.log(\\"Hello\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\") +end +return ____exports" +`; + +exports[`console.log ("console.log(\\"Hello\\", \\"There\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\", \\"There\\") +end +return ____exports" +`; + +exports[`console.trace ("console.trace()") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + debug.traceback() + ) +end +return ____exports" +`; + +exports[`console.trace ("console.trace(\\"Hello %%s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + debug.traceback( + string.format(\\"Hello %%s\\", \\"there\\") + ) + ) +end +return ____exports" +`; + +exports[`console.trace ("console.trace(\\"Hello %s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + debug.traceback( + string.format(\\"Hello %s\\", \\"there\\") + ) + ) +end +return ____exports" +`; + +exports[`console.trace ("console.trace(\\"Hello\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + debug.traceback(\\"Hello\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.trace ("console.trace(\\"message\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + debug.traceback(\\"message\\") + ) +end +return ____exports" +`; diff --git a/test/unit/builtins/__snapshots__/math.spec.ts.snap b/test/unit/builtins/__snapshots__/math.spec.ts.snap new file mode 100644 index 000000000..65d6680d8 --- /dev/null +++ b/test/unit/builtins/__snapshots__/math.spec.ts.snap @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Math.PI 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = math.pi +end +return ____exports" +`; + +exports[`Math.atan2(2, 3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.atan(2 / 3) +end +return ____exports" +`; + +exports[`Math.cos() 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.cos() +end +return ____exports" +`; + +exports[`Math.log1p(3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.log(1 + 3) +end +return ____exports" +`; + +exports[`Math.log2(3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = (math.log(3) / 0.6931471805599453) +end +return ____exports" +`; + +exports[`Math.log10(3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____ = (math.log(3) / 2.302585092994046) +end +return ____exports" +`; + +exports[`Math.min() 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.min() +end +return ____exports" +`; + +exports[`Math.round(3.3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.floor(3.3 + 0.5) +end +return ____exports" +`; + +exports[`Math.sin() 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + math.sin() +end +return ____exports" +`; + +exports[`const x = Math.log2(3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = (math.log(3) / 0.6931471805599453) +end +return ____exports" +`; + +exports[`const x = Math.log10(3) 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = (math.log(3) / 2.302585092994046) +end +return ____exports" +`; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts new file mode 100644 index 000000000..edac44090 --- /dev/null +++ b/test/unit/builtins/array.spec.ts @@ -0,0 +1,522 @@ +import * as util from "../../util"; + +test("omitted expression", () => { + util.testFunction` + const array = [1, , 2]; + return { a: array[0], b: array[1], c: array[2] }; + `.expectToMatchJsResult(); +}); + +describe("access", () => { + test("Array", () => { + util.testFunction` + const array: Array = [3, 5, 1]; + return array[1]; + `.expectToMatchJsResult(); + }); + + test("ReadonlyArray", () => { + util.testFunction` + const array: ReadonlyArray = [3, 5, 1]; + return array[1]; + `.expectToMatchJsResult(); + }); + + test("array literal", () => { + util.testExpression`[3, 5, 1][1]`.expectToMatchJsResult(); + }); + + test("const array literal", () => { + util.testExpression`([3, 5, 1] as const)[1]`.expectToMatchJsResult(); + }); + + test("tuple", () => { + util.testFunction` + const tuple: [number, number, number] = [3, 5, 1]; + return tuple[1]; + `.expectToMatchJsResult(); + }); + + test("readonly tuple", () => { + util.testFunction` + const tuple: readonly [number, number, number] = [3, 5, 1]; + return tuple[1]; + `.expectToMatchJsResult(); + }); + + test("union", () => { + util.testFunction` + const array: number[] | string[] = [3, 5, 1]; + return array[1]; + `.expectToMatchJsResult(); + }); + + test("union with empty tuple", () => { + util.testFunction` + const array: number[] | [] = [3, 5, 1]; + return array[1]; + `.expectToMatchJsResult(); + }); + + test("union with tuple", () => { + util.testFunction` + const tuple: number[] | [number, number, number] = [3, 5, 1]; + return tuple[1]; + `.expectToMatchJsResult(); + }); + + test("access in call", () => { + util.testExpression`[() => "foo", () => "bar"][0]()`.expectToMatchJsResult(); + }); + + test("intersection", () => { + util.testFunction` + const array = Object.assign([3, 5, 1], { foo: "bar" }); + return { foo: array.foo, a: array[0], b: array[1], c: array[2] }; + `.expectToMatchJsResult(); + }); + + test("with enum value index", () => { + util.testFunction` + enum TestEnum { + A, + B, + C, + } + + const array = ["a", "b", "c"]; + let index = TestEnum.A; + return array[index]; + `.expectToMatchJsResult(); + }); + + test.each([ + { member: "firstElement()", expected: 3 }, + { member: "name", expected: "array" }, + { member: "length", expected: 1 }, + ])("derived array (.%p)", ({ member, expected }) => { + const luaHeader = ` + local array = { + name = "array", + firstElement = function(self) return self[1] end + } + `; + + util.testModule` + interface CustomArray extends Array { + name: string; + firstElement(): number; + }; + + declare const array: CustomArray; + + array[0] = 3; + export const result = array.${member}; + ` + .setReturnExport("result") + .setLuaHeader(luaHeader) + .expectToEqual(expected); + }); +}); + +describe("array.length", () => { + describe("get", () => { + test("union", () => { + util.testFunction` + const array: number[] | string[] = [3, 5, 1]; + return array.length; + `.expectToMatchJsResult(); + }); + + test("intersection", () => { + util.testFunction` + const array = Object.assign([3, 5, 1], { foo: "bar" }); + return array.length; + `.expectToMatchJsResult(); + }); + + test("tuple", () => { + util.testFunction` + const tuple: [number, number, number] = [3, 5, 1]; + return tuple.length; + `.expectToMatchJsResult(); + }); + }); + + describe("set", () => { + test.each([{ length: 0, newLength: 0 }, { length: 1, newLength: 1 }, { length: 7, newLength: 3 }])( + "removes extra elements", + ({ length, newLength }) => { + util.testFunction` + const array = [1, 2, 3]; + array.length = ${length}; + return array.length; + `.expectToEqual(newLength); + } + ); + + test.each([0, 1, 7])("returns right-hand side value", length => { + util.testExpression`[1, 2, 3].length = ${length}`.expectToEqual(length); + }); + + test.each([-1, -7, 0.1, NaN, Infinity, -Infinity])("throws on invalid values (%p)", length => { + util.testFunction` + [1, 2, 3].length = ${length}; + `.expectToEqual(new util.ExecutionError(`invalid array length: ${length}`)); + }); + + test("in array destructuring", () => { + util.testFunction` + const array = [0, 1, 2]; + [array.length] = [0]; + return array.length; + `.expectToEqual(0); + }); + + test("in nested array destructuring", () => { + util.testFunction` + const array = [0, 1, 2]; + [[array.length]] = [[0]]; + return array.length; + `.expectToEqual(0); + }); + + test("in object destructuring", () => { + util.testFunction` + const array = [0, 1, 2]; + ({ length: array.length } = { length: 0 }); + return array.length; + `.expectToEqual(0); + }); + + test("in nested object destructuring", () => { + util.testFunction` + const array = [0, 1, 2]; + ({ obj: { length: array.length } } = { obj: { length: 0 } }); + return array.length; + `.expectToEqual(0); + }); + }); +}); + +describe("delete", () => { + test("deletes element", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + delete array[2]; + return { a: array[0], b: array[1], c: array[2], d: array[3] }; + `.expectToMatchJsResult(); + }); + + test("returns true when element exists", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + const exists = delete array[2]; + return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + `.expectToMatchJsResult(); + }); + + test("returns false when element not exists", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + const exists = delete array[4]; + return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + `.expectToMatchJsResult(); + }); +}); + +test("tuple.forEach", () => { + util.testFunction` + const tuple: [number, number, number] = [3, 5, 1]; + let count = 0; + tuple.forEach(value => { + count += value; + }); + return count; + `.expectToMatchJsResult(); +}); + +test("array.forEach (%p)", () => { + util.testFunction` + const array = [0, 1, 2, 3]; + array.forEach((elem, index) => { + array[index] = array[index] + 1; + }); + return array; + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [], searchElement: 3 }, + { array: [0, 2, 4, 8], searchElement: 10 }, + { array: [0, 2, 4, 8], searchElement: 8 }, +])("array.findIndex (%p)", ({ array, searchElement }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + return array.findIndex((elem, index, arr) => elem === ${searchElement} && arr[index] === elem); + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [], func: "x => x" }, + { array: [0, 1, 2, 3], func: "x => x" }, + { array: [0, 1, 2, 3], func: "x => x*2" }, + { array: [1, 2, 3, 4], func: "x => -x" }, + { array: [0, 1, 2, 3], func: "x => x+2" }, + { array: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, +])("array.map (%p)", ({ array, func }) => { + util.testExpression`${util.valueToString(array)}.map(${func})`.expectToMatchJsResult(); +}); + +test.each([ + { array: [], func: "x => x > 1" }, + { array: [0, 1, 2, 3], func: "x => x > 1" }, + { array: [0, 1, 2, 3], func: "x => x < 3" }, + { array: [0, 1, 2, 3], func: "x => x < 0" }, + { array: [0, -1, -2, -3], func: "x => x < 0" }, + { array: [0, 1, 2, 3], func: "() => true" }, + { array: [0, 1, 2, 3], func: "() => false" }, +])("array.filter (%p)", ({ array, func }) => { + util.testExpression`${util.valueToString(array)}.filter(${func})`.expectToMatchJsResult(); +}); + +test.each([ + { array: [], func: "x => x > 1" }, + { array: [0, 1, 2, 3], func: "x => x > 1" }, + { array: [false, true, false], func: "x => x" }, + { array: [true, true, true], func: "x => x" }, +])("array.every (%p)", ({ array, func }) => { + util.testExpression`${util.valueToString(array)}.every(${func})`.expectToMatchJsResult(); +}); + +test.each([ + { array: [], func: "x => x > 1" }, + { array: [0, 1, 2, 3], func: "x => x > 1" }, + { array: [false, true, false], func: "x => x" }, + { array: [true, true, true], func: "x => x" }, +])("array.some (%p)", ({ array, func }) => { + util.testExpression`${util.valueToString(array)}.some(${func})`.expectToMatchJsResult(); +}); + +test.each([ + { array: [2, 3, 4, 5], args: [] }, + { array: [], args: [1, 2] }, + { array: [0, 1, 2, 3], args: [1, 2] }, + { array: [0, 1, 2, 3], args: [1, 1] }, + { array: [0, 1, 2, 3], args: [1, -1] }, + { array: [0, 1, 2, 3], args: [-3, -1] }, + { array: [0, 1, 2, 3, 4, 5], args: [1, 3] }, + { array: [0, 1, 2, 3, 4, 5], args: [3] }, +])("array.slice (%p)", ({ array, args }) => { + util.testExpression`${util.valueToString(array)}.slice(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([ + // Insert + { array: [], start: 0, deleteCount: 0, newElements: [9, 10, 11] }, + { array: [0, 1, 2, 3], start: 1, deleteCount: 0, newElements: [9, 10, 11] }, + { array: [0, 1, 2, 3], start: 2, deleteCount: 2, newElements: [9, 10, 11] }, + { array: [0, 1, 2, 3], start: 4, deleteCount: 1, newElements: [8, 9] }, + { array: [0, 1, 2, 3], start: 4, deleteCount: 0, newElements: [8, 9] }, + { array: [0, 1, 2, 3], start: -2, deleteCount: 0, newElements: [8, 9] }, + { array: [0, 1, 2, 3], start: -3, deleteCount: 0, newElements: [8, 9] }, + { array: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, + { array: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, + + // Remove + { array: [], start: 1, deleteCount: 1 }, + { array: [0, 1, 2, 3], start: 1, deleteCount: 1 }, + { array: [0, 1, 2, 3], start: 10, deleteCount: 1 }, + { array: [0, 1, 2, 3], start: 1, deleteCount: undefined }, + { array: [0, 1, 2, 3], start: 4 }, + { array: [0, 1, 2, 3, 4, 5], start: 3 }, + { array: [0, 1, 2, 3, 4, 5], start: -3 }, + { array: [0, 1, 2, 3, 4, 5], start: -2 }, + { array: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, + { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, +])("array.splice (%p)", ({ array, start, deleteCount, newElements = [] }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + array.splice(${util.valuesToString([start, deleteCount, ...newElements])}); + return array; + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [], args: [[]] }, + { array: [1, 2, 3], args: [[]] }, + { array: [1, 2, 3], args: [[4]] }, + { array: [1, 2, 3], args: [[4, 5]] }, + { array: [1, 2, 3], args: [[4, 5]] }, + { array: [1, 2, 3], args: [4, [5]] }, + { array: [1, 2, 3], args: [4, [5, 6]] }, + { array: [1, 2, 3], args: [4, [5, 6], 7] }, + { array: [1, 2, 3], args: ["test", [5, 6], 7, ["test1", "test2"]] }, + { array: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, +])("array.concat (%p)", ({ array, args }) => { + util.testFunction` + const array: any[] = ${util.valueToString(array)}; + return array.concat(${util.valuesToString(args)}); + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [] }, + { array: ["test1"] }, + { array: ["test1", "test2"] }, + { array: ["test1", "test2"], separator: ";" }, + { array: ["test1", "test2"], separator: "" }, +])("array.join (%p)", ({ array, separator }) => { + util.testExpression`${util.valueToString(array)}.join(${util.valueToString(separator)})`.expectToMatchJsResult(); +}); + +test.each([ + { array: [], args: ["test1"] }, + { array: ["test1"], args: ["test1"] }, + { array: ["test1", "test2"], args: ["test2"] }, + { array: ["test1", "test2", "test3"], args: ["test3", 1] }, + { array: ["test1", "test2", "test3"], args: ["test1", 2] }, + { array: ["test1", "test2", "test3"], args: ["test1", -2] }, + { array: ["test1", "test2", "test3"], args: ["test1", 12] }, +])("array.indexOf (%p)", ({ array, args }) => { + util.testExpression`${util.valueToString(array)}.indexOf(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([{ args: [1] }, { args: [1, 2, 3] }])("array.push (%p)", ({ args }) => { + util.testFunction` + const array = [0]; + const value = array.push(${util.valuesToString(args)}); + return { array, value }; + `.expectToMatchJsResult(); +}); + +// tslint:disable-next-line: no-null-keyword +test.each([{ array: [1, 2, 3], expected: [3, 2] }, { array: [1, 2, 3, null], expected: [3, 2] }])( + "array.pop (%p)", + ({ array, expected }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + const value = array.pop(); + return [value, array.length]; + `.expectToEqual(expected); + } +); + +test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { array: [] }])( + "array.reverse (%p)", + ({ array }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + array.reverse(); + return array; + `.expectToMatchJsResult(); + } +); + +test.each([{ array: [1, 2, 3] }, { array: [1] }, { array: [] }])("array.shift (%p)", ({ array }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + const value = array.shift(); + return { array, value }; + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [3, 4, 5], args: [1, 2] }, + { array: [], args: [] }, + { array: [1], args: [] }, + { array: [], args: [1] }, +])("array.unshift (%p)", ({ array, args }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + const value = array.unshift(${util.valuesToString(args)}); + return { array, value }; + `.expectToMatchJsResult(); +}); + +test.each([{ array: [4, 5, 3, 2, 1] }, { array: [1] }, { array: [] }])("array.sort (%p)", ({ array }) => { + util.testFunctionTemplate` + const array = ${array}; + array.sort(); + return array; + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [1, 2, 3, 4, 5], compare: (a: number, b: number) => a - b }, + { array: ["4", "5", "3", "2", "1"], compare: (a: string, b: string) => Number(a) - Number(b) }, + { array: ["4", "5", "3", "2", "1"], compare: (a: string, b: string) => Number(b) - Number(a) }, +])("array.sort with compare function (%p)", ({ array, compare }) => { + util.testFunctionTemplate` + const array = ${array}; + array.sort(${compare}); + return array; + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, + { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, + { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, + { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, +])("array.flat (%p)", ({ array, depth, expected }) => { + // TODO: Node 12 + util.testExpressionTemplate`${array}.flat(${depth})`.expectToEqual(expected); +}); + +test.each([ + { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, + { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, + { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, + { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, +])("array.flatMap (%p)", ({ array, map, expected }) => { + // TODO: Node 12 + util.testExpressionTemplate`${array}.flatMap(${map})`.expectToEqual(expected); +}); + +test.each<[[(total: number, currentItem: number, index: number, array: number[]) => number, number?]]>([ + [[(total, currentItem) => total + currentItem]], + [[(total, currentItem) => total * currentItem]], + [[(total, currentItem) => total + currentItem, 10]], + [[(total, currentItem) => total * currentItem, 10]], + [[(total, _, index, array) => total + array[index]]], + [[(a, b) => a + b]], +])("array.reduce (%p)", args => { + util.testExpression`[1, 3, 5, 7].reduce(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +const genericChecks = [ + "function generic(array: T)", + "function generic(array: T)", + "function generic(array: T[])", + "type ArrayType = number[]; function generic(array: T)", + "function generic(array: T & {})", + "function generic(array: T)", +]; + +test.each(genericChecks)("array constrained generic foreach (%p)", signature => { + const code = ` + ${signature}: number { + let sum = 0; + array.forEach(item => { + if (typeof item === "number") { + sum += item; + } + }); + return sum; + } + return generic([1, 2, 3]); + `; + expect(util.transpileAndExecute(code)).toBe(6); +}); + +test.each(genericChecks)("array constrained generic length (%p)", signature => { + const code = ` + ${signature}: number { + return array.length; + } + return generic([1, 2, 3]); + `; + expect(util.transpileAndExecute(code)).toBe(3); +}); diff --git a/test/unit/builtins/console.spec.ts b/test/unit/builtins/console.spec.ts new file mode 100644 index 000000000..7e7f68e9e --- /dev/null +++ b/test/unit/builtins/console.spec.ts @@ -0,0 +1,58 @@ +import * as util from "../../util"; + +const compilerOptions = { lib: ["lib.esnext.d.ts", "lib.dom.d.ts"] }; + +test.each([ + "console.log()", + 'console.log("Hello")', + 'console.log("Hello %s", "there")', + 'console.log("Hello %%s", "there")', + 'console.log("Hello", "There")', +])("console.log (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + +test.each([ + "console.trace()", + 'console.trace("message")', + 'console.trace("Hello %s", "there")', + 'console.trace("Hello %%s", "there")', + 'console.trace("Hello", "there")', +])("console.trace (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + +test.each([ + "console.assert(false)", + 'console.assert(false, "message")', + 'console.assert(false, "message %s", "info")', + 'console.assert(false, "message %%s", "info")', + 'console.assert(false, "message", "more")', +])("console.assert (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + +test("console.differentiation", () => { + util.testModule` + export class Console { + public test() { + return 42; + } + } + + function test() { + const console = new Console(); + return console.test(); + } + + export const result = test(); + ` + .setReturnExport("result") + .expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/globalThis.spec.ts b/test/unit/builtins/globalThis.spec.ts new file mode 100644 index 000000000..85463f7ff --- /dev/null +++ b/test/unit/builtins/globalThis.spec.ts @@ -0,0 +1,32 @@ +import * as util from "../../util"; + +test("equals _G", () => { + util.testExpression`globalThis === _G`.setTsHeader("declare const _G: typeof globalThis;").expectToEqual(true); +}); + +test("registers global symbol", () => { + util.testFunction` + globalThis.foo = "bar"; + return foo; + ` + .setTsHeader("declare global { var foo: string }") + .expectToEqual("bar"); +}); + +test("uses global symbol", () => { + util.testFunction` + foo = "bar"; + return globalThis.foo; + ` + .setTsHeader("declare global { var foo: string }") + .expectToEqual("bar"); +}); + +test("function call", () => { + util.testFunction` + foo = () => "bar"; + return globalThis.foo(); + ` + .setTsHeader("declare global { var foo: () => string }") + .expectToEqual("bar"); +}); diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts new file mode 100644 index 000000000..d08f846e9 --- /dev/null +++ b/test/unit/builtins/loading.spec.ts @@ -0,0 +1,53 @@ +import * as tstl from "../../../src"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +describe("luaLibImport", () => { + test("inline", () => { + util.testExpression`[0].push(1)` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Inline }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain(`require("lualib_bundle")`)) + .expectToMatchJsResult(); + }); + + test("require", () => { + util.testExpression`[0].push(1)` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain(`require("lualib_bundle")`)) + .expectToMatchJsResult(); + }); + + test("always", () => { + util.testModule`` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Always }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain(`require("lualib_bundle")`)) + .expectToEqual(undefined); + }); +}); + +test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( + "should not include lualib without code (%p)", + luaLibImport => { + util.testModule``.setOptions({ luaLibImport }).tap(builder => expect(builder.getMainLuaCodeChunk()).toBe("")); + } +); + +test("lualib should not include tstl header", () => { + util.testExpression`[0].push(1)`.tap(builder => + expect(builder.getMainLuaCodeChunk()).not.toContain("Generated with") + ); +}); + +describe("Unknown builtin property", () => { + test("access", () => { + util.testExpression`Math.unknownProperty` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("Math", "unknownProperty", util.nodeStub)); + }); + + test("function call", () => { + util.testExpression`[].unknownFunction()` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub)); + }); +}); diff --git a/test/unit/lualib/map.spec.ts b/test/unit/builtins/map.spec.ts similarity index 100% rename from test/unit/lualib/map.spec.ts rename to test/unit/builtins/map.spec.ts diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts new file mode 100644 index 000000000..6dcd0749a --- /dev/null +++ b/test/unit/builtins/math.spec.ts @@ -0,0 +1,26 @@ +import * as util from "../../util"; + +test.each([ + "Math.cos()", + "Math.sin()", + "Math.min()", + "Math.atan2(2, 3)", + "Math.log2(3)", + "Math.log10(3)", + "const x = Math.log2(3)", + "const x = Math.log10(3)", + "Math.log1p(3)", + "Math.round(3.3)", + "Math.PI", +])("%s", code => { + // TODO: Remove? + util.testFunction(code) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + +test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s", constant => { + util.testExpression`Math.${constant}`.tap(builder => { + expect(builder.getLuaExecutionResult()).toBeCloseTo(builder.getJsExecutionResult()); + }); +}); diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts new file mode 100644 index 000000000..4369f22c6 --- /dev/null +++ b/test/unit/builtins/numbers.spec.ts @@ -0,0 +1,57 @@ +import * as util from "../../util"; + +test.each([ + "NaN === NaN", + "NaN !== NaN", + "NaN + NaN", + "NaN - NaN", + "NaN * NaN", + "NaN / NaN", + "NaN + 1", + "1 + NaN", + "1 / NaN", + "NaN * 0", + + "Infinity", + "Infinity - Infinity", + "Infinity / -1", + "Infinity * -1", + "Infinity + 1", + "Infinity - 1", +])("%s", code => { + util.testExpression(code).expectToMatchJsResult(); +}); + +test.skip.each(["NaN", "Infinity"])("%s reassignment", name => { + util.testFunction` + const ${name} = 1; + return ${name}; + `.expectToMatchJsResult(); +}); + +const numberCases = [-1, 0, 1, 1.5, Infinity, -Infinity]; +const stringCases = ["-1", "0", "1", "1.5", "Infinity", "-Infinity"]; +const restCases = [true, false, "", " ", "\t", "\n", "foo", {}]; +const cases = [...numberCases, ...stringCases, ...restCases]; + +describe("Number", () => { + test.each(cases)("constructor(%p)", value => { + util.testExpressionTemplate`Number(${value})`.expectToMatchJsResult(); + }); + + test.each(cases)("isNaN(%p)", value => { + util.testExpressionTemplate`Number.isNaN(${value} as any)`.expectToMatchJsResult(); + }); + + test.each(cases)("isFinite(%p)", value => { + util.testExpressionTemplate`Number.isFinite(${value} as any)`.expectToMatchJsResult(); + }); +}); + +test.each(cases)("isNaN(%p)", value => { + util.testExpressionTemplate`isNaN(${value} as any)`.expectToMatchJsResult(); +}); + +test.each(cases)("isFinite(%p)", value => { + util.testExpressionTemplate`isFinite(${value} as any)`.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts new file mode 100644 index 000000000..ca1516254 --- /dev/null +++ b/test/unit/builtins/object.spec.ts @@ -0,0 +1,35 @@ +import * as util from "../../util"; + +test.each([ + { initial: { a: 3 }, args: [{}] }, + { initial: {}, args: [{ a: 3 }] }, + { initial: { a: 3 }, args: [{ a: 5 }] }, + { initial: { a: 3 }, args: [{ b: 5 }, { c: 7 }] }, +])("Object.assign (%p)", ({ initial, args }) => { + util.testExpression`Object.assign(${util.valueToString(initial)}, ${util.valuesToString( + args + )})`.expectToMatchJsResult(); +}); + +test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { + util.testExpressionTemplate`Object.entries(${obj})`.expectToMatchJsResult(); +}); + +test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.keys (%p)", obj => { + util.testExpressionTemplate`Object.keys(${obj})`.expectToMatchJsResult(); +}); + +test.each([{}, { abc: "def" }, { abc: 3, def: "xyz" }])("Object.values (%p)", obj => { + util.testExpressionTemplate`Object.values(${obj})`.expectToMatchJsResult(); +}); + +// TODO: Jest 25: as const +test.each<[string, object]>([ + ["[]", []], + ['[["a", 1], ["b", 2]]', { a: 1, b: 2 }], + ['[["a", 1], ["a", 2]]', { a: 2 }], + ['new Map([["foo", "bar"]])', { foo: "bar" }], +])("Object.fromEntries(%s)", (entries, expected) => { + // TODO: Node 12 + util.testExpression`Object.fromEntries(${entries})`.expectToEqual(expected); +}); diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts new file mode 100644 index 000000000..bac8773f8 --- /dev/null +++ b/test/unit/builtins/set.spec.ts @@ -0,0 +1,122 @@ +import * as util from "../../util"; + +test("set constructor", () => { + util.testFunction` + let myset = new Set(); + return myset.size; + `.expectToMatchJsResult(); +}); + +test("set iterable constructor", () => { + util.testFunction` + let myset = new Set(["a", "b"]); + return myset.has("a") || myset.has("b"); + `.expectToMatchJsResult(); +}); + +test("set iterable constructor set", () => { + util.testFunction` + let myset = new Set(new Set(["a", "b"])); + return myset.has("a") || myset.has("b"); + `.expectToMatchJsResult(); +}); + +test("set add", () => { + util.testFunction` + let myset = new Set(); + myset.add("a"); + return myset.has("a"); + `.expectToMatchJsResult(); +}); + +test("set clear", () => { + util.testFunction` + let myset = new Set(["a", "b"]); + myset.clear(); + return { size: myset.size, has: !myset.has("a") && !myset.has("b") }; + `.expectToMatchJsResult(); +}); + +test("set delete", () => { + util.testFunction` + let myset = new Set(["a", "b"]); + myset.delete("a"); + return myset.has("b") && !myset.has("a"); + `.expectToMatchJsResult(); +}); + +test("set entries", () => { + util.testFunction` + let myset = new Set([5, 6, 7]); + let count = 0; + for (var [key, value] of myset.entries()) { count += key + value; } + return count; + `.expectToMatchJsResult(); +}); + +test("set foreach", () => { + util.testFunction` + let myset = new Set([2, 3, 4]); + let count = 0; + myset.forEach(i => { count += i; }); + return count; + `.expectToMatchJsResult(); +}); + +test("set foreach keys", () => { + util.testFunction` + let myset = new Set([2, 3, 4]); + let count = 0; + myset.forEach((value, key) => { count += key; }); + return count; + `.expectToMatchJsResult(); +}); + +test("set has", () => { + util.testFunction` + let myset = new Set(["a", "c"]); + return myset.has("a"); + `.expectToMatchJsResult(); +}); + +test("set has false", () => { + util.testFunction` + let myset = new Set(); + return myset.has("a"); + `.expectToMatchJsResult(); +}); + +test("set has null", () => { + util.testFunction` + let myset = new Set(["a", "c"]); + return myset.has(null); + `.expectToMatchJsResult(); +}); + +test("set keys", () => { + util.testFunction` + let myset = new Set([5, 6, 7]); + let count = 0; + for (var key of myset.keys()) { count += key; } + return count; + `.expectToMatchJsResult(); +}); + +test("set values", () => { + util.testFunction` + let myset = new Set([5, 6, 7]); + let count = 0; + for (var value of myset.values()) { count += value; } + return count; + `.expectToMatchJsResult(); +}); + +test.each([ + `let m = new Set()`, + `let m = new Set(); m.add(1)`, + `let m = new Set([1, 2])`, + `let m = new Set([1, 2]); m.clear()`, + `let m = new Set([1, 2]); m.delete(2)`, +])("set size (%p)", code => { + util.testFunction`${code}; return m.size`.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts new file mode 100644 index 000000000..af5b46762 --- /dev/null +++ b/test/unit/builtins/string.spec.ts @@ -0,0 +1,264 @@ +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test("Unsupported string function", () => { + util.testExpression`"test".testThisIsNoMember()` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); +}); + +test("Supported lua string function", () => { + const tsHeader = ` + declare global { + interface String { + upper(): string; + } + } + `; + + util.testExpression`"test".upper()`.setTsHeader(tsHeader).expectToEqual("TEST"); +}); + +test.each([[], [65], [65, 66], [65, 66, 67]])("String.fromCharCode (%p)", (...args) => { + util.testExpression`String.fromCharCode(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([ + { a: 12, b: 23, c: 43 }, + { a: "test", b: "hello", c: "bye" }, + { a: "test", b: 42, c: "bye" }, + { a: "test", b: 42, c: 12 }, + { a: "test", b: 42, c: true }, + { a: false, b: 42, c: 12 }, +])("String Concat Operator (%p)", ({ a, b, c }) => { + util.testFunctionTemplate` + let a = ${a}; + let b = ${b}; + let c = ${c}; + return a + " " + b + " test " + c; + `.expectToMatchJsResult(); +}); + +test.each([ + { input: "abcd", index: 3 }, + { input: "abcde", index: 3 }, + { input: "abcde", index: 0 }, + { input: "a", index: 0 }, +])("string index (%p)", ({ input, index }) => { + util.testExpressionTemplate`${input}[${index}]`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", searchValue: "", replaceValue: "" }, + { inp: "hello test", searchValue: " ", replaceValue: "" }, + { inp: "hello test", searchValue: "hello", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "world" }, + { inp: "hello test", searchValue: "test", replaceValue: "%world" }, + { inp: "hello %test", searchValue: "test", replaceValue: "world" }, + { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, + { inp: "hello test", searchValue: "test", replaceValue: (): string => "a" }, + { inp: "hello test", searchValue: "test", replaceValue: (): string => "%a" }, + { inp: "aaa", searchValue: "a", replaceValue: "b" }, +])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { + util.testExpression`"${inp}".replace(${util.valuesToString([searchValue, replaceValue])})`.expectToMatchJsResult(); +}); + +test.each([["", ""], ["hello", "test"], ["hello", "test", "bye"], ["hello", 42], [42, "hello"]])( + "string.concat[+] (%p)", + (...elements) => { + util.testExpression(elements.map(e => util.valueToString(e)).join(" + ")).expectToMatchJsResult(); + } +); + +test.each([ + { str: "", args: ["", ""] }, + { str: "hello", args: ["test"] }, + { str: "hello", args: [] }, + { str: "hello", args: ["test", "bye"] }, +])("string.concatFct (%p)", ({ str, args }) => { + util.testExpression`"${str}".concat(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", searchValue: "" }, + { inp: "hello test", searchValue: "t" }, + { inp: "hello test", searchValue: "h" }, + { inp: "hello test", searchValue: "invalid" }, + { inp: "hello.test", searchValue: "." }, +])("string.indexOf (%p)", ({ inp, searchValue }) => { + util.testExpressionTemplate`${inp}.indexOf(${searchValue})`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", searchValue: "t", offset: 5 }, + { inp: "hello test", searchValue: "t", offset: 6 }, + { inp: "hello test", searchValue: "t", offset: 7 }, + { inp: "hello test", searchValue: "h", offset: 4 }, +])("string.indexOf with offset (%p)", ({ inp, searchValue, offset }) => { + util.testExpressionTemplate`${inp}.indexOf(${searchValue}, ${offset})`.expectToMatchJsResult(); +}); + +test.each([{ inp: "hello test", searchValue: "t", x: 4, y: 3 }, { inp: "hello test", searchValue: "h", x: 3, y: 4 }])( + "string.indexOf with offset expression (%p)", + ({ inp, searchValue, x, y }) => { + util.testExpressionTemplate`${inp}.indexOf(${searchValue}, 2 > 1 && ${x} || ${y})`.expectToMatchJsResult(); + } +); + +test.each([ + { inp: "hello test", args: [] }, + { inp: "hello test", args: [0] }, + { inp: "hello test", args: [1] }, + { inp: "hello test", args: [1, 2] }, + { inp: "hello test", args: [1, 5] }, +])("string.slice (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".slice(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", args: [0] }, + { inp: "hello test", args: [1] }, + { inp: "hello test", args: [1, 2] }, + { inp: "hello test", args: [1, 5] }, +])("string.substring (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".substring(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 5 }])( + "string.substring with expression (%p)", + ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + util.testExpression`"${inp}".substring(${paramStr})`.expectToMatchJsResult(); + } +); + +test.each([ + { inp: "hello test", args: [0] }, + { inp: "hello test", args: [1] }, + { inp: "hello test", args: [1, 2] }, + { inp: "hello test", args: [1, 5] }, +])("string.substr (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".substr(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 2 }])( + "string.substr with expression (%p)", + ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); + + expect(result).toBe(inp.substr(start, end)); + } +); + +test.each(["", "h", "hello"])("string.length (%p)", input => { + util.testExpressionTemplate`${input}.length`.expectToMatchJsResult(); +}); + +test.each(["hello TEST"])("string.toLowerCase (%p)", inp => { + util.testExpressionTemplate`${inp}.toLowerCase()`.expectToMatchJsResult(); +}); + +test.each(["hello test"])("string.toUpperCase (%p)", inp => { + util.testExpressionTemplate`${inp}.toUpperCase()`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", separator: "" }, + { inp: "hello test", separator: " " }, + { inp: "hello test", separator: "h" }, + { inp: "hello test", separator: "t" }, + { inp: "hello test", separator: "l" }, + { inp: "hello test", separator: "invalid" }, + { inp: "hello test", separator: "hello test" }, +])("string.split (%p)", ({ inp, separator }) => { + util.testExpressionTemplate`${inp}.split(${separator})`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", index: 1 }, + { inp: "hello test", index: 2 }, + { inp: "hello test", index: 3 }, + { inp: "hello test", index: 99 }, +])("string.charAt (%p)", ({ inp, index }) => { + util.testExpressionTemplate`${inp}.charAt(${index})`.expectToMatchJsResult(); +}); + +test.each([{ inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }])( + "string.charCodeAt (%p)", + ({ inp, index }) => { + util.testExpressionTemplate`${inp}.charCodeAt(${index})`.expectToMatchJsResult(); + } +); + +test.each([ + { inp: "hello test", index: 1, ignored: 0 }, + { inp: "hello test", index: 1, ignored: 2 }, + { inp: "hello test", index: 3, ignored: 2 }, + { inp: "hello test", index: 3, ignored: 99 }, +])("string.charAt with expression (%p)", ({ inp, index, ignored }) => { + util.testExpressionTemplate`${inp}.charAt(2 > 1 && ${index} || ${ignored})`.expectToMatchJsResult(); +}); + +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["hello"] }, + { inp: "hello test", args: ["test"] }, + { inp: "hello test", args: ["test", 6] }, +])("string.startsWith (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".startsWith(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["test"] }, + { inp: "hello test", args: ["hello"] }, + { inp: "hello test", args: ["hello", 5] }, +])("string.endsWith (%p)", ({ inp, args }) => { + const argsString = util.valuesToString(args); + util.testExpression`"${inp}".endsWith(${argsString})`.expectToMatchJsResult(); +}); + +test.each([ + { inp: "hello test", count: 0 }, + { inp: "hello test", count: 1 }, + { inp: "hello test", count: 2 }, + { inp: "hello test", count: 1.1 }, + { inp: "hello test", count: 1.5 }, + { inp: "hello test", count: 1.9 }, +])("string.repeat (%p)", ({ inp, count }) => { + util.testExpression`"${inp}".repeat(${count})`.expectToMatchJsResult(); +}); + +const padCases = [ + { inp: "foo", args: [0] }, + { inp: "foo", args: [3] }, + { inp: "foo", args: [5] }, + { inp: "foo", args: [4, " "] }, + { inp: "foo", args: [10, " "] }, + { inp: "foo", args: [5, "1234"] }, + { inp: "foo", args: [5.9, "1234"] }, + { inp: "foo", args: [NaN] }, +]; + +test.each(padCases)("string.padStart (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".padStart(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each(padCases)("string.padEnd (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".padEnd(${util.valuesToString(args)})`.expectToMatchJsResult(); +}); + +test.each([ + "function generic(string: T)", + "type StringType = string; function generic(string: T)", +])("string constrained generic foreach (%p)", signature => { + const code = ` + ${signature}: number { + return string.length; + } + return generic("string"); + `; + expect(util.transpileAndExecute(code)).toBe(6); +}); diff --git a/test/unit/builtins/symbol.spec.ts b/test/unit/builtins/symbol.spec.ts new file mode 100644 index 000000000..75da67a59 --- /dev/null +++ b/test/unit/builtins/symbol.spec.ts @@ -0,0 +1,38 @@ +import * as util from "../../util"; + +test.each([undefined, 1, "name"])("symbol.toString() (%p)", description => { + util.testExpression`Symbol(${util.valueToString(description)}).toString()`.expectToMatchJsResult(); +}); + +test.each([undefined, 1, "name"])("symbol.description (%p)", description => { + // TODO: Supported since node 11 + util.testExpression`Symbol(${util.valueToString(description)}).description`.expectToEqual(description); +}); + +test("symbol uniqueness", () => { + util.testExpression`Symbol("a") === Symbol("a")`.expectToMatchJsResult(); +}); + +test("Symbol.for", () => { + // TODO: Supported since node 11 + util.testExpression(`Symbol.for("name").description`).expectToEqual("name"); +}); + +test("Symbol.for non-uniqueness", () => { + util.testExpression`Symbol.for("a") === Symbol.for("a")`.expectToMatchJsResult(); +}); + +test("Symbol.keyFor", () => { + util.testFunction` + const sym = Symbol.for("a"); + Symbol.for("b"); + return Symbol.keyFor(sym); + `.expectToMatchJsResult(); +}); + +test("Symbol.keyFor empty", () => { + util.testFunction` + Symbol.for("a"); + return Symbol.keyFor(Symbol()); + `.expectToMatchJsResult(); +}); diff --git a/test/unit/lualib/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts similarity index 100% rename from test/unit/lualib/weakMap.spec.ts rename to test/unit/builtins/weakMap.spec.ts diff --git a/test/unit/lualib/weakSet.spec.ts b/test/unit/builtins/weakSet.spec.ts similarity index 100% rename from test/unit/lualib/weakSet.spec.ts rename to test/unit/builtins/weakSet.spec.ts diff --git a/test/unit/classDecorator.spec.ts b/test/unit/classDecorator.spec.ts deleted file mode 100644 index 8d7afd8fa..000000000 --- a/test/unit/classDecorator.spec.ts +++ /dev/null @@ -1,199 +0,0 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; - -test("Class decorator with no parameters", () => { - const source = ` - function SetBool(constructor: T) { - return class extends constructor { - decoratorBool = true; - } - } - - @SetBool - class TestClass { - public decoratorBool = false; - } - - const classInstance = new TestClass(); - return classInstance.decoratorBool; - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe(true); -}); - -test("Class decorator with parameters", () => { - const source = ` - function SetNum(numArg: number) { - return {}>(constructor: T) => { - return class extends constructor { - decoratorNum = numArg; - }; - }; - } - - @SetNum(420) - class TestClass { - public decoratorNum; - } - - const classInstance = new TestClass(); - return classInstance.decoratorNum; - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe(420); -}); - -test("Class decorator with variable parameters", () => { - const source = ` - function SetNumbers(...numArgs: number[]) { - return {}>(constructor: T) => { - return class extends constructor { - decoratorNums = new Set(numArgs); - }; - }; - } - - @SetNumbers(120, 30, 54) - class TestClass { - public decoratorNums; - } - - const classInstance = new TestClass(); - let sum = 0; - for (const value of classInstance.decoratorNums) { - sum += value; - } - return sum; - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe(204); -}); - -test("Multiple class decorators", () => { - const source = ` - function SetTen(constructor: T) { - return class extends constructor { - decoratorTen = 10; - } - } - - function SetNum(numArg: number) { - return {}>(constructor: T) => { - return class extends constructor { - decoratorNum = numArg; - }; - }; - } - - @SetTen - @SetNum(410) - class TestClass { - public decoratorTen; - public decoratorNum; - } - - const classInstance = new TestClass(); - return classInstance.decoratorNum + classInstance.decoratorTen; - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe(420); -}); - -test("Class decorator with inheritance", () => { - const source = ` - function SetTen(constructor: T) { - return class extends constructor { - decoratorTen = 10; - } - } - - function SetNum(numArg: number) { - return {}>(constructor: T) => { - return class extends constructor { - decoratorNum = numArg; - }; - }; - } - - class TestClass { - public decoratorTen = 0; - public decoratorNum = 0; - } - - @SetTen - @SetNum(410) - class SubTestClass extends TestClass {} - - const classInstance = new SubTestClass(); - return classInstance.decoratorNum + classInstance.decoratorTen; - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe(420); -}); - -test("Class decorators are applied in order and executed in reverse order", () => { - const source = ` - const order = []; - - function SetString(stringArg: string) { - order.push("eval " + stringArg); - return {}>(constructor: T) => { - order.push("execute " + stringArg); - return class extends constructor { - decoratorString = stringArg; - }; - }; - } - - @SetString("fox") - @SetString("jumped") - @SetString("over dog") - class TestClass { - public static decoratorString = ""; - } - - const inst = new TestClass(); - return order.join(" "); - `; - - const result = util.transpileAndExecute(source); - expect(result).toBe("eval fox eval jumped eval over dog execute over dog execute jumped execute fox"); -}); - -test("Throws error if decorator function has void context", () => { - const source = ` - function SetBool(this: void, constructor: T) { - return class extends constructor { - decoratorBool = true; - } - } - - @SetBool - class TestClass { - public decoratorBool = false; - } - - const classInstance = new TestClass(); - return classInstance.decoratorBool; - `; - - expect(() => util.transpileAndExecute(source)).toThrowExactError(TSTLErrors.InvalidDecoratorContext(util.nodeStub)); -}); - -test("Exported class decorator", () => { - const code = ` - function decorator(c: T): T { - c.bar = "foobar"; - return c; - } - - @decorator - export class Foo {}`; - - expect(util.transpileExecuteAndReturnExport(code, "Foo.bar")).toBe("foobar"); -}); diff --git a/test/unit/accessors.spec.ts b/test/unit/classes/accessors.spec.ts similarity index 76% rename from test/unit/accessors.spec.ts rename to test/unit/classes/accessors.spec.ts index fd63233df..5f9232246 100644 --- a/test/unit/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -1,19 +1,18 @@ -import * as util from "../util"; +import * as util from "../../util"; test("get accessor", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } } const f = new Foo(); return f.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test("get accessor in base class", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -21,12 +20,11 @@ test("get accessor in base class", () => { class Bar extends Foo {} const b = new Bar(); return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); -test("get accessor override", () => { - const code = ` +test.skip("get accessor override", () => { + util.testFunction` class Foo { _foo = "foo"; foo = "foo"; @@ -36,12 +34,11 @@ test("get accessor override", () => { } const b = new Bar(); return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); -test("get accessor overridden", () => { - const code = ` +test.skip("get accessor overridden", () => { + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -51,12 +48,11 @@ test("get accessor overridden", () => { } const b = new Bar(); return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("get accessor override accessor", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -67,12 +63,11 @@ test("get accessor override accessor", () => { } const b = new Bar(); return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("get accessor from interface", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -82,12 +77,11 @@ test("get accessor from interface", () => { } const b: Bar = new Foo(); return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test("set accessor", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; set foo(val: string) { this._foo = val; } @@ -95,12 +89,11 @@ test("set accessor", () => { const f = new Foo(); f.foo = "bar" return f._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("set accessor in base class", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; set foo(val: string) { this._foo = val; } @@ -109,12 +102,11 @@ test("set accessor in base class", () => { const b = new Bar(); b.foo = "bar" return b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("set accessor override", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; foo = "foo"; @@ -125,12 +117,11 @@ test("set accessor override", () => { const b = new Bar(); b.foo = "bar" return b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("set accessor overridden", () => { - const code = ` + util.testFunction` class Foo { _foo = "baz"; set foo(val: string) { this._foo = val; } @@ -142,12 +133,11 @@ test("set accessor overridden", () => { const fooOriginal = b._foo; b.foo = "bar" return fooOriginal + b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("set accessor override accessor", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; set foo(val: string) { this._foo = "foo"; } @@ -158,12 +148,11 @@ test("set accessor override accessor", () => { const b = new Bar(); b.foo = "bar" return b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("set accessor from interface", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; set foo(val: string) { this._foo = val; } @@ -175,12 +164,11 @@ test("set accessor from interface", () => { const b: Bar = new Foo(); b.foo = "bar" return b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("get/set accessors", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -190,12 +178,11 @@ test("get/set accessors", () => { const fooOriginal = f.foo; f.foo = "bar"; return fooOriginal + f.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("get/set accessors in base class", () => { - const code = ` + util.testFunction` class Foo { _foo = "foo"; get foo() { return this._foo; } @@ -206,35 +193,32 @@ test("get/set accessors in base class", () => { const fooOriginal = b.foo; b.foo = "bar" return fooOriginal + b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("static get accessor", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } } return Foo.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test("static get accessor in base class", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } } class Bar extends Foo {} return Bar.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test("static get accessor override", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static foo = "foo"; @@ -243,12 +227,11 @@ test("static get accessor override", () => { static get foo() { return this._foo + "bar"; } } return Bar.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); -test("static get accessor overridden", () => { - const code = ` +test.skip("static get accessor overridden", () => { + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } @@ -257,12 +240,11 @@ test("static get accessor overridden", () => { static foo = "bar"; } return Bar.foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static get accessor override accessor", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } @@ -272,12 +254,11 @@ test("static get accessor override accessor", () => { static get foo() { return this._bar; } } return Bar.foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static get accessor from interface", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } @@ -287,24 +268,22 @@ test("static get accessor from interface", () => { } const b: Bar = Foo; return b.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test("static set accessor", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static set foo(val: string) { this._foo = val; } } Foo.foo = "bar" return Foo._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static set accessor in base class", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static set foo(val: string) { this._foo = val; } @@ -312,12 +291,11 @@ test("static set accessor in base class", () => { class Bar extends Foo {} Bar.foo = "bar" return Bar._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static set accessor override", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static foo = "foo"; @@ -327,12 +305,11 @@ test("static set accessor override", () => { } Bar.foo = "bar" return Bar._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static set accessor overridden", () => { - const code = ` + util.testFunction` class Foo { static _foo = "baz"; static set foo(val: string) { this._foo = val; } @@ -343,12 +320,11 @@ test("static set accessor overridden", () => { const fooOriginal = Bar._foo; Bar.foo = "bar" return fooOriginal + Bar._foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("static set accessor override accessor", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static set foo(val: string) { this._foo = "foo"; } @@ -358,12 +334,11 @@ test("static set accessor override accessor", () => { } Bar.foo = "bar" return Bar._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static set accessor from interface", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static set foo(val: string) { this._foo = val; } @@ -375,12 +350,11 @@ test("static set accessor from interface", () => { const b: Bar = Foo; b.foo = "bar" return b._foo; - `; - expect(util.transpileAndExecute(code)).toBe("bar"); + `.expectToMatchJsResult(); }); test("static get/set accessors", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } @@ -389,12 +363,11 @@ test("static get/set accessors", () => { const fooOriginal = Foo.foo; Foo.foo = "bar"; return fooOriginal + Foo.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("static get/set accessors in base class", () => { - const code = ` + util.testFunction` class Foo { static _foo = "foo"; static get foo() { return this._foo; } @@ -404,6 +377,5 @@ test("static get/set accessors in base class", () => { const fooOriginal = Bar.foo; Bar.foo = "bar" return fooOriginal + Bar.foo; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/class.spec.ts b/test/unit/classes/classes.spec.ts similarity index 96% rename from test/unit/class.spec.ts rename to test/unit/classes/classes.spec.ts index 37f1db79a..3f156c93a 100644 --- a/test/unit/class.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; test("ClassFieldInitializer", () => { const result = util.transpileAndExecute( @@ -733,28 +733,6 @@ test.each([{ input: "(new Foo())", expectResult: "foo" }, { input: "Foo", expect } ); -test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { - const code = ` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - class C extends B {} - `; - expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidExtendsExtension(util.nodeStub)); -}); - -test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { - const code = ` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - const b = new B(); - `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub) - ); -}); - test("Class static instance of self", () => { const code = ` class Foo { diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts new file mode 100644 index 000000000..e5c44e51d --- /dev/null +++ b/test/unit/classes/decorators.spec.ts @@ -0,0 +1,127 @@ +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test("Class decorator with no parameters", () => { + util.testFunction` + function setBool {}>(constructor: T) { + return class extends constructor { + decoratorBool = true; + } + } + + @setBool + class TestClass { + public decoratorBool = false; + } + + return new TestClass(); + `.expectToMatchJsResult(); +}); + +test("Class decorator with parameters", () => { + util.testFunction` + function setNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + @setNum(420) + class TestClass { + public decoratorNum; + } + + return new TestClass(); + `.expectToMatchJsResult(); +}); + +test("Multiple class decorators", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + function setNum {}>(constructor: T) { + return class extends constructor { + decoratorNum = 410; + } + } + + @setTen + @setNum + class TestClass { + public decoratorTen; + public decoratorNum; + } + + return new TestClass(); + `.expectToMatchJsResult(); +}); + +test("Class decorator with inheritance", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + class TestClass { + public decoratorTen = 0; + } + + @setTen + class SubTestClass extends TestClass { + public decoratorTen = 5; + } + + return new SubTestClass(); + `.expectToMatchJsResult(); +}); + +test("Class decorators are applied in order and executed in reverse order", () => { + util.testFunction` + const order = []; + + function pushOrder(index: number) { + order.push("eval " + index); + return (constructor: new (...args: any[]) => {}) => { + order.push("execute " + index); + }; + } + + @pushOrder(1) + @pushOrder(2) + @pushOrder(3) + class TestClass {} + + return order; + `.expectToMatchJsResult(); +}); + +test("Throws error if decorator function has void context", () => { + util.testFunction` + function SetBool(this: void, constructor: new (...args: any[]) => {}) {} + + @SetBool + class TestClass {} + `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidDecoratorContext(util.nodeStub)); +}); + +test("Exported class decorator", () => { + util.testModule` + function decorator(c: T): T { + c.bar = "foobar"; + return c; + } + + @decorator + export class Foo {} + ` + .setReturnExport("Foo.bar") + .expectToMatchJsResult(); +}); diff --git a/test/unit/classes/instanceof.spec.ts b/test/unit/classes/instanceof.spec.ts new file mode 100644 index 000000000..fdbb6e36e --- /dev/null +++ b/test/unit/classes/instanceof.spec.ts @@ -0,0 +1,76 @@ +import * as util from "../../util"; + +test("instanceof", () => { + util.testFunction` + class myClass {} + const instance = new myClass(); + return instance instanceof myClass; + `.expectToMatchJsResult(); +}); + +test("instanceof inheritance", () => { + util.testFunction` + class myClass {} + class childClass extends myClass {} + const instance = new childClass(); + return instance instanceof myClass; + `.expectToMatchJsResult(); +}); + +test("instanceof inheritance false", () => { + util.testFunction` + class myClass {} + class childClass extends myClass {} + const instance = new myClass(); + return instance instanceof childClass; + `.expectToMatchJsResult(); +}); + +test("{} instanceof Object", () => { + util.testExpression`{} instanceof Object`.expectToMatchJsResult(); +}); + +test("function instanceof Object", () => { + util.testExpression`(() => {}) instanceof Object`.expectToMatchJsResult(); +}); + +test("null instanceof Object", () => { + util.testExpression`(null as any) instanceof Object`.expectToMatchJsResult(); +}); + +test("instanceof undefined", () => { + util.testExpression`{} instanceof (undefined as any)`.expectToMatchJsResult(true); +}); + +test("null instanceof Class", () => { + util.testFunction` + class myClass {} + return (null as any) instanceof myClass; + `.expectToMatchJsResult(); +}); + +test("instanceof export", () => { + util.testModule` + export class myClass {} + const instance = new myClass(); + export const result = instance instanceof myClass; + ` + .setReturnExport("result") + .expectToMatchJsResult(); +}); + +test("instanceof Symbol.hasInstance", () => { + util.testFunction` + class myClass { + static [Symbol.hasInstance]() { + return false; + } + } + + const instance = new myClass(); + const isInstanceOld = instance instanceof myClass; + myClass[Symbol.hasInstance] = () => true; + const isInstanceNew = instance instanceof myClass; + return { isInstanceOld, isInstanceNew }; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 04a285457..d5bc14792 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -2,36 +2,30 @@ import * as tstl from "../../src"; import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("if (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([0, 1])("if (%p)", inp => { + util.testFunction` + let input: number = ${inp}; if (input === 0) { return 0; } - return 1;` - ); - - expect(result).toBe(expected); + return 1; + `.expectToMatchJsResult(); }); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }])("ifelse (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; - if (input === 0) { - return 0; - } else { - return 1; - }` - ); - - expect(result).toBe(expected); +test.each([0, 1])("ifelse (%p)", inp => { + util.testFunction` + let input: number = ${inp}; + if (input === 0) { + return 0; + } else { + return 1; + } + `.expectToMatchJsResult(); }); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: 3 }])( - "ifelseif (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([0, 1, 2, 3])("ifelseif (%p)", inp => { + util.testFunction` + let input: number = ${inp}; if (input === 0) { return 0; } else if (input === 1){ @@ -39,18 +33,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: } else if (input === 2){ return 2; } - return 3;` - ); - - expect(result).toBe(expected); - } -); + return 3; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: 3 }])( - "ifelseifelse (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let input: number = ${inp}; +test.each([0, 1, 2, 3])("ifelseifelse (%p)", inp => { + util.testFunction` + let input: number = ${inp}; if (input === 0) { return 0; } else if (input === 1){ @@ -59,18 +48,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: return 2; } else { return 3; - }` - ); - - expect(result).toBe(expected); - } -); + } + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( - "switch (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("switch (%p)", inp => { + util.testFunction` + let result: number = -1; switch (${inp}) { case 0: @@ -83,18 +67,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: result = 2; break; } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -2 }])( - "switchdefault (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { + util.testFunction` + let result: number = -1; switch (${inp}) { case 0: @@ -110,24 +89,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: result = -2; break; } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([ - { inp: 0, expected: 1 }, - { inp: 0, expected: 1 }, - { inp: 2, expected: 4 }, - { inp: 3, expected: 4 }, - { inp: 4, expected: 4 }, - { inp: 5, expected: 15 }, - { inp: 7, expected: -2 }, -])("switchfallthrough (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { + util.testFunction` + let result: number = -1; switch (${inp}) { case 0: @@ -152,24 +120,21 @@ test.each([ result = -2; break; } - return result;` - ); - expect(result).toBe(expected); + return result; + `.expectToMatchJsResult(); }); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -2 }])( - "nestedSwitch (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { + util.testFunction` + let result: number = -1; - switch (${inp}) { + switch (${inp} as number) { case 0: result = 0; break; case 1: - switch(${inp}) { + switch(${inp} as number) { case 0: result = 0; break; @@ -188,47 +153,37 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: result = -2; break; } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 2 }, { inp: 2, expected: 2 }])( - "switchLocalScope (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2])("switchLocalScope (%p)", inp => { + util.testFunction` + let result: number = -1; - switch (${inp}) { - case 0: { - let x = 0; - result = 0; - break; - } - case 1: { - let x = 1; - result = x; - } - case 2: { - let x = 2; - result = x; - break; - } + switch (${inp}) { + case 0: { + let x = 0; + result = 0; + break; } - return result;` - ); - - expect(result).toBe(expected); - } -); + case 1: { + let x = 1; + result = x; + } + case 2: { + let x = 2; + result = x; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( - "switchReturn (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `const result: number = -1; +test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { + util.testFunction` + const result: number = -1; switch (${inp}) { case 0: @@ -240,18 +195,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: return 2; break; } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( - "switchWithBrackets (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { + util.testFunction` + let result: number = -1; switch (${inp}) { case 0: { @@ -267,18 +217,13 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: break; } } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( - "switchWithBracketsBreakInConditional (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { + util.testFunction` + let result: number = -1; switch (${inp}) { case 0: { @@ -295,20 +240,15 @@ test.each([{ inp: 0, expected: 0 }, { inp: 1, expected: 1 }, { inp: 2, expected: break; } } - return result;` - ); - - expect(result).toBe(expected); - } -); + return result; + `.expectToMatchJsResult(); +}); -test.each([{ inp: 0, expected: 4 }, { inp: 1, expected: 0 }, { inp: 2, expected: 2 }, { inp: 3, expected: -1 }])( - "switchWithBracketsBreakInInternalLoop (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let result: number = -1; +test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { + util.testFunction` + let result: number = -1; - switch (${inp}) { + switch (${inp} as number) { case 0: { result = 0; @@ -329,29 +269,64 @@ test.each([{ inp: 0, expected: 4 }, { inp: 1, expected: 0 }, { inp: 2, expected: break; } } - return result;` - ); - - expect(result).toBe(expected); - } -); - -test("If dead code after return", () => { - const result = util.transpileAndExecute(`if (true) { return 3; const b = 8; }`); + return result; + `.expectToMatchJsResult(); +}); - expect(result).toBe(3); +test("switch not allowed in 5.1", () => { + util.testFunction` + switch ("abc") {} + ` + .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) + .expectToHaveDiagnosticOfError( + TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub) + ); }); -test("switch dead code after return", () => { - const result = util.transpileAndExecute( - `switch ("abc") { case "def": return 4; let abc = 4; case "abc": return 5; let def = 6; }` - ); +test.each([ + { input: "true ? 'a' : 'b'" }, + { input: "false ? 'a' : 'b'" }, + { input: "true ? false : true" }, + { input: "false ? false : true" }, + { input: "true ? literalValue : true" }, + { input: "true ? variableValue : true" }, + { input: "true ? maybeUndefinedValue : true" }, + { input: "true ? maybeBooleanValue : true" }, + { input: "true ? maybeUndefinedValue : true", options: { strictNullChecks: true } }, + { input: "true ? maybeBooleanValue : true", options: { strictNullChecks: true } }, + { input: "true ? undefined : true", options: { strictNullChecks: true } }, + { input: "true ? null : true", options: { strictNullChecks: true } }, + { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, + { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, + { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, + { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, +])("Ternary operator (%p)", ({ input, options }) => { + util.testFunction` + const literalValue = "literal"; + let variableValue: string; + let maybeBooleanValue: string | boolean = false; + let maybeUndefinedValue: string | undefined; + return ${input}; + ` + .setOptions(options) + .expectToMatchJsResult(); +}); - expect(result).toBe(5); +test.each([ + { condition: true, lhs: 4, rhs: 5 }, + { condition: false, lhs: 4, rhs: 5 }, + { condition: 3, lhs: 4, rhs: 5 }, +])("Ternary Conditional (%p)", ({ condition, lhs, rhs }) => { + util.testExpressionTemplate`${condition} ? ${lhs} : ${rhs}`.expectToMatchJsResult(); }); -test("switch not allowed in 5.1", () => { - expect(() => util.transpileString(`switch ("abc") {}`, { luaTarget: tstl.LuaTarget.Lua51 })).toThrowExactError( - TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub) - ); +test.each(["true", "false", "a < 4", "a == 8"])("Ternary Conditional Delayed (%p)", condition => { + util.testFunction` + let a = 3; + let delay = () => ${condition} ? a + 3 : a + 5; + a = 8; + return delay(); + `.expectToMatchJsResult(); }); diff --git a/test/unit/console.spec.ts b/test/unit/console.spec.ts deleted file mode 100644 index e82c23b04..000000000 --- a/test/unit/console.spec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as util from "../util"; - -const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - -test.each([ - { inp: "console.log()", expected: "print()" }, - { inp: 'console.log("Hello")', expected: 'print("Hello")' }, - { inp: 'console.log("Hello %s", "there")', expected: 'print(\n string.format("Hello %s", "there")\n)' }, - { inp: 'console.log("Hello %%s", "there")', expected: 'print(\n string.format("Hello %%s", "there")\n)' }, - { inp: 'console.log("Hello", "There")', expected: 'print("Hello", "There")' }, -])("console.log (%p)", ({ inp, expected }) => { - expect(util.transpileString(inp, compilerOptions)).toBe(expected); -}); - -test.each([ - { - inp: "console.trace()", - expected: "print(\n debug.traceback()\n)", - }, - { - inp: 'console.trace("message")', - expected: 'print(\n debug.traceback("message")\n)', - }, - { - inp: 'console.trace("Hello %s", "there")', - expected: 'print(\n debug.traceback(\n string.format("Hello %s", "there")\n )\n)', - }, - { - inp: 'console.trace("Hello %%s", "there")', - expected: 'print(\n debug.traceback(\n string.format("Hello %%s", "there")\n )\n)', - }, - { - inp: 'console.trace("Hello", "there")', - expected: 'print(\n debug.traceback("Hello", "there")\n)', - }, -])("console.trace (%p)", ({ inp, expected }) => { - expect(util.transpileString(inp, compilerOptions)).toBe(expected); -}); - -test.each([ - { - inp: "console.assert(false)", - expected: "assert(false)", - }, - { - inp: 'console.assert(false, "message")', - expected: 'assert(false, "message")', - }, - { - inp: 'console.assert(false, "message %s", "info")', - expected: 'assert(\n false,\n string.format("message %s", "info")\n)', - }, - { - inp: 'console.assert(false, "message %%s", "info")', - expected: 'assert(\n false,\n string.format("message %%s", "info")\n)', - }, - { - inp: 'console.assert(false, "message", "more")', - expected: 'assert(false, "message", "more")', - }, -])("console.assert (%p)", ({ inp, expected }) => { - expect(util.transpileString(inp, compilerOptions)).toBe(expected); -}); - -test("console.differentiation", () => { - const result = util.transpileExecuteAndReturnExport( - ` - export class Console { - test() { return 42; } - } - - function test() { - const console = new Console(); - return console.test(); - } - - export const result = test(); - `, - "result", - compilerOptions - ); - expect(result).toBe(42); -}); diff --git a/test/unit/curry.spec.ts b/test/unit/curry.spec.ts deleted file mode 100644 index b39d2f3c6..000000000 --- a/test/unit/curry.spec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as util from "../util"; - -test.each([{ x: 2, y: 3 }, { x: 5, y: 4 }])("curryingAdd (%p)", ({ x, y }) => { - const result = util.transpileAndExecute( - `let add = (x: number) => (y: number) => x + y; - return add(${x})(${y})` - ); - - expect(result).toBe(x + y); -}); diff --git a/test/unit/declarations.spec.ts b/test/unit/declarations.spec.ts deleted file mode 100644 index 415153e2c..000000000 --- a/test/unit/declarations.spec.ts +++ /dev/null @@ -1,135 +0,0 @@ -import * as util from "../util"; - -test("Declaration function call", () => { - const libLua = `function declaredFunction(x) return 3*x end`; - - const tsHeader = `declare function declaredFunction(this: void, x: number): number;`; - - const source = `return declaredFunction(2) + 4;`; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe(10); -}); - -test("Declaration function call tupleReturn", () => { - const libLua = `function declaredFunction(x) return x, 2*x + 1 end`; - - const tsHeader = ` - /** @tupleReturn */ - declare function declaredFunction(this: void, x: number): [number, number]; - `; - - const source = ` - const tuple = declaredFunction(3); - const [destructedLeft, destructedRight] = declaredFunction(2); - return \`\${tuple[0] + destructedLeft},\${tuple[1] + destructedRight}\`; - `; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe("5,12"); -}); - -test("Declaration namespace function call", () => { - const libLua = ` - myNameSpace = {} - function myNameSpace.declaredFunction(x) return 3*x end - `; - - const tsHeader = `declare namespace myNameSpace { function declaredFunction(this: void, x: number): number; }`; - - const source = `return myNameSpace.declaredFunction(2) + 4;`; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe(10); -}); - -test("Declaration interface function call", () => { - const libLua = ` - myInterfaceInstance = {} - myInterfaceInstance.x = 10 - function myInterfaceInstance:declaredFunction(x) return self.x + 3*x end - `; - - const tsHeader = ` - declare interface MyInterface { - declaredFunction(x: number): number; - } - declare var myInterfaceInstance: MyInterface; - `; - - const source = `return myInterfaceInstance.declaredFunction(3);`; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe(19); -}); - -test("Declaration function callback", () => { - const libLua = `function declaredFunction(callback) return callback(4) end`; - const tsHeader = `declare function declaredFunction(this: void, callback: (this: void, x: number) => number): number;`; - - const source = `return declaredFunction(x => 2 * x);`; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe(8); -}); - -test("Declaration instance function callback", () => { - const libLua = ` - myInstance = {} - myInstance.x = 10 - function myInstance:declaredFunction(callback) return callback(self.x) end - `; - - const tsHeader = ` - declare interface MyInterface { - declaredFunction(callback: (this: void, x: number) => number): number; - } - declare var myInstance: MyInterface; - `; - - const source = `return myInstance.declaredFunction(x => 2 * x);`; - - const result = util.transpileAndExecute(source, undefined, libLua, tsHeader); - expect(result).toBe(20); -}); - -test("ImportEquals declaration", () => { - const header = ` - namespace outerNamespace { - export namespace innerNamespace { - export function func() { return "foo" } - } - }; - - import importedFunc = outerNamespace.innerNamespace.func; - `; - - const execution = `return importedFunc();`; - - const result = util.transpileAndExecute(execution, undefined, undefined, header); - expect(result).toEqual("foo"); -}); - -test("ImportEquals declaration ambient", () => { - const header = ` - declare namespace outerNamespace { - namespace innerNamespace { - function func(): string; - } - }; - - import importedFunc = outerNamespace.innerNamespace.func; - `; - - const luaHeader = `outerNamespace = { - innerNamespace = { - func = function() return "foo" end - } - } - `; - - const execution = `return importedFunc();`; - - const result = util.transpileAndExecute(execution, undefined, luaHeader, header); - expect(result).toEqual("foo"); -}); diff --git a/test/unit/decorators/compileMembersOnly.spec.ts b/test/unit/decorators/compileMembersOnly.spec.ts new file mode 100644 index 000000000..5db0fe974 --- /dev/null +++ b/test/unit/decorators/compileMembersOnly.spec.ts @@ -0,0 +1,34 @@ +import * as util from "../../util"; + +test("@compileMembersOnly", () => { + util.testFunction` + /** @compileMembersOnly */ + enum TestEnum { + A = 0, + B = 2, + C, + D = "D", + } + + return { A: TestEnum.A, B: TestEnum.B, C: TestEnum.C, D: TestEnum.D }; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("TestEnum")) + .expectToMatchJsResult(); +}); + +test("@compileMembersOnly in a namespace", () => { + util.testModule` + namespace Test { + /** @compileMembersOnly */ + export enum TestEnum { + A = "A", + B = "B", + } + } + + export const A = Test.TestEnum.A; + ` + .setReturnExport("A") + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("Test.A")) + .expectToEqual("A"); +}); diff --git a/test/unit/decoratorCustomConstructor.spec.ts b/test/unit/decorators/customConstructor.spec.ts similarity index 91% rename from test/unit/decoratorCustomConstructor.spec.ts rename to test/unit/decorators/customConstructor.spec.ts index 126c44e4f..48c473943 100644 --- a/test/unit/decoratorCustomConstructor.spec.ts +++ b/test/unit/decorators/customConstructor.spec.ts @@ -1,5 +1,5 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; test("CustomCreate", () => { const luaHeader = ` diff --git a/test/unit/decorators/extension.spec.ts b/test/unit/decorators/extension.spec.ts new file mode 100644 index 000000000..e7717792e --- /dev/null +++ b/test/unit/decorators/extension.spec.ts @@ -0,0 +1,34 @@ +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { + const code = ` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + class C extends B {} + `; + expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidExtendsExtension(util.nodeStub)); +}); + +test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { + const code = ` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + const b = new B(); + `; + expect(() => util.transpileString(code)).toThrowExactError( + TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub) + ); +}); + +test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { + util.testModule` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + declare const foo: any; + const result = foo instanceof B; + `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidInstanceOfExtension(util.nodeStub)); +}); diff --git a/test/unit/decorators/forRange.spec.ts b/test/unit/decorators/forRange.spec.ts new file mode 100644 index 000000000..11f8aec85 --- /dev/null +++ b/test/unit/decorators/forRange.spec.ts @@ -0,0 +1,112 @@ +import * as ts from "typescript"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test.each([ + { args: [1, 10], expectResult: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, + { args: [1, 10, 2], expectResult: [1, 3, 5, 7, 9] }, + { args: [10, 1, -1], expectResult: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, + { args: [10, 1, -2], expectResult: [10, 8, 6, 4, 2] }, +])("@forRange loop", ({ args, expectResult }) => { + const tsHeader = "/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];"; + const code = ` + const results: number[] = []; + for (const i of luaRange(${args})) { + results.push(i); + } + return JSONStringify(results);`; + + const result = util.transpileAndExecute(code, undefined, undefined, tsHeader); + expect(JSON.parse(result)).toEqual(expectResult); +}); + +test("invalid non-ambient @forRange function", () => { + const code = ` + /** @forRange **/ function luaRange(i: number, j: number, k?: number): number[] { return []; } + for (const i of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function can only be used as an iterable in a for...of loop." + ).message + ); +}); + +test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => { + const code = ` + /** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; } + for (const i of luaRange(${args})) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.") + .message + ); +}); + +test("invalid @forRange control variable", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; + let i: number; + for (i of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange loop must declare its own control variable." + ).message + ); +}); + +test("invalid @forRange argument type", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: string, j: number): number[] { return []; } + for (const i of luaRange("foo", 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message + ); +}); + +test("invalid @forRange destructuring", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[][]; + for (const [i] of luaRange(1, 10, 2)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message + ); +}); + +test("invalid @forRange return type", () => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): string[]; + for (const i of luaRange(1, 10)) {}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function must return Iterable or Array." + ).message + ); +}); + +test.each([ + "const range = luaRange(1, 10);", + "console.log(luaRange);", + "luaRange.call(null, 0, 0, 0);", + "let array = [0, luaRange, 1];", + "const call: any; call(luaRange);", + "for (const i of [...luaRange(1, 10)]) {}", +])("invalid @forRange reference (%p)", statement => { + const code = ` + /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; + ${statement}`; + + expect(() => util.transpileString(code)).toThrow( + TSTLErrors.InvalidForRangeCall( + ts.createEmptyStatement(), + "@forRange function can only be used as an iterable in a for...of loop." + ).message + ); +}); diff --git a/test/unit/decorators/luaIterator.spec.ts b/test/unit/decorators/luaIterator.spec.ts new file mode 100644 index 000000000..5aa24d8ae --- /dev/null +++ b/test/unit/decorators/luaIterator.spec.ts @@ -0,0 +1,262 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test("forof lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof array lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Array {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof lua iterator with existing variable", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + let e: string; + for (e of luaIter()) { result += e; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof lua iterator destructuring", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i] && [i.toString(), arr[i++]]) as any; + } + let result = ""; + for (let [a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator destructuring with existing variables", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i] && [i.toString(), arr[i++]]) as any; + } + let result = ""; + let a: string; + let b: string; + for ([a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + /** @tupleReturn */ + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + let result = ""; + for (let [a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return with existing variables", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + /** @tupleReturn */ + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + let result = ""; + let a: string; + let b: string; + for ([a, b] of luaIter()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); + +test("forof lua iterator tuple-return single variable", () => { + const code = ` + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; + for (let x of luaIter()) {} + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) + ); +}); + +test("forof lua iterator tuple-return single existing variable", () => { + const code = ` + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + declare function luaIter(): Iter; + let x: [string, string]; + for (x of luaIter()) {} + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( + TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) + ); +}); + +test("forof forwarded lua iterator", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + function iter() { return arr[i++]; } + return iter as any; + } + function forward() { + const iter = luaIter(); + return iter; + } + let result = ""; + for (let a of forward()) { result += a; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("abc"); +}); + +test("forof forwarded lua iterator with tupleReturn", () => { + const code = ` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + /** @tupleReturn */ + interface Iter extends Iterable<[string, string]> {} + function luaIter(): Iter { + let i = 0; + /** @tupleReturn */ + function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } + return iter as any; + } + function forward() { + const iter = luaIter(); + return iter; + } + let result = ""; + for (let [a, b] of forward()) { result += a + b; } + return result; + `; + const compilerOptions = { + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget: tstl.LuaTarget.Lua53, + target: ts.ScriptTarget.ES2015, + }; + const result = util.transpileAndExecute(code, compilerOptions); + expect(result).toBe("0a1b2c"); +}); diff --git a/test/unit/luaTable.spec.ts b/test/unit/decorators/luaTable.spec.ts similarity index 98% rename from test/unit/luaTable.spec.ts rename to test/unit/decorators/luaTable.spec.ts index ddc5f81a3..6419cc735 100644 --- a/test/unit/luaTable.spec.ts +++ b/test/unit/decorators/luaTable.spec.ts @@ -1,5 +1,5 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; const tableLibClass = ` /** @luaTable */ diff --git a/test/unit/decoratorMetaExtension.spec.ts b/test/unit/decorators/metaExtension.spec.ts similarity index 93% rename from test/unit/decoratorMetaExtension.spec.ts rename to test/unit/decorators/metaExtension.spec.ts index 20bf7fb4d..cac222c97 100644 --- a/test/unit/decoratorMetaExtension.spec.ts +++ b/test/unit/decorators/metaExtension.spec.ts @@ -1,5 +1,5 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; test("MetaExtension", () => { const tsHeader = ` diff --git a/test/unit/tuples.spec.ts b/test/unit/decorators/tupleReturn.spec.ts similarity index 52% rename from test/unit/tuples.spec.ts rename to test/unit/decorators/tupleReturn.spec.ts index 779bd8666..66df74aba 100644 --- a/test/unit/tuples.spec.ts +++ b/test/unit/decorators/tupleReturn.spec.ts @@ -1,214 +1,96 @@ -import * as util from "../util"; +import * as util from "../../util"; -test("Tuple loop", () => { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - let count = 0; - for (const value of tuple) { count += value; } - return count;` - ); - - expect(result).toBe(9); -}); - -test("Tuple foreach", () => { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - let count = 0; - tuple.forEach(v => count += v); - return count;` - ); - - expect(result).toBe(9); -}); - -test("Tuple access", () => { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - return tuple[1];` - ); - - expect(result).toBe(5); -}); - -test("Readonly Tuple access", () => { - const result = util.transpileAndExecute( - `const tuple: readonly [number, number, number] = [3,5,1]; - return tuple[1];` - ); - - expect(result).toBe(5); -}); - -test("Tuple union access", () => { - const result = util.transpileAndExecute( - `function makeTuple(): [number, number, number] | [string, string, string] { return [3,5,1]; } - const tuple = makeTuple(); - return tuple[1];` - ); - expect(result).toBe(5); -}); - -test("Tuple intersection access", () => { - const result = util.transpileAndExecute( - `type I = [number, number, number] & {foo: string}; - function makeTuple(): I { - let t = [3,5,1]; - (t as I).foo = "bar"; - return (t as I); - } - const tuple = makeTuple(); - return tuple[1];` - ); - expect(result).toBe(5); -}); - -test("Tuple Destruct", () => { - const result = util.transpileAndExecute( - `function tuple(): [number, number, number] { return [3,5,1]; } - const [a,b,c] = tuple(); - return b;` - ); - - expect(result).toBe(5); -}); - -test("Tuple Destruct Array Literal", () => { - const code = ` - const [a,b,c] = [3,5,1]; - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); -}); - -test("Tuple Destruct Array Literal Extra Values", () => { - const code = ` - let result = ""; - const set = () => { result = "bar"; }; - const [a] = ["foo", set()]; - return a + result;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); -}); - -test("Tuple length", () => { - const result = util.transpileAndExecute( - `const tuple: [number, number, number] = [3,5,1]; - return tuple.length;` - ); - - expect(result).toBe(3); -}); +const expectNoUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack"); test("Tuple Return Access", () => { - const code = ` + util.testFunction` /** @tupleReturn */ - function tuple(): [number, number, number] { return [3,5,1]; } - return tuple()[2];`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(1); + function tuple(): [number, number, number] { return [3, 5, 1]; } + return tuple()[2]; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Destruct Declaration", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function tuple(): [number, number, number] { return [3,5,1]; } const [,b,c] = tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Destruct Assignment", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function tuple(): [number, number] { return [3,6]; } let [a,b] = [1,2]; [b,a] = tuple(); - return a - b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(3); + return a - b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Static Method Return Destruct", () => { - const code = ` + util.testFunction` class Test { /** @tupleReturn */ static tuple(): [number, number, number] { return [3,5,1]; } } const [a,b,c] = Test.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Static Function Property Return Destruct", () => { - const code = ` + util.testFunction` class Test { /** @tupleReturn */ static tuple: () => [number, number, number] = () => [3,5,1]; } const [a,b,c] = Test.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Non-Static Method Return Destruct", () => { - const code = ` + util.testFunction` class Test { /** @tupleReturn */ tuple(): [number, number, number] { return [3,5,1]; } } const t = new Test(); const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Non-Static Function Property Return Destruct", () => { - const code = ` + util.testFunction` class Test { /** @tupleReturn */ tuple: () => [number, number, number] = () => [3,5,1]; } const t = new Test(); const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Interface Method Return Destruct", () => { - const code = ` + util.testFunction` interface Test { /** @tupleReturn */ tuple(): [number, number, number]; @@ -217,16 +99,14 @@ test("Tuple Interface Method Return Destruct", () => { tuple() { return [3,5,1]; } }; const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Interface Function Property Return Destruct", () => { - const code = ` + util.testFunction` interface Test { /** @tupleReturn */ tuple: () => [number, number, number]; @@ -235,116 +115,100 @@ test("Tuple Interface Function Property Return Destruct", () => { tuple: () => [3,5,1] }; const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Object Literal Method Return Destruct", () => { - const code = ` + util.testFunction` const t = { /** @tupleReturn */ tuple() { return [3,5,1]; } }; const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Object Literal Function Property Return Destruct", () => { - const code = ` + util.testFunction` const t = { /** @tupleReturn */ tuple: () => [3,5,1] }; const [a,b,c] = t.tuple(); - return b;`; - - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(5); + return b; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Arrow Function", () => { - const code = ` + util.testFunction` const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; const [a, b] = fn("foo"); return a + b; - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Inference", () => { - const code = ` + util.testFunction` /** @tupleReturn */ interface Fn { (s: string): [string, string] } const fn: Fn = s => [s, "bar"]; const [a, b] = fn("foo"); return a + b; - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Inference as Argument", () => { - const code = ` + util.testFunction` /** @tupleReturn */ interface Fn { (s: string): [string, string] } function foo(fn: Fn) { const [a, b] = fn("foo"); return a + b; } return foo(s => [s, "bar"]); - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Inference as Elipsis Argument", () => { - const code = ` + util.testFunction` /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(a: number, ...fn: Fn[]) { + function foo(_: number, ...fn: Fn[]) { const [a, b] = fn[0]("foo"); return a + b; } - return foo(7, s => [s, "bar"]); - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + return foo(0, s => [s, "bar"]); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return Inference as Elipsis Tuple Argument", () => { - const code = ` + util.testFunction` /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(a: number, ...fn: [number, Fn]) { + function foo(_: number, ...fn: [number, Fn]) { const [a, b] = fn[1]("foo"); return a + b; } - return foo(7, 17, s => [s, "bar"]); - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + return foo(0, 0, s => [s, "bar"]); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return in Spread", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function foo(): [string, string] { return ["foo", "bar"]; } @@ -352,56 +216,48 @@ test("Tuple Return in Spread", () => { return a + b; } return bar(...foo()); - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Type Alias", () => { - const code = ` + util.testFunction` /** @tupleReturn */ type Fn = () => [number, number]; const fn: Fn = () => [1, 2]; const [a, b] = fn(); return a + b; - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(3); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Interface", () => { - const code = ` + util.testFunction` /** @tupleReturn */ interface Fn { (): [number, number]; } const fn: Fn = () => [1, 2]; const [a, b] = fn(); return a + b; - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(3); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Interface Signature", () => { - const code = ` + util.testFunction` interface Fn { /** @tupleReturn */ (): [number, number]; } const fn: Fn = () => [1, 2]; const [a, b] = fn(); return a + b; - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe(3); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Overload", () => { - const code = ` + util.testFunction` function fn(a: number): number; /** @tupleReturn */ function fn(a: string, b: string): [string, string]; function fn(a: number | string, b?: string): number | [string, string] { @@ -414,15 +270,13 @@ test("Tuple Return on Overload", () => { const a = fn(3); const [b, c] = fn("foo", "bar"); return a + b + c - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("3foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Interface Overload", () => { - const code = ` + util.testFunction` interface Fn { (a: number): number; /** @tupleReturn */ (a: string, b: string): [string, string]; @@ -437,20 +291,18 @@ test("Tuple Return on Interface Overload", () => { const a = fn(3); const [b, c] = fn("foo", "bar"); return a + b + c - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("3foobar"); + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return on Interface Method Overload", () => { - const code = ` + util.testFunction` interface Foo { foo(a: number): number; /** @tupleReturn */ foo(a: string, b: string): [string, string]; } - const bar = ({ + const bar = { foo: (a: number | string, b?: string): number | [string, string] => { if (typeof a === "number") { return a; @@ -458,15 +310,13 @@ test("Tuple Return on Interface Method Overload", () => { return [a, b as string]; } } - }) as Foo; + } as Foo; const a = bar.foo(3); const [b, c] = bar.foo("foo", "bar"); - return a + b + c - `; - const lua = util.transpileString(code); - expect(lua).not.toContain("unpack"); - const result = util.executeLua(lua); - expect(result).toBe("3foobar"); + return a + b + c; + ` + .tap(expectNoUnpack) + .expectToMatchJsResult(); }); test("Tuple Return vs Non-Tuple Return Overload", () => { @@ -479,15 +329,218 @@ test("Tuple Return vs Non-Tuple Return Overload", () => { end end `; + const tsHeader = ` declare function fn(this: void, a: number): [number, number]; /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string]; `; - const code = ` + + util.testFunction` const [a, b] = fn(3); const [c, d] = fn("foo", "bar"); return (a + b) + c + d; + ` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .expectToEqual("7foobar"); +}); + +test("TupleReturn assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): number[] + let [a,b] = abc(); `; - const result = util.transpileAndExecute(code, undefined, luaHeader, tsHeader); - expect(result).toBe("7foobar"); + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = abc()"); +}); + +test("TupleReturn Single assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): [number, string]; + let a = abc(); + a = abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); +}); + +test("TupleReturn interface assignment", () => { + const code = ` + interface def { + /** @tupleReturn */ + abc(); + } declare const jkl : def; + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = jkl:abc()"); +}); + +test("TupleReturn namespace assignment", () => { + const code = ` + declare namespace def { + /** @tupleReturn */ + function abc(this: void) {} + } + let [a,b] = def.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = def.abc()"); +}); + +test("TupleReturn method assignment", () => { + const code = ` + declare class def { + /** @tupleReturn */ + abc() { return [1,2,3]; } + } const jkl = new def(); + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); +}); + +test("TupleReturn functional", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const [a, b] = abc(); + return b + a; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); +}); + +test("TupleReturn single", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const res = abc(); + return res.length + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe(2); +}); + +test("TupleReturn in expression", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + return abc()[1] + abc()[0]; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); +}); + +test("TupleReturn assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): number[] + let [a,b] = abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = abc()"); +}); + +test("TupleReturn Single assignment", () => { + const code = ` + /** @tupleReturn */ + declare function abc(this: void): [number, string]; + let a = abc(); + a = abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); +}); + +test("TupleReturn interface assignment", () => { + const code = ` + interface def { + /** @tupleReturn */ + abc(); + } declare const jkl : def; + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = jkl:abc()"); +}); + +test("TupleReturn namespace assignment", () => { + const code = ` + declare namespace def { + /** @tupleReturn */ + function abc(this: void) {} + } + let [a,b] = def.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local a, b = def.abc()"); +}); + +test("TupleReturn method assignment", () => { + const code = ` + declare class def { + /** @tupleReturn */ + abc() { return [1,2,3]; } + } const jkl = new def(); + let [a,b] = jkl.abc(); + `; + + const lua = util.transpileString(code); + expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); +}); + +test("TupleReturn functional", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const [a, b] = abc(); + return b + a; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); +}); + +test("TupleReturn single", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + const res = abc(); + return res.length + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe(2); +}); + +test("TupleReturn in expression", () => { + const code = ` + /** @tupleReturn */ + function abc(): [number, string] { return [3, "a"]; } + return abc()[1] + abc()[0]; + `; + + const result = util.transpileAndExecute(code); + + expect(result).toBe("a3"); }); diff --git a/test/unit/decorators/vararg.spec.ts b/test/unit/decorators/vararg.spec.ts new file mode 100644 index 000000000..2a99fa4a7 --- /dev/null +++ b/test/unit/decorators/vararg.spec.ts @@ -0,0 +1,55 @@ +import * as util from "../../util"; + +test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + function foo(a: unknown, ...b: LuaVarArg) { + const c = [...b]; + return c.join(""); + } + function bar(a: unknown, ...b: LuaVarArg) { + return foo(a, ...b); + } + return bar("A", "B", "C", "D"); + `; + + const lua = util.transpileString(code, compilerOptions); + expect(lua).not.toMatch("b = ({...})"); + expect(lua).not.toMatch("unpack"); + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("@vararg array access", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + function foo(a: unknown, ...b: LuaVarArg) { + const c = [...b]; + return c.join("") + b[0]; + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCDB"); +}); + +test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => { + const code = ` + /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; + declare const arg: LuaVarArg; + const arr = [...arg]; + const result = arr.join(""); + `; + + const luaBody = util.transpileString(code, compilerOptions, false); + expect(luaBody).not.toMatch("unpack"); + + const lua = ` + function test(...) + ${luaBody} + return result + end + return test("A", "B", "C", "D") + `; + + expect(util.executeLua(lua)).toBe("ABCD"); +}); diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts new file mode 100644 index 000000000..b4ae3dd50 --- /dev/null +++ b/test/unit/destructuring.spec.ts @@ -0,0 +1,123 @@ +import * as util from "../util"; + +const allBindings = "x, y, z"; +const testCases = [ + { binding: "{ x }", value: { x: true } }, + { binding: "{ x, y }", value: { x: false, y: true } }, + { binding: "{ x: z, y }", value: { x: true, y: false } }, + { binding: "{ x: { x, y }, z }", value: { x: { x: true, y: false }, z: false } }, + { binding: "{ x, y = true }", value: { x: false, y: false } }, + { binding: "{ x = true }", value: {} }, + { binding: "{ x, y = true }", value: { x: false } }, + + { binding: "[]", value: [] }, + { binding: "[x, y]", value: ["x", "y"] }, + { binding: "[x, , y]", value: ["x", "", "y"] }, + { binding: "[x = true]", value: [false] }, + { binding: "[[x, y]]", value: [["x", "y"]] }, + + { binding: "{ y: [z = true] }", value: { y: [false] } }, + { binding: "{ x: [x, y] }", value: { x: ["x", "y"] } }, + { binding: "{ x: [{ y }] }", value: { x: [{ y: "y" }] } }, +].map(({ binding, value }) => ({ binding, value: util.valueToString(value) })); + +test.each([ + ...testCases, + { binding: "{ x, y }, z", value: "{ x: false, y: false }, true" }, + { binding: "{ x, y }, { z }", value: "{ x: false, y: false }, { z: true }" }, +])("in function parameter (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + function test(${binding}) { + return { ${allBindings} }; + } + + return test(${value}); + `.expectToMatchJsResult(); +}); + +test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + { + const ${binding} = ${value}; + return { ${allBindings} }; + } + `.expectToMatchJsResult(); +}); + +// TODO: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/695 +test.each(testCases.filter(x => x.binding !== "[x, , y]"))( + "in exported variable declaration (%p)", + ({ binding, value }) => { + util.testModule` + export const ${binding} = ${value}; + `.expectToMatchJsResult(); + } +); + +const assignmentTestCases = [ + ...testCases, + ...[ + { binding: "{ x: obj.prop }", value: { x: true } }, + { binding: "{ x: obj.prop = true }", value: {} }, + { binding: "[{ x: obj.prop }]", value: [{ x: true }] }, + { binding: "{ obj: { prop: obj.prop } }", value: { obj: { prop: true } } }, + { binding: "{ x = true }", value: {} }, + ].map(({ binding, value }) => ({ binding, value: util.valueToString(value) })), + { binding: "{ x: { [(3).toString()]: y } }", value: "{ x: { [(3).toString()]: true } }" }, +]; + +test.each(assignmentTestCases)("in assignment expression (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + const obj = { prop: false }; + const expressionResult = (${binding} = ${value}); + return { ${allBindings}, obj, expressionResult }; + `.expectToMatchJsResult(); +}); + +describe("array destructuring optimization", () => { + // TODO: Try to generalize optimization logic between declaration and assignment and make more generic tests + + test("array", () => { + util.testFunction` + const array = [3, 5, 1]; + const [a, b, c] = array; + return { a, b, c }; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("unpack")) + .expectToMatchJsResult(); + }); + + test("array literal", () => { + util.testFunction` + const [a, b, c] = [3, 5, 1]; + return { a, b, c }; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack")) + .expectToMatchJsResult(); + }); + + test("array literal with extra values", () => { + util.testFunction` + let called = false; + const set = () => { called = true; }; + const [head] = ["foo", set()]; + return { head, called }; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack")) + .expectToMatchJsResult(); + }); + + test("array union", () => { + util.testFunction` + const array: [string] | [] = ["bar"]; + let x: string; + [x] = array; + return x; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("unpack")) + .expectToMatchJsResult(); + }); +}); diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 219927f41..6fd75556b 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -1,176 +1,134 @@ import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; -test("Declare const enum", () => { - const testCode = ` - declare const enum TestEnum { - MEMBER_ONE = "test", - MEMBER_TWO = "test2" - } - - const valueOne = TestEnum.MEMBER_ONE; - `; - - expect(util.transpileString(testCode)).toBe(`local valueOne = "test"`); -}); - -test("Const enum", () => { - const testCode = ` - const enum TestEnum { - MEMBER_ONE = "test", - MEMBER_TWO = "test2" - } - - const valueOne = TestEnum.MEMBER_TWO; - `; - - expect(util.transpileString(testCode)).toBe(`local valueOne = "test2"`); -}); - -test("Const enum without initializer", () => { - const testCode = ` - const enum TestEnum { - MEMBER_ONE, - MEMBER_TWO - } - - const valueOne = TestEnum.MEMBER_TWO; - `; - - expect(util.transpileString(testCode)).toBe(`local valueOne = 1`); -}); - -test("Const enum without initializer in some values", () => { - const testCode = ` - const enum TestEnum { - MEMBER_ONE = 3, - MEMBER_TWO, - MEMBER_THREE = 5 +// TODO: string.toString() +const serializeEnum = (identifier: string) => `(() => { + const mappedTestEnum: any = {}; + for (const key in ${identifier}) { + mappedTestEnum[(key as any).toString()] = ${identifier}[key]; + } + return mappedTestEnum; +})()`; + +// TODO: Move to namespace tests? +test("in a namespace", () => { + util.testModule` + namespace Test { + export enum TestEnum { + A, + B, + } } - const valueOne = TestEnum.MEMBER_TWO; - `; - - expect(util.transpileString(testCode)).toBe(`local valueOne = 4`); + export const result = ${serializeEnum("Test.TestEnum")} + `.expectToMatchJsResult(); }); -test("Invalid heterogeneous enum", () => { - expect(() => { - util.transpileString(` +describe("initializers", () => { + test("expression", () => { + util.testFunction` + const value = 6; enum TestEnum { - a, - b = "ok", - c, + A, + B = value, } - `); - }).toThrowExactError(TSTLErrors.HeterogeneousEnum(util.nodeStub)); -}); -test("String literal name in enum", () => { - const code = ` - enum TestEnum { - ["name"] = "foo" - } - return TestEnum["name"]; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); -}); + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); -test("Enum identifier value internal", () => { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi = def, - jkl, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` - ); + test("inference", () => { + util.testFunction` + enum TestEnum { + A, + B, + C, + } - expect(result).toBe("0,1,1,2"); -}); + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); -test("Enum identifier value internal recursive", () => { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi = def, - jkl = ghi, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi},\${testEnum.jkl}\`;` - ); + test("partial inference", () => { + util.testFunction` + enum TestEnum { + A = 3, + B, + C = 5, + } - expect(result).toBe("0,1,1,1"); -}); + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); -test("Enum identifier value external", () => { - const result = util.transpileAndExecute( - `const ext = 6; - enum testEnum { - abc, - def, - ghi = ext, - } - return \`\${testEnum.abc},\${testEnum.def},\${testEnum.ghi}\`;` - ); + test("other member reference", () => { + util.testFunction` + enum TestEnum { + A, + B = A, + C = B, + } - expect(result).toBe("0,1,6"); + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); }); -test("Enum reverse mapping", () => { - const result = util.transpileAndExecute( - `enum testEnum { - abc, - def, - ghi +test("invalid heterogeneous enum", () => { + util.testFunction` + enum TestEnum { + A, + B = "B", + C, } - return testEnum[testEnum.abc] + testEnum[testEnum.ghi]` - ); - - expect(result).toBe("abcghi"); + ` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.HeterogeneousEnum(util.nodeStub)); }); -test("Const enum index", () => { - const result = util.transpileAndExecute( - `const enum testEnum { - abc, - def, - ghi - } - return testEnum["def"];` - ); - - expect(result).toBe(1); -}); +describe("const enum", () => { + const expectToBeConst: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).not.toContain("TestEnum"); -test("Const enum index identifier value", () => { - const result = util.transpileAndExecute( - `const enum testEnum { - abc, - def = 4, - ghi, - jkl = ghi - } - return testEnum["jkl"];` - ); + test.each(["", "declare"])("%s without initializer", () => { + util.testFunction` + const enum TestEnum { + A, + B, + } - expect(result).toBe(5); -}); + return TestEnum.A; + ` + .tap(expectToBeConst) + .expectToMatchJsResult(); + }); + + test("with initializer", () => { + util.testFunction` + const enum TestEnum { + A = "ONE", + B = "TWO", + } -test("Const enum index identifier chain", () => { - const result = util.transpileAndExecute( - `const enum testEnum { - abc = 3, - def, - ghi = def, - jkl = ghi, - } - return testEnum["ghi"];` - ); + return TestEnum.A; + ` + .tap(expectToBeConst) + .expectToMatchJsResult(); + }); + + test("access with string literal", () => { + util.testFunction` + const enum TestEnum { + A, + B, + C, + } - expect(result).toBe(4); + return TestEnum["C"]; + ` + .tap(expectToBeConst) + .expectToMatchJsResult(); + }); }); test("enum toString", () => { @@ -196,34 +154,3 @@ test("enum concat", () => { return test + "_foobar";`; expect(util.transpileAndExecute(code)).toBe("0_foobar"); }); - -test("enum value as array index", () => { - const code = ` - enum TestEnum { - A, - B, - C, - } - const arr = ["a", "b", "c"]; - let i = TestEnum.A; - return arr[i];`; - expect(util.transpileAndExecute(code)).toBe("a"); -}); - -test("enum property value as array index", () => { - const code = ` - enum TestEnum { - A, - B, - C, - } - - class Foo { - i = TestEnum.A; - } - const foo = new Foo(); - - const arr = ["a", "b", "c"]; - return arr[foo.i];`; - expect(util.transpileAndExecute(code)).toBe("a"); -}); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 5f0ec7df6..17a6bc15c 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -2,51 +2,47 @@ import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("throwString", () => { - const lua = util.transpileString(`throw "Some Error"`); - expect(lua).toBe(`error("Some Error")`); + util.testFunction` + throw "Some Error" + `.expectToEqual(new util.ExecutionError("Some Error")); }); test("throwError", () => { - expect(() => { - util.transpileString(`throw Error("Some Error")`); - }).toThrowExactError(TSTLErrors.InvalidThrowExpression(util.nodeStub)); + util.testFunction` + throw Error("Some Error") + `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidThrowExpression(util.nodeStub)); }); -test.each([{ i: 0, expected: "A" }, { i: 1, expected: "B" }, { i: 2, expected: "C" }])( - "re-throw (%p)", - ({ i, expected }) => { - const source = ` - const i: number = ${i}; - function foo() { +test.skip.each([0, 1, 2])("re-throw (%p)", i => { + util.testFunction` + const i: number = ${i}; + function foo() { + try { try { - try { - if (i === 0) { throw "z"; } - } catch (e) { - throw "a"; - } finally { - if (i === 1) { throw "b"; } - } + if (i === 0) { throw "z"; } } catch (e) { - throw (e as string).toUpperCase(); + throw "a"; } finally { - throw "C"; + if (i === 1) { throw "b"; } } - } - let result: string = "x"; - try { - foo(); } catch (e) { - result = (e as string)[(e as string).length - 1]; + throw (e as string).toUpperCase(); + } finally { + throw "C"; } - return result; - `; - const result = util.transpileAndExecute(source); - expect(result).toBe(expected); - } -); + } + let result: string = "x"; + try { + foo(); + } catch (e) { + result = (e as string)[(e as string).length - 1]; + } + return result; + `.expectToMatchJsResult(); +}); test("re-throw (no catch var)", () => { - const source = ` + util.testFunction` let result = "x"; try { try { @@ -58,9 +54,7 @@ test("re-throw (no catch var)", () => { result = (e as string)[(e as string).length - 1]; } return result; - `; - const result = util.transpileAndExecute(source); - expect(result).toBe("z"); + `.expectToMatchJsResult(); }); test("return from try", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index a2e902352..5209bb59c 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -3,53 +3,44 @@ import * as tstl from "../../src"; import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; -test.each([ - { input: "i++", lua: "i = i + 1" }, - { input: "++i", lua: "i = i + 1" }, - { input: "i--", lua: "i = i - 1" }, - { input: "--i", lua: "i = i - 1" }, - { input: "!a", lua: "local ____ = not a" }, - { input: "-a", lua: "local ____ = -a" }, - { input: "+a", lua: "local ____ = a" }, - { input: "let a = delete tbl['test']", lua: "local a = (function()\n tbl.test = nil\n return true\nend)()" }, - { input: "delete tbl['test']", lua: "tbl.test = nil" }, - { input: "let a = delete tbl.test", lua: "local a = (function()\n tbl.test = nil\n return true\nend)()" }, - { input: "delete tbl.test", lua: "tbl.test = nil" }, -])("Unary expressions basic (%p)", ({ input, lua }) => { - expect(util.transpileString(input)).toBe(lua); +// TODO: +test("Block statement", () => { + util.testFunction` + let a = 4; + { let a = 42; } + return a; + `.expectToMatchJsResult(); }); test.each([ - { input: "3+4", output: 3 + 4 }, - { input: "5-2", output: 5 - 2 }, - { input: "6*3", output: 6 * 3 }, - { input: "6**3", output: 6 ** 3 }, - { input: "20/5", output: 20 / 5 }, - { input: "15/10", output: 15 / 10 }, - { input: "15%3", output: 15 % 3 }, -])("Binary expressions basic numeric (%p)", ({ input, output }) => { - const result = util.transpileAndExecute(`return ${input}`); - - expect(result).toBe(output); + "i++", + "++i", + "i--", + "--i", + "!a", + "-a", + "+a", + "let a = delete tbl['test']", + "delete tbl['test']", + "let a = delete tbl.test", + "delete tbl.test", +])("Unary expressions basic (%p)", input => { + util.testFunction(input) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); }); -test.each([ - { input: "1==1", expected: true }, - { input: "1===1", expected: true }, - { input: "1!=1", expected: false }, - { input: "1!==1", expected: false }, - { input: "1>1", expected: false }, - { input: "1>=1", expected: true }, - { input: "1<1", expected: false }, - { input: "1<=1", expected: true }, - { input: "1&&1", expected: 1 }, - { input: "1||1", expected: 1 }, -])("Binary expressions basic boolean (%p)", ({ input, expected }) => { - const result = util.transpileAndExecute(`return ${input}`); - - expect(result).toBe(expected); +test.each(["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"])("Binary expressions basic numeric (%p)", input => { + util.testExpression(input).expectToMatchJsResult(); }); +test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1", "1||1"])( + "Binary expressions basic boolean (%p)", + input => { + util.testExpression(input).expectToMatchJsResult(); + } +); + test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Binary expression in (%p)", input => { const tsHeader = "declare var obj: any;"; const tsSource = `return ${input}`; @@ -59,143 +50,84 @@ test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Bin expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); }); -test.each([ - { input: "a+=b", expected: 5 + 3 }, - { input: "a-=b", expected: 5 - 3 }, - { input: "a*=b", expected: 5 * 3 }, - { input: "a/=b", expected: 5 / 3 }, - { input: "a%=b", expected: 5 % 3 }, - { input: "a**=b", expected: 5 ** 3 }, -])("Binary expressions overridden operators (%p)", ({ input, expected }) => { - const result = util.transpileAndExecute(`let a = 5; let b = 3; ${input}; return a;`); - - expect(result).toBe(expected); +test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions overridden operators (%p)", input => { + util.testFunction` + let a = 5; + let b = 3; + ${input}; + return a; + `.expectToMatchJsResult(); }); -test.each([ - { input: "~b" }, - { input: "a&b" }, - { input: "a&=b" }, - { input: "a|b" }, - { input: "a|=b" }, - { input: "a^b" }, - { input: "a^=b" }, - { input: "a<>b" }, - { input: "a>>=b" }, - { input: "a>>>b" }, - { input: "a>>>=b" }, -])("Bitop [5.1] (%p)", ({ input }) => { +const supportedInAll = ["~a", "a&b", "a&=b", "a|b", "a|=b", "a^b", "a^=b", "a<>>b", "a>>>=b"]; +const unsupportedIn53 = ["a>>b", "a>>=b"]; +const allBinaryOperators = [...supportedInAll, ...unsupportedIn53]; +test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception - expect(() => - util.transpileString(input, { - luaTarget: tstl.LuaTarget.Lua51, - luaLibImport: tstl.LuaLibImportKind.None, - }) - ).toThrow(); -}); - -test.each([ - { input: "~a", lua: "bit.bnot(a)" }, - { input: "a&b", lua: "bit.band(a, b)" }, - { input: "a&=b", lua: "a = bit.band(a, b)" }, - { input: "a|b", lua: "bit.bor(a, b)" }, - { input: "a|=b", lua: "a = bit.bor(a, b)" }, - { input: "a^b", lua: "bit.bxor(a, b)" }, - { input: "a^=b", lua: "a = bit.bxor(a, b)" }, - { input: "a<>b", lua: "bit.arshift(a, b)" }, - { input: "a>>=b", lua: "a = bit.arshift(a, b)" }, - { input: "a>>>b", lua: "bit.rshift(a, b)" }, - { input: "a>>>=b", lua: "a = bit.rshift(a, b)" }, -])("Bitop [JIT] (%p)", ({ input, lua }) => { - const options = { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.None }; - expect(util.transpileString(input, options)).toBe(lua); -}); - -test.each([ - { input: "~a", lua: "bit32.bnot(a)" }, - { input: "a&b", lua: "bit32.band(a, b)" }, - { input: "a&=b", lua: "a = bit32.band(a, b)" }, - { input: "a|b", lua: "bit32.bor(a, b)" }, - { input: "a|=b", lua: "a = bit32.bor(a, b)" }, - { input: "a^b", lua: "bit32.bxor(a, b)" }, - { input: "a^=b", lua: "a = bit32.bxor(a, b)" }, - { input: "a<>b", lua: "bit32.arshift(a, b)" }, - { input: "a>>=b", lua: "a = bit32.arshift(a, b)" }, - { input: "a>>>b", lua: "bit32.rshift(a, b)" }, - { input: "a>>>=b", lua: "a = bit32.rshift(a, b)" }, -])("Bitop [5.2] (%p)", ({ input, lua }) => { - const options = { luaTarget: tstl.LuaTarget.Lua52, luaLibImport: tstl.LuaLibImportKind.None }; - expect(util.transpileString(input, options)).toBe(lua); -}); - -test.each([ - { input: "~a", lua: "local ____ = ~a" }, - { input: "a&b", lua: "local ____ = a & b" }, - { input: "a&=b", lua: "a = a & b" }, - { input: "a|b", lua: "local ____ = a | b" }, - { input: "a|=b", lua: "a = a | b" }, - { input: "a^b", lua: "local ____ = a ~ b" }, - { input: "a^=b", lua: "a = a ~ b" }, - { input: "a<>>b", lua: "local ____ = a >> b" }, - { input: "a>>>=b", lua: "a = a >> b" }, -])("Bitop [5.3] (%p)", ({ input, lua }) => { - const options = { luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }; - expect(util.transpileString(input, options)).toBe(lua); -}); - -test.each(["a>>b", "a>>=b"])("Unsupported bitop 5.3 (%p)", input => { - expect(() => - util.transpileString(input, { - luaTarget: tstl.LuaTarget.Lua53, - luaLibImport: tstl.LuaLibImportKind.None, - }) - ).toThrowExactError( - TSTLErrors.UnsupportedKind( - "right shift operator (use >>> instead)", - ts.SyntaxKind.GreaterThanGreaterThanToken, - util.nodeStub - ) - ); -}); - -test.each([ - { input: "1+1", lua: "1 + 1" }, - { input: "-1+1", lua: "-1 + 1" }, - { input: "1*30+4", lua: "1 * 30 + 4" }, - { input: "1*(3+4)", lua: "1 * (3 + 4)" }, - { input: "1*(3+4*2)", lua: "1 * (3 + 4 * 2)" }, - { input: "10-(4+5)", lua: "10 - (4 + 5)" }, -])("Binary expressions ordering parentheses (%p)", ({ input, lua }) => { - expect(util.transpileString(input)).toBe("local ____ = " + lua); -}); + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua51, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectToHaveDiagnosticOfError( + TSTLErrors.UnsupportedForTarget("Bitwise operations", tstl.LuaTarget.Lua51, util.nodeStub) + ); +}); + +test.each(allBinaryOperators)("Bitop [JIT] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + +test.each(allBinaryOperators)("Bitop [5.2] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua52, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + +test.each(supportedInAll)("Bitop [5.3] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + +test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectToHaveDiagnosticOfError( + TSTLErrors.UnsupportedKind( + "right shift operator (use >>> instead)", + ts.SyntaxKind.GreaterThanGreaterThanToken, + util.nodeStub + ) + ); +}); + +test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( + "Binary expressions ordering parentheses (%p)", + input => { + util.testExpression(input).expectLuaToMatchSnapshot(); + } +); -test.each([ - { input: "bar(),foo()", expectResult: 1 }, - { input: "foo(),bar()", expectResult: 2 }, - { input: "foo(),bar(),baz()", expectResult: 3 }, -])("Binary Comma (%p)", ({ input, expectResult }) => { - const code = `function foo() { return 1; } +test.each(["bar(),foo()", "foo(),bar()", "foo(),bar(),baz()"])("Binary Comma (%p)", input => { + util.testFunction` + function foo() { return 1; } function bar() { return 2; }; function baz() { return 3; }; - return (${input});`; - expect(util.transpileAndExecute(code)).toBe(expectResult); + return (${input}); + `.expectToMatchJsResult(); }); test("Binary Comma Statement in For Loop", () => { - const code = ` + util.testFunction` let x: number, y: number; for (x = 0, y = 17; x < 5; ++x, --y) {} return y; - `; - expect(util.transpileAndExecute(code)).toBe(12); + `.expectToMatchJsResult(); }); test("Null Expression", () => { @@ -206,301 +138,19 @@ test("Undefined Expression", () => { expect(util.transpileString("undefined")).toBe("local ____ = nil"); }); -test.each([ - { input: "true ? 'a' : 'b'", expected: "a" }, - { input: "false ? 'a' : 'b'", expected: "b" }, - { input: "true ? false : true", expected: false }, - { input: "false ? false : true", expected: true }, - { input: "true ? literalValue : true", expected: "literal" }, - { input: "true ? variableValue : true" }, - { input: "true ? maybeUndefinedValue : true" }, - { input: "true ? maybeBooleanValue : true", expected: false }, - { input: "true ? maybeUndefinedValue : true", options: { strictNullChecks: true } }, - { input: "true ? maybeBooleanValue : true", expected: false, options: { strictNullChecks: true } }, - { input: "true ? undefined : true", options: { strictNullChecks: true } }, - { input: "true ? null : true", options: { strictNullChecks: true } }, - { input: "true ? false : true", expected: false, options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "false ? false : true", expected: true, options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "true ? false : true", expected: false, options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "false ? false : true", expected: true, options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, -])("Ternary operator (%p)", ({ input, expected, options }) => { - const result = util.transpileAndExecute( - `const literalValue = 'literal'; - let variableValue:string; - let maybeBooleanValue:string|boolean = false; - let maybeUndefinedValue:string|undefined; - return ${input};`, - options - ); - - expect(result).toBe(expected); -}); - -test.each([ - { expression: "inst.field", expected: 8 }, - { expression: "inst.field + 3", expected: 8 + 3 }, - { expression: "inst.field * 3", expected: 8 * 3 }, - { expression: "inst.field / 2", expected: 8 / 2 }, - { expression: "inst.field && 3", expected: 8 && 3 }, - { expression: "inst.field || 3", expected: 8 || 3 }, - { expression: "(inst.field + 3) & 3", expected: (8 + 3) & 3 }, - { expression: "inst.field | 3", expected: 8 | 3 }, - { expression: "inst.field << 3", expected: 8 << 3 }, - { expression: "inst.field >>> 1", expected: 8 >> 1 }, - { expression: "inst.field = 3", expected: 3 }, - { expression: `"abc" + inst.field`, expected: "abc8" }, -])("Get accessor expression (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute(` - class MyClass { - public _field: number; - public get field(): number { return this._field + 4; } - public set field(v: number) { this._field = v; } - } - var inst = new MyClass(); - inst._field = 4; +test.each(["i++", "i--", "++i", "--i"])("Incrementor value (%p)", expression => { + util.testFunction` + let i = 10; return ${expression}; - `); - - expect(result).toBe(expected); -}); - -test.each([ - { expression: "= 4", expected: 4 + 4 }, - { expression: "-= 3", expected: 4 - 3 + 4 }, - { expression: "+= 3", expected: 4 + 3 + 4 }, - { expression: "*= 3", expected: 4 * 3 + 4 }, - { expression: "/= 2", expected: 4 / 2 + 4 }, - { expression: "&= 3", expected: (4 & 3) + 4 }, - { expression: "|= 3", expected: (4 | 3) + 4 }, - { expression: "<<= 3", expected: (4 << 3) + 4 }, - { expression: ">>>= 3", expected: (4 >> 3) + 4 }, -])("Set accessorExpression (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute(` - class MyClass { - public _field: number = 4; - public get field(): number { return this._field; } - public set field(v: number) { this._field = v + 4; } - } - var inst = new MyClass(); - inst.field ${expression}; - return inst._field; - `); - - expect(result).toBe(expected); -}); - -test.each([ - { expression: "inst.baseField", expected: 7 }, - { expression: "inst.field", expected: 6 }, - { expression: "inst.superField", expected: 5 }, - { expression: "inst.superBaseField", expected: 4 }, -])("Inherited accessors (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute(` - class MyBaseClass { - public _baseField: number; - public get baseField(): number { return this._baseField + 6; } - public set baseField(v: number) { this._baseField = v; } - } - class MyClass extends MyBaseClass { - public _field: number; - public get field(): number { return this._field + 4; } - public set field(v: number) { this._field = v; } - } - class MySuperClass extends MyClass { - public _superField: number; - public get superField(): number { return this._superField + 2; } - public set superField(v: number) { this._superField = v; } - public get superBaseField() { return this.baseField - 3; } - } - var inst = new MySuperClass(); - inst.baseField = 1; - inst.field = 2; - inst.superField = 3; - return ${expression} - `); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "return x.value;", expected: 1 }, - { expression: "x.value = 3; return x.value;", expected: 3 }, -])("Union accessors (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `class A{ get value(){ return this.v || 1; } set value(v){ this.v = v; } v: number; } - class B{ get value(){ return this.v || 2; } set value(v){ this.v = v; } v: number; } - let x: A|B = new A(); - ${expression}` - ); - - expect(result).toBe(expected); -}); - -test.each([ - { expression: "i++", expected: 10 }, - { expression: "i--", expected: 10 }, - { expression: "++i", expected: 11 }, - { expression: "--i", expected: 9 }, -])("Incrementor value (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute(`let i = 10; return ${expression};`); - - expect(result).toBe(expected); -}); - -test.each([ - { lambda: "a++", expected: "val3" }, - { lambda: "a--", expected: "val3" }, - { lambda: "--a", expected: "val2" }, - { lambda: "++a", expected: "val4" }, -])("Template string expression (%p)", ({ lambda, expected }) => { - const result = util.transpileAndExecute("let a = 3; return `val${" + lambda + "}`;"); - - expect(result).toEqual(expected); -}); - -test.each([{ expression: "x = y", expected: "y" }, { expression: "x += y", expected: "xy" }])( - "Assignment expressions (%p)", - ({ expression, expected }) => { - const result = util.transpileAndExecute(`let x = "x"; let y = "y"; return ${expression};`); - expect(result).toBe(expected); - } -); - -test.each([ - { expression: "x = o.p", expected: "o" }, - { expression: "x = a[0]", expected: "a" }, - { expression: "x = y = o.p", expected: "o" }, - { expression: "x = o.p", expected: "o" }, -])("Assignment expressions using temp (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let x = "x"; - let y = "y"; - let o = {p: "o"}; - let a = ["a"]; - return ${expression};` - ); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "o.p = x", expected: "x" }, - { expression: "a[0] = x", expected: "x" }, - { expression: "o.p = a[0]", expected: "a" }, - { expression: "o.p = a[0] = x", expected: "x" }, -])("Property assignment expressions (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let x = "x"; - let o = {p: "o"}; - let a = ["a"]; - return ${expression};` - ); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "x = t()", expected: "t0,t1" }, - { expression: "x = tr()", expected: "tr0,tr1" }, - { expression: "[x[1], x[0]] = t()", expected: "t0,t1" }, - { expression: "[x[1], x[0]] = tr()", expected: "tr0,tr1" }, - { expression: "x = [y[1], y[0]]", expected: "y1,y0" }, - { expression: "[x[0], x[1]] = [y[1], y[0]]", expected: "y1,y0" }, -])("Tuple assignment expressions (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let x: [string, string] = ["x0", "x1"]; - let y: [string, string] = ["y0", "y1"]; - function t(): [string, string] { return ["t0", "t1"] }; - /** @tupleReturn */ - function tr(): [string, string] { return ["tr0", "tr1"] }; - const r = ${expression}; - return \`\${r[0]},\${r[1]}\`` - ); - expect(result).toBe(expected); -}); - -test("Block expression", () => { - const result = util.transpileAndExecute(`let a = 4; {let a = 42; } return a;`); - expect(result).toBe(4); + `.expectToMatchJsResult(); }); test("Non-null expression", () => { - const result = util.transpileAndExecute(` + util.testFunction` function abc(): number | undefined { return 3; } const a: number = abc()!; return a; - `); - expect(result).toBe(3); -}); - -test("Unknown unary postfix error", () => { - const transformer = util.makeTestTransformer(); - - const mockExpression: any = { - operand: ts.createLiteral(false), - operator: ts.SyntaxKind.AsteriskToken, - }; - - expect(() => - transformer.transformPostfixUnaryExpression(mockExpression as ts.PostfixUnaryExpression) - ).toThrowExactError( - TSTLErrors.UnsupportedKind("unary postfix operator", ts.SyntaxKind.AsteriskToken, util.nodeStub) - ); -}); - -test("Unknown unary postfix error", () => { - const transformer = util.makeTestTransformer(); - - const mockExpression: any = { - operand: ts.createLiteral(false), - operator: ts.SyntaxKind.AsteriskToken, - }; - - expect(() => - transformer.transformPrefixUnaryExpression(mockExpression as ts.PrefixUnaryExpression) - ).toThrowExactError( - TSTLErrors.UnsupportedKind("unary prefix operator", ts.SyntaxKind.AsteriskToken, util.nodeStub) - ); -}); - -test("Incompatible fromCodePoint expression error", () => { - expect(() => util.transpileString("const abc = String.fromCodePoint(123);")).toThrowExactError( - TSTLErrors.UnsupportedForTarget("string property fromCodePoint", tstl.LuaTarget.Lua53, util.nodeStub) - ); -}); - -test("Unknown string expression error", () => { - expect(() => util.transpileString("const abc = String.abcd();")).toThrowExactError( - TSTLErrors.UnsupportedForTarget("string property abcd", tstl.LuaTarget.Lua53, util.nodeStub) - ); -}); - -test("Unsupported array function error", () => { - expect(() => util.transpileString("const abc = [].unknownFunction();")).toThrowExactError( - TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub) - ); -}); - -test("Unsupported math property error", () => { - expect(() => util.transpileString("const abc = Math.unknownProperty;")).toThrowExactError( - TSTLErrors.UnsupportedProperty("math", "unknownProperty", util.nodeStub) - ); -}); - -test("Unsupported object literal element error", () => { - const transformer = util.makeTestTransformer(); - - const mockObject: any = { - properties: [ - { - kind: ts.SyntaxKind.FalseKeyword, - name: ts.createIdentifier("testProperty"), - }, - ], - }; - - expect(() => transformer.transformObjectLiteral(mockObject as ts.ObjectLiteralExpression)).toThrowExactError( - TSTLErrors.UnsupportedKind("object literal element", ts.SyntaxKind.FalseKeyword, util.nodeStub) - ); + `.expectToMatchJsResult(); }); test.each([ @@ -514,80 +164,15 @@ test.each([ "!foo()", "foo()", "typeof foo", - '"bar" in bar', + '"foo" in bar', "foo as Function", "Math.log2(2)", "Math.log10(2)", '"".indexOf("")', ])("Expression statements (%p)", input => { - const code = ` + util.testFunction` function foo() { return 17; } - const bar = {}; + const bar = { foo }; ${input}; - return 1; - `; - expect(util.transpileAndExecute(code)).toBe(1); -}); - -test("binary expression with 'as' type assertion wrapped in parenthesis", () => { - expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); -}); - -test.each([ - "(x as any).foo;", - "(y.x as any).foo;", - "(y['x'] as any).foo;", - "(z() as any).foo;", - "(y.z() as any).foo;", - "(x).foo;", - "(y.x).foo;", - "(y['x']).foo;", - "(z()).foo;", - "(y.z()).foo;", - "(x as unknown as any).foo;", - "(x as any).foo;", - "((x as unknown) as any).foo;", - "((x) as any).foo;", -])("'as' type assertion should strip parenthesis (%p)", expression => { - const code = ` - declare let x: unknown; - declare let y: { x: unknown; z(this: void): unknown; }; - declare function z(this: void): unknown; - ${expression}`; - - const lua = util.transpileString(code, undefined, false); - expect(lua).not.toMatch(/\(.+\)/); -}); - -test.each([ - "(x + 1 as any).foo;", - "(!x as any).foo;", - "(x ** 2 as any).foo;", - "(x < 2 as any).foo;", - "(x in y as any).foo;", - "(x + 1).foo;", - "(!x).foo;", - "(x + 1 as unknown as any).foo;", - "((x + 1 as unknown) as any).foo;", - "(!x as unknown as any).foo;", - "((!x as unknown) as any).foo;", - "(!x as any).foo;", - "((!x) as any).foo;", -])("'as' type assertion should not strip parenthesis (%p)", expression => { - const code = ` - declare let x: number; - declare let y: {}; - ${expression}`; - - const lua = util.transpileString(code, undefined, false); - expect(lua).toMatch(/\(.+\)/); -}); - -test("not operator precedence (%p)", () => { - const code = ` - const a = true; - const b = false; - return !a && b;`; - - expect(util.transpileAndExecute(code)).toBe(false); + `.expectNoExecutionError(); }); diff --git a/test/unit/functions.spec.ts b/test/unit/functions.spec.ts deleted file mode 100644 index b8558a3cd..000000000 --- a/test/unit/functions.spec.ts +++ /dev/null @@ -1,633 +0,0 @@ -import * as ts from "typescript"; -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; - -test("Arrow Function Expression", () => { - const result = util.transpileAndExecute(`let add = (a, b) => a+b; return add(1,2);`); - - expect(result).toBe(3); -}); - -test.each([ - { lambda: "i++", expected: 15 }, - { lambda: "i--", expected: 5 }, - { lambda: "++i", expected: 15 }, - { lambda: "--i", expected: 5 }, -])("Arrow function unary expression (%p)", ({ lambda, expected }) => { - const result = util.transpileAndExecute(`let i = 10; [1,2,3,4,5].forEach(() => ${lambda}); return i;`); - - expect(result).toBe(expected); -}); - -test.each([ - { lambda: "b => a = b", expected: 5 }, - { lambda: "b => a += b", expected: 15 }, - { lambda: "b => a -= b", expected: 5 }, - { lambda: "b => a *= b", expected: 50 }, - { lambda: "b => a /= b", expected: 2 }, - { lambda: "b => a **= b", expected: 100000 }, - { lambda: "b => a %= b", expected: 0 }, -])("Arrow function assignment (%p)", ({ lambda, expected }) => { - const result = util.transpileAndExecute(`let a = 10; let lambda = ${lambda}; - lambda(5); return a;`); - - expect(result).toBe(expected); -}); - -test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Arrow Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - - const callArgs = inp.join(","); - - const result = util.transpileAndExecute( - `let add = (a: number = 3, b: number = 4) => a+b; - return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); -}); - -test("Function Expression", () => { - const result = util.transpileAndExecute(`let add = function(a, b) {return a+b}; return add(1,2);`); - - expect(result).toBe(3); -}); - -test("Function definition scope", () => { - const result = util.transpileAndExecute(`function abc() { function xyz() { return 5; } }\n - function def() { function xyz() { return 3; } abc(); return xyz(); }\n - return def();`); - - expect(result).toBe(3); -}); - -test("Function default parameter", () => { - const result = util.transpileAndExecute(`function abc(defaultParam: string = "abc") { return defaultParam; }\n - return abc() + abc("def");`); - - expect(result).toBe("abcdef"); -}); - -test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - - const callArgs = inp.join(","); - - const result = util.transpileAndExecute( - `let add = function(a: number = 3, b: number = 4) { return a+b; }; - return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); -}); - -test("Function default array binding parameter", () => { - const code = ` - function foo([bar]: [string] = ["foobar"]) { - return bar; - } - return foo();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); -}); - -test("Function default object binding parameter", () => { - const code = ` - function foo({ bar }: { bar: string } = { bar: "foobar" }) { - return bar; - } - return foo();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); -}); - -test("Function default binding parameter maintains order", () => { - const code = ` - const resultsA = [{x: "foo"}, {x: "baz"}]; - const resultsB = ["blah", "bar"]; - let i = 0; - function a() { return resultsA[i++]; } - function b() { return resultsB[i++]; } - function foo({ x }: { x: string } = a(), y = b()) { - return x + y; - } - return foo();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); -}); - -test("Class method call", () => { - const returnValue = 4; - const source = `class TestClass { - public classMethod(): number { return ${returnValue}; } - } - - const classInstance = new TestClass(); - return classInstance.classMethod();`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe(returnValue); -}); - -test("Class dot method call void", () => { - const returnValue = 4; - const source = `class TestClass { - public dotMethod: () => number = () => ${returnValue}; - } - - const classInstance = new TestClass(); - return classInstance.dotMethod();`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe(returnValue); -}); - -test("Class dot method call with parameter", () => { - const returnValue = 4; - const source = `class TestClass { - public dotMethod: (x: number) => number = x => 3 * x; - } - - const classInstance = new TestClass(); - return classInstance.dotMethod(${returnValue});`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe(3 * returnValue); -}); - -test("Class static dot method", () => { - const returnValue = 4; - const source = `class TestClass { - public static dotMethod: () => number = () => ${returnValue}; - } - - return TestClass.dotMethod();`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe(returnValue); -}); - -test("Class static dot method with parameter", () => { - const returnValue = 4; - const source = `class TestClass { - public static dotMethod: (x: number) => number = x => 3 * x; - } - - return TestClass.dotMethod(${returnValue});`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe(3 * returnValue); -}); - -test("Function bind", () => { - const source = `const abc = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } - return abc.bind({ a: 4 }, "b")("c");`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe("4bc"); -}); - -test("Function apply", () => { - const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } - return abc.apply({ a: 4 }, ["b"]);`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe("4b"); -}); - -test("Function call", () => { - const source = `const abc = function (this: { a: number }, a: string) { return this.a + a; } - return abc.call({ a: 4 }, "b");`; - - const result = util.transpileAndExecute(source); - - expect(result).toBe("4b"); -}); - -test("Invalid property access call transpilation", () => { - const transformer = util.makeTestTransformer(); - - const mockObject: any = { - expression: ts.createLiteral("abc"), - }; - - expect(() => transformer.transformPropertyCall(mockObject as ts.CallExpression)).toThrowExactError( - TSTLErrors.InvalidPropertyCall(util.nodeStub) - ); -}); - -test("Function dead code after return", () => { - const result = util.transpileAndExecute(`function abc() { return 3; const a = 5; } return abc();`); - - expect(result).toBe(3); -}); - -test("Method dead code after return", () => { - const result = util.transpileAndExecute( - `class def { public static abc() { return 3; const a = 5; } } return def.abc();` - ); - - expect(result).toBe(3); -}); - -test("Recursive function definition", () => { - const result = util.transpileAndExecute(`function f() { return typeof f; }; return f();`); - - expect(result).toBe("function"); -}); - -test("Recursive function expression", () => { - const result = util.transpileAndExecute(`let f = function() { return typeof f; }; return f();`); - - expect(result).toBe("function"); -}); - -test("Wrapped recursive function expression", () => { - const result = util.transpileAndExecute( - `function wrap(fn: T) { return fn; } - let f = wrap(function() { return typeof f; }); return f();` - ); - - expect(result).toBe("function"); -}); - -test("Recursive arrow function", () => { - const result = util.transpileAndExecute(`let f = () => typeof f; return f();`); - - expect(result).toBe("function"); -}); - -test("Wrapped recursive arrow function", () => { - const result = util.transpileAndExecute( - `function wrap(fn: T) { return fn; } - let f = wrap(() => typeof f); return f();` - ); - - expect(result).toBe("function"); -}); - -test("Object method declaration", () => { - const result = util.transpileAndExecute( - `let o = { v: 4, m(i: number): number { return this.v * i; } }; return o.m(3);` - ); - expect(result).toBe(12); -}); - -test.each([{ args: ["bar"], expectResult: "foobar" }, { args: ["baz", "bar"], expectResult: "bazbar" }])( - "Function overload (%p)", - ({ args, expectResult }) => { - const code = ` - class O { - prop = "foo"; - method(s: string): string; - method(this: void, s1: string, s2: string): string; - method(s1: string) { - if (typeof this === "string") { - return this + s1; - } - return this.prop + s1; - } - }; - const o = new O(); - return o.method(${args.map(a => '"' + a + '"').join(", ")}); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); - } -); - -test("Nested Function", () => { - const code = ` - class C { - private prop = "bar"; - public outer() { - const o = { - prop: "foo", - innerFunc: function() { return this.prop; }, - innerArrow: () => this.prop - }; - return o.innerFunc() + o.innerArrow(); - } - } - let c = new C(); - return c.outer(); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foobar"); -}); - -test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])("Dot vs Colon method call (%p)", ({ s1, s2 }) => { - const result = util.transpileAndExecute(` - class MyClass { - dotMethod(this: void, s: string) { - return s; - } - colonMethod(s: string) { - return s; - } - } - const inst = new MyClass(); - return inst.dotMethod("${s1}") == inst.colonMethod("${s2}"); - `); - expect(result).toBe(s1 === s2); -}); - -test("Element access call", () => { - const code = ` - class C { - prop = "bar"; - method(s: string) { return s + this.prop; } - } - const c = new C(); - return c['method']("foo"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foobar"); -}); - -test("Element access call no args", () => { - const code = ` - class C { - prop = "bar"; - method() { return this.prop; } - } - const c = new C(); - return c['method'](); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("bar"); -}); - -test("Complex element access call", () => { - const code = ` - class C { - prop = "bar"; - method(s: string) { return s + this.prop; } - } - function getC() { return new C(); } - return getC()['method']("foo"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foobar"); -}); - -test("Complex element access call no args", () => { - const code = ` - class C { - prop = "bar"; - method() { return this.prop; } - } - function getC() { return new C(); } - return getC()['method'](); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("bar"); -}); - -test("Complex element access call statement", () => { - const code = ` - let foo: string; - class C { - prop = "bar"; - method(s: string) { foo = s + this.prop; } - } - function getC() { return new C(); } - getC()['method']("foo"); - return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foobar"); -}); - -test.each([{ iterations: 1, expectedResult: 1 }, { iterations: 2, expectedResult: 42 }])( - "Generator functions value (%p)", - ({ iterations, expectedResult }) => { - const code = ` - function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: number; - for(let i = 0; i < ${iterations}; ++i) - { - ret = gen.next(i).value; - } - return ret; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectedResult); - } -); - -test.each([{ iterations: 1, expectedResult: false }, { iterations: 2, expectedResult: true }])( - "Generator functions done (%p)", - ({ iterations, expectedResult }) => { - const code = ` - function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: boolean; - for(let i = 0; i < ${iterations}; ++i) - { - ret = gen.next(i).done; - } - return ret; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectedResult); - } -); - -test("Generator for..of", () => { - const code = ` - function* seq() { - yield(1); - yield(2); - yield(3); - return 4; - } - let result = 0; - for(let i of seq()) - { - result = result * 10 + i; - } - return result - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(123); -}); - -test("Function local overriding export", () => { - const code = ` - export const foo = 5; - function bar(foo: number) { - return foo; - } - export const result = bar(7); - `; - expect(util.transpileExecuteAndReturnExport(code, "result")).toBe(7); -}); - -test("Function using global as this", () => { - const code = ` - var foo = "foo"; - function bar(this: any) { - return this.foo; - } - `; - expect(util.transpileAndExecute("return foo;", undefined, undefined, code)).toBe("foo"); -}); - -test("Function rest binding pattern", () => { - const result = util.transpileAndExecute(` - function bar(foo: string, ...[bar, baz]: [string, string]) { - return bar + baz + foo; - } - return bar("abc", "def", "xyz"); - `); - - expect(result).toBe("defxyzabc"); -}); - -test.each([{}, { noHoisting: true }])("Function rest parameter", compilerOptions => { - const code = ` - function foo(a: unknown, ...b: string[]) { - return b.join(""); - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); -}); - -test.each([{}, { noHoisting: true }])("Function nested rest parameter", compilerOptions => { - const code = ` - function foo(a: unknown, ...b: string[]) { - function bar() { - return b.join(""); - } - return bar(); - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); -}); - -test.each([{}, { noHoisting: true }])("Function nested rest spread", compilerOptions => { - const code = ` - function foo(a: unknown, ...b: string[]) { - function bar() { - const c = [...b]; - return c.join(""); - } - return bar(); - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); -}); - -test.each([{}, { noHoisting: true }])("Function rest parameter (unreferenced)", compilerOptions => { - const code = ` - function foo(a: unknown, ...b: string[]) { - return "foobar"; - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileString(code, compilerOptions)).not.toMatch("b = ({...})"); - expect(util.transpileAndExecute(code, compilerOptions)).toBe("foobar"); -}); - -test.each([{}, { noHoisting: true }])("Function rest parameter (referenced in property shorthand)", compilerOptions => { - const code = ` - function foo(a: unknown, ...b: string[]) { - const c = { b }; - return c.b.join(""); - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); -}); - -test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; - function foo(a: unknown, ...b: LuaVarArg) { - const c = [...b]; - return c.join(""); - } - function bar(a: unknown, ...b: LuaVarArg) { - return foo(a, ...b); - } - return bar("A", "B", "C", "D"); - `; - - const lua = util.transpileString(code, compilerOptions); - expect(lua).not.toMatch("b = ({...})"); - expect(lua).not.toMatch("unpack"); - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); -}); - -test.each([{}, { noHoisting: true }])("@vararg array access", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; - function foo(a: unknown, ...b: LuaVarArg) { - const c = [...b]; - return c.join("") + b[0]; - } - return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCDB"); -}); - -test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; - declare const arg: LuaVarArg; - const arr = [...arg]; - const result = arr.join(""); - `; - - const luaBody = util.transpileString(code, compilerOptions, false); - expect(luaBody).not.toMatch("unpack"); - - const lua = ` - function test(...) - ${luaBody} - return result - end - return test("A", "B", "C", "D") - `; - - expect(util.executeLua(lua)).toBe("ABCD"); -}); - -test("named function expression reference", () => { - const code = ` - const y = function x(inp: string) { - return inp + typeof x; - }; - return y("foo-");`; - expect(util.transpileAndExecute(code)).toBe("foo-function"); -}); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts new file mode 100644 index 000000000..8214e6bfd --- /dev/null +++ b/test/unit/functions/functions.spec.ts @@ -0,0 +1,514 @@ +import * as ts from "typescript"; +import * as TSTLErrors from "../../../src/TSTLErrors"; +import * as util from "../../util"; + +test("Arrow Function Expression", () => { + util.testFunction` + const add = (a, b) => a + b; + return add(1, 2); + `.expectToMatchJsResult(); +}); + +test("Returning arrow function from arrow function", () => { + util.testFunction` + const add = (x: number) => (y: number) => x + y; + return add(1)(2); + `.expectToMatchJsResult(); +}); + +test.each(["i++", "i--", "++i", "--i"])("Arrow function unary expression (%p)", lambda => { + util.testFunction` + let i = 10; + [1,2,3,4,5].forEach(() => ${lambda}); + return i; + `.expectToMatchJsResult(); +}); + +test.each(["b => a = b", "b => a += b", "b => a -= b", "b => a *= b", "b => a /= b", "b => a **= b", "b => a %= b"])( + "Arrow function assignment (%p)", + lambda => { + util.testFunction` + let a = 10; + let lambda = ${lambda}; + lambda(5); + return a; + `.expectToMatchJsResult(); + } +); + +test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Arrow Default Values (%p)", ({ inp }) => { + // Default value is 3 for v1 + const v1 = inp.length > 0 ? inp[0] : 3; + // Default value is 4 for v2 + const v2 = inp.length > 1 ? inp[1] : 4; + + const callArgs = inp.join(","); + + const result = util.transpileAndExecute( + `let add = (a: number = 3, b: number = 4) => a+b; + return add(${callArgs});` + ); + + expect(result).toBe(v1 + v2); +}); + +test("Function Expression", () => { + util.testFunction` + let add = function(a, b) {return a+b}; + return add(1,2); + `.expectToMatchJsResult(); +}); + +test("Function definition scope", () => { + util.testFunction` + function abc() { function xyz() { return 5; } } + function def() { function xyz() { return 3; } abc(); return xyz(); } + return def(); + `.expectToMatchJsResult(); +}); + +test("Function default parameter", () => { + util.testFunction` + function abc(defaultParam: string = "abc") { return defaultParam; } + return abc() + abc("def"); + `.expectToMatchJsResult(); +}); + +test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { + // Default value is 3 for v1 + const v1 = inp.length > 0 ? inp[0] : 3; + // Default value is 4 for v2 + const v2 = inp.length > 1 ? inp[1] : 4; + + const callArgs = inp.join(","); + + const result = util.transpileAndExecute( + `let add = function(a: number = 3, b: number = 4) { return a+b; }; + return add(${callArgs});` + ); + + expect(result).toBe(v1 + v2); +}); + +test("Function default array binding parameter", () => { + util.testFunction` + function foo([bar]: [string] = ["foobar"]) { + return bar; + } + return foo(); + `.expectToMatchJsResult(); +}); + +test("Function default object binding parameter", () => { + util.testFunction` + function foo({ bar }: { bar: string } = { bar: "foobar" }) { + return bar; + } + return foo(); + `.expectToMatchJsResult(); +}); + +test("Function default binding parameter maintains order", () => { + util.testFunction` + const resultsA = [{x: "foo"}, {x: "baz"}]; + const resultsB = ["blah", "bar"]; + let i = 0; + function a() { return resultsA[i++]; } + function b() { return resultsB[i++]; } + function foo({ x }: { x: string } = a(), y = b()) { + return x + y; + } + return foo(); + `.expectToMatchJsResult(); +}); + +test("Class method call", () => { + util.testFunction` + class TestClass { + public classMethod(): number { return 4; } + } + + const classInstance = new TestClass(); + return classInstance.classMethod(); + `.expectToMatchJsResult(); +}); + +test("Class dot method call void", () => { + util.testFunction` + class TestClass { + public dotMethod: () => number = () => 4; + } + + const classInstance = new TestClass(); + return classInstance.dotMethod(); + `.expectToMatchJsResult(); +}); + +test("Class dot method call with parameter", () => { + util.testFunction` + class TestClass { + public dotMethod: (x: number) => number = x => 3 * x; + } + + const classInstance = new TestClass(); + return classInstance.dotMethod(4); + `.expectToMatchJsResult(); +}); + +test("Class static dot method", () => { + util.testFunction` + class TestClass { + public static dotMethod: () => number = () => 4; + } + + return TestClass.dotMethod(); + `.expectToMatchJsResult(); +}); + +test("Class static dot method with parameter", () => { + util.testFunction` + class TestClass { + public static dotMethod: (x: number) => number = x => 3 * x; + } + + return TestClass.dotMethod(4); + `.expectToMatchJsResult(); +}); + +test("Function bind", () => { + util.testFunction` + const abc = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } + return abc.bind({ a: 4 }, "b")("c"); + `.expectToMatchJsResult(); +}); + +test("Function apply", () => { + util.testFunction` + const abc = function (this: { a: number }, a: string) { return this.a + a; } + return abc.apply({ a: 4 }, ["b"]); + `.expectToMatchJsResult(); +}); + +test("Function call", () => { + util.testFunction` + const abc = function (this: { a: number }, a: string) { return this.a + a; } + return abc.call({ a: 4 }, "b"); + `.expectToMatchJsResult(); +}); + +test("Invalid property access call transpilation", () => { + const transformer = util.makeTestTransformer(); + + const mockObject: any = { + expression: ts.createLiteral("abc"), + }; + + expect(() => transformer.transformPropertyCall(mockObject as ts.CallExpression)).toThrowExactError( + TSTLErrors.InvalidPropertyCall(util.nodeStub) + ); +}); + +test("Recursive function definition", () => { + util.testFunction` + function f() { return typeof f; }; + return f(); + `.expectToMatchJsResult(); +}); + +test("Recursive function expression", () => { + util.testFunction` + let f = function() { return typeof f; }; + return f(); + `.expectToMatchJsResult(); +}); + +test("Wrapped recursive function expression", () => { + util.testFunction` + function wrap(fn: T) { return fn; } + let f = wrap(function() { return typeof f; }); return f(); + `.expectToMatchJsResult(); +}); + +test("Recursive arrow function", () => { + util.testFunction` + let f = () => typeof f; + return f(); + `.expectToMatchJsResult(); +}); + +test("Wrapped recursive arrow function", () => { + util.testFunction` + function wrap(fn: T) { return fn; } + let f = wrap(() => typeof f); + return f(); + `.expectToMatchJsResult(); +}); + +test("Object method declaration", () => { + util.testFunction` + let o = { v: 4, m(i: number): number { return this.v * i; } }; + return o.m(3); + `.expectToMatchJsResult(); +}); + +test.each([{ args: ["bar"], expected: "foobar" }, { args: ["baz", "bar"], expected: "bazbar" }])( + "Function overload (%p)", + ({ args, expected }) => { + util.testFunction` + class O { + prop = "foo"; + method(s: string): string; + method(this: void, s1: string, s2: string): string; + method(s1: string) { + if (typeof this === "string") { + return this + s1; + } + return this.prop + s1; + } + }; + const o = new O(); + return o.method(${util.valuesToString(args)}); + `.expectToEqual(expected); + } +); + +test("Nested Function", () => { + util.testFunction` + class C { + private prop = "bar"; + public outer() { + const o = { + prop: "foo", + innerFunc: function() { return this.prop; }, + innerArrow: () => this.prop + }; + return o.innerFunc() + o.innerArrow(); + } + } + let c = new C(); + return c.outer(); + `.expectToMatchJsResult(); +}); + +test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])("Dot vs Colon method call (%p)", ({ s1, s2 }) => { + util.testFunction` + class MyClass { + dotMethod(this: void, s: string) { + return s; + } + colonMethod(s: string) { + return s; + } + } + const inst = new MyClass(); + return inst.dotMethod("${s1}") == inst.colonMethod("${s2}"); + `.expectToMatchJsResult(); +}); + +test("Element access call", () => { + util.testFunction` + class C { + prop = "bar"; + method(s: string) { return s + this.prop; } + } + const c = new C(); + return c['method']("foo"); + `.expectToMatchJsResult(); +}); + +test("Element access call no args", () => { + util.testFunction` + class C { + prop = "bar"; + method() { return this.prop; } + } + const c = new C(); + return c['method'](); + `.expectToMatchJsResult(); +}); + +test("Complex element access call", () => { + util.testFunction` + class C { + prop = "bar"; + method(s: string) { return s + this.prop; } + } + function getC() { return new C(); } + return getC()['method']("foo"); + `.expectToMatchJsResult(); +}); + +test("Complex element access call no args", () => { + util.testFunction` + class C { + prop = "bar"; + method() { return this.prop; } + } + function getC() { return new C(); } + return getC()['method'](); + `.expectToMatchJsResult(); +}); + +test("Complex element access call statement", () => { + util.testFunction` + let foo: string; + class C { + prop = "bar"; + method(s: string) { foo = s + this.prop; } + } + function getC() { return new C(); } + getC()['method']("foo"); + return foo; + `.expectToMatchJsResult(); +}); + +test.each([1, 2])("Generator functions value (%p)", iterations => { + util.testFunction` + function* seq(value: number) { + let a = yield value + 1; + return 42; + } + const gen = seq(0); + let ret: number; + for(let i = 0; i < ${iterations}; ++i) { + ret = gen.next(i).value; + } + return ret; + `.expectToMatchJsResult(); +}); + +test.each([1, 2])("Generator functions done (%p)", iterations => { + util.testFunction` + function* seq(value: number) { + let a = yield value + 1; + return 42; + } + const gen = seq(0); + let ret: boolean; + for(let i = 0; i < ${iterations}; ++i) { + ret = gen.next(i).done; + } + return ret; + `.expectToMatchJsResult(); +}); + +test("Generator for..of", () => { + util.testFunction` + function* seq() { + yield(1); + yield(2); + yield(3); + return 4; + } + let result = 0; + for(let i of seq()) { + result = result * 10 + i; + } + return result + `.expectToMatchJsResult(); +}); + +test("Function local overriding export", () => { + util.testModule` + export const foo = 5; + function bar(foo: number) { + return foo; + } + export const result = bar(7); + ` + .setReturnExport("result") + .expectToMatchJsResult(); +}); + +test("Function using global as this", () => { + const tsHeader = ` + var foo = "foo"; + function bar(this: any) { + return this.foo; + } + `; + + util.testExpression`foo`.setTsHeader(tsHeader).expectToMatchJsResult(); +}); + +test("Function rest binding pattern", () => { + util.testFunction` + function bar(foo: string, ...[bar, baz]: [string, string]) { + return bar + baz + foo; + } + return bar("abc", "def", "xyz"); + `.expectToMatchJsResult(); +}); + +test.each([{}, { noHoisting: true }])("Function rest parameter", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + return b.join(""); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function nested rest parameter", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + function bar() { + return b.join(""); + } + return bar(); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function nested rest spread", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + function bar() { + const c = [...b]; + return c.join(""); + } + return bar(); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test.each([{}, { noHoisting: true }])("Function rest parameter (unreferenced)", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + return "foobar"; + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileString(code, compilerOptions)).not.toMatch("b = ({...})"); + expect(util.transpileAndExecute(code, compilerOptions)).toBe("foobar"); +}); + +test.each([{}, { noHoisting: true }])("Function rest parameter (referenced in property shorthand)", compilerOptions => { + const code = ` + function foo(a: unknown, ...b: string[]) { + const c = { b }; + return c.b.join(""); + } + return foo("A", "B", "C", "D"); + `; + + expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); +}); + +test("named function expression reference", () => { + const code = ` + const y = function x(inp: string) { + return inp + typeof x; + }; + return y("foo-");`; + expect(util.transpileAndExecute(code)).toBe("foo-function"); +}); diff --git a/test/unit/assignments/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts similarity index 99% rename from test/unit/assignments/functionExpressionTypeInference.spec.ts rename to test/unit/functions/validation/functionExpressionTypeInference.spec.ts index aefc24427..767fe0b30 100644 --- a/test/unit/assignments/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -1,4 +1,4 @@ -import * as util from "../../util"; +import * as util from "../../../util"; test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", noSelfTag => { const header = ` diff --git a/test/unit/assignments/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts similarity index 100% rename from test/unit/assignments/functionPermutations.ts rename to test/unit/functions/validation/functionPermutations.ts diff --git a/test/unit/assignments/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts similarity index 98% rename from test/unit/assignments/invalidFunctionAssignments.spec.ts rename to test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 97002fd7d..06050ac5e 100644 --- a/test/unit/assignments/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -1,5 +1,5 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; -import * as util from "../../util"; +import * as TSTLErrors from "../../../../src/TSTLErrors"; +import * as util from "../../../util"; import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; test.each(invalidTestFunctionAssignments)( diff --git a/test/unit/assignments/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts similarity index 99% rename from test/unit/assignments/validFunctionAssignments.spec.ts rename to test/unit/functions/validation/validFunctionAssignments.spec.ts index be553b956..be1130ba6 100644 --- a/test/unit/assignments/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -1,17 +1,17 @@ -import * as util from "../../util"; +import * as util from "../../../util"; import { - validTestFunctionAssignments, - validTestFunctionCasts, - selfTestFunctions, + anonTestFunctionExpressions, + anonTestFunctionType, + noSelfTestFunctionExpressions, noSelfTestFunctions, - TestFunctionAssignment, + noSelfTestFunctionType, selfTestFunctionExpressions, - noSelfTestFunctionExpressions, + selfTestFunctions, selfTestFunctionType, - anonTestFunctionType, - noSelfTestFunctionType, - anonTestFunctionExpressions, TestFunction, + TestFunctionAssignment, + validTestFunctionAssignments, + validTestFunctionCasts, } from "./functionPermutations"; test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index d8b00733f..bde4477fa 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -21,56 +21,50 @@ const invalidLuaNames = [...invalidLuaCharNames, ...luaKeywords.values()]; const validTsInvalidLuaNames = [...invalidLuaCharNames, ...validTsInvalidLuaKeywordNames]; test.each(validTsInvalidLuaNames)("invalid lua identifier name (%p)", name => { - const code = ` + util.testFunction` const ${name} = "foobar"; - return ${name};`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return ${name}; + `.expectToMatchJsResult(); }); test.each([...luaKeywords.values()])("lua keyword as property name (%p)", keyword => { - const code = ` + util.testFunction` const x = { ${keyword}: "foobar" }; - return x.${keyword};`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return x.${keyword}; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaKeywordNames)("destructuring lua keyword (%p)", keyword => { - const code = ` - const { foo: ${keyword} } = { foo: "foobar" }; - return ${keyword};`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + util.testFunction` + const { foo: ${keyword} } = { foo: "foobar" }; + return ${keyword}; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaKeywordNames)("destructuring shorthand lua keyword (%p)", keyword => { - const code = ` - const { ${keyword} } = { ${keyword}: "foobar" }; - return ${keyword};`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + util.testFunction` + const { ${keyword} } = { ${keyword}: "foobar" }; + return ${keyword}; + `.expectToMatchJsResult(); }); test.each(invalidLuaNames)("lua keyword or invalid identifier as method call (%p)", name => { - const code = ` + util.testFunction` const foo = { ${name}(arg: string) { return "foo" + arg; } }; - return foo.${name}("bar");`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo.${name}("bar"); + `.expectToMatchJsResult(); }); test.each(invalidLuaNames)("lua keyword or invalid identifier as complex method call (%p)", name => { - const code = ` + util.testFunction` const foo = { ${name}(arg: string) { return "foo" + arg; } }; function getFoo() { return foo; } - return getFoo().${name}("bar");`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return getFoo().${name}("bar"); + `.expectToMatchJsResult(); }); test.each([ @@ -84,13 +78,12 @@ test.each([ "enum local {}", "function local() {}", ])("ambient identifier cannot be a lua keyword (%p)", statement => { - const code = ` + util.testModule` declare ${statement} - const foo = local;`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local")).message - ); + local; + ` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local"))); }); test.each([ @@ -102,42 +95,40 @@ test.each([ "namespace $$$ { export const bar: any; }", "module $$$ { export const bar: any; }", "enum $$$ {}", - "function $$$() {}", + "function $$$();", ])("ambient identifier must be a valid lua identifier (%p)", statement => { - const code = ` + util.testModule` declare ${statement} - const foo = $$$;`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$")).message - ); + $$$; + `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$"))); }); test.each(validTsInvalidLuaNames)( "ambient identifier must be a valid lua identifier (object literal shorthand) (%p)", name => { - const code = ` - declare var ${name}: any; - const foo = { ${name} };`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message - ); + util.testModule` + declare var ${name}: any; + const foo = { ${name} }; + `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); } ); test.each(validTsInvalidLuaNames)("undeclared identifier must be a valid lua identifier (%p)", name => { - expect(() => util.transpileString(`const foo = ${name};`)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message - ); + util.testModule` + const foo = ${name}; + ` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); }); test.each(validTsInvalidLuaNames)( "undeclared identifier must be a valid lua identifier (object literal shorthand) (%p)", name => { - expect(() => util.transpileString(`const foo = { ${name} };`)).toThrow( - TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name)).message - ); + util.testModule` + const foo = { ${name} }; + ` + .disableSemanticCheck() + .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); } ); @@ -196,15 +187,14 @@ test.each(validTsInvalidLuaNames)( ); test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name property", name => { - const code = ` + util.testFunction` class ${name} {} - return ${name}.name;`; - - expect(util.transpileAndExecute(code)).toBe(name); + return ${name}.name; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name => { - const code = ` + util.testFunction` function decorator(c: T): T { c.bar = "foobar"; return c; @@ -212,9 +202,8 @@ test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name @decorator class ${name} {} - return (${name} as any).bar;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (${name} as any).bar; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua name", name => { @@ -788,66 +777,3 @@ test("exported variable with lua keyword as name is not renamed", () => { expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); }); - -describe("globalThis translation", () => { - test("globalThis to _G (expression)", () => { - const code = ` - var foo = "bar"; - return globalThis.foo;`; - - const lua = util.transpileString(code); - - expect(util.executeLua(lua)).toBe("bar"); - }); - - test("globalThis to _G (assign)", () => { - const code = ` - globalThis.foo = "bar"; - return globalThis.foo;`; - - expect(util.transpileAndExecute(code)).toBe("bar"); - }); - - test("globalThis to _G (reassign)", () => { - const code = ` - globalThis.foo = "bar"; - globalThis.foo = "baz"; - return globalThis.foo;`; - - expect(util.transpileAndExecute(code)).toBe("baz"); - }); - - test("globalThis to _G (function)", () => { - const code = ` - globalThis.foo = () => "bar"; - return globalThis.foo();`; - - expect(util.transpileAndExecute(code)).toBe("bar"); - }); - - test("globalThis to _G (assign + noImplicitAny)", () => { - const code = ` - (globalThis).foo = "bar"; - return (globalThis).foo;`; - - expect(util.transpileAndExecute(code)).toBe("bar"); - }); - - test("globalThis to _G (var)", () => { - const code = ` - var globalFoo = "bar"; - return globalThis.globalFoo;`; - - const lua = util.transpileString(code); - - expect(util.executeLua(lua)).toBe("bar"); - }); - - test("globalThis to _G (let)", () => { - const code = ` - let NotAGlobalFoo = "bar"; - return (globalThis).NotAGlobalFoo;`; - - expect(util.transpileAndExecute(code)).toBe(undefined); - }); -}); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index 642243155..e822fc1ae 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -8,17 +8,16 @@ const jsonOptions = { moduleResolution: ts.ModuleResolutionKind.NodeJs, }; -test.each(["0", '""', "[]", '[1, "2", []]', '{ "a": "b" }', '{ "a": { "b": "c" } }'])("JSON (%p)", json => { - const lua = util - .transpileString({ "main.json": json }, jsonOptions, false) - .replace(/^return ([\s\S]+)$/, "return JSONStringify($1)"); - - const result = util.executeLua(lua); - expect(JSON.parse(result)).toEqual(JSON.parse(json)); +test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { + util.testModule(JSON.stringify(json)) + .setOptions(jsonOptions) + .setMainFileName("main.json") + .expectToEqual(json); }); test("Empty JSON", () => { - expect(() => util.transpileString({ "main.json": "" }, jsonOptions, false)).toThrowExactError( - TSTLErrors.InvalidJsonFileContent(util.nodeStub) - ); + util.testModule("") + .setOptions(jsonOptions) + .setMainFileName("main.json") + .expectToHaveDiagnosticOfError(TSTLErrors.InvalidJsonFileContent(util.nodeStub)); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 57cd5cc11..34e92998a 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -170,53 +170,48 @@ test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoCondition (%p)" expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoPostExpression (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; - for (;;) { - if (i >= arrTest.length) { - break; - } - - arrTest[i] = arrTest[i] + 1; - - i++; +test("forNoPostExpression (%p)", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; + let i = 0; + for (;;) { + if (i >= arrTest.length) { + break; } - return JSONStringify(arrTest);` - ); - expect(result).toBe(JSON.stringify(expected)); + arrTest[i] = arrTest[i] + 1; + + i++; + } + return arrTest; + `.expectToMatchJsResult(); }); test.each([ - { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; i < arrTest.length; i++" }, - { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; i <= arrTest.length - 1; i++" }, - { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; arrTest.length > i; i++" }, - { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = 0; arrTest.length - 1 >= i; i++" }, - { inp: [0, 1, 2, 3], expected: [1, 1, 3, 3], header: "let i = 0; i < arrTest.length; i += 2" }, - { inp: [0, 1, 2, 3], expected: [1, 2, 3, 4], header: "let i = arrTest.length - 1; i >= 0; i--" }, - { inp: [0, 1, 2, 3], expected: [0, 2, 2, 4], header: "let i = arrTest.length - 1; i >= 0; i -= 2" }, - { inp: [0, 1, 2, 3], expected: [0, 2, 2, 4], header: "let i = arrTest.length - 1; i > 0; i -= 2" }, -])("forheader (%p)", ({ inp, expected, header }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; + { inp: [0, 1, 2, 3], header: "let i = 0; i < arrTest.length; i++" }, + { inp: [0, 1, 2, 3], header: "let i = 0; i <= arrTest.length - 1; i++" }, + { inp: [0, 1, 2, 3], header: "let i = 0; arrTest.length > i; i++" }, + { inp: [0, 1, 2, 3], header: "let i = 0; arrTest.length - 1 >= i; i++" }, + { inp: [0, 1, 2, 3], header: "let i = 0; i < arrTest.length; i += 2" }, + { inp: [0, 1, 2, 3], header: "let i = arrTest.length - 1; i >= 0; i--" }, + { inp: [0, 1, 2, 3], header: "let i = arrTest.length - 1; i >= 0; i -= 2" }, + { inp: [0, 1, 2, 3], header: "let i = arrTest.length - 1; i > 0; i -= 2" }, +])("forheader (%p)", ({ inp, header }) => { + util.testFunction` + let arrTest = ${JSON.stringify(inp)}; for (${header}) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrTest; + `.expectToMatchJsResult(); }); test("for scope", () => { - const code = ` + util.testFunction` let i = 42; for (let i = 0; i < 10; ++i) {} return i; - `; - expect(util.transpileAndExecute(code)).toBe(42); + `.expectToMatchJsResult(); }); test.each([ @@ -279,6 +274,15 @@ test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expec expect(result).toBe(JSON.stringify(expected)); }); +test("Tuple loop", () => { + util.testFunction` + const tuple: [number, number, number] = [3,5,1]; + let count = 0; + for (const value of tuple) { count += value; } + return count; + `.expectToMatchJsResult(); +}); + test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof existing variable (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( `let objTest = ${JSON.stringify(inp)}; @@ -496,264 +500,6 @@ test("forof with array typed as iterable", () => { expect(util.transpileAndExecute(code)).toBe("ABC"); }); -test("forof lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); -}); - -test("forof array lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Array {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); -}); - -test("forof lua iterator with existing variable", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - let e: string; - for (e of luaIter()) { result += e; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); -}); - -test("forof lua iterator destructuring", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator destructuring with existing variables", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return with existing variables", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); -}); - -test("forof lua iterator tuple-return single variable", () => { - const code = ` - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - for (let x of luaIter()) {} - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) - ); -}); - -test("forof lua iterator tuple-return single existing variable", () => { - const code = ` - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - let x: [string, string]; - for (x of luaIter()) {} - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) - ); -}); - -test("forof forwarded lua iterator", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - function iter() { return arr[i++]; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let a of forward()) { result += a; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); -}); - -test("forof forwarded lua iterator with tupleReturn", () => { - const code = ` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let [a, b] of forward()) { result += a + b; } - return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); -}); - describe("for...of empty destructuring", () => { const declareTests = (destructuringPrefix: string) => { test("array", () => { @@ -849,139 +595,6 @@ test.each([ expect(util.transpileString(loop, luajit).indexOf("::__continue1::") !== -1).toBe(true); }); -test("for dead code after return", () => { - const result = util.transpileAndExecute(`for (let i = 0; i < 10; i++) { return 3; const b = 8; }`); - - expect(result).toBe(3); -}); - -test("for..in dead code after return", () => { - const result = util.transpileAndExecute(`for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`); - - expect(result).toBe(3); -}); - -test("for..of dead code after return", () => { - const result = util.transpileAndExecute(`for (let a of [1,2,4]) { return 3; const b = 8; }`); - - expect(result).toBe(3); -}); - -test("while dead code after return", () => { - const result = util.transpileAndExecute(`while (true) { return 3; const b = 8; }`); - - expect(result).toBe(3); -}); - -test.each([ - { args: [1, 10], expectResult: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { args: [1, 10, 2], expectResult: [1, 3, 5, 7, 9] }, - { args: [10, 1, -1], expectResult: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, - { args: [10, 1, -2], expectResult: [10, 8, 6, 4, 2] }, -])("@forRange loop", ({ args, expectResult }) => { - const tsHeader = "/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];"; - const code = ` - const results: number[] = []; - for (const i of luaRange(${args})) { - results.push(i); - } - return JSONStringify(results);`; - - const result = util.transpileAndExecute(code, undefined, undefined, tsHeader); - expect(JSON.parse(result)).toEqual(expectResult); -}); - -test("invalid non-ambient @forRange function", () => { - const code = ` - /** @forRange **/ function luaRange(i: number, j: number, k?: number): number[] { return []; } - for (const i of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function can only be used as an iterable in a for...of loop." - ).message - ); -}); - -test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => { - const code = ` - /** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; } - for (const i of luaRange(${args})) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.") - .message - ); -}); - -test("invalid @forRange control variable", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; - let i: number; - for (i of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange loop must declare its own control variable." - ).message - ); -}); - -test("invalid @forRange argument type", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: string, j: number): number[] { return []; } - for (const i of luaRange("foo", 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message - ); -}); - -test("invalid @forRange destructuring", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[][]; - for (const [i] of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message - ); -}); - -test("invalid @forRange return type", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): string[]; - for (const i of luaRange(1, 10)) {}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function must return Iterable or Array." - ).message - ); -}); - -test.each([ - "const range = luaRange(1, 10);", - "console.log(luaRange);", - "luaRange.call(null, 0, 0, 0);", - "let array = [0, luaRange, 1];", - "const call: any; call(luaRange);", - "for (const i of [...luaRange(1, 10)]) {}", -])("invalid @forRange reference (%p)", statement => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; - ${statement}`; - - expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function can only be used as an iterable in a for...of loop." - ).message - ); -}); - test("do...while", () => { const code = ` let result = 0; diff --git a/test/unit/lualib/array.spec.ts b/test/unit/lualib/array.spec.ts deleted file mode 100644 index ad8c64db2..000000000 --- a/test/unit/lualib/array.spec.ts +++ /dev/null @@ -1,458 +0,0 @@ -import * as util from "../../util"; - -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forEach (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - arrTest.forEach((elem, index) => { - arrTest[index] = arrTest[index] + 1; - }) - return JSONStringify(arrTest);` - ); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { inp: [], searchEl: 3, expected: -1 }, - { inp: [0, 2, 4, 8], searchEl: 10, expected: -1 }, - { inp: [0, 2, 4, 8], searchEl: 8, expected: 3 }, -])("array.findIndex[value] (%p)", ({ inp, searchEl, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index) => { - return elem === ${searchEl}; - }));` - ); - - expect(result).toEqual(expected); -}); - -test.each([{ inp: [0, 2, 4, 8], expected: 3, value: 8 }, { inp: [0, 2, 4, 8], expected: 1, value: 2 }])( - "array.findIndex[index] (%p)", - ({ inp, expected, value }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - return JSONStringify(arrTest.findIndex((elem, index, arr) => { - return index === ${expected} && arr[${expected}] === ${value}; - }));` - ); - - expect(result).toEqual(expected); - } -); - -test.each([ - { inp: [], func: "x => x" }, - { inp: [0, 1, 2, 3], func: "x => x" }, - { inp: [0, 1, 2, 3], func: "x => x*2" }, - { inp: [1, 2, 3, 4], func: "x => -x" }, - { inp: [0, 1, 2, 3], func: "x => x+2" }, - { inp: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, -])("array.map (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].map(${func}))`); - - expect(JSON.parse(result)).toEqual(inp.map(eval(func))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x < 3" }, - { inp: [0, 1, 2, 3], func: "x => x < 0" }, - { inp: [0, -1, -2, -3], func: "x => x < 0" }, - { inp: [0, 1, 2, 3], func: "() => true" }, - { inp: [0, 1, 2, 3], func: "() => false" }, -])("array.filter (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].filter(${func}))`); - - expect(JSON.parse(result)).toEqual(inp.filter(eval(func))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [false, true, false], func: "x => x" }, - { inp: [true, true, true], func: "x => x" }, -])("array.every (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].every(${func}))`); - - expect(JSON.parse(result)).toEqual(inp.every(eval(func))); -}); - -test.each([ - { inp: [], func: "x => x > 1" }, - { inp: [0, 1, 2, 3], func: "x => x > 1" }, - { inp: [false, true, false], func: "x => x" }, - { inp: [true, true, true], func: "x => x" }, -])("array.some (%p)", ({ inp, func }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].some(${func}))`); - - expect(JSON.parse(result)).toEqual(inp.some(eval(func))); -}); - -test.each([ - { inp: [], start: 1, end: 2 }, - { inp: [0, 1, 2, 3], start: 1, end: 2 }, - { inp: [0, 1, 2, 3], start: 1, end: 1 }, - { inp: [0, 1, 2, 3], start: 1, end: -1 }, - { inp: [0, 1, 2, 3], start: -3, end: -1 }, - { inp: [0, 1, 2, 3, 4, 5], start: 1, end: 3 }, - { inp: [0, 1, 2, 3, 4, 5], start: 3 }, -])("array.slice (%p)", ({ inp, start, end }) => { - const result = util.transpileAndExecute(`return JSONStringify([${inp.toString()}].slice(${start}, ${end}))`); - - expect(JSON.parse(result)).toEqual(inp.slice(start, end)); -}); - -test("array.slice no argument", () => { - const input = [2, 3, 4, 5]; - const result = util.transpileAndExecute(`return JSONStringify(${JSON.stringify(input)}.slice())`); - - expect(JSON.parse(result)).toEqual(input); -}); - -test.each([ - { inp: [], start: 0, deleteCount: 0, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 1, deleteCount: 0, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 2, deleteCount: 2, newElements: [9, 10, 11] }, - { inp: [0, 1, 2, 3], start: 4, deleteCount: 1, newElements: [8, 9] }, - { inp: [0, 1, 2, 3], start: 4, deleteCount: 0, newElements: [8, 9] }, - { inp: [0, 1, 2, 3], start: -2, deleteCount: 0, newElements: [8, 9] }, - { inp: [0, 1, 2, 3], start: -3, deleteCount: 0, newElements: [8, 9] }, - { inp: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, - { inp: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, -])("array.splice[Insert] (%p)", ({ inp, start, deleteCount, newElements }) => { - const result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` - ); - - inp.splice(start, deleteCount, ...newElements); - expect(JSON.parse(result)).toEqual(inp); -}); - -test.each([ - { inp: [], start: 1, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 1, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 10, deleteCount: 1 }, - { inp: [0, 1, 2, 3], start: 1, deleteCount: undefined }, - { inp: [0, 1, 2, 3], start: 4 }, - { inp: [0, 1, 2, 3, 4, 5], start: 3 }, - { inp: [0, 1, 2, 3, 4, 5], start: -3 }, - { inp: [0, 1, 2, 3, 4, 5], start: -2 }, - { inp: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, - { inp: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, -])("array.splice[Remove] (%p)", ({ inp, start, deleteCount, newElements = [] }) => { - let result; - if (deleteCount) { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}, ${deleteCount}, ${newElements}); - return JSONStringify(spliceTestTable);` - ); - } else { - result = util.transpileAndExecute( - `let spliceTestTable = [${inp.toString()}]; - spliceTestTable.splice(${start}); - return JSONStringify(spliceTestTable);` - ); - } - - if (deleteCount) { - inp.splice(start, deleteCount, ...newElements); - expect(JSON.parse(result)).toEqual(inp); - } else { - inp.splice(start); - expect(JSON.parse(result)).toEqual(inp); - } -}); - -test.each([ - { arr: [], args: [[]] }, - { arr: [1, 2, 3], args: [[]] }, - { arr: [1, 2, 3], args: [[4]] }, - { arr: [1, 2, 3], args: [[4, 5]] }, - { arr: [1, 2, 3], args: [[4, 5]] }, - { arr: [1, 2, 3], args: [4, [5]] }, - { arr: [1, 2, 3], args: [4, [5, 6]] }, - { arr: [1, 2, 3], args: [4, [5, 6], 7] }, - { arr: [1, 2, 3], args: ["test", [5, 6], 7, ["test1", "test2"]] }, - { arr: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, -])("array.concat (%p)", ({ arr, args }: { arr: any[]; args: any[] }) => { - const argStr = args.map(arg => JSON.stringify(arg)).join(","); - - const result = util.transpileAndExecute( - `let concatTestTable: any[] = ${JSON.stringify(arr)}; - return JSONStringify(concatTestTable.concat(${argStr}));` - ); - - const concatArr = arr.concat(...args); - expect(JSON.parse(result)).toEqual(concatArr); -}); - -test.each([ - { inp: [] }, - { inp: ["test1"] }, - { inp: ["test1", "test2"] }, - { inp: ["test1", "test2"], separator: ";" }, - { inp: ["test1", "test2"], separator: "" }, -])("array.join (%p)", ({ inp, separator }) => { - let separatorLua; - if (separator === "") { - separatorLua = '""'; - } else if (separator) { - separatorLua = '"' + separator + '"'; - } else { - separatorLua = ""; - } - const result = util.transpileAndExecute( - `let joinTestTable = ${JSON.stringify(inp)}; - return joinTestTable.join(${separatorLua});` - ); - - expect(result).toEqual(inp.join(separator)); -}); - -test.each([ - { inp: [], element: "test1" }, - { inp: ["test1"], element: "test1" }, - { inp: ["test1", "test2"], element: "test2" }, - { inp: ["test1", "test2", "test3"], element: "test3", fromIndex: 1 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 2 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: -2 }, - { inp: ["test1", "test2", "test3"], element: "test1", fromIndex: 12 }, -])("array.indexOf (%p)", ({ inp, element, fromIndex }) => { - let str = `return ${JSON.stringify(inp)}.indexOf("${element}");`; - if (fromIndex) { - str = `return ${JSON.stringify(inp)}.indexOf("${element}", ${fromIndex});`; - } - - const result = util.transpileAndExecute(str); - - // Account for lua indexing (-1) - expect(result).toEqual(inp.indexOf(element, fromIndex)); -}); - -test.each([{ inp: [1, 2, 3], expected: 3 }, { inp: [1, 2, 3, 4, 5], expected: 3 }])( - "array.destructuring.simple (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let [x, y, z] = ${JSON.stringify(inp)} - return z;` - ); - - expect(result).toEqual(expected); - } -); - -test.each([{ inp: [1] }, { inp: [1, 2, 3] }])("array.push (%p)", ({ inp }) => { - const result = util.transpileAndExecute( - `let testArray = [0]; - testArray.push(${inp.join(", ")}); - return JSONStringify(testArray);` - ); - - expect(JSON.parse(result)).toEqual([0].concat(inp)); -}); - -test.each([{ array: "[1, 2, 3]", expected: [3, 2] }, { array: "[1, 2, 3, null]", expected: [3, 2] }])( - "array.pop (%p)", - ({ array, expected }) => { - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.pop(); - return val` - ); - - expect(result).toEqual(expected[0]); - } - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.pop(); - return testArray.length` - ); - - expect(result).toEqual(expected[1]); - } - } -); - -test.each([ - { array: "[1, 2, 3]", expected: [3, 2, 1] }, - { array: "[1, 2, 3, null]", expected: [3, 2, 1] }, - { array: "[1, 2, 3, 4]", expected: [4, 3, 2, 1] }, - { array: "[1]", expected: [1] }, - { array: "[]", expected: [] }, -])("array.reverse (%p)", ({ array, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.reverse(); - return JSONStringify(testArray)` - ); - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { array: "[1, 2, 3]", expectedArray: [2, 3], expectedValue: 1 }, - { array: "[1]", expectedArray: [], expectedValue: 1 }, - { array: "[]", expectedArray: [], expectedValue: undefined }, -])("array.shift (%p)", ({ array, expectedArray, expectedValue }) => { - { - // test array mutation - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return JSONStringify(testArray)` - ); - expect(JSON.parse(result)).toEqual(expectedArray); - } - // test return value - { - const result = util.transpileAndExecute( - `let testArray = ${array}; - let val = testArray.shift(); - return val` - ); - - expect(result).toEqual(expectedValue); - } - } -}); - -test.each([ - { array: "[3, 4, 5]", toUnshift: [1, 2], expected: [1, 2, 3, 4, 5] }, - { array: "[]", toUnshift: [], expected: [] }, - { array: "[1]", toUnshift: [], expected: [1] }, - { array: "[]", toUnshift: [1], expected: [1] }, -])("array.unshift (%p)", ({ array, toUnshift, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.unshift(${toUnshift}); - return JSONStringify(testArray)` - ); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { array: "[4, 5, 3, 2, 1]", expected: [1, 2, 3, 4, 5] }, - { array: "[1]", expected: [1] }, - { array: "[1, null]", expected: [1] }, - { array: "[]", expected: [] }, -])("array.sort (%p)", ({ array, expected }) => { - const result = util.transpileAndExecute( - `let testArray = ${array}; - testArray.sort(); - return JSONStringify(testArray)` - ); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { array: [1, 2, 3, 4, 5], compareStr: "a - b", compareFn: (a: any, b: any) => a - b }, - { - array: ["4", "5", "3", "2", "1"], - compareStr: "tonumber(a) - tonumber(b)", - compareFn: (a: any, b: any) => Number(a) - Number(b), - }, - { - array: ["4", "5", "3", "2", "1"], - compareStr: "tonumber(b) - tonumber(a)", - compareFn: (a: any, b: any) => Number(b) - Number(a), - }, -])("array.sort with compare function (%p)", ({ array, compareStr, compareFn }) => { - const result = util.transpileAndExecute( - `let testArray = ${JSON.stringify(array)}; - testArray.sort((a, b) => ${compareStr}); - return JSONStringify(testArray)`, - undefined, - undefined, - `declare function tonumber(this: void, e: any): number` - ); - - expect(JSON.parse(result)).toEqual(array.sort(compareFn)); -}); - -test.each([ - { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, - { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, - { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, - { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, -])("array.flat (%p)", ({ array, depth, expected }) => { - // TODO: Remove once `Infinity` would be implemented - const luaDepth = depth === Infinity ? "1 / 0" : depth; - const result = util.transpileAndExecute(` - return JSONStringify(${JSON.stringify(array)}.flat(${luaDepth})) - `); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, - { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, - { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, -])("array.flatMap (%p)", ({ array, map, expected }) => { - const result = util.transpileAndExecute(` - const array = ${JSON.stringify(array)}; - const result = array.flatMap(${map.toString()}); - return JSONStringify(result); - `); - - // TODO(node 12): array.flatMap(map) - expect(JSON.parse(result)).toEqual(expected); -}); - -test.each([ - (total: number, currentItem: number) => total + currentItem, - (total: number, currentItem: number) => total * currentItem, -])("array reduce (%p)", reducer => { - const array = [1, 3, 5, 7]; - - const result = util.transpileAndExecute(` - const myArray = ${JSON.stringify(array)}; - return myArray.reduce(${reducer.toString()}); - `); - - expect(result).toEqual(array.reduce(reducer)); -}); - -test.each([ - (total: number, currentItem: number) => total + currentItem, - (total: number, currentItem: number) => total * currentItem, -])("array reduce with initial value (%p)", reducer => { - const array = [1, 3, 5, 7]; - const initial = 10; - - const result = util.transpileAndExecute(` - const myArray = ${JSON.stringify(array)}; - return myArray.reduce(${reducer.toString()}, ${initial}); - `); - - expect(result).toEqual(array.reduce(reducer, initial)); -}); - -test("array reduce index & array arguments (%p)", () => { - const array = [1, 3, 5, 7]; - const reducer = (total: number, _: number, index: number, array: number[]) => total + array[index]; - - const result = util.transpileAndExecute(` - const myArray = ${JSON.stringify(array)}; - return myArray.reduce(${reducer.toString()}); - `); - - expect(result).toEqual(array.reduce(reducer)); -}); - -test("array reduce index & array arguments (%p)", () => { - expect(() => { - util.transpileAndExecute("return [].reduce((a, b) => a + b);"); - }).toThrow("Reduce of empty array with no initial value"); -}); diff --git a/test/unit/lualib/inlining.spec.ts b/test/unit/lualib/inlining.spec.ts deleted file mode 100644 index b7a73fc57..000000000 --- a/test/unit/lualib/inlining.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { LuaLibImportKind, LuaTarget } from "../../../src"; -import * as util from "../../util"; - -test("map constructor", () => { - const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`, { - luaLibImport: LuaLibImportKind.Inline, - luaTarget: LuaTarget.Lua53, - }); - - expect(result).toBe(0); -}); - -test("map foreach keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); - let count = 0; - mymap.forEach((value, key) => { count += key; }); - return count;`, - { luaLibImport: LuaLibImportKind.Inline } - ); - - expect(result).toBe(18); -}); - -test("set constructor", () => { - const result = util.transpileAndExecute( - `class abc {} let def = new abc(); let myset = new Set(); return myset.size;`, - { luaLibImport: LuaLibImportKind.Inline } - ); - - expect(result).toBe(0); -}); - -test("set foreach keys", () => { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach((value, key) => { count += key; }); - return count;`, - { luaLibImport: LuaLibImportKind.Inline } - ); - - expect(result).toBe(9); -}); diff --git a/test/unit/lualib/lualib.spec.ts b/test/unit/lualib/lualib.spec.ts deleted file mode 100644 index 5ff9e45de..000000000 --- a/test/unit/lualib/lualib.spec.ts +++ /dev/null @@ -1,169 +0,0 @@ -import * as util from "../../util"; - -test.each([ - { condition: "true", lhs: "4", rhs: "5", expected: 4 }, - { condition: "false", lhs: "4", rhs: "5", expected: 5 }, - { condition: "3", lhs: "4", rhs: "5", expected: 4 }, -])("Ternary Conditional (%p)", ({ condition, lhs, rhs, expected }) => { - const result = util.transpileAndExecute(`return ${condition} ? ${lhs} : ${rhs};`); - - expect(result).toBe(expected); -}); - -test.each([ - { condition: "true", expected: 11 }, - { condition: "false", expected: 13 }, - { condition: "a < 4", expected: 13 }, - { condition: "a == 8", expected: 11 }, -])("Ternary Conditional Delayed (%p)", ({ condition, expected }) => { - const result = util.transpileAndExecute( - `let a = 3; - let delay = () => ${condition} ? a + 3 : a + 5; - a = 8; - return delay();` - ); - - expect(result).toBe(expected); -}); - -test.each([ - { initial: "{a: 3}", parameters: "{}", expected: { a: 3 } }, - { initial: "{}", parameters: "{a: 3}", expected: { a: 3 } }, - { initial: "{a: 3}", parameters: "{a: 5}", expected: { a: 5 } }, - { initial: "{a: 3}", parameters: "{b: 5},{c: 7}", expected: { a: 3, b: 5, c: 7 } }, -])("Object.assign (%p)", ({ initial, parameters, expected }) => { - const jsonResult = util.transpileAndExecute(` - return JSONStringify(Object.assign(${initial},${parameters})); - `); - - const result = JSON.parse(jsonResult); - expect(result).toEqual(expected); -}); - -test.each([ - { obj: "{}", expected: [] }, - { obj: "{abc: 3}", expected: ["abc,3"] }, - { obj: "{abc: 3, def: 'xyz'}", expected: ["abc,3", "def,xyz"] }, -])("Object.entries (%p)", ({ obj, expected }) => { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.entries(obj).map(e => e.join(",")).join(";"); - `) as string; - - const foundKeys = result.split(";"); - if (expected.length === 0) { - expect(foundKeys.length).toBe(1); - expect(foundKeys[0]).toBe(""); - } else { - expect(foundKeys.length).toBe(expected.length); - for (const key of expected) { - expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); - } - } -}); - -test.each([ - { obj: "{}", expected: [] }, - { obj: "{abc: 3}", expected: ["abc"] }, - { obj: "{abc: 3, def: 'xyz'}", expected: ["abc", "def"] }, -])("Object.keys (%p)", ({ obj, expected }) => { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.keys(obj).join(","); - `) as string; - - const foundKeys = result.split(","); - if (expected.length === 0) { - expect(foundKeys.length).toBe(1); - expect(foundKeys[0]).toBe(""); - } else { - expect(foundKeys.length).toBe(expected.length); - for (const key of expected) { - expect(foundKeys.indexOf(key) >= 0).toBeTruthy(); - } - } -}); - -test.each([ - { obj: "{}", expected: [] }, - { obj: "{abc: 'def'}", expected: ["def"] }, - { obj: "{abc: 3, def: 'xyz'}", expected: ["3", "xyz"] }, -])("Object.values (%p)", ({ obj, expected }) => { - const result = util.transpileAndExecute(` - const obj = ${obj}; - return Object.values(obj).join(","); - `) as string; - - const foundValues = result.split(","); - if (expected.length === 0) { - expect(foundValues.length).toBe(1); - expect(foundValues[0]).toBe(""); - } else { - expect(foundValues.length).toBe(expected.length); - for (const key of expected) { - expect(foundValues.indexOf(key) >= 0).toBeTruthy(); - } - } -}); - -// https://github.com/Microsoft/TypeScript/pull/26149 -const objectFromEntriesDeclaration = ` - interface ObjectConstructor { - fromEntries(entries: ReadonlyArray<[string, T]> | Iterable<[string, T]>): Record; - fromEntries(entries: ReadonlyArray<[string, any]> | Iterable<[string, any]>): Record; - } -`; - -test.each([ - { entries: [], expected: [] }, - { entries: [["a", 1], ["b", 2]], expected: { a: 1, b: 2 } }, - { entries: [["a", 1], ["a", 2]], expected: { a: 2 } }, -])("Object.fromEntries (%p)", ({ entries, expected }) => { - const result = util.transpileAndExecute( - `const obj = Object.fromEntries(${JSON.stringify(entries)}); - return JSONStringify(obj);`, - undefined, - undefined, - objectFromEntriesDeclaration - ); - - expect(JSON.parse(result)).toEqual(expected); -}); - -test("Object.fromEntries (Map)", () => { - const result = util.transpileAndExecute( - `const map = new Map([["foo", "bar"]]); - const obj = Object.fromEntries(map); - return JSONStringify(obj);`, - undefined, - undefined, - objectFromEntriesDeclaration - ); - - expect(JSON.parse(result)).toEqual({ foo: "bar" }); -}); - -test("lualibs should not include tstl header", () => { - const code = ` - const arr = [1, 2, 3]; - arr.push(4);`; - - expect(util.transpileString(code)).not.toMatch("Generated with"); -}); - -test("compileMembersOnly in namespace", () => { - const header = ` - namespace wifi { - /** @compileMembersOnly */ - export enum WifiMode { - NULLMODE = 0, - STATION = 1, - SOFTAP = 2 - } - }`; - const code = ` - return wifi.WifiMode.STATION; - `; - - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe(1); -}); diff --git a/test/unit/lualib/set.spec.ts b/test/unit/lualib/set.spec.ts deleted file mode 100644 index 6018d42cf..000000000 --- a/test/unit/lualib/set.spec.ts +++ /dev/null @@ -1,124 +0,0 @@ -import * as util from "../../util"; - -test("set constructor", () => { - const result = util.transpileAndExecute(`let myset = new Set(); return myset.size;`); - - expect(result).toBe(0); -}); - -test("set iterable constructor", () => { - const result = util.transpileAndExecute( - `let myset = new Set(["a", "b"]); - return myset.has("a") || myset.has("b");` - ); - - expect(result).toBe(true); -}); - -test("set iterable constructor set", () => { - const result = util.transpileAndExecute( - `let myset = new Set(new Set(["a", "b"])); - return myset.has("a") || myset.has("b");` - ); - - expect(result).toBe(true); -}); - -test("set add", () => { - const has = util.transpileAndExecute(`let myset = new Set(); myset.add("a"); return myset.has("a");`); - expect(has).toBe(true); -}); - -test("set clear", () => { - const setTS = `let myset = new Set(["a", "b"]); myset.clear();`; - const size = util.transpileAndExecute(setTS + `return myset.size;`); - expect(size).toBe(0); - - const contains = util.transpileAndExecute(setTS + `return !myset.has("a") && !myset.has("b");`); - expect(contains).toBe(true); -}); - -test("set delete", () => { - const setTS = `let myset = new Set(["a", "b"]); myset.delete("a");`; - const contains = util.transpileAndExecute(setTS + `return myset.has("b") && !myset.has("a");`); - expect(contains).toBe(true); -}); - -test("set entries", () => { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var [key, value] of myset.entries()) { count += key + value; } - return count;` - ); - - expect(result).toBe(36); -}); - -test("set foreach", () => { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach(i => { count += i; }); - return count;` - ); - expect(result).toBe(9); -}); - -test("set foreach keys", () => { - const result = util.transpileAndExecute( - `let myset = new Set([2, 3, 4]); - let count = 0; - myset.forEach((value, key) => { count += key; }); - return count;` - ); - - expect(result).toBe(9); -}); - -test("set has", () => { - const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has("a");`); - expect(contains).toBe(true); -}); - -test("set has false", () => { - const contains = util.transpileAndExecute(`let myset = new Set(); return myset.has("a");`); - expect(contains).toBe(false); -}); - -test("set has null", () => { - const contains = util.transpileAndExecute(`let myset = new Set(["a", "c"]); return myset.has(null);`); - expect(contains).toBe(false); -}); - -test("set keys", () => { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var key of myset.keys()) { count += key; } - return count;` - ); - - expect(result).toBe(18); -}); - -test("set values", () => { - const result = util.transpileAndExecute( - `let myset = new Set([5, 6, 7]); - let count = 0; - for (var value of myset.values()) { count += value; } - return count;` - ); - - expect(result).toBe(18); -}); - -test.each([ - { code: `let m = new Set(); return m.size;`, expected: 0 }, - { code: `let m = new Set(); m.add(1); return m.size;`, expected: 1 }, - { code: `let m = new Set([1, 2]); return m.size;`, expected: 2 }, - { code: `let m = new Set([1, 2]); m.clear(); return m.size;`, expected: 0 }, - { code: `let m = new Set([1, 2]); m.delete(2); return m.size;`, expected: 1 }, -])("set size (%p)", ({ code, expected }) => { - expect(util.transpileAndExecute(code)).toBe(expected); -}); diff --git a/test/unit/lualib/symbol.spec.ts b/test/unit/lualib/symbol.spec.ts deleted file mode 100644 index 857a9918a..000000000 --- a/test/unit/lualib/symbol.spec.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as util from "../../util"; - -test.each([{}, { description: 1 }, { description: "name" }])("symbol.toString() (%p)", ({ description }) => { - const result = util.transpileAndExecute(` - return Symbol(${JSON.stringify(description)}).toString(); - `); - - expect(result).toBe(`Symbol(${description || ""})`); -}); - -test.each([{}, { description: 1 }, { description: "name" }])("symbol.description (%p)", ({ description }) => { - const result = util.transpileAndExecute(` - return Symbol(${JSON.stringify(description)}).description; - `); - - expect(result).toBe(description); -}); - -test("symbol uniqueness", () => { - const result = util.transpileAndExecute(` - return Symbol("a") === Symbol("a"); - `); - - expect(result).toBe(false); -}); - -test("Symbol.for", () => { - const result = util.transpileAndExecute(` - return Symbol.for("name").description; - `); - - expect(result).toBe("name"); -}); - -test("Symbol.for non-uniqueness", () => { - const result = util.transpileAndExecute(` - return Symbol.for("a") === Symbol.for("a"); - `); - - expect(result).toBe(true); -}); - -test("Symbol.keyFor", () => { - const result = util.transpileAndExecute(` - const sym = Symbol.for("a"); - Symbol.for("b"); - return Symbol.keyFor(sym); - `); - - expect(result).toBe("a"); -}); - -test("Symbol.keyFor empty", () => { - const result = util.transpileAndExecute(` - Symbol.for("a"); - return Symbol.keyFor(Symbol()); - `); - - expect(result).toBe(undefined); -}); diff --git a/test/unit/math.spec.ts b/test/unit/math.spec.ts deleted file mode 100644 index 84b1b071f..000000000 --- a/test/unit/math.spec.ts +++ /dev/null @@ -1,253 +0,0 @@ -import * as util from "../util"; - -test.each([ - { inp: "Math.cos()", expected: "math.cos()" }, - { inp: "Math.sin()", expected: "math.sin()" }, - { inp: "Math.min()", expected: "math.min()" }, - { inp: "Math.atan2(2, 3)", expected: "math.atan(2 / 3)" }, - { inp: "Math.log2(3)", expected: `local ____ = (math.log(3) / ${Math.LN2})` }, - { inp: "Math.log10(3)", expected: `local ____ = (math.log(3) / ${Math.LN10})` }, - { inp: "const x = Math.log2(3)", expected: `local x = (math.log(3) / ${Math.LN2})` }, - { inp: "const x = Math.log10(3)", expected: `local x = (math.log(3) / ${Math.LN10})` }, - { inp: "Math.log1p(3)", expected: "math.log(1 + 3)" }, - { inp: "Math.round(3.3)", expected: "math.floor(3.3 + 0.5)" }, - { inp: "Math.PI", expected: "local ____ = math.pi" }, -])("Math (%p)", ({ inp, expected }) => { - const lua = util.transpileString(inp); - - expect(lua).toBe(expected); -}); - -test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math constant (%p)", constant => { - const epsilon = 0.000001; - const jsValue: number = (Math as Math & { [key: string]: any })[constant]; - const code = `return Math.abs(Math.${constant} - ${jsValue}) <= ${epsilon}`; - expect(util.transpileAndExecute(code)).toBe(true); -}); - -test.each([ - { statement: "++x", expected: "x=4;y=6" }, - { statement: "x++", expected: "x=4;y=6" }, - { statement: "--x", expected: "x=2;y=6" }, - { statement: "x--", expected: "x=2;y=6" }, - { statement: "x += y", expected: "x=9;y=6" }, - { statement: "x -= y", expected: "x=-3;y=6" }, - { statement: "x *= y", expected: "x=18;y=6" }, - { statement: "y /= x", expected: "x=3;y=2.0" }, - { statement: "y %= x", expected: "x=3;y=0" }, - { statement: "y **= x", expected: "x=3;y=216.0" }, - { statement: "x |= y", expected: "x=7;y=6" }, - { statement: "x &= y", expected: "x=2;y=6" }, - { statement: "x ^= y", expected: "x=5;y=6" }, - { statement: "x <<= y", expected: "x=192;y=6" }, - { statement: "x >>>= y", expected: "x=0;y=6" }, -])("Operator assignment statements (%p)", ({ statement, expected }) => { - const result = util.transpileAndExecute( - `let x = 3; - let y = 6; - ${statement}; - return \`x=\${x};y=\${y}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { statement: "++o.p", expected: "o=4;a=6" }, - { statement: "o.p++", expected: "o=4;a=6" }, - { statement: "--o.p", expected: "o=2;a=6" }, - { statement: "o.p--", expected: "o=2;a=6" }, - { statement: "o.p += a[0]", expected: "o=9;a=6" }, - { statement: "o.p -= a[0]", expected: "o=-3;a=6" }, - { statement: "o.p *= a[0]", expected: "o=18;a=6" }, - { statement: "a[0] /= o.p", expected: "o=3;a=2.0" }, - { statement: "a[0] %= o.p", expected: "o=3;a=0" }, - { statement: "a[0] **= o.p", expected: "o=3;a=216.0" }, - { statement: "o.p |= a[0]", expected: "o=7;a=6" }, - { statement: "o.p &= a[0]", expected: "o=2;a=6" }, - { statement: "o.p ^= a[0]", expected: "o=5;a=6" }, - { statement: "o.p <<= a[0]", expected: "o=192;a=6" }, - { statement: "o.p >>>= a[0]", expected: "o=0;a=6" }, -])("Operator assignment to simple property statements (%p)", ({ statement, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - ${statement}; - return \`o=\${o.p};a=\${a[0]}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { statement: "++o.p.d", expected: "o=4;a=[6,11],[7,13]" }, - { statement: "o.p.d++", expected: "o=4;a=[6,11],[7,13]" }, - { statement: "--o.p.d", expected: "o=2;a=[6,11],[7,13]" }, - { statement: "o.p.d--", expected: "o=2;a=[6,11],[7,13]" }, - { statement: "o.p.d += a[0][0]", expected: "o=9;a=[6,11],[7,13]" }, - { statement: "o.p.d -= a[0][0]", expected: "o=-3;a=[6,11],[7,13]" }, - { statement: "o.p.d *= a[0][0]", expected: "o=18;a=[6,11],[7,13]" }, - { statement: "a[0][0] /= o.p.d", expected: "o=3;a=[2.0,11],[7,13]" }, - { statement: "a[0][0] %= o.p.d", expected: "o=3;a=[0,11],[7,13]" }, - { statement: "a[0][0] **= o.p.d", expected: "o=3;a=[216.0,11],[7,13]" }, - { statement: "o.p.d |= a[0][0]", expected: "o=7;a=[6,11],[7,13]" }, - { statement: "o.p.d &= a[0][0]", expected: "o=2;a=[6,11],[7,13]" }, - { statement: "o.p.d ^= a[0][0]", expected: "o=5;a=[6,11],[7,13]" }, - { statement: "o.p.d <<= a[0][0]", expected: "o=192;a=[6,11],[7,13]" }, - { statement: "o.p.d >>>= a[0][0]", expected: "o=0;a=[6,11],[7,13]" }, -])("Operator assignment to deep property statements (%p)", ({ statement, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: {d: 3}}; - let a = [[6,11], [7,13]]; - ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}]\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { statement: "++of().p", expected: "o=4;a=6" }, - { statement: "of().p++", expected: "o=4;a=6" }, - { statement: "--of().p", expected: "o=2;a=6" }, - { statement: "of().p--", expected: "o=2;a=6" }, - { statement: "of().p += af()[i()]", expected: "o=9;a=6" }, - { statement: "of().p -= af()[i()]", expected: "o=-3;a=6" }, - { statement: "of().p *= af()[i()]", expected: "o=18;a=6" }, - { statement: "af()[i()] /= of().p", expected: "o=3;a=2.0" }, - { statement: "af()[i()] %= of().p", expected: "o=3;a=0" }, - { statement: "af()[i()] **= of().p", expected: "o=3;a=216.0" }, - { statement: "of().p |= af()[i()]", expected: "o=7;a=6" }, - { statement: "of().p &= af()[i()]", expected: "o=2;a=6" }, - { statement: "of().p ^= af()[i()]", expected: "o=5;a=6" }, - { statement: "of().p <<= af()[i()]", expected: "o=192;a=6" }, - { statement: "of().p >>>= af()[i()]", expected: "o=0;a=6" }, -])("Operator assignment to complex property statements (%p)", ({ statement, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - function of() { return o; } - function af() { return a; } - function i() { return 0; } - ${statement}; - return \`o=\${o.p};a=\${a[0]}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { statement: "++of().p.d", expected: "o=4;a=[7,6],[11,13];i=0" }, - { statement: "of().p.d++", expected: "o=4;a=[7,6],[11,13];i=0" }, - { statement: "--of().p.d", expected: "o=2;a=[7,6],[11,13];i=0" }, - { statement: "of().p.d--", expected: "o=2;a=[7,6],[11,13];i=0" }, - { statement: "of().p.d += af()[i()][i()]", expected: "o=9;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d -= af()[i()][i()]", expected: "o=-3;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d *= af()[i()][i()]", expected: "o=18;a=[7,6],[11,13];i=2" }, - { statement: "af()[i()][i()] /= of().p.d", expected: "o=3;a=[7,2.0],[11,13];i=2" }, - { statement: "af()[i()][i()] %= of().p.d", expected: "o=3;a=[7,0],[11,13];i=2" }, - { statement: "af()[i()][i()] **= of().p.d", expected: "o=3;a=[7,216.0],[11,13];i=2" }, - { statement: "of().p.d |= af()[i()][i()]", expected: "o=7;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d &= af()[i()][i()]", expected: "o=2;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d ^= af()[i()][i()]", expected: "o=5;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d <<= af()[i()][i()]", expected: "o=192;a=[7,6],[11,13];i=2" }, - { statement: "of().p.d >>>= af()[i()][i()]", expected: "o=0;a=[7,6],[11,13];i=2" }, -])("Operator assignment to complex deep property statements (%p)", ({ statement, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: {d: 3}}; - let a = [[7, 6], [11, 13]]; - function of() { return o; } - function af() { return a; } - let _i = 0; - function i() { return _i++; } - ${statement}; - return \`o=\${o.p.d};a=[\${a[0][0]},\${a[0][1]}],[\${a[1][0]},\${a[1][1]}];i=\${_i}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "++x", expected: "4;x=4;y=6" }, - { expression: "x++", expected: "3;x=4;y=6" }, - { expression: "--x", expected: "2;x=2;y=6" }, - { expression: "x--", expected: "3;x=2;y=6" }, - { expression: "x += y", expected: "9;x=9;y=6" }, - { expression: "x -= y", expected: "-3;x=-3;y=6" }, - { expression: "x *= y", expected: "18;x=18;y=6" }, - { expression: "y /= x", expected: "2.0;x=3;y=2.0" }, - { expression: "y %= x", expected: "0;x=3;y=0" }, - { expression: "y **= x", expected: "216.0;x=3;y=216.0" }, - { expression: "x |= y", expected: "7;x=7;y=6" }, - { expression: "x &= y", expected: "2;x=2;y=6" }, - { expression: "x ^= y", expected: "5;x=5;y=6" }, - { expression: "x <<= y", expected: "192;x=192;y=6" }, - { expression: "x >>>= y", expected: "0;x=0;y=6" }, - { expression: "x + (y += 7)", expected: "16;x=3;y=13" }, - { expression: "x + (y += 7)", expected: "16;x=3;y=13" }, - { expression: "x++ + (y += 7)", expected: "16;x=4;y=13" }, -])("Operator assignment expressions (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let x = 3; - let y = 6; - const r = ${expression}; - return \`\${r};x=\${x};y=\${y}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "++o.p", expected: "4;o=4;a=6" }, - { expression: "o.p++", expected: "3;o=4;a=6" }, - { expression: "--o.p", expected: "2;o=2;a=6" }, - { expression: "o.p--", expected: "3;o=2;a=6" }, - { expression: "o.p += a[0]", expected: "9;o=9;a=6" }, - { expression: "o.p -= a[0]", expected: "-3;o=-3;a=6" }, - { expression: "o.p *= a[0]", expected: "18;o=18;a=6" }, - { expression: "a[0] /= o.p", expected: "2.0;o=3;a=2.0" }, - { expression: "a[0] %= o.p", expected: "0;o=3;a=0" }, - { expression: "a[0] **= o.p", expected: "216.0;o=3;a=216.0" }, - { expression: "o.p |= a[0]", expected: "7;o=7;a=6" }, - { expression: "o.p &= a[0]", expected: "2;o=2;a=6" }, - { expression: "o.p ^= a[0]", expected: "5;o=5;a=6" }, - { expression: "o.p <<= a[0]", expected: "192;o=192;a=6" }, - { expression: "o.p >>>= a[0]", expected: "0;o=0;a=6" }, - { expression: "o.p + (a[0] += 7)", expected: "16;o=3;a=13" }, - { expression: "o.p += (a[0] += 7)", expected: "16;o=16;a=13" }, - { expression: "o.p++ + (a[0] += 7)", expected: "16;o=4;a=13" }, -])("Operator assignment to simple property expressions (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\`` - ); - expect(result).toBe(expected); -}); - -test.each([ - { expression: "++of().p", expected: "4;o=4;a=6" }, - { expression: "of().p++", expected: "3;o=4;a=6" }, - { expression: "--of().p", expected: "2;o=2;a=6" }, - { expression: "of().p--", expected: "3;o=2;a=6" }, - { expression: "of().p += af()[i()]", expected: "9;o=9;a=6" }, - { expression: "of().p -= af()[i()]", expected: "-3;o=-3;a=6" }, - { expression: "of().p *= af()[i()]", expected: "18;o=18;a=6" }, - { expression: "af()[i()] /= of().p", expected: "2.0;o=3;a=2.0" }, - { expression: "af()[i()] %= of().p", expected: "0;o=3;a=0" }, - { expression: "af()[i()] **= of().p", expected: "216.0;o=3;a=216.0" }, - { expression: "of().p |= af()[i()]", expected: "7;o=7;a=6" }, - { expression: "of().p &= af()[i()]", expected: "2;o=2;a=6" }, - { expression: "of().p ^= af()[i()]", expected: "5;o=5;a=6" }, - { expression: "of().p <<= af()[i()]", expected: "192;o=192;a=6" }, - { expression: "of().p >>>= af()[i()]", expected: "0;o=0;a=6" }, - { expression: "of().p + (af()[i()] += 7)", expected: "16;o=3;a=13" }, - { expression: "of().p += (af()[i()] += 7)", expected: "16;o=16;a=13" }, - { expression: "of().p++ + (af()[i()] += 7)", expected: "16;o=4;a=13" }, -])("Operator assignment to complex property expressions (%p)", ({ expression, expected }) => { - const result = util.transpileAndExecute( - `let o = {p: 3}; - let a = [6]; - function of() { return o; } - function af() { return a; } - function i() { return 0; } - const r = ${expression}; - return \`\${r};o=\${o.p};a=\${a[0]}\`` - ); - expect(result).toBe(expected); -}); diff --git a/test/unit/modules.spec.ts b/test/unit/modules.spec.ts deleted file mode 100644 index 53674df46..000000000 --- a/test/unit/modules.spec.ts +++ /dev/null @@ -1,165 +0,0 @@ -import * as ts from "typescript"; -import * as tstl from "../../src"; -import * as util from "../util"; - -describe("module import/export elision", () => { - const moduleDeclaration = ` - declare module "module" { - export type Type = string; - export declare const value: string; - } - `; - - const expectToElideImport = (code: string) => { - const lua = util.transpileString( - { "module.d.ts": moduleDeclaration, "main.ts": code }, - { module: ts.ModuleKind.CommonJS }, - false - ); - - expect(() => util.executeLua(lua)).not.toThrow(); - }; - - test("should elide named type imports", () => { - expectToElideImport(` - import { Type } from "module"; - const foo: Type = "bar"; - `); - }); - - test("should elide named value imports used only as a type", () => { - expectToElideImport(` - import { value } from "module"; - const foo: typeof value = "bar"; - `); - }); - - test("should elide namespace imports with unused values", () => { - expectToElideImport(` - import * as module from "module"; - const foo: module.Type = "bar"; - `); - }); - - test("should elide `import =` declarations", () => { - expectToElideImport(` - import module = require("module"); - const foo: module.Type = "bar"; - `); - }); - - test("should elide type exports", () => { - const code = ` - declare const _G: any; - - _G.foo = true; - type foo = boolean; - export { foo }; - `; - - expect(util.transpileExecuteAndReturnExport(code, "foo")).toBeUndefined(); - }); -}); - -test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( - "Import module names with invalid lua identifier characters (%p)", - name => { - const code = ` - import { foo } from "${name}"; - foo; - `; - - const lua = ` - setmetatable(package.loaded, {__index = function() return {foo = "bar"} end}) - ${util.transpileString(code)} - return foo;`; - - expect(util.executeLua(lua)).toBe("bar"); - } -); - -test("lualibRequire", () => { - const lua = util.transpileString(`let a = b instanceof c;`, { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.LuaJIT, - }); - - expect(lua.startsWith(`require("lualib_bundle")`)); -}); - -test("lualibRequireAlways", () => { - const lua = util.transpileString(``, { - luaLibImport: tstl.LuaLibImportKind.Always, - luaTarget: tstl.LuaTarget.LuaJIT, - }); - - expect(lua).toBe(`require("lualib_bundle");`); -}); - -test("Non-exported module", () => { - const result = util.transpileAndExecute( - "return g.test();", - undefined, - undefined, - "module g { export function test() { return 3; } }" - ); - - expect(result).toBe(3); -}); - -test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( - "LuaLib no uses? No code (%p)", - luaLibImport => { - const lua = util.transpileString(``, { luaLibImport }); - - expect(lua).toBe(``); - } -); - -test("Nested module with dot in name", () => { - const code = `module a.b { - export const foo = "foo"; - }`; - expect(util.transpileAndExecute("return a.b.foo;", undefined, undefined, code)).toBe("foo"); -}); - -test("Access this in module", () => { - const header = ` - module M { - export const foo = "foo"; - export function bar() { return this.foo + "bar"; } - } - `; - const code = `return M.bar();`; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); -}); - -test("Module merged with interface", () => { - const header = ` - interface Foo {} - module Foo { - export function bar() { return "foobar"; } - }`; - const code = `return Foo.bar();`; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foobar"); -}); - -test("module merged across files", () => { - const testA = ` - namespace NS { - export namespace Inner { - export const foo = "foo"; - } - } - `; - const testB = ` - namespace NS { - export namespace Inner { - export const bar = "bar"; - } - } - `; - const { transpiledFiles } = util.transpileStringsAsProject({ "testA.ts": testA, "testB.ts": testB }); - const lua = transpiledFiles.map(f => f.lua).join("\n") + "\nreturn NS.Inner.foo .. NS.Inner.bar"; - expect(util.executeLua(lua)).toBe("foobar"); -}); diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts new file mode 100644 index 000000000..9209a0819 --- /dev/null +++ b/test/unit/modules/modules.spec.ts @@ -0,0 +1,211 @@ +import * as ts from "typescript"; +import * as util from "../../util"; + +describe("module import/export elision", () => { + const moduleDeclaration = ` + declare module "module" { + export type Type = string; + export declare const value: string; + } + `; + + const expectToElideImport: util.TapCallback = builder => { + builder.addExtraFile("module.d.ts", moduleDeclaration).setOptions({ module: ts.ModuleKind.CommonJS }); + expect(builder.getLuaExecutionResult()).not.toBeInstanceOf(util.ExecutionError); + }; + + test("should elide named type imports", () => { + util.testModule` + import { Type } from "module"; + const foo: Type = "bar"; + `.tap(expectToElideImport); + }); + + test("should elide named value imports used only as a type", () => { + util.testModule` + import { value } from "module"; + const foo: typeof value = "bar"; + `.tap(expectToElideImport); + }); + + test("should elide namespace imports with unused values", () => { + util.testModule` + import * as module from "module"; + const foo: module.Type = "bar"; + `.tap(expectToElideImport); + }); + + test("should elide `import =` declarations", () => { + util.testModule` + import module = require("module"); + const foo: module.Type = "bar"; + `.tap(expectToElideImport); + }); + + test("should elide type exports", () => { + util.testModule` + (globalThis as any).foo = true; + type foo = boolean; + export { foo }; + `.expectToEqual([]); + }); +}); + +test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"])( + "Import module names with invalid lua identifier characters (%p)", + name => { + util.testModule` + import { foo } from "./${name}"; + export { foo }; + ` + .disableSemanticCheck() + .setLuaHeader(`setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })`) + .setReturnExport("foo") + .expectToEqual("bar"); + } +); + +test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + export { default } from "./module"; + `, + "module.ts": ` + export const value = true; + ${exportStatement}; + `, + }, + "default" + ); + + expect(result).toBe(true); +}); + +test("Default Import and Export Expression", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport; + `, + "module.ts": ` + export default 1 + 2 + 3; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Import and Export Assignment", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import * as m from "./module"; + export const value = m; + `, + "module.ts": ` + export = true; + `, + }, + "value" + ); + + expect(result).toBe(true); +}); + +test("Mixed Exports, Default and Named Imports", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport, { a, b, c } from "./module"; + export const value = defaultExport + b + c; + `, + "module.ts": ` + export const a = 1; + export const b = 2; + export const c = 3; + export default a; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Mixed Exports, Default and Namespace Import", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport, * as ns from "./module"; + export const value = defaultExport + ns.b + ns.c; + `, + "module.ts": ` + export const a = 1; + export const b = 2; + export const c = 3; + export default a; + `, + }, + "value" + ); + + expect(result).toBe(6); +}); + +test("Export Default Function", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport(); + `, + "module.ts": ` + export default function() { + return true; + } + `, + }, + "value" + ); + + expect(result).toBe(true); +}); + +test.each([ + ["Test", "export default class Test { static method() { return true; } }"], + ["default", "export default class { static method() { return true; } }"], +])("Export Default Class Name (%p)", (expectedClassName, classDeclarationStatement) => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import defaultExport from "./module"; + export const value = defaultExport.name; + `, + "module.ts": classDeclarationStatement, + }, + "value" + ); + + expect(result).toBe(expectedClassName); +}); + +test("Export Equals", () => { + const [result] = util.transpileAndExecuteProjectReturningMainExport( + { + "main.ts": ` + import * as module from "./module"; + export const value = module; + `, + "module.ts": ` + export = true; + `, + }, + "value" + ); + + expect(result).toBe(true); +}); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts new file mode 100644 index 000000000..6c1dbe105 --- /dev/null +++ b/test/unit/modules/resolution.spec.ts @@ -0,0 +1,143 @@ +import * as ts from "typescript"; +import * as util from "../../util"; + +const requireRegex = /require\("(.*?)"\)/; +const expectToRequire = (expected: string): util.TapCallback => builder => { + const match = requireRegex.exec(builder.getMainLuaCodeChunk()); + if (util.expectToBeDefined(match)) { + expect(match[1]).toBe(expected); + } +}; + +test.each([ + { + filePath: "main.ts", + usedPath: "./folder/Module", + expected: "folder.Module", + options: { rootDir: "." }, + }, + { + filePath: "main.ts", + usedPath: "./folder/Module", + expected: "folder.Module", + options: { rootDir: "./" }, + }, + { + filePath: "src/main.ts", + usedPath: "./folder/Module", + expected: "src.folder.Module", + options: { rootDir: "." }, + }, + { + filePath: "main.ts", + usedPath: "folder/Module", + expected: "folder.Module", + options: { rootDir: ".", baseUrl: "." }, + }, + { + filePath: "main.ts", + usedPath: "folder/Module", + expected: "folder.Module", + options: { rootDir: "./", baseUrl: "." }, + }, + { + filePath: "src/main.ts", + usedPath: "./folder/Module", + expected: "folder.Module", + options: { rootDir: "src" }, + }, + { + filePath: "src/main.ts", + usedPath: "./folder/Module", + expected: "folder.Module", + options: { rootDir: "./src" }, + }, + { + filePath: "src/dir/main.ts", + usedPath: "../Module", + expected: "Module", + options: { rootDir: "./src" }, + }, + { + filePath: "src/dir/dir/main.ts", + usedPath: "../../dir/Module", + expected: "dir.Module", + options: { rootDir: "./src" }, + }, +])("resolve paths with baseUrl or rootDir (%p)", ({ filePath, usedPath, expected, options }) => { + util.testModule` + import * as module from "${usedPath}"; + module; + ` + .setMainFileName(filePath) + .setOptions(options) + .tap(expectToRequire(expected)); +}); + +test("doesn't resolve paths out of root dir", () => { + util.testModule` + import * as module from "../module"; + module; + ` + .setMainFileName("src/main.ts") + .setOptions({ rootDir: "./src" }) + .disableSemanticCheck() + .expectToHaveDiagnostics(); +}); + +test.each([ + { + declarationStatement: ` + /** @noResolution */ + declare module "fake" {} + `, + mainCode: `import "fake";`, + expectedPath: "fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module "fake" {} + `, + mainCode: `import * as fake from "fake"; fake;`, + expectedPath: "fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module "fake" { + export const x: number; + } + `, + mainCode: `import { x } from "fake"; x;`, + expectedPath: "fake", + }, + { + declarationStatement: ` + /** @noResolution */ + declare module "fake" { + export const x: number; + } + + declare module "fake" { + export const y: number; + } + `, + mainCode: `import { y } from "fake"; y;`, + expectedPath: "fake", + }, +])("noResolution prevents any module path resolution behavior", ({ declarationStatement, mainCode, expectedPath }) => { + util.testModule(mainCode) + .setMainFileName("src/main.ts") + .addExtraFile("module.d.ts", declarationStatement) + .tap(expectToRequire(expectedPath)); +}); + +test("import = require", () => { + util.testModule` + import foo = require("./foo/bar"); + foo; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .tap(expectToRequire("foo.bar")); +}); diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts new file mode 100644 index 000000000..21272ae8e --- /dev/null +++ b/test/unit/namespaces.spec.ts @@ -0,0 +1,121 @@ +import * as util from "../util"; + +test("legacy internal module syntax", () => { + util.testModule` + module Foo { + export const foo = "bar"; + } + + export const foo = Foo.foo; + `.expectToMatchJsResult(); +}); + +test("global scoping", () => { + const result = util.transpileAndExecute( + "return a.foo();", + undefined, + undefined, + `namespace a { export function foo() { return "bar"; } }` + ); + + expect(result).toBe("bar"); +}); + +test("nested namespace", () => { + util.testModule` + namespace A { + export namespace B { + export const foo = "foo"; + } + } + + export const foo = A.B.foo; + `.expectToMatchJsResult(); +}); + +test("nested namespace with dot in name", () => { + util.testModule` + namespace A.B { + export const foo = "foo"; + } + + export const foo = A.B.foo; + `.expectToMatchJsResult(); +}); + +test("context in namespace function", () => { + util.testModule` + namespace a { + export const foo = "foo"; + export function bar() { return this.foo + "bar"; } + } + + export const result = a.bar(); + `.expectToMatchJsResult(); +}); + +test("namespace merged with interface", () => { + util.testModule` + interface Foo {} + namespace Foo { + export function bar() { return "foobar"; } + } + + export const result = Foo.bar(); + `.expectToMatchJsResult(); +}); + +test("namespace merged across files", () => { + const testA = ` + namespace NS { + export namespace Inner { + export const foo = "foo"; + } + } + `; + + const testB = ` + namespace NS { + export namespace Inner { + export const bar = "bar"; + } + } + `; + + const { transpiledFiles } = util.transpileStringsAsProject({ "testA.ts": testA, "testB.ts": testB }); + const lua = transpiledFiles.map(f => f.lua).join("\n") + "\nreturn NS.Inner.foo .. NS.Inner.bar"; + expect(util.executeLua(lua)).toBe("foobar"); +}); + +test("declared namespace function call", () => { + const luaHeader = ` + myNameSpace = {} + function myNameSpace.declaredFunction(x) return 3*x end + `; + + util.testModule` + declare namespace myNameSpace { + function declaredFunction(this: void, x: number): number; + } + + export const result = myNameSpace.declaredFunction(2); + ` + .setReturnExport("result") + .setLuaHeader(luaHeader) + .expectToEqual(6); +}); + +test("`import =` on a namespace", () => { + util.testModule` + namespace outerNamespace { + export namespace innerNamespace { + export function func() { + return "foo"; + } + } + } + + import importedFunc = outerNamespace.innerNamespace.func; + export const result = importedFunc(); + `.expectToMatchJsResult(); +}); diff --git a/test/unit/numbers.spec.ts b/test/unit/numbers.spec.ts deleted file mode 100644 index ecda5d93a..000000000 --- a/test/unit/numbers.spec.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as util from "../util"; - -test.each([ - "NaN === NaN", - "NaN !== NaN", - "NaN + NaN", - "NaN - NaN", - "NaN * NaN", - "NaN / NaN", - "NaN + 1", - "1 + NaN", - "1 / NaN", - "NaN * 0", -])("%s", code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code))); - -test("NaN reassignment", () => { - const result = util.transpileAndExecute(`const NaN = 1; return NaN`); - - expect(result).toBe(NaN); -}); - -test.each(["Infinity", "Infinity - Infinity", "Infinity / -1", "Infinity * -1", "Infinity + 1", "Infinity - 1"])( - "%s", - code => expect(util.transpileAndExecute(`return ${code}`)).toBe(eval(code)) -); - -test("Infinity reassignment", () => { - const result = util.transpileAndExecute(`const Infinity = 1; return Infinity`); - - expect(result).toBe(Infinity); -}); - -const numberCases = [-1, 0, 1, 1.5, Infinity, -Infinity]; -const stringCases = ["-1", "0", "1", "1.5", "Infinity", "-Infinity"]; -const restCases: any[] = [true, false, "", " ", "\t", "\n", "foo", {}]; -const cases: any[] = [...numberCases, ...stringCases, ...restCases]; - -describe("Number", () => { - test.each(cases)("constructor(%p)", value => { - const result = util.transpileAndExecute(`return Number(${util.valueToString(value)})`); - expect(result).toBe(Number(value)); - }); - - test.each(cases)("isNaN(%p)", value => { - const result = util.transpileAndExecute(` - return Number.isNaN(${util.valueToString(value)} as any) - `); - - expect(result).toBe(Number.isNaN(value)); - }); - - test.each(cases)("isFinite(%p)", value => { - const result = util.transpileAndExecute(` - return Number.isFinite(${util.valueToString(value)} as any) - `); - - expect(result).toBe(Number.isFinite(value)); - }); -}); - -test.each(cases)("isNaN(%p)", value => { - const result = util.transpileAndExecute(`return isNaN(${util.valueToString(value)} as any)`); - expect(result).toBe(isNaN(value)); -}); - -test.each(cases)("isFinite(%p)", value => { - const result = util.transpileAndExecute(`return isFinite(${util.valueToString(value)} as any)`); - expect(result).toBe(isFinite(value)); -}); diff --git a/test/unit/printer/deadCodeAfterReturn.spec.ts b/test/unit/printer/deadCodeAfterReturn.spec.ts new file mode 100644 index 000000000..08c88658d --- /dev/null +++ b/test/unit/printer/deadCodeAfterReturn.spec.ts @@ -0,0 +1,61 @@ +import * as util from "../../util"; + +test("If dead code after return", () => { + util.testFunction` + if (true) { + return 3; + const b = 8; + } + `.expectToMatchJsResult(); +}); + +test("switch dead code after return", () => { + util.testFunction` + switch ("abc" as string) { + case "def": + return 4; + let abc = 4; + case "abc": + return 5; + let def = 6; + } + `.expectToMatchJsResult(); +}); + +test("Function dead code after return", () => { + util.testFunction` + function abc() { return 3; const a = 5; } + return abc(); + `.expectToMatchJsResult(); +}); + +test("Method dead code after return", () => { + util.testFunction` + class def { public static abc() { return 3; const a = 5; } } + return def.abc(); + `.expectToMatchJsResult(); +}); + +test("for dead code after return", () => { + const result = util.transpileAndExecute(`for (let i = 0; i < 10; i++) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); + +test("for..in dead code after return", () => { + const result = util.transpileAndExecute(`for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); + +test("for..of dead code after return", () => { + const result = util.transpileAndExecute(`for (let a of [1,2,4]) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); + +test("while dead code after return", () => { + const result = util.transpileAndExecute(`while (true) { return 3; const b = 8; }`); + + expect(result).toBe(3); +}); diff --git a/test/unit/printer/parenthesis.spec.ts b/test/unit/printer/parenthesis.spec.ts new file mode 100644 index 000000000..ef08a6e3d --- /dev/null +++ b/test/unit/printer/parenthesis.spec.ts @@ -0,0 +1,64 @@ +import * as util from "../../util"; + +test("binary expression with 'as' type assertion wrapped in parenthesis", () => { + expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); +}); + +test.each([ + "(x as any).foo;", + "(y.x as any).foo;", + "(y['x'] as any).foo;", + "(z() as any).foo;", + "(y.z() as any).foo;", + "(x).foo;", + "(y.x).foo;", + "(y['x']).foo;", + "(z()).foo;", + "(y.z()).foo;", + "(x as unknown as any).foo;", + "(x as any).foo;", + "((x as unknown) as any).foo;", + "((x) as any).foo;", +])("'as' type assertion should strip parenthesis (%p)", expression => { + const code = ` + declare let x: unknown; + declare let y: { x: unknown; z(this: void): unknown; }; + declare function z(this: void): unknown; + ${expression}`; + + const lua = util.transpileString(code, undefined, false); + expect(lua).not.toMatch(/\(.+\)/); +}); + +test.each([ + "(x + 1 as any).foo;", + "(!x as any).foo;", + "(x ** 2 as any).foo;", + "(x < 2 as any).foo;", + "(x in y as any).foo;", + "(x + 1).foo;", + "(!x).foo;", + "(x + 1 as unknown as any).foo;", + "((x + 1 as unknown) as any).foo;", + "(!x as unknown as any).foo;", + "((!x as unknown) as any).foo;", + "(!x as any).foo;", + "((!x) as any).foo;", +])("'as' type assertion should not strip parenthesis (%p)", expression => { + const code = ` + declare let x: number; + declare let y: {}; + ${expression}`; + + const lua = util.transpileString(code, undefined, false); + expect(lua).toMatch(/\(.+\)/); +}); + +test("not operator precedence (%p)", () => { + const code = ` + const a = true; + const b = false; + return !a && b;`; + + expect(util.transpileAndExecute(code)).toBe(false); +}); diff --git a/test/unit/semicolons.spec.ts b/test/unit/printer/semicolons.spec.ts similarity index 56% rename from test/unit/semicolons.spec.ts rename to test/unit/printer/semicolons.spec.ts index 2cbe3ecb6..ae3a79244 100644 --- a/test/unit/semicolons.spec.ts +++ b/test/unit/printer/semicolons.spec.ts @@ -1,15 +1,15 @@ -import * as util from "../util"; +import * as util from "../../util"; test.each(["const a = 1; const b = a;", "const a = 1; let b: number; b = a;", "{}", "function bar() {} bar();"])( "semicolon insertion (%p)", leadingStatement => { const code = ` - let result = ""; - function foo() { result = "foo"; } - ${leadingStatement} - (foo)(); - return result; - `; + let result = ""; + function foo() { result = "foo"; } + ${leadingStatement} + (foo)(); + return result; + `; expect(util.transpileAndExecute(code)).toEqual("foo"); } ); diff --git a/test/unit/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts similarity index 70% rename from test/unit/sourcemaps.spec.ts rename to test/unit/printer/sourcemaps.spec.ts index 51d01bbc8..4023dad19 100644 --- a/test/unit/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,14 +1,15 @@ import { Position, SourceMapConsumer } from "source-map"; -import * as tstl from "../../src"; -import * as util from "../util"; +import * as tstl from "../../../src"; +import * as util from "../../util"; test.each([ { - typeScriptSource: ` + code: ` const abc = "foo"; const def = "bar"; - const xyz = "baz";`, + const xyz = "baz"; + `, assertPatterns: [ { luaPattern: "abc", typeScriptPattern: "abc" }, @@ -20,26 +21,28 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` function abc() { return def(); } + function def() { return "foo"; } - return abc();`, + `, assertPatterns: [ { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, { luaPattern: "function def(", typeScriptPattern: "function def() {" }, - { luaPattern: "return abc(", typeScriptPattern: "return abc(" }, + { luaPattern: "return def(", typeScriptPattern: "return def(" }, { luaPattern: "end", typeScriptPattern: "function def() {" }, ], }, { - typeScriptSource: ` + code: ` const enum abc { foo = 2, bar = 4 }; - const xyz = abc.foo;`, + const xyz = abc.foo; + `, assertPatterns: [ { luaPattern: "xyz", typeScriptPattern: "xyz" }, @@ -47,8 +50,9 @@ test.each([ ], }, { - typeScriptSource: ` - import {Foo} from "foo"; + code: ` + // @ts-ignore + import { Foo } from "foo"; Foo; `, @@ -58,7 +62,8 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` + // @ts-ignore import * as Foo from "foo"; Foo; `, @@ -69,7 +74,8 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` + // @ts-ignore class Bar extends Foo { constructor() { super(); @@ -92,7 +98,7 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` class Foo { } `, @@ -100,7 +106,7 @@ test.each([ assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }], }, { - typeScriptSource: ` + code: ` class Foo { bar = "baz"; } @@ -109,7 +115,7 @@ test.each([ assertPatterns: [{ luaPattern: "function Foo.prototype.____constructor", typeScriptPattern: "class Foo" }], }, { - typeScriptSource: ` + code: ` declare const arr: string[]; for (const element of arr) {} `, @@ -120,7 +126,7 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` declare function getArr(this: void): string[]; for (const element of getArr()) {} `, @@ -132,7 +138,7 @@ test.each([ ], }, { - typeScriptSource: ` + code: ` declare const arr: string[] for (let i = 0; i < arr.length; ++i) {} `, @@ -143,31 +149,28 @@ test.each([ { luaPattern: "i + 1", typeScriptPattern: "++i" }, ], }, -])("Source map has correct mapping (%p)", async ({ typeScriptSource, assertPatterns }) => { - // Act - const { file } = util.transpileStringResult(typeScriptSource); - - // Assert - if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; +])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { + const file = util + .testModule(code) + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.sourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { const luaPosition = lineAndColumnOf(file.lua, luaPattern); const mappedPosition = consumer.originalPositionFor(luaPosition); + const typescriptPosition = lineAndColumnOf(code, typeScriptPattern); - const typescriptPosition = lineAndColumnOf(typeScriptSource, typeScriptPattern); - - const mappedLineColumn = { line: mappedPosition.line, column: mappedPosition.column }; - expect(mappedLineColumn).toEqual(typescriptPosition); + expect(mappedPosition).toMatchObject(typescriptPosition); } }); test("Source map has correct sources", async () => { - const code = `const foo = "foo"`; - - const { file } = util.transpileStringResult(code); - - if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + const file = util.testModule` + const foo = "foo" + ` + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.sourceMap); expect(consumer.sources.length).toBe(1); @@ -175,11 +178,11 @@ test("Source map has correct sources", async () => { }); test("Source map has correct source root", async () => { - const code = `const foo = "foo"`; - - const { file } = util.transpileStringResult(code); - - if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + const file = util.testModule` + const foo = "foo" + ` + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const sourceMap = JSON.parse(file.sourceMap); expect(sourceMap.sourceRoot).toBe("."); @@ -189,14 +192,15 @@ test.each([ { code: `const type = "foobar";`, name: "type" }, { code: `const and = "foobar";`, name: "and" }, { code: `const $$$ = "foobar";`, name: "$$$" }, - { code: `const foo = { bar() { console.log(this); } };`, name: "this" }, + { code: `const foo = { bar() { this; } };`, name: "this" }, { code: `function foo($$$: unknown) {}`, name: "$$$" }, { code: `class $$$ {}`, name: "$$$" }, { code: `namespace $$$ { const foo = "bar"; }`, name: "$$$" }, ])("Source map has correct name mappings (%p)", async ({ code, name }) => { - const { file } = util.transpileStringResult(code); - - if (!util.expectToBeDefined(file.lua) || !util.expectToBeDefined(file.sourceMap)) return; + const file = util + .testModule(code) + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.sourceMap); const typescriptPosition = lineAndColumnOf(code, name); @@ -206,41 +210,30 @@ test.each([ mappedName = mapping.name; } }); + expect(mappedName).toBe(name); }); test("sourceMapTraceback saves sourcemap in _G", () => { - // Arrange - const typeScriptSource = ` + const code = ` function abc() { return "foo"; } - return JSONStringify(_G.__TS__sourcemap);`; - - const options: tstl.CompilerOptions = { - sourceMapTraceback: true, - luaLibImport: tstl.LuaLibImportKind.Inline, - }; - // Act - const transpiledLua = util.transpileString(typeScriptSource, options); + return (globalThis as any).__TS__sourcemap; + `; - const sourceMapJson = util.transpileAndExecute( - typeScriptSource, - options, - undefined, - "declare const _G: {__TS__sourcemap: any};" - ); + const builder = util + .testFunction(code) + .setOptions({ sourceMapTraceback: true, luaLibImport: tstl.LuaLibImportKind.Inline }); - // Assert - expect(sourceMapJson).toBeDefined(); - - const sourceMap = JSON.parse(sourceMapJson); + const sourceMap = builder.getLuaExecutionResult(); + const transpiledLua = builder.getMainLuaCodeChunk(); + expect(sourceMap).toEqual(expect.any(Object)); const sourceMapFiles = Object.keys(sourceMap); - - expect(sourceMapFiles.length).toBe(1); - expect(sourceMap[sourceMapFiles[0]]).toBeDefined(); + expect(sourceMapFiles).toHaveLength(1); + const mainSourceMap = sourceMap[sourceMapFiles[0]]; const assertPatterns = [ { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, @@ -249,37 +242,36 @@ test("sourceMapTraceback saves sourcemap in _G", () => { for (const { luaPattern, typeScriptPattern } of assertPatterns) { const luaPosition = lineAndColumnOf(transpiledLua, luaPattern); - const mappedLine = sourceMap[sourceMapFiles[0]][luaPosition.line.toString()]; + const mappedLine = mainSourceMap[luaPosition.line.toString()]; - const typescriptPosition = lineAndColumnOf(typeScriptSource, typeScriptPattern); - - // Add 1 to account for transpiledAndExecute-added function header - expect(mappedLine).toEqual(typescriptPosition.line + 1); + const typescriptPosition = lineAndColumnOf(code, typeScriptPattern); + expect(mappedLine).toEqual(typescriptPosition.line); } }); test("Inline sourcemaps", () => { - const typeScriptSource = ` + const code = ` function abc() { return def(); } + function def() { return "foo"; } - return abc();`; - const compilerOptions: tstl.CompilerOptions = { inlineSourceMap: true }; + return abc(); + `; - const { file } = util.transpileStringResult(typeScriptSource, compilerOptions); - if (!util.expectToBeDefined(file.lua)) return; + const file = util + .testFunction(code) + .setOptions({ inlineSourceMap: true }) + .expectToMatchJsResult() + .getMainLuaFileResult(); const inlineSourceMapMatch = file.lua.match(/--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/); - if (util.expectToBeDefined(inlineSourceMapMatch)) { const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); expect(file.sourceMap).toBe(inlineSourceMap); - - expect(util.executeLua(file.lua)).toBe("foo"); } }); diff --git a/test/unit/require.spec.ts b/test/unit/require.spec.ts deleted file mode 100644 index 216f8fbc6..000000000 --- a/test/unit/require.spec.ts +++ /dev/null @@ -1,334 +0,0 @@ -import * as ts from "typescript"; -import * as util from "../util"; - -const requireRegex = /require\("(.*?)"\)/; - -test.each([ - { - filePath: "main.ts", - usedPath: "./folder/Module", - expectedPath: "folder.Module", - options: { rootDir: "." }, - throwsError: false, - }, - { - filePath: "main.ts", - usedPath: "./folder/Module", - expectedPath: "folder.Module", - options: { rootDir: "./" }, - throwsError: false, - }, - { - filePath: "src/main.ts", - usedPath: "./folder/Module", - expectedPath: "src.folder.Module", - options: { rootDir: "." }, - throwsError: false, - }, - { - filePath: "main.ts", - usedPath: "folder/Module", - expectedPath: "folder.Module", - options: { rootDir: ".", baseUrl: "." }, - throwsError: false, - }, - { - filePath: "main.ts", - usedPath: "folder/Module", - expectedPath: "folder.Module", - options: { rootDir: "./", baseUrl: "." }, - throwsError: false, - }, - { - filePath: "src/main.ts", - usedPath: "./folder/Module", - expectedPath: "folder.Module", - options: { rootDir: "src" }, - throwsError: false, - }, - { - filePath: "src/main.ts", - usedPath: "./folder/Module", - expectedPath: "folder.Module", - options: { rootDir: "./src" }, - throwsError: false, - }, - { - filePath: "main.ts", - usedPath: "../Module", - expectedPath: "", - options: { rootDir: "./src" }, - throwsError: true, - }, - { - filePath: "src/dir/main.ts", - usedPath: "../Module", - expectedPath: "Module", - options: { rootDir: "./src" }, - throwsError: false, - }, - { - filePath: "src/dir/dir/main.ts", - usedPath: "../../dir/Module", - expectedPath: "dir.Module", - options: { rootDir: "./src" }, - throwsError: false, - }, -])( - "require paths root from --baseUrl or --rootDir (%p)", - ({ filePath, usedPath, expectedPath, options, throwsError }) => { - const input = { [filePath]: `import * as module from "${usedPath}"; module;` }; - if (throwsError) { - expect(() => util.transpileString(input, options)).toThrow(); - } else { - const lua = util.transpileString(input, options); - const match = requireRegex.exec(lua); - - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe(expectedPath); - } - } - } -); - -test.each([ - { - declarationStatement: ` - declare module 'fake' {} - `, - mainCode: "import * as fake from 'fake'; fake;", - expectedPath: "src.fake", - }, - { - declarationStatement: ` - /** @noResolution */ - declare module 'fake' {} - `, - mainCode: "import * as fake from 'fake'; fake;", - expectedPath: "fake", - }, - { - declarationStatement: ` - declare module 'fake' { - export const x: number; - } - `, - mainCode: "import { x } from 'fake'; x;", - expectedPath: "src.fake", - }, - { - declarationStatement: ` - /** @noResolution */ - declare module 'fake' { - export const x: number; - } - `, - mainCode: "import { x } from 'fake'; x;", - expectedPath: "fake", - }, - { - declarationStatement: ` - /** @noResolution */ - declare module 'fake' { - export const x: number; - } - declare module 'fake' { - export const y: number; - } - `, - mainCode: "import { y } from 'fake'; y;", - expectedPath: "fake", - }, - { - declarationStatement: ` - declare module 'fake' { - export const x: number; - } - declare module 'fake' { - export const y: number; - } - `, - mainCode: "import { y } from 'fake'; y;", - expectedPath: "src.fake", - }, - { - declarationStatement: ` - declare module 'fake' {} - `, - mainCode: "import 'fake';", - expectedPath: "src.fake", - }, - { - declarationStatement: ` - /** @noResolution */ - declare module 'fake' {} - `, - mainCode: "import 'fake';", - expectedPath: "fake", - }, -])("noResolution prevents any module path resolution behaviour", ({ declarationStatement, mainCode, expectedPath }) => { - const lua = util.transpileString({ - "src/main.ts": mainCode, - "module.d.ts": declarationStatement, - }); - const match = requireRegex.exec(lua); - - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe(expectedPath); - } -}); - -test("ImportEquals declaration require", () => { - const input = `import foo = require("./foo/bar"); foo;`; - - const lua = util.transpileString(input, { module: ts.ModuleKind.CommonJS }); - const match = requireRegex.exec(lua); - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe("foo.bar"); - } -}); - -test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - export { default } from "./module"; - `, - "module.ts": ` - export const value = true; - ${exportStatement}; - `, - }, - "default" - ); - - expect(result).toBe(true); -}); - -test("Default Import and Export Expression", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport; - `, - "module.ts": ` - export default 1 + 2 + 3; - `, - }, - "value" - ); - - expect(result).toBe(6); -}); - -test("Import and Export Assignment", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as m from "./module"; - export const value = m; - `, - "module.ts": ` - export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); -}); - -test("Mixed Exports, Default and Named Imports", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, { a, b, c } from "./module"; - export const value = defaultExport + b + c; - `, - "module.ts": ` - export const a = 1; - export default a; - export const b = 2; - export const c = 3; - `, - }, - "value" - ); - - expect(result).toBe(6); -}); - -test("Mixed Exports, Default and Namespace Import", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, * as ns from "./module"; - export const value = defaultExport + ns.b + ns.c; - `, - "module.ts": ` - export const a = 1; - export default a; - export const b = 2; - export const c = 3; - `, - }, - "value" - ); - - expect(result).toBe(6); -}); - -test("Export Default Function", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport(); - `, - "module.ts": ` - export default function() { - return true; - } - `, - }, - "value" - ); - - expect(result).toBe(true); -}); - -test.each([ - ["Test", "export default class Test { static method() { return true; } }"], - ["default", "export default class { static method() { return true; } }"], -])("Export Default Class Name (%p)", (expectedClassName, classDeclarationStatement) => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport.name; - `, - "module.ts": classDeclarationStatement, - }, - "value" - ); - - expect(result).toBe(expectedClassName); -}); - -test("Export Equals", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as module from "./module"; - export const value = module; - `, - "module.ts": ` - export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); -}); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts new file mode 100644 index 000000000..9f6f19ae4 --- /dev/null +++ b/test/unit/spread.spec.ts @@ -0,0 +1,89 @@ +import * as tstl from "../../src"; +import * as util from "../util"; + +// TODO: Make some utils for testing other targets +const expectUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch(/[^.]unpack\(/); +const expectTableUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("table.unpack"); + +describe("in function call", () => { + util.testEachVersion( + undefined, + () => util.testFunction` + function foo(a: number, b: number, ...rest: number[]) { + return { a, b, rest } + } + + const array = [0, 1, 2, 3] as const; + return foo(...array); + `, + { + [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + } + ); +}); + +describe("in array literal", () => { + util.testEachVersion("of array literal", () => util.testExpression`[...[0, 1, 2]]`, { + [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + }); + + test.each(["", "string", "string with spaces", "string 1 2 3"])("of string literal (%p)", str => { + util.testExpressionTemplate`[...${str}]`.expectToMatchJsResult(); + }); + + test("of iterable", () => { + util.testFunction` + const it = { + i: -1, + [Symbol.iterator]() { + return this; + }, + next() { + ++this.i; + return { + value: 2 ** this.i, + done: this.i == 9, + } + } + }; + + return [...it] + `.expectToMatchJsResult(); + }); +}); + +describe("in object literal", () => { + test.each([ + "{ x: false, ...{ x: true, y: true } }", + "{ ...{ x: true, y: true } }", + "{ ...{ x: true }, ...{ y: true, z: true } }", + "{ ...{ x: false }, x: true }", + "{ ...{ x: false }, x: false, ...{ x: true } }", + ])("of object literal (%p)", expression => { + util.testExpression(expression).expectToMatchJsResult(); + }); + + test("of object reference", () => { + util.testFunction` + const object = { x: 0, y: 1 }; + const result = { ...object, z: 2 }; + return { object, result }; + `.expectToMatchJsResult(); + }); + + test.each([ + ["literal", "const object = { ...[0, 1, 2] };"], + ["reference", "const array = [0, 1, 2]; const object = { ...array };"], + ])("of array %p", (_name, expressionToCreateObject) => { + util.testFunction` + ${expressionToCreateObject} + return { "0": object[0], "1": object[1], "2": object[2] }; + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/spreadElement.spec.ts b/test/unit/spreadElement.spec.ts deleted file mode 100644 index 13e528102..000000000 --- a/test/unit/spreadElement.spec.ts +++ /dev/null @@ -1,114 +0,0 @@ -import * as tstl from "../../src"; -import * as util from "../util"; - -test.each([{ inp: [] }, { inp: [1, 2, 3] }, { inp: [1, "test", 3] }])("Spread Element Push (%p)", ({ inp }) => { - const result = util.transpileAndExecute( - `return JSONStringify(([] as Array).push(...${JSON.stringify(inp)}));` - ); - expect(result).toBe(([] as Array).push(...inp)); -}); - -test("Spread Element Lua 5.1", () => { - // Cant test functional because our VM doesn't run on 5.1 - const options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua51, - luaLibImport: tstl.LuaLibImportKind.None, - }; - const lua = util.transpileString(`[].push(...${JSON.stringify([1, 2, 3])});`, options); - expect(lua).toBe("__TS__ArrayPush(\n {},\n unpack({1, 2, 3})\n)"); -}); - -test("Spread Element Lua 5.2", () => { - const options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua52, - luaLibImport: tstl.LuaLibImportKind.None, - }; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {\n table.unpack({0, 1, 2})\n}"); -}); - -test("Spread Element Lua 5.3", () => { - const options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua53, - luaLibImport: tstl.LuaLibImportKind.None, - }; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {\n table.unpack({0, 1, 2})\n}"); -}); - -test("Spread Element Lua JIT", () => { - const options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.LuaJIT, - luaLibImport: tstl.LuaLibImportKind.None, - }; - const lua = util.transpileString(`[...[0, 1, 2]]`, options); - expect(lua).toBe("local ____ = {\n unpack({0, 1, 2})\n}"); -}); - -test("Spread Element Iterable", () => { - const code = ` - const it = { - i: -1, - [Symbol.iterator]() { - return this; - }, - next() { - ++this.i; - return { - value: 2 ** this.i, - done: this.i == 9, - } - } - }; - const arr = [...it]; - return JSONStringify(arr)`; - expect(JSON.parse(util.transpileAndExecute(code))).toEqual([1, 2, 4, 8, 16, 32, 64, 128, 256]); -}); - -test.each(["", "string", "string with spaces", "string 1 2 3"])('Spread Element String "%s"', str => { - const code = ` - const arr = [..."${str}"]; - return JSONStringify(arr)`; - expect(JSON.parse(util.transpileAndExecute(code))).toEqual([...str]); -}); - -test.each([ - "{ value: false, ...{ value: true } }", - "{ ...{ value: false }, value: true }", - "{ ...{ value: false }, value: false, ...{ value: true } }", - "{ ...{ x: true, y: true } }", - "{ x: true, ...{ y: true, z: true } }", - "{ ...{ x: true }, ...{ y: true, z: true } }", -])('SpreadAssignment "%s"', expression => { - const code = `return JSONStringify(${expression});`; - expect(JSON.parse(util.transpileAndExecute(code))).toEqual(eval(`(${expression})`)); -}); - -test("SpreadAssignment Destructure", () => { - const code = `let obj = { x: 0, y: 1, z: 2 };`; - const luaCode = ` - ${code} - return JSONStringify({ a: 0, ...obj, b: 1, c: 2 });`; - const jsCode = ` - ${code} - ({ a: 0, ...obj, b: 1, c: 2 })`; - expect(JSON.parse(util.transpileAndExecute(luaCode))).toStrictEqual(eval(jsCode)); -}); - -test("SpreadAssignment No Mutation", () => { - const code = ` - const obj: { x: number, y: number, z?: number } = { x: 0, y: 1 }; - const merge = { ...obj, z: 2 }; - return obj.z;`; - expect(util.transpileAndExecute(code)).toBe(undefined); -}); - -test.each([ - "function spread() { return [0, 1, 2] } const object = { ...spread() };", - "const object = { ...[0, 1, 2] };", -])('SpreadAssignment Array "%s"', expressionToCreateObject => { - const code = ` - ${expressionToCreateObject} - return JSONStringify([object[0], object[1], object[2]]);`; - expect(JSON.parse(util.transpileAndExecute(code))).toEqual([0, 1, 2]); -}); diff --git a/test/unit/string.spec.ts b/test/unit/string.spec.ts deleted file mode 100644 index 9590c478d..000000000 --- a/test/unit/string.spec.ts +++ /dev/null @@ -1,380 +0,0 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; - -test("Unsuported string function", () => { - expect(() => { - util.transpileString(`return "test".testThisIsNoMember()`); - }).toThrowExactError(TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); -}); - -test("Suported lua string function", () => { - expect( - util.transpileAndExecute(`return "test".upper()`, undefined, undefined, `interface String { upper(): string; }`) - ).toBe("TEST"); -}); - -test.each([{ inp: [] }, { inp: [65] }, { inp: [65, 66] }, { inp: [65, 66, 67] }])( - "String.fromCharCode (%p)", - ({ inp }) => { - const result = util.transpileAndExecute(`return String.fromCharCode(${inp.toString()})`); - - expect(result).toBe(String.fromCharCode(...inp)); - } -); - -test.each([ - { a: 12, b: 23, c: 43 }, - { a: "test", b: "hello", c: "bye" }, - { a: "test", b: 42, c: "bye" }, - { a: "test", b: 42, c: 12 }, - { a: "test", b: 42, c: true }, - { a: false, b: 42, c: 12 }, -])("Template Strings (%p)", ({ a, b, c }) => { - const a1 = typeof a === "string" ? `'${a}'` : a; - const b1 = typeof b === "string" ? `'${b}'` : b; - const c1 = typeof c === "string" ? `'${c}'` : c; - - const result = util.transpileAndExecute(` - let a = ${a1}; - let b = ${b1}; - let c = ${c1}; - return \`${a} ${b} test ${c}\`; - `); - - expect(result).toBe(`${a} ${b} test ${c}`); -}); - -test.each([ - { a: 12, b: 23, c: 43 }, - { a: "test", b: "hello", c: "bye" }, - { a: "test", b: 42, c: "bye" }, - { a: "test", b: 42, c: 12 }, - { a: "test", b: 42, c: true }, - { a: false, b: 42, c: 12 }, -])("String Concat Operator (%p)", ({ a, b, c }) => { - const a1 = typeof a === "string" ? `'${a}'` : a; - const b1 = typeof b === "string" ? `'${b}'` : b; - const c1 = typeof c === "string" ? `'${c}'` : c; - - const result = util.transpileAndExecute(` - let a = ${a1}; - let b = ${b1}; - let c = ${c1}; - return a + " " + b + " test " + c; - `); - - expect(result).toBe(`${a} ${b} test ${c}`); -}); - -test.each([ - { input: "abcd", index: 3 }, - { input: "abcde", index: 3 }, - { input: "abcde", index: 0 }, - { input: "a", index: 0 }, -])("string index (%p)", ({ input, index }) => { - const result = util.transpileAndExecute(`return "${input}"[${index}];`); - - expect(result).toBe(input[index]); -}); - -test.each([ - { inp: "hello test", searchValue: "", replaceValue: "" }, - { inp: "hello test", searchValue: " ", replaceValue: "" }, - { inp: "hello test", searchValue: "hello", replaceValue: "" }, - { inp: "hello test", searchValue: "test", replaceValue: "" }, - { inp: "hello test", searchValue: "test", replaceValue: "world" }, - { inp: "hello test", searchValue: "test", replaceValue: "%world" }, - { inp: "hello %test", searchValue: "test", replaceValue: "world" }, - { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, - { inp: "hello test", searchValue: "test", replaceValue: (): string => "a" }, - { inp: "hello test", searchValue: "test", replaceValue: (): string => "%a" }, - { inp: "aaa", searchValue: "a", replaceValue: "b" }, -])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { - const replaceValueString = - typeof replaceValue === "string" ? JSON.stringify(replaceValue) : replaceValue.toString(); - const result = util.transpileAndExecute(`return "${inp}".replace("${searchValue}", ${replaceValueString});`); - - // https://github.com/Microsoft/TypeScript/issues/22378 - if (typeof replaceValue === "string") { - expect(result).toBe(inp.replace(searchValue, replaceValue)); - } else { - expect(result).toBe(inp.replace(searchValue, replaceValue)); - } -}); - -test.each([ - { inp: ["", ""], expected: "" }, - { inp: ["hello", "test"], expected: "hellotest" }, - { inp: ["hello", "test", "bye"], expected: "hellotestbye" }, - { inp: ["hello", 42], expected: "hello42" }, - { inp: [42, "hello"], expected: "42hello" }, -])("string.concat[+] (%p)", ({ inp, expected }) => { - const concatStr = inp.map(elem => (typeof elem === "string" ? `"${elem}"` : elem)).join(" + "); - - const result = util.transpileAndExecute(`return ${concatStr}`); - - expect(result).toBe(expected); -}); - -test.each([ - { str: "", param: ["", ""] }, - { str: "hello", param: ["test"] }, - { str: "hello", param: [] }, - { str: "hello", param: ["test", "bye"] }, -])("string.concatFct (%p)", ({ str, param }) => { - const paramStr = param.map(elem => `"${elem}"`).join(", "); - const result = util.transpileAndExecute(`return "${str}".concat(${paramStr})`); - expect(result).toBe(str.concat(...param)); -}); - -test.each([ - { inp: "hello test", searchValue: "" }, - { inp: "hello test", searchValue: "t" }, - { inp: "hello test", searchValue: "h" }, - { inp: "hello test", searchValue: "invalid" }, - { inp: "hello.test", searchValue: "." }, -])("string.indexOf (%p)", ({ inp, searchValue }) => { - const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}")`); - - expect(result).toBe(inp.indexOf(searchValue)); -}); - -test.each([ - { inp: "hello test", searchValue: "t", offset: 5 }, - { inp: "hello test", searchValue: "t", offset: 6 }, - { inp: "hello test", searchValue: "t", offset: 7 }, - { inp: "hello test", searchValue: "h", offset: 4 }, -])("string.indexOf with offset (%p)", ({ inp, searchValue, offset }) => { - const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}", ${offset})`); - - expect(result).toBe(inp.indexOf(searchValue, offset)); -}); - -test.each([{ inp: "hello test", searchValue: "t", x: 4, y: 3 }, { inp: "hello test", searchValue: "h", x: 3, y: 4 }])( - "string.indexOf with offset expression (%p)", - ({ inp, searchValue, x, y }) => { - const result = util.transpileAndExecute(`return "${inp}".indexOf("${searchValue}", 2 > 1 && ${x} || ${y})`); - - expect(result).toBe(inp.indexOf(searchValue, x)); - } -); - -test.each([ - { inp: "hello test" }, - { inp: "hello test", start: 0 }, - { inp: "hello test", start: 1 }, - { inp: "hello test", start: 1, end: 2 }, - { inp: "hello test", start: 1, end: 5 }, -])("string.slice (%p)", ({ inp, start, end }) => { - const paramStr = start ? (end ? `${start}, ${end}` : `${start}`) : ""; - const result = util.transpileAndExecute(`return "${inp}".slice(${paramStr})`); - - expect(result).toBe(inp.slice(start, end)); -}); - -test.each([ - { inp: "hello test", start: 0 }, - { inp: "hello test", start: 1 }, - { inp: "hello test", start: 1, end: 2 }, - { inp: "hello test", start: 1, end: 5 }, -])("string.substring (%p)", ({ inp, start, end }) => { - const paramStr = end ? `${start}, ${end}` : `${start}`; - const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); - - expect(result).toBe(inp.substring(start, end)); -}); - -test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 5 }])( - "string.substring with expression (%p)", - ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substring(${paramStr})`); - - expect(result).toBe(inp.substring(start, end)); - } -); - -test.each([ - { inp: "hello test", start: 0 }, - { inp: "hello test", start: 1 }, - { inp: "hello test", start: 1, end: 2 }, - { inp: "hello test", start: 1, end: 5 }, -])("string.substr (%p)", ({ inp, start, end }) => { - const paramStr = end ? `${start}, ${end}` : `${start}`; - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - - expect(result).toBe(inp.substr(start, end)); -}); - -test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 2 }])( - "string.substr with expression (%p)", - ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - - expect(result).toBe(inp.substr(start, end)); - } -); - -test.each(["", "h", "hello"])("string.length (%p)", input => { - const result = util.transpileAndExecute(`return "${input}".length`); - - expect(result).toBe(input.length); -}); - -test.each(["hello TEST"])("string.toLowerCase (%p)", inp => { - const result = util.transpileAndExecute(`return "${inp}".toLowerCase()`); - - expect(result).toBe(inp.toLowerCase()); -}); - -test.each(["hello test"])("string.toUpperCase (%p)", inp => { - const result = util.transpileAndExecute(`return "${inp}".toUpperCase()`); - - expect(result).toBe(inp.toUpperCase()); -}); - -test.each([ - { inp: "hello test", separator: "" }, - { inp: "hello test", separator: " " }, - { inp: "hello test", separator: "h" }, - { inp: "hello test", separator: "t" }, - { inp: "hello test", separator: "l" }, - { inp: "hello test", separator: "invalid" }, - { inp: "hello test", separator: "hello test" }, -])("string.split (%p)", ({ inp, separator }) => { - const result = util.transpileAndExecute(`return JSONStringify("${inp}".split("${separator}"))`); - - expect(result).toBe(JSON.stringify(inp.split(separator))); -}); - -test.each([ - { inp: "hello test", index: 1 }, - { inp: "hello test", index: 2 }, - { inp: "hello test", index: 3 }, - { inp: "hello test", index: 99 }, -])("string.charAt (%p)", ({ inp, index }) => { - const result = util.transpileAndExecute(`return "${inp}".charAt(${index})`); - - expect(result).toBe(inp.charAt(index)); -}); - -test.each([{ inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }])( - "string.charCodeAt (%p)", - ({ inp, index }) => { - const result = util.transpileAndExecute(`return "${inp}".charCodeAt(${index})`); - - expect(result).toBe(inp.charCodeAt(index)); - } -); - -test.each([ - { inp: "hello test", index: 1, ignored: 0 }, - { inp: "hello test", index: 1, ignored: 2 }, - { inp: "hello test", index: 3, ignored: 2 }, - { inp: "hello test", index: 3, ignored: 99 }, -])("string.charAt with expression (%p)", ({ inp, index, ignored }) => { - const result = util.transpileAndExecute(`return "${inp}".charAt(2 > 1 && ${index} || ${ignored})`); - - expect(result).toBe(inp.charAt(index)); -}); - -test.each<{ inp: string; args: Parameters }>([ - { inp: "hello test", args: [""] }, - { inp: "hello test", args: ["hello"] }, - { inp: "hello test", args: ["test"] }, - { inp: "hello test", args: ["test", 6] }, -])("string.startsWith (%p)", ({ inp, args }) => { - const argsString = util.valuesToString(args); - const result = util.transpileAndExecute(`return "${inp}".startsWith(${argsString})`); - - expect(result).toBe(inp.startsWith(...args)); -}); - -test.each<{ inp: string; args: Parameters }>([ - { inp: "hello test", args: [""] }, - { inp: "hello test", args: ["test"] }, - { inp: "hello test", args: ["hello"] }, - { inp: "hello test", args: ["hello", 5] }, -])("string.endsWith (%p)", ({ inp, args }) => { - const argsString = util.valuesToString(args); - const result = util.transpileAndExecute(`return "${inp}".endsWith(${argsString})`); - - expect(result).toBe(inp.endsWith(...args)); -}); - -test.each([ - { inp: "hello test", count: 0 }, - { inp: "hello test", count: 1 }, - { inp: "hello test", count: 2 }, - { inp: "hello test", count: 1.1 }, - { inp: "hello test", count: 1.5 }, - { inp: "hello test", count: 1.9 }, -])("string.repeat (%p)", ({ inp, count }) => { - const result = util.transpileAndExecute(`return "${inp}".repeat(${count})`); - - expect(result).toBe(inp.repeat(count)); -}); - -const padCases = [ - { inp: "foo", maxLength: 0 }, - { inp: "foo", maxLength: 3 }, - { inp: "foo", maxLength: 5 }, - { inp: "foo", maxLength: 4, fillString: " " }, - { inp: "foo", maxLength: 10, fillString: " " }, - { inp: "foo", maxLength: 5, fillString: "1234" }, - { inp: "foo", maxLength: 5.9, fillString: "1234" }, - { inp: "foo", maxLength: NaN }, -]; - -test.each(padCases)("string.padStart (%p)", ({ inp, maxLength, fillString }) => { - const argsString = util.valuesToString([maxLength, fillString]); - const result = util.transpileAndExecute(`return "${inp}".padStart(${argsString})`); - - expect(result).toBe(inp.padStart(maxLength, fillString)); -}); - -test.each(padCases)("string.padEnd (%p)", ({ inp, maxLength, fillString }) => { - const argsString = util.valuesToString([maxLength, fillString]); - const result = util.transpileAndExecute(`return "${inp}".padEnd(${argsString})`); - - expect(result).toBe(inp.padEnd(maxLength, fillString)); -}); - -test.each([`"foobar".length`, `"foobar".repeat(2)`, "`foo${'bar'}`.length", "`foo${'bar'}`.repeat(2)"])( - "string literal property access (%p)", - expression => { - const code = `return ${expression}`; - const expectResult = eval(expression); - expect(util.transpileAndExecute(code)).toBe(expectResult); - } -); - -test("scoped string-union inference", () => { - const inp = "foo"; - - const result = util.transpileAndExecute(` - const union: string = "${inp}"; - - if (union === "foo" || union === "bar") { - return union.length; - } - - return 0; - `); - - expect(result).toBe(inp.length); -}); - -test.each([ - "function generic(string: T)", - "type StringType = string; function generic(string: T)", -])("string constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - return string.length; - } - return generic("string"); - `; - expect(util.transpileAndExecute(code)).toBe(6); -}); diff --git a/test/unit/taggedTemplateLiterals.spec.ts b/test/unit/taggedTemplateLiterals.spec.ts deleted file mode 100644 index 6ab4e68cd..000000000 --- a/test/unit/taggedTemplateLiterals.spec.ts +++ /dev/null @@ -1,123 +0,0 @@ -import * as util from "../util"; - -const testCases = [ - { - callExpression: "func``", - joinAllResult: "", - joinRawResult: "", - }, - { - callExpression: "func`hello`", - joinAllResult: "hello", - joinRawResult: "hello", - }, - { - callExpression: "func`hello ${1} ${2} ${3}`", - joinAllResult: "hello 1 2 3", - joinRawResult: "hello ", - }, - { - callExpression: "func`hello ${(() => 'iife')()}`", - joinAllResult: "hello iife", - joinRawResult: "hello ", - }, - { - callExpression: "func`hello ${1 + 2 + 3} arithmetic`", - joinAllResult: "hello 6 arithmetic", - joinRawResult: "hello arithmetic", - }, - { - callExpression: "func`begin ${'middle'} end`", - joinAllResult: "begin middle end", - joinRawResult: "begin end", - }, - { - callExpression: "func`hello ${func`hello`}`", - joinAllResult: "hello hello", - joinRawResult: "hello ", - }, - { - callExpression: "func`hello \\u00A9`", - joinAllResult: "hello ©", - joinRawResult: "hello \\u00A9", - }, - { - callExpression: "func`hello $ { }`", - joinAllResult: "hello $ { }", - joinRawResult: "hello $ { }", - }, - { - callExpression: "func`hello { ${'brackets'} }`", - joinAllResult: "hello { brackets }", - joinRawResult: "hello { }", - }, - { - callExpression: "func`hello \\``", - joinAllResult: "hello `", - joinRawResult: "hello \\`", - }, - { - callExpression: "obj.func`hello ${'propertyAccessExpression'}`", - joinAllResult: "hello propertyAccessExpression", - joinRawResult: "hello ", - }, - { - callExpression: "obj['func']`hello ${'elementAccessExpression'}`", - joinAllResult: "hello elementAccessExpression", - joinRawResult: "hello ", - }, -]; - -test.each(testCases)("TaggedTemplateLiteral call (%p)", ({ callExpression, joinAllResult }) => { - const result = util.transpileAndExecute(` - function func(strings: TemplateStringsArray, ...expressions: any[]) { - const toJoin = []; - for (let i = 0; i < strings.length; ++i) { - if (strings[i]) { - toJoin.push(strings[i]); - } - if (expressions[i]) { - toJoin.push(expressions[i]); - } - } - return toJoin.join(""); - } - const obj = { - func - }; - return ${callExpression}; - `); - - expect(result).toBe(joinAllResult); -}); - -test.each(testCases)("TaggedTemplateLiteral raw preservation (%p)", ({ callExpression, joinRawResult }) => { - const result = util.transpileAndExecute(` - function func(strings: TemplateStringsArray, ...expressions: any[]) { - return strings.raw.join(""); - } - const obj = { - func - }; - return ${callExpression}; - `); - - expect(result).toBe(joinRawResult); -}); - -test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`noSelfParameter`"])( - "TaggedTemplateLiteral no self parameter", - callExpression => { - const result = util.transpileAndExecute(` - function func(this: void, strings: TemplateStringsArray, ...expressions: any[]) { - return strings.join(""); - } - const obj = { - func - }; - return ${callExpression}; - `); - - expect(result).toBe("noSelfParameter"); - } -); diff --git a/test/unit/templateLiterals.spec.ts b/test/unit/templateLiterals.spec.ts new file mode 100644 index 000000000..7db192a88 --- /dev/null +++ b/test/unit/templateLiterals.spec.ts @@ -0,0 +1,62 @@ +import * as util from "../util"; + +test.each([ + { a: 12, b: 23, c: 43 }, + { a: "test", b: "hello", c: "bye" }, + { a: "test", b: 42, c: "bye" }, + { a: "test", b: 42, c: 12 }, + { a: "test", b: 42, c: true }, + { a: false, b: 42, c: 12 }, +])("template literal (%p)", ({ a, b, c }) => { + util.testExpressionTemplate`\`\${${a}} \${${b}} test \${${c}}\``.expectToMatchJsResult(); +}); + +test.each(["a++", "a--", "--a", "++a"])("template literal with expression (%p)", expression => { + util.testFunction` + let a = 3; + return \`value\${${expression}}\`; + `.expectToMatchJsResult(); +}); + +test.each(["`foo${'bar'}`.length", "`foo${'bar'}`.repeat(2)"])("template literal property access (%p)", expression => { + util.testExpression(expression).expectToMatchJsResult(); +}); + +test.each([ + "func``", + "func`hello`", + "func`hello ${1} ${2} ${3}`", + "func`hello ${(() => 'iife')()}`", + "func`hello ${1 + 2 + 3} arithmetic`", + "func`begin ${'middle'} end`", + "func`hello ${func`hello`}`", + "func`hello \\u00A9`", + "func`hello $ { }`", + "func`hello { ${'brackets'} }`", + "func`hello \\``", + "obj.func`hello ${'propertyAccessExpression'}`", + "obj['func']`hello ${'elementAccessExpression'}`", +])("tagged template literal (%p)", expression => { + util.testFunction` + function func(strings: TemplateStringsArray, ...expressions: any[]) { + return { strings: [...strings], raw: strings.raw, expressions }; + } + + const obj = { func }; + return ${expression}; + `.expectToMatchJsResult(); +}); + +test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`noSelfParameter`"])( + "tagged template literal function context (%p)", + expression => { + util.testFunction` + function func(this: void, strings: TemplateStringsArray) { + return [...strings]; + } + + const obj = { func }; + return ${expression}; + `.expectToMatchJsResult(); + } +); diff --git a/test/unit/transformers.spec.ts b/test/unit/transformers/transformers.spec.ts similarity index 81% rename from test/unit/transformers.spec.ts rename to test/unit/transformers/transformers.spec.ts index cb7f143fe..db36c27dc 100644 --- a/test/unit/transformers.spec.ts +++ b/test/unit/transformers/transformers.spec.ts @@ -1,6 +1,6 @@ import * as path from "path"; -import * as tstl from "../../src"; -import * as util from "../util"; +import * as tstl from "../../../src"; +import * as util from "../../util"; const optionsOfTransformer = (transformer: tstl.TransformerImport): tstl.CompilerOptions => ({ plugins: [transformer], @@ -8,7 +8,7 @@ const optionsOfTransformer = (transformer: tstl.TransformerImport): tstl.Compile test("should ignore language service plugins", () => { const options: tstl.CompilerOptions = { - plugins: [{ name: path.join(__dirname, "transformers/resolve.ts") }], + plugins: [{ name: path.join(__dirname, "resolve.ts") }], }; expect(util.transpileAndExecute("return", options)).toBe(undefined); @@ -22,26 +22,26 @@ describe("resolution", () => { test("should resolve relative transformer paths", () => { jest.spyOn(process, "cwd").mockReturnValue(__dirname); - testTransform({ transform: "./transformers/resolve.ts" }); + testTransform({ transform: "./resolve.ts" }); }); test("should load js transformers", () => { - testTransform({ transform: path.join(__dirname, "transformers/resolve.js") }); + testTransform({ transform: path.join(__dirname, "resolve.js") }); }); test("should load ts transformers", () => { - testTransform({ transform: path.join(__dirname, "transformers/resolve.ts") }); + testTransform({ transform: path.join(__dirname, "resolve.ts") }); }); test('should support "import" option', () => { testTransform({ - transform: path.join(__dirname, "transformers/import.ts"), + transform: path.join(__dirname, "import.ts"), import: "transformer", }); }); test("should error if transformer could not be resolved", () => { - const transform = path.join(__dirname, "transformers/error.ts"); + const transform = path.join(__dirname, "error.ts"); const options = optionsOfTransformer({ transform }); const { diagnostics } = util.transpileStringResult("", options); expect(diagnostics).toHaveDiagnostics(); @@ -52,7 +52,7 @@ describe("factory types", () => { const value = "foo"; const getOptions = (options: Partial) => optionsOfTransformer({ - transform: path.join(__dirname, "transformers/types.ts"), + transform: path.join(__dirname, "types.ts"), ...options, }); diff --git a/test/unit/typechecking.spec.ts b/test/unit/typechecking.spec.ts deleted file mode 100644 index 500e4e094..000000000 --- a/test/unit/typechecking.spec.ts +++ /dev/null @@ -1,185 +0,0 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; - -test.each(["0", "30", "30_000", "30.00"])("typeof number (%p)", inp => { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - expect(result).toBe("number"); -}); - -test.each(['"abc"', "`abc`"])("typeof string (%p)", inp => { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - expect(result).toBe("string"); -}); - -test.each(["false", "true"])("typeof boolean (%p)", inp => { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - expect(result).toBe("boolean"); -}); - -test.each(["{}", "[]"])("typeof object literal (%p)", inp => { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - expect(result).toBe("object"); -}); - -test("typeof class instance", () => { - const result = util.transpileAndExecute(`class myClass {} let inst = new myClass(); return typeof inst;`); - - expect(result).toBe("object"); -}); - -test("typeof function", () => { - const result = util.transpileAndExecute(`return typeof (() => 3);`); - - expect(result).toBe("function"); -}); - -test.each(["null", "undefined"])("typeof undefined (%p)", inp => { - const result = util.transpileAndExecute(`return typeof ${inp};`); - - expect(result).toBe("undefined"); -}); - -test("instanceof", () => { - const result = util.transpileAndExecute( - "class myClass {} let inst = new myClass(); return inst instanceof myClass;" - ); - - expect(result).toBe(true); -}); - -test("instanceof inheritance", () => { - const result = util.transpileAndExecute(` - class myClass {} - class childClass extends myClass{} - let inst = new childClass(); return inst instanceof myClass; - `); - - expect(result).toBe(true); -}); - -test("instanceof inheritance false", () => { - const result = util.transpileAndExecute(` - class myClass {} - class childClass extends myClass{} - let inst = new myClass(); return inst instanceof childClass; - `); - - expect(result).toBe(false); -}); - -test("{} instanceof Object", () => { - const result = util.transpileAndExecute("return {} instanceof Object;"); - - expect(result).toBe(true); -}); - -test("function instanceof Object", () => { - const result = util.transpileAndExecute("return (() => {}) instanceof Object;"); - - expect(result).toBe(true); -}); - -test("null instanceof Object", () => { - const result = util.transpileAndExecute("return (null as any) instanceof Object;"); - - expect(result).toBe(false); -}); - -test("instanceof undefined", () => { - expect(() => { - util.transpileAndExecute("return {} instanceof (undefined as any);"); - }).toThrow("Right-hand side of 'instanceof' is not an object"); -}); - -test("null instanceof Class", () => { - const result = util.transpileAndExecute("class myClass {} return (null as any) instanceof myClass;"); - - expect(result).toBe(false); -}); - -test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { - const code = ` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - declare const foo: any; - const result = foo instanceof B; - `; - expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidInstanceOfExtension(util.nodeStub)); -}); - -test("instanceof export", () => { - const result = util.transpileExecuteAndReturnExport( - `export class myClass {} - let inst = new myClass(); - export const result = inst instanceof myClass;`, - "result" - ); - - expect(result).toBe(true); -}); - -test("instanceof Symbol.hasInstance", () => { - const result = util.transpileAndExecute(` - class myClass { - static [Symbol.hasInstance]() { - return false; - } - } - - const inst = new myClass(); - const isInstanceOld = inst instanceof myClass; - myClass[Symbol.hasInstance] = () => true; - const isInstanceNew = inst instanceof myClass; - return isInstanceOld !== isInstanceNew; - `); - - expect(result).toBe(true); -}); - -test.each([ - { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, - { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, - { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, - { expression: "1", operator: "===", compareTo: "number", expectResult: true }, - { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, - { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, -])("typeof literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { - const code = ` - let val = ${expression}; - return typeof val ${operator} "${compareTo}";`; - - expect(util.transpileString(code)).not.toMatch("__TS__TypeOf"); - expect(util.transpileAndExecute(code)).toBe(expectResult); -}); - -test.each([ - { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, - { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, - { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, - { expression: "1", operator: "===", compareTo: "number", expectResult: true }, - { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, - { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, -])("typeof non-literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { - const code = ` - let val = ${expression}; - let compareTo = "${compareTo}"; - return typeof val ${operator} compareTo;`; - - expect(util.transpileString(code)).toMatch("__TS__TypeOf"); - expect(util.transpileAndExecute(code)).toBe(expectResult); -}); diff --git a/test/unit/typeof.spec.ts b/test/unit/typeof.spec.ts new file mode 100644 index 000000000..1541884b1 --- /dev/null +++ b/test/unit/typeof.spec.ts @@ -0,0 +1,76 @@ +import * as util from "../util"; + +test.each(["0", "30", "30_000", "30.00"])("typeof number (%p)", inp => { + util.testExpression`typeof ${inp}`.expectToMatchJsResult(); +}); + +test.each(['"abc"', "`abc`"])("typeof string (%p)", inp => { + util.testExpression`typeof ${inp}`.expectToMatchJsResult(); +}); + +test.each(["false", "true"])("typeof boolean (%p)", inp => { + util.testExpression`typeof ${inp}`.expectToMatchJsResult(); +}); + +test.each(["{}", "[]"])("typeof object literal (%p)", inp => { + util.testExpression`typeof ${inp}`.expectToMatchJsResult(); +}); + +test("typeof class instance", () => { + util.testFunction` + class myClass {} + let inst = new myClass(); + return typeof inst; + `.expectToMatchJsResult(); +}); + +test("typeof function", () => { + util.testExpression`typeof (() => 3)`.expectToMatchJsResult(); +}); + +test.each(["null", "undefined"])("typeof undefined (%p)", inp => { + util.testExpression`typeof ${inp}`.expectToEqual("undefined"); +}); + +test.each([ + { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, + { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, + { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, + { expression: "1", operator: "===", compareTo: "number", expectResult: true }, + { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, + { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, +])("typeof literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { + const code = ` + let val = ${expression}; + return typeof val ${operator} "${compareTo}";`; + + expect(util.transpileString(code)).not.toMatch("__TS__TypeOf"); + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); + +test.each([ + { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, + { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, + { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, + { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, + { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, + { expression: "1", operator: "===", compareTo: "number", expectResult: true }, + { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, + { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, +])("typeof non-literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { + const code = ` + let val = ${expression}; + let compareTo = "${compareTo}"; + return typeof val ${operator} compareTo;`; + + expect(util.transpileString(code)).toMatch("__TS__TypeOf"); + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); diff --git a/test/util.ts b/test/util.ts index f12f81d5a..42f53e58f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,173 +1,20 @@ -import * as tsHelper from "../src/TSHelper"; import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; import * as path from "path"; +import * as prettyFormat from "pretty-format"; import * as ts from "typescript"; +import * as vm from "vm"; import * as tstl from "../src"; -export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); - -export function transpileString( - str: string | { [filename: string]: string }, - options: tstl.CompilerOptions = {}, - ignoreDiagnostics = true -): string { - const { diagnostics, file } = transpileStringResult(str, options); - if (!expectToBeDefined(file) || !expectToBeDefined(file.lua)) return ""; - - const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); - expect(errors).not.toHaveDiagnostics(); - - return file.lua.trim(); -} - -export function transpileStringsAsProject( - input: Record, - options: tstl.CompilerOptions = {} -): tstl.TranspileResult { - const optionsWithDefaults = { - luaTarget: tstl.LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: ["lib.esnext.d.ts"], - experimentalDecorators: true, - ...options, - }; - - return tstl.transpileVirtualProject(input, optionsWithDefaults); -} - -export function transpileStringResult( - input: string | Record, - options: tstl.CompilerOptions = {} -): Required { - const { diagnostics, transpiledFiles } = transpileStringsAsProject( - typeof input === "string" ? { "main.ts": input } : input, - options - ); - - const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); - if (file === undefined) { - throw new Error('Program should have a file named "main"'); - } - - return { diagnostics, file }; -} - -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; -export function executeLua(luaStr: string, withLib = true): any { - luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); - if (withLib) { - luaStr = minimalTestLib + luaStr; - } - - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); - - if (status === lua.LUA_OK) { - // Read the return value from stack depending on its type. - if (lua.lua_isboolean(L, -1)) { - return lua.lua_toboolean(L, -1); - } else if (lua.lua_isnil(L, -1)) { - return undefined; - } else if (lua.lua_isnumber(L, -1)) { - return lua.lua_tonumber(L, -1); - } else if (lua.lua_isstring(L, -1)) { - return lua.lua_tojsstring(L, -1); - } else { - throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); - } - } else { - // If the lua VM did not terminate with status code LUA_OK an error occurred. - // Throw a JS error with the message, retrieved by reading a string from the stack. +export * from "./legacy-utils"; - // Filter control characters out of string which are in there because ???? - throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20))); - } -} +export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); // Get a mock transformer to use for testing export function makeTestTransformer(luaTarget = tstl.LuaTarget.Lua53): tstl.LuaTransformer { return new tstl.LuaTransformer(ts.createProgram([], { luaTarget })); } -export function transpileAndExecute( - tsStr: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string, - tsHeader?: string -): any { - const wrappedTsString = `${tsHeader ? tsHeader : ""} - declare function JSONStringify(this: void, p: any): string; - function __runTest(this: void): any {${tsStr}}`; - - const lua = `${luaHeader ? luaHeader : ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - return __runTest();`; - - return executeLua(lua); -} - -export function transpileAndExecuteProjectReturningMainExport( - typeScriptFiles: Record, - exportName: string, - options: tstl.CompilerOptions = {} -): [any, string] { - const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); - if (!mainFile) { - throw new Error("An entry point file needs to be specified. This should be called main.ts"); - } - - const joinedTranspiledFiles = Object.keys(typeScriptFiles) - .filter(typeScriptFileName => typeScriptFileName !== "main.ts") - .map(typeScriptFileName => { - const modulePath = tsHelper.getExportPath(typeScriptFileName, options); - const tsCode = typeScriptFiles[typeScriptFileName]; - const luaCode = transpileString(tsCode, options); - return `package.preload["${modulePath}"] = function() - ${luaCode} - end`; - }) - .join("\n"); - - const luaCode = `return (function() - ${joinedTranspiledFiles} - ${transpileString(typeScriptFiles[mainFile])} - end)().${exportName}`; - - try { - return [executeLua(luaCode), luaCode]; - } catch (err) { - throw new Error(` - Encountered an error when executing the following Lua code: - - ${luaCode} - - ${err} - `); - } -} - -export function transpileExecuteAndReturnExport( - tsStr: string, - returnExport: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string -): any { - const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; - ${tsStr}`; - - const lua = `return (function() - ${luaHeader ? luaHeader : ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - end)().${returnExport}`; - - return executeLua(lua); -} - export function parseTypeScript( typescript: string, target: tstl.LuaTarget = tstl.LuaTarget.Lua53 @@ -203,8 +50,419 @@ export function expectToBeDefined(subject: T | null | undefined): subject is } export const valueToString = (value: unknown) => - value === Infinity || value === -Infinity || (typeof value === "number" && Number.isNaN(value)) + (typeof value === "number" && (!Number.isFinite(value) || Number.isNaN(value))) || typeof value === "function" ? String(value) : JSON.stringify(value); export const valuesToString = (values: unknown[]) => values.map(valueToString).join(", "); + +export function testEachVersion( + name: string | undefined, + common: () => T, + special: Record T) | false> +): void { + for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) { + const specialBuilder = special[version]; + if (specialBuilder === false) return; + + const testName = name === undefined ? version : `${name} [${version}]`; + test(testName, () => { + const builder = common(); + builder.setOptions({ luaTarget: version }); + specialBuilder(builder); + }); + } +} + +interface TranspiledJsFile { + fileName: string; + js?: string; + sourceMap?: string; +} + +interface TranspileJsResult { + diagnostics: ts.Diagnostic[]; + transpiledFiles: TranspiledJsFile[]; +} + +function transpileJs(program: ts.Program): TranspileJsResult { + const transpiledFiles: TranspiledJsFile[] = []; + const updateTranspiledFile = (fileName: string, update: Omit) => { + const file = transpiledFiles.find(f => f.fileName === fileName); + if (file) { + Object.assign(file, update); + } else { + transpiledFiles.push({ fileName, ...update }); + } + }; + + const { diagnostics } = program.emit(undefined, (fileName, data, _bom, _onError, sourceFiles = []) => { + for (const sourceFile of sourceFiles) { + const isJs = fileName.endsWith(".js"); + const isSourceMap = fileName.endsWith(".js.map"); + if (isJs || isSourceMap) { + updateTranspiledFile(sourceFile.fileName, { js: data }); + } else if (isSourceMap) { + updateTranspiledFile(sourceFile.fileName, { sourceMap: data }); + } + } + }); + + return { transpiledFiles, diagnostics: [...diagnostics] }; +} + +const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { + const originalFunction = descriptor.value as any; + const memoized = new WeakMap(); + descriptor.value = function(this: any, ...args: any[]): any { + if (!memoized.has(this)) { + memoized.set(this, originalFunction.apply(this, args)); + } + + return memoized.get(this); + } as any; + return descriptor; +}; + +export class ExecutionError extends Error { + public name = "ExecutionError"; + constructor(message: string) { + super(message); + } +} + +export type ExecutableTranspiledFile = tstl.TranspiledFile & { lua: string; sourceMap: string }; +export type TapCallback = (builder: TestBuilder) => void; +export abstract class TestBuilder { + constructor(protected _tsCode: string) {} + + // Options + + // TODO: Use testModule in these cases? + protected tsHeader = ""; + public setTsHeader(tsHeader: string): this { + expect(this.hasProgram).toBe(false); + this.tsHeader = tsHeader; + return this; + } + + private luaHeader = ""; + public setLuaHeader(luaHeader: string): this { + expect(this.hasProgram).toBe(false); + this.luaHeader += luaHeader; + return this; + } + + protected jsHeader = ""; + public setJsHeader(jsHeader: string): this { + expect(this.hasProgram).toBe(false); + this.jsHeader += jsHeader; + return this; + } + + private semanticCheck = true; + public disableSemanticCheck(): this { + expect(this.hasProgram).toBe(false); + this.semanticCheck = false; + return this; + } + + private options: tstl.CompilerOptions = { + luaTarget: tstl.LuaTarget.Lua53, + noHeader: true, + skipLibCheck: true, + target: ts.ScriptTarget.ES2017, + lib: ["lib.esnext.d.ts"], + experimentalDecorators: true, + }; + public setOptions(options: tstl.CompilerOptions = {}): this { + expect(this.hasProgram).toBe(false); + Object.assign(this.options, options); + return this; + } + + protected mainFileName = "main.ts"; + public setMainFileName(mainFileName: string): this { + expect(this.hasProgram).toBe(false); + this.mainFileName = mainFileName; + return this; + } + + private extraFiles: Record = {}; + public addExtraFile(fileName: string, code: string): this { + expect(this.hasProgram).toBe(false); + this.extraFiles[fileName] = code; + return this; + } + + // Transpilation and execution + + public getTsCode(): string { + return `${this.tsHeader}${this._tsCode}`; + } + + protected hasProgram = false; + @memoize + public getProgram(): ts.Program { + this.hasProgram = true; + return tstl.createVirtualProgram({ ...this.extraFiles, [this.mainFileName]: this.getTsCode() }, this.options); + } + + @memoize + public getLuaResult(): tstl.TranspileResult { + const program = this.getProgram(); + const result = tstl.transpile({ program }); + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...result.diagnostics, + ]); + + return { ...result, diagnostics: [...diagnostics] }; + } + + @memoize + public getMainLuaFileResult(): ExecutableTranspiledFile { + const { transpiledFiles } = this.getLuaResult(); + const mainFile = transpiledFiles.find(x => x.fileName === this.mainFileName); + expect(mainFile).toMatchObject({ lua: expect.any(String), sourceMap: expect.any(String) }); + return mainFile as ExecutableTranspiledFile; + } + + @memoize + public getMainLuaCodeChunk(): string { + const header = this.luaHeader ? `${this.luaHeader.trimRight()}\n` : ""; + return header + this.getMainLuaFileResult().lua.trimRight(); + } + + public abstract getLuaCodeWithWrapper(): string; + + @memoize + public getLuaExecutionResult(): any { + const code = this.getLuaCodeWithWrapper(); + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + const status = lauxlib.luaL_dostring(L, to_luastring(code)); + + if (status === lua.LUA_OK) { + if (lua.lua_isstring(L, -1)) { + const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + return result === null ? undefined : result; + } else { + const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + throw new Error(`Unsupported Lua return type: ${returnType}`); + } + } else { + const message = to_jsstring(lua.lua_tostring(L, -1)).replace(/^\[string "--\.\.\."\]:\d+: /, ""); + return new ExecutionError(message); + } + } + + @memoize + public getJsResult(): TranspileJsResult { + const program = this.getProgram(); + program.getCompilerOptions().module = ts.ModuleKind.CommonJS; + return transpileJs(program); + } + + @memoize + protected getMainJsCodeChunk(): string { + const { transpiledFiles } = this.getJsResult(); + const mainFile = transpiledFiles.find(x => x.fileName === this.mainFileName); + expect(mainFile).toBeDefined(); + + const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; + return header + mainFile!.js!; + } + + protected abstract getJsCodeWithWrapper(): string; + + @memoize + public getJsExecutionResult(): any { + const exports = {}; + const context = vm.createContext({ exports, module: { exports } }); + context.global = context; + let result: unknown; + try { + result = vm.runInContext(this.getJsCodeWithWrapper(), context); + } catch (error) { + return new ExecutionError(error.message); + } + + function transform(currentValue: any): any { + if (currentValue === null) { + return undefined; + } + + if (Array.isArray(currentValue)) { + return currentValue.map(transform); + } + + if (typeof currentValue === "object") { + for (const [key, value] of Object.entries(currentValue)) { + currentValue[key] = transform(value); + if (currentValue[key] === undefined) { + delete currentValue[key]; + } + } + + if (Object.keys(currentValue).length === 0) { + return []; + } + } + + return currentValue; + } + + return transform(result); + } + + // Utilities + + private getLuaDiagnostics(): ts.Diagnostic[] { + const { diagnostics } = this.getLuaResult(); + return diagnostics.filter(d => this.semanticCheck || d.source === "typescript-to-lua"); + } + + // Actions + + public debug(): this { + const luaCode = this.getMainLuaCodeChunk().replace(/(^|\n)/g, "\n "); + const value = prettyFormat(this.getLuaExecutionResult()); + console.log(`Lua Code:${luaCode}\nValue: ${value}`); + return this; + } + + public expectToHaveDiagnostics(): this { + expect(this.getLuaDiagnostics()).toHaveDiagnostics(); + return this; + } + + public expectToHaveDiagnosticOfError(error: tstl.TranspileError): this { + this.expectToHaveDiagnostics(); + expect(this.getLuaDiagnostics()).toHaveLength(1); + const firstDiagnostic = this.getLuaDiagnostics()[0]; + expect(firstDiagnostic).toMatchObject({ messageText: error.message }); + return this; + } + + public expectToHaveNoDiagnostics(): this { + expect(this.getLuaDiagnostics()).not.toHaveDiagnostics(); + return this; + } + + public expectNoExecutionError(): this { + const luaResult = this.getLuaExecutionResult(); + if (luaResult instanceof ExecutionError) { + throw luaResult; + } + + return this; + } + + public expectToMatchJsResult(allowErrors = false): this { + this.expectToHaveNoDiagnostics(); + if (!allowErrors) this.expectNoExecutionError(); + + const luaResult = this.getLuaExecutionResult(); + const jsResult = this.getJsExecutionResult(); + expect(luaResult).toEqual(jsResult); + + return this; + } + + public expectToEqual(expected: any): this { + this.expectToHaveNoDiagnostics(); + const luaResult = this.getLuaExecutionResult(); + expect(luaResult).toEqual(expected); + return this; + } + + public expectLuaToMatchSnapshot(): this { + this.expectToHaveNoDiagnostics(); + expect(this.getMainLuaCodeChunk()).toMatchSnapshot(); + return this; + } + + public expectResultToMatchSnapshot(): this { + this.expectToHaveNoDiagnostics(); + expect(this.getLuaExecutionResult()).toMatchSnapshot(); + return this; + } + + public tap(callback: TapCallback): this { + callback(this); + return this; + } +} + +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; +class AccessorTestBuilder extends TestBuilder { + protected accessor = ""; + + @memoize + public getLuaCodeWithWrapper(): string { + let code = this.getMainLuaCodeChunk(); + if (code.includes('require("lualib_bundle")')) { + code = `package.preload.lualib_bundle = function()\n${lualibContent}\nend\n${code}`; + } + + return `${minimalTestLib}\nreturn JSONStringify((function()\n${code}\nend)()${this.accessor})`; + } + + @memoize + protected getJsCodeWithWrapper(): string { + return this.getMainJsCodeChunk() + `\n;module.exports = module.exports${this.accessor}`; + } +} + +class ModuleTestBuilder extends AccessorTestBuilder { + public setReturnExport(name: string): this { + expect(this.hasProgram).toBe(false); + this.accessor = `.${name}`; + return this; + } +} + +class FunctionTestBuilder extends AccessorTestBuilder { + protected accessor = ".__main()"; + public getTsCode(): string { + return `${this.tsHeader}export function __main() {${this._tsCode}}`; + } +} + +class ExpressionTestBuilder extends AccessorTestBuilder { + protected accessor = ".__result"; + public getTsCode(): string { + return `${this.tsHeader}export const __result = ${this._tsCode};`; + } +} + +const createTestBuilderFactory = ( + builder: new (_tsCode: string) => T, + serializeSubstitutions: boolean +) => (...args: [string] | [TemplateStringsArray, ...any[]]): T => { + let tsCode: string; + if (typeof args[0] === "string") { + expect(serializeSubstitutions).toBe(false); + tsCode = args[0]; + } else { + let [template, ...substitutions] = args; + if (serializeSubstitutions) { + substitutions = substitutions.map(valueToString); + } + + tsCode = template + .map((chunk, index) => (substitutions[index - 1] !== undefined ? substitutions[index - 1] : "") + chunk) + .join(""); + } + + return new builder(tsCode); +}; + +export const testModule = createTestBuilderFactory(ModuleTestBuilder, false); +export const testModuleTemplate = createTestBuilderFactory(ModuleTestBuilder, true); +export const testFunction = createTestBuilderFactory(FunctionTestBuilder, false); +export const testFunctionTemplate = createTestBuilderFactory(FunctionTestBuilder, true); +export const testExpression = createTestBuilderFactory(ExpressionTestBuilder, false); +export const testExpressionTemplate = createTestBuilderFactory(ExpressionTestBuilder, true); diff --git a/tslint.json b/tslint.json index 2bf168c59..be6ae2b58 100644 --- a/tslint.json +++ b/tslint.json @@ -22,7 +22,6 @@ "interface-name": [true, "never-prefix"], "jsdoc-format": true, "label-position": true, - "max-classes-per-file": [true, 1], "member-access": true, "no-angle-bracket-type-assertion": true, "no-any": false, From 57efc144bfc5ccaf9c27811113d36f1f6ba58714 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 1 Aug 2019 23:04:55 +0200 Subject: [PATCH 156/764] Filter out control characters from lua error message --- test/util.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/util.ts b/test/util.ts index 42f53e58f..8abc0dbc6 100644 --- a/test/util.ts +++ b/test/util.ts @@ -252,7 +252,9 @@ export abstract class TestBuilder { throw new Error(`Unsupported Lua return type: ${returnType}`); } } else { - const message = to_jsstring(lua.lua_tostring(L, -1)).replace(/^\[string "--\.\.\."\]:\d+: /, ""); + // Filter out control characters appearing on some systems + const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); + const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); return new ExecutionError(message); } } From 8655fe12f826fbf2d0e2e079369c36b24fd76c0d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 1 Aug 2019 23:06:13 +0200 Subject: [PATCH 157/764] 0.26.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce9752f4b..46b514743 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.25.0", + "version": "0.26.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 669b8997f..3788a172e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.25.0", + "version": "0.26.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 688517dd0cdf2fe082a5d266c0d41255f04c4751 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 1 Aug 2019 23:26:37 +0200 Subject: [PATCH 158/764] Update CHANGELOG.md --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78322e78f..7b5af657c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 0.26.0 + +- Added support for [default exports and export equals statements](https://github.com/Microsoft/TypeScript/issues/7185#issuecomment-421632656). +- Added support for [object spread expressions](https://mariusschulz.com/blog/object-rest-and-spread-in-typescript). +- Added support for most common [destructuring assignments](https://basarat.gitbooks.io/typescript/content/docs/destructuring.html). +- Added support for omitted declarations in destructuring tuples. (i.e. `const [a,,c] = foo();`) + +- `@noSelf` now only applies to members of the namespace with the directive, in case of namespace merging. +- Fixed issue with isNumerType causing enum members as array indices not to recieve the `+1`. +- Fixed string.indexOf failing in case the search string was a Lua string pattern. +- Fixed some crashes from recursive type constraints. + +- Some simplification to the printing of expression statements. +- Added new testing util methods to improve the testing process. + ## 0.25.0 - Added support for named function assignments, i.e. `const myFunc = function x(n) { ...; return x(n - 1); }` From 532d09d909a9d9e2657269cd0cbc612b5df918de Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 3 Aug 2019 17:23:51 +0500 Subject: [PATCH 159/764] Simplify and improve enum transform (#685) * Simplify and improve enum transform * Tests * Fix enum toString test not working * Don't generate reverse mapping for nil member values --- src/LuaTransformer.ts | 144 +++++++++++++---------------------- src/TSHelper.ts | 20 ----- src/TSTLErrors.ts | 7 -- test/unit/enum.spec.ts | 90 +++++++++++----------- test/unit/namespaces.spec.ts | 12 +++ 5 files changed, 110 insertions(+), 163 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index a8a5cdd35..50bc074d5 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1727,115 +1727,77 @@ export class LuaTransformer { return result; } - public transformEnumDeclaration(enumDeclaration: ts.EnumDeclaration): StatementVisitResult { - const type = this.checker.getTypeAtLocation(enumDeclaration); - - // Const enums should never appear in the resulting code - if (type.symbol.getFlags() & ts.SymbolFlags.ConstEnum) { + public transformEnumDeclaration(node: ts.EnumDeclaration): StatementVisitResult { + if (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Const && !this.options.preserveConstEnums) { return undefined; } + const type = this.checker.getTypeAtLocation(node); const membersOnly = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.CompileMembersOnly); - const result: tstl.Statement[] = []; if (!membersOnly) { - const name = this.transformIdentifier(enumDeclaration.name); + const name = this.transformIdentifier(node.name); const table = tstl.createTableExpression(); - result.push(...this.createLocalOrExportedOrGlobalDeclaration(name, table, enumDeclaration)); + result.push(...this.createLocalOrExportedOrGlobalDeclaration(name, table, node)); } - for (const enumMember of this.computeEnumMembers(enumDeclaration)) { - const memberName = this.transformPropertyName(enumMember.name); - if (membersOnly) { - const enumSymbol = this.checker.getSymbolAtLocation(enumDeclaration.name); - const exportScope = enumSymbol ? this.getSymbolExportScope(enumSymbol) : undefined; + const enumReference = this.transformExpression(node.name); + for (const member of node.members) { + const memberName = this.transformPropertyName(member.name); - if (tstl.isIdentifier(memberName)) { - result.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - memberName, - enumMember.value, - enumDeclaration, - undefined, - exportScope - ) - ); - } else { - result.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - tstl.createIdentifier(enumMember.name.getText(), enumMember.name), - enumMember.value, - enumDeclaration, - undefined, - exportScope - ) - ); + let valueExpression: tstl.Expression | undefined; + const constEnumValue = this.tryGetConstEnumValue(member); + if (constEnumValue) { + valueExpression = constEnumValue; + } else if (member.initializer) { + if (ts.isIdentifier(member.initializer)) { + const symbol = this.checker.getSymbolAtLocation(member.initializer); + if ( + symbol && + symbol.valueDeclaration && + ts.isEnumMember(symbol.valueDeclaration) && + symbol.valueDeclaration.parent === node + ) { + const otherMemberName = this.transformPropertyName(symbol.valueDeclaration.name); + valueExpression = tstl.createTableIndexExpression(enumReference, otherMemberName); + } } - } else { - const enumTable = this.transformIdentifierExpression(enumDeclaration.name); - const property = tstl.createTableIndexExpression(enumTable, memberName); - result.push(tstl.createAssignmentStatement(property, enumMember.value, enumMember.original)); - const valueIndex = tstl.createTableIndexExpression(enumTable, enumMember.value); - result.push(tstl.createAssignmentStatement(valueIndex, memberName, enumMember.original)); - } - } - - return result; - } - - protected computeEnumMembers( - node: ts.EnumDeclaration - ): Array<{ name: ts.PropertyName; value: tstl.Expression; original: ts.Node }> { - let numericValue = 0; - let hasStringInitializers = false; - - const valueMap = new Map(); - - return node.members.map(member => { - let valueExpression: ExpressionVisitResult; - if (member.initializer) { - if (ts.isNumericLiteral(member.initializer)) { - numericValue = Number(member.initializer.text); - valueExpression = this.transformNumericLiteral(member.initializer); - numericValue++; - } else if (ts.isStringLiteral(member.initializer)) { - hasStringInitializers = true; - valueExpression = this.transformStringLiteral(member.initializer); - } else { - if (ts.isIdentifier(member.initializer)) { - const [isEnumMember, originalName] = tsHelper.isEnumMember(node, member.initializer); - if (isEnumMember === true && originalName !== undefined) { - if (valueMap.has(originalName)) { - valueExpression = valueMap.get(originalName)!; - } else { - throw new Error(`Expected valueMap to contain ${originalName}`); - } - } else { - valueExpression = this.transformExpression(member.initializer); - } - } else { - valueExpression = this.transformExpression(member.initializer); - } + if (!valueExpression) { + valueExpression = this.transformExpression(member.initializer); } - } else if (hasStringInitializers) { - throw TSTLErrors.HeterogeneousEnum(node); } else { - valueExpression = tstl.createNumericLiteral(numericValue); - numericValue++; + valueExpression = tstl.createNilLiteral(); } - valueMap.set(member.name, valueExpression); + if (membersOnly) { + const enumSymbol = this.checker.getSymbolAtLocation(node.name); + const exportScope = enumSymbol ? this.getSymbolExportScope(enumSymbol) : undefined; - const enumMember = { - name: member.name, - original: member, - value: valueExpression, - }; + result.push( + ...this.createLocalOrExportedOrGlobalDeclaration( + tstl.isIdentifier(memberName) + ? memberName + : tstl.createIdentifier(member.name.getText(), member.name), + valueExpression, + node, + undefined, + exportScope + ) + ); + } else { + const memberAccessor = tstl.createTableIndexExpression(enumReference, memberName); + result.push(tstl.createAssignmentStatement(memberAccessor, valueExpression, member)); - return enumMember; - }); + if (!tstl.isStringLiteral(valueExpression) && !tstl.isNilLiteral(valueExpression)) { + const reverseMemberAccessor = tstl.createTableIndexExpression(enumReference, memberAccessor); + result.push(tstl.createAssignmentStatement(reverseMemberAccessor, memberName, member)); + } + } + } + + return result; } protected transformGeneratorFunction( @@ -4707,7 +4669,7 @@ export class LuaTransformer { } private tryGetConstEnumValue( - node: ts.PropertyAccessExpression | ts.ElementAccessExpression + node: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression ): tstl.Expression | undefined { const value = this.checker.getConstantValue(node); if (typeof value === "string") { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index cbb250e77..023a0c0c6 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -871,26 +871,6 @@ export function isStandardLibraryType(type: ts.Type, name: string | undefined, p return isStandardLibraryDeclaration(declaration, program); } -export function isEnumMember( - enumDeclaration: ts.EnumDeclaration, - value: ts.Expression -): [true, ts.PropertyName] | [false, undefined] { - if (ts.isIdentifier(value)) { - const enumMember = enumDeclaration.members.find(m => ts.isIdentifier(m.name) && m.name.text === value.text); - if (enumMember !== undefined) { - if (enumMember.initializer && ts.isIdentifier(enumMember.initializer)) { - return isEnumMember(enumDeclaration, enumMember.initializer); - } else { - return [true, enumMember.name]; - } - } else { - return [false, undefined]; - } - } else { - return [false, undefined]; - } -} - export function isWithinLiteralAssignmentStatement(node: ts.Node): boolean { if (!node.parent) { return false; diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 0e53dd713..8d9966c0b 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -31,13 +31,6 @@ export const InvalidInstanceOfLuaTable = (node: ts.Node) => export const ForbiddenLuaTableUseException = (description: string, node: ts.Node) => new TranspileError(`Invalid @luaTable usage: ${description}`, node); -export const HeterogeneousEnum = (node: ts.Node) => - new TranspileError( - `Invalid heterogeneous enum. Enums should either specify no member values, ` + - `or specify values (of the same type) for all members.`, - node - ); - export const InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 6fd75556b..8da16355c 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -1,4 +1,3 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; // TODO: string.toString() @@ -10,21 +9,18 @@ const serializeEnum = (identifier: string) => `(() => { return mappedTestEnum; })()`; -// TODO: Move to namespace tests? -test("in a namespace", () => { - util.testModule` - namespace Test { - export enum TestEnum { - A, - B, +describe("initializers", () => { + test("string", () => { + util.testFunction` + enum TestEnum { + A = "A", + B = "B", } - } - export const result = ${serializeEnum("Test.TestEnum")} - `.expectToMatchJsResult(); -}); + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); -describe("initializers", () => { test("expression", () => { util.testFunction` const value = 6; @@ -37,6 +33,18 @@ describe("initializers", () => { `.expectToMatchJsResult(); }); + test("expression with side effect", () => { + util.testFunction` + let value = 0; + enum TestEnum { + A = value++, + B = A, + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); + test("inference", () => { util.testFunction` enum TestEnum { @@ -61,7 +69,7 @@ describe("initializers", () => { `.expectToMatchJsResult(); }); - test("other member reference", () => { + test("member reference", () => { util.testFunction` enum TestEnum { A, @@ -72,38 +80,38 @@ describe("initializers", () => { return ${serializeEnum("TestEnum")} `.expectToMatchJsResult(); }); -}); -test("invalid heterogeneous enum", () => { - util.testFunction` - enum TestEnum { - A, - B = "B", - C, - } - ` - .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.HeterogeneousEnum(util.nodeStub)); + test("string literal member reference", () => { + util.testFunction` + enum TestEnum { + ["A"], + "B" = A, + C = B, + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); + }); }); describe("const enum", () => { const expectToBeConst: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).not.toContain("TestEnum"); - test.each(["", "declare"])("%s without initializer", () => { - util.testFunction` - const enum TestEnum { + test.each(["", "declare "])("%swithout initializer", modifier => { + util.testModule` + ${modifier} const enum TestEnum { A, B, } - return TestEnum.A; + export const A = TestEnum.A; ` .tap(expectToBeConst) .expectToMatchJsResult(); }); - test("with initializer", () => { + test("with string initializer", () => { util.testFunction` const enum TestEnum { A = "ONE", @@ -131,26 +139,18 @@ describe("const enum", () => { }); }); -test("enum toString", () => { - const code = ` +test("toString", () => { + util.testFunction` enum TestEnum { A, B, C, } - let test = TestEnum.A; - return test.toString();`; - expect(util.transpileAndExecute(code)).toBe(0); -}); -test("enum concat", () => { - const code = ` - enum TestEnum { - A, - B, - C, + function foo(value: TestEnum) { + return value.toString(); } - let test = TestEnum.A; - return test + "_foobar";`; - expect(util.transpileAndExecute(code)).toBe("0_foobar"); + + return foo(TestEnum.A); + `.expectToMatchJsResult(); }); diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 21272ae8e..fe17f6da4 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -119,3 +119,15 @@ test("`import =` on a namespace", () => { export const result = importedFunc(); `.expectToMatchJsResult(); }); + +test("enum in a namespace", () => { + util.testModule` + namespace Test { + export enum TestEnum { + A, + } + } + + export const result = Test.TestEnum.A; + `.expectToMatchJsResult(); +}); From c94e0708f4b5cbaa8ea183619288de7bea375227 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 12 Aug 2019 01:28:02 -0600 Subject: [PATCH 160/764] class field initialization order (#700) * fixed order of class property initialization fixes #697 * fixed constructor field initialization to falsey values * using new test builder * updated comment --- src/LuaTransformer.ts | 103 +++++++++++++++--------------- test/unit/classes/classes.spec.ts | 19 ++++++ 2 files changed, 72 insertions(+), 50 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 50bc074d5..d8aee1a01 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1237,55 +1237,29 @@ export class LuaTransformer { return undefined; } - const bodyWithFieldInitializers: tstl.Statement[] = this.transformClassInstanceFields( - classDeclaration, - instanceFields - ); - - // Check for field declarations in constructor - const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - - // Add in instance field declarations - for (const declaration of constructorFieldsDeclarations) { - const declarationName = this.transformIdentifier(declaration.name as ts.Identifier); - if (declaration.initializer) { - // self.declarationName = declarationName or initializer - const assignment = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createSelfIdentifier(), - tstl.createStringLiteral(declarationName.text) - ), - tstl.createBinaryExpression( - declarationName, - this.transformExpression(declaration.initializer), - tstl.SyntaxKind.OrOperator - ) - ); - bodyWithFieldInitializers.push(assignment); - } else { - // self.declarationName = declarationName - const assignment = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createSelfIdentifier(), - tstl.createStringLiteral(declarationName.text) - ), - declarationName - ); - bodyWithFieldInitializers.push(assignment); - } - } - - // function className.constructor(self, params) ... end + // Transform body + const [body, scope] = this.transformFunctionBodyStatements(statement.body); const [params, dotsLiteral, restParamName] = this.transformParameters( statement.parameters, this.createSelfIdentifier() ); - const [body] = this.transformFunctionBody(statement.parameters, statement.body, restParamName); + // Make sure default parameters are assigned before fields are initialized + const bodyWithFieldInitializers = this.transformFunctionBodyHeader(scope, statement.parameters, restParamName); - // If there are field initializers and the first statement is a super call, hoist the super call to the top - if (bodyWithFieldInitializers.length > 0 && statement.body && statement.body.statements.length > 0) { + // Check for field declarations in constructor + const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); + + const classInstanceFields = this.transformClassInstanceFields(classDeclaration, instanceFields); + + // If there are field initializers and the first statement is a super call, + // move super call between default assignments and initializers + if ( + (constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) && + statement.body && + statement.body.statements.length > 0 + ) { const firstStatement = statement.body.statements[0]; if ( ts.isExpressionStatement(firstStatement) && @@ -1294,11 +1268,27 @@ export class LuaTransformer { ) { const superCall = body.shift(); if (superCall) { - bodyWithFieldInitializers.unshift(superCall); + bodyWithFieldInitializers.push(superCall); } } } + // Add in instance field declarations + for (const declaration of constructorFieldsDeclarations) { + const declarationName = this.transformIdentifier(declaration.name as ts.Identifier); + // self.declarationName = declarationName + const assignment = tstl.createAssignmentStatement( + tstl.createTableIndexExpression( + this.createSelfIdentifier(), + tstl.createStringLiteral(declarationName.text) + ), + declarationName + ); + bodyWithFieldInitializers.push(assignment); + } + + bodyWithFieldInitializers.push(...classInstanceFields); + bodyWithFieldInitializers.push(...body); const block: tstl.Block = tstl.createBlock(bodyWithFieldInitializers); @@ -1490,16 +1480,19 @@ export class LuaTransformer { ); } - protected transformFunctionBody( - parameters: ts.NodeArray, - body: ts.Block, - spreadIdentifier?: tstl.Identifier - ): [tstl.Statement[], Scope] { + protected transformFunctionBodyStatements(body: ts.Block): [tstl.Statement[], Scope] { this.pushScope(ScopeType.Function); const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); const scope = this.popScope(); + return [bodyStatements, scope]; + } - const headerStatements = []; + protected transformFunctionBodyHeader( + bodyScope: Scope, + parameters: ts.NodeArray, + spreadIdentifier?: tstl.Identifier + ): tstl.Statement[] { + const headerStatements: tstl.Statement[] = []; // Add default parameters and object binding patterns const bindingPatternDeclarations: tstl.Statement[] = []; @@ -1530,7 +1523,7 @@ export class LuaTransformer { } // Push spread operator here - if (spreadIdentifier && this.isRestParameterReferenced(spreadIdentifier, scope)) { + if (spreadIdentifier && this.isRestParameterReferenced(spreadIdentifier, bodyScope)) { const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -1538,6 +1531,16 @@ export class LuaTransformer { // Binding pattern statements need to be after spread table is declared headerStatements.push(...bindingPatternDeclarations); + return headerStatements; + } + + protected transformFunctionBody( + parameters: ts.NodeArray, + body: ts.Block, + spreadIdentifier?: tstl.Identifier + ): [tstl.Statement[], Scope] { + const [bodyStatements, scope] = this.transformFunctionBodyStatements(body); + const headerStatements = this.transformFunctionBodyHeader(scope, parameters, spreadIdentifier); return [headerStatements.concat(bodyStatements), scope]; } diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 3f156c93a..343ad75ad 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -88,6 +88,25 @@ test("ClassConstructorAssignmentDefault", () => { expect(result).toBe(3); }); +test("ClassConstructorPropertyInitiailizationOrder", () => { + util.testFunction` + class Test { + public foo = this.bar; + constructor(public bar: string) {} + } + return (new Test("baz")).foo; + `.expectToMatchJsResult(); +}); + +test("ClassConstructorPropertyInitiailizationFalsey", () => { + util.testFunction` + class Test { + constructor(public foo = true) {} + } + return (new Test(false)).foo; + `.expectToMatchJsResult(); +}); + test("ClassNewNoBrackets", () => { const result = util.transpileAndExecute( `class a { From 2c271d769d6498416d9c0e265a30a0c2a4f40c2f Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 18 Aug 2019 18:37:21 +0500 Subject: [PATCH 161/764] Support rest pattern in destructuring (#568) * Support rest pattern in destructuring * Remove failing test * Use map for usedProperties * Small destructuring assignment refactor * Tests * Support expression assignments --- src/LuaAST.ts | 3 + src/LuaLib.ts | 1 + src/LuaTransformer.ts | 297 ++++++++++++++++++-------------- src/TSHelper.ts | 44 ++--- src/TSTLErrors.ts | 3 - src/lualib/ObjectRest.ts | 14 ++ test/unit/destructuring.spec.ts | 10 +- 7 files changed, 205 insertions(+), 167 deletions(-) create mode 100644 src/lualib/ObjectRest.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index ee6c8002b..d88dbef09 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -887,6 +887,9 @@ export function createTableIndexExpression( } export type AssignmentLeftHandSideExpression = Identifier | TableIndexExpression; +export function isAssignmentLeftHandSideExpression(node: Node): node is AssignmentLeftHandSideExpression { + return isIdentifier(node) || isTableIndexExpression(node); +} export type FunctionDefinition = (VariableDeclarationStatement | AssignmentStatement) & { right: [FunctionExpression]; diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 25cd83268..050e1eaf3 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -41,6 +41,7 @@ export enum LuaLibFeature { ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", ObjectKeys = "ObjectKeys", + ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", Set = "Set", WeakMap = "WeakMap", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index d8aee1a01..9a6367837 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1572,60 +1572,90 @@ export class LuaTransformer { const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (let index = 0; index < pattern.elements.length; index++) { const element = pattern.elements[index]; - if (ts.isBindingElement(element)) { - if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { - // nested binding pattern - const propertyName = isObjectBindingPattern - ? element.propertyName - : ts.createNumericLiteral(String(index + 1)); - if (propertyName !== undefined) { - propertyAccessStack.push(propertyName); - } - result.push( - ...this.statementVisitResultToArray( - this.transformBindingPattern(element.name, table, propertyAccessStack) + if (ts.isOmittedExpression(element)) continue; + + if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { + // nested binding pattern + const propertyName = isObjectBindingPattern + ? element.propertyName + : ts.createNumericLiteral(String(index + 1)); + if (propertyName !== undefined) { + propertyAccessStack.push(propertyName); + } + result.push( + ...this.statementVisitResultToArray( + this.transformBindingPattern(element.name, table, propertyAccessStack) + ) + ); + continue; + } + + // Build the path to the table + let tableExpression: tstl.Expression = table; + propertyAccessStack.forEach(property => { + const propertyName = ts.isPropertyName(property) + ? this.transformPropertyName(property) + : this.transformNumericLiteral(property); + tableExpression = tstl.createTableIndexExpression(tableExpression, propertyName); + }); + + // The identifier of the new variable + const variableName = this.transformIdentifier(element.name as ts.Identifier); + // The field to extract + const propertyName = this.transformPropertyName(element.propertyName || element.name); + + let expression: tstl.Expression; + if (element.dotDotDotToken) { + if (index !== pattern.elements.length - 1) continue; + + if (isObjectBindingPattern) { + const elements = pattern.elements as ts.NodeArray; + const usedProperties = elements.map(e => + tstl.createTableFieldExpression( + tstl.createBooleanLiteral(true), + tstl.createStringLiteral( + ((e.propertyName || e.name) as ts.Identifier).text, + e.propertyName || e.name + ) ) ); + + expression = this.transformLuaLibFunction( + LuaLibFeature.ObjectRest, + undefined, + tableExpression, + tstl.createTableExpression(usedProperties) + ); } else { - // Disallow ellipsis destructure - if (element.dotDotDotToken) { - throw TSTLErrors.ForbiddenEllipsisDestruction(element); - } - // Build the path to the table - let tableExpression: tstl.Expression = table; - propertyAccessStack.forEach(property => { - const propertyName = ts.isPropertyName(property) - ? this.transformPropertyName(property) - : this.transformNumericLiteral(property); - tableExpression = tstl.createTableIndexExpression(tableExpression, propertyName); - }); - // The identifier of the new variable - const variableName = this.transformIdentifier(element.name as ts.Identifier); - // The field to extract - const propertyName = this.transformPropertyName(element.propertyName || element.name); - const expression = isObjectBindingPattern - ? tstl.createTableIndexExpression(tableExpression, propertyName) - : tstl.createTableIndexExpression(tableExpression, tstl.createNumericLiteral(index + 1)); - result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); - if (element.initializer) { - const identifier = this.addExportToIdentifier(variableName); - result.push( - tstl.createIfStatement( - tstl.createBinaryExpression( - identifier, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ), - tstl.createBlock([ - tstl.createAssignmentStatement( - identifier, - this.transformExpression(element.initializer) - ), - ]) - ) - ); - } + expression = this.transformLuaLibFunction( + LuaLibFeature.ArraySlice, + undefined, + tableExpression, + tstl.createNumericLiteral(index) + ); } + } else { + expression = tstl.createTableIndexExpression( + tableExpression, + isObjectBindingPattern ? propertyName : tstl.createNumericLiteral(index + 1) + ); + } + + result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); + if (element.initializer) { + const identifier = this.addExportToIdentifier(variableName); + result.push( + tstl.createIfStatement( + tstl.createBinaryExpression( + identifier, + tstl.createNilLiteral(), + tstl.SyntaxKind.EqualityOperator + ), + tstl.createBlock([ + tstl.createAssignmentStatement(identifier, this.transformExpression(element.initializer)), + ]) + ) + ); } } propertyAccessStack.pop(); @@ -1990,17 +2020,15 @@ export class LuaTransformer { } } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { // Destructuring types - const statements: tstl.Statement[] = []; - // For nested bindings and object bindings, fall back to transformBindingPattern + // For object, nested, omitted or rest bindings fall back to transformBindingPattern if ( ts.isObjectBindingPattern(statement.name) || statement.name.elements.some( - elem => (!ts.isBindingElement(elem) || !ts.isIdentifier(elem.name)) && !ts.isOmittedExpression(elem) + e => ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken) ) ) { - const statements = []; let table: tstl.Identifier; if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { table = this.transformIdentifier(statement.initializer); @@ -2022,17 +2050,6 @@ export class LuaTransformer { return statements; } - // Disallow ellipsis destruction - if ( - statement.name.elements.some( - elem => - (!ts.isBindingElement(elem) || elem.dotDotDotToken !== undefined) && - !ts.isOmittedExpression(elem) - ) - ) { - throw TSTLErrors.ForbiddenEllipsisDestruction(statement); - } - const vars = statement.name.elements.length > 0 ? this.filterUndefinedAndCast( @@ -3111,67 +3128,49 @@ export class LuaTransformer { this.validateFunctionAssignment(expression.right, rightType, leftType); this.validatePropertyAssignment(expression); - if (tsHelper.isAssignmentPattern(expression.left)) { + if (tsHelper.isDestructuringAssignment(expression)) { // Destructuring assignment - const flattenable = tsHelper.isValidFlattenableDestructuringAssignmentLeftHandSide( - expression as ts.DestructuringAssignment, - this.checker, - this.program - ); - - if (flattenable) { - const expressionType = this.checker.getTypeAtLocation(expression.right); + if ( + ts.isArrayLiteralExpression(expression.left) && + expression.left.elements.every( + e => + (ts.isIdentifier(e) || ts.isPropertyAccessExpression(e) || ts.isElementAccessExpression(e)) && + !tsHelper.isArrayLength(e, this.checker, this.program) + ) + ) { + const rightType = this.checker.getTypeAtLocation(expression.right); let right = this.transformExpression(expression.right); - if ( !tsHelper.isTupleReturnCall(expression.right, this.checker) && - tsHelper.isArrayType(expressionType, this.checker, this.program) + tsHelper.isArrayType(rightType, this.checker, this.program) ) { right = this.createUnpackCall(right, expression.right); } - return this.transformFlattenableDestructuringAssignment( - expression as ts.DestructuringAssignment, - right + const left = this.castElements( + expression.left.elements.map(e => this.transformExpression(e)), + tstl.isAssignmentLeftHandSideExpression ); + + return tstl.createAssignmentStatement(left, right, expression); } let right = this.transformExpression(expression.right); - const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); - if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { right = this.wrapInTable(right); } - const rootDeclaration = tstl.createVariableDeclarationStatement(rootIdentifier, right); - - const statements = this.transformDestructuringAssignment( - expression as ts.DestructuringAssignment, - rootIdentifier - ); - statements.unshift(rootDeclaration); - - return statements; + const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); + return [ + tstl.createVariableDeclarationStatement(rootIdentifier, right), + ...this.transformDestructuringAssignment(expression, rootIdentifier), + ]; } else { // Simple assignment return this.transformAssignment(expression.left, this.transformExpression(expression.right)); } } - protected transformFlattenableDestructuringAssignment( - node: ts.DestructuringAssignment, - right: tstl.Expression | tstl.Expression[] - ): tstl.Statement { - if (ts.isArrayLiteralExpression(node.left)) { - const left: tstl.AssignmentLeftHandSideExpression[] = node.left.elements.map( - element => this.transformExpression(element) as tstl.AssignmentLeftHandSideExpression - ); - return tstl.createAssignmentStatement(left, right, node); - } - - throw TSTLErrors.NonFlattenableDestructure(node); - } - protected transformDestructuringAssignment( node: ts.DestructuringAssignment, root: tstl.Expression @@ -3233,6 +3232,36 @@ export class LuaTransformer { return result; } + protected transformSpreadAssignment( + node: ts.SpreadAssignment, + root: tstl.Expression, + properties: ts.NodeArray + ): tstl.Statement[] { + const usedProperties: tstl.TableFieldExpression[] = []; + // TODO: .flatMap + for (const property of properties) { + if ( + (ts.isShorthandPropertyAssignment(property) || ts.isPropertyAssignment(property)) && + !ts.isComputedPropertyName(property.name) + ) { + const name = ts.isIdentifier(property.name) + ? tstl.createStringLiteral(property.name.text) + : this.transformExpression(property.name); + + usedProperties.push(tstl.createTableFieldExpression(tstl.createBooleanLiteral(true), name)); + } + } + + const extractingExpression = this.transformLuaLibFunction( + LuaLibFeature.ObjectRest, + undefined, + root, + tstl.createTableExpression(usedProperties) + ); + + return [this.transformAssignment(node.expression, extractingExpression)]; + } + protected transformObjectLiteralAssignmentPattern( node: ts.ObjectLiteralExpression, root: tstl.Expression @@ -3248,7 +3277,8 @@ export class LuaTransformer { result.push(...this.transformPropertyAssignment(property, root)); break; case ts.SyntaxKind.SpreadAssignment: - throw TSTLErrors.ForbiddenEllipsisDestruction(property); + result.push(...this.transformSpreadAssignment(property, root, node.properties)); + break; default: throw TSTLErrors.UnsupportedKind("Object Destructure Property", property.kind, property); } @@ -3264,11 +3294,7 @@ export class LuaTransformer { const result: tstl.Statement[] = []; node.elements.forEach((element, index) => { - const indexedRoot = tstl.createTableIndexExpression( - root as tstl.Expression, - tstl.createNumericLiteral(index + 1), - element - ); + const indexedRoot = tstl.createTableIndexExpression(root, tstl.createNumericLiteral(index + 1), element); switch (element.kind) { case ts.SyntaxKind.ObjectLiteralExpression: @@ -3327,6 +3353,18 @@ export class LuaTransformer { result.push(assignmentStatement); break; + case ts.SyntaxKind.SpreadElement: + if (index !== node.elements.length - 1) break; + + const restElements = this.transformLuaLibFunction( + LuaLibFeature.ArraySlice, + undefined, + root, + tstl.createNumericLiteral(index) + ); + + result.push(this.transformAssignment((element as ts.SpreadElement).expression, restElements)); + break; case ts.SyntaxKind.OmittedExpression: break; default: @@ -3353,13 +3391,7 @@ export class LuaTransformer { } } - let leftExpression: ts.Expression; - if (ts.isBinaryExpression(node.initializer)) { - leftExpression = node.initializer.left; - } else { - leftExpression = node.initializer; - } - + const leftExpression = ts.isBinaryExpression(node.initializer) ? node.initializer.left : node.initializer; const variableToExtract = this.transformPropertyName(node.name); const extractingExpression = tstl.createTableIndexExpression(root, variableToExtract); @@ -3406,7 +3438,7 @@ export class LuaTransformer { ); } - if (tsHelper.isAssignmentPattern(expression.left)) { + if (tsHelper.isDestructuringAssignment(expression)) { // Destructuring assignment const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); @@ -3415,13 +3447,10 @@ export class LuaTransformer { right = this.wrapInTable(right); } - const rootDeclaration = tstl.createVariableDeclarationStatement(rootIdentifier, right); - - const statements = this.transformDestructuringAssignment( - expression as ts.DestructuringAssignment, - rootIdentifier - ); - statements.unshift(rootDeclaration); + const statements = [ + tstl.createVariableDeclarationStatement(rootIdentifier, right), + ...this.transformDestructuringAssignment(expression, rootIdentifier), + ]; return this.createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); } @@ -6089,6 +6118,17 @@ export class LuaTransformer { return this.filterUndefined(visitResult); } + public castElements( + items: TOriginal[], + cast: (item: TOriginal) => item is TCast + ): TCast[] { + if (items.every(cast)) { + return items as TCast[]; + } else { + throw TSTLErrors.CouldNotCast(cast.name); + } + } + protected filterUndefined(items: Array): T[] { return items.filter(i => i !== undefined) as T[]; } @@ -6097,12 +6137,7 @@ export class LuaTransformer { items: Array, cast: (item: TOriginal) => item is TCast ): TCast[] { - const filteredItems = items.filter(i => i !== undefined) as TOriginal[]; - if (filteredItems.every(i => cast(i))) { - return filteredItems as TCast[]; - } else { - throw TSTLErrors.CouldNotCast(cast.name); - } + return this.castElements(this.filterUndefined(items), cast); } protected createConstructorDecorationStatement( diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 023a0c0c6..903b7f069 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -60,6 +60,14 @@ export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); } +export function isDestructuringAssignment(node: ts.Node): node is ts.DestructuringAssignment { + return ( + ts.isBinaryExpression(node) && + node.operatorToken.kind === ts.SyntaxKind.EqualsToken && + isAssignmentPattern(node.left) + ); +} + export function getExportable(exportSpecifiers: ts.NamedExports, resolver: EmitResolver): ts.ExportSpecifier[] { return exportSpecifiers.elements.filter(exportSpecifier => resolver.isValueAliasDeclaration(exportSpecifier)); } @@ -400,7 +408,7 @@ export function getCustomNodeDirectives(node: ts.Node): Map(); ts.getJSDocTags(node).forEach(tag => { - const tagName = tag.tagName.escapedText as string; + const tagName = tag.tagName.text; if (Decorator.isValid(tagName)) { const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); directivesMap.set(dec.kind, dec); @@ -908,34 +916,6 @@ export function moduleHasEmittedBody( return false; } -export function isValidFlattenableDestructuringAssignmentLeftHandSide( - node: ts.DestructuringAssignment, - checker: ts.TypeChecker, - program: ts.Program -): boolean { - if (ts.isArrayLiteralExpression(node.left)) { - if (node.left.elements.length > 0) { - return !node.left.elements.some(element => { - switch (element.kind) { - case ts.SyntaxKind.Identifier: - case ts.SyntaxKind.PropertyAccessExpression: - if (isArrayLength(element, checker, program)) { - return true; - } - case ts.SyntaxKind.ElementAccessExpression: - // Can be on the left hand side of a Lua assignment statement - return false; - default: - // Cannot be - return true; - } - }); - } - } - - return false; -} - export function isArrayLength( expression: ts.Expression, checker: ts.TypeChecker, @@ -951,8 +931,10 @@ export function isArrayLength( } const name = ts.isPropertyAccessExpression(expression) - ? (expression.name.escapedText as string) - : ts.isStringLiteral(expression.argumentExpression) && expression.argumentExpression.text; + ? expression.name.text + : ts.isStringLiteral(expression.argumentExpression) + ? expression.argumentExpression.text + : undefined; return name === "length"; } diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 8d9966c0b..b2adf7bfa 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -7,9 +7,6 @@ const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? export const CouldNotCast = (castName: string) => new Error(`Failed to cast all elements to expected type using ${castName}.`); -export const ForbiddenEllipsisDestruction = (node: ts.Node) => - new TranspileError(`Ellipsis destruction is not allowed.`, node); - export const ForbiddenForIn = (node: ts.Node) => new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); diff --git a/src/lualib/ObjectRest.ts b/src/lualib/ObjectRest.ts new file mode 100644 index 000000000..7da14b2fb --- /dev/null +++ b/src/lualib/ObjectRest.ts @@ -0,0 +1,14 @@ +function __TS__ObjectRest( + this: void, + target: Record, + usedProperties: Partial> +): Partial> { + const result: Partial> = {}; + for (const property in target) { + if (!usedProperties[property]) { + result[property] = target[property]; + } + } + + return result; +} diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index b4ae3dd50..35519f299 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -1,6 +1,6 @@ import * as util from "../util"; -const allBindings = "x, y, z"; +const allBindings = "x, y, z, rest"; const testCases = [ { binding: "{ x }", value: { x: true } }, { binding: "{ x, y }", value: { x: false, y: true } }, @@ -9,12 +9,17 @@ const testCases = [ { binding: "{ x, y = true }", value: { x: false, y: false } }, { binding: "{ x = true }", value: {} }, { binding: "{ x, y = true }", value: { x: false } }, + { binding: "{ ...rest }", value: {} }, + { binding: "{ x, ...rest }", value: { x: "x" } }, + { binding: "{ x, ...rest }", value: { x: "x", y: "y", z: "z" } }, { binding: "[]", value: [] }, { binding: "[x, y]", value: ["x", "y"] }, { binding: "[x, , y]", value: ["x", "", "y"] }, { binding: "[x = true]", value: [false] }, { binding: "[[x, y]]", value: [["x", "y"]] }, + { binding: "[x, ...rest]", value: ["x"] }, + { binding: "[x, ...rest]", value: ["x", "y", "z"] }, { binding: "{ y: [z = true] }", value: { y: [false] } }, { binding: "{ x: [x, y] }", value: { x: ["x", "y"] } }, @@ -47,7 +52,8 @@ test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { }); // TODO: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/695 -test.each(testCases.filter(x => x.binding !== "[x, , y]"))( +// TODO: https://github.com/microsoft/TypeScript/issues/32656 +test.each(testCases.filter(x => x.binding !== "[x, , y]" && x.binding !== "{ x, ...rest }"))( "in exported variable declaration (%p)", ({ binding, value }) => { util.testModule` From 1ab86dada123e2024bc14d41f9e1608270a2ca75 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 26 Aug 2019 23:45:50 +1000 Subject: [PATCH 162/764] Fix LuaTable (#702) * Fix LuaTable * Change getLuaTablePropertyName to if/else statements * Use getCustomDecorators for LuaTable * Change LuaTableExpression tableAccessExpression -> leftHandSideExpression * Revert LuaTable ExpressionStatement conditional change * Use luaTable to identify table access expressions * Remove unusable getLuaTablePropertyName Identifier case * Change transformLuaTableProperty flow * Prevent luaTable methods from being isolated * Avoid double transformation in validateLuaTableCall * Remove unnecessary luaTable set expression check and specific exception * Remove two unneeded line changes * Revert "Remove two unneeded line changes" This reverts commit cd5324c776ae7c9512a791f5ad708fe11bc799c5. --- src/LuaTransformer.ts | 107 +++++++++++++------------- src/TSTLErrors.ts | 6 -- test/unit/decorators/luaTable.spec.ts | 46 ++++++++--- 3 files changed, 89 insertions(+), 70 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 9a6367837..e060b6ad3 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2186,13 +2186,7 @@ export class LuaTransformer { const ownerType = this.checker.getTypeAtLocation(expression.expression.expression); const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); if (classDecorators.has(DecoratorKind.LuaTable)) { - this.validateLuaTableCall( - expression as ts.CallExpression & { expression: ts.PropertyAccessExpression }, - true - ); - return this.transformLuaTableExpressionStatement(statement as ts.ExpressionStatement & { - expression: ts.CallExpression; - } & { expression: { expression: ts.PropertyAccessExpression } }); + return this.transformLuaTableExpressionAsExpressionStatement(expression); } } @@ -4283,10 +4277,7 @@ export class LuaTransformer { const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); if (classDecorators.has(DecoratorKind.LuaTable)) { - this.validateLuaTableCall(node as ts.CallExpression & { expression: ts.PropertyAccessExpression }, false); - return this.transformLuaTableCallExpression(node as ts.CallExpression & { - expression: ts.PropertyAccessExpression; - }); + return this.transformLuaTableCallExpression(node); } if (tsHelper.isStringType(ownerType, this.checker, this.program)) { @@ -4370,6 +4361,13 @@ export class LuaTransformer { throw TSTLErrors.InvalidElementCall(node); } + const ownerType = this.checker.getTypeAtLocation(node.expression.expression); + const ownerDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); + + if (ownerDecorators.has(DecoratorKind.LuaTable)) { + return this.transformLuaTableCallExpression(node); + } + const signature = this.checker.getResolvedSignature(node); const signatureDeclaration = signature && signature.getDeclaration(); const parameters = this.transformArguments(node.arguments, signature); @@ -4648,13 +4646,14 @@ export class LuaTransformer { } } - protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { - switch (node.name.text) { + protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.Expression { + const [luaTable, propertyName] = this.parseLuaTableExpression(node); + switch (propertyName) { case "length": - const propertyAccessExpression = this.transformExpression(node.expression); - return tstl.createUnaryExpression(propertyAccessExpression, tstl.SyntaxKind.LengthOperator, node); + const unaryExpression = tstl.createUnaryExpression(luaTable, tstl.SyntaxKind.LengthOperator, node); + return unaryExpression; default: - throw TSTLErrors.UnsupportedProperty("LuaTable", node.name.text, node); + throw TSTLErrors.UnsupportedProperty("LuaTable", propertyName, node); } } @@ -4685,6 +4684,11 @@ export class LuaTransformer { const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); const type = this.checker.getTypeAtLocation(expression.expression); + const decorators = tsHelper.getCustomDecorators(type, this.checker); + if (decorators.has(DecoratorKind.LuaTable)) { + throw TSTLErrors.UnsupportedKind("LuaTable access expression", expression.kind, expression); + } + if ( tsHelper.isNumberType(argumentType, this.checker, this.program) && tsHelper.isStringType(type, this.checker, this.program) @@ -5003,78 +5007,63 @@ export class LuaTransformer { } protected validateLuaTableCall( - expression: ts.CallExpression & { expression: ts.PropertyAccessExpression }, - isWithinExpressionStatement: boolean + methodName: string, + callArguments: ts.NodeArray, + original: ts.Node ): void { - const methodName = expression.expression.name.text; - if (expression.arguments.some(argument => ts.isSpreadElement(argument))) { - throw TSTLErrors.ForbiddenLuaTableUseException("Arguments cannot be spread.", expression); + if (callArguments.some(argument => ts.isSpreadElement(argument))) { + throw TSTLErrors.ForbiddenLuaTableUseException("Arguments cannot be spread.", original); } switch (methodName) { case "get": - if (expression.arguments.length !== 1) { - throw TSTLErrors.ForbiddenLuaTableUseException("One parameter is required for get().", expression); + if (callArguments.length !== 1) { + throw TSTLErrors.ForbiddenLuaTableUseException("One parameter is required for get().", original); } break; case "set": - if (expression.arguments.length !== 2) { - throw TSTLErrors.ForbiddenLuaTableUseException( - "Two parameters are required for set().", - expression - ); - } - if (!isWithinExpressionStatement) { - throw TSTLErrors.ForbiddenLuaTableSetExpression(expression); + if (callArguments.length !== 2) { + throw TSTLErrors.ForbiddenLuaTableUseException("Two parameters are required for set().", original); } break; } } - protected transformLuaTableExpressionStatement( - node: ts.ExpressionStatement & { expression: ts.CallExpression } & { - expression: { expression: ts.PropertyAccessExpression }; - } - ): tstl.VariableDeclarationStatement | tstl.AssignmentStatement { - const methodName = node.expression.expression.name.text; - const signature = this.checker.getResolvedSignature(node.expression); - const tableName = (node.expression.expression.expression as ts.Identifier).text; - const luaTable = tstl.createIdentifier(tableName); - const params = this.transformArguments((node.expression as ts.CallExpression).arguments, signature); + protected transformLuaTableExpressionAsExpressionStatement(expression: ts.CallExpression): tstl.Statement { + const [luaTable, methodName] = this.parseLuaTableExpression(expression.expression); + this.validateLuaTableCall(methodName, expression.arguments, expression); + const signature = this.checker.getResolvedSignature(expression); + const params = this.transformArguments(expression.arguments, signature); switch (methodName) { case "get": return tstl.createVariableDeclarationStatement( - tstl.createAnonymousIdentifier(node.expression), - tstl.createTableIndexExpression(luaTable, params[0], node.expression), - node.expression + tstl.createAnonymousIdentifier(expression), + tstl.createTableIndexExpression(luaTable, params[0], expression), + expression ); case "set": return tstl.createAssignmentStatement( - tstl.createTableIndexExpression(luaTable, params[0], node.expression), + tstl.createTableIndexExpression(luaTable, params[0], expression), params.splice(1), - node.expression + expression ); default: - throw TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", node.expression); + throw TSTLErrors.UnsupportedProperty("LuaTable", methodName, expression); } } - protected transformLuaTableCallExpression( - expression: ts.CallExpression & { expression: ts.PropertyAccessExpression } - ): tstl.Expression { - const method = expression.expression; - const methodName = method.name.text; + protected transformLuaTableCallExpression(expression: ts.CallExpression): tstl.Expression { + const [luaTable, methodName] = this.parseLuaTableExpression(expression.expression); + this.validateLuaTableCall(methodName, expression.arguments, expression); const signature = this.checker.getResolvedSignature(expression); - const tableName = (method.expression as ts.Identifier).text; - const luaTable = tstl.createIdentifier(tableName); const params = this.transformArguments(expression.arguments, signature); switch (methodName) { case "get": return tstl.createTableIndexExpression(luaTable, params[0], expression); default: - throw TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", expression); + throw TSTLErrors.UnsupportedProperty("LuaTable", methodName, expression); } } @@ -5473,6 +5462,14 @@ export class LuaTransformer { return scope; } + protected parseLuaTableExpression(node: ts.LeftHandSideExpression): [tstl.Expression, string] { + if (ts.isPropertyAccessExpression(node)) { + return [this.transformExpression(node.expression), node.name.text]; + } else { + throw TSTLErrors.UnsupportedKind("LuaTable access expression", node.kind, node); + } + } + protected transformLuaLibFunction( func: LuaLibFeature, tsParent?: ts.Expression, diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index b2adf7bfa..7318b9cd0 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -10,12 +10,6 @@ export const CouldNotCast = (castName: string) => export const ForbiddenForIn = (node: ts.Node) => new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); -export const ForbiddenLuaTableSetExpression = (node: ts.Node) => - new TranspileError( - `A '@luaTable' object's 'set()' method can only be used as a Statement, not an Expression.`, - node - ); - export const ForbiddenLuaTableNonDeclaration = (node: ts.Node) => new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); diff --git a/test/unit/decorators/luaTable.spec.ts b/test/unit/decorators/luaTable.spec.ts index 6419cc735..e7559f7c0 100644 --- a/test/unit/decorators/luaTable.spec.ts +++ b/test/unit/decorators/luaTable.spec.ts @@ -1,3 +1,4 @@ +import * as ts from "typescript"; import * as TSTLErrors from "../../../src/TSTLErrors"; import * as util from "../../util"; @@ -34,21 +35,24 @@ test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tab ); }); -test.each([tableLibClass, tableLibInterface])("LuaTable set() cannot be used in an expression position", tableLib => { - expect(() => util.transpileString(tableLib + `const exp = tbl.set("value", 5)`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableSetExpression(util.nodeStub) - ); -}); +test.each([tableLibClass, tableLibInterface])( + "LuaTable set() cannot be used in a LuaTable call expression", + tableLib => { + expect(() => util.transpileString(tableLib + `const exp = tbl.set("value", 5)`)).toThrowExactError( + TSTLErrors.UnsupportedProperty("LuaTable", "set", util.nodeStub) + ); + } +); -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { +test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { expect(() => util.transpileString(tableLib + `tbl.other()`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub) + TSTLErrors.UnsupportedProperty("LuaTable", "other", util.nodeStub) ); }); -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other methods", tableLib => { +test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { expect(() => util.transpileString(tableLib + `let x = tbl.other()`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException("Unsupported method.", util.nodeStub) + TSTLErrors.UnsupportedProperty("LuaTable", "other", util.nodeStub) ); }); @@ -113,12 +117,36 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { }); }); +test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpression on a LuaTable", tableLib => { + test.each([`tbl["get"]("field")`, `tbl["set"]("field")`, `tbl["length"]`])( + "Cannot use ElementAccessExpression on a LuaTable (%p)", + code => { + expect(() => util.transpileString(tableLib + code)).toThrowExactError( + TSTLErrors.UnsupportedKind( + "LuaTable access expression", + ts.SyntaxKind.ElementAccessExpression, + util.nodeStub + ) + ); + } + ); +}); + +test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { + test.each([`set`, `get`])("Cannot isolate LuaTable method (%p)", propertyName => { + expect(() => util.transpileString(`${tableLib} let property = tbl.${propertyName}`)).toThrowExactError( + TSTLErrors.UnsupportedProperty("LuaTable", propertyName, util.nodeStub) + ); + }); +}); + test.each([tableLibClass])("LuaTable functional tests", tableLib => { test.each<[string, any]>([ [`const t = new Table(); t.set("field", "value"); return t.get("field");`, "value"], [`const t = new Table(); t.set("field", 0); return t.get("field");`, 0], [`const t = new Table(); t.set(1, true); return t.length`, 1], [`const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length`, 2], + [`const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);`, 3], ])("LuaTable test (%p)", (code, expectedReturnValue) => { expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); }); From 0c65c0c16ad308355a3537a346c9a4dbdc049613 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 27 Aug 2019 22:07:58 +0200 Subject: [PATCH 163/764] Preserving order in Map and Set using doubly linked lists (#706) * Added order tests * Added key ordering using doubly linked lists for Map and Set * Changed Set constructor to use this.add * Fixed some issues and added tests to catch them * Use luatable instead of hacky objects for Set and Map internal storage * map.has() correctly deal with undefined values * Changed map and set luatype property definitions * Updated lualib LuaTable declaration * Grouped iteration order tests in describe * Used LuaTable for WeakMap and WeakSet --- src/lualib/Map.ts | 92 ++++++++++++++++++++------- src/lualib/Set.ts | 85 ++++++++++++++++++------- src/lualib/WeakMap.ts | 15 ++--- src/lualib/WeakSet.ts | 13 ++-- src/lualib/declarations/luatable.d.ts | 6 ++ test/unit/builtins/map.spec.ts | 87 ++++++++++++++++++++++++- test/unit/builtins/set.spec.ts | 74 +++++++++++++++++++++ 7 files changed, 307 insertions(+), 65 deletions(-) create mode 100644 src/lualib/declarations/luatable.d.ts diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index 57da9d86d..aec325664 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -2,10 +2,15 @@ Map = class Map { public static [Symbol.species] = Map; public [Symbol.toStringTag] = "Map"; - // Type of key is actually K - private items: { [key: string]: V } = {}; + private items = new LuaTable(); public size = 0; + // Key-order variables + private firstKey: K | undefined; + private lastKey: K | undefined; + private nextKey = new LuaTable(); + private previousKey = new LuaTable(); + constructor(entries?: Iterable | Array) { if (entries === undefined) return; @@ -23,15 +28,18 @@ Map = class Map { } } else { const array = entries as Array<[K, V]>; - this.size = array.length; for (const kvp of array) { - this.items[kvp[0] as any] = kvp[1]; + this.set(kvp[0], kvp[1]); } } } public clear(): void { - this.items = {}; + this.items = new LuaTable(); + this.nextKey = new LuaTable(); + this.previousKey = new LuaTable(); + this.firstKey = undefined; + this.lastKey = undefined; this.size = 0; return; } @@ -40,31 +48,64 @@ Map = class Map { const contains = this.has(key); if (contains) { this.size--; + + // Do order bookkeeping + const next = this.nextKey.get(key); + const previous = this.previousKey.get(key); + if (next && previous) { + this.nextKey.set(previous, next); + this.previousKey.set(next, previous); + } else if (next) { + this.firstKey = next; + this.previousKey.set(next, undefined); + } else if (previous) { + this.lastKey = previous; + this.nextKey.set(previous, undefined); + } else { + this.firstKey = undefined; + this.lastKey = undefined; + } + + this.nextKey.set(key, undefined); + this.previousKey.set(key, undefined); } - this.items[key as any] = undefined; + this.items.set(key, undefined); + return contains; } public forEach(callback: (value: V, key: K, map: Map) => any): void { - for (const key in this.items) { - callback(this.items[key], key as any, this); + for (const key of this.keys()) { + callback(this.items.get(key), key, this); } return; } public get(key: K): V | undefined { - return this.items[key as any]; + return this.items.get(key); } public has(key: K): boolean { - return this.items[key as any] !== undefined; + return this.nextKey.get(key) !== undefined || this.lastKey === key; } public set(key: K, value: V): this { - if (!this.has(key)) { + const isNewValue = !this.has(key); + if (isNewValue) { this.size++; } - this.items[key as any] = value; + this.items.set(key, value); + + // Do order bookkeeping + if (this.firstKey === undefined) { + this.firstKey = key; + this.lastKey = key; + } else if (isNewValue) { + this.nextKey.set(this.lastKey, key); + this.previousKey.set(key, this.lastKey); + this.lastKey = key; + } + return this; } @@ -74,44 +115,47 @@ Map = class Map { public entries(): IterableIterator<[K, V]> { const items = this.items; - let key: K; - let value: V; + const nextKey = this.nextKey; + let key = this.firstKey; return { [Symbol.iterator](): IterableIterator<[K, V]> { return this; }, next(): IteratorResult<[K, V]> { - [key, value] = next(items, key); - return { done: !key, value: [key, value] }; + const result = { done: !key, value: [key, items.get(key)] as [K, V] }; + key = nextKey.get(key); + return result; }, }; } public keys(): IterableIterator { - const items = this.items; - let key: K; + const nextKey = this.nextKey; + let key = this.firstKey; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - [key] = next(items, key); - return { done: !key, value: key }; + const result = { done: !key, value: key }; + key = nextKey.get(key); + return result; }, }; } public values(): IterableIterator { const items = this.items; - let key: K; - let value: V; + const nextKey = this.nextKey; + let key = this.firstKey; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - [key, value] = next(items, key); - return { done: !key, value }; + const result = { done: !key, value: items.get(key) }; + key = nextKey.get(key); + return result; }, }; } diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index 238843d8c..6dcbcac8b 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -2,10 +2,13 @@ Set = class Set { public static [Symbol.species] = Set; public [Symbol.toStringTag] = "Set"; - // Key type is actually T - private items: { [key: string]: boolean } = {}; public size = 0; + private firstKey: T | undefined; + private lastKey: T | undefined; + private nextKey = new LuaTable(); + private previousKey = new LuaTable(); + constructor(values?: Iterable | T[]) { if (values === undefined) return; @@ -22,23 +25,36 @@ Set = class Set { } } else { const array = values as T[]; - this.size = array.length; for (const value of array) { - this.items[value as any] = true; + this.add(value); } } } public add(value: T): Set { - if (!this.has(value)) { + const isNewValue = !this.has(value); + if (isNewValue) { this.size++; } - this.items[value as any] = true; + + // Do order bookkeeping + if (this.firstKey === undefined) { + this.firstKey = value; + this.lastKey = value; + } else if (isNewValue) { + this.nextKey.set(this.lastKey, value); + this.previousKey.set(value, this.lastKey); + this.lastKey = value; + } + return this; } public clear(): void { - this.items = {}; + this.nextKey = new LuaTable(); + this.previousKey = new LuaTable(); + this.firstKey = undefined; + this.lastKey = undefined; this.size = 0; return; } @@ -47,19 +63,39 @@ Set = class Set { const contains = this.has(value); if (contains) { this.size--; + + // Do order bookkeeping + const next = this.nextKey.get(value); + const previous = this.previousKey.get(value); + if (next && previous) { + this.nextKey.set(previous, next); + this.previousKey.set(next, previous); + } else if (next) { + this.firstKey = next; + this.previousKey.set(next, undefined); + } else if (previous) { + this.lastKey = previous; + this.nextKey.set(previous, undefined); + } else { + this.firstKey = undefined; + this.lastKey = undefined; + } + + this.nextKey.set(value, undefined); + this.previousKey.set(value, undefined); } - this.items[value as any] = undefined; + return contains; } public forEach(callback: (value: T, key: T, set: Set) => any): void { - for (const key in this.items) { - callback(key as any, key as any, this); + for (const key of this.keys()) { + callback(key, key, this); } } public has(value: T): boolean { - return this.items[value as any] === true; + return this.nextKey.get(value) !== undefined || this.lastKey === value; } public [Symbol.iterator](): IterableIterator { @@ -67,43 +103,46 @@ Set = class Set { } public entries(): IterableIterator<[T, T]> { - const items = this.items; - let key: T; + const nextKey = this.nextKey; + let key: T = this.firstKey; return { [Symbol.iterator](): IterableIterator<[T, T]> { return this; }, next(): IteratorResult<[T, T]> { - [key] = next(items, key); - return { done: !key, value: [key, key] }; + const result = { done: !key, value: [key, key] as [T, T] }; + key = nextKey.get(key); + return result; }, }; } public keys(): IterableIterator { - const items = this.items; - let key: T; + const nextKey = this.nextKey; + let key: T = this.firstKey; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - [key] = next(items, key); - return { done: !key, value: key }; + const result = { done: !key, value: key }; + key = nextKey.get(key); + return result; }, }; } public values(): IterableIterator { - const items = this.items; - let key: T; + const nextKey = this.nextKey; + let key: T = this.firstKey; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - [key] = next(items, key); - return { done: !key, value: key }; + const result = { done: !key, value: key }; + key = nextKey.get(key); + return result; }, }; } diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index cf93e3421..169ad7ded 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -2,8 +2,7 @@ WeakMap = class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; - // Type of key is actually K - private items: { [key: string]: V } = {}; + private items = new LuaTable(); constructor(entries?: Iterable | Array) { setmetatable(this.items, { __mode: "k" }); @@ -19,31 +18,31 @@ WeakMap = class WeakMap { break; } const value: [K, V] = result.value; // Ensures index is offset when tuple is accessed - this.set(value[0], value[1]); + this.items.set(value[0], value[1]); } } else { for (const kvp of entries as Array<[K, V]>) { - this.items[kvp[0] as any] = kvp[1]; + this.items.set(kvp[0], kvp[1]); } } } public delete(key: K): boolean { const contains = this.has(key); - this.items[key as any] = undefined; + this.items.set(key, undefined); return contains; } public get(key: K): V | undefined { - return this.items[key as any]; + return this.items.get(key); } public has(key: K): boolean { - return this.items[key as any] !== undefined; + return this.items.get(key) !== undefined; } public set(key: K, value: V): this { - this.items[key as any] = value; + this.items.set(key, value); return this; } }; diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index 80b3ffda1..ebc950a5a 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -2,8 +2,7 @@ WeakSet = class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; - // Key type is actually T - private items: { [key: string]: boolean } = {}; + private items = new LuaTable(); constructor(values?: Iterable | T[]) { setmetatable(this.items, { __mode: "k" }); @@ -18,27 +17,27 @@ WeakSet = class WeakSet { if (result.done) { break; } - this.add(result.value); + this.items.set(result.value, true); } } else { for (const value of values as T[]) { - this.items[value as any] = true; + this.items.set(value, true); } } } public add(value: T): this { - this.items[value as any] = true; + this.items.set(value, true); return this; } public delete(value: T): boolean { const contains = this.has(value); - this.items[value as any] = undefined; + this.items.set(value, undefined); return contains; } public has(value: T): boolean { - return this.items[value as any] === true; + return this.items.get(value) === true; } }; diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts new file mode 100644 index 000000000..63805d283 --- /dev/null +++ b/src/lualib/declarations/luatable.d.ts @@ -0,0 +1,6 @@ +/** @LuaTable */ +declare class LuaTable { + public readonly length: number; + public set(key: K, value: V | undefined): void; + public get(key: K): V | undefined; +} diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index fc989628c..cc5d1eb9c 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -92,9 +92,28 @@ test("map has false", () => { expect(contains).toBe(false); }); -test("map has null", () => { - const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has(null);`); - expect(contains).toBe(false); +test.each([ + `[["a", null]]`, + `[["b", "c"], ["a", null]]`, + `[["a", null], ["b", "c"]]`, + `[["b", "c"], ["a", null], ["x", "y"]]`, +])("map (%p) has null", entries => { + util.testFunction` + let mymap = new Map(${entries}); + return mymap.has("a"); + `.expectToMatchJsResult(); +}); + +test.each([ + `[["a", undefined]]`, + `[["b", "c"], ["a", undefined]]`, + `[["a", undefined], ["b", "c"]]`, + `[["b", "c"], ["a", undefined], ["x", "y"]]`, +])("map (%p) has undefined", entries => { + util.testFunction` + let mymap = new Map(${entries}); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test("map keys", () => { @@ -135,3 +154,65 @@ test("map size", () => { expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`)).toBe(0); expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`)).toBe(1); }); + +const iterationMethods = ["entries", "keys", "values"]; +describe.each(iterationMethods)("map.%s() preserves insertion order", iterationMethod => { + test("basic", () => { + util.testFunction` + const mymap = new Map(); + + mymap.set("x", 1); + mymap.set("a", 2); + mymap.set(4, 3); + mymap.set("b", 6); + mymap.set(1, 4); + mymap.set("a", 5); + + mymap.delete("b"); + + return [...mymap.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing last", () => { + util.testFunction` + const mymap = new Map(); + + mymap.set("x", 1); + mymap.set("a", 2); + mymap.set(4, 3); + + mymap.delete(4); + + return [...mymap.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing first", () => { + util.testFunction` + const mymap = new Map(); + + mymap.set("x", 1); + mymap.set("a", 2); + mymap.set(4, 3); + + mymap.delete("x"); + + return [...mymap.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing all", () => { + util.testFunction` + const mymap = new Map(); + + mymap.set("x", 1); + mymap.set("a", 2); + + mymap.delete("a"); + mymap.delete("x"); + + return [...mymap.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index bac8773f8..c2e2fe433 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -79,6 +79,18 @@ test("set has", () => { `.expectToMatchJsResult(); }); +test("set has after deleting keys", () => { + util.testFunction` + let myset = new Set(["a", "c"]); + const results = [myset.has("c")]; + myset.delete("c"); + results.push(myset.has("c")); + myset.delete("a"); + results.push(myset.has("a")) + return results; + `.expectToMatchJsResult(); +}); + test("set has false", () => { util.testFunction` let myset = new Set(); @@ -120,3 +132,65 @@ test.each([ ])("set size (%p)", code => { util.testFunction`${code}; return m.size`.expectToMatchJsResult(); }); + +const iterationMethods = ["entries", "keys", "values"]; +describe.each(iterationMethods)("set.%s() preserves insertion order", iterationMethod => { + test("basic", () => { + util.testFunction` + const myset = new Set(); + + myset.add("x"); + myset.add("a"); + myset.add(4); + myset.add("b"); + myset.add(1); + myset.add("a"); + + myset.delete("b"); + + return [...myset.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing last", () => { + util.testFunction` + const myset = new Set(); + + myset.add("x"); + myset.add("a"); + myset.add(4); + + myset.delete(4); + + return [...myset.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing first", () => { + util.testFunction` + const myset = new Set(); + + myset.add("x"); + myset.add("a"); + myset.add(4); + + myset.delete("x"); + + return [...myset.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); + + test("after removing all", () => { + util.testFunction` + const myset = new Set(); + + myset.add("x"); + myset.add("a"); + + myset.delete("a"); + myset.delete("x"); + + return [...myset.${iterationMethod}()]; + `.expectToMatchJsResult(); + }); +}); From cd9f03294045729cf17b7bc768188678f8754592 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 1 Sep 2019 13:31:22 +0200 Subject: [PATCH 164/764] Fix broken for-in declaration (#711) * Fix busted for-in declaration * Fixed scoping issue once the for-in loop is finished * replaced splice with unshift Co-Authored-By: ark120202 --- src/LuaTransformer.ts | 29 ++++++++++++++++++++++++----- src/TSTLErrors.ts | 3 +++ test/unit/loops.spec.ts | 24 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e060b6ad3..3c9fb2c89 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -2628,10 +2628,6 @@ export class LuaTransformer { } public transformForInStatement(statement: ts.ForInStatement): StatementVisitResult { - // Get variable identifier - const variable = (statement.initializer as ts.VariableDeclarationList).declarations[0]; - const identifier = variable.name as ts.Identifier; - // Transpile expression const pairsIdentifier = tstl.createIdentifier("pairs"); const expression = this.transformExpression(statement.expression); @@ -2643,7 +2639,30 @@ export class LuaTransformer { const body = tstl.createBlock(this.transformLoopBody(statement)); - return tstl.createForInStatement(body, [this.transformIdentifier(identifier)], [pairsCall], statement); + // Transform iteration variable + // TODO: After the transformation pipeline refactor we should look at refactoring this together with the + // for-of initializer transformation. + let iterationVariable: tstl.Identifier; + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { + iterationVariable = this.transformIdentifier(statement.initializer.declarations[0].name); + } else if (ts.isIdentifier(statement.initializer)) { + // Iteration variable becomes ____key + iterationVariable = tstl.createIdentifier("____key"); + // Push variable = ____key to the start of the loop body to match TS scoping + const initializer = tstl.createAssignmentStatement( + this.transformIdentifier(statement.initializer), + iterationVariable + ); + body.statements.unshift(initializer); + } else { + // This should never occur + throw TSTLErrors.UnsupportedForInVariable(statement.initializer); + } + + return tstl.createForInStatement(body, [iterationVariable], [pairsCall], statement); } public transformSwitchStatement(statement: ts.SwitchStatement): StatementVisitResult { diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 7318b9cd0..89867e01d 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -77,6 +77,9 @@ export const NonFlattenableDestructure = (node: ts.Node) => export const UndefinedFunctionDefinition = (functionSymbolId: number) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); +export const UnsupportedForInVariable = (initializer: ts.Node) => + new TranspileError(`Unsuppored for-in variable kind.`, initializer); + export const UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); export const UndefinedTypeNode = (node: ts.Node) => new TranspileError("Failed to resolve required type node.", node); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 34e92998a..4d50dca20 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -630,3 +630,27 @@ test("do...while double-negation", () => { expect(util.transpileString(code)).not.toMatch("not"); expect(util.transpileAndExecute(code)).toBe(2); }); + +test("for...in with pre-defined variable", () => { + util.testFunction` + const obj = { x: "y", foo: "bar" }; + + let x = ""; + let result = []; + for (x in obj) { + result.push(x); + } + return result; + `.expectToMatchJsResult(); +}); + +test("for...in with pre-defined variable keeps last value", () => { + util.testFunction` + const obj = { x: "y", foo: "bar" }; + + let x = ""; + for (x in obj) { + } + return x; + `.expectToMatchJsResult(); +}); From 12b1f2d0a8766aa97e07d441ea3751a6a44fc5f5 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Sep 2019 14:44:54 +0200 Subject: [PATCH 165/764] 0.27.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 46b514743..422b0e16b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.26.0", + "version": "0.27.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3788a172e..d85d96972 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.26.0", + "version": "0.27.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From c2743a57cdb7291c4c4911291ff4cd71d99a504d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 1 Sep 2019 16:58:46 +0200 Subject: [PATCH 166/764] Update CHANGELOG.md 0.27.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b5af657c..60f6f6932 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 0.27.0 + +- Added support for [Spread Assignment](https://basarat.gitbooks.io/typescript/content/docs/spread-operator.html) statements. +- Changed Map and Set implementations to they preserve insertion order when iterated over, as specified by ECMAScript. + +- Fixed an issue with [/** @luaTable */](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luaTable) variable names disappearing. +- Fixed for-in loops throwing an error when using a pre-defined variable. +- Fixed issue with initialization order of class properties. + +- Simplified enum transformation code. + ## 0.26.0 - Added support for [default exports and export equals statements](https://github.com/Microsoft/TypeScript/issues/7185#issuecomment-421632656). From 4cc402bc29c98925f7f01d42037487739d189091 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Sep 2019 17:18:25 +0200 Subject: [PATCH 167/764] Fixed changelog formatting --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 60f6f6932..e2e8fcc84 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,10 @@ ## 0.27.0 -- Added support for [Spread Assignment](https://basarat.gitbooks.io/typescript/content/docs/spread-operator.html) statements. +- Added support for [Array Spread assignment and Object Spread assignment](https://basarat.gitbooks.io/typescript/content/docs/spread-operator.html) statements. - Changed Map and Set implementations to they preserve insertion order when iterated over, as specified by ECMAScript. -- Fixed an issue with [/** @luaTable */](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luaTable) variable names disappearing. +- Fixed an issue with [`/** @luaTable */`](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luaTable) variable names disappearing. - Fixed for-in loops throwing an error when using a pre-defined variable. - Fixed issue with initialization order of class properties. From 61cc717f254573352e51ee99101902f453e2c494 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Sep 2019 17:34:17 +0200 Subject: [PATCH 168/764] Corrected incorrect spread changelog item --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2e8fcc84..a0dab5e74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.27.0 -- Added support for [Array Spread assignment and Object Spread assignment](https://basarat.gitbooks.io/typescript/content/docs/spread-operator.html) statements. +- Added support for [array and object destructuring with rest](https://basarat.gitbooks.io/typescript/content/docs/destructuring.html#object-destructuring-with-rest). - Changed Map and Set implementations to they preserve insertion order when iterated over, as specified by ECMAScript. - Fixed an issue with [`/** @luaTable */`](https://github.com/TypeScriptToLua/TypeScriptToLua/wiki/Compiler-Directives#luaTable) variable names disappearing. From c7b1b25f005ecfefcb50fcb22f43fab4f5968ae1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 2 Sep 2019 15:21:44 +0200 Subject: [PATCH 169/764] lock TS dependency to 3.5.x for now --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d85d96972..a2d06c61c 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "dependencies": { "resolve": "^1.11.0", "source-map": "^0.7.3", - "typescript": "^3.5.2" + "typescript": "3.5.x" }, "devDependencies": { "@types/glob": "^7.1.1", From f54cdef77e512a9dcd79c528aef6523865f76f69 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 2 Sep 2019 15:23:26 +0200 Subject: [PATCH 170/764] 0.27.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 422b0e16b..7837795a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.27.0", + "version": "0.27.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a2d06c61c..13ae2cce3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.27.0", + "version": "0.27.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 20a5d92f97757773b6600505576b227929c33101 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Tue, 3 Sep 2019 19:31:36 +0200 Subject: [PATCH 171/764] Add parentheses to ternary conditional (#715) * add broken ternary test case * add parentheses to ternary condition --- src/LuaTransformer.ts | 4 ++-- test/unit/conditionals.spec.ts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 3c9fb2c89..386139c39 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -3829,7 +3829,7 @@ export class LuaTransformer { } protected transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { - const condition = this.transformExpression(expression.condition); + const condition = tstl.createParenthesizedExpression(this.transformExpression(expression.condition)); const val1 = this.transformExpression(expression.whenTrue); const val2 = this.transformExpression(expression.whenFalse); @@ -3847,7 +3847,7 @@ export class LuaTransformer { if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { return this.transformProtectedConditionalExpression(expression); } - const condition = this.transformExpression(expression.condition); + const condition = tstl.createParenthesizedExpression(this.transformExpression(expression.condition)); const val1 = this.transformExpression(expression.whenTrue); const val2 = this.transformExpression(expression.whenFalse); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index d5bc14792..a359535bb 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -288,6 +288,10 @@ test.each([ { input: "false ? 'a' : 'b'" }, { input: "true ? false : true" }, { input: "false ? false : true" }, + { input: "true || true ? 'a' : 'b'" }, + { input: "true || false ? 'a' : 'b'" }, + { input: "false || true ? 'a' : 'b'" }, + { input: "false || false ? 'a' : 'b'" }, { input: "true ? literalValue : true" }, { input: "true ? variableValue : true" }, { input: "true ? maybeUndefinedValue : true" }, From 57350934c617a79ee10b25560f0fa74dcac7153e Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 10 Sep 2019 17:05:07 +0500 Subject: [PATCH 172/764] Upgrade TypeScript to v3.6 (#714) * Upgrade TypeScript to v3.6 * Add explicit reference to typescript-internal file * Include main project in test config includes * Exclude lualib from test tsconfig * Add noSelfInFile with other annotations test --- package-lock.json | 6 ++-- package.json | 6 ++-- src/LuaTransformer.ts | 2 +- src/TSHelper.ts | 21 +++++++++++-- src/index.ts | 2 +- src/typescript-internal.ts | 7 +++++ test/tsconfig.json | 10 ++++++- test/unit/decorators/luaIterator.spec.ts | 30 ++++++++++++------- .../functionExpressionTypeInference.spec.ts | 11 +++++++ test/unit/loops.spec.ts | 6 ++-- test/unit/tshelper.spec.ts | 7 +++-- 11 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 src/typescript-internal.ts diff --git a/package-lock.json b/package-lock.json index 7837795a6..8b6468a77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5179,9 +5179,9 @@ } }, "typescript": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", - "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==" + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz", + "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==" }, "uglify-js": { "version": "3.6.0", diff --git a/package.json b/package.json index 13ae2cce3..768745cb9 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc -p tsconfig.json && npm run build-lualib", - "build-lualib": "ts-node ./build_lualib.ts", - "pretest": "npm run lint && ts-node --transpile-only ./build_lualib.ts", + "build-lualib": "ts-node --files ./build_lualib.ts", + "pretest": "npm run lint && ts-node --files --transpile-only ./build_lualib.ts", "test": "jest", "lint": "npm run lint:tslint && npm run lint:prettier", "lint:prettier": "prettier --check \"**/*.{js,ts,yml,json,md}\" || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", @@ -41,7 +41,7 @@ "dependencies": { "resolve": "^1.11.0", "source-map": "^0.7.3", - "typescript": "3.5.x" + "typescript": "^3.6.2" }, "devDependencies": { "@types/glob": "^7.1.1", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 386139c39..43111e5d1 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4458,7 +4458,7 @@ export class LuaTransformer { } protected transformArguments( - params: ts.NodeArray | ts.Expression[], + params: readonly ts.Expression[], sig?: ts.Signature, context?: T ): tstl.Expression[] { diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 903b7f069..c68c07298 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -404,7 +404,7 @@ export function getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map return decMap; } -export function getCustomNodeDirectives(node: ts.Node): Map { +function getCustomNodeDirectives(node: ts.Node): Map { const directivesMap = new Map(); ts.getJSDocTags(node).forEach(tag => { @@ -419,10 +419,25 @@ export function getCustomNodeDirectives(node: ts.Node): Map { + const directivesMap = new Map(); + if (file.statements.length > 0) { - return getCustomNodeDirectives(file.statements[0]); + // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment + const jsDoc = file.statements[0].jsDoc; + if (jsDoc) { + // TODO(refactor): flatMap + const tags = jsDoc.reduce((acc, x) => [...acc, ...(x.tags || [])], []); + tags.forEach(tag => { + const tagName = tag.tagName.text; + if (Decorator.isValid(tagName)) { + const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); + directivesMap.set(dec.kind, dec); + } + }); + } } - return new Map(); + + return directivesMap; } export function getCustomSignatureDirectives( diff --git a/src/index.ts b/src/index.ts index 4da0e6639..17226cf7f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,10 +7,10 @@ import { emitTranspiledFiles, OutputFile } from "./Emit"; import { transpile, TranspiledFile, TranspileResult } from "./Transpile"; export { + createDiagnosticReporter, parseCommandLine, ParsedCommandLine, updateParsedConfigFile, - createDiagnosticReporter, } from "./CommandLineParser"; export * from "./CompilerOptions"; export * from "./Emit"; diff --git a/src/typescript-internal.ts b/src/typescript-internal.ts new file mode 100644 index 000000000..ddff96eaf --- /dev/null +++ b/src/typescript-internal.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; + +declare module "typescript" { + interface Statement { + jsDoc?: ts.JSDoc[]; + } +} diff --git a/test/tsconfig.json b/test/tsconfig.json index 700c9d291..63542f392 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -13,5 +13,13 @@ "noEmit": true, "module": "commonjs" }, - "exclude": ["translation/transformation", "cli/errors", "cli/watch", "transpile/directories", "transpile/outFile"] + "include": [".", "../src"], + "exclude": [ + "translation/transformation", + "cli/errors", + "cli/watch", + "transpile/directories", + "transpile/outFile", + "../src/lualib" + ] } diff --git a/test/unit/decorators/luaIterator.spec.ts b/test/unit/decorators/luaIterator.spec.ts index 5aa24d8ae..6f25320d7 100644 --- a/test/unit/decorators/luaIterator.spec.ts +++ b/test/unit/decorators/luaIterator.spec.ts @@ -119,8 +119,10 @@ test("forof lua iterator destructuring with existing variables", () => { test("forof lua iterator tuple-return", () => { const code = ` const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} function luaIter(): Iter { let i = 0; @@ -144,8 +146,10 @@ test("forof lua iterator tuple-return", () => { test("forof lua iterator tuple-return with existing variables", () => { const code = ` const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} function luaIter(): Iter { let i = 0; @@ -170,8 +174,10 @@ test("forof lua iterator tuple-return with existing variables", () => { test("forof lua iterator tuple-return single variable", () => { const code = ` - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} declare function luaIter(): Iter; for (let x of luaIter()) {} @@ -188,8 +194,10 @@ test("forof lua iterator tuple-return single variable", () => { test("forof lua iterator tuple-return single existing variable", () => { const code = ` - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} declare function luaIter(): Iter; let x: [string, string]; @@ -235,8 +243,10 @@ test("forof forwarded lua iterator", () => { test("forof forwarded lua iterator with tupleReturn", () => { const code = ` const arr = ["a", "b", "c"]; - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} function luaIter(): Iter { let i = 0; diff --git a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts index 767fe0b30..e475f2216 100644 --- a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -16,6 +16,17 @@ test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", no expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); }); +test("noSelfInFile works when first statement has other annotations", () => { + util.testModule` + /** @noSelfInFile */ + + /** @internal */ + function foo() {} + + const test: (this: void) => void = foo; + `.expectToHaveNoDiagnostics(); +}); + test.each(["(this: void, s: string) => string", "(this: any, s: string) => string", "(s: string) => string"])( "Function expression type inference in binary operator (%p)", funcType => { diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 4d50dca20..5e137bdc5 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -547,8 +547,10 @@ describe("for...of empty destructuring", () => { test("luaIterator+tupleReturn", () => { const code = ` const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; - /** @luaIterator */ - /** @tupleReturn */ + /** + * @luaIterator + * @tupleReturn + */ interface Iter extends Iterable<[string, string]> {} function luaIter(): Iter { let it = 0; diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts index 7202ff2e4..6cc1a809b 100644 --- a/test/unit/tshelper.spec.ts +++ b/test/unit/tshelper.spec.ts @@ -114,9 +114,10 @@ test("GetCustomDecorators multiple jsdoc", () => { test("GetCustomDecorators multiple default jsdoc", () => { const source = ` /** - * @description abc - * @phantom - * @compileMembersOnly */ + * @description abc + * @phantom + * @compileMembersOnly + */ enum TestEnum { val1 = 0, val2 = 2, From c1e77c9ee56889a751a50f827a442ba6ffe18713 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Tue, 1 Oct 2019 05:51:27 +1000 Subject: [PATCH 173/764] No self option (#718) * Implement noSelf option * Test noSelf option * Fix noSelf to follow only noSelfInFile behaviour * Use NotEmittedStatement * Use expectToBeDefined * Neaten up noSelf test names * Correct new transformer structure * Avoid using legacy test utils * Fix noSelfOption testFunction indenting * Update src/NoSelfTransformer.ts Co-Authored-By: ark120202 * Tidy up tests * Add more detailed comment about noSelf to TSHelper * Rename noSelf option to noImplicitSelf * Update TSHelper noImplicitSelf comment * Update noImplicitSelf help description * Update TSHelper noImplicitSelf comment --- src/CommandLineParser.ts | 5 +++ src/CompilerOptions.ts | 1 + src/LuaTransformer.ts | 22 +++++----- src/NoImplicitSelfTransformer.ts | 10 +++++ src/TSHelper.ts | 21 +++++++--- src/TSTransformers.ts | 17 ++++++-- .../functions/noImplicitSelfOption.spec.ts | 40 +++++++++++++++++++ 7 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 src/NoImplicitSelfTransformer.ts create mode 100644 test/unit/functions/noImplicitSelfOption.spec.ts diff --git a/src/CommandLineParser.ts b/src/CommandLineParser.ts index fdb3fa573..d657e0127 100644 --- a/src/CommandLineParser.ts +++ b/src/CommandLineParser.ts @@ -38,6 +38,11 @@ const optionDeclarations: CommandLineOption[] = [ type: "enum", choices: Object.values(LuaTarget), }, + { + name: "noImplicitSelf", + description: 'If "this" is implicitly considered an any type, do not generate a self parameter.', + type: "boolean", + }, { name: "noHeader", description: "Specify if a header will be added to compiled files.", diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index ca09566d0..f7c5999c5 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -18,6 +18,7 @@ export interface TransformerImport { } export type CompilerOptions = OmitIndexSignature & { + noImplicitSelf?: boolean; noHeader?: boolean; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 43111e5d1..fcb8c4cd0 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -1393,7 +1393,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(node); const context = - tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void + tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void ? this.createSelfIdentifier() : undefined; const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); @@ -1942,7 +1942,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(functionDeclaration); const context = - tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void + tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void ? this.createSelfIdentifier() : undefined; const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); @@ -4017,7 +4017,7 @@ export class LuaTransformer { const type = this.checker.getTypeAtLocation(node); let context: tstl.Identifier | undefined; - if (tsHelper.getFunctionContextType(type, this.checker) !== tsHelper.ContextType.Void) { + if (tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void) { if (ts.isArrowFunction(node)) { // dummy context for arrow functions with parameters if (node.parameters.length > 0) { @@ -4215,7 +4215,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); if ( signatureDeclaration && - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) === tsHelper.ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.program) === tsHelper.ContextType.Void ) { parameters = this.transformArguments(expression.arguments, signature); } else { @@ -4353,7 +4353,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); if ( !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void ) { // table:name() return this.transformContextualCallExpression(node, parameters); @@ -4392,7 +4392,7 @@ export class LuaTransformer { const parameters = this.transformArguments(node.arguments, signature); if ( !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void + tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void ) { // A contextual parameter must be given to this call expression return this.transformContextualCallExpression(node, parameters); @@ -5152,7 +5152,7 @@ export class LuaTransformer { protected transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { const expression = node.expression as ts.PropertyAccessExpression; const callerType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.getFunctionContextType(callerType, this.checker) === tsHelper.ContextType.Void) { + if (tsHelper.getFunctionContextType(callerType, this.program) === tsHelper.ContextType.Void) { throw TSTLErrors.UnsupportedSelfFunctionConversion(node); } const signature = this.checker.getResolvedSignature(node); @@ -5278,7 +5278,7 @@ export class LuaTransformer { const signatureDeclaration = signature && signature.getDeclaration(); const useSelfParameter = signatureDeclaration && - tsHelper.getDeclarationContextType(signatureDeclaration, this.checker) !== tsHelper.ContextType.Void; + tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void; // Argument evaluation. const callArguments = this.transformArguments(expressions, signature); @@ -5690,8 +5690,8 @@ export class LuaTransformer { fromTypeCache.add(toType); // Check function assignments - const fromContext = tsHelper.getFunctionContextType(fromType, this.checker); - const toContext = tsHelper.getFunctionContextType(toType, this.checker); + const fromContext = tsHelper.getFunctionContextType(fromType, this.program); + const toContext = tsHelper.getFunctionContextType(toType, this.program); if (fromContext === tsHelper.ContextType.Mixed || toContext === tsHelper.ContextType.Mixed) { throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); @@ -6172,7 +6172,7 @@ export class LuaTransformer { const decoratorExpressions = decorators.map(decorator => { const expression = decorator.expression; const type = this.checker.getTypeAtLocation(expression); - const context = tsHelper.getFunctionContextType(type, this.checker); + const context = tsHelper.getFunctionContextType(type, this.program); if (context === tsHelper.ContextType.Void) { throw TSTLErrors.InvalidDecoratorContext(decorator); } diff --git a/src/NoImplicitSelfTransformer.ts b/src/NoImplicitSelfTransformer.ts new file mode 100644 index 000000000..1b77c4070 --- /dev/null +++ b/src/NoImplicitSelfTransformer.ts @@ -0,0 +1,10 @@ +import * as ts from "typescript"; + +const transformSourceFile: ts.Transformer = node => { + const empty = ts.createNotEmittedStatement(undefined!); + ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); + return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); +}; + +export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => + ts.isBundle(node) ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) : transformSourceFile(node); diff --git a/src/TSHelper.ts b/src/TSHelper.ts index c68c07298..514d6e44e 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import * as path from "path"; +import { CompilerOptions } from "./CompilerOptions"; import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import * as TSTLErrors from "./TSTLErrors"; @@ -692,8 +693,10 @@ export function hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeC export function getDeclarationContextType( signatureDeclaration: ts.SignatureDeclaration, - checker: ts.TypeChecker + program: ts.Program ): ContextType { + const checker = program.getTypeChecker(); + const thisParameter = getExplicitThisParameter(signatureDeclaration); if (thisParameter) { // Explicit 'this' @@ -727,7 +730,13 @@ export function getDeclarationContextType( return ContextType.NonVoid; } - // Walk up to find @noSelf or @noSelfOnFile + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. + const options = program.getCompilerOptions() as CompilerOptions; + if (options.noImplicitSelf && program.getRootFileNames().includes(signatureDeclaration.getSourceFile().fileName)) { + return ContextType.Void; + } + + // Walk up to find @noSelf or @noSelfInFile if (hasNoSelfAncestor(signatureDeclaration, checker)) { return ContextType.Void; } @@ -750,13 +759,15 @@ export function reduceContextTypes(contexts: ContextType[]): ContextType { return contexts.reduce(reducer, ContextType.None); } -export function getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): ContextType { +export function getFunctionContextType(type: ts.Type, program: ts.Program): ContextType { + const checker = program.getTypeChecker(); + if (type.isTypeParameter()) { type = type.getConstraint() || type; } if (type.isUnion()) { - return reduceContextTypes(type.types.map(t => getFunctionContextType(t, checker))); + return reduceContextTypes(type.types.map(t => getFunctionContextType(t, program))); } const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); @@ -764,7 +775,7 @@ export function getFunctionContextType(type: ts.Type, checker: ts.TypeChecker): return ContextType.None; } const signatureDeclarations = getSignatureDeclarations(signatures, checker); - return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(s, checker))); + return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(s, program))); } export function escapeString(text: string): string { diff --git a/src/TSTransformers.ts b/src/TSTransformers.ts index 81241810c..8cc38356c 100644 --- a/src/TSTransformers.ts +++ b/src/TSTransformers.ts @@ -3,6 +3,7 @@ import * as resolve from "resolve"; import * as ts from "typescript"; import { CompilerOptions, TransformerImport } from "./CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; +import { noImplicitSelfTransformer } from "./NoImplicitSelfTransformer"; export function getCustomTransformers( program: ts.Program, @@ -16,11 +17,19 @@ export function getCustomTransformers( }; const transformersFromOptions = loadTransformersFromOptions(program, diagnostics); + + const afterDeclarations = [ + ...(transformersFromOptions.afterDeclarations || []), + ...(customTransformers.afterDeclarations || []), + ]; + + const options = program.getCompilerOptions() as CompilerOptions; + if (options.noImplicitSelf) { + afterDeclarations.unshift(noImplicitSelfTransformer); + } + return { - afterDeclarations: [ - ...(transformersFromOptions.afterDeclarations || []), - ...(customTransformers.afterDeclarations || []), - ], + afterDeclarations, before: [ ...(customTransformers.before || []), ...(transformersFromOptions.before || []), diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts new file mode 100644 index 000000000..906d80a65 --- /dev/null +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -0,0 +1,40 @@ +import * as util from "../../util"; + +test("enables noSelfInFile behaviour for functions", () => { + util.testFunction` + function fooBar() {} + const test: (this: void) => void = fooBar; + ` + .setOptions({ noImplicitSelf: true }) + .expectToHaveNoDiagnostics(); +}); + +test("enables noSelfInFile behaviour for methods", () => { + util.testFunction` + class FooBar { + fooBar() {} + } + const fooBar = new FooBar(); + const test: (this: any) => void = fooBar.fooBar; + ` + .setOptions({ noImplicitSelf: true }) + .expectToHaveNoDiagnostics(); +}); + +test("generates declaration files with @noSelfInFile", () => { + const builder = util.testModule` + export function bar() {} + ` + .setOptions({ declaration: true, noImplicitSelf: true }) + .expectToHaveNoDiagnostics(); + + const declarationFile = builder.getLuaResult().transpiledFiles.find(f => f.declaration); + if (!util.expectToBeDefined(declarationFile) || !util.expectToBeDefined(declarationFile.declaration)) return; + + util.testModule` + import { bar } from "./foo.d"; + const test: (this: void) => void = bar; + ` + .addExtraFile("foo.d.ts", declarationFile.declaration) + .expectToHaveNoDiagnostics(); +}); From b26ec4890caeb251a72aae50e7f79df538be8927 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 5 Oct 2019 18:29:36 +0200 Subject: [PATCH 174/764] Fixed out of spec behavior of array.reduce (#731) * Fixed out of spec behavior of array.reduce * Moved select declarations from ArrayReduce to lualib declaration files * Fixed issue in reduce with undefined returning callback * Changed reduce loop from while to for for performance reasons * Cleaned up code a little from PR feedback * testcase formatting --- src/lualib/ArrayReduce.ts | 25 +++++++++++++------------ src/lualib/declarations/global.d.ts | 3 +++ src/lualib/declarations/tstl.d.ts | 6 ++++++ test/unit/builtins/array.spec.ts | 16 ++++++++++++++++ 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 9122afa68..db80f4e62 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -3,25 +3,26 @@ function __TS__ArrayReduce( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - initial?: T + ...initial: Vararg ): T { const len = arr.length; - if (len === 0 && initial === undefined) { - // tslint:disable-next-line: no-string-throw - throw "Reduce of empty array with no initial value"; - } - let k = 0; - let accumulator = initial; - if (initial === undefined) { + let accumulator = undefined; + + // Check if initial value is present in function call + if (select("#", ...initial) !== 0) { + accumulator = select(1, ...initial); + } else if (len > 0) { accumulator = arr[0]; - k++; + k = 1; + } else { + // tslint:disable-next-line: no-string-throw + throw "Reduce of empty array with no initial value"; } - while (k < len) { - accumulator = callbackFn(accumulator, arr[k], k, arr); - k = k + 1; + for (const i of forRange(k, len - 1)) { + accumulator = callbackFn(accumulator, arr[i], i, arr); } return accumulator; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index e27b9ecea..fc04d3377 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -16,3 +16,6 @@ declare function rawset(table: T, key: K, val: T[K]): void declare function next(table: Record, index?: K): [K, V]; declare function pcall(func: () => any): any; declare function unpack(list: T[], i?: number, j?: number): T[]; + +declare function select(index: number, ...args: T[]): T; +declare function select(index: "#", ...args: T[]): number; diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 8441e227b..7a7a8bf4f 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,5 +1,11 @@ /** @noSelfInFile */ +/** @vararg */ +interface Vararg extends Array {} + +/** @forRange */ +declare function forRange(start: number, limit: number, step?: number): number[]; + interface LuaClass { prototype: LuaObject; ____super?: LuaClass; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index edac44090..7f1cf095b 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -486,6 +486,22 @@ test.each<[[(total: number, currentItem: number, index: number, array: number[]) util.testExpression`[1, 3, 5, 7].reduce(${util.valuesToString(args)})`.expectToMatchJsResult(); }); +test("array.reduce empty undefined initial", () => { + util.testExpression`[].reduce(() => {}, undefined)`.expectToMatchJsResult(); +}); + +test("array.reduce empty no initial", () => { + util.testExpression`[].reduce(() => {})`.expectToMatchJsResult(true); +}); + +test("array.reduce undefined returning callback", () => { + util.testFunction` + const calls: Array<{ a: void, b: string }> = []; + ["a", "b"].reduce((a, b) => { calls.push({ a, b }) }, undefined); + return calls; + `.expectToMatchJsResult(); +}); + const genericChecks = [ "function generic(array: T)", "function generic(array: T)", From de818bcaf407dc4cb5f344882856bdb654c860fb Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 5 Oct 2019 18:29:54 +0200 Subject: [PATCH 175/764] Added support for array.find (#730) * Added support for array.find * Changed lualib function signature to match TS lib --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 2 ++ src/lualib/ArrayFind.ts | 18 ++++++++++++++++++ test/unit/builtins/array.spec.ts | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 src/lualib/ArrayFind.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 050e1eaf3..9d15f9fb4 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -6,6 +6,7 @@ export enum LuaLibFeature { ArrayEvery = "ArrayEvery", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", + ArrayFind = "ArrayFind", ArrayFindIndex = "ArrayFindIndex", ArrayIndexOf = "ArrayIndexOf", ArrayMap = "ArrayMap", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index fcb8c4cd0..cff5f45df 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -5113,6 +5113,8 @@ export class LuaTransformer { ); case "forEach": return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, node, caller, ...params); + case "find": + return this.transformLuaLibFunction(LuaLibFeature.ArrayFind, node, caller, ...params); case "findIndex": return this.transformLuaLibFunction(LuaLibFeature.ArrayFindIndex, node, caller, ...params); case "indexOf": diff --git a/src/lualib/ArrayFind.ts b/src/lualib/ArrayFind.ts new file mode 100644 index 000000000..370200df1 --- /dev/null +++ b/src/lualib/ArrayFind.ts @@ -0,0 +1,18 @@ +// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.find +function __TS__ArrayFind( + this: void, + arr: T[], + predicate: (value: T, index: number, obj: T[]) => unknown +): T | undefined { + const len = arr.length; + let k = 0; + while (k < len) { + const elem = arr[k]; + if (predicate(elem, k, arr)) { + return elem; + } + k = k + 1; + } + + return undefined; +} diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 7f1cf095b..b81260516 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -246,9 +246,25 @@ test("array.forEach (%p)", () => { `.expectToMatchJsResult(); }); +test.each([ + { array: [], predicate: "elem > 3" }, + { array: [0, 2, 4, 8], predicate: "elem > 10" }, + { array: [0, 2, 4, 8], predicate: "elem > 7" }, + { array: [0, 2, 4, 8], predicate: "elem == 0" }, + { array: [0, 2, 4, 8], predicate: "elem > 7" }, + { array: [0, 2, 4, 8], predicate: "true" }, + { array: [0, 2, 4, 8], predicate: "false" }, +])("array.find (%p)", ({ array, predicate }) => { + util.testFunction` + const array = ${util.valueToString(array)}; + return array.find((elem, index, arr) => ${predicate} && arr[index] === elem); + `.expectToMatchJsResult(); +}); + test.each([ { array: [], searchElement: 3 }, { array: [0, 2, 4, 8], searchElement: 10 }, + { array: [0, 2, 4, 8], searchElement: 0 }, { array: [0, 2, 4, 8], searchElement: 8 }, ])("array.findIndex (%p)", ({ array, searchElement }) => { util.testFunction` From 3603296fe8804b4ab8929b4aeac81ce3a8116a99 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 6 Oct 2019 23:49:13 +0500 Subject: [PATCH 176/764] Add GitHub Actions workflows (#707) * Add GitHub Actions workflows * Rename 'Continuous Integration' workflow to 'CI' * Run Lint job on latest node * Change release workflow event filter to `tags` * Update setup-node action version parameter name --- .github/workflows/ci.yml | 42 +++++++++++++++++++++++++++++++++++ .github/workflows/release.yml | 20 +++++++++++++++++ .prettierrc.js | 2 +- .travis.yml | 17 -------------- README.md | 7 +++--- appveyor.yml | 31 -------------------------- 6 files changed, 66 insertions(+), 53 deletions(-) create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .travis.yml delete mode 100644 appveyor.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..645444dc9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,42 @@ +name: CI + +on: [push, pull_request] + +jobs: + lint: + name: Lint + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + - run: npm install --global npm@6 + - run: npm ci + - run: npm run lint + env: + CI: true + + test: + name: Test on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest] + + steps: + - uses: actions/checkout@v1 + - name: Use Node.js 8.5.0 + uses: actions/setup-node@v1 + with: + node-version: 8.5.0 + - run: npm install --global npm@6 + - run: npm ci + - run: npm run build + - run: npx jest --coverage + env: + CI: true + - if: matrix.os == 'ubuntu-latest' + continue-on-error: true + uses: codecov/codecov-action@v1.0.0 + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..b344325aa --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: Release + +on: + push: + tags: "*" + +jobs: + release: + name: Release + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + - run: npm install --global npm@6 + - run: npm ci + - run: npm run build + - run: npm publish --dry-run + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} diff --git a/.prettierrc.js b/.prettierrc.js index 87974397e..e9fb0b291 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -6,5 +6,5 @@ module.exports = { tabWidth: 4, trailingComma: "es5", endOfLine: isCI ? "lf" : "auto", - overrides: [{ files: ["**/*.md", "**/*.yml", "**/.*.yml"], options: { tabWidth: 2 } }], + overrides: [{ files: ["**/*.md", "**/*.yml"], options: { tabWidth: 2 } }], }; diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index e75d82b40..000000000 --- a/.travis.yml +++ /dev/null @@ -1,17 +0,0 @@ -language: node_js -node_js: "8.5.0" - -script: - - npm run build - - npm test -- --coverage -after_success: npx codecov - -deploy: - provider: npm - email: lorenz.junglas@student.kit.edu - skip_cleanup: true - api_key: - secure: zXFXK1GohutgqKXQ101uKcJKcf0wgCuVPFMY44Xl/JwXeLsA1CJ4aqUdoXh2ramcI+9wTVj7RR3N3/7W+2DeDCfUlj+gxw26pTV3EUnU2B1TXEz01Ar07WPHmhHJSS5tgyo9kPUqm/YBFkJuDtfx0Kp3sL6IRYDddvGv/2L1X8r3I14PxgppkU9T4FGINdClOEwfwelmxx3kjxpnTsUHZ+ztx7o+blteSf/r+pT1RDaIap80JaTy6vHwJKECRSvtpyTKEYeVmBIaA3yXqRhfMdlp8bU20t2DXoDGXWPk0GXRGXkVHE6yj64gPe/eOOesAxzv0v/vr5w4poemJ+SGwP3RSbrbVtiusD4FC6+hFBH7hiNUhxww5euvbAfNOTq2XyxtjcNmKB5/O675xGihK1gBgrsPdJ4enwkhQNrUuQBHm5wIKGiaH7t7q+T8W9JAnk3FGGuSZPg9b7AnFDQ3graxZK9mtOxi0GvE7DHinH6qErd4noGjS/KSy1fnDkCEkeplOQmvxb4w7wLMR5pePFc77NBXiR3RJDKh4QKskcvXPx58OWNffTkS2QwYPYhraNNKbUfGFBNEA4KPNmw1jYlDE/1BhOebmONpZQMP/CdcCWL+CKyTdi1/289Ak4B0iSZZN+Yx+AONzPlcvBVi+bXeXtqoIt2zMFKkr/0YFQg= - on: - tags: true - repo: TypeScriptToLua/TypeScriptToLua diff --git a/README.md b/README.md index 5fff008ac..ad83fb83e 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,9 @@

TypeScriptToLua

-
Build status - Build status - Coverage - Chat with us! + Continuous Integration status + Coverage + Chat with us!

diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 5e5b29138..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,31 +0,0 @@ -# Test against the latest version of this Node.js version -environment: - nodejs_version: "8.5.0" - -# Do not build feature branch with open Pull Requests -skip_branch_with_pr: true - -# Cache dependencies -cache: - - node_modules - -# Install scripts. (runs after repo cloning) -install: - # Get the latest stable version of Node.js or io.js - - ps: Install-Product node $env:nodejs_version - # Upgrade npm - - npm install --global npm@6 - # Install modules - - npm ci - -# Post-install test scripts. -test_script: - # Output useful info for debugging. - - node --version - - npm --version - # Run tests - - npm run build - - npm test - -# Don't actually build. -build: off From 68bccfc18e9ae50f03b0b1b2ea303c9c8f16a073 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 6 Oct 2019 23:59:55 +0500 Subject: [PATCH 177/764] Update GitHub Actions CI badge workflow URL --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad83fb83e..b1438a222 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

TypeScriptToLua

- Continuous Integration status + Continuous Integration status Coverage Chat with us!

From a858d85992871d8ae6e5706eb74178d90ccb66c3 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 9 Oct 2019 01:10:08 +0500 Subject: [PATCH 178/764] Update CI workflow (#735) --- .github/workflows/ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 645444dc9..95cb25965 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,9 @@ name: CI -on: [push, pull_request] +on: + push: + branches: master + pull_request: jobs: lint: @@ -32,7 +35,7 @@ jobs: - run: npm install --global npm@6 - run: npm ci - run: npm run build - - run: npx jest --coverage + - run: npx jest --maxWorkers 2 --coverage env: CI: true - if: matrix.os == 'ubuntu-latest' From bf9f6092c4a4bfaf4bb7828ffcb9132ccf0db147 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Wed, 9 Oct 2019 21:43:29 +0200 Subject: [PATCH 179/764] Allow throwing arbitrary types and add builtin error classes (#724) * allow throwing arbitrary types and add builtin error classes * track Scope in transformClassExpression * allow subclassing Error * Update test/unit/error.spec.ts Co-Authored-By: ark120202 * use custom traceback in errors * return full stack on fallback * use builder API for tests * cleanup * add error name to type and reduce dependencies * test subclasses for stack * test string representation of subclassed errors * fix throwing as function test * style changes * formatting * add sourceMapTraceback option to test * add 'This error serves to prevent false positives from .expectNoExecutionError()' * Update test/unit/error.spec.ts Co-Authored-By: ark120202 * rollback to use debug.traceback * Update src/lualib/Error.ts Co-Authored-By: ark120202 * fix throwing strings and update tests * Update src/lualib/Error.ts Co-Authored-By: ark120202 * test extending from error with custom toString() * update identifiers test for new exception handling * use constructor assignment for message property * print stack for uncaught errors * Update test/unit/error.spec.ts Co-Authored-By: ark120202 * Update test/unit/error.spec.ts Co-Authored-By: ark120202 * rollback toString() support * add more test cases * formatting * set __tostring metamethod in constructor * update tests * remove generic from ErrorType * add info string to tests * style changes * style changes --- src/LuaLib.ts | 2 + src/LuaTransformer.ts | 36 +++++++++------ src/TSHelper.ts | 20 +++++++++ src/TSTLErrors.ts | 3 -- src/lualib/Error.ts | 70 +++++++++++++++++++++++++++++ src/lualib/declarations/debug.d.ts | 18 ++++++++ src/lualib/declarations/global.d.ts | 1 + test/unit/error.spec.ts | 58 +++++++++++++++++++++--- test/unit/identifiers.spec.ts | 2 +- 9 files changed, 186 insertions(+), 24 deletions(-) create mode 100644 src/lualib/Error.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 9d15f9fb4..181996d8b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -26,6 +26,7 @@ export enum LuaLibFeature { ClassIndex = "ClassIndex", ClassNewIndex = "ClassNewIndex", Decorate = "Decorate", + Error = "Error", FunctionApply = "FunctionApply", FunctionBind = "FunctionBind", FunctionCall = "FunctionCall", @@ -64,6 +65,7 @@ export enum LuaLibFeature { const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], + Error: [LuaLibFeature.FunctionCall], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index cff5f45df..b17f777e4 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -613,6 +613,10 @@ export class LuaTransformer { // Get type that is extended const extendsType = tsHelper.getExtendedType(statement, this.checker); + if (extendsType) { + this.checkForLuaLibType(extendsType); + } + if (!(isExtension || isMetaExtension) && extendsType) { // Non-extensions cannot extend extension classes const extendsDecorators = tsHelper.getCustomDecorators(extendsType, this.checker); @@ -2843,20 +2847,17 @@ export class LuaTransformer { } public transformThrowStatement(statement: ts.ThrowStatement): StatementVisitResult { - if (statement.expression === undefined) { - throw TSTLErrors.InvalidThrowExpression(statement); - } + const parameters: tstl.Expression[] = []; - const type = this.checker.getTypeAtLocation(statement.expression); - if (tsHelper.isStringType(type, this.checker, this.program)) { - const error = tstl.createIdentifier("error"); - return tstl.createExpressionStatement( - tstl.createCallExpression(error, [this.transformExpression(statement.expression)]), - statement - ); - } else { - throw TSTLErrors.InvalidThrowExpression(statement.expression); + if (statement.expression) { + parameters.push(this.transformExpression(statement.expression)); + parameters.push(tstl.createNumericLiteral(0)); } + + return tstl.createExpressionStatement( + tstl.createCallExpression(tstl.createIdentifier("error"), parameters), + statement + ); } public transformContinueStatement(statement: ts.ContinueStatement): StatementVisitResult { @@ -3679,7 +3680,10 @@ export class LuaTransformer { className = tstl.createAnonymousIdentifier(); } + this.pushScope(ScopeType.Function); const classDeclaration = this.transformClassDeclaration(expression, className); + this.popScope(); + return this.createImmediatelyInvokedFunctionExpression( this.statementVisitResultToArray(classDeclaration), className, @@ -4205,6 +4209,7 @@ export class LuaTransformer { const expressionType = this.checker.getTypeAtLocation(expression.expression); if (tsHelper.isStandardLibraryType(expressionType, undefined, this.program)) { + this.checkForLuaLibType(expressionType); const result = this.transformGlobalFunctionCall(expression); if (result) { return result; @@ -5503,7 +5508,8 @@ export class LuaTransformer { protected checkForLuaLibType(type: ts.Type): void { if (type.symbol) { - switch (this.checker.getFullyQualifiedName(type.symbol)) { + const name = this.checker.getFullyQualifiedName(type.symbol); + switch (name) { case "Map": this.importLuaLibFeature(LuaLibFeature.Map); return; @@ -5517,6 +5523,10 @@ export class LuaTransformer { this.importLuaLibFeature(LuaLibFeature.WeakSet); return; } + + if (tsHelper.isBuiltinErrorTypeName(name)) { + this.importLuaLibFeature(LuaLibFeature.Error); + } } } diff --git a/src/TSHelper.ts b/src/TSHelper.ts index 514d6e44e..c237ae188 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -34,6 +34,22 @@ const defaultArrayCallMethodNames = new Set([ "flatMap", ]); +// TODO [2019-09-27/Perry]: Refactor lualib detection to consistent map +const builtinErrorTypeNames = new Set([ + "Error", + "ErrorConstructor", + "RangeError", + "RangeErrorConstructor", + "ReferenceError", + "ReferenceErrorConstructor", + "SyntaxError", + "SyntaxErrorConstructor", + "TypeError", + "TypeErrorConstructor", + "URIError", + "URIErrorConstructor", +]); + export function getExtendedTypeNode( node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker @@ -1052,3 +1068,7 @@ export function formatPathToLuaPath(filePath: string): string { } return filePath.replace(/\.\//g, "").replace(/\//g, "."); } + +export function isBuiltinErrorTypeName(name: string): boolean { + return builtinErrorTypeNames.has(name); +} diff --git a/src/TSTLErrors.ts b/src/TSTLErrors.ts index 89867e01d..c32318f45 100644 --- a/src/TSTLErrors.ts +++ b/src/TSTLErrors.ts @@ -54,9 +54,6 @@ export const InvalidPropertyCall = (node: ts.Node) => export const InvalidElementCall = (node: ts.Node) => new TranspileError(`Tried to transpile a non-element call as an element call.`, node); -export const InvalidThrowExpression = (node: ts.Node) => - new TranspileError(`Invalid throw expression, only strings can be thrown.`, node); - export const ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts new file mode 100644 index 000000000..c91223f65 --- /dev/null +++ b/src/lualib/Error.ts @@ -0,0 +1,70 @@ +interface ErrorType { + name: string; + new (...args: any[]): Error; +} + +function __TS__GetErrorStack(constructor: Function): string { + let level = 1; + while (true) { + const info = debug.getinfo(level, "f"); + level += 1; + if (!info) { + // constructor is not in call stack + level = 1; + break; + } else if (info.func === constructor) { + break; + } + } + + return debug.traceback(undefined, level); +} + +function __TS__WrapErrorToString(getDescription: (this: T) => string): (this: T) => string { + return function(this: Error): string { + const description = getDescription.call(this); + const caller = debug.getinfo(3, "f"); + if (_VERSION === "Lua 5.1" || (caller && caller.func !== error)) { + return description; + } else { + return `${description}\n${this.stack}`; + } + }; +} + +function __TS__InitErrorClass(Type: ErrorType, name: string): any { + Type.name = name; + return setmetatable(Type, { + __call: (_self: any, message: string) => new Type(message), + }); +} + +Error = __TS__InitErrorClass( + class implements Error { + public name = "Error"; + public stack: string; + + constructor(public message = "") { + this.stack = __TS__GetErrorStack((this.constructor as any).new); + const metatable = getmetatable(this); + if (!metatable.__errorToStringPatched) { + metatable.__errorToStringPatched = true; + metatable.__tostring = __TS__WrapErrorToString(metatable.__tostring); + } + } + + public toString(): string { + return this.message !== "" ? `${this.name}: ${this.message}` : this.name; + } + }, + "Error" +); + +for (const errorName of ["RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError"]) { + globalThis[errorName] = __TS__InitErrorClass( + class extends Error { + public name = errorName; + }, + errorName + ); +} diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts index d5bd489d4..a451fe07f 100644 --- a/src/lualib/declarations/debug.d.ts +++ b/src/lualib/declarations/debug.d.ts @@ -1,5 +1,23 @@ /** @noSelfInFile */ +declare const _VERSION: string; +declare function error(...args: any[]): never; + declare namespace debug { function traceback(...args: any[]): string; + + interface FunctionInfo { + func: T; + name?: string; + namewhat: "global" | "local" | "method" | "field" | ""; + source: string; + short_src: string; + linedefined: number; + lastlinedefined: number; + what: "Lua" | "C" | "main"; + currentline: number; + nups: number; + } + + function getinfo(i: number, what?: string): Partial; } diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index fc04d3377..77a88b694 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -10,6 +10,7 @@ declare function type( value: any ): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; declare function setmetatable(table: T, metatable: any): T; +declare function getmetatable(table: T): any; declare function rawget(table: T, key: K): T[K]; declare function rawset(table: T, key: K, val: T[K]): void; /** @tupleReturn */ diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 17a6bc15c..e1959abb8 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -1,4 +1,3 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; import * as util from "../util"; test("throwString", () => { @@ -7,12 +6,6 @@ test("throwString", () => { `.expectToEqual(new util.ExecutionError("Some Error")); }); -test("throwError", () => { - util.testFunction` - throw Error("Some Error") - `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidThrowExpression(util.nodeStub)); -}); - test.skip.each([0, 1, 2])("re-throw (%p)", i => { util.testFunction` const i: number = ${i}; @@ -292,3 +285,54 @@ test("return from nested finally", () => { `; expect(util.transpileAndExecute(code)).toBe("finally AB"); }); + +test.each([ + `"error string"`, + `42`, + `3.141`, + `true`, + `false`, + `undefined`, + `{ x: "error object" }`, + `() => "error function"`, +])("throw and catch %s", error => { + util.testFunction` + try { + throw ${error}; + } catch (error) { + if (typeof error == 'function') { + return error(); + } else { + return error; + } + } + `.expectToMatchJsResult(); +}); + +const builtinErrors = ["Error", "RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError"]; + +test.each([...builtinErrors, ...builtinErrors.map(type => `new ${type}`)])("%s properties", errorType => { + util.testFunction` + const error = ${errorType}(); + return { name: error.name, message: error.message, string: error.toString() }; + `.expectToMatchJsResult(); +}); + +test.each([...builtinErrors, "CustomError"])("get stack from %s", errorType => { + const stack = util.testFunction` + class CustomError extends Error { + public name = "CustomError"; + } + + let stack: string | undefined; + + function innerFunction() { stack = new ${errorType}().stack; } + function outerFunction() { innerFunction(); } + outerFunction(); + + return stack; + `.getLuaExecutionResult(); + + expect(stack).toMatch("innerFunction"); + expect(stack).toMatch("outerFunction"); +}); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index bde4477fa..3cd3753f6 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -356,7 +356,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const error = "foobar"; throw error;`; - expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: .+ foobar$/); + expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: foobar$/); }); test("variable (assert)", () => { From b7e72964c6490a3d56d6b2c6192ca5df6f9c0cd4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 9 Oct 2019 21:47:21 +0200 Subject: [PATCH 180/764] Fixed issue in test code formatting, fixed array.splice and array.join (#734) * Refactored test formatting helper causing some tests to start (correctly) failing * Fix array.join with unidentified argument * Fixed splice implementation * Improved code from PR feedback --- package-lock.json | 12 +++-- package.json | 1 + src/LuaTransformer.ts | 9 +++- src/lualib/ArraySplice.ts | 21 ++++++--- test/unit/builtins/array.spec.ts | 68 +++++++++++++++++---------- test/unit/builtins/object.spec.ts | 5 +- test/unit/builtins/string.spec.ts | 23 +++++---- test/unit/builtins/symbol.spec.ts | 4 +- test/unit/destructuring.spec.ts | 4 +- test/unit/functions/functions.spec.ts | 2 +- test/util.ts | 10 ++-- 11 files changed, 94 insertions(+), 65 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b6468a77..e3b501293 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2484,9 +2484,9 @@ "dev": true }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.2.tgz", + "integrity": "sha512-cIv17+GhL8pHHnRJzGu2wwcthL5sb8uDKBHvZ2Dtu5s1YNt0ljbzKbamnc+gr69y7bzwQiBdr5+hOpRd5pnOdg==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -2944,6 +2944,12 @@ "handlebars": "^4.1.2" } }, + "javascript-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.0.tgz", + "integrity": "sha512-zzK8+ByrzvOL6N92hRewwUKL0wN0TOaIuUjX0Jj8lraxWvr5wHYs2YTjaj2lstF+8qMv5cmPPef47va8NT8lDw==", + "dev": true + }, "jest": { "version": "24.8.0", "resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz", diff --git a/package.json b/package.json index 768745cb9..eb409eb1a 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "@types/node": "^11.13.14", "@types/resolve": "0.0.8", "fengari": "^0.1.4", + "javascript-stringify": "^2.0.0", "jest": "^24.8.0", "jest-circus": "^24.8.0", "prettier": "^1.18.2", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index b17f777e4..5782b24a3 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -5139,8 +5139,13 @@ export class LuaTransformer { case "splice": return this.transformLuaLibFunction(LuaLibFeature.ArraySplice, node, caller, ...params); case "join": - const parameters = - node.arguments.length === 0 ? [caller, tstl.createStringLiteral(",")] : [caller].concat(params); + const defaultSeparatorLiteral = tstl.createStringLiteral(","); + const parameters = [ + caller, + node.arguments.length === 0 + ? defaultSeparatorLiteral + : tstl.createBinaryExpression(params[0], defaultSeparatorLiteral, tstl.SyntaxKind.OrOperator), + ]; return tstl.createCallExpression( tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("concat")), diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index bb2527583..862422e39 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,6 +1,11 @@ -function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: number, ...items: T[]): T[] { +// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice +function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { const len = list.length; + const actualArgumentCount = select("#", ...args); + const start = select(1, ...args) as number; + const deleteCount = select(2, ...args) as number; + let actualStart: number; if (start < 0) { @@ -9,16 +14,18 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: actualStart = Math.min(start, len); } - const itemCount = items.length; + const itemCount = Math.max(actualArgumentCount - 2, 0); let actualDeleteCount: number; - if (!start) { + if (actualArgumentCount === 0) { + // ECMA-spec line 5: if number of actual arguments is 0 actualDeleteCount = 0; - } else if (!deleteCount) { + } else if (actualArgumentCount === 1) { + // ECMA-spec line 6: if number of actual arguments is 1 actualDeleteCount = len - actualStart; } else { - actualDeleteCount = Math.min(Math.max(deleteCount, 0), len - actualStart); + actualDeleteCount = Math.min(Math.max(deleteCount || 0, 0), len - actualStart); } const out: T[] = []; @@ -59,8 +66,8 @@ function __TS__ArraySplice(this: void, list: T[], start: number, deleteCount: } let j = actualStart; - for (const e of items) { - list[j] = e; + for (const i of forRange(3, actualArgumentCount)) { + list[j] = select(i, ...args) as T; j++; } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index b81260516..00d831fdb 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -256,7 +256,7 @@ test.each([ { array: [0, 2, 4, 8], predicate: "false" }, ])("array.find (%p)", ({ array, predicate }) => { util.testFunction` - const array = ${util.valueToString(array)}; + const array = ${util.formatCode(array)}; return array.find((elem, index, arr) => ${predicate} && arr[index] === elem); `.expectToMatchJsResult(); }); @@ -268,7 +268,7 @@ test.each([ { array: [0, 2, 4, 8], searchElement: 8 }, ])("array.findIndex (%p)", ({ array, searchElement }) => { util.testFunction` - const array = ${util.valueToString(array)}; + const array = ${util.formatCode(array)}; return array.findIndex((elem, index, arr) => elem === ${searchElement} && arr[index] === elem); `.expectToMatchJsResult(); }); @@ -281,7 +281,7 @@ test.each([ { array: [0, 1, 2, 3], func: "x => x+2" }, { array: [0, 1, 2, 3], func: "x => x%2 == 0 ? x + 1 : x - 1" }, ])("array.map (%p)", ({ array, func }) => { - util.testExpression`${util.valueToString(array)}.map(${func})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.map(${func})`.expectToMatchJsResult(); }); test.each([ @@ -293,7 +293,7 @@ test.each([ { array: [0, 1, 2, 3], func: "() => true" }, { array: [0, 1, 2, 3], func: "() => false" }, ])("array.filter (%p)", ({ array, func }) => { - util.testExpression`${util.valueToString(array)}.filter(${func})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.filter(${func})`.expectToMatchJsResult(); }); test.each([ @@ -302,7 +302,7 @@ test.each([ { array: [false, true, false], func: "x => x" }, { array: [true, true, true], func: "x => x" }, ])("array.every (%p)", ({ array, func }) => { - util.testExpression`${util.valueToString(array)}.every(${func})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.every(${func})`.expectToMatchJsResult(); }); test.each([ @@ -311,7 +311,7 @@ test.each([ { array: [false, true, false], func: "x => x" }, { array: [true, true, true], func: "x => x" }, ])("array.some (%p)", ({ array, func }) => { - util.testExpression`${util.valueToString(array)}.some(${func})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.some(${func})`.expectToMatchJsResult(); }); test.each([ @@ -324,7 +324,8 @@ test.each([ { array: [0, 1, 2, 3, 4, 5], args: [1, 3] }, { array: [0, 1, 2, 3, 4, 5], args: [3] }, ])("array.slice (%p)", ({ array, args }) => { - util.testExpression`${util.valueToString(array)}.slice(${util.valuesToString(args)})`.expectToMatchJsResult(); + const argumentString = util.formatCode(...args); + util.testExpression`${util.formatCode(array)}.slice(${argumentString})`.expectToMatchJsResult(); }); test.each([ @@ -338,26 +339,37 @@ test.each([ { array: [0, 1, 2, 3], start: -3, deleteCount: 0, newElements: [8, 9] }, { array: [0, 1, 2, 3, 4, 5], start: 5, deleteCount: 9, newElements: [10, 11] }, { array: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, + { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, + { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: undefined, newElements: [10, 11] }, + // tslint:disable-next-line:no-null-keyword + { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: null, newElements: [10, 11] }, // Remove { array: [], start: 1, deleteCount: 1 }, { array: [0, 1, 2, 3], start: 1, deleteCount: 1 }, { array: [0, 1, 2, 3], start: 10, deleteCount: 1 }, - { array: [0, 1, 2, 3], start: 1, deleteCount: undefined }, - { array: [0, 1, 2, 3], start: 4 }, - { array: [0, 1, 2, 3, 4, 5], start: 3 }, - { array: [0, 1, 2, 3, 4, 5], start: -3 }, - { array: [0, 1, 2, 3, 4, 5], start: -2 }, { array: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, - { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, + { array: [0, 1, 2, 3, 4, 5], start: -3, deleteCount: 2 }, + { array: [0, 1, 2, 3], start: 1, deleteCount: undefined }, + // tslint:disable-next-line:no-null-keyword + { array: [0, 1, 2, 3], start: 1, deleteCount: null }, ])("array.splice (%p)", ({ array, start, deleteCount, newElements = [] }) => { util.testFunction` - const array = ${util.valueToString(array)}; - array.splice(${util.valuesToString([start, deleteCount, ...newElements])}); + const array = ${util.formatCode(array)}; + array.splice(${util.formatCode(start, deleteCount, ...newElements)}); return array; `.expectToMatchJsResult(); }); +test.each([ + { array: [0, 1, 2, 3], start: 4 }, + { array: [0, 1, 2, 3, 4, 5], start: 3 }, + { array: [0, 1, 2, 3, 4, 5], start: -3 }, + { array: [0, 1, 2, 3, 4, 5], start: -2 }, +])("array.splice no delete argument", ({ array, start }) => { + util.testExpression`${util.formatCode(array)}.splice(${start})`.expectToMatchJsResult(); +}); + test.each([ { array: [], args: [[]] }, { array: [1, 2, 3], args: [[]] }, @@ -371,8 +383,8 @@ test.each([ { array: [1, 2, "test"], args: ["test", ["test1", "test2"]] }, ])("array.concat (%p)", ({ array, args }) => { util.testFunction` - const array: any[] = ${util.valueToString(array)}; - return array.concat(${util.valuesToString(args)}); + const array: any[] = ${util.formatCode(array)}; + return array.concat(${util.formatCode(...args)}); `.expectToMatchJsResult(); }); @@ -383,7 +395,11 @@ test.each([ { array: ["test1", "test2"], separator: ";" }, { array: ["test1", "test2"], separator: "" }, ])("array.join (%p)", ({ array, separator }) => { - util.testExpression`${util.valueToString(array)}.join(${util.valueToString(separator)})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.join(${util.formatCode(separator)})`.expectToMatchJsResult(); +}); + +test("array.join without separator argument", () => { + util.testExpression`["test1", "test2"].join()`.expectToMatchJsResult(); }); test.each([ @@ -395,13 +411,13 @@ test.each([ { array: ["test1", "test2", "test3"], args: ["test1", -2] }, { array: ["test1", "test2", "test3"], args: ["test1", 12] }, ])("array.indexOf (%p)", ({ array, args }) => { - util.testExpression`${util.valueToString(array)}.indexOf(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(array)}.indexOf(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([{ args: [1] }, { args: [1, 2, 3] }])("array.push (%p)", ({ args }) => { util.testFunction` const array = [0]; - const value = array.push(${util.valuesToString(args)}); + const value = array.push(${util.formatCode(...args)}); return { array, value }; `.expectToMatchJsResult(); }); @@ -411,7 +427,7 @@ test.each([{ array: [1, 2, 3], expected: [3, 2] }, { array: [1, 2, 3, null], exp "array.pop (%p)", ({ array, expected }) => { util.testFunction` - const array = ${util.valueToString(array)}; + const array = ${util.formatCode(array)}; const value = array.pop(); return [value, array.length]; `.expectToEqual(expected); @@ -422,7 +438,7 @@ test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { arra "array.reverse (%p)", ({ array }) => { util.testFunction` - const array = ${util.valueToString(array)}; + const array = ${util.formatCode(array)}; array.reverse(); return array; `.expectToMatchJsResult(); @@ -431,7 +447,7 @@ test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { arra test.each([{ array: [1, 2, 3] }, { array: [1] }, { array: [] }])("array.shift (%p)", ({ array }) => { util.testFunction` - const array = ${util.valueToString(array)}; + const array = ${util.formatCode(array)}; const value = array.shift(); return { array, value }; `.expectToMatchJsResult(); @@ -444,8 +460,8 @@ test.each([ { array: [], args: [1] }, ])("array.unshift (%p)", ({ array, args }) => { util.testFunction` - const array = ${util.valueToString(array)}; - const value = array.unshift(${util.valuesToString(args)}); + const array = ${util.formatCode(array)}; + const value = array.unshift(${util.formatCode(...args)}); return { array, value }; `.expectToMatchJsResult(); }); @@ -499,7 +515,7 @@ test.each<[[(total: number, currentItem: number, index: number, array: number[]) [[(total, _, index, array) => total + array[index]]], [[(a, b) => a + b]], ])("array.reduce (%p)", args => { - util.testExpression`[1, 3, 5, 7].reduce(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`[1, 3, 5, 7].reduce(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test("array.reduce empty undefined initial", () => { diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index ca1516254..5e0a973a4 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -6,9 +6,8 @@ test.each([ { initial: { a: 3 }, args: [{ a: 5 }] }, { initial: { a: 3 }, args: [{ b: 5 }, { c: 7 }] }, ])("Object.assign (%p)", ({ initial, args }) => { - util.testExpression`Object.assign(${util.valueToString(initial)}, ${util.valuesToString( - args - )})`.expectToMatchJsResult(); + const argsString = util.formatCode(...args); + util.testExpression`Object.assign(${util.formatCode(initial)}, ${argsString})`.expectToMatchJsResult(); }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index af5b46762..9e6f73e28 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -20,7 +20,7 @@ test("Supported lua string function", () => { }); test.each([[], [65], [65, 66], [65, 66, 67]])("String.fromCharCode (%p)", (...args) => { - util.testExpression`String.fromCharCode(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`String.fromCharCode(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([ @@ -61,13 +61,13 @@ test.each([ { inp: "hello test", searchValue: "test", replaceValue: (): string => "%a" }, { inp: "aaa", searchValue: "a", replaceValue: "b" }, ])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { - util.testExpression`"${inp}".replace(${util.valuesToString([searchValue, replaceValue])})`.expectToMatchJsResult(); + util.testExpression`"${inp}".replace(${util.formatCode(searchValue, replaceValue)})`.expectToMatchJsResult(); }); test.each([["", ""], ["hello", "test"], ["hello", "test", "bye"], ["hello", 42], [42, "hello"]])( "string.concat[+] (%p)", (...elements) => { - util.testExpression(elements.map(e => util.valueToString(e)).join(" + ")).expectToMatchJsResult(); + util.testExpression(elements.map(e => util.formatCode(e)).join(" + ")).expectToMatchJsResult(); } ); @@ -77,7 +77,7 @@ test.each([ { str: "hello", args: [] }, { str: "hello", args: ["test", "bye"] }, ])("string.concatFct (%p)", ({ str, args }) => { - util.testExpression`"${str}".concat(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${str}".concat(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([ @@ -113,7 +113,7 @@ test.each([ { inp: "hello test", args: [1, 2] }, { inp: "hello test", args: [1, 5] }, ])("string.slice (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".slice(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".slice(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([ @@ -122,7 +122,7 @@ test.each([ { inp: "hello test", args: [1, 2] }, { inp: "hello test", args: [1, 5] }, ])("string.substring (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".substring(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".substring(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 5 }])( @@ -139,7 +139,7 @@ test.each([ { inp: "hello test", args: [1, 2] }, { inp: "hello test", args: [1, 5] }, ])("string.substr (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".substr(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".substr(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 2 }])( @@ -207,7 +207,7 @@ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: ["test"] }, { inp: "hello test", args: ["test", 6] }, ])("string.startsWith (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".startsWith(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".startsWith(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each<{ inp: string; args: Parameters }>([ @@ -216,8 +216,7 @@ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: ["hello"] }, { inp: "hello test", args: ["hello", 5] }, ])("string.endsWith (%p)", ({ inp, args }) => { - const argsString = util.valuesToString(args); - util.testExpression`"${inp}".endsWith(${argsString})`.expectToMatchJsResult(); + util.testExpression`"${inp}".endsWith(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([ @@ -243,11 +242,11 @@ const padCases = [ ]; test.each(padCases)("string.padStart (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".padStart(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".padStart(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each(padCases)("string.padEnd (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".padEnd(${util.valuesToString(args)})`.expectToMatchJsResult(); + util.testExpression`"${inp}".padEnd(${util.formatCode(...args)})`.expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/builtins/symbol.spec.ts b/test/unit/builtins/symbol.spec.ts index 75da67a59..7faabef84 100644 --- a/test/unit/builtins/symbol.spec.ts +++ b/test/unit/builtins/symbol.spec.ts @@ -1,12 +1,12 @@ import * as util from "../../util"; test.each([undefined, 1, "name"])("symbol.toString() (%p)", description => { - util.testExpression`Symbol(${util.valueToString(description)}).toString()`.expectToMatchJsResult(); + util.testExpression`Symbol(${util.formatCode(description)}).toString()`.expectToMatchJsResult(); }); test.each([undefined, 1, "name"])("symbol.description (%p)", description => { // TODO: Supported since node 11 - util.testExpression`Symbol(${util.valueToString(description)}).description`.expectToEqual(description); + util.testExpression`Symbol(${util.formatCode(description)}).description`.expectToEqual(description); }); test("symbol uniqueness", () => { diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 35519f299..6572d8b6b 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -24,7 +24,7 @@ const testCases = [ { binding: "{ y: [z = true] }", value: { y: [false] } }, { binding: "{ x: [x, y] }", value: { x: ["x", "y"] } }, { binding: "{ x: [{ y }] }", value: { x: [{ y: "y" }] } }, -].map(({ binding, value }) => ({ binding, value: util.valueToString(value) })); +].map(({ binding, value }) => ({ binding, value: util.formatCode(value) })); test.each([ ...testCases, @@ -70,7 +70,7 @@ const assignmentTestCases = [ { binding: "[{ x: obj.prop }]", value: [{ x: true }] }, { binding: "{ obj: { prop: obj.prop } }", value: { obj: { prop: true } } }, { binding: "{ x = true }", value: {} }, - ].map(({ binding, value }) => ({ binding, value: util.valueToString(value) })), + ].map(({ binding, value }) => ({ binding, value: util.formatCode(value) })), { binding: "{ x: { [(3).toString()]: y } }", value: "{ x: { [(3).toString()]: true } }" }, ]; diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 8214e6bfd..f0f6fd6e0 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -267,7 +267,7 @@ test.each([{ args: ["bar"], expected: "foobar" }, { args: ["baz", "bar"], expect } }; const o = new O(); - return o.method(${util.valuesToString(args)}); + return o.method(${util.formatCode(...args)}); `.expectToEqual(expected); } ); diff --git a/test/util.ts b/test/util.ts index 8abc0dbc6..33e48b16f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -5,6 +5,7 @@ import * as prettyFormat from "pretty-format"; import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; +import { stringify } from "javascript-stringify"; export * from "./legacy-utils"; @@ -49,12 +50,7 @@ export function expectToBeDefined(subject: T | null | undefined): subject is return true; // If this was false the expect would have thrown an error } -export const valueToString = (value: unknown) => - (typeof value === "number" && (!Number.isFinite(value) || Number.isNaN(value))) || typeof value === "function" - ? String(value) - : JSON.stringify(value); - -export const valuesToString = (values: unknown[]) => values.map(valueToString).join(", "); +export const formatCode = (...values: unknown[]) => values.map(e => stringify(e)).join(", "); export function testEachVersion( name: string | undefined, @@ -451,7 +447,7 @@ const createTestBuilderFactory = ( } else { let [template, ...substitutions] = args; if (serializeSubstitutions) { - substitutions = substitutions.map(valueToString); + substitutions = substitutions.map(s => formatCode(s)); } tsCode = template From 28397f4270e70d57b8aeb30d1f4db87ed622c9a9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 9 Oct 2019 21:59:40 +0200 Subject: [PATCH 181/764] Added support for reduceRight (#732) * Fixed out of spec behavior of array.reduce * Moved select declarations from ArrayReduce to lualib declaration files * Fixed issue in reduce with undefined returning callback * Changed reduce loop from while to for for performance reasons * Cleaned up code a little from PR feedback * testcase formatting * Added reduceRight * Added tests, fixed implementation * Changed test structure for reduce to describe * Removed duplicate test --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 2 ++ src/lualib/ArrayReduceRight.ts | 29 ++++++++++++++++++++ test/unit/builtins/array.spec.ts | 46 +++++++++++++++++--------------- 4 files changed, 56 insertions(+), 22 deletions(-) create mode 100644 src/lualib/ArrayReduceRight.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 181996d8b..c877dd9cc 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -12,6 +12,7 @@ export enum LuaLibFeature { ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", ArrayReduce = "ArrayReduce", + ArrayReduceRight = "ArrayReduceRight", ArrayReverse = "ArrayReverse", ArrayShift = "ArrayShift", ArrayUnshift = "ArrayUnshift", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 5782b24a3..e460993b7 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -5130,6 +5130,8 @@ export class LuaTransformer { return this.transformLuaLibFunction(LuaLibFeature.ArrayFilter, node, caller, ...params); case "reduce": return this.transformLuaLibFunction(LuaLibFeature.ArrayReduce, node, caller, ...params); + case "reduceRight": + return this.transformLuaLibFunction(LuaLibFeature.ArrayReduceRight, node, caller, ...params); case "some": return this.transformLuaLibFunction(LuaLibFeature.ArraySome, node, caller, ...params); case "every": diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts new file mode 100644 index 000000000..2ac6d21d3 --- /dev/null +++ b/src/lualib/ArrayReduceRight.ts @@ -0,0 +1,29 @@ +// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce +function __TS__ArrayReduceRight( + this: void, + arr: T[], + callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, + ...initial: Vararg +): T { + const len = arr.length; + + let k = len - 1; + let accumulator = undefined; + + // Check if initial value is present in function call + if (select("#", ...initial) !== 0) { + accumulator = select(1, ...initial); + } else if (len > 0) { + accumulator = arr[k]; + k = k - 1; + } else { + // tslint:disable-next-line: no-string-throw + throw "Reduce of empty array with no initial value"; + } + + for (const i of forRange(k, 0, -1)) { + accumulator = callbackFn(accumulator, arr[i], i, arr); + } + + return accumulator; +} diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 00d831fdb..51aac9cc3 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -507,31 +507,33 @@ test.each([ util.testExpressionTemplate`${array}.flatMap(${map})`.expectToEqual(expected); }); -test.each<[[(total: number, currentItem: number, index: number, array: number[]) => number, number?]]>([ - [[(total, currentItem) => total + currentItem]], - [[(total, currentItem) => total * currentItem]], - [[(total, currentItem) => total + currentItem, 10]], - [[(total, currentItem) => total * currentItem, 10]], - [[(total, _, index, array) => total + array[index]]], - [[(a, b) => a + b]], -])("array.reduce (%p)", args => { - util.testExpression`[1, 3, 5, 7].reduce(${util.formatCode(...args)})`.expectToMatchJsResult(); -}); +describe.each(["reduce", "reduceRight"])("array.%s", reduce => { + test.each<[[(total: number, currentItem: number, index: number, array: number[]) => number, number?]]>([ + [[(total, currentItem) => total + currentItem]], + [[(total, currentItem) => total * currentItem]], + [[(total, currentItem) => total + currentItem, 10]], + [[(total, currentItem) => total * currentItem, 10]], + [[(total, _, index, array) => total + array[index]]], + [[(a, b) => a + b]], + ])("usage (%p)", args => { + util.testExpression`[1, 3, 5, 7].${reduce}(${util.formatCode(...args)})`.expectToMatchJsResult(); + }); -test("array.reduce empty undefined initial", () => { - util.testExpression`[].reduce(() => {}, undefined)`.expectToMatchJsResult(); -}); + test("empty undefined initial", () => { + util.testExpression`[].${reduce}(() => {}, undefined)`.expectToMatchJsResult(); + }); -test("array.reduce empty no initial", () => { - util.testExpression`[].reduce(() => {})`.expectToMatchJsResult(true); -}); + test("empty no initial", () => { + util.testExpression`[].${reduce}(() => {})`.expectToMatchJsResult(true); + }); -test("array.reduce undefined returning callback", () => { - util.testFunction` - const calls: Array<{ a: void, b: string }> = []; - ["a", "b"].reduce((a, b) => { calls.push({ a, b }) }, undefined); - return calls; - `.expectToMatchJsResult(); + test("undefined returning callback", () => { + util.testFunction` + const calls: Array<{ a: void, b: string }> = []; + ["a", "b"].${reduce}((a, b) => { calls.push({ a, b }) }, undefined); + return calls; + `.expectToMatchJsResult(); + }); }); const genericChecks = [ From 0a3fce67f51da1dbb90eaaa143b023f9741ef847 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 9 Oct 2019 22:08:19 +0200 Subject: [PATCH 182/764] 0.28.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3b501293..ee0062bf3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.27.1", + "version": "0.28.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index eb409eb1a..3c08b8fa1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.27.1", + "version": "0.28.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From bce6a6900a423d7797a0723026f2346a24e7579d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 9 Oct 2019 22:41:33 +0200 Subject: [PATCH 183/764] Update CHANGELOG.md 0.28.0 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0dab5e74..1bbf79dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.28.0 + +- We now have a `noImplicitSelf` option you can add to your tstl tsconfig.json. Default behavior is `false`. Setting this option to `true` will cause no 'self' arguments to be considered/generated in the project. Declarations will behave as if they have a `/** @noSelfInFile */` directive. This option is new and might cause correctness issues, use at your own risk and create an issue if you experience any issues. +- Regular `Error` objects can now be thrown, `throw` is no longer limited to only strings. Take care: printing/toString'ing the LuaLib error class might have different results for different Lua versions. +- Added LuaLib support for `array.reduceRight`. +- Added LuaLib support for `array.find`. + +- Fixed an issue in test code causing some inconsistent behavior between JS <-> Lua to go unnoticed. Also fixed `array.splice` and `array.join` whose Lua versions behaved differently from the ECMAScript specification. +- Fixed array.reduce not behaving according to ECMAScript specification. +- Fixed order of operations issue with ternary conditional. + +- Updated to TS 3.6. +- Moved from Travis+Appveyor to GitHub Actions! + ## 0.27.0 - Added support for [array and object destructuring with rest](https://basarat.gitbooks.io/typescript/content/docs/destructuring.html#object-destructuring-with-rest). From 53be6c32388d75e91a8ae1858bc0330094980372 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 9 Oct 2019 22:57:33 +0200 Subject: [PATCH 184/764] Removed --dry-run from release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b344325aa..fa6e9c5dc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,6 +15,6 @@ jobs: - run: npm install --global npm@6 - run: npm ci - run: npm run build - - run: npm publish --dry-run + - run: npm publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} From 5d2d64bc018a58594651326f45f8dcefec408f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Miernik?= Date: Tue, 22 Oct 2019 23:02:54 +0200 Subject: [PATCH 185/764] Fixed array.flat[Map] on [[]] (fixes #719). (#737) * Fixed array.flat[Map] on [[]] (fixes #719). * Added failing flat[Map] tests. * Added empty table checks. * Added a clean workaround for next. * Documented workaround. --- src/lualib/ArrayFlat.ts | 8 +++++++- src/lualib/ArrayFlatMap.ts | 7 ++++++- src/lualib/declarations/global.d.ts | 3 +++ test/unit/builtins/array.spec.ts | 4 ++++ 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index 4006b51d5..54120e69a 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,7 +1,13 @@ function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { let result: any[] = []; for (const value of array) { - if (depth > 0 && type(value) === "table" && 1 in value) { + if ( + depth > 0 && + type(value) === "table" && + // Workaround to determine if value is an array or not (fails in case of objects without keys) + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined) + ) { result = result.concat(__TS__ArrayFlat(value, depth - 1)); } else { result[result.length] = value; diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 7bd7a8a22..02d58329b 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -6,7 +6,12 @@ function __TS__ArrayFlatMap( let result: U[] = []; for (let i = 0; i < array.length; i++) { const value = callback(array[i], i, array); - if (type(value) === "table" && 1 in value) { + if ( + type(value) === "table" && + // Workaround to determine if value is an array or not (fails in case of objects without keys) + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + (1 in value || (next as NextEmptyCheck)(value as any, undefined) === undefined) + ) { result = result.concat(value); } else { result[result.length] = value as U; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 77a88b694..4a86d2542 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -5,6 +5,9 @@ declare var __TS__originalTraceback: | ((this: void, thread?: any, message?: string, level?: number) => string) | undefined; +// Override next declaration so we can omit extra return values +declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; + declare function tonumber(value: any, base?: number): number | undefined; declare function type( value: any diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 51aac9cc3..56d144e02 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -487,6 +487,8 @@ test.each([ }); test.each([ + { array: [[]], expected: [] }, + { array: [{ a: 1 }, { a: 2 }, { a: 3 }], expected: [{ a: 1 }, { a: 2 }, { a: 3 }] }, { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, @@ -497,6 +499,8 @@ test.each([ }); test.each([ + { array: [[]], map: (v: T) => v, expected: [] }, + { array: [1, 2, 3], map: (v: number) => ({ a: v * 2 }), expected: [{ a: 2 }, { a: 4 }, { a: 6 }] }, { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, From 0f5c5aa32001c32883d593b1cf1d4b3942540273 Mon Sep 17 00:00:00 2001 From: Lars Melchior Date: Sat, 26 Oct 2019 16:54:00 +0200 Subject: [PATCH 186/764] Support non-string errors with SourceMapTraceback (#741) * support custom errors with SourceMapTraceback * pass-through non-string tracebacks * minimize changes --- src/lualib/SourceMapTraceBack.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 374f52b10..edad12c45 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -8,6 +8,11 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li globalThis.__TS__originalTraceback = debug.traceback; debug.traceback = (thread, message, level) => { const trace = globalThis.__TS__originalTraceback(thread, message, level); + + if (typeof trace !== "string") { + return trace; + } + const [result] = string.gsub(trace, "(%S+).lua:(%d+)", (file, line) => { const fileSourceMap = globalThis.__TS__sourcemap[file + ".lua"]; if (fileSourceMap && fileSourceMap[line]) { From 38608428ab794db7cd489638f695251f8adfdc70 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 1 Nov 2019 01:43:36 +0500 Subject: [PATCH 187/764] Refactor CLI file structure and fix `--project` path resolution on Windows (#743) * Fix `--project` path resolution on Windows * Add tests * Remove unnecessary condition part * Reset working directory after running tests * Refactor CLI directory structure * Move `tstl` out of `cli` directory * Rename `config` to `tsconfig` * Remove `cli/tsconfig` module reexport --- package-lock.json | 43 +++++++ package.json | 2 + src/Emit.ts | 4 +- src/TSTransformers.ts | 9 +- src/cli/diagnostics.ts | 81 ++++++++++++++ src/cli/information.ts | 32 ++++++ src/{CommandLineParser.ts => cli/parse.ts} | 78 ++----------- src/cli/report.ts | 12 ++ src/cli/tsconfig.ts | 82 ++++++++++++++ src/diagnostics.ts | 80 ------------- src/index.ts | 11 +- src/tstl.ts | 105 +++++------------- src/typescript-internal.ts | 7 ++ src/utils.ts | 1 + .../parse.spec.ts} | 0 test/cli/tsconfig.spec.ts | 93 ++++++++++++++++ 16 files changed, 399 insertions(+), 241 deletions(-) create mode 100644 src/cli/diagnostics.ts create mode 100644 src/cli/information.ts rename src/{CommandLineParser.ts => cli/parse.ts} (67%) create mode 100644 src/cli/report.ts create mode 100644 src/cli/tsconfig.ts create mode 100644 src/utils.ts rename test/{unit/commandLineParser.spec.ts => cli/parse.spec.ts} (100%) create mode 100644 test/cli/tsconfig.spec.ts diff --git a/package-lock.json b/package-lock.json index ee0062bf3..a4794e0aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -623,6 +623,15 @@ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", "dev": true }, + "@types/fs-extra": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.1.tgz", + "integrity": "sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", @@ -1861,6 +1870,25 @@ "map-cache": "^0.2.2" } }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -3493,6 +3521,15 @@ "minimist": "^1.2.0" } }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -5221,6 +5258,12 @@ "set-value": "^2.0.1" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", diff --git a/package.json b/package.json index 3c08b8fa1..5ea65f798 100644 --- a/package.json +++ b/package.json @@ -44,11 +44,13 @@ "typescript": "^3.6.2" }, "devDependencies": { + "@types/fs-extra": "^8.0.1", "@types/glob": "^7.1.1", "@types/jest": "^24.0.15", "@types/node": "^11.13.14", "@types/resolve": "0.0.8", "fengari": "^0.1.4", + "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.0", "jest": "^24.8.0", "jest-circus": "^24.8.0", diff --git a/src/Emit.ts b/src/Emit.ts index 50d5c1fdf..ecb1453f9 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -1,10 +1,10 @@ import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; -import { TranspiledFile, EmitHost } from "./Transpile"; +import { EmitHost, TranspiledFile } from "./Transpile"; +import { normalizeSlashes } from "./utils"; const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); -const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); export interface OutputFile { name: string; diff --git a/src/TSTransformers.ts b/src/TSTransformers.ts index 8cc38356c..710e3ac0e 100644 --- a/src/TSTransformers.ts +++ b/src/TSTransformers.ts @@ -1,6 +1,7 @@ import * as path from "path"; import * as resolve from "resolve"; import * as ts from "typescript"; +import * as cliDiagnostics from "./cli/diagnostics"; import { CompilerOptions, TransformerImport } from "./CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; import { noImplicitSelfTransformer } from "./NoImplicitSelfTransformer"; @@ -111,7 +112,7 @@ function resolveTransformerFactory( ): { error?: ts.Diagnostic; factory?: TransformerFactory } { if (typeof transform !== "string") { const optionName = `${transformerOptionPath}.transform`; - return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "string") }; + return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "string") }; } let resolved: string; @@ -167,18 +168,18 @@ function loadTransformer( break; default: { const optionName = `--${transformerOptionPath}.type`; - return { error: diagnosticFactories.argumentForOptionMustBe(optionName, "program") }; + return { error: cliDiagnostics.argumentForOptionMustBe(optionName, "program") }; } } if (typeof after !== "boolean") { const optionName = `${transformerOptionPath}.after`; - return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "boolean") }; + return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "boolean") }; } if (typeof afterDeclarations !== "boolean") { const optionName = `${transformerOptionPath}.afterDeclarations`; - return { error: diagnosticFactories.compilerOptionRequiresAValueOfType(optionName, "boolean") }; + return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "boolean") }; } if (typeof transformer === "function") { diff --git a/src/cli/diagnostics.ts b/src/cli/diagnostics.ts new file mode 100644 index 000000000..9e950710f --- /dev/null +++ b/src/cli/diagnostics.ts @@ -0,0 +1,81 @@ +import * as ts from "typescript"; + +export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Warning, + code: 0, + source: "typescript-to-lua", + messageText: + 'TSTL options are moving to the "tstl" object. Adjust your tsconfig to look like\n' + + `"tstl": ${JSON.stringify(tstl, undefined, 4)}`, +}); + +export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Message, + code: errorCount === 1 ? 6193 : 6194, + messageText: + errorCount === 1 + ? "Found 1 error. Watching for file changes." + : `Found ${errorCount} errors. Watching for file changes.`, +}); + +const createCommandLineError = (code: number, getMessage: (...args: Args) => string) => ( + ...args: Args +): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code, + messageText: getMessage(...args), +}); + +export const unknownCompilerOption = createCommandLineError( + 5023, + (name: string) => `Unknown compiler option '${name}'.` +); + +export const compilerOptionRequiresAValueOfType = createCommandLineError( + 5024, + (name: string, type: string) => `Compiler option '${name}' requires a value of type ${type}.` +); + +export const optionProjectCannotBeMixedWithSourceFilesOnACommandLine = createCommandLineError( + 5042, + () => "Option 'project' cannot be mixed with source files on a command line." +); + +export const cannotFindATsconfigJsonAtTheSpecifiedDirectory = createCommandLineError( + 5057, + (dir: string) => `Cannot find a tsconfig.json file at the specified directory: '${dir}'.` +); + +export const theSpecifiedPathDoesNotExist = createCommandLineError( + 5058, + (dir: string) => `The specified path does not exist: '${dir}'.` +); + +export const compilerOptionExpectsAnArgument = createCommandLineError( + 6044, + (name: string) => `Compiler option '${name}' expects an argument.` +); + +export const argumentForOptionMustBe = createCommandLineError( + 6046, + (name: string, values: string) => `Argument for '${name}' option must be: ${values}.` +); + +export const optionCanOnlyBeSpecifiedInTsconfigJsonFile = createCommandLineError( + 6064, + (name: string) => `Option '${name}' can only be specified in 'tsconfig.json' file.` +); + +export const optionBuildMustBeFirstCommandLineArgument = createCommandLineError( + 6369, + () => "Option '--build' must be the first command line argument." +); diff --git a/src/cli/information.ts b/src/cli/information.ts new file mode 100644 index 000000000..df39c0ecd --- /dev/null +++ b/src/cli/information.ts @@ -0,0 +1,32 @@ +import { optionDeclarations } from "./parse"; + +export const { version } = require("../../package.json"); +export const versionString = `Version ${version}`; + +const helpString = ` +Syntax: tstl [options] [files...] + +Examples: tstl path/to/file.ts [...] + tstl -p path/to/tsconfig.json + +In addition to the options listed below you can also pass options +for the typescript compiler (For a list of options use tsc -h). +Some tsc options might have no effect. +`.trim(); + +export function getHelpString(): string { + let result = helpString + "\n\n"; + + result += "Options:\n"; + for (const option of optionDeclarations) { + const aliasStrings = (option.aliases || []).map(a => "-" + a); + const optionString = aliasStrings.concat(["--" + option.name]).join("|"); + + const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; + const spacing = " ".repeat(Math.max(1, 45 - optionString.length - valuesHint.length)); + + result += `\n ${optionString} <${valuesHint}>${spacing}${option.description}\n`; + } + + return result; +} diff --git a/src/CommandLineParser.ts b/src/cli/parse.ts similarity index 67% rename from src/CommandLineParser.ts rename to src/cli/parse.ts index d657e0127..8bbaad42b 100644 --- a/src/CommandLineParser.ts +++ b/src/cli/parse.ts @@ -1,7 +1,6 @@ -import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; -import * as diagnosticFactories from "./diagnostics"; +import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; +import * as cliDiagnostics from "./diagnostics"; export interface ParsedCommandLine extends ts.ParsedCommandLine { options: CompilerOptions; @@ -24,7 +23,7 @@ interface CommandLineOptionOfBoolean extends CommandLineOptionBase { type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean; -const optionDeclarations: CommandLineOption[] = [ +export const optionDeclarations: CommandLineOption[] = [ { name: "luaLibImport", description: "Specifies how js standard features missing in lua are imported.", @@ -60,36 +59,6 @@ const optionDeclarations: CommandLineOption[] = [ }, ]; -export const version = `Version ${require("../package.json").version}`; - -const helpString = ` -Syntax: tstl [options] [files...] - -Examples: tstl path/to/file.ts [...] - tstl -p path/to/tsconfig.json - -In addition to the options listed below you can also pass options -for the typescript compiler (For a list of options use tsc -h). -Some tsc options might have no effect. -`.trim(); - -export function getHelpString(): string { - let result = helpString + "\n\n"; - - result += "Options:\n"; - for (const option of optionDeclarations) { - const aliasStrings = (option.aliases || []).map(a => "-" + a); - const optionString = aliasStrings.concat(["--" + option.name]).join("|"); - - const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; - const spacing = " ".repeat(Math.max(1, 45 - optionString.length - valuesHint.length)); - - result += `\n ${optionString} <${valuesHint}>${spacing}${option.description}\n`; - } - - return result; -} - export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { let hasRootLevelOptions = false; for (const key in parsedConfigFile.raw) { @@ -103,15 +72,13 @@ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): if (parsedConfigFile.raw.tstl) { if (hasRootLevelOptions) { - parsedConfigFile.errors.push( - diagnosticFactories.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl) - ); + parsedConfigFile.errors.push(cliDiagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl)); } for (const key in parsedConfigFile.raw.tstl) { const option = optionDeclarations.find(option => option.name === key); if (!option) { - parsedConfigFile.errors.push(diagnosticFactories.unknownCompilerOption(key)); + parsedConfigFile.errors.push(cliDiagnostics.unknownCompilerOption(key)); continue; } @@ -179,7 +146,7 @@ function readCommandLineArgument(option: CommandLineOption, value: any): Command if (value === undefined) { return { - error: diagnosticFactories.compilerOptionExpectsAnArgument(option.name), + error: cliDiagnostics.compilerOptionExpectsAnArgument(option.name), value: undefined, increment: 0, }; @@ -201,7 +168,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (typeof value !== "boolean") { return { value: undefined, - error: diagnosticFactories.compilerOptionRequiresAValueOfType(option.name, "boolean"), + error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, "boolean"), }; } @@ -212,7 +179,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (typeof value !== "string") { return { value: undefined, - error: diagnosticFactories.compilerOptionRequiresAValueOfType(option.name, "string"), + error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, "string"), }; } @@ -221,7 +188,7 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { const optionChoices = option.choices.join(", "); return { value: undefined, - error: diagnosticFactories.argumentForOptionMustBe(`--${option.name}`, optionChoices), + error: cliDiagnostics.argumentForOptionMustBe(`--${option.name}`, optionChoices), }; } @@ -229,30 +196,3 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { } } } - -export function parseConfigFileWithSystem( - configFileName: string, - commandLineOptions?: CompilerOptions, - system = ts.sys -): ParsedCommandLine { - const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent( - ts.readJsonConfigFile(configFileName, system.readFile), - system, - path.dirname(configFileName), - commandLineOptions, - configFileName - ); - - return updateParsedConfigFile(parsedConfigFile); -} - -export function createDiagnosticReporter(pretty: boolean, system = ts.sys): ts.DiagnosticReporter { - const reporter: ts.DiagnosticReporter = (ts as any).createDiagnosticReporter(system, pretty); - return diagnostic => { - if (diagnostic.source === "typescript-to-lua") { - diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; - } - - reporter(diagnostic); - }; -} diff --git a/src/cli/report.ts b/src/cli/report.ts new file mode 100644 index 000000000..039ca069c --- /dev/null +++ b/src/cli/report.ts @@ -0,0 +1,12 @@ +import * as ts from "typescript"; + +export function createDiagnosticReporter(pretty: boolean, system = ts.sys): ts.DiagnosticReporter { + const reporter = ts.createDiagnosticReporter(system, pretty); + return diagnostic => { + if (diagnostic.source === "typescript-to-lua") { + diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; + } + + reporter(diagnostic); + }; +} diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts new file mode 100644 index 000000000..369c14363 --- /dev/null +++ b/src/cli/tsconfig.ts @@ -0,0 +1,82 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { CompilerOptions } from "../CompilerOptions"; +import { normalizeSlashes } from "../utils"; +import * as cliDiagnostics from "./diagnostics"; +import { ParsedCommandLine, updateParsedConfigFile } from "./parse"; + +export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic | string | undefined { + const { project } = commandLine.options; + if (!project) { + if (commandLine.fileNames.length > 0) { + return undefined; + } + + const searchPath = normalizeSlashes(ts.sys.getCurrentDirectory()); + return ts.findConfigFile(searchPath, ts.sys.fileExists); + } + + if (commandLine.fileNames.length !== 0) { + return cliDiagnostics.optionProjectCannotBeMixedWithSourceFilesOnACommandLine(); + } + + // TODO: Unlike tsc, this resolves `.` to absolute path + const fileOrDirectory = normalizeSlashes(path.resolve(ts.sys.getCurrentDirectory(), project)); + if (ts.sys.directoryExists(fileOrDirectory)) { + const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); + if (ts.sys.fileExists(configFileName)) { + return configFileName; + } else { + return cliDiagnostics.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project); + } + } else if (ts.sys.fileExists(fileOrDirectory)) { + return fileOrDirectory; + } else { + return cliDiagnostics.theSpecifiedPathDoesNotExist(project); + } +} + +export function parseConfigFileWithSystem( + configFileName: string, + commandLineOptions?: CompilerOptions, + system = ts.sys +): ParsedCommandLine { + const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent( + ts.readJsonConfigFile(configFileName, system.readFile), + system, + path.dirname(configFileName), + commandLineOptions, + configFileName + ); + + return updateParsedConfigFile(parsedConfigFile); +} + +export function createConfigFileUpdater( + optionsToExtend: CompilerOptions +): (options: ts.CompilerOptions) => ts.Diagnostic[] { + const configFileMap = new WeakMap(); + return options => { + const configFile = options.configFile as ts.TsConfigSourceFile | undefined; + const configFilePath = options.configFilePath as string | undefined; + if (!configFile || !configFilePath) return []; + + if (!configFileMap.has(configFile)) { + const parsedConfigFile = updateParsedConfigFile( + ts.parseJsonSourceFileConfigFileContent( + configFile, + ts.sys, + path.dirname(configFilePath), + optionsToExtend, + configFilePath + ) + ); + + configFileMap.set(configFile, parsedConfigFile); + } + + const parsedConfigFile = configFileMap.get(configFile)!; + Object.assign(options, parsedConfigFile.options); + return parsedConfigFile.errors; + }; +} diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 2f052d272..5e614a380 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -11,18 +11,6 @@ export const transpileError = (error: TranspileError): ts.Diagnostic => ({ messageText: error.message, }); -export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Warning, - code: 0, - source: "typescript-to-lua", - messageText: - 'TSTL options are moving to the "tstl" object. Adjust your tsconfig to look like\n' + - `"tstl": ${JSON.stringify(tstl, undefined, 4)}`, -}); - export const toLoadTransformerItShouldBeTranspiled = (transform: string): ts.Diagnostic => ({ file: undefined, start: undefined, @@ -62,71 +50,3 @@ export const transformerShouldBeATsTransformerFactory = (transform: string): ts. source: "typescript-to-lua", messageText: `"${transform}" transformer should be a ts.TransformerFactory or an object with ts.TransformerFactory values`, }); - -export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Message, - code: errorCount === 1 ? 6193 : 6194, - messageText: - errorCount === 1 - ? "Found 1 error. Watching for file changes." - : `Found ${errorCount} errors. Watching for file changes.`, -}); - -const createCommandLineError = (code: number, getMessage: (...args: Args) => string) => ( - ...args: Args -): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code, - messageText: getMessage(...args), -}); - -export const unknownCompilerOption = createCommandLineError( - 5023, - (name: string) => `Unknown compiler option '${name}'.` -); - -export const compilerOptionRequiresAValueOfType = createCommandLineError( - 5024, - (name: string, type: string) => `Compiler option '${name}' requires a value of type ${type}.` -); - -export const optionProjectCannotBeMixedWithSourceFilesOnACommandLine = createCommandLineError( - 5042, - () => "Option 'project' cannot be mixed with source files on a command line." -); - -export const cannotFindATsconfigJsonAtTheSpecifiedDirectory = createCommandLineError( - 5057, - (dir: string) => `Cannot find a tsconfig.json file at the specified directory: '${dir}'.` -); - -export const theSpecifiedPathDoesNotExist = createCommandLineError( - 5058, - (dir: string) => `The specified path does not exist: '${dir}'.` -); - -export const compilerOptionExpectsAnArgument = createCommandLineError( - 6044, - (name: string) => `Compiler option '${name}' expects an argument.` -); - -export const argumentForOptionMustBe = createCommandLineError( - 6046, - (name: string, values: string) => `Argument for '${name}' option must be: ${values}.` -); - -export const optionCanOnlyBeSpecifiedInTsconfigJsonFile = createCommandLineError( - 6064, - (name: string) => `Option '${name}' can only be specified in 'tsconfig.json' file.` -); - -export const optionBuildMustBeFirstCommandLineArgument = createCommandLineError( - 6369, - () => "Option '--build' must be the first command line argument." -); diff --git a/src/index.ts b/src/index.ts index 17226cf7f..f9a514fb6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,17 +1,14 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; -import { parseConfigFileWithSystem } from "./CommandLineParser"; +import { parseConfigFileWithSystem } from "./cli/tsconfig"; import { CompilerOptions } from "./CompilerOptions"; import { emitTranspiledFiles, OutputFile } from "./Emit"; import { transpile, TranspiledFile, TranspileResult } from "./Transpile"; -export { - createDiagnosticReporter, - parseCommandLine, - ParsedCommandLine, - updateParsedConfigFile, -} from "./CommandLineParser"; +export { version } from "./cli/information"; +export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./cli/parse"; +export * from "./cli/report"; export * from "./CompilerOptions"; export * from "./Emit"; export * from "./LuaAST"; diff --git a/src/tstl.ts b/src/tstl.ts index 8860b8929..e3c416f6e 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -1,13 +1,11 @@ #!/usr/bin/env node -import * as path from "path"; import * as ts from "typescript"; import * as tstl from "."; -import * as CommandLineParser from "./CommandLineParser"; -import * as diagnosticFactories from "./diagnostics"; - -function createWatchStatusReporter(options?: ts.CompilerOptions): ts.WatchStatusReporter { - return (ts as any).createWatchStatusReporter(ts.sys, shouldBePretty(options)); -} +import * as cliDiagnostics from "./cli/diagnostics"; +import { getHelpString, versionString } from "./cli/information"; +import { parseCommandLine } from "./cli/parse"; +import { createDiagnosticReporter } from "./cli/report"; +import { createConfigFileUpdater, locateConfigFile, parseConfigFileWithSystem } from "./cli/tsconfig"; function shouldBePretty(options?: ts.CompilerOptions): boolean { return !options || options.pretty === undefined @@ -15,49 +13,13 @@ function shouldBePretty(options?: ts.CompilerOptions): boolean { : Boolean(options.pretty); } -let reportDiagnostic = tstl.createDiagnosticReporter(false); +let reportDiagnostic = createDiagnosticReporter(false); function updateReportDiagnostic(options?: ts.CompilerOptions): void { - reportDiagnostic = tstl.createDiagnosticReporter(shouldBePretty(options)); + reportDiagnostic = createDiagnosticReporter(shouldBePretty(options)); } -function locateConfigFile(commandLine: tstl.ParsedCommandLine): string | undefined { - const { project } = commandLine.options; - if (!project) { - if (commandLine.fileNames.length === 0) { - const searchPath = path.posix.normalize(ts.sys.getCurrentDirectory()); - return ts.findConfigFile(searchPath, ts.sys.fileExists); - } - return; - } - - if (commandLine.fileNames.length !== 0) { - reportDiagnostic(diagnosticFactories.optionProjectCannotBeMixedWithSourceFilesOnACommandLine()); - ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); - return; - } - - let fileOrDirectory = path.posix.normalize(project); - if (!path.isAbsolute(fileOrDirectory)) { - fileOrDirectory = path.posix.join(ts.sys.getCurrentDirectory(), fileOrDirectory); - } - - if (!fileOrDirectory || ts.sys.directoryExists(fileOrDirectory)) { - const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); - if (ts.sys.fileExists(configFileName)) { - return configFileName; - } else { - reportDiagnostic(diagnosticFactories.cannotFindATsconfigJsonAtTheSpecifiedDirectory(project)); - - ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); - } - } else { - if (ts.sys.fileExists(fileOrDirectory)) { - return fileOrDirectory; - } else { - reportDiagnostic(diagnosticFactories.theSpecifiedPathDoesNotExist(project)); - ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); - } - } +function createWatchStatusReporter(options?: ts.CompilerOptions): ts.WatchStatusReporter { + return ts.createWatchStatusReporter(ts.sys, shouldBePretty(options)); } function executeCommandLine(args: string[]): void { @@ -68,10 +30,10 @@ function executeCommandLine(args: string[]): void { } } - const commandLine = CommandLineParser.parseCommandLine(args); + const commandLine = parseCommandLine(args); if (commandLine.options.build) { - reportDiagnostic(diagnosticFactories.optionBuildMustBeFirstCommandLineArgument()); + reportDiagnostic(cliDiagnostics.optionBuildMustBeFirstCommandLineArgument()); return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); } @@ -83,20 +45,25 @@ function executeCommandLine(args: string[]): void { } if (commandLine.options.version) { - console.log(CommandLineParser.version); + console.log(versionString); return ts.sys.exit(ts.ExitStatus.Success); } if (commandLine.options.help) { - console.log(CommandLineParser.version); - console.log(CommandLineParser.getHelpString()); + console.log(versionString); + console.log(getHelpString()); return ts.sys.exit(ts.ExitStatus.Success); } const configFileName = locateConfigFile(commandLine); + if (typeof configFileName === "object") { + reportDiagnostic(configFileName); + return ts.sys.exit(ts.ExitStatus.DiagnosticsPresent_OutputsSkipped); + } + const commandLineOptions = commandLine.options; if (configFileName) { - const configParseResult = CommandLineParser.parseConfigFileWithSystem(configFileName, commandLineOptions); + const configParseResult = parseConfigFileWithSystem(configFileName, commandLineOptions); updateReportDiagnostic(configParseResult.options); if (configParseResult.options.watch) { @@ -191,34 +158,12 @@ function updateWatchCompilationHost( optionsToExtend: tstl.CompilerOptions ): void { let fullRecompile = true; - const configFileMap = new WeakMap(); + const updateConfigFile = createConfigFileUpdater(optionsToExtend); host.afterProgramCreate = builderProgram => { const program = builderProgram.getProgram(); const options = builderProgram.getCompilerOptions() as tstl.CompilerOptions; - - let configFileParsingDiagnostics: ts.Diagnostic[] = []; - const configFile = options.configFile as ts.TsConfigSourceFile | undefined; - const configFilePath = options.configFilePath as string | undefined; - if (configFile && configFilePath) { - if (!configFileMap.has(configFile)) { - const parsedConfigFile = CommandLineParser.updateParsedConfigFile( - ts.parseJsonSourceFileConfigFileContent( - configFile, - ts.sys, - path.dirname(configFilePath), - optionsToExtend, - configFilePath - ) - ); - - configFileMap.set(configFile, parsedConfigFile); - } - - const parsedConfigFile = configFileMap.get(configFile)!; - Object.assign(options, parsedConfigFile.options); - configFileParsingDiagnostics = parsedConfigFile.errors; - } + const configFileParsingDiagnostics: ts.Diagnostic[] = updateConfigFile(options); let sourceFiles: ts.SourceFile[] | undefined; if (!fullRecompile) { @@ -255,10 +200,12 @@ function updateWatchCompilationHost( // do a full recompile after an error fullRecompile = errors.length > 0; - host.onWatchStatusChange!(diagnosticFactories.watchErrorSummary(errors.length), host.getNewLine(), options); + host.onWatchStatusChange!(cliDiagnostics.watchErrorSummary(errors.length), host.getNewLine(), options); }; } -if ((ts.sys as any).setBlocking) (ts.sys as any).setBlocking(); +if (ts.sys.setBlocking) { + ts.sys.setBlocking(); +} executeCommandLine(ts.sys.args); diff --git a/src/typescript-internal.ts b/src/typescript-internal.ts index ddff96eaf..6f5819c38 100644 --- a/src/typescript-internal.ts +++ b/src/typescript-internal.ts @@ -1,6 +1,13 @@ import * as ts from "typescript"; declare module "typescript" { + function createDiagnosticReporter(system: ts.System, pretty?: boolean): ts.DiagnosticReporter; + function createWatchStatusReporter(system: ts.System, pretty?: boolean): ts.WatchStatusReporter; + + interface System { + setBlocking?(): void; + } + interface Statement { jsDoc?: ts.JSDoc[]; } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 000000000..0fe3f68b6 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1 @@ +export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); diff --git a/test/unit/commandLineParser.spec.ts b/test/cli/parse.spec.ts similarity index 100% rename from test/unit/commandLineParser.spec.ts rename to test/cli/parse.spec.ts diff --git a/test/cli/tsconfig.spec.ts b/test/cli/tsconfig.spec.ts new file mode 100644 index 000000000..b4fac5cbf --- /dev/null +++ b/test/cli/tsconfig.spec.ts @@ -0,0 +1,93 @@ +import * as fs from "fs-extra"; +import * as os from "os"; +import * as path from "path"; +import { locateConfigFile } from "../../src/cli/tsconfig"; +import { normalizeSlashes } from "../../src/utils"; + +let temp: string; +beforeEach(async () => { + temp = await fs.mkdtemp(path.join(os.tmpdir(), "tstl-test-")); + process.chdir(temp); +}); + +const originalWorkingDirectory = process.cwd(); +afterEach(async () => { + process.chdir(originalWorkingDirectory); + // TODO [node@12]: `rmdir` has `recursive` option + await fs.remove(temp); +}); + +const locate = (project: string | undefined, fileNames: string[] = []) => + locateConfigFile({ errors: [], fileNames, options: { project } }); + +const normalize = (name: string) => normalizeSlashes(path.resolve(temp, name)); + +describe("specified", () => { + for (const separator of process.platform === "win32" ? ["/", "\\"] : ["/"]) { + for (const pointsTo of ["file", "directory"] as const) { + const findAndExpect = (project: string, expected: string) => { + project = project.replace(/[\\/]/g, separator); + if (pointsTo === "directory") { + project = path.dirname(project); + } + + expect(locate(project)).toBe(normalize(expected)); + }; + + test(`relative to ${pointsTo} separated with '${separator}'`, async () => { + await fs.outputFile("tsconfig.json", ""); + await fs.mkdir("src"); + process.chdir("src"); + findAndExpect("../tsconfig.json", "tsconfig.json"); + }); + + test(`absolute to ${pointsTo} separated with '${separator}'`, async () => { + await fs.outputFile("tsconfig.json", ""); + findAndExpect(path.resolve("tsconfig.json"), "tsconfig.json"); + }); + } + } + + test.each(["", ".", "./"])("current directory (%p)", async () => { + await fs.outputFile("tsconfig.json", ""); + expect(locate(".")).toBe(normalize("tsconfig.json")); + }); +}); + +describe("inferred", () => { + test("in current directory", async () => { + await fs.outputFile("tsconfig.json", ""); + expect(locate(undefined)).toBe(normalize("tsconfig.json")); + }); + + test("in parent directory", async () => { + await fs.outputFile("tsconfig.json", ""); + await fs.mkdir("src"); + process.chdir("src"); + expect(locate(undefined)).toBe(normalize("tsconfig.json")); + }); + + test("not found", () => { + expect(locate(undefined)).toBe(undefined); + }); + + test("does not attempt when has files", async () => { + await fs.outputFile("tsconfig.json", ""); + expect(locate(undefined, [""])).toBe(undefined); + }); +}); + +describe("errors", () => { + test("specified file does not exist", () => { + expect([locate("tsconfig.json")]).toHaveDiagnostics(); + }); + + test("specified directory does not exist", () => { + expect([locate("project")]).toHaveDiagnostics(); + }); + + test("cannot be mixed", async () => { + await fs.outputFile("tsconfig.json", ""); + expect([locate("tsconfig.json", [""])]).toHaveDiagnostics(); + }); +}); From f0f057d4352d63c1bd136c3037cefacfa29bcc75 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 31 Oct 2019 22:12:04 +0100 Subject: [PATCH 188/764] 0.28.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a4794e0aa..a69f58e8f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.28.0", + "version": "0.28.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5ea65f798..0ecb94080 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.28.0", + "version": "0.28.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 1b580b4832c8a2956a5160f3942d9f313bd6375c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 1 Nov 2019 21:55:29 +0100 Subject: [PATCH 189/764] Add registry url to release workflow (#744) * Add registry url * Fixed linter issue in release workflow --- .github/workflows/release.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fa6e9c5dc..55f5b96f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,6 +12,8 @@ jobs: steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 + with: + registry-url: "https://registry.npmjs.org" - run: npm install --global npm@6 - run: npm ci - run: npm run build From c7b381044f96c15fa26eb64f870d2edc7ccb2c11 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 27 Nov 2019 00:45:56 +0500 Subject: [PATCH 190/764] Implement Number.prototype.toString(radix) (#752) * Implement Number.prototype.toString(radix) * Use `flatMap` to make combinations * Test special values separately * Add link to spec --- src/LuaLib.ts | 1 + src/LuaTransformer.ts | 25 +++++++++++++-- src/lualib/NumberToString.ts | 49 +++++++++++++++++++++++++++++ src/lualib/declarations/math.d.ts | 5 +++ src/lualib/declarations/string.d.ts | 1 + src/utils.ts | 15 +++++++++ test/unit/builtins/numbers.spec.ts | 13 ++++++++ 7 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/lualib/NumberToString.ts create mode 100644 src/lualib/declarations/math.d.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index c877dd9cc..b50ab1e75 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -40,6 +40,7 @@ export enum LuaLibFeature { Number = "Number", NumberIsFinite = "NumberIsFinite", NumberIsNaN = "NumberIsNaN", + NumberToString = "NumberToString", ObjectAssign = "ObjectAssign", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index e460993b7..5479fc889 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -4295,7 +4295,7 @@ export class LuaTransformer { } if (tsHelper.isStandardLibraryType(ownerType, "NumberConstructor", this.program)) { - return this.transformNumberCallExpression(node); + return this.transformNumberExpression(node); } const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); @@ -4308,6 +4308,10 @@ export class LuaTransformer { return this.transformStringCallExpression(node); } + if (tsHelper.isNumberType(ownerType, this.checker, this.program)) { + return this.transformNumberCallExpression(node); + } + // if ownerType is a array, use only supported functions if (tsHelper.isExplicitArrayType(ownerType, this.checker, this.program)) { return this.transformArrayCallExpression(node); @@ -4883,6 +4887,23 @@ export class LuaTransformer { ); } + protected transformNumberCallExpression(node: ts.CallExpression): tstl.Expression { + const expression = node.expression as ts.PropertyAccessExpression; + const signature = this.checker.getResolvedSignature(node); + const params = this.transformArguments(node.arguments, signature); + const caller = this.transformExpression(expression.expression); + + const expressionName = expression.name.text; + switch (expressionName) { + case "toString": + return params.length === 0 + ? tstl.createCallExpression(tstl.createIdentifier("tostring"), [caller], node) + : this.transformLuaLibFunction(LuaLibFeature.NumberToString, node, caller, ...params); + default: + throw TSTLErrors.UnsupportedProperty("number", expressionName, node); + } + } + // Transpile a String._ property protected transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { const identifierString = identifier.text; @@ -5015,7 +5036,7 @@ export class LuaTransformer { } // Transpile a Number._ property - protected transformNumberCallExpression(expression: ts.CallExpression): tstl.CallExpression { + protected transformNumberExpression(expression: ts.CallExpression): tstl.CallExpression { const method = expression.expression as ts.PropertyAccessExpression; const parameters = this.transformArguments(expression.arguments); const methodName = method.name.text; diff --git a/src/lualib/NumberToString.ts b/src/lualib/NumberToString.ts new file mode 100644 index 000000000..3ad9a3d5e --- /dev/null +++ b/src/lualib/NumberToString.ts @@ -0,0 +1,49 @@ +// tslint:disable-next-line: variable-name +const ____radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; + +// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tostring +function __TS__NumberToString(this: number, radix?: number): string { + if (radix === undefined || radix === 10 || this === Infinity || this === -Infinity || this !== this) { + return this.toString(); + } + + radix = Math.floor(radix); + if (radix < 2 || radix > 36) { + // tslint:disable-next-line: no-string-throw + throw "toString() radix argument must be between 2 and 36"; + } + + let [integer, fraction] = math.modf(Math.abs(this)); + + let result = ""; + if (radix === 8) { + result = string.format("%o", integer); + } else if (radix === 16) { + result = string.format("%x", integer); + } else { + do { + result = ____radixChars[integer % radix] + result; + integer = Math.floor(integer / radix); + } while (integer !== 0); + } + + // https://github.com/v8/v8/blob/f78e8d43c224847fa56b3220a90be250fc0f0d6e/src/numbers/conversions.cc#L1221 + if (fraction !== 0) { + result += "."; + let delta = 1e-16; + do { + fraction *= radix; + delta *= radix; + const digit = Math.floor(fraction); + result += ____radixChars[digit]; + fraction -= digit; + // TODO: Round to even + } while (fraction >= delta); + } + + if (this < 0) { + result = "-" + result; + } + + return result; +} diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts new file mode 100644 index 000000000..a0fb6c0e6 --- /dev/null +++ b/src/lualib/declarations/math.d.ts @@ -0,0 +1,5 @@ +/** @noSelf */ +declare namespace math { + /** @tupleReturn */ + function modf(x: number): [number, number]; +} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 1003f5450..a21500d28 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -8,4 +8,5 @@ declare namespace string { n?: number ): [string, number]; function sub(s: string, i: number, j?: number): string; + function format(formatstring: string, ...args: any[]): string; } diff --git a/src/utils.ts b/src/utils.ts index 0fe3f68b6..204a1d16c 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1 +1,16 @@ export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); + +export function flatMap(array: readonly T[], callback: (value: T, index: number) => U | readonly U[]): U[] { + const result: U[] = []; + + for (const [index, value] of array.entries()) { + const mappedValue = callback(value, index); + if (Array.isArray(mappedValue)) { + result.push(...mappedValue); + } else { + result[result.length] = mappedValue as U; + } + } + + return result; +} diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 4369f22c6..7a5d5c731 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -1,3 +1,4 @@ +import { flatMap } from "../../../src/utils"; import * as util from "../../util"; test.each([ @@ -48,6 +49,18 @@ describe("Number", () => { }); }); +const toStringRadixes = [undefined, 10, 2, 8, 9, 16, 17, 36, 36.9]; +const toStringValues = [-1, 0, 1, 1.5, 1024, 1.2]; +const toStringPairs = flatMap(toStringValues, value => toStringRadixes.map(radix => [value, radix] as const)); + +test.each(toStringPairs)("(%p).toString(%p)", (value, radix) => { + util.testExpressionTemplate`(${value}).toString(${radix})`.expectToMatchJsResult(); +}); + +test.each([NaN, Infinity, -Infinity])("%p.toString(2)", value => { + util.testExpressionTemplate`(${value}).toString(2)`.expectToMatchJsResult(); +}); + test.each(cases)("isNaN(%p)", value => { util.testExpressionTemplate`isNaN(${value} as any)`.expectToMatchJsResult(); }); From d88c93090c6677fc77ac241ba4e41ab60ea008c0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 30 Nov 2019 16:53:15 +0100 Subject: [PATCH 191/764] Alternative bundling (#750) * security audit fix * Alternative bundling approach * Changed default lualib inline to require, support for lualib require in bundling. Added diagnostics and more tests * Added failing test for entry point resolution * Fixed bundle transpile test, broke all other bundle tests * Fix bundle tests * Added basic project transpilation test * Fixed test paths * Moved resolution modules to resolve.ts, rewrote them to use configFilePath and rootDir, addressed other PR comments * Fixed bug with getProjectDir * Use getCommonSourcesDir in all cases * Changed path resolution again, using confFilePath again * Renamed transpile/basic test to transpile/project, normalized output path of bundle * Reverted toHaveDiagnostics change * Reverted some more forgotten stuff * Final stuff to revert * Do not emit lualib bundle when bundling * Updated emit lualib_bundle logic --- package-lock.json | 21 ++- src/CompilerOptions.ts | 41 +++++ src/Emit.ts | 67 ++++----- src/LuaPrinter.ts | 10 +- src/TSHelper.ts | 10 +- src/Transpile.ts | 31 +++- src/bundle.ts | 112 ++++++++++++++ src/cli/parse.ts | 21 ++- src/diagnostics.ts | 10 ++ src/index.ts | 2 +- src/tstl.ts | 4 +- src/typescript-internal.ts | 8 + src/utils.ts | 13 ++ test/cli/parse.spec.ts | 32 ++++ .../__snapshots__/directories.spec.ts.snap | 6 +- .../__snapshots__/project.spec.ts.snap | 25 ++++ test/transpile/bundle.spec.ts | 19 +++ test/transpile/bundle/index.ts | 3 + test/transpile/bundle/otherFile.ts | 3 + test/transpile/bundle/tsconfig.json | 16 ++ test/transpile/outFile.spec.ts | 44 ------ test/transpile/outFile/index.ts | 1 - test/transpile/project.spec.ts | 18 +++ test/transpile/project/api.d.ts | 3 + test/transpile/project/index.ts | 4 + test/transpile/project/otherFile.ts | 3 + test/transpile/project/tsconfig.json | 11 ++ test/unit/bundle.spec.ts | 141 ++++++++++++++++++ test/util.ts | 76 +++++++--- 29 files changed, 620 insertions(+), 135 deletions(-) create mode 100644 src/bundle.ts create mode 100644 test/transpile/__snapshots__/project.spec.ts.snap create mode 100644 test/transpile/bundle.spec.ts create mode 100644 test/transpile/bundle/index.ts create mode 100644 test/transpile/bundle/otherFile.ts create mode 100644 test/transpile/bundle/tsconfig.json delete mode 100644 test/transpile/outFile.spec.ts delete mode 100644 test/transpile/outFile/index.ts create mode 100644 test/transpile/project.spec.ts create mode 100644 test/transpile/project/api.d.ts create mode 100644 test/transpile/project/index.ts create mode 100644 test/transpile/project/otherFile.ts create mode 100644 test/transpile/project/tsconfig.json create mode 100644 test/unit/bundle.spec.ts diff --git a/package-lock.json b/package-lock.json index a69f58e8f..a33e2537d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2512,9 +2512,9 @@ "dev": true }, "handlebars": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.4.2.tgz", - "integrity": "sha512-cIv17+GhL8pHHnRJzGu2wwcthL5sb8uDKBHvZ2Dtu5s1YNt0ljbzKbamnc+gr69y7bzwQiBdr5+hOpRd5pnOdg==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz", + "integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -5227,16 +5227,23 @@ "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==" }, "uglify-js": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", - "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz", + "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==", "dev": true, "optional": true, "requires": { - "commander": "~2.20.0", + "commander": "~2.20.3", "source-map": "~0.6.1" }, "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index f7c5999c5..be3aa09b4 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -20,6 +20,8 @@ export interface TransformerImport { export type CompilerOptions = OmitIndexSignature & { noImplicitSelf?: boolean; noHeader?: boolean; + luaBundle?: string; + luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; noHoisting?: boolean; @@ -41,3 +43,42 @@ export enum LuaTarget { Lua53 = "5.3", LuaJIT = "JIT", } + +export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { + const diagnostics: ts.Diagnostic[] = []; + + if (options.luaBundle && !options.luaBundleEntry) { + diagnostics.push(configErrorDiagnostic(`'luaBundleEntry' is required when 'luaBundle' is enabled.`)); + } + + if (options.luaBundle && options.luaLibImport === LuaLibImportKind.Inline) { + diagnostics.push( + configWarningDiagnostic( + `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + + `It is recommended to use 'luaLibImport: "require"'` + ) + ); + } + + return diagnostics; +} + +const configErrorDiagnostic = (message: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: message, +}); + +const configWarningDiagnostic = (message: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Warning, + code: 0, + source: "typescript-to-lua", + messageText: message, +}); diff --git a/src/Emit.ts b/src/Emit.ts index ecb1453f9..dd3208eb9 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -1,10 +1,8 @@ import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; +import { LuaLibImportKind } from "./CompilerOptions"; import { EmitHost, TranspiledFile } from "./Transpile"; -import { normalizeSlashes } from "./utils"; - -const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); +import { normalizeSlashes, trimExtension } from "./utils"; export interface OutputFile { name: string; @@ -13,18 +11,15 @@ export interface OutputFile { let lualibContent: string; export function emitTranspiledFiles( - options: CompilerOptions, + program: ts.Program, transpiledFiles: TranspiledFile[], emitHost: EmitHost = ts.sys ): OutputFile[] { - let { rootDir, outDir, outFile, luaLibImport } = options; - - const configFileName = options.configFilePath as string | undefined; - // TODO: Use getCommonSourceDirectory - const baseDir = configFileName ? path.dirname(configFileName) : process.cwd(); + const options = program.getCompilerOptions(); + let { outDir, luaLibImport, luaBundle } = options; - rootDir = rootDir || baseDir; - outDir = outDir ? path.resolve(baseDir, outDir) : rootDir; + const rootDir = program.getCommonSourceDirectory(); + outDir = outDir || rootDir; const files: OutputFile[] = []; for (const { fileName, lua, sourceMap, declaration, declarationMap } of transpiledFiles) { @@ -33,14 +28,8 @@ export function emitTranspiledFiles( outPath = path.resolve(outDir, path.relative(rootDir, fileName)); } - // change extension or rename to outFile - if (outFile) { - outPath = path.isAbsolute(outFile) ? outFile : path.resolve(baseDir, outFile); - } else { - outPath = trimExt(outPath) + ".lua"; - } - - outPath = normalizeSlashes(outPath); + // change extension + outPath = normalizeSlashes(trimExtension(outPath) + ".lua"); if (lua !== undefined) { files.push({ name: outPath, text: lua }); @@ -51,30 +40,38 @@ export function emitTranspiledFiles( } if (declaration !== undefined) { - files.push({ name: trimExt(outPath) + ".d.ts", text: declaration }); + files.push({ name: trimExtension(outPath) + ".d.ts", text: declaration }); } if (declarationMap !== undefined) { - files.push({ name: trimExt(outPath) + ".d.ts.map", text: declarationMap }); + files.push({ name: trimExtension(outPath) + ".d.ts.map", text: declarationMap }); } } - if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) { - if (lualibContent === undefined) { - const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); - if (lualibBundle !== undefined) { - lualibContent = lualibBundle; - } else { - throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua"); + if ( + !luaBundle && + (luaLibImport === undefined || + luaLibImport === LuaLibImportKind.Require || + luaLibImport === LuaLibImportKind.Always) + ) { + const lualibRequired = files.some(f => f.text && f.text.includes(`require("lualib_bundle")`)); + if (lualibRequired) { + if (lualibContent === undefined) { + const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); + if (lualibBundle !== undefined) { + lualibContent = lualibBundle; + } else { + throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua"); + } } - } - let outPath = path.resolve(rootDir, "lualib_bundle.lua"); - if (outDir !== rootDir) { - outPath = path.join(outDir, path.relative(rootDir, outPath)); - } + let outPath = path.resolve(rootDir, "lualib_bundle.lua"); + if (outDir !== rootDir) { + outPath = path.join(outDir, path.relative(rootDir, outPath)); + } - files.push({ name: normalizeSlashes(outPath), text: lualibContent }); + files.push({ name: normalizeSlashes(outPath), text: lualibContent }); + } } return files; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 48ea0e752..4fec7e595 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -43,7 +43,11 @@ export class LuaPrinter { public constructor(private options: CompilerOptions, private emitHost: EmitHost) {} - public print(block: tstl.Block, luaLibFeatures?: Set, sourceFile = ""): [string, string] { + public print( + block: tstl.Block, + luaLibFeatures?: Set, + sourceFile = "" + ): [string, string, SourceNode] { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { if (luaLibFeatures === undefined) { @@ -71,7 +75,7 @@ export class LuaPrinter { codeResult = codeResult.replace("{#SourceMapTraceback}", stackTraceOverride); } - return [codeResult, sourceMap.toString()]; + return [codeResult, sourceMap.toString(), rootSourceNode]; } private printInlineSourceMap(sourceMap: SourceMapGenerator): string { @@ -113,7 +117,7 @@ export class LuaPrinter { } if (luaLibFeatures) { - const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Inline; + const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Require; // Require lualib bundle if ( (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) || diff --git a/src/TSHelper.ts b/src/TSHelper.ts index c237ae188..4c0735310 100644 --- a/src/TSHelper.ts +++ b/src/TSHelper.ts @@ -5,6 +5,7 @@ import { Decorator, DecoratorKind } from "./Decorator"; import * as tstl from "./LuaAST"; import * as TSTLErrors from "./TSTLErrors"; import { EmitResolver } from "./LuaTransformer"; +import { formatPathToLuaPath } from "./utils"; export enum ContextType { None, @@ -1060,15 +1061,6 @@ export function getExportPath(fileName: string, options: ts.CompilerOptions): st return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); } -export function formatPathToLuaPath(filePath: string): string { - filePath = filePath.replace(/\.json$/, ""); - if (process.platform === "win32") { - // Windows can use backslashes - filePath = filePath.replace(/\.\\/g, "").replace(/\\/g, "."); - } - return filePath.replace(/\.\//g, "").replace(/\//g, "."); -} - export function isBuiltinErrorTypeName(name: string): boolean { return builtinErrorTypeNames.has(name); } diff --git a/src/Transpile.ts b/src/Transpile.ts index 28a6282a9..01d8df15a 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -1,5 +1,7 @@ +import { SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions } from "./CompilerOptions"; +import { bundleTranspiledFiles } from "./bundle"; +import { CompilerOptions, validateOptions } from "./CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; import { Block } from "./LuaAST"; import { LuaPrinter } from "./LuaPrinter"; @@ -14,6 +16,8 @@ export interface TranspiledFile { sourceMap?: string; declaration?: string; declarationMap?: string; + /** @internal */ + sourceMapNode?: SourceNode; } export interface TranspileResult { @@ -31,6 +35,7 @@ export interface TranspileOptions { } export interface EmitHost { + getCurrentDirectory(): string; readFile(path: string): string | undefined; } @@ -44,7 +49,7 @@ export function transpile({ }: TranspileOptions): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; - const diagnostics: ts.Diagnostic[] = []; + const diagnostics = validateOptions(options); let transpiledFiles: TranspiledFile[] = []; const updateTranspiledFile = (fileName: string, update: Omit) => { @@ -57,7 +62,11 @@ export function transpile({ }; if (options.noEmitOnError) { - const preEmitDiagnostics = [...program.getOptionsDiagnostics(), ...program.getGlobalDiagnostics()]; + const preEmitDiagnostics = [ + ...diagnostics, + ...program.getOptionsDiagnostics(), + ...program.getGlobalDiagnostics(), + ]; if (targetSourceFiles) { for (const sourceFile of targetSourceFiles) { @@ -82,8 +91,8 @@ export function transpile({ try { const [luaAst, lualibFeatureSet] = transformer.transform(sourceFile); if (!options.noEmit && !options.emitDeclarationOnly) { - const [lua, sourceMap] = printer.print(luaAst, lualibFeatureSet, sourceFile.fileName); - updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap }); + const [lua, sourceMap, sourceNode] = printer.print(luaAst, lualibFeatureSet, sourceFile.fileName); + updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap, sourceMapNode: sourceNode }); } } catch (err) { if (!(err instanceof TranspileError)) throw err; @@ -144,5 +153,17 @@ export function transpile({ transpiledFiles = []; } + if (options.luaBundle && options.luaBundleEntry) { + const [bundleDiagnostics, bundle] = bundleTranspiledFiles( + options.luaBundle, + options.luaBundleEntry, + transpiledFiles, + program, + emitHost + ); + diagnostics.push(...bundleDiagnostics); + transpiledFiles = [bundle]; + } + return { diagnostics, transpiledFiles }; } diff --git a/src/bundle.ts b/src/bundle.ts new file mode 100644 index 000000000..20476b43b --- /dev/null +++ b/src/bundle.ts @@ -0,0 +1,112 @@ +import * as path from "path"; +import { SourceNode } from "source-map"; +import * as ts from "typescript"; +import { couldNotFindBundleEntryPoint } from "./diagnostics"; +import { EmitHost, TranspiledFile } from "./Transpile"; +import { formatPathToLuaPath, trimExtension, normalizeSlashes } from "./utils"; +import { escapeString } from "./TSHelper"; +import { CompilerOptions } from "./CompilerOptions"; + +const createModulePath = (baseDir: string, pathToResolve: string) => + escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); + +export function bundleTranspiledFiles( + bundleFile: string, + entryModule: string, + transpiledFiles: TranspiledFile[], + program: ts.Program, + emitHost: EmitHost +): [ts.Diagnostic[], TranspiledFile] { + const diagnostics: ts.Diagnostic[] = []; + + const options = program.getCompilerOptions() as CompilerOptions; + + const projectRootDir = options.configFilePath + ? path.dirname(options.configFilePath) + : emitHost.getCurrentDirectory(); + + // Resolve project settings relative to project file. + const resolvedEntryModule = path.resolve(projectRootDir, entryModule); + const resolvedBundleFile = path.resolve(projectRootDir, bundleFile); + + // Resolve source files relative to common source directory. + const sourceRootDir = program.getCommonSourceDirectory(); + if (!transpiledFiles.some(f => path.resolve(sourceRootDir, f.fileName) === resolvedEntryModule)) { + return [[couldNotFindBundleEntryPoint(entryModule)], { fileName: bundleFile }]; + } + + // For each file: [""] = function() end, + const moduleTableEntries: SourceChunk[] = transpiledFiles.map(f => + moduleSourceNode(f, createModulePath(sourceRootDir, f.fileName)) + ); + + // If any of the modules contains a require for lualib_bundle, add it to the module table. + const lualibRequired = transpiledFiles.some(f => f.lua && f.lua.includes(`require("lualib_bundle")`)); + if (lualibRequired) { + const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); + moduleTableEntries.push(`["lualib_bundle"] = function() ${lualibBundle} end,\n`); + } + + // Create ____modules table containing all entries from moduleTableEntries + const moduleTable = createModuleTableNode(moduleTableEntries); + + // Override `require` to read from ____modules table. + const requireOverride = ` +local ____moduleCache = {} +local ____originalRequire = require +function require(file) + if ____moduleCache[file] then + return ____moduleCache[file] + end + if ____modules[file] then + ____moduleCache[file] = ____modules[file]() + return ____moduleCache[file] + else + if ____originalRequire then + return ____originalRequire(file) + else + error("module '" .. file .. "' not found") + end + end +end\n`; + + // return require("") + const entryPoint = `return require("${createModulePath(sourceRootDir, resolvedEntryModule)}")\n`; + + const bundleNode = joinSourceChunks([moduleTable, requireOverride, entryPoint]); + const { code, map } = bundleNode.toStringWithSourceMap(); + + return [ + diagnostics, + { + fileName: normalizeSlashes(resolvedBundleFile), + lua: code, + sourceMap: map.toString(), + sourceMapNode: moduleTable, + }, + ]; +} + +function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): SourceNode { + const tableEntryHead = `["${modulePath}"] = function() `; + const tableEntryTail = `end,\n`; + + if (transpiledFile.lua && transpiledFile.sourceMapNode) { + return joinSourceChunks([tableEntryHead, transpiledFile.sourceMapNode, tableEntryTail]); + } else { + return joinSourceChunks([tableEntryHead, tableEntryTail]); + } +} + +function createModuleTableNode(fileChunks: SourceChunk[]): SourceNode { + const tableHead = `local ____modules = {\n`; + const tableEnd = `}\n`; + + return joinSourceChunks([tableHead, ...fileChunks, tableEnd]); +} + +type SourceChunk = string | SourceNode; +function joinSourceChunks(chunks: SourceChunk[]): SourceNode { + // tslint:disable-next-line:no-null-keyword + return new SourceNode(null, null, null, chunks); +} diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 8bbaad42b..40f564268 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -21,9 +21,23 @@ interface CommandLineOptionOfBoolean extends CommandLineOptionBase { type: "boolean"; } -type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean; +interface CommandLineOptionOfString extends CommandLineOptionBase { + type: "string"; +} + +type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean | CommandLineOptionOfString; export const optionDeclarations: CommandLineOption[] = [ + { + name: "luaBundle", + description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", + type: "string", + }, + { + name: "luaBundleEntry", + description: "The entry *.ts file that will be executed when entering the luaBundle. Requires luaBundle.", + type: "string", + }, { name: "luaLibImport", description: "Specifies how js standard features missing in lua are imported.", @@ -164,11 +178,12 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (value === null) return { value }; switch (option.type) { + case "string": case "boolean": { - if (typeof value !== "boolean") { + if (typeof value !== option.type) { return { value: undefined, - error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, "boolean"), + error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, option.type), }; } diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 5e614a380..9382ca834 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -50,3 +50,13 @@ export const transformerShouldBeATsTransformerFactory = (transform: string): ts. source: "typescript-to-lua", messageText: `"${transform}" transformer should be a ts.TransformerFactory or an object with ts.TransformerFactory values`, }); + +export const couldNotFindBundleEntryPoint = (entryPoint: string): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: `Could not find bundle entry point '${entryPoint}'. It should be a file in the project.`, +}); diff --git a/src/index.ts b/src/index.ts index f9a514fb6..fc686df20 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,7 +26,7 @@ export interface TranspileFilesResult { export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult { const program = ts.createProgram(rootNames, options); const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); - const emitResult = emitTranspiledFiles(program.getCompilerOptions(), transpiledFiles); + const emitResult = emitTranspiledFiles(program, transpiledFiles); const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...ts.getPreEmitDiagnostics(program), diff --git a/src/tstl.ts b/src/tstl.ts index e3c416f6e..e37073442 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -111,7 +111,7 @@ function performCompilation( ...transpileDiagnostics, ]); - const emitResult = tstl.emitTranspiledFiles(options, transpiledFiles); + const emitResult = tstl.emitTranspiledFiles(program, transpiledFiles); emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); diagnostics.forEach(reportDiagnostic); @@ -182,7 +182,7 @@ function updateWatchCompilationHost( const { diagnostics: emitDiagnostics, transpiledFiles } = tstl.transpile({ program, sourceFiles }); - const emitResult = tstl.emitTranspiledFiles(options, transpiledFiles); + const emitResult = tstl.emitTranspiledFiles(program, transpiledFiles); emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); const diagnostics = ts.sortAndDeduplicateDiagnostics([ diff --git a/src/typescript-internal.ts b/src/typescript-internal.ts index 6f5819c38..3a8013d61 100644 --- a/src/typescript-internal.ts +++ b/src/typescript-internal.ts @@ -11,4 +11,12 @@ declare module "typescript" { interface Statement { jsDoc?: ts.JSDoc[]; } + + interface Program { + getCommonSourceDirectory(): string; + } + + interface CompilerOptions { + configFilePath?: string; + } } diff --git a/src/utils.ts b/src/utils.ts index 204a1d16c..16997a549 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,18 @@ +import * as path from "path"; + export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); +export const trimExtension = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); + +export function formatPathToLuaPath(filePath: string): string { + filePath = filePath.replace(/\.json$/, ""); + if (process.platform === "win32") { + // Windows can use backslashes + filePath = filePath.replace(/\.\\/g, "").replace(/\\/g, "."); + } + return filePath.replace(/\.\//g, "").replace(/\//g, "."); +} + export function flatMap(array: readonly T[], callback: (value: T, index: number) => U | readonly U[]): U[] { const result: U[] = []; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 0f4942d9c..ae95751e9 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -115,6 +115,9 @@ describe("command line", () => { ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], + + ["luaBundle", "foo", { luaBundle: "foo" }], + ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], ])("--%s %s", (optionName, value, expected) => { const result = tstl.parseCommandLine([`--${optionName}`, value]); @@ -201,4 +204,33 @@ describe("tsconfig", () => { expect(result.options.noHeader).toBeUndefined(); }); }); + + describe("integration", () => { + test.each<[string, any, tstl.CompilerOptions]>([ + ["noHeader", false, { noHeader: false }], + ["noHeader", true, { noHeader: true }], + ["noHoisting", false, { noHoisting: false }], + ["noHoisting", true, { noHoisting: true }], + ["sourceMapTraceback", false, { sourceMapTraceback: false }], + ["sourceMapTraceback", true, { sourceMapTraceback: true }], + + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], + ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], + ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], + ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], + + ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], + ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], + ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], + ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], + + ["luaBundle", "foo", { luaBundle: "foo" }], + ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], + ])("{ %p: %p }", (optionName, value, expected) => { + const result = parseConfigFileContent({ tstl: { [optionName]: value } }); + + expect(result.errors).not.toHaveDiagnostics(); + expect(result.options).toEqual(expected); + }); + }); }); diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index 952fd709b..901d885f4 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -10,17 +10,17 @@ Array [ exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` Array [ - "directories/basic/lualib_bundle.lua", "directories/basic/src/lib/file.lua", + "directories/basic/src/lualib_bundle.lua", "directories/basic/src/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 2`] = ` Array [ + "directories/basic/out/lib/file.lua", "directories/basic/out/lualib_bundle.lua", - "directories/basic/out/src/lib/file.lua", - "directories/basic/out/src/main.lua", + "directories/basic/out/main.lua", ] `; diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap new file mode 100644 index 000000000..498b36d47 --- /dev/null +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -0,0 +1,25 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should transpile 1`] = ` +Array [ + Object { + "name": "otherFile.lua", + "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] +local ____exports = {} +function ____exports.getNumber(self) + return GetAPIValue() +end +return ____exports +", + }, + Object { + "name": "index.lua", + "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] +local ____otherFile = require(\\"otherFile\\") +local getNumber = ____otherFile.getNumber +local myNumber = getNumber(nil) +SetAPIValue(myNumber * 5) +", + }, +] +`; diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts new file mode 100644 index 000000000..a5afd90b0 --- /dev/null +++ b/test/transpile/bundle.spec.ts @@ -0,0 +1,19 @@ +import * as path from "path"; +import * as util from "../util"; +import { transpileProject } from "../../src"; + +const projectDir = path.join(__dirname, "bundle"); +const inputProject = path.join(projectDir, "tsconfig.json"); + +test("should transpile into one file", () => { + const transpileResult = transpileProject(inputProject); + + expect(transpileResult.diagnostics).not.toHaveDiagnostics(); + expect(transpileResult.emitResult.length).toBe(1); + + const { name, text } = transpileResult.emitResult[0]; + // Verify the name is as specified in tsconfig + expect(name).toBe(path.join(projectDir, "bundle.lua").replace(/\\/g, "/")); + // Verify exported module by executing + expect(util.executeLuaModule(text)).toEqual({ myNumber: 3 }); +}); diff --git a/test/transpile/bundle/index.ts b/test/transpile/bundle/index.ts new file mode 100644 index 000000000..f189ac088 --- /dev/null +++ b/test/transpile/bundle/index.ts @@ -0,0 +1,3 @@ +import { getNumber } from "./otherFile"; + +export const myNumber = getNumber(); diff --git a/test/transpile/bundle/otherFile.ts b/test/transpile/bundle/otherFile.ts new file mode 100644 index 000000000..ad9eaceb7 --- /dev/null +++ b/test/transpile/bundle/otherFile.ts @@ -0,0 +1,3 @@ +export function getNumber(): number { + return 3; +} diff --git a/test/transpile/bundle/tsconfig.json b/test/transpile/bundle/tsconfig.json new file mode 100644 index 000000000..71060927d --- /dev/null +++ b/test/transpile/bundle/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + }, + "tstl": { + "luaBundle": "bundle.lua", + "luaBundleEntry": "index.ts" + }, + "include": ["."] +} diff --git a/test/transpile/outFile.spec.ts b/test/transpile/outFile.spec.ts deleted file mode 100644 index fa073490e..000000000 --- a/test/transpile/outFile.spec.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as path from "path"; -import { buildVirtualProject } from "./run"; - -const inputFilePath = path.join(__dirname, "outFile/index.ts"); -test("should support absolute outFile", () => { - const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { - outFile: path.join(__dirname, "output.script"), - }); - - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toEqual(["output.script"]); -}); - -test("should support relative outFile", () => { - jest.spyOn(process, "cwd").mockReturnValue(__dirname); - const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { - outFile: "output.script", - }); - - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toEqual(["output.script"]); -}); - -test("should support outFile with declaration", () => { - const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { - outFile: path.join(__dirname, "output.script"), - declaration: true, - }); - - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toEqual(["output.d.ts", "output.script"]); -}); - -test("should resolve outFile relative to base directory", () => { - jest.spyOn(process, "cwd").mockReturnValue(__dirname); - const { diagnostics, emittedFiles } = buildVirtualProject([inputFilePath], { - outFile: "output.script", - outDir: "out", - declaration: true, - }); - - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toEqual(["output.d.ts", "output.script"]); -}); diff --git a/test/transpile/outFile/index.ts b/test/transpile/outFile/index.ts deleted file mode 100644 index ef22a69f1..000000000 --- a/test/transpile/outFile/index.ts +++ /dev/null @@ -1 +0,0 @@ -class Test {} diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts new file mode 100644 index 000000000..a8afc4229 --- /dev/null +++ b/test/transpile/project.spec.ts @@ -0,0 +1,18 @@ +import * as path from "path"; +import { transpileProject } from "../../src"; + +const projectDir = path.join(__dirname, "project"); +const inputProject = path.join(projectDir, "tsconfig.json"); + +test("should transpile", () => { + const transpileResult = transpileProject(inputProject); + + expect(transpileResult.diagnostics).not.toHaveDiagnostics(); + + // Check output paths relative to projectDir + const relativeResult = transpileResult.emitResult.map(({ name, text }) => ({ + name: path.relative(projectDir, name), + text, + })); + expect(relativeResult).toMatchSnapshot(); +}); diff --git a/test/transpile/project/api.d.ts b/test/transpile/project/api.d.ts new file mode 100644 index 000000000..dcac56a84 --- /dev/null +++ b/test/transpile/project/api.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +declare function GetAPIValue(): number; +declare function SetAPIValue(n: number): void; diff --git a/test/transpile/project/index.ts b/test/transpile/project/index.ts new file mode 100644 index 000000000..bd11cd347 --- /dev/null +++ b/test/transpile/project/index.ts @@ -0,0 +1,4 @@ +import { getNumber } from "./otherFile"; + +const myNumber = getNumber(); +SetAPIValue(myNumber * 5); diff --git a/test/transpile/project/otherFile.ts b/test/transpile/project/otherFile.ts new file mode 100644 index 000000000..ca4d2aa23 --- /dev/null +++ b/test/transpile/project/otherFile.ts @@ -0,0 +1,3 @@ +export function getNumber(): number { + return GetAPIValue(); +} diff --git a/test/transpile/project/tsconfig.json b/test/transpile/project/tsconfig.json new file mode 100644 index 000000000..8fb9d9e90 --- /dev/null +++ b/test/transpile/project/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts new file mode 100644 index 000000000..7bca27ae5 --- /dev/null +++ b/test/unit/bundle.spec.ts @@ -0,0 +1,141 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { DiagnosticCategory } from "typescript"; +import { LuaLibImportKind } from "../../src"; +import { couldNotFindBundleEntryPoint } from "../../src/diagnostics"; +import * as util from "../util"; + +test("no entry point", () => { + util.testBundle`` + .setOptions({ luaBundleEntry: undefined }) + .expectToHaveDiagnostic( + d => + d.messageText === `'luaBundleEntry' is required when 'luaBundle' is enabled.` && + d.category === DiagnosticCategory.Error + ); +}); + +test("import module -> main", () => { + util.testBundle` + export { value } from "./module"; + ` + .addExtraFile("module.ts", "export const value = true") + .expectToEqual({ value: true }); +}); + +test("bundle file name", () => { + const { diagnostics, transpiledFiles } = util.testModule` + export { value } from "./module"; +` + .addExtraFile("module.ts", "export const value = true") + .setOptions({ luaBundle: "mybundle.lua", luaBundleEntry: "main.ts" }) + .getLuaResult(); + + expect(diagnostics.length).toBe(0); + expect(transpiledFiles.length).toBe(1); + expect(transpiledFiles[0].fileName).toBe( + path.join(ts.sys.getCurrentDirectory(), "mybundle.lua").replace(/\\/g, "/") + ); +}); + +test("import chain export -> reexport -> main", () => { + util.testBundle` + export { value } from "./reexport"; + ` + .addExtraFile("reexport.ts", "export { value } from './export'") + .addExtraFile("export.ts", "export const value = true") + .expectToEqual({ value: true }); +}); + +test("diamond imports/exports -> reexport1 & reexport2 -> main", () => { + util.testBundle` + export { value as a } from "./reexport1"; + export { value as b } from "./reexport2"; + ` + .addExtraFile("reexport1.ts", "export { value } from './export'") + .addExtraFile("reexport2.ts", "export { value } from './export'") + .addExtraFile("export.ts", "export const value = true") + .expectToEqual({ a: true, b: true }); +}); + +test("module in directory", () => { + util.testBundle` + export { value } from "./module/module"; + ` + .addExtraFile("module/module.ts", "export const value = true") + .expectToEqual({ value: true }); +}); + +test("modules aren't ordered by name", () => { + util.testBundle` + export { value } from "./a"; + ` + .addExtraFile("a.ts", "export const value = true") + .expectToEqual({ value: true }); +}); + +test("entry point in directory", () => { + util.testBundle`` + .addExtraFile( + "main/main.ts", + ` + export { value } from "../module"; + ` + ) + .addExtraFile("module.ts", "export const value = true") + .setEntryPoint("main/main.ts") + .expectToEqual({ value: true }); +}); + +test.each([LuaLibImportKind.Inline, LuaLibImportKind.Require])("LuaLib %p", lualibOption => { + const testBundle = util.testBundle` + export const result = [1, 2]; + result.push(3); + `.setOptions({ luaLibImport: lualibOption }); + + if (lualibOption === LuaLibImportKind.Inline) { + testBundle.expectToHaveDiagnostic(d => d.category === DiagnosticCategory.Warning); + } else { + expect(testBundle.getLuaResult().diagnostics).toEqual([]); + } + expect(testBundle.getLuaExecutionResult()).toEqual({ result: [1, 2, 3] }); +}); + +test("LuaBundle and LuaLibImport.Inline generate warning", () => { + const testBundle = util.testBundle` + export const result = [1, 2]; + result.push(3); + ` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToHaveDiagnostic( + d => + d.category === DiagnosticCategory.Warning && + d.messageText === + `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + + `It is recommended to use 'luaLibImport: "require"'` + ); + + expect(testBundle.getLuaExecutionResult()).toEqual({ result: [1, 2, 3] }); // Result should still be the same +}); + +test("cyclic imports", () => { + util.testBundle` + import * as b from "./b"; + export const a = true; + export const valueResult = b.value; + export const lazyValueResult = b.lazyValue(); + ` + .addExtraFile( + "b.ts", + ` + import * as a from "./main"; + export const value = a.a; + export const lazyValue = () => a.a; + ` + ) + .expectToEqual(new util.ExecutionError("stack overflow")); +}); + +test("luaEntry doesn't exist", () => { + util.testBundle``.setEntryPoint("entry.ts").expectToHaveExactDiagnostic(couldNotFindBundleEntryPoint("entry.ts")); +}); diff --git a/test/util.ts b/test/util.ts index 33e48b16f..b1dc96934 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,11 +1,11 @@ import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; +import { stringify } from "javascript-stringify"; import * as path from "path"; import * as prettyFormat from "pretty-format"; import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; -import { stringify } from "javascript-stringify"; export * from "./legacy-utils"; @@ -107,6 +107,31 @@ function transpileJs(program: ts.Program): TranspileJsResult { return { transpiledFiles, diagnostics: [...diagnostics] }; } +function executeLua(code: string): any { + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + const status = lauxlib.luaL_dostring(L, to_luastring(code)); + + if (status === lua.LUA_OK) { + if (lua.lua_isstring(L, -1)) { + const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + return result === null ? undefined : result; + } else { + const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + throw new Error(`Unsupported Lua return type: ${returnType}`); + } + } else { + // Filter out control characters appearing on some systems + const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); + const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); + return new ExecutionError(message); + } +} + +export function executeLuaModule(code: string): any { + return executeLua(`${minimalTestLib}return JSONStringify((function()\n${code}\nend)())`); +} + const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); @@ -129,6 +154,7 @@ export class ExecutionError extends Error { export type ExecutableTranspiledFile = tstl.TranspiledFile & { lua: string; sourceMap: string }; export type TapCallback = (builder: TestBuilder) => void; +export type DiagnosticMatcher = (diagnostic: ts.Diagnostic) => boolean; export abstract class TestBuilder { constructor(protected _tsCode: string) {} @@ -219,7 +245,9 @@ export abstract class TestBuilder { @memoize public getMainLuaFileResult(): ExecutableTranspiledFile { const { transpiledFiles } = this.getLuaResult(); - const mainFile = transpiledFiles.find(x => x.fileName === this.mainFileName); + const mainFile = this.options.luaBundle + ? transpiledFiles[0] + : transpiledFiles.find(x => x.fileName === this.mainFileName); expect(mainFile).toMatchObject({ lua: expect.any(String), sourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; } @@ -234,25 +262,7 @@ export abstract class TestBuilder { @memoize public getLuaExecutionResult(): any { - const code = this.getLuaCodeWithWrapper(); - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(code)); - - if (status === lua.LUA_OK) { - if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); - return result === null ? undefined : result; - } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); - throw new Error(`Unsupported Lua return type: ${returnType}`); - } - } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); - return new ExecutionError(message); - } + return executeLua(this.getLuaCodeWithWrapper()); } @memoize @@ -330,12 +340,22 @@ export abstract class TestBuilder { return this; } + public expectToHaveDiagnostic(matcher: DiagnosticMatcher): this { + expect(this.getLuaDiagnostics().find(matcher)).toBeDefined(); + return this; + } + + public expectToHaveExactDiagnostic(diagnostic: ts.Diagnostic): this { + expect(this.getLuaDiagnostics()).toContainEqual(diagnostic); + return this; + } + public expectToHaveDiagnostics(): this { expect(this.getLuaDiagnostics()).toHaveDiagnostics(); return this; } - public expectToHaveDiagnosticOfError(error: tstl.TranspileError): this { + public expectToHaveDiagnosticOfError(error: Error): this { this.expectToHaveDiagnostics(); expect(this.getLuaDiagnostics()).toHaveLength(1); const firstDiagnostic = this.getLuaDiagnostics()[0]; @@ -414,6 +434,17 @@ class AccessorTestBuilder extends TestBuilder { } } +class BundleTestBuilder extends AccessorTestBuilder { + public constructor(_tsCode: string) { + super(_tsCode); + this.setOptions({ luaBundle: "main.lua", luaBundleEntry: this.mainFileName }); + } + + public setEntryPoint(fileName: string): this { + return this.setOptions({ luaBundleEntry: fileName }); + } +} + class ModuleTestBuilder extends AccessorTestBuilder { public setReturnExport(name: string): this { expect(this.hasProgram).toBe(false); @@ -458,6 +489,7 @@ const createTestBuilderFactory = ( return new builder(tsCode); }; +export const testBundle = createTestBuilderFactory(BundleTestBuilder, false); export const testModule = createTestBuilderFactory(ModuleTestBuilder, false); export const testModuleTemplate = createTestBuilderFactory(ModuleTestBuilder, true); export const testFunction = createTestBuilderFactory(FunctionTestBuilder, false); From 0fc836dc679bd6eb46608809bd8dd9ed3c93cf70 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 30 Nov 2019 22:38:39 +0100 Subject: [PATCH 192/764] 0.29.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index a33e2537d..ccdf13fdd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.28.1", + "version": "0.29.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 0ecb94080..bfcdb8684 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.28.1", + "version": "0.29.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 77a23258736f8d5589371e3a2f458360660db47b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 30 Nov 2019 23:07:44 +0100 Subject: [PATCH 193/764] CHANGELOG.md 0.29.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1bbf79dbd..f5b257bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.29.0 + +- Added bundling support using options `luaBundle` and `luaBundleEntry` (so **not** TS's outFile). This will bundle all output files into one single bundle file, with _luaBundleEntry_ as entry point. For more information on these options see https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options +- Added support for `Number.prototype.toString(radix)`. +- Fixed `array.flat()` not flattening empty arrays. + **Note:** Due to language restrictions, flat will also flatten _objects_ without keys (or only undefined values) so be careful. + For more info on this issue see https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 +- Fixed runtime error when throwing non-string errors and `sourceMapTraceback`. + ## 0.28.0 - We now have a `noImplicitSelf` option you can add to your tstl tsconfig.json. Default behavior is `false`. Setting this option to `true` will cause no 'self' arguments to be considered/generated in the project. Declarations will behave as if they have a `/** @noSelfInFile */` directive. This option is new and might cause correctness issues, use at your own risk and create an issue if you experience any issues. From d91dfb2c11e70aa28be4a9a84f00c89f0b12bad3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 1 Dec 2019 16:53:53 +0100 Subject: [PATCH 194/764] Made require overload local to prevent it affecting other lua (#757) --- src/bundle.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bundle.ts b/src/bundle.ts index 20476b43b..b4851e78f 100644 --- a/src/bundle.ts +++ b/src/bundle.ts @@ -52,9 +52,10 @@ export function bundleTranspiledFiles( // Override `require` to read from ____modules table. const requireOverride = ` +local ____modules = {} local ____moduleCache = {} local ____originalRequire = require -function require(file) +local function require(file) if ____moduleCache[file] then return ____moduleCache[file] end @@ -73,7 +74,7 @@ end\n`; // return require("") const entryPoint = `return require("${createModulePath(sourceRootDir, resolvedEntryModule)}")\n`; - const bundleNode = joinSourceChunks([moduleTable, requireOverride, entryPoint]); + const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); const { code, map } = bundleNode.toStringWithSourceMap(); return [ @@ -99,7 +100,7 @@ function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): S } function createModuleTableNode(fileChunks: SourceChunk[]): SourceNode { - const tableHead = `local ____modules = {\n`; + const tableHead = `____modules = {\n`; const tableEnd = `}\n`; return joinSourceChunks([tableHead, ...fileChunks, tableEnd]); From 3373e4a0aab57c475c02bca07d9d7554ae5768e9 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Dec 2019 17:45:48 +0100 Subject: [PATCH 195/764] 0.29.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ccdf13fdd..fdc631602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.29.0", + "version": "0.29.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index bfcdb8684..12336a104 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.29.0", + "version": "0.29.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 757302b89d69aceeebe01db00937e8b47b3e7744 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 4 Dec 2019 05:09:30 +1000 Subject: [PATCH 196/764] Avoid exporting anonymous identifiers (#756) * Avoid exporting anonymous identifiers * Use existing test for anonymous destructuring * Remove TODO for issue 32656 with test filter * Update test/unit/destructuring.spec.ts Co-Authored-By: ark120202 * Update test/unit/destructuring.spec.ts Co-Authored-By: ark120202 --- src/LuaAST.ts | 3 +++ src/LuaTransformer.ts | 4 ++++ test/unit/destructuring.spec.ts | 15 +++++---------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index d88dbef09..7fcd4a74b 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -829,6 +829,7 @@ export function createMethodCallExpression( export interface Identifier extends Expression { kind: SyntaxKind.Identifier; + exportable: boolean; text: string; originalName?: string; symbolId?: SymbolId; @@ -846,6 +847,7 @@ export function createIdentifier( parent?: Node ): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; + expression.exportable = true; expression.text = text; expression.symbolId = symbolId; expression.originalName = originalName; @@ -858,6 +860,7 @@ export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): I export function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; + expression.exportable = false; expression.text = "____"; return expression; } diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts index 5479fc889..8287ebb08 100644 --- a/src/LuaTransformer.ts +++ b/src/LuaTransformer.ts @@ -5480,6 +5480,10 @@ export class LuaTransformer { identifier: tstl.Identifier, exportScope?: ts.SourceFile | ts.ModuleDeclaration ): tstl.AssignmentLeftHandSideExpression { + if (!identifier.exportable) { + return identifier; + } + const exportTable = exportScope && ts.isModuleDeclaration(exportScope) ? this.createModuleLocalNameIdentifier(exportScope) diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 6572d8b6b..ed6d5219d 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -51,16 +51,11 @@ test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { `.expectToMatchJsResult(); }); -// TODO: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/695 -// TODO: https://github.com/microsoft/TypeScript/issues/32656 -test.each(testCases.filter(x => x.binding !== "[x, , y]" && x.binding !== "{ x, ...rest }"))( - "in exported variable declaration (%p)", - ({ binding, value }) => { - util.testModule` - export const ${binding} = ${value}; - `.expectToMatchJsResult(); - } -); +test.each(testCases)("in exported variable declaration (%p)", ({ binding, value }) => { + util.testModule` + export const ${binding} = ${value}; + `.expectToMatchJsResult(); +}); const assignmentTestCases = [ ...testCases, From e238cc7e0e4dbdbafc4ffa8462fca2d38217c06f Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 7 Dec 2019 21:34:17 +0500 Subject: [PATCH 197/764] Transformation Pipeline Refactor (#705) * Transformation Pipeline Refactor * Add missing export * Fix formatting * Fix memory leak * Rename `setIfMissing` to `getOrUpdate` * Change `SymbolId` brand style * Extract constructed object visitor to a variable * Add -expression to n-ary transformer names * Handle `@noResolve` in `export *` and external module references * Remove disabled tshelper tests * Resolve some TODOs * Rename decorators/directives to annotations * Remove 'custom' from annotation functions * Simplify few error creators * Refactor standard transformers to a single plugin * Refactor typeof tests * Refactor class accessor checks * Import Lua AST as `lua` instead of `tstl` * Fix formatting * Move plugin out of transformation pipeline * Allow to specify custom printer through plugins * Make printer plugin stateless * Fix 'printer' property name in error message * Make standard transformers have lowest priority * Add few comments to public plugin API * Simplify some code * Use canonical casing for annotations * Move `OmittedExpression` handling to context visitors * Move TODO visitors to `typescript` file * Class `creation` -> `setup` * Merge `annotations` utils files * Some minor refactors * Rename prototype transform functions * Update `printer` comment * `variable` -> `variable-declaration` * Rename `transformation/transformers` to `transformation/visitors` * Remove unnecessary import --- package.json | 2 +- src/Decorator.ts | 39 - src/LuaAST.ts | 8 +- src/LuaKeywords.ts | 46 - src/LuaPrinter.ts | 481 +- src/LuaTransformer.ts | 6240 ----------------- src/TSHelper.ts | 1066 --- src/Transpile.ts | 47 +- src/TranspileError.ts | 8 - src/bundle.ts | 12 +- src/diagnostics.ts | 11 - src/index.ts | 4 +- src/lualib/TypeOf.ts | 2 - src/plugins.ts | 27 + src/transformation/builtins/array.ts | 102 + src/transformation/builtins/console.ts | 63 + src/transformation/builtins/function.ts | 32 + src/transformation/builtins/global.ts | 34 + src/transformation/builtins/index.ts | 136 + src/transformation/builtins/math.ts | 97 + src/transformation/builtins/number.ts | 42 + src/transformation/builtins/object.ts | 56 + src/transformation/builtins/string.ts | 191 + src/transformation/builtins/symbol.ts | 26 + src/transformation/context/context.ts | 96 + src/transformation/context/index.ts | 2 + src/transformation/context/visitors.ts | 164 + src/transformation/index.ts | 74 + src/transformation/utils/annotations.ts | 205 + .../utils/assignment-validation.ts | 125 + .../utils/errors.ts} | 134 +- src/transformation/utils/export.ts | 129 + src/transformation/utils/function-context.ts | 146 + src/transformation/utils/lua-ast.ts | 235 + src/transformation/utils/lualib.ts | 27 + src/transformation/utils/safe-names.ts | 102 + src/transformation/utils/scope.ts | 221 + src/transformation/utils/symbols.ts | 70 + src/transformation/utils/typescript/index.ts | 99 + src/transformation/utils/typescript/nodes.ts | 41 + src/transformation/utils/typescript/types.ts | 78 + src/transformation/visitors/access.ts | 103 + .../visitors/binary-expression/assignments.ts | 163 + .../visitors/binary-expression/bit.ts | 111 + .../visitors/binary-expression/compound.ts | 182 + .../destructuring-assignments.ts | 279 + .../visitors/binary-expression/index.ts | 241 + src/transformation/visitors/block.ts | 26 + src/transformation/visitors/break-continue.ts | 33 + src/transformation/visitors/call.ts | 218 + .../visitors/class/decorators.ts | 43 + src/transformation/visitors/class/index.ts | 363 + .../visitors/class/members/accessors.ts | 104 + .../visitors/class/members/constructor.ts | 95 + .../visitors/class/members/fields.ts | 49 + .../visitors/class/members/method.ts | 51 + src/transformation/visitors/class/new.ts | 86 + src/transformation/visitors/class/setup.ts | 348 + src/transformation/visitors/class/utils.ts | 32 + src/transformation/visitors/conditional.ts | 97 + src/transformation/visitors/delete.ts | 25 + src/transformation/visitors/enum.ts | 94 + src/transformation/visitors/errors.ts | 120 + .../visitors/expression-statement.ts | 36 + src/transformation/visitors/function.ts | 284 + src/transformation/visitors/generator.ts | 115 + src/transformation/visitors/identifier.ts | 48 + src/transformation/visitors/index.ts | 100 + src/transformation/visitors/literal.ts | 150 + src/transformation/visitors/loops/body.ts | 25 + src/transformation/visitors/loops/do-while.ts | 24 + src/transformation/visitors/loops/for-in.ts | 45 + src/transformation/visitors/loops/for-of.ts | 270 + src/transformation/visitors/loops/for.ts | 35 + src/transformation/visitors/lua-table.ts | 145 + src/transformation/visitors/modules/export.ts | 148 + src/transformation/visitors/modules/import.ts | 207 + src/transformation/visitors/namespace.ts | 133 + src/transformation/visitors/return.ts | 63 + src/transformation/visitors/sourceFile.ts | 38 + src/transformation/visitors/switch.ts | 61 + src/transformation/visitors/template.ts | 87 + src/transformation/visitors/typeof.ts | 51 + src/transformation/visitors/typescript.ts | 25 + .../visitors/unary-expression.ts | 122 + .../visitors/variable-declaration.ts | 226 + src/utils.ts | 45 +- test/legacy-utils.ts | 12 +- .../__snapshots__/transformation.spec.ts.snap | 10 +- .../transformation/characterEscapeSequence.ts | 2 +- test/unit/builtins/loading.spec.ts | 6 +- test/unit/builtins/string.spec.ts | 4 +- test/unit/classes/classes.spec.ts | 18 +- test/unit/classes/decorators.spec.ts | 4 +- test/unit/conditionals.spec.ts | 6 +- .../unit/decorators/customConstructor.spec.ts | 4 +- test/unit/decorators/extension.spec.ts | 14 +- test/unit/decorators/forRange.spec.ts | 20 +- test/unit/decorators/luaIterator.spec.ts | 6 +- test/unit/decorators/luaTable.spec.ts | 42 +- test/unit/decorators/metaExtension.spec.ts | 6 +- test/unit/error.spec.ts | 2 +- test/unit/expressions.spec.ts | 8 +- test/unit/functions/functions.spec.ts | 14 - .../invalidFunctionAssignments.spec.ts | 54 +- test/unit/hoisting.spec.ts | 4 +- test/unit/identifiers.spec.ts | 16 +- test/unit/json.spec.ts | 6 +- test/unit/loops.spec.ts | 18 +- test/unit/tshelper.spec.ts | 143 - test/unit/typeof.spec.ts | 107 +- test/util.ts | 5 - 112 files changed, 8527 insertions(+), 8070 deletions(-) delete mode 100644 src/Decorator.ts delete mode 100644 src/LuaKeywords.ts delete mode 100644 src/LuaTransformer.ts delete mode 100644 src/TSHelper.ts delete mode 100644 src/TranspileError.ts create mode 100644 src/plugins.ts create mode 100644 src/transformation/builtins/array.ts create mode 100644 src/transformation/builtins/console.ts create mode 100644 src/transformation/builtins/function.ts create mode 100644 src/transformation/builtins/global.ts create mode 100644 src/transformation/builtins/index.ts create mode 100644 src/transformation/builtins/math.ts create mode 100644 src/transformation/builtins/number.ts create mode 100644 src/transformation/builtins/object.ts create mode 100644 src/transformation/builtins/string.ts create mode 100644 src/transformation/builtins/symbol.ts create mode 100644 src/transformation/context/context.ts create mode 100644 src/transformation/context/index.ts create mode 100644 src/transformation/context/visitors.ts create mode 100644 src/transformation/index.ts create mode 100644 src/transformation/utils/annotations.ts create mode 100644 src/transformation/utils/assignment-validation.ts rename src/{TSTLErrors.ts => transformation/utils/errors.ts} (57%) create mode 100644 src/transformation/utils/export.ts create mode 100644 src/transformation/utils/function-context.ts create mode 100644 src/transformation/utils/lua-ast.ts create mode 100644 src/transformation/utils/lualib.ts create mode 100644 src/transformation/utils/safe-names.ts create mode 100644 src/transformation/utils/scope.ts create mode 100644 src/transformation/utils/symbols.ts create mode 100644 src/transformation/utils/typescript/index.ts create mode 100644 src/transformation/utils/typescript/nodes.ts create mode 100644 src/transformation/utils/typescript/types.ts create mode 100644 src/transformation/visitors/access.ts create mode 100644 src/transformation/visitors/binary-expression/assignments.ts create mode 100644 src/transformation/visitors/binary-expression/bit.ts create mode 100644 src/transformation/visitors/binary-expression/compound.ts create mode 100644 src/transformation/visitors/binary-expression/destructuring-assignments.ts create mode 100644 src/transformation/visitors/binary-expression/index.ts create mode 100644 src/transformation/visitors/block.ts create mode 100644 src/transformation/visitors/break-continue.ts create mode 100644 src/transformation/visitors/call.ts create mode 100644 src/transformation/visitors/class/decorators.ts create mode 100644 src/transformation/visitors/class/index.ts create mode 100644 src/transformation/visitors/class/members/accessors.ts create mode 100644 src/transformation/visitors/class/members/constructor.ts create mode 100644 src/transformation/visitors/class/members/fields.ts create mode 100644 src/transformation/visitors/class/members/method.ts create mode 100644 src/transformation/visitors/class/new.ts create mode 100644 src/transformation/visitors/class/setup.ts create mode 100644 src/transformation/visitors/class/utils.ts create mode 100644 src/transformation/visitors/conditional.ts create mode 100644 src/transformation/visitors/delete.ts create mode 100644 src/transformation/visitors/enum.ts create mode 100644 src/transformation/visitors/errors.ts create mode 100644 src/transformation/visitors/expression-statement.ts create mode 100644 src/transformation/visitors/function.ts create mode 100644 src/transformation/visitors/generator.ts create mode 100644 src/transformation/visitors/identifier.ts create mode 100644 src/transformation/visitors/index.ts create mode 100644 src/transformation/visitors/literal.ts create mode 100644 src/transformation/visitors/loops/body.ts create mode 100644 src/transformation/visitors/loops/do-while.ts create mode 100644 src/transformation/visitors/loops/for-in.ts create mode 100644 src/transformation/visitors/loops/for-of.ts create mode 100644 src/transformation/visitors/loops/for.ts create mode 100644 src/transformation/visitors/lua-table.ts create mode 100644 src/transformation/visitors/modules/export.ts create mode 100644 src/transformation/visitors/modules/import.ts create mode 100644 src/transformation/visitors/namespace.ts create mode 100644 src/transformation/visitors/return.ts create mode 100644 src/transformation/visitors/sourceFile.ts create mode 100644 src/transformation/visitors/switch.ts create mode 100644 src/transformation/visitors/template.ts create mode 100644 src/transformation/visitors/typeof.ts create mode 100644 src/transformation/visitors/typescript.ts create mode 100644 src/transformation/visitors/unary-expression.ts create mode 100644 src/transformation/visitors/variable-declaration.ts delete mode 100644 test/unit/tshelper.spec.ts diff --git a/package.json b/package.json index 12336a104..b7c1f469a 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { - "build": "tsc -p tsconfig.json && npm run build-lualib", + "build": "tsc && npm run build-lualib", "build-lualib": "ts-node --files ./build_lualib.ts", "pretest": "npm run lint && ts-node --files --transpile-only ./build_lualib.ts", "test": "jest", diff --git a/src/Decorator.ts b/src/Decorator.ts deleted file mode 100644 index 107676b0d..000000000 --- a/src/Decorator.ts +++ /dev/null @@ -1,39 +0,0 @@ -export class Decorator { - public static isValid(decoratorKindString: string): boolean { - return this.getDecoratorKind(decoratorKindString) !== undefined; - } - - public static getDecoratorKind(decoratorKindString: string): DecoratorKind | undefined { - return Object.values(DecoratorKind).find( - decoratorKind => decoratorKind.toLowerCase() === decoratorKindString.toLowerCase() - ); - } - - public kind: DecoratorKind; - - constructor(name: string, public args: string[]) { - const kind = Decorator.getDecoratorKind(name); - if (kind === undefined) { - throw new Error(`Failed to parse decorator '${name}'`); - } - - this.kind = kind; - } -} - -export enum DecoratorKind { - Extension = "Extension", - MetaExtension = "MetaExtension", - CustomConstructor = "CustomConstructor", - CompileMembersOnly = "CompileMembersOnly", - NoResolution = "NoResolution", - PureAbstract = "PureAbstract", - Phantom = "Phantom", - TupleReturn = "TupleReturn", - LuaIterator = "LuaIterator", - LuaTable = "LuaTable", - NoSelf = "NoSelf", - NoSelfInFile = "NoSelfInFile", - Vararg = "Vararg", - ForRange = "ForRange", -} diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 7fcd4a74b..2ef2310dd 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -1,8 +1,8 @@ // Simplified Lua AST based roughly on http://lua-users.org/wiki/MetaLuaAbstractSyntaxTree, -// https://www.lua.org/manual/5.3/manual.html (9 – The Complete Syntax of Lua) and the TS AST implementation +// https://www.lua.org/manual/5.3/manual.html#9 and the TS AST implementation // We can elide a lot of nodes especially tokens and keywords -// because we dont create the AST from text +// because we don't create the AST from text import * as ts from "typescript"; @@ -121,7 +121,7 @@ export type BinaryOperator = export type Operator = UnaryOperator | BinaryOperator; -export type SymbolId = number; +export type SymbolId = number & { _symbolIdBrand: any }; export interface TextRange { line?: number; @@ -616,7 +616,7 @@ export function isStringLiteral(node: Node): node is StringLiteral { export function createStringLiteral(value: string, tsOriginal?: ts.Node, parent?: Node): StringLiteral { const expression = createNode(SyntaxKind.StringLiteral, tsOriginal, parent) as StringLiteral; - expression.value = value as string; + expression.value = value; return expression; } diff --git a/src/LuaKeywords.ts b/src/LuaKeywords.ts deleted file mode 100644 index 55aa120f9..000000000 --- a/src/LuaKeywords.ts +++ /dev/null @@ -1,46 +0,0 @@ -export const luaKeywords: Set = new Set([ - "and", - "break", - "do", - "else", - "elseif", - "end", - "false", - "for", - "function", - "goto", - "if", - "in", - "local", - "nil", - "not", - "or", - "repeat", - "return", - "then", - "until", - "while", -]); - -export const luaBuiltins: Set = new Set([ - "_G", - "assert", - "coroutine", - "debug", - "error", - "ipairs", - "math", - "pairs", - "pcall", - "print", - "rawget", - "rawset", - "repeat", - "require", - "self", - "string", - "table", - "tostring", - "type", - "unpack", -]); diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 4fec7e595..2d8a2ac20 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,81 +1,166 @@ import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; +import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; -import * as tstl from "./LuaAST"; -import { luaKeywords } from "./LuaKeywords"; +import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; +import { isValidLuaIdentifier, luaKeywords } from "./transformation/utils/safe-names"; import { EmitHost } from "./Transpile"; -import * as tsHelper from "./TSHelper"; +import { trimExtension } from "./utils"; + +// https://www.lua.org/pil/2.4.html +// https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 +const escapeStringRegExp = /[\b\f\n\r\t\v\\"\0]/g; +const escapeStringMap: Record = { + "\b": "\\b", + "\f": "\\f", + "\n": "\\n", + "\r": "\\r", + "\t": "\\t", + "\v": "\\v", + "\\": "\\\\", + '"': '\\"', + "\0": "\\0", +}; + +export const escapeString = (value: string) => + `"${value.replace(escapeStringRegExp, char => escapeStringMap[char] || char)}"`; + +/** + * Checks that a name is valid for use in lua function declaration syntax: + * + * `foo.bar` => passes (`function foo.bar()` is valid) + * `getFoo().bar` => fails (`function getFoo().bar()` would be illegal) + */ +const isValidLuaFunctionDeclarationName = (str: string) => /^[a-zA-Z0-9_\.]+$/.test(str); + +/** + * Returns true if expression contains no function calls. + */ +function isSimpleExpression(expression: lua.Expression): boolean { + switch (expression.kind) { + case lua.SyntaxKind.CallExpression: + case lua.SyntaxKind.MethodCallExpression: + case lua.SyntaxKind.FunctionExpression: + return false; + + case lua.SyntaxKind.TableExpression: + const tableExpression = expression as lua.TableExpression; + return tableExpression.fields.every(e => isSimpleExpression(e)); + + case lua.SyntaxKind.TableFieldExpression: + const fieldExpression = expression as lua.TableFieldExpression; + return ( + (!fieldExpression.key || isSimpleExpression(fieldExpression.key)) && + isSimpleExpression(fieldExpression.value) + ); + + case lua.SyntaxKind.TableIndexExpression: + const indexExpression = expression as lua.TableIndexExpression; + return isSimpleExpression(indexExpression.table) && isSimpleExpression(indexExpression.index); + + case lua.SyntaxKind.UnaryExpression: + return isSimpleExpression((expression as lua.UnaryExpression).operand); + + case lua.SyntaxKind.BinaryExpression: + const binaryExpression = expression as lua.BinaryExpression; + return isSimpleExpression(binaryExpression.left) && isSimpleExpression(binaryExpression.right); + + case lua.SyntaxKind.ParenthesizedExpression: + return isSimpleExpression((expression as lua.ParenthesizedExpression).innerExpression); + } + + return true; +} type SourceChunk = string | SourceNode; +export type Printer = ( + program: ts.Program, + emitHost: EmitHost, + fileName: string, + block: lua.Block, + luaLibFeatures: Set +) => PrintResult; + +export interface PrintResult { + code: string; + sourceMap: string; + sourceMapNode: SourceNode; +} + +export function createPrinter(printers: Printer[]): Printer { + if (printers.length === 0) { + return (program, emitHost, fileName, ...args) => + new LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args); + } else if (printers.length === 1) { + return printers[0]; + } else { + throw new Error("Only one plugin can specify 'printer'"); + } +} + export class LuaPrinter { - private static operatorMap: { [key in tstl.Operator]: string } = { - [tstl.SyntaxKind.AdditionOperator]: "+", - [tstl.SyntaxKind.SubtractionOperator]: "-", - [tstl.SyntaxKind.MultiplicationOperator]: "*", - [tstl.SyntaxKind.DivisionOperator]: "/", - [tstl.SyntaxKind.FloorDivisionOperator]: "//", - [tstl.SyntaxKind.ModuloOperator]: "%", - [tstl.SyntaxKind.PowerOperator]: "^", - [tstl.SyntaxKind.NegationOperator]: "-", - [tstl.SyntaxKind.ConcatOperator]: "..", - [tstl.SyntaxKind.LengthOperator]: "#", - [tstl.SyntaxKind.EqualityOperator]: "==", - [tstl.SyntaxKind.InequalityOperator]: "~=", - [tstl.SyntaxKind.LessThanOperator]: "<", - [tstl.SyntaxKind.LessEqualOperator]: "<=", - [tstl.SyntaxKind.GreaterThanOperator]: ">", - [tstl.SyntaxKind.GreaterEqualOperator]: ">=", - [tstl.SyntaxKind.AndOperator]: "and", - [tstl.SyntaxKind.OrOperator]: "or", - [tstl.SyntaxKind.NotOperator]: "not ", - [tstl.SyntaxKind.BitwiseAndOperator]: "&", - [tstl.SyntaxKind.BitwiseOrOperator]: "|", - [tstl.SyntaxKind.BitwiseExclusiveOrOperator]: "~", - [tstl.SyntaxKind.BitwiseRightShiftOperator]: ">>", - [tstl.SyntaxKind.BitwiseLeftShiftOperator]: "<<", - [tstl.SyntaxKind.BitwiseNotOperator]: "~", + private static operatorMap: Record = { + [lua.SyntaxKind.AdditionOperator]: "+", + [lua.SyntaxKind.SubtractionOperator]: "-", + [lua.SyntaxKind.MultiplicationOperator]: "*", + [lua.SyntaxKind.DivisionOperator]: "/", + [lua.SyntaxKind.FloorDivisionOperator]: "//", + [lua.SyntaxKind.ModuloOperator]: "%", + [lua.SyntaxKind.PowerOperator]: "^", + [lua.SyntaxKind.NegationOperator]: "-", + [lua.SyntaxKind.ConcatOperator]: "..", + [lua.SyntaxKind.LengthOperator]: "#", + [lua.SyntaxKind.EqualityOperator]: "==", + [lua.SyntaxKind.InequalityOperator]: "~=", + [lua.SyntaxKind.LessThanOperator]: "<", + [lua.SyntaxKind.LessEqualOperator]: "<=", + [lua.SyntaxKind.GreaterThanOperator]: ">", + [lua.SyntaxKind.GreaterEqualOperator]: ">=", + [lua.SyntaxKind.AndOperator]: "and", + [lua.SyntaxKind.OrOperator]: "or", + [lua.SyntaxKind.NotOperator]: "not ", + [lua.SyntaxKind.BitwiseAndOperator]: "&", + [lua.SyntaxKind.BitwiseOrOperator]: "|", + [lua.SyntaxKind.BitwiseExclusiveOrOperator]: "~", + [lua.SyntaxKind.BitwiseRightShiftOperator]: ">>", + [lua.SyntaxKind.BitwiseLeftShiftOperator]: "<<", + [lua.SyntaxKind.BitwiseNotOperator]: "~", }; private currentIndent = ""; - private sourceFile = ""; + private sourceFile: string; - public constructor(private options: CompilerOptions, private emitHost: EmitHost) {} + public constructor(private options: CompilerOptions, private emitHost: EmitHost, fileName: string) { + this.sourceFile = path.basename(fileName); + } - public print( - block: tstl.Block, - luaLibFeatures?: Set, - sourceFile = "" - ): [string, string, SourceNode] { + public print(block: lua.Block, luaLibFeatures: Set): PrintResult { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { - if (luaLibFeatures === undefined) { - luaLibFeatures = new Set(); - } luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); } - const rootSourceNode = this.printImplementation(block, luaLibFeatures, sourceFile); - const sourceRoot = this.options.sourceRoot || (this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : "."); - const sourceMap = this.buildSourceMap(sourceFile, sourceRoot, rootSourceNode); + const rootSourceNode = this.printImplementation(block, luaLibFeatures); + const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); - let codeResult = rootSourceNode.toString(); + let code = rootSourceNode.toString(); if (this.options.inlineSourceMap) { - codeResult += "\n" + this.printInlineSourceMap(sourceMap); + code += "\n" + this.printInlineSourceMap(sourceMap); } if (this.options.sourceMapTraceback) { const stackTraceOverride = this.printStackTraceOverride(rootSourceNode); - codeResult = codeResult.replace("{#SourceMapTraceback}", stackTraceOverride); + code = code.replace("{#SourceMapTraceback}", stackTraceOverride); } - return [codeResult, sourceMap.toString(), rootSourceNode]; + return { code, sourceMap: sourceMap.toString(), sourceMapNode: rootSourceNode }; } private printInlineSourceMap(sourceMap: SourceMapGenerator): string { @@ -86,54 +171,46 @@ export class LuaPrinter { } private printStackTraceOverride(rootNode: SourceNode): string { - let line = 1; - const map: { [line: number]: number } = {}; + let currentLine = 1; + const map: Record = {}; rootNode.walk((chunk, mappedPosition) => { if (mappedPosition.line !== undefined && mappedPosition.line > 0) { - if (map[line] === undefined) { - map[line] = mappedPosition.line; + if (map[currentLine] === undefined) { + map[currentLine] = mappedPosition.line; } else { - map[line] = Math.min(map[line], mappedPosition.line); + map[currentLine] = Math.min(map[currentLine], mappedPosition.line); } } - line += chunk.split("\n").length - 1; - }); - const mapItems = []; - for (const lineNr in map) { - mapItems.push(`["${lineNr}"] = ${map[lineNr]}`); - } + currentLine += chunk.split("\n").length - 1; + }); + const mapItems = Object.entries(map).map(([line, original]) => `["${line}"] = ${original}`); const mapString = "{" + mapItems.join(",") + "}"; return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printImplementation(block: tstl.Block, luaLibFeatures?: Set, sourceFile = ""): SourceNode { + private printImplementation(block: lua.Block, luaLibFeatures: Set): SourceNode { let header = ""; if (!this.options.noHeader) { header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`; } - if (luaLibFeatures) { - const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Require; + const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Require; + if ( + luaLibImport === LuaLibImportKind.Always || + (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) + ) { // Require lualib bundle - if ( - (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) || - luaLibImport === LuaLibImportKind.Always - ) { - header += `require("lualib_bundle");\n`; - } + header += `require("lualib_bundle");\n`; + } else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { // Inline lualib features - else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { - header += "-- Lua Library inline imports\n"; - header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); - } + header += "-- Lua Library inline imports\n"; + header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); } - this.sourceFile = path.basename(sourceFile); - if (this.options.sourceMapTraceback) { header += "{#SourceMapTraceback}\n"; } @@ -155,8 +232,8 @@ export class LuaPrinter { return this.concatNodes(this.currentIndent, input); } - protected createSourceNode(node: tstl.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode { - const originalPos = tstl.getOriginalPos(node); + protected createSourceNode(node: lua.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode { + const originalPos = lua.getOriginalPos(node); return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks, name) @@ -168,16 +245,16 @@ export class LuaPrinter { return new SourceNode(null, null, this.sourceFile, chunks); } - protected printBlock(block: tstl.Block): SourceNode { + protected printBlock(block: lua.Block): SourceNode { return this.concatNodes(...this.printStatementArray(block.statements)); } - private statementMayRequireSemiColon(statement: tstl.Statement): boolean { + private statementMayRequireSemiColon(statement: lua.Statement): boolean { // Types of statements that could create ambiguous syntax if followed by parenthesis return ( - tstl.isVariableDeclarationStatement(statement) || - tstl.isAssignmentStatement(statement) || - tstl.isExpressionStatement(statement) + lua.isVariableDeclarationStatement(statement) || + lua.isAssignmentStatement(statement) || + lua.isExpressionStatement(statement) ); } @@ -195,7 +272,7 @@ export class LuaPrinter { return result || false; } - protected printStatementArray(statements: tstl.Statement[]): SourceChunk[] { + protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; statements = this.removeDeadAndEmptyStatements(statements); statements.forEach((s, i) => { @@ -210,40 +287,40 @@ export class LuaPrinter { return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } - public printStatement(statement: tstl.Statement): SourceNode { + public printStatement(statement: lua.Statement): SourceNode { switch (statement.kind) { - case tstl.SyntaxKind.DoStatement: - return this.printDoStatement(statement as tstl.DoStatement); - case tstl.SyntaxKind.VariableDeclarationStatement: - return this.printVariableDeclarationStatement(statement as tstl.VariableDeclarationStatement); - case tstl.SyntaxKind.AssignmentStatement: - return this.printVariableAssignmentStatement(statement as tstl.AssignmentStatement); - case tstl.SyntaxKind.IfStatement: - return this.printIfStatement(statement as tstl.IfStatement); - case tstl.SyntaxKind.WhileStatement: - return this.printWhileStatement(statement as tstl.WhileStatement); - case tstl.SyntaxKind.RepeatStatement: - return this.printRepeatStatement(statement as tstl.RepeatStatement); - case tstl.SyntaxKind.ForStatement: - return this.printForStatement(statement as tstl.ForStatement); - case tstl.SyntaxKind.ForInStatement: - return this.printForInStatement(statement as tstl.ForInStatement); - case tstl.SyntaxKind.GotoStatement: - return this.printGotoStatement(statement as tstl.GotoStatement); - case tstl.SyntaxKind.LabelStatement: - return this.printLabelStatement(statement as tstl.LabelStatement); - case tstl.SyntaxKind.ReturnStatement: - return this.printReturnStatement(statement as tstl.ReturnStatement); - case tstl.SyntaxKind.BreakStatement: - return this.printBreakStatement(statement as tstl.BreakStatement); - case tstl.SyntaxKind.ExpressionStatement: - return this.printExpressionStatement(statement as tstl.ExpressionStatement); + case lua.SyntaxKind.DoStatement: + return this.printDoStatement(statement as lua.DoStatement); + case lua.SyntaxKind.VariableDeclarationStatement: + return this.printVariableDeclarationStatement(statement as lua.VariableDeclarationStatement); + case lua.SyntaxKind.AssignmentStatement: + return this.printVariableAssignmentStatement(statement as lua.AssignmentStatement); + case lua.SyntaxKind.IfStatement: + return this.printIfStatement(statement as lua.IfStatement); + case lua.SyntaxKind.WhileStatement: + return this.printWhileStatement(statement as lua.WhileStatement); + case lua.SyntaxKind.RepeatStatement: + return this.printRepeatStatement(statement as lua.RepeatStatement); + case lua.SyntaxKind.ForStatement: + return this.printForStatement(statement as lua.ForStatement); + case lua.SyntaxKind.ForInStatement: + return this.printForInStatement(statement as lua.ForInStatement); + case lua.SyntaxKind.GotoStatement: + return this.printGotoStatement(statement as lua.GotoStatement); + case lua.SyntaxKind.LabelStatement: + return this.printLabelStatement(statement as lua.LabelStatement); + case lua.SyntaxKind.ReturnStatement: + return this.printReturnStatement(statement as lua.ReturnStatement); + case lua.SyntaxKind.BreakStatement: + return this.printBreakStatement(statement as lua.BreakStatement); + case lua.SyntaxKind.ExpressionStatement: + return this.printExpressionStatement(statement as lua.ExpressionStatement); default: - throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[statement.kind]}`); + throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[statement.kind]}`); } } - public printDoStatement(statement: tstl.DoStatement): SourceNode { + public printDoStatement(statement: lua.DoStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("do\n")); @@ -255,12 +332,12 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - public printVariableDeclarationStatement(statement: tstl.VariableDeclarationStatement): SourceNode { + public printVariableDeclarationStatement(statement: lua.VariableDeclarationStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("local ")); - if (tstl.isFunctionDefinition(statement)) { + if (lua.isFunctionDefinition(statement)) { // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion chunks.push(this.printFunctionDefinition(statement)); } else { @@ -275,18 +352,18 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - public printVariableAssignmentStatement(statement: tstl.AssignmentStatement): SourceNode { + public printVariableAssignmentStatement(statement: lua.AssignmentStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent()); if ( - tstl.isFunctionDefinition(statement) && - (statement.right[0].flags & tstl.FunctionExpressionFlags.Declaration) !== 0 + lua.isFunctionDefinition(statement) && + (statement.right[0].flags & lua.FunctionExpressionFlags.Declaration) !== 0 ) { // Use `function foo()` instead of `foo = function()` const name = this.printExpression(statement.left[0]); - if (tsHelper.isValidLuaFunctionDeclarationName(name.toString())) { + if (isValidLuaFunctionDeclarationName(name.toString())) { chunks.push(this.printFunctionDefinition(statement)); return this.createSourceNode(statement, chunks); } @@ -299,10 +376,10 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - public printIfStatement(statement: tstl.IfStatement): SourceNode { + public printIfStatement(statement: lua.IfStatement): SourceNode { const chunks: SourceChunk[] = []; - const isElseIf = statement.parent !== undefined && tstl.isIfStatement(statement.parent); + const isElseIf = statement.parent !== undefined && lua.isIfStatement(statement.parent); const prefix = isElseIf ? "elseif" : "if"; @@ -313,7 +390,7 @@ export class LuaPrinter { this.popIndent(); if (statement.elseBlock) { - if (tstl.isIfStatement(statement.elseBlock)) { + if (lua.isIfStatement(statement.elseBlock)) { chunks.push(this.printIfStatement(statement.elseBlock)); } else { chunks.push(this.indent("else\n")); @@ -329,7 +406,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - public printWhileStatement(statement: tstl.WhileStatement): SourceNode { + public printWhileStatement(statement: lua.WhileStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent("while "), this.printExpression(statement.condition), " do\n"); @@ -343,7 +420,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - public printRepeatStatement(statement: tstl.RepeatStatement): SourceNode { + public printRepeatStatement(statement: lua.RepeatStatement): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.indent(`repeat\n`)); @@ -357,7 +434,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - public printForStatement(statement: tstl.ForStatement): SourceNode { + public printForStatement(statement: lua.ForStatement): SourceNode { const ctrlVar = this.printExpression(statement.controlVariable); const ctrlVarInit = this.printExpression(statement.controlVariableInitializer); const limit = this.printExpression(statement.limitExpression); @@ -380,7 +457,7 @@ export class LuaPrinter { return this.concatNodes(...chunks); } - public printForInStatement(statement: tstl.ForInStatement): SourceNode { + public printForInStatement(statement: lua.ForInStatement): SourceNode { const names = this.joinChunks(", ", statement.names.map(i => this.printIdentifier(i))); const expressions = this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e))); @@ -396,15 +473,15 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - public printGotoStatement(statement: tstl.GotoStatement): SourceNode { + public printGotoStatement(statement: lua.GotoStatement): SourceNode { return this.createSourceNode(statement, [this.indent("goto "), statement.label]); } - public printLabelStatement(statement: tstl.LabelStatement): SourceNode { + public printLabelStatement(statement: lua.LabelStatement): SourceNode { return this.createSourceNode(statement, [this.indent("::"), statement.name, "::"]); } - public printReturnStatement(statement: tstl.ReturnStatement): SourceNode { + public printReturnStatement(statement: lua.ReturnStatement): SourceNode { if (!statement.expressions || statement.expressions.length === 0) { return this.createSourceNode(statement, this.indent("return")); } @@ -416,78 +493,78 @@ export class LuaPrinter { return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } - public printBreakStatement(statement: tstl.BreakStatement): SourceNode { + public printBreakStatement(statement: lua.BreakStatement): SourceNode { return this.createSourceNode(statement, this.indent("break")); } - public printExpressionStatement(statement: tstl.ExpressionStatement): SourceNode { + public printExpressionStatement(statement: lua.ExpressionStatement): SourceNode { return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]); } // Expressions - public printExpression(expression: tstl.Expression): SourceNode { + public printExpression(expression: lua.Expression): SourceNode { switch (expression.kind) { - case tstl.SyntaxKind.StringLiteral: - return this.printStringLiteral(expression as tstl.StringLiteral); - case tstl.SyntaxKind.NumericLiteral: - return this.printNumericLiteral(expression as tstl.NumericLiteral); - case tstl.SyntaxKind.NilKeyword: - return this.printNilLiteral(expression as tstl.NilLiteral); - case tstl.SyntaxKind.DotsKeyword: - return this.printDotsLiteral(expression as tstl.DotsLiteral); - case tstl.SyntaxKind.TrueKeyword: - case tstl.SyntaxKind.FalseKeyword: - return this.printBooleanLiteral(expression as tstl.BooleanLiteral); - case tstl.SyntaxKind.FunctionExpression: - return this.printFunctionExpression(expression as tstl.FunctionExpression); - case tstl.SyntaxKind.TableFieldExpression: - return this.printTableFieldExpression(expression as tstl.TableFieldExpression); - case tstl.SyntaxKind.TableExpression: - return this.printTableExpression(expression as tstl.TableExpression); - case tstl.SyntaxKind.UnaryExpression: - return this.printUnaryExpression(expression as tstl.UnaryExpression); - case tstl.SyntaxKind.BinaryExpression: - return this.printBinaryExpression(expression as tstl.BinaryExpression); - case tstl.SyntaxKind.ParenthesizedExpression: - return this.printParenthesizedExpression(expression as tstl.ParenthesizedExpression); - case tstl.SyntaxKind.CallExpression: - return this.printCallExpression(expression as tstl.CallExpression); - case tstl.SyntaxKind.MethodCallExpression: - return this.printMethodCallExpression(expression as tstl.MethodCallExpression); - case tstl.SyntaxKind.Identifier: - return this.printIdentifier(expression as tstl.Identifier); - case tstl.SyntaxKind.TableIndexExpression: - return this.printTableIndexExpression(expression as tstl.TableIndexExpression); + case lua.SyntaxKind.StringLiteral: + return this.printStringLiteral(expression as lua.StringLiteral); + case lua.SyntaxKind.NumericLiteral: + return this.printNumericLiteral(expression as lua.NumericLiteral); + case lua.SyntaxKind.NilKeyword: + return this.printNilLiteral(expression as lua.NilLiteral); + case lua.SyntaxKind.DotsKeyword: + return this.printDotsLiteral(expression as lua.DotsLiteral); + case lua.SyntaxKind.TrueKeyword: + case lua.SyntaxKind.FalseKeyword: + return this.printBooleanLiteral(expression as lua.BooleanLiteral); + case lua.SyntaxKind.FunctionExpression: + return this.printFunctionExpression(expression as lua.FunctionExpression); + case lua.SyntaxKind.TableFieldExpression: + return this.printTableFieldExpression(expression as lua.TableFieldExpression); + case lua.SyntaxKind.TableExpression: + return this.printTableExpression(expression as lua.TableExpression); + case lua.SyntaxKind.UnaryExpression: + return this.printUnaryExpression(expression as lua.UnaryExpression); + case lua.SyntaxKind.BinaryExpression: + return this.printBinaryExpression(expression as lua.BinaryExpression); + case lua.SyntaxKind.ParenthesizedExpression: + return this.printParenthesizedExpression(expression as lua.ParenthesizedExpression); + case lua.SyntaxKind.CallExpression: + return this.printCallExpression(expression as lua.CallExpression); + case lua.SyntaxKind.MethodCallExpression: + return this.printMethodCallExpression(expression as lua.MethodCallExpression); + case lua.SyntaxKind.Identifier: + return this.printIdentifier(expression as lua.Identifier); + case lua.SyntaxKind.TableIndexExpression: + return this.printTableIndexExpression(expression as lua.TableIndexExpression); default: - throw new Error(`Tried to print unknown statement kind: ${tstl.SyntaxKind[expression.kind]}`); + throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`); } } - public printStringLiteral(expression: tstl.StringLiteral): SourceNode { - return this.createSourceNode(expression, `"${expression.value}"`); + public printStringLiteral(expression: lua.StringLiteral): SourceNode { + return this.createSourceNode(expression, escapeString(expression.value)); } - public printNumericLiteral(expression: tstl.NumericLiteral): SourceNode { + public printNumericLiteral(expression: lua.NumericLiteral): SourceNode { return this.createSourceNode(expression, String(expression.value)); } - public printNilLiteral(expression: tstl.NilLiteral): SourceNode { + public printNilLiteral(expression: lua.NilLiteral): SourceNode { return this.createSourceNode(expression, "nil"); } - public printDotsLiteral(expression: tstl.DotsLiteral): SourceNode { + public printDotsLiteral(expression: lua.DotsLiteral): SourceNode { return this.createSourceNode(expression, "..."); } - public printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { - if (expression.kind === tstl.SyntaxKind.TrueKeyword) { + public printBooleanLiteral(expression: lua.BooleanLiteral): SourceNode { + if (expression.kind === lua.SyntaxKind.TrueKeyword) { return this.createSourceNode(expression, "true"); } else { return this.createSourceNode(expression, "false"); } } - private printFunctionParameters(expression: tstl.FunctionExpression): SourceChunk[] { + private printFunctionParameters(expression: lua.FunctionExpression): SourceChunk[] { const parameterChunks: SourceNode[] = expression.params ? expression.params.map(i => this.printIdentifier(i)) : []; @@ -499,14 +576,14 @@ export class LuaPrinter { return this.joinChunks(", ", parameterChunks); } - public printFunctionExpression(expression: tstl.FunctionExpression): SourceNode { + public printFunctionExpression(expression: lua.FunctionExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push("function("); chunks.push(...this.printFunctionParameters(expression)); chunks.push(")"); - if (tstl.isInlineFunctionExpression(expression)) { + if (lua.isInlineFunctionExpression(expression)) { const returnStatement = expression.body.statements[0]; chunks.push(" "); const returnNode: SourceChunk[] = [ @@ -526,7 +603,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printFunctionDefinition(statement: tstl.FunctionDefinition): SourceNode { + public printFunctionDefinition(statement: lua.FunctionDefinition): SourceNode { const expression = statement.right[0]; const chunks: SourceChunk[] = []; @@ -544,15 +621,15 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printTableFieldExpression(expression: tstl.TableFieldExpression): SourceNode { + public printTableFieldExpression(expression: lua.TableFieldExpression): SourceNode { const chunks: SourceChunk[] = []; const value = this.printExpression(expression.value); if (expression.key) { if ( - tstl.isStringLiteral(expression.key) && - tsHelper.isValidLuaIdentifier(expression.key.value) && + lua.isStringLiteral(expression.key) && + isValidLuaIdentifier(expression.key.value) && !luaKeywords.has(expression.key.value) ) { chunks.push(expression.key.value, " = ", value); @@ -566,11 +643,11 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printTableExpression(expression: tstl.TableExpression): SourceNode { + public printTableExpression(expression: lua.TableExpression): SourceNode { return this.createSourceNode(expression, ["{", ...this.printExpressionList(expression.fields), "}"]); } - public printUnaryExpression(expression: tstl.UnaryExpression): SourceNode { + public printUnaryExpression(expression: lua.UnaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); @@ -579,7 +656,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printBinaryExpression(expression: tstl.BinaryExpression): SourceNode { + public printBinaryExpression(expression: lua.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.left)); @@ -589,20 +666,20 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - private canStripParenthesis(expression: tstl.Expression): boolean { + private canStripParenthesis(expression: lua.Expression): boolean { return ( - tstl.isParenthesizedExpression(expression) || - tstl.isTableIndexExpression(expression) || - tstl.isCallExpression(expression) || - tstl.isMethodCallExpression(expression) || - tstl.isIdentifier(expression) || - tstl.isNilLiteral(expression) || - tstl.isNumericLiteral(expression) || - tstl.isBooleanLiteral(expression) + lua.isParenthesizedExpression(expression) || + lua.isTableIndexExpression(expression) || + lua.isCallExpression(expression) || + lua.isMethodCallExpression(expression) || + lua.isIdentifier(expression) || + lua.isNilLiteral(expression) || + lua.isNumericLiteral(expression) || + lua.isBooleanLiteral(expression) ); } - public printParenthesizedExpression(expression: tstl.ParenthesizedExpression): SourceNode { + public printParenthesizedExpression(expression: lua.ParenthesizedExpression): SourceNode { const innerExpression = this.printExpression(expression.innerExpression); if (this.canStripParenthesis(expression.innerExpression)) { return this.createSourceNode(expression, innerExpression); @@ -610,7 +687,7 @@ export class LuaPrinter { return this.createSourceNode(expression, ["(", innerExpression, ")"]); } - public printCallExpression(expression: tstl.CallExpression): SourceNode { + public printCallExpression(expression: lua.CallExpression): SourceNode { const chunks = []; chunks.push(this.printExpression(expression.expression), "("); @@ -624,7 +701,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printMethodCallExpression(expression: tstl.MethodCallExpression): SourceNode { + public printMethodCallExpression(expression: lua.MethodCallExpression): SourceNode { const chunks = []; const prefix = this.printExpression(expression.prefixExpression); @@ -642,7 +719,7 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printIdentifier(expression: tstl.Identifier): SourceNode { + public printIdentifier(expression: lua.Identifier): SourceNode { return this.createSourceNode( expression, expression.text, @@ -650,13 +727,13 @@ export class LuaPrinter { ); } - public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { + public printTableIndexExpression(expression: lua.TableIndexExpression): SourceNode { const chunks: SourceChunk[] = []; chunks.push(this.printExpression(expression.table)); if ( - tstl.isStringLiteral(expression.index) && - tsHelper.isValidLuaIdentifier(expression.index.value) && + lua.isStringLiteral(expression.index) && + isValidLuaIdentifier(expression.index.value) && !luaKeywords.has(expression.index.value) ) { chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); @@ -666,26 +743,26 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } - public printOperator(kind: tstl.Operator): SourceNode { + public printOperator(kind: lua.Operator): SourceNode { // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } - protected removeDeadAndEmptyStatements(statements: tstl.Statement[]): tstl.Statement[] { + protected removeDeadAndEmptyStatements(statements: lua.Statement[]): lua.Statement[] { const aliveStatements = []; for (const statement of statements) { if (!this.isStatementEmpty(statement)) { aliveStatements.push(statement); } - if (tstl.isReturnStatement(statement)) { + if (lua.isReturnStatement(statement)) { break; } } return aliveStatements; } - protected isStatementEmpty(statement: tstl.Statement): boolean { - return tstl.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); + protected isStatementEmpty(statement: lua.Statement): boolean { + return lua.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); } protected joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { @@ -699,10 +776,10 @@ export class LuaPrinter { return result; } - protected printExpressionList(expressions: tstl.Expression[]): SourceChunk[] { + protected printExpressionList(expressions: lua.Expression[]): SourceChunk[] { const chunks: SourceChunk[] = []; - if (expressions.every(e => tsHelper.isSimpleExpression(e))) { + if (expressions.every(isSimpleExpression)) { chunks.push(...this.joinChunks(", ", expressions.map(e => this.printExpression(e)))); } else { chunks.push("\n"); @@ -720,9 +797,9 @@ export class LuaPrinter { // The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column // will not generate 'empty' mappings in the source map that point to nothing in the original TS. - private buildSourceMap(sourceFile: string, sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { + private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { const map = new SourceMapGenerator({ - file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua", + file: trimExtension(this.sourceFile) + ".lua", sourceRoot, }); diff --git a/src/LuaTransformer.ts b/src/LuaTransformer.ts deleted file mode 100644 index 8287ebb08..000000000 --- a/src/LuaTransformer.ts +++ /dev/null @@ -1,6240 +0,0 @@ -import * as path from "path"; -import * as ts from "typescript"; -import { CompilerOptions, LuaTarget } from "./CompilerOptions"; -import { DecoratorKind } from "./Decorator"; -import * as tstl from "./LuaAST"; -import { LuaLibFeature } from "./LuaLib"; -import * as tsHelper from "./TSHelper"; -import * as TSTLErrors from "./TSTLErrors"; -import { luaKeywords, luaBuiltins } from "./LuaKeywords"; - -export type StatementVisitResult = tstl.Statement | tstl.Statement[] | undefined; -export type ExpressionVisitResult = tstl.Expression; -export enum ScopeType { - File = 0x1, - Function = 0x2, - Switch = 0x4, - Loop = 0x8, - Conditional = 0x10, - Block = 0x20, - Try = 0x40, - Catch = 0x80, -} - -interface SymbolInfo { - symbol: ts.Symbol; - firstSeenAtPos: number; -} - -interface FunctionDefinitionInfo { - referencedSymbols: Map; - definition?: tstl.VariableDeclarationStatement | tstl.AssignmentStatement; -} - -interface Scope { - type: ScopeType; - id: number; - referencedSymbols?: Map; - variableDeclarations?: tstl.VariableDeclarationStatement[]; - functionDefinitions?: Map; - importStatements?: tstl.Statement[]; - loopContinued?: boolean; - functionReturned?: boolean; -} - -export interface EmitResolver { - isValueAliasDeclaration(node: ts.Node): boolean; - isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; - isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; - moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; -} - -export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { - getEmitResolver(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): EmitResolver; -} - -export class LuaTransformer { - protected readonly typeValidationCache = new Map>(); - protected currentNamespace?: ts.ModuleDeclaration; - - protected checker: DiagnosticsProducingTypeChecker; - protected options: CompilerOptions; - - protected luaTarget: LuaTarget; - protected isStrict: boolean; - - public constructor(protected program: ts.Program) { - this.checker = (program as any).getDiagnosticsProducingTypeChecker(); - this.options = program.getCompilerOptions(); - - this.luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; - this.isStrict = - this.options.alwaysStrict !== undefined || - (this.options.strict !== undefined && this.options.alwaysStrict !== false) || - (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); - - this.setupState(); - } - - protected genVarCounter!: number; - protected luaLibFeatureSet!: Set; - - protected visitedExportEquals!: boolean; - - protected scopeStack!: Scope[]; - protected classStack!: ts.ClassLikeDeclaration[]; - - protected symbolInfo!: Map; - protected symbolIds!: Map; - protected genSymbolIdCounter!: number; - - private setupState(): void { - this.genVarCounter = 0; - this.luaLibFeatureSet = new Set(); - - this.visitedExportEquals = false; - - this.scopeStack = []; - this.classStack = []; - - this.symbolInfo = new Map(); - this.symbolIds = new Map(); - this.genSymbolIdCounter = 1; - } - - protected currentSourceFile!: ts.SourceFile; - protected isModule!: boolean; - protected resolver!: EmitResolver; - - /** @internal */ - public transform(sourceFile: ts.SourceFile): [tstl.Block, Set] { - this.setupState(); - this.currentSourceFile = sourceFile; - this.isModule = tsHelper.isFileModule(sourceFile); - - // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. - // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` - // and would try to re-analyze the file, which would fail because of replaced nodes. - const originalSourceFile = ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; - this.resolver = this.checker.getEmitResolver(originalSourceFile); - - return [this.transformSourceFile(sourceFile), this.luaLibFeatureSet]; - } - - public transformSourceFile(sourceFile: ts.SourceFile): tstl.Block { - let statements: tstl.Statement[] = []; - if (sourceFile.flags & ts.NodeFlags.JsonFile) { - const statement = sourceFile.statements[0]; - if (!statement || !ts.isExpressionStatement(statement)) { - throw TSTLErrors.InvalidJsonFileContent(sourceFile); - } - - statements.push(tstl.createReturnStatement([this.transformExpression(statement.expression)])); - } else { - this.pushScope(ScopeType.File); - statements = this.performHoisting(this.transformStatements(sourceFile.statements)); - this.popScope(); - - if (this.isModule) { - // If export equals was not used. Create the exports table. - // local exports = {} - if (!this.visitedExportEquals) { - statements.unshift( - tstl.createVariableDeclarationStatement( - this.createExportsIdentifier(), - tstl.createTableExpression() - ) - ); - } - - // return exports - statements.push(tstl.createReturnStatement([this.createExportsIdentifier()])); - } - } - - return tstl.createBlock(statements, sourceFile); - } - - public transformStatement(node: ts.Statement): StatementVisitResult { - // Ignore declarations - if (node.modifiers && node.modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { - return undefined; - } - - switch (node.kind) { - // Block - case ts.SyntaxKind.Block: - return this.transformBlockAsDoStatement(node as ts.Block); - // Declaration Statements - case ts.SyntaxKind.ExportAssignment: - return this.transformExportAssignment(node as ts.ExportAssignment); - case ts.SyntaxKind.ExportDeclaration: - return this.transformExportDeclaration(node as ts.ExportDeclaration); - case ts.SyntaxKind.ImportDeclaration: - return this.transformImportDeclaration(node as ts.ImportDeclaration); - case ts.SyntaxKind.ImportEqualsDeclaration: - return this.transformImportEqualsDeclaration(node as ts.ImportEqualsDeclaration); - case ts.SyntaxKind.ClassDeclaration: - return this.transformClassDeclaration(node as ts.ClassDeclaration); - case ts.SyntaxKind.ModuleDeclaration: - return this.transformModuleDeclaration(node as ts.ModuleDeclaration); - case ts.SyntaxKind.EnumDeclaration: - return this.transformEnumDeclaration(node as ts.EnumDeclaration); - case ts.SyntaxKind.FunctionDeclaration: - return this.transformFunctionDeclaration(node as ts.FunctionDeclaration); - case ts.SyntaxKind.TypeAliasDeclaration: - return this.transformTypeAliasDeclaration(node as ts.TypeAliasDeclaration); - case ts.SyntaxKind.InterfaceDeclaration: - return this.transformInterfaceDeclaration(node as ts.InterfaceDeclaration); - // Statements - case ts.SyntaxKind.VariableStatement: - return this.transformVariableStatement(node as ts.VariableStatement); - case ts.SyntaxKind.ExpressionStatement: - return this.transformExpressionStatement(node as ts.ExpressionStatement); - case ts.SyntaxKind.ReturnStatement: - return this.transformReturnStatement(node as ts.ReturnStatement); - case ts.SyntaxKind.IfStatement: - return this.transformIfStatement(node as ts.IfStatement); - case ts.SyntaxKind.WhileStatement: - return this.transformWhileStatement(node as ts.WhileStatement); - case ts.SyntaxKind.DoStatement: - return this.transformDoStatement(node as ts.DoStatement); - case ts.SyntaxKind.ForStatement: - return this.transformForStatement(node as ts.ForStatement); - case ts.SyntaxKind.ForOfStatement: - return this.transformForOfStatement(node as ts.ForOfStatement); - case ts.SyntaxKind.ForInStatement: - return this.transformForInStatement(node as ts.ForInStatement); - case ts.SyntaxKind.SwitchStatement: - return this.transformSwitchStatement(node as ts.SwitchStatement); - case ts.SyntaxKind.BreakStatement: - return this.transformBreakStatement(node as ts.BreakStatement); - case ts.SyntaxKind.TryStatement: - return this.transformTryStatement(node as ts.TryStatement); - case ts.SyntaxKind.ThrowStatement: - return this.transformThrowStatement(node as ts.ThrowStatement); - case ts.SyntaxKind.ContinueStatement: - return this.transformContinueStatement(node as ts.ContinueStatement); - case ts.SyntaxKind.EmptyStatement: - return this.transformEmptyStatement(node as ts.EmptyStatement); - case ts.SyntaxKind.NotEmittedStatement: - return undefined; - default: - throw TSTLErrors.UnsupportedKind("Statement", node.kind, node); - } - } - - /** Converts an array of ts.Statements into an array of tstl.Statements */ - protected transformStatements(statements: readonly ts.Statement[]): tstl.Statement[] { - const tstlStatements: tstl.Statement[] = []; - (statements as ts.Statement[]).forEach(statement => { - tstlStatements.push(...this.statementVisitResultToArray(this.transformStatement(statement))); - }); - return tstlStatements; - } - - public transformBlock(block: ts.Block): tstl.Block { - this.pushScope(ScopeType.Block); - const statements = this.performHoisting(this.transformStatements(block.statements)); - this.popScope(); - return tstl.createBlock(statements, block); - } - - public transformBlockAsDoStatement(block: ts.Block): StatementVisitResult { - this.pushScope(ScopeType.Block); - const statements = this.performHoisting(this.transformStatements(block.statements)); - this.popScope(); - return tstl.createDoStatement(statements, block); - } - - public transformExportAssignment(statement: ts.ExportAssignment): StatementVisitResult { - if (!this.resolver.isValueAliasDeclaration(statement)) { - return undefined; - } - - // export = [expression]; - // ____exports = [expression]; - if (statement.isExportEquals) { - // Stop the creation of the exports table. - // This should be the only export of the module. - this.visitedExportEquals = true; - - return tstl.createVariableDeclarationStatement( - this.createExportsIdentifier(), - this.transformExpression(statement.expression), - statement - ); - } - - // export default [expression]; - // ____exports.default = [expression]; - const defaultIdentifier = this.createDefaultExportStringLiteral(statement); - return tstl.createAssignmentStatement( - tstl.createTableIndexExpression(this.createExportsIdentifier(), defaultIdentifier), - this.transformExpression(statement.expression), - statement - ); - } - - public transformExportDeclaration(statement: ts.ExportDeclaration): StatementVisitResult { - if (statement.exportClause) { - if (!this.resolver.isValueAliasDeclaration(statement)) { - return undefined; - } - - const exportSpecifiers = tsHelper.getExportable(statement.exportClause, this.resolver); - - // export { ... }; - if (statement.moduleSpecifier === undefined) { - return exportSpecifiers.map(exportSpecifier => this.transformExportSpecifier(exportSpecifier)); - } - - // export { ... } from "..."; - return this.transformExportSpecifiersFrom(statement, statement.moduleSpecifier, exportSpecifiers); - } else { - // export * from "..."; - return this.transformExportAllFrom(statement); - } - } - - protected transformExportSpecifier(node: ts.ExportSpecifier): tstl.AssignmentStatement { - const exportedSymbol = this.checker.getExportSpecifierLocalTargetSymbol(node); - const exportedIdentifier = node.propertyName ? node.propertyName : node.name; - const exportedExpression = this.createShorthandIdentifier(exportedSymbol, exportedIdentifier); - - const isDefault = tsHelper.isDefaultExportSpecifier(node); - const identifierToExport = isDefault - ? this.createDefaultExportIdentifier(node) - : this.transformIdentifier(node.name); - const exportAssignmentLeftHandSide = this.createExportedIdentifier(identifierToExport); - - return tstl.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); - } - - protected transformExportSpecifiersFrom( - statement: ts.ExportDeclaration, - moduleSpecifier: ts.Expression, - exportSpecifiers: ts.ExportSpecifier[] - ): tstl.Statement { - // First transpile as import clause - const importClause = ts.createImportClause( - undefined, - ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) - ); - - const importDeclaration = ts.createImportDeclaration( - statement.decorators, - statement.modifiers, - importClause, - moduleSpecifier - ); - - // Wrap in block to prevent imports from hoisting out of `do` statement - const block = ts.createBlock([importDeclaration]); - const result = this.transformBlock(block).statements; - - // Now the module is imported, add the imports to the export table - for (const specifier of exportSpecifiers) { - result.push( - tstl.createAssignmentStatement( - this.createExportedIdentifier(this.transformIdentifier(specifier.name)), - this.transformIdentifier(specifier.name) - ) - ); - } - - // Wrap this in a DoStatement to prevent polluting the scope. - return tstl.createDoStatement(this.filterUndefined(result), statement); - } - - protected transformExportAllFrom(statement: ts.ExportDeclaration): tstl.Statement | undefined { - if (statement.moduleSpecifier === undefined) { - throw TSTLErrors.InvalidExportDeclaration(statement); - } - - if (!this.resolver.moduleExportsSomeValue(statement.moduleSpecifier)) { - return undefined; - } - - const moduleRequire = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral); - const tempModuleIdentifier = tstl.createIdentifier("____export"); - - const declaration = tstl.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); - - const forKey = tstl.createIdentifier("____exportKey"); - const forValue = tstl.createIdentifier("____exportValue"); - - const body = tstl.createBlock([ - tstl.createAssignmentStatement( - tstl.createTableIndexExpression(this.createExportsIdentifier(), forKey), - forValue - ), - ]); - - const pairsIdentifier = tstl.createIdentifier("pairs"); - const forIn = tstl.createForInStatement( - body, - [tstl.cloneIdentifier(forKey), tstl.cloneIdentifier(forValue)], - [tstl.createCallExpression(pairsIdentifier, [tstl.cloneIdentifier(tempModuleIdentifier)])] - ); - - // Wrap this in a DoStatement to prevent polluting the scope. - return tstl.createDoStatement([declaration, forIn], statement); - } - - public transformImportDeclaration(statement: ts.ImportDeclaration): StatementVisitResult { - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - if (!this.options.noHoisting && !scope.importStatements) { - scope.importStatements = []; - } - - const shouldResolve = tsHelper.shouldResolveModulePath(statement.moduleSpecifier, this.checker); - const moduleSpecifier = statement.moduleSpecifier as ts.StringLiteral; - const importPath = moduleSpecifier.text.replace(new RegExp('"', "g"), ""); - const requireCall = this.createModuleRequire(statement.moduleSpecifier as ts.StringLiteral, shouldResolve); - - const result: tstl.Statement[] = []; - - // import "./module"; - // require("module") - if (statement.importClause === undefined) { - result.push(tstl.createExpressionStatement(requireCall)); - - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; - } - } - - // Create the require statement to extract values. - // local ____module = require("module") - const tstlIdentifier = (name: string) => "____" + tsHelper.fixInvalidLuaIdentifier(name); - const importUniqueName = tstl.createIdentifier(tstlIdentifier(path.basename(importPath))); - const requireStatement = tstl.createVariableDeclarationStatement( - tstl.createIdentifier(tstlIdentifier(path.basename(importPath))), - requireCall, - statement - ); - - let usingRequireStatement = false; - - // import defaultValue from "./module"; - // local defaultValue = __module.default - if (statement.importClause.name) { - if (tsHelper.shouldBeImported(statement.importClause, this.checker, this.resolver)) { - const propertyName = this.createDefaultExportStringLiteral(statement.importClause.name); - const defaultImportAssignmentStatement = tstl.createVariableDeclarationStatement( - this.transformIdentifier(statement.importClause.name), - tstl.createTableIndexExpression(importUniqueName, propertyName), - statement.importClause.name - ); - - result.push(defaultImportAssignmentStatement); - usingRequireStatement = true; - } - } - - // import * as module from "./module"; - // local module = require("module") - if (statement.importClause.namedBindings && ts.isNamespaceImport(statement.importClause.namedBindings)) { - if (this.resolver.isReferencedAliasDeclaration(statement.importClause.namedBindings)) { - const requireStatement = tstl.createVariableDeclarationStatement( - this.transformIdentifier(statement.importClause.namedBindings.name), - requireCall, - statement - ); - - result.push(requireStatement); - } - } - - // import { a, b, c } from "./module"; - // local a = __module.a - // local b = __module.b - // local c = __module.c - if (statement.importClause.namedBindings && ts.isNamedImports(statement.importClause.namedBindings)) { - const assignmentStatements = statement.importClause.namedBindings.elements - .filter(importSpecifier => tsHelper.shouldBeImported(importSpecifier, this.checker, this.resolver)) - .map(importSpecifier => this.transformImportSpecifier(importSpecifier, importUniqueName)); - - if (assignmentStatements.length > 0) { - usingRequireStatement = true; - } - result.push(...assignmentStatements); - } - - if (result.length === 0) { - return undefined; - } - - if (usingRequireStatement) { - result.unshift(requireStatement); - } - - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; - } - } - - protected transformImportSpecifier( - importSpecifier: ts.ImportSpecifier, - moduleTableName: tstl.Identifier - ): tstl.VariableDeclarationStatement { - const leftIdentifier = this.transformIdentifier(importSpecifier.name); - const propertyName = this.transformPropertyName( - importSpecifier.propertyName ? importSpecifier.propertyName : importSpecifier.name - ); - - return tstl.createVariableDeclarationStatement( - leftIdentifier, - tstl.createTableIndexExpression(moduleTableName, propertyName), - importSpecifier - ); - } - - protected createModuleRequire(moduleSpecifier: ts.StringLiteral, resolveModule = true): tstl.CallExpression { - const modulePathString = resolveModule - ? tsHelper.getImportPath( - this.currentSourceFile.fileName, - moduleSpecifier.text.replace(new RegExp('"', "g"), ""), - moduleSpecifier, - this.options - ) - : moduleSpecifier.text; - const modulePath = tstl.createStringLiteral(modulePathString); - return tstl.createCallExpression(tstl.createIdentifier("require"), [modulePath], moduleSpecifier); - } - - protected validateClassElement(element: ts.ClassElement): void { - if (element.name && (ts.isStringLiteral(element.name) || ts.isIdentifier(element.name))) { - if (tsHelper.isStaticNode(element) && element.name.text === "new") { - throw TSTLErrors.ForbiddenStaticClassPropertyName(element, element.name.text); - } - } - } - - public transformImportEqualsDeclaration(declaration: ts.ImportEqualsDeclaration): StatementVisitResult { - const name = this.transformIdentifier(declaration.name); - let expression: tstl.Expression; - if (ts.isExternalModuleReference(declaration.moduleReference)) { - if (!this.resolver.isReferencedAliasDeclaration(declaration)) { - return undefined; - } - - expression = this.transformExternalModuleReference(declaration.moduleReference); - } else { - const shouldEmit = - this.resolver.isReferencedAliasDeclaration(declaration) || - (!ts.isExternalModule(this.currentSourceFile) && - this.resolver.isTopLevelValueImportEqualsWithEntityName(declaration)); - - if (!shouldEmit) { - return undefined; - } - - expression = this.transformEntityName(declaration.moduleReference); - } - - return this.createHoistableVariableDeclarationStatement(name, expression, declaration); - } - - public transformExternalModuleReference( - externalModuleReference: ts.ExternalModuleReference - ): ExpressionVisitResult { - // TODO: Should `externalModuleReference` be original node? - return this.createModuleRequire(externalModuleReference.expression as ts.StringLiteral); - } - - protected transformEntityName(entityName: ts.EntityName): ExpressionVisitResult { - return ts.isQualifiedName(entityName) - ? this.transformQualifiedName(entityName) - : this.transformIdentifierExpression(entityName); - } - - public transformQualifiedName(qualifiedName: ts.QualifiedName): ExpressionVisitResult { - const right = tstl.createStringLiteral(qualifiedName.right.text, qualifiedName.right); - const left = this.transformEntityName(qualifiedName.left); - - return tstl.createTableIndexExpression(left, right, qualifiedName); - } - - public transformClassDeclaration( - statement: ts.ClassLikeDeclaration, - nameOverride?: tstl.Identifier - ): StatementVisitResult { - this.classStack.push(statement); - - let className: tstl.Identifier; - let classNameText: string; - if (nameOverride !== undefined) { - className = nameOverride; - classNameText = nameOverride.text; - } else if (statement.name !== undefined) { - className = this.transformIdentifier(statement.name); - classNameText = statement.name.text; - } else { - const isDefaultExport = tsHelper.hasDefaultExportModifier(statement.modifiers); - if (isDefaultExport) { - const left = this.createExportedIdentifier(this.createDefaultExportIdentifier(statement)); - const right = this.transformClassExpression(statement); - - return tstl.createAssignmentStatement(left, right, statement); - } else { - throw TSTLErrors.MissingClassName(statement); - } - } - - const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); - - // Find out if this class is extension of existing class - const extensionDirective = decorators.get(DecoratorKind.Extension); - const isExtension = extensionDirective !== undefined; - - const isMetaExtension = decorators.has(DecoratorKind.MetaExtension); - - if (isExtension && isMetaExtension) { - throw TSTLErrors.InvalidExtensionMetaExtension(statement); - } - - if ((isExtension || isMetaExtension) && this.getIdentifierExportScope(className) !== undefined) { - // Cannot export extension classes - throw TSTLErrors.InvalidExportsExtension(statement); - } - - // Get type that is extended - const extendsType = tsHelper.getExtendedType(statement, this.checker); - - if (extendsType) { - this.checkForLuaLibType(extendsType); - } - - if (!(isExtension || isMetaExtension) && extendsType) { - // Non-extensions cannot extend extension classes - const extendsDecorators = tsHelper.getCustomDecorators(extendsType, this.checker); - if (extendsDecorators.has(DecoratorKind.Extension) || extendsDecorators.has(DecoratorKind.MetaExtension)) { - throw TSTLErrors.InvalidExtendsExtension(statement); - } - } - - // You cannot extend LuaTable classes - if (extendsType) { - const decorators = tsHelper.getCustomDecorators(extendsType, this.checker); - if (decorators.has(DecoratorKind.LuaTable)) { - throw TSTLErrors.InvalidExtendsLuaTable(statement); - } - } - - // LuaTable classes must be ambient - if (decorators.has(DecoratorKind.LuaTable) && !tsHelper.isAmbientNode(statement)) { - throw TSTLErrors.ForbiddenLuaTableNonDeclaration(statement); - } - - // Get all properties with value - const properties = statement.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); - - // Divide properties into static and non-static - const staticFields = properties.filter(tsHelper.isStaticNode); - const instanceFields = properties.filter(prop => !tsHelper.isStaticNode(prop)); - - const result: tstl.Statement[] = []; - - // Overwrite the original className with the class we are overriding for extensions - if (isMetaExtension) { - if (!extendsType) { - throw TSTLErrors.MissingMetaExtension(statement); - } - - const extendsName = tstl.createStringLiteral(extendsType.symbol.escapedName as string); - className = tstl.createIdentifier("__meta__" + extendsName.value); - - // local className = debug.getregistry()["extendsName"] - const assignDebugCallIndex = tstl.createVariableDeclarationStatement( - className, - tstl.createTableIndexExpression( - tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("debug"), - tstl.createStringLiteral("getregistry") - ), - [] - ), - extendsName - ), - statement - ); - - result.push(assignDebugCallIndex); - } - - if (extensionDirective !== undefined) { - const extensionNameArg = extensionDirective.args[0]; - if (extensionNameArg) { - className = tstl.createIdentifier(extensionNameArg); - } else if (extendsType) { - className = tstl.createIdentifier(extendsType.symbol.escapedName as string); - } - } - - let localClassName: tstl.Identifier; - if (this.isUnsafeName(className.text)) { - localClassName = tstl.createIdentifier( - this.createSafeName(className.text), - undefined, - className.symbolId, - className.text - ); - tstl.setNodePosition(localClassName, className); - } else { - localClassName = className; - } - - if (!isExtension && !isMetaExtension) { - const classCreationMethods = this.createClassCreationMethods( - statement, - className, - localClassName, - classNameText, - extendsType - ); - result.push(...classCreationMethods); - } else { - for (const f of instanceFields) { - const fieldName = this.transformPropertyName(f.name); - - const value = f.initializer !== undefined ? this.transformExpression(f.initializer) : undefined; - - // className["fieldName"] - const classField = tstl.createTableIndexExpression(tstl.cloneIdentifier(className), fieldName); - - // className["fieldName"] = value; - const assignClassField = tstl.createAssignmentStatement(classField, value); - - result.push(assignClassField); - } - } - - // Find first constructor with body - if (!isExtension && !isMetaExtension) { - const constructor = statement.members.filter( - n => ts.isConstructorDeclaration(n) && n.body - )[0] as ts.ConstructorDeclaration; - if (constructor) { - // Add constructor plus initialization of instance fields - const constructorResult = this.transformConstructorDeclaration( - constructor, - localClassName, - instanceFields, - statement - ); - result.push(...this.statementVisitResultToArray(constructorResult)); - } else if (!extendsType) { - // Generate a constructor if none was defined in a base class - const constructorResult = this.transformConstructorDeclaration( - ts.createConstructor([], [], [], ts.createBlock([], true)), - localClassName, - instanceFields, - statement - ); - result.push(...this.statementVisitResultToArray(constructorResult)); - } else if ( - instanceFields.length > 0 || - statement.members.some(m => tsHelper.isGetAccessorOverride(m, statement, this.checker)) - ) { - // Generate a constructor if none was defined in a class with instance fields that need initialization - // localClassName.prototype.____constructor = function(self, ...) - // baseClassName.prototype.____constructor(self, ...) - // ... - const constructorBody = this.transformClassInstanceFields(statement, instanceFields); - const superCall = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createTableIndexExpression( - this.transformSuperKeyword(ts.createSuper()), - tstl.createStringLiteral("____constructor") - ), - [this.createSelfIdentifier(), tstl.createDotsLiteral()] - ) - ); - constructorBody.unshift(superCall); - const constructorFunction = tstl.createFunctionExpression( - tstl.createBlock(constructorBody), - [this.createSelfIdentifier()], - tstl.createDotsLiteral(), - undefined, - tstl.FunctionExpressionFlags.Declaration - ); - result.push( - tstl.createAssignmentStatement( - this.createConstructorName(localClassName), - constructorFunction, - statement - ) - ); - } - } - - // Transform get accessors - statement.members.filter(ts.isGetAccessor).forEach(getAccessor => { - const transformResult = this.transformGetAccessorDeclaration(getAccessor, localClassName); - result.push(...this.statementVisitResultToArray(transformResult)); - }); - - // Transform set accessors - statement.members.filter(ts.isSetAccessor).forEach(setAccessor => { - const transformResult = this.transformSetAccessorDeclaration(setAccessor, localClassName); - result.push(...this.statementVisitResultToArray(transformResult)); - }); - - // Transform methods - statement.members.filter(ts.isMethodDeclaration).forEach(method => { - const methodResult = this.transformMethodDeclaration( - method, - localClassName, - isExtension || isMetaExtension - ); - result.push(...this.statementVisitResultToArray(methodResult)); - }); - - // Add static declarations - for (const field of staticFields) { - this.validateClassElement(field); - - const fieldName = this.transformPropertyName(field.name); - const value = field.initializer ? this.transformExpression(field.initializer) : undefined; - - const classField = tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), fieldName); - - const fieldAssign = tstl.createAssignmentStatement(classField, value); - - result.push(fieldAssign); - } - - const decorationStatement = this.createConstructorDecorationStatement(statement); - if (decorationStatement) { - result.push(decorationStatement); - } - - this.classStack.pop(); - - return result; - } - - protected createClassCreationMethods( - statement: ts.ClassLikeDeclarationBase, - className: tstl.Identifier, - localClassName: tstl.Identifier, - classNameText: string, - extendsType?: ts.Type - ): tstl.Statement[] { - const result: tstl.Statement[] = []; - - // [____exports.]className = {} - const classTable: tstl.Expression = tstl.createTableExpression(); - - const isDefaultExport = tsHelper.hasDefaultExportModifier(statement.modifiers); - - const defaultExportLeftHandSide = isDefaultExport - ? tstl.createTableIndexExpression( - this.createExportsIdentifier(), - this.createDefaultExportStringLiteral(statement) - ) - : undefined; - - const classVar = defaultExportLeftHandSide - ? [tstl.createAssignmentStatement(defaultExportLeftHandSide, classTable, statement)] - : this.createLocalOrExportedOrGlobalDeclaration(className, classTable, statement); - - result.push(...classVar); - - if (defaultExportLeftHandSide) { - // local localClassName = ____exports.default - result.push(tstl.createVariableDeclarationStatement(localClassName, defaultExportLeftHandSide)); - } else { - const exportScope = this.getIdentifierExportScope(className); - if (exportScope) { - // local localClassName = ____exports.className - result.push( - tstl.createVariableDeclarationStatement( - localClassName, - this.createExportedIdentifier(tstl.cloneIdentifier(className), exportScope) - ) - ); - } - } - - // localClassName.name = className - result.push( - tstl.createAssignmentStatement( - tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("name")), - tstl.createStringLiteral(classNameText), - statement - ) - ); - - // localClassName.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && tsHelper.isStaticNode(m))) { - const classGetters = tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("____getters") - ); - const assignClassGetters = tstl.createAssignmentStatement( - classGetters, - tstl.createTableExpression(), - statement - ); - result.push(assignClassGetters); - - this.importLuaLibFeature(LuaLibFeature.ClassIndex); - } - - // localClassName.__index = localClassName - const classIndex = tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("__index") - ); - const assignClassIndex = tstl.createAssignmentStatement( - classIndex, - tstl.cloneIdentifier(localClassName), - statement - ); - result.push(assignClassIndex); - - // localClassName.____setters = {} - if (statement.members.some(m => ts.isSetAccessor(m) && tsHelper.isStaticNode(m))) { - const classSetters = tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("____setters") - ); - const assignClassSetters = tstl.createAssignmentStatement( - classSetters, - tstl.createTableExpression(), - statement - ); - result.push(assignClassSetters); - - this.importLuaLibFeature(LuaLibFeature.ClassNewIndex); - } - - // localClassName.prototype = {} - const createClassPrototype = () => - tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("prototype") - ); - const classPrototypeTable = tstl.createTableExpression(); - const assignClassPrototype = tstl.createAssignmentStatement( - createClassPrototype(), - classPrototypeTable, - statement - ); - result.push(assignClassPrototype); - - // localClassName.prototype.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && !tsHelper.isStaticNode(m))) { - const classPrototypeGetters = tstl.createTableIndexExpression( - createClassPrototype(), - tstl.createStringLiteral("____getters") - ); - const assignClassPrototypeGetters = tstl.createAssignmentStatement( - classPrototypeGetters, - tstl.createTableExpression(), - statement - ); - result.push(assignClassPrototypeGetters); - } - - const classPrototypeIndex = tstl.createTableIndexExpression( - createClassPrototype(), - tstl.createStringLiteral("__index") - ); - if (tsHelper.hasGetAccessorInClassOrAncestor(statement, false, this.checker)) { - // localClassName.prototype.__index = __TS__Index(localClassName.prototype) - const assignClassPrototypeIndex = tstl.createAssignmentStatement( - classPrototypeIndex, - this.transformLuaLibFunction(LuaLibFeature.Index, undefined, createClassPrototype()), - statement - ); - result.push(assignClassPrototypeIndex); - } else { - // localClassName.prototype.__index = localClassName.prototype - const assignClassPrototypeIndex = tstl.createAssignmentStatement( - classPrototypeIndex, - createClassPrototype(), - statement - ); - result.push(assignClassPrototypeIndex); - } - - if (statement.members.some(m => ts.isSetAccessor(m) && !tsHelper.isStaticNode(m))) { - // localClassName.prototype.____setters = {} - const classPrototypeSetters = tstl.createTableIndexExpression( - createClassPrototype(), - tstl.createStringLiteral("____setters") - ); - const assignClassPrototypeSetters = tstl.createAssignmentStatement( - classPrototypeSetters, - tstl.createTableExpression(), - statement - ); - result.push(assignClassPrototypeSetters); - } - - if (tsHelper.hasSetAccessorInClassOrAncestor(statement, false, this.checker)) { - // localClassName.prototype.__newindex = __TS__NewIndex(localClassName.prototype) - const classPrototypeNewIndex = tstl.createTableIndexExpression( - createClassPrototype(), - tstl.createStringLiteral("__newindex") - ); - const assignClassPrototypeIndex = tstl.createAssignmentStatement( - classPrototypeNewIndex, - this.transformLuaLibFunction(LuaLibFeature.NewIndex, undefined, createClassPrototype()), - statement - ); - result.push(assignClassPrototypeIndex); - } - - // localClassName.prototype.constructor = localClassName - const classPrototypeConstructor = tstl.createTableIndexExpression( - createClassPrototype(), - tstl.createStringLiteral("constructor") - ); - const assignClassPrototypeConstructor = tstl.createAssignmentStatement( - classPrototypeConstructor, - tstl.cloneIdentifier(localClassName), - statement - ); - result.push(assignClassPrototypeConstructor); - - const hasStaticGetters = tsHelper.hasGetAccessorInClassOrAncestor(statement, true, this.checker); - const hasStaticSetters = tsHelper.hasSetAccessorInClassOrAncestor(statement, true, this.checker); - - if (extendsType) { - const extendedTypeNode = tsHelper.getExtendedTypeNode(statement, this.checker); - if (extendedTypeNode === undefined) { - throw TSTLErrors.UndefinedTypeNode(statement); - } - - // localClassName.____super = extendsExpression - const createClassBase = () => - tstl.createTableIndexExpression( - tstl.cloneIdentifier(localClassName), - tstl.createStringLiteral("____super") - ); - const assignClassBase = tstl.createAssignmentStatement( - createClassBase(), - this.transformExpression(extendedTypeNode.expression), - extendedTypeNode.expression - ); - result.push(assignClassBase); - - if (hasStaticGetters || hasStaticSetters) { - const metatableFields: tstl.TableFieldExpression[] = []; - if (hasStaticGetters) { - // __index = __TS__ClassIndex - metatableFields.push( - tstl.createTableFieldExpression( - tstl.createIdentifier("__TS__ClassIndex"), - tstl.createStringLiteral("__index"), - extendedTypeNode.expression - ) - ); - } else { - // __index = localClassName.____super - metatableFields.push( - tstl.createTableFieldExpression( - createClassBase(), - tstl.createStringLiteral("__index"), - extendedTypeNode.expression - ) - ); - } - - if (hasStaticSetters) { - // __newindex = __TS__ClassNewIndex - metatableFields.push( - tstl.createTableFieldExpression( - tstl.createIdentifier("__TS__ClassNewIndex"), - tstl.createStringLiteral("__newindex"), - extendedTypeNode.expression - ) - ); - } - - const setClassMetatable = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(localClassName), tstl.createTableExpression(metatableFields)], - extendedTypeNode.expression - ) - ); - result.push(setClassMetatable); - } else { - // setmetatable(localClassName, localClassName.____super) - const setClassMetatable = tstl.createExpressionStatement( - tstl.createCallExpression( - tstl.createIdentifier("setmetatable"), - [tstl.cloneIdentifier(localClassName), createClassBase()], - extendedTypeNode.expression - ) - ); - result.push(setClassMetatable); - } - - // setmetatable(localClassName.prototype, localClassName.____super.prototype) - const basePrototype = tstl.createTableIndexExpression( - createClassBase(), - tstl.createStringLiteral("prototype") - ); - const setClassPrototypeMetatable = tstl.createExpressionStatement( - tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ - createClassPrototype(), - basePrototype, - ]), - extendedTypeNode.expression - ); - result.push(setClassPrototypeMetatable); - } else if (hasStaticGetters || hasStaticSetters) { - const metatableFields: tstl.TableFieldExpression[] = []; - if (hasStaticGetters) { - // __index = __TS__ClassIndex - metatableFields.push( - tstl.createTableFieldExpression( - tstl.createIdentifier("__TS__ClassIndex"), - tstl.createStringLiteral("__index"), - statement - ) - ); - } - - if (hasStaticSetters) { - // __newindex = __TS__ClassNewIndex - metatableFields.push( - tstl.createTableFieldExpression( - tstl.createIdentifier("__TS__ClassNewIndex"), - tstl.createStringLiteral("__newindex"), - statement - ) - ); - } - - const setClassMetatable = tstl.createExpressionStatement( - tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ - tstl.cloneIdentifier(localClassName), - tstl.createTableExpression(metatableFields), - ]), - statement - ); - result.push(setClassMetatable); - } - - const newFuncStatements: tstl.Statement[] = []; - - // local self = setmetatable({}, localClassName.prototype) - const assignSelf = tstl.createVariableDeclarationStatement( - this.createSelfIdentifier(), - tstl.createCallExpression(tstl.createIdentifier("setmetatable"), [ - tstl.createTableExpression(), - createClassPrototype(), - ]), - statement - ); - newFuncStatements.push(assignSelf); - - // self:____constructor(...) - const callConstructor = tstl.createExpressionStatement( - tstl.createMethodCallExpression(this.createSelfIdentifier(), tstl.createIdentifier("____constructor"), [ - tstl.createDotsLiteral(), - ]), - statement - ); - newFuncStatements.push(callConstructor); - - // return self - const returnSelf = tstl.createReturnStatement([this.createSelfIdentifier()], statement); - newFuncStatements.push(returnSelf); - - // function localClassName.new(construct, ...) ... end - // or function export.localClassName.new(construct, ...) ... end - const newFunc = tstl.createAssignmentStatement( - tstl.createTableIndexExpression(tstl.cloneIdentifier(localClassName), tstl.createStringLiteral("new")), - tstl.createFunctionExpression( - tstl.createBlock(newFuncStatements), - undefined, - tstl.createDotsLiteral(), - undefined, - tstl.FunctionExpressionFlags.Declaration - ), - statement - ); - result.push(newFunc); - - return result; - } - - protected transformClassInstanceFields( - classDeclaration: ts.ClassLikeDeclaration, - instanceFields: ts.PropertyDeclaration[] - ): tstl.Statement[] { - const statements: tstl.Statement[] = []; - - for (const f of instanceFields) { - this.validateClassElement(f); - - // Get identifier - const fieldName = this.transformPropertyName(f.name); - - const value = f.initializer ? this.transformExpression(f.initializer) : undefined; - - // self[fieldName] - const selfIndex = tstl.createTableIndexExpression(this.createSelfIdentifier(), fieldName); - - // self[fieldName] = value - const assignClassField = tstl.createAssignmentStatement(selfIndex, value, f); - - statements.push(assignClassField); - } - - const getOverrides = classDeclaration.members.filter(m => - tsHelper.isGetAccessorOverride(m, classDeclaration, this.checker) - ) as ts.GetAccessorDeclaration[]; - - for (const getter of getOverrides) { - const getterName = this.transformPropertyName(getter.name); - - const resetGetter = tstl.createExpressionStatement( - tstl.createCallExpression(tstl.createIdentifier("rawset"), [ - this.createSelfIdentifier(), - getterName, - tstl.createNilLiteral(), - ]), - classDeclaration.members.find(ts.isConstructorDeclaration) || classDeclaration - ); - statements.push(resetGetter); - } - - return statements; - } - - protected createConstructorName(className: tstl.Identifier): tstl.TableIndexExpression { - return tstl.createTableIndexExpression( - tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")), - tstl.createStringLiteral("____constructor") - ); - } - - protected transformConstructorDeclaration( - statement: ts.ConstructorDeclaration, - className: tstl.Identifier, - instanceFields: ts.PropertyDeclaration[], - classDeclaration: ts.ClassLikeDeclaration - ): StatementVisitResult { - // Don't transform methods without body (overload declarations) - if (!statement.body) { - return undefined; - } - - // Transform body - const [body, scope] = this.transformFunctionBodyStatements(statement.body); - - const [params, dotsLiteral, restParamName] = this.transformParameters( - statement.parameters, - this.createSelfIdentifier() - ); - - // Make sure default parameters are assigned before fields are initialized - const bodyWithFieldInitializers = this.transformFunctionBodyHeader(scope, statement.parameters, restParamName); - - // Check for field declarations in constructor - const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - - const classInstanceFields = this.transformClassInstanceFields(classDeclaration, instanceFields); - - // If there are field initializers and the first statement is a super call, - // move super call between default assignments and initializers - if ( - (constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) && - statement.body && - statement.body.statements.length > 0 - ) { - const firstStatement = statement.body.statements[0]; - if ( - ts.isExpressionStatement(firstStatement) && - ts.isCallExpression(firstStatement.expression) && - firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword - ) { - const superCall = body.shift(); - if (superCall) { - bodyWithFieldInitializers.push(superCall); - } - } - } - - // Add in instance field declarations - for (const declaration of constructorFieldsDeclarations) { - const declarationName = this.transformIdentifier(declaration.name as ts.Identifier); - // self.declarationName = declarationName - const assignment = tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createSelfIdentifier(), - tstl.createStringLiteral(declarationName.text) - ), - declarationName - ); - bodyWithFieldInitializers.push(assignment); - } - - bodyWithFieldInitializers.push(...classInstanceFields); - - bodyWithFieldInitializers.push(...body); - - const block: tstl.Block = tstl.createBlock(bodyWithFieldInitializers); - - const constructorWasGenerated = statement.pos === -1; - - const result = tstl.createAssignmentStatement( - this.createConstructorName(className), - tstl.createFunctionExpression( - block, - params, - dotsLiteral, - restParamName, - tstl.FunctionExpressionFlags.Declaration - ), - constructorWasGenerated ? classDeclaration : statement - ); - - return result; - } - - public transformGetAccessorDeclaration( - getAccessor: ts.GetAccessorDeclaration, - className: tstl.Identifier - ): StatementVisitResult { - if (getAccessor.body === undefined) { - return undefined; - } - - this.validateClassElement(getAccessor); - - const name = this.transformIdentifier(getAccessor.name as ts.Identifier); - - const [body] = this.transformFunctionBody(getAccessor.parameters, getAccessor.body); - const accessorFunction = tstl.createFunctionExpression( - tstl.createBlock(body), - [this.createSelfIdentifier()], - undefined, - undefined, - tstl.FunctionExpressionFlags.Declaration - ); - - const methodTable = tsHelper.isStaticNode(getAccessor) - ? tstl.cloneIdentifier(className) - : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); - - const classGetters = tstl.createTableIndexExpression(methodTable, tstl.createStringLiteral("____getters")); - const getter = tstl.createTableIndexExpression(classGetters, tstl.createStringLiteral(name.text)); - const assignGetter = tstl.createAssignmentStatement(getter, accessorFunction, getAccessor); - return assignGetter; - } - - public transformSetAccessorDeclaration( - setAccessor: ts.SetAccessorDeclaration, - className: tstl.Identifier - ): StatementVisitResult { - if (setAccessor.body === undefined) { - return undefined; - } - - this.validateClassElement(setAccessor); - - const name = this.transformIdentifier(setAccessor.name as ts.Identifier); - - const [params, dot, restParam] = this.transformParameters(setAccessor.parameters, this.createSelfIdentifier()); - - const [body] = this.transformFunctionBody(setAccessor.parameters, setAccessor.body, restParam); - const accessorFunction = tstl.createFunctionExpression( - tstl.createBlock(body), - params, - dot, - restParam, - tstl.FunctionExpressionFlags.Declaration - ); - - const methodTable = tsHelper.isStaticNode(setAccessor) - ? tstl.cloneIdentifier(className) - : tstl.createTableIndexExpression(tstl.cloneIdentifier(className), tstl.createStringLiteral("prototype")); - - const classSetters = tstl.createTableIndexExpression(methodTable, tstl.createStringLiteral("____setters")); - const setter = tstl.createTableIndexExpression(classSetters, tstl.createStringLiteral(name.text)); - const assignSetter = tstl.createAssignmentStatement(setter, accessorFunction, setAccessor); - return assignSetter; - } - - public transformMethodDeclaration( - node: ts.MethodDeclaration, - className: tstl.Identifier, - noPrototype: boolean - ): StatementVisitResult { - // Don't transform methods without body (overload declarations) - if (!node.body) { - return undefined; - } - - this.validateClassElement(node); - - let methodName = this.transformPropertyName(node.name); - if (tstl.isStringLiteral(methodName) && methodName.value === "toString") { - methodName = tstl.createStringLiteral("__tostring", node.name); - } - - const type = this.checker.getTypeAtLocation(node); - const context = - tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void - ? this.createSelfIdentifier() - : undefined; - const [paramNames, dots, restParamName] = this.transformParameters(node.parameters, context); - - const [body] = this.transformFunctionBody(node.parameters, node.body, restParamName); - const functionExpression = tstl.createFunctionExpression( - tstl.createBlock(body), - paramNames, - dots, - restParamName, - tstl.FunctionExpressionFlags.Declaration, - node.body - ); - - const methodTable = - tsHelper.isStaticNode(node) || noPrototype - ? tstl.cloneIdentifier(className) - : tstl.createTableIndexExpression( - tstl.cloneIdentifier(className), - tstl.createStringLiteral("prototype") - ); - - return tstl.createAssignmentStatement( - tstl.createTableIndexExpression(methodTable, methodName), - functionExpression, - node - ); - } - - protected transformParameters( - parameters: ts.NodeArray, - context?: tstl.Identifier - ): [tstl.Identifier[], tstl.DotsLiteral | undefined, tstl.Identifier | undefined] { - // Build parameter string - const paramNames: tstl.Identifier[] = []; - if (context) { - paramNames.push(context); - } - - let restParamName: tstl.Identifier | undefined; - let dotsLiteral: tstl.DotsLiteral | undefined; - let identifierIndex = 0; - - // Only push parameter name to paramName array if it isn't a spread parameter - for (const param of parameters) { - if (ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { - continue; - } - - // Binding patterns become ____bindingPattern0, ____bindingPattern1, etc as function parameters - // See transformFunctionBody for how these values are destructured - const paramName = - ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) - ? tstl.createIdentifier(`____bindingPattern${identifierIndex++}`) - : this.transformIdentifier(param.name as ts.Identifier); - - // This parameter is a spread parameter (...param) - if (!param.dotDotDotToken) { - paramNames.push(paramName); - } else { - restParamName = paramName; - // Push the spread operator into the paramNames array - dotsLiteral = tstl.createDotsLiteral(); - } - } - - return [paramNames, dotsLiteral, restParamName]; - } - - protected isRestParameterReferenced(identifier: tstl.Identifier, scope: Scope): boolean { - if (!identifier.symbolId) { - return true; - } - if (scope.referencedSymbols === undefined) { - return false; - } - const references = scope.referencedSymbols.get(identifier.symbolId); - if (!references) { - return false; - } - // Ignore references to @vararg types in spread elements - return references.some( - r => !r.parent || !ts.isSpreadElement(r.parent) || !tsHelper.isVarArgType(r, this.checker) - ); - } - - protected transformFunctionBodyStatements(body: ts.Block): [tstl.Statement[], Scope] { - this.pushScope(ScopeType.Function); - const bodyStatements = this.performHoisting(this.transformStatements(body.statements)); - const scope = this.popScope(); - return [bodyStatements, scope]; - } - - protected transformFunctionBodyHeader( - bodyScope: Scope, - parameters: ts.NodeArray, - spreadIdentifier?: tstl.Identifier - ): tstl.Statement[] { - const headerStatements: tstl.Statement[] = []; - - // Add default parameters and object binding patterns - const bindingPatternDeclarations: tstl.Statement[] = []; - let bindPatternIndex = 0; - for (const declaration of parameters) { - if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) { - const identifier = tstl.createIdentifier(`____bindingPattern${bindPatternIndex++}`); - if (declaration.initializer !== undefined) { - // Default binding parameter - headerStatements.push( - this.transformParameterDefaultValueDeclaration(identifier, declaration.initializer) - ); - } - - // Binding pattern - bindingPatternDeclarations.push( - ...this.statementVisitResultToArray(this.transformBindingPattern(declaration.name, identifier)) - ); - } else if (declaration.initializer !== undefined) { - // Default parameter - headerStatements.push( - this.transformParameterDefaultValueDeclaration( - this.transformIdentifier(declaration.name), - declaration.initializer - ) - ); - } - } - - // Push spread operator here - if (spreadIdentifier && this.isRestParameterReferenced(spreadIdentifier, bodyScope)) { - const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); - headerStatements.push(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); - } - - // Binding pattern statements need to be after spread table is declared - headerStatements.push(...bindingPatternDeclarations); - - return headerStatements; - } - - protected transformFunctionBody( - parameters: ts.NodeArray, - body: ts.Block, - spreadIdentifier?: tstl.Identifier - ): [tstl.Statement[], Scope] { - const [bodyStatements, scope] = this.transformFunctionBodyStatements(body); - const headerStatements = this.transformFunctionBodyHeader(scope, parameters, spreadIdentifier); - return [headerStatements.concat(bodyStatements), scope]; - } - - protected transformParameterDefaultValueDeclaration( - parameterName: tstl.Identifier, - value?: ts.Expression, - tsOriginal?: ts.Node - ): tstl.Statement { - const parameterValue = value ? this.transformExpression(value) : undefined; - const assignment = tstl.createAssignmentStatement(parameterName, parameterValue); - - const nilCondition = tstl.createBinaryExpression( - parameterName, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ); - - const ifBlock = tstl.createBlock([assignment]); - - return tstl.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); - } - - public transformBindingPattern( - pattern: ts.BindingPattern, - table: tstl.Identifier, - propertyAccessStack: ts.PropertyName[] = [] - ): StatementVisitResult { - const result: tstl.Statement[] = []; - const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); - for (let index = 0; index < pattern.elements.length; index++) { - const element = pattern.elements[index]; - if (ts.isOmittedExpression(element)) continue; - - if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { - // nested binding pattern - const propertyName = isObjectBindingPattern - ? element.propertyName - : ts.createNumericLiteral(String(index + 1)); - if (propertyName !== undefined) { - propertyAccessStack.push(propertyName); - } - result.push( - ...this.statementVisitResultToArray( - this.transformBindingPattern(element.name, table, propertyAccessStack) - ) - ); - continue; - } - - // Build the path to the table - let tableExpression: tstl.Expression = table; - propertyAccessStack.forEach(property => { - const propertyName = ts.isPropertyName(property) - ? this.transformPropertyName(property) - : this.transformNumericLiteral(property); - tableExpression = tstl.createTableIndexExpression(tableExpression, propertyName); - }); - - // The identifier of the new variable - const variableName = this.transformIdentifier(element.name as ts.Identifier); - // The field to extract - const propertyName = this.transformPropertyName(element.propertyName || element.name); - - let expression: tstl.Expression; - if (element.dotDotDotToken) { - if (index !== pattern.elements.length - 1) continue; - - if (isObjectBindingPattern) { - const elements = pattern.elements as ts.NodeArray; - const usedProperties = elements.map(e => - tstl.createTableFieldExpression( - tstl.createBooleanLiteral(true), - tstl.createStringLiteral( - ((e.propertyName || e.name) as ts.Identifier).text, - e.propertyName || e.name - ) - ) - ); - - expression = this.transformLuaLibFunction( - LuaLibFeature.ObjectRest, - undefined, - tableExpression, - tstl.createTableExpression(usedProperties) - ); - } else { - expression = this.transformLuaLibFunction( - LuaLibFeature.ArraySlice, - undefined, - tableExpression, - tstl.createNumericLiteral(index) - ); - } - } else { - expression = tstl.createTableIndexExpression( - tableExpression, - isObjectBindingPattern ? propertyName : tstl.createNumericLiteral(index + 1) - ); - } - - result.push(...this.createLocalOrExportedOrGlobalDeclaration(variableName, expression)); - if (element.initializer) { - const identifier = this.addExportToIdentifier(variableName); - result.push( - tstl.createIfStatement( - tstl.createBinaryExpression( - identifier, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ), - tstl.createBlock([ - tstl.createAssignmentStatement(identifier, this.transformExpression(element.initializer)), - ]) - ) - ); - } - } - propertyAccessStack.pop(); - return result; - } - - protected createModuleLocalNameIdentifier(declaration: ts.ModuleDeclaration): tstl.Identifier { - const moduleSymbol = this.checker.getSymbolAtLocation(declaration.name); - if (moduleSymbol !== undefined && this.isUnsafeName(moduleSymbol.name)) { - return tstl.createIdentifier( - this.createSafeName(declaration.name.text), - declaration.name, - moduleSymbol && this.symbolIds.get(moduleSymbol), - declaration.name.text - ); - } - return this.transformIdentifier(declaration.name as ts.Identifier); - } - - public transformModuleDeclaration(statement: ts.ModuleDeclaration): StatementVisitResult { - const decorators = tsHelper.getCustomDecorators(this.checker.getTypeAtLocation(statement), this.checker); - // If phantom namespace elide the declaration and return the body - if (decorators.has(DecoratorKind.Phantom) && statement.body && ts.isModuleBlock(statement.body)) { - return this.transformStatements(statement.body.statements); - } - - const result: tstl.Statement[] = []; - - const symbol = this.checker.getSymbolAtLocation(statement.name); - const hasExports = symbol !== undefined && this.checker.getExportsOfModule(symbol).length > 0; - const nameIdentifier = this.transformIdentifier(statement.name as ts.Identifier); - const exportScope = this.getIdentifierExportScope(nameIdentifier); - - // Non-module namespace could be merged if: - // - is top level - // - is nested and exported - const isNonModuleMergeable = !this.isModule && (!this.currentNamespace || exportScope); - - // This is NOT the first declaration if: - // - declared as a module before this (ignore interfaces with same name) - // - declared as a class or function at all (TS requires these to be before module, unless module is empty) - const isFirstDeclaration = - symbol === undefined || - (symbol.declarations.findIndex(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) === -1 && - statement === symbol.declarations.find(ts.isModuleDeclaration)); - - if (isNonModuleMergeable) { - // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' - const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( - nameIdentifier, - tstl.createBinaryExpression( - this.addExportToIdentifier(nameIdentifier), - tstl.createTableExpression(), - tstl.SyntaxKind.OrOperator - ) - ); - - result.push(...localDeclaration); - } else if (isFirstDeclaration) { - // local NS = {} or exportTable.NS = {} - const localDeclaration = this.createLocalOrExportedOrGlobalDeclaration( - nameIdentifier, - tstl.createTableExpression() - ); - - result.push(...localDeclaration); - } - - if ( - (isNonModuleMergeable || isFirstDeclaration) && - exportScope && - hasExports && - tsHelper.moduleHasEmittedBody(statement) - ) { - // local NS = exportTable.NS - const localDeclaration = this.createHoistableVariableDeclarationStatement( - this.createModuleLocalNameIdentifier(statement), - this.createExportedIdentifier(nameIdentifier, exportScope) - ); - - result.push(localDeclaration); - } - - // Set current namespace for nested NS - // Keep previous currentNS to reset after block transpilation - const previousNamespace = this.currentNamespace; - this.currentNamespace = statement; - - // Transform moduleblock to block and visit it - if (tsHelper.moduleHasEmittedBody(statement)) { - this.pushScope(ScopeType.Block); - let statements = ts.isModuleBlock(statement.body) - ? this.transformStatements(statement.body.statements) - : this.transformModuleDeclaration(statement.body); - statements = this.performHoisting(this.statementVisitResultToArray(statements)); - this.popScope(); - result.push(tstl.createDoStatement(statements)); - } - - this.currentNamespace = previousNamespace; - - return result; - } - - public transformEnumDeclaration(node: ts.EnumDeclaration): StatementVisitResult { - if (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Const && !this.options.preserveConstEnums) { - return undefined; - } - - const type = this.checker.getTypeAtLocation(node); - const membersOnly = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.CompileMembersOnly); - const result: tstl.Statement[] = []; - - if (!membersOnly) { - const name = this.transformIdentifier(node.name); - const table = tstl.createTableExpression(); - result.push(...this.createLocalOrExportedOrGlobalDeclaration(name, table, node)); - } - - const enumReference = this.transformExpression(node.name); - for (const member of node.members) { - const memberName = this.transformPropertyName(member.name); - - let valueExpression: tstl.Expression | undefined; - const constEnumValue = this.tryGetConstEnumValue(member); - if (constEnumValue) { - valueExpression = constEnumValue; - } else if (member.initializer) { - if (ts.isIdentifier(member.initializer)) { - const symbol = this.checker.getSymbolAtLocation(member.initializer); - if ( - symbol && - symbol.valueDeclaration && - ts.isEnumMember(symbol.valueDeclaration) && - symbol.valueDeclaration.parent === node - ) { - const otherMemberName = this.transformPropertyName(symbol.valueDeclaration.name); - valueExpression = tstl.createTableIndexExpression(enumReference, otherMemberName); - } - } - - if (!valueExpression) { - valueExpression = this.transformExpression(member.initializer); - } - } else { - valueExpression = tstl.createNilLiteral(); - } - - if (membersOnly) { - const enumSymbol = this.checker.getSymbolAtLocation(node.name); - const exportScope = enumSymbol ? this.getSymbolExportScope(enumSymbol) : undefined; - - result.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - tstl.isIdentifier(memberName) - ? memberName - : tstl.createIdentifier(member.name.getText(), member.name), - valueExpression, - node, - undefined, - exportScope - ) - ); - } else { - const memberAccessor = tstl.createTableIndexExpression(enumReference, memberName); - result.push(tstl.createAssignmentStatement(memberAccessor, valueExpression, member)); - - if (!tstl.isStringLiteral(valueExpression) && !tstl.isNilLiteral(valueExpression)) { - const reverseMemberAccessor = tstl.createTableIndexExpression(enumReference, memberAccessor); - result.push(tstl.createAssignmentStatement(reverseMemberAccessor, memberName, member)); - } - } - } - - return result; - } - - protected transformGeneratorFunction( - parameters: ts.NodeArray, - body: ts.Block, - spreadIdentifier?: tstl.Identifier - ): [tstl.Statement[], Scope] { - this.importLuaLibFeature(LuaLibFeature.Symbol); - const [functionBody, functionScope] = this.transformFunctionBody(parameters, body); - - const coroutineIdentifier = tstl.createIdentifier("____co"); - const valueIdentifier = tstl.createIdentifier("____value"); - const errIdentifier = tstl.createIdentifier("____err"); - const itIdentifier = tstl.createIdentifier("____it"); - - //local ____co = coroutine.create(originalFunction) - const coroutine = tstl.createVariableDeclarationStatement( - coroutineIdentifier, - tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("create")), - [tstl.createFunctionExpression(tstl.createBlock(functionBody))] - ) - ); - - const nextBody = []; - // coroutine.resume(__co, ...) - const resumeCall = tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("resume")), - [coroutineIdentifier, tstl.createDotsLiteral()] - ); - - // ____err, ____value = coroutine.resume(____co, ...) - nextBody.push(tstl.createVariableDeclarationStatement([errIdentifier, valueIdentifier], resumeCall)); - - //if(not ____err){error(____value)} - const errorCheck = tstl.createIfStatement( - tstl.createUnaryExpression(errIdentifier, tstl.SyntaxKind.NotOperator), - tstl.createBlock([ - tstl.createExpressionStatement( - tstl.createCallExpression(tstl.createIdentifier("error"), [valueIdentifier]) - ), - ]) - ); - nextBody.push(errorCheck); - - //coroutine.status(____co) == "dead"; - const coStatus = tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("status")), - [coroutineIdentifier] - ); - const status = tstl.createBinaryExpression( - coStatus, - tstl.createStringLiteral("dead"), - tstl.SyntaxKind.EqualityOperator - ); - - //{done = coroutine.status(____co) == "dead"; value = ____value} - const iteratorResult = tstl.createTableExpression([ - tstl.createTableFieldExpression(status, tstl.createStringLiteral("done")), - tstl.createTableFieldExpression(valueIdentifier, tstl.createStringLiteral("value")), - ]); - nextBody.push(tstl.createReturnStatement([iteratorResult])); - - //function(____, ...) - const nextFunctionDeclaration = tstl.createFunctionExpression( - tstl.createBlock(nextBody), - [tstl.createAnonymousIdentifier()], - tstl.createDotsLiteral() - ); - - //____it = {next = function(____, ...)} - const iterator = tstl.createVariableDeclarationStatement( - itIdentifier, - tstl.createTableExpression([ - tstl.createTableFieldExpression(nextFunctionDeclaration, tstl.createStringLiteral("next")), - ]) - ); - - const symbolIterator = tstl.createTableIndexExpression( - tstl.createIdentifier("Symbol"), - tstl.createStringLiteral("iterator") - ); - - const block = [ - coroutine, - iterator, - //____it[Symbol.iterator] = {return ____it} - tstl.createAssignmentStatement( - tstl.createTableIndexExpression(itIdentifier, symbolIterator), - tstl.createFunctionExpression(tstl.createBlock([tstl.createReturnStatement([itIdentifier])])) - ), - //return ____it - tstl.createReturnStatement([itIdentifier]), - ]; - - if (spreadIdentifier) { - const spreadTable = this.wrapInTable(tstl.createDotsLiteral()); - block.unshift(tstl.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); - } - - return [block, functionScope]; - } - - public transformFunctionDeclaration(functionDeclaration: ts.FunctionDeclaration): StatementVisitResult { - // Don't transform functions without body (overload declarations) - if (!functionDeclaration.body) { - return undefined; - } - - const type = this.checker.getTypeAtLocation(functionDeclaration); - const context = - tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void - ? this.createSelfIdentifier() - : undefined; - const [params, dotsLiteral, restParamName] = this.transformParameters(functionDeclaration.parameters, context); - - const [body, functionScope] = functionDeclaration.asteriskToken - ? this.transformGeneratorFunction(functionDeclaration.parameters, functionDeclaration.body, restParamName) - : this.transformFunctionBody(functionDeclaration.parameters, functionDeclaration.body, restParamName); - const block = tstl.createBlock(body); - const functionExpression = tstl.createFunctionExpression( - block, - params, - dotsLiteral, - restParamName, - tstl.FunctionExpressionFlags.Declaration - ); - - const name = functionDeclaration.name ? this.transformIdentifier(functionDeclaration.name) : undefined; - - if (name) { - // Remember symbols referenced in this function for hoisting later - if (!this.options.noHoisting && name.symbolId !== undefined) { - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - if (!scope.functionDefinitions) { - scope.functionDefinitions = new Map(); - } - const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Map() }; - scope.functionDefinitions.set(name.symbolId, functionInfo); - } - } - - const isDefaultExport = tsHelper.hasDefaultExportModifier(functionDeclaration.modifiers); - - if (isDefaultExport) { - return tstl.createAssignmentStatement( - tstl.createTableIndexExpression( - this.createExportsIdentifier(), - this.createDefaultExportStringLiteral(functionDeclaration) - ), - this.transformFunctionExpression(functionDeclaration) - ); - } else if (!name) { - throw TSTLErrors.MissingFunctionName(functionDeclaration); - } - - return this.createLocalOrExportedOrGlobalDeclaration(name, functionExpression, functionDeclaration); - } - - public transformTypeAliasDeclaration(_statement: ts.TypeAliasDeclaration): StatementVisitResult { - return undefined; - } - - public transformInterfaceDeclaration(_statement: ts.InterfaceDeclaration): StatementVisitResult { - return undefined; - } - - public transformVariableDeclaration(statement: ts.VariableDeclaration): StatementVisitResult { - if (statement.initializer && statement.type) { - // Validate assignment - const initializerType = this.checker.getTypeAtLocation(statement.initializer); - const varType = this.checker.getTypeFromTypeNode(statement.type); - this.validateFunctionAssignment(statement.initializer, initializerType, varType); - } - - if (ts.isIdentifier(statement.name)) { - // Find variable identifier - const identifierName = this.transformIdentifier(statement.name); - if (statement.initializer) { - const value = this.transformExpression(statement.initializer); - return this.createLocalOrExportedOrGlobalDeclaration(identifierName, value, statement); - } else { - return this.createLocalOrExportedOrGlobalDeclaration(identifierName, undefined, statement); - } - } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { - // Destructuring types - const statements: tstl.Statement[] = []; - - // For object, nested, omitted or rest bindings fall back to transformBindingPattern - if ( - ts.isObjectBindingPattern(statement.name) || - statement.name.elements.some( - e => ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken) - ) - ) { - let table: tstl.Identifier; - if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { - table = this.transformIdentifier(statement.initializer); - } else { - // Contain the expression in a temporary variable - table = tstl.createAnonymousIdentifier(); - if (statement.initializer) { - statements.push( - tstl.createVariableDeclarationStatement( - table, - this.transformExpression(statement.initializer) - ) - ); - } - } - statements.push( - ...this.statementVisitResultToArray(this.transformBindingPattern(statement.name, table)) - ); - return statements; - } - - const vars = - statement.name.elements.length > 0 - ? this.filterUndefinedAndCast( - statement.name.elements.map(e => this.transformArrayBindingElement(e)), - tstl.isIdentifier - ) - : tstl.createAnonymousIdentifier(statement.name); - - if (statement.initializer) { - if (tsHelper.isTupleReturnCall(statement.initializer, this.checker)) { - // Don't unpack TupleReturn decorated functions - statements.push( - ...this.createLocalOrExportedOrGlobalDeclaration( - vars, - this.transformExpression(statement.initializer), - statement - ) - ); - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Don't unpack array literals - const values = - statement.initializer.elements.length > 0 - ? statement.initializer.elements.map(e => this.transformExpression(e)) - : tstl.createNilLiteral(); - statements.push(...this.createLocalOrExportedOrGlobalDeclaration(vars, values, statement)); - } else { - // local vars = this.transpileDestructingAssignmentValue(node.initializer); - const initializer = this.createUnpackCall( - this.transformExpression(statement.initializer), - statement.initializer - ); - statements.push(...this.createLocalOrExportedOrGlobalDeclaration(vars, initializer, statement)); - } - } else { - statements.push( - ...this.createLocalOrExportedOrGlobalDeclaration(vars, tstl.createNilLiteral(), statement) - ); - } - - statement.name.elements.forEach(element => { - if (!ts.isOmittedExpression(element) && element.initializer) { - const variableName = this.transformIdentifier(element.name as ts.Identifier); - const identifier = this.addExportToIdentifier(variableName); - statements.push( - tstl.createIfStatement( - tstl.createBinaryExpression( - identifier, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ), - tstl.createBlock([ - tstl.createAssignmentStatement( - identifier, - this.transformExpression(element.initializer) - ), - ]) - ) - ); - } - }); - - return statements; - } - } - - public transformVariableStatement(statement: ts.VariableStatement): StatementVisitResult { - const result: tstl.Statement[] = []; - statement.declarationList.declarations.forEach(declaration => { - const declarationStatements = this.transformVariableDeclaration(declaration); - result.push(...this.statementVisitResultToArray(declarationStatements)); - }); - return result; - } - - public transformExpressionStatement(statement: ts.ExpressionStatement | ts.Expression): StatementVisitResult { - const expression = ts.isExpressionStatement(statement) ? statement.expression : statement; - if (ts.isBinaryExpression(expression)) { - const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(expression.operatorToken.kind); - if (isCompound && replacementOperator) { - // +=, -=, etc... - return this.transformCompoundAssignmentStatement( - expression, - expression.left, - expression.right, - replacementOperator - ); - } else if (expression.operatorToken.kind === ts.SyntaxKind.EqualsToken) { - // = assignment - return this.transformAssignmentStatement(expression); - } else if (expression.operatorToken.kind === ts.SyntaxKind.CommaToken) { - const lhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)); - const rhs = this.statementVisitResultToArray(this.transformExpressionStatement(expression.right)); - return tstl.createDoStatement([...lhs, ...rhs], expression); - } - } else if ( - ts.isPrefixUnaryExpression(expression) && - (expression.operator === ts.SyntaxKind.PlusPlusToken || - expression.operator === ts.SyntaxKind.MinusMinusToken) - ) { - // ++i, --i - const replacementOperator = - expression.operator === ts.SyntaxKind.PlusPlusToken - ? ts.SyntaxKind.PlusToken - : ts.SyntaxKind.MinusToken; - - return this.transformCompoundAssignmentStatement( - expression, - expression.operand, - ts.createLiteral(1), - replacementOperator - ); - } else if (ts.isPostfixUnaryExpression(expression)) { - // i++, i-- - const replacementOperator = - expression.operator === ts.SyntaxKind.PlusPlusToken - ? ts.SyntaxKind.PlusToken - : ts.SyntaxKind.MinusToken; - - return this.transformCompoundAssignmentStatement( - expression, - expression.operand, - ts.createLiteral(1), - replacementOperator - ); - } else if (ts.isDeleteExpression(expression)) { - return tstl.createAssignmentStatement( - this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression, - tstl.createNilLiteral(), - expression - ); - } - - if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { - const ownerType = this.checker.getTypeAtLocation(expression.expression.expression); - const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); - if (classDecorators.has(DecoratorKind.LuaTable)) { - return this.transformLuaTableExpressionAsExpressionStatement(expression); - } - } - - const result = this.transformExpression(expression); - return tstl.isCallExpression(result) || tstl.isMethodCallExpression(result) - ? tstl.createExpressionStatement(result) - : // Assign expression statements to dummy to make sure they're legal Lua - tstl.createVariableDeclarationStatement(tstl.createAnonymousIdentifier(), result); - } - - public transformYieldExpression(expression: ts.YieldExpression): ExpressionVisitResult { - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("coroutine"), tstl.createStringLiteral("yield")), - expression.expression ? [this.transformExpression(expression.expression)] : [], - expression - ); - } - - public transformReturnStatement(statement: ts.ReturnStatement): StatementVisitResult { - // Bubble up explicit return flag and check if we're inside a try/catch block - let insideTryCatch = false; - for (let i = this.scopeStack.length - 1; i >= 0; --i) { - const scope = this.scopeStack[i]; - scope.functionReturned = true; - - if (scope.type === ScopeType.Function) { - break; - } - - insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; - } - - let results: tstl.Expression[]; - - if (statement.expression) { - const expressionType = this.checker.getTypeAtLocation(statement.expression); - const returnType = tsHelper.getContainingFunctionReturnType(statement, this.checker); - if (returnType) { - this.validateFunctionAssignment(statement, expressionType, returnType); - } - if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { - // Parent function is a TupleReturn function - if (ts.isArrayLiteralExpression(statement.expression)) { - // If return expression is an array literal, leave out brackets. - results = statement.expression.elements.map(elem => this.transformExpression(elem)); - } else if ( - !tsHelper.isTupleReturnCall(statement.expression, this.checker) && - tsHelper.isArrayType(expressionType, this.checker, this.program) - ) { - // If return expression is an array-type and not another TupleReturn call, unpack it - const expression = this.createUnpackCall( - this.transformExpression(statement.expression), - statement.expression - ); - results = [expression]; - } else { - results = [this.transformExpression(statement.expression)]; - } - - // Wrap tupleReturn results when returning inside try/catch - if (insideTryCatch) { - results = [this.wrapInTable(...results)]; - } - } else { - results = [this.transformExpression(statement.expression)]; - } - } else { - // Empty return - results = []; - } - - if (insideTryCatch) { - results.unshift(tstl.createBooleanLiteral(true)); - } - - return tstl.createReturnStatement(results, statement); - } - - public transformIfStatement(statement: ts.IfStatement): StatementVisitResult { - this.pushScope(ScopeType.Conditional); - const condition = this.transformExpression(statement.expression); - const statements = this.performHoisting(this.transformBlockOrStatement(statement.thenStatement)); - this.popScope(); - const ifBlock = tstl.createBlock(statements); - if (statement.elseStatement) { - if (ts.isIfStatement(statement.elseStatement)) { - const elseStatement = this.transformIfStatement(statement.elseStatement) as tstl.IfStatement; - return tstl.createIfStatement(condition, ifBlock, elseStatement); - } else { - this.pushScope(ScopeType.Conditional); - const elseStatements = this.performHoisting(this.transformBlockOrStatement(statement.elseStatement)); - this.popScope(); - const elseBlock = tstl.createBlock(elseStatements); - return tstl.createIfStatement(condition, ifBlock, elseBlock); - } - } - return tstl.createIfStatement(condition, ifBlock); - } - - public transformWhileStatement(statement: ts.WhileStatement): StatementVisitResult { - return tstl.createWhileStatement( - tstl.createBlock(this.transformLoopBody(statement)), - this.transformExpression(statement.expression), - statement - ); - } - - public transformDoStatement(statement: ts.DoStatement): StatementVisitResult { - const body = tstl.createDoStatement(this.transformLoopBody(statement)); - let condition = this.transformExpression(statement.expression); - if (tstl.isUnaryExpression(condition) && condition.operator === tstl.SyntaxKind.NotOperator) { - condition = condition.operand; - } else { - condition = tstl.createUnaryExpression( - tstl.createParenthesizedExpression(condition), - tstl.SyntaxKind.NotOperator - ); - } - return tstl.createRepeatStatement(tstl.createBlock([body]), condition, statement); - } - - public transformForStatement(statement: ts.ForStatement): StatementVisitResult { - const result: tstl.Statement[] = []; - - if (statement.initializer) { - if (ts.isVariableDeclarationList(statement.initializer)) { - for (const variableDeclaration of statement.initializer.declarations) { - // local initializer = value - const declarations = this.transformVariableDeclaration(variableDeclaration); - result.push(...this.statementVisitResultToArray(declarations)); - } - } else { - const initializerStatements = this.transformExpressionStatement(statement.initializer); - result.push(...this.statementVisitResultToArray(initializerStatements)); - } - } - - const condition = statement.condition - ? this.transformExpression(statement.condition) - : tstl.createBooleanLiteral(true); - - // Add body - const body: tstl.Statement[] = this.transformLoopBody(statement); - - if (statement.incrementor) { - const bodyStatements = this.transformExpressionStatement(statement.incrementor); - body.push(...this.statementVisitResultToArray(bodyStatements)); - } - - // while (condition) do ... end - result.push(tstl.createWhileStatement(tstl.createBlock(body), condition)); - - return tstl.createDoStatement(result, statement); - } - - protected transformForOfInitializer( - initializer: ts.ForInitializer, - expression: tstl.Expression - ): tstl.Statement | undefined { - if (ts.isVariableDeclarationList(initializer)) { - // Declaration of new variable - const variableDeclarations = this.transformVariableDeclaration(initializer.declarations[0]); - if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { - if (initializer.declarations[0].name.elements.length === 0) { - // Ignore empty destructuring assignment - return undefined; - } - expression = this.createUnpackCall(expression, initializer); - } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { - throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); - } - - const variableStatements = this.statementVisitResultToArray(variableDeclarations); - if (variableStatements[0]) { - // we can safely assume that for vars are not exported and therefore declarationstatenents - return tstl.createVariableDeclarationStatement( - (variableStatements[0] as tstl.VariableDeclarationStatement).left, - expression - ); - } else { - throw TSTLErrors.MissingForOfVariables(initializer); - } - } else { - // Assignment to existing variable - let variables: tstl.AssignmentLeftHandSideExpression | tstl.AssignmentLeftHandSideExpression[]; - if (ts.isArrayLiteralExpression(initializer)) { - if (initializer.elements.length > 0) { - expression = this.createUnpackCall(expression, initializer); - variables = initializer.elements.map(e => - this.transformExpression(e) - ) as tstl.AssignmentLeftHandSideExpression[]; - } else { - // Ignore empty destructring assignment - return undefined; - } - } else if (ts.isObjectLiteralExpression(initializer)) { - throw TSTLErrors.UnsupportedObjectDestructuringInForOf(initializer); - } else { - variables = this.transformExpression(initializer) as tstl.AssignmentLeftHandSideExpression; - } - return tstl.createAssignmentStatement(variables, expression); - } - } - - protected transformLoopBody( - loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement - ): tstl.Statement[] { - this.pushScope(ScopeType.Loop); - const body = this.performHoisting(this.transformBlockOrStatement(loop.statement)); - const scope = this.popScope(); - const scopeId = scope.id; - - if (!scope.loopContinued) { - return body; - } - - const baseResult: tstl.Statement[] = [tstl.createDoStatement(body)]; - const continueLabel = tstl.createLabelStatement(`__continue${scopeId}`); - baseResult.push(continueLabel); - - return baseResult; - } - - protected transformBlockOrStatement(statement: ts.Statement): tstl.Statement[] { - return ts.isBlock(statement) - ? this.transformStatements(statement.statements) - : this.statementVisitResultToArray(this.transformStatement(statement)); - } - - protected transformForOfArrayStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - let valueVariable: tstl.Identifier; - if (ts.isVariableDeclarationList(statement.initializer)) { - // Declaration of new variable - const variables = statement.initializer.declarations[0].name; - if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { - valueVariable = tstl.createIdentifier("____values"); - const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - if (initializer) { - block.statements.unshift(initializer); - } - } else { - valueVariable = this.transformIdentifier(variables); - } - } else { - // Assignment to existing variable - valueVariable = tstl.createIdentifier("____value"); - const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - if (initializer) { - block.statements.unshift(initializer); - } - } - - const ipairsCall = tstl.createCallExpression(tstl.createIdentifier("ipairs"), [ - this.transformExpression(statement.expression), - ]); - - return tstl.createForInStatement( - block, - [tstl.createAnonymousIdentifier(), valueVariable], - [ipairsCall], - statement - ); - } - - protected transformForOfLuaIteratorStatement( - statement: ts.ForOfStatement, - block: tstl.Block - ): StatementVisitResult { - const luaIterator = this.transformExpression(statement.expression); - const type = this.checker.getTypeAtLocation(statement.expression); - const tupleReturn = tsHelper.getCustomDecorators(type, this.checker).has(DecoratorKind.TupleReturn); - if (tupleReturn) { - // LuaIterator + TupleReturn - if (ts.isVariableDeclarationList(statement.initializer)) { - // Variables declared in for loop - // for ${initializer} in ${iterable} do - const initializerVariable = statement.initializer.declarations[0].name; - if (ts.isArrayBindingPattern(initializerVariable)) { - const identifiers = this.filterUndefinedAndCast( - initializerVariable.elements.map(e => this.transformArrayBindingElement(e)), - tstl.isIdentifier - ); - if (identifiers.length === 0) { - identifiers.push(tstl.createAnonymousIdentifier()); - } - return tstl.createForInStatement(block, identifiers, [luaIterator]); - } else { - // Single variable is not allowed - throw TSTLErrors.UnsupportedNonDestructuringLuaIterator(statement.initializer); - } - } else { - // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____value0 in ${iterable} do - // ${initializer} = ____value0 - if (ts.isArrayLiteralExpression(statement.initializer)) { - const tmps = statement.initializer.elements.map((_, i) => tstl.createIdentifier(`____value${i}`)); - if (tmps.length > 0) { - const assign = tstl.createAssignmentStatement( - statement.initializer.elements.map( - e => this.transformExpression(e) as tstl.AssignmentLeftHandSideExpression - ), - tmps - ); - block.statements.splice(0, 0, assign); - } else { - tmps.push(tstl.createAnonymousIdentifier()); - } - return tstl.createForInStatement(block, tmps, [luaIterator]); - } else { - // Single variable is not allowed - throw TSTLErrors.UnsupportedNonDestructuringLuaIterator(statement.initializer); - } - } - } else { - // LuaIterator (no TupleReturn) - if ( - ts.isVariableDeclarationList(statement.initializer) && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - // Single variable declared in for loop - // for ${initializer} in ${iterator} do - return tstl.createForInStatement( - block, - [this.transformIdentifier(statement.initializer.declarations[0].name as ts.Identifier)], - [luaIterator] - ); - } else { - // Destructuring or variable NOT declared in for loop - // for ____value in ${iterator} do - // local ${initializer} = unpack(____value) - const valueVariable = tstl.createIdentifier("____value"); - const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - if (initializer) { - block.statements.splice(0, 0, initializer); - } - return tstl.createForInStatement(block, [valueVariable], [luaIterator]); - } - } - } - - protected transformForOfIteratorStatement(statement: ts.ForOfStatement, block: tstl.Block): StatementVisitResult { - const iterable = this.transformExpression(statement.expression); - if ( - ts.isVariableDeclarationList(statement.initializer) && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - // Single variable declared in for loop - // for ${initializer} in __TS__iterator(${iterator}) do - return tstl.createForInStatement( - block, - [this.transformIdentifier(statement.initializer.declarations[0].name as ts.Identifier)], - [this.transformLuaLibFunction(LuaLibFeature.Iterator, statement.expression, iterable)] - ); - } else { - // Destructuring or variable NOT declared in for loop - // for ____value in __TS__iterator(${iterator}) do - // local ${initializer} = ____value - const valueVariable = tstl.createIdentifier("____value"); - const initializer = this.transformForOfInitializer(statement.initializer, valueVariable); - if (initializer) { - block.statements.splice(0, 0, initializer); - } - return tstl.createForInStatement( - block, - [valueVariable], - [this.transformLuaLibFunction(LuaLibFeature.Iterator, statement.expression, iterable)] - ); - } - } - - protected transformForRangeStatement(statement: ts.ForOfStatement, body: tstl.Block): StatementVisitResult { - if (!ts.isCallExpression(statement.expression)) { - throw TSTLErrors.InvalidForRangeCall(statement.expression, "Expression must be a call expression."); - } - - if (statement.expression.arguments.length < 2 || statement.expression.arguments.length > 3) { - throw TSTLErrors.InvalidForRangeCall( - statement.expression, - "@forRange function must take 2 or 3 arguments." - ); - } - - if ( - statement.expression.arguments.some( - a => !tsHelper.isNumberType(this.checker.getTypeAtLocation(a), this.checker, this.program) - ) - ) { - throw TSTLErrors.InvalidForRangeCall(statement.expression, "@forRange arguments must be number types."); - } - - if (!ts.isVariableDeclarationList(statement.initializer)) { - throw TSTLErrors.InvalidForRangeCall( - statement.initializer, - "@forRange loop must declare its own control variable." - ); - } - - const controlDeclaration = statement.initializer.declarations[0]; - if (!ts.isIdentifier(controlDeclaration.name)) { - throw TSTLErrors.InvalidForRangeCall(statement.initializer, "@forRange loop cannot use destructuring."); - } - - const controlType = this.checker.getTypeAtLocation(controlDeclaration); - if (controlType && !tsHelper.isNumberType(controlType, this.checker, this.program)) { - throw TSTLErrors.InvalidForRangeCall( - statement.expression, - "@forRange function must return Iterable or Array." - ); - } - - const control = this.transformIdentifier(controlDeclaration.name); - const signature = this.checker.getResolvedSignature(statement.expression); - const [start, limit, step] = this.transformArguments(statement.expression.arguments, signature); - return tstl.createForStatement(body, control, start, limit, step, statement); - } - - public transformForOfStatement(statement: ts.ForOfStatement): StatementVisitResult { - // Transpile body - const body = tstl.createBlock(this.transformLoopBody(statement)); - - if ( - ts.isCallExpression(statement.expression) && - tsHelper.isForRangeType(statement.expression.expression, this.checker) - ) { - // ForRange - return this.transformForRangeStatement(statement, body); - } else if (tsHelper.isLuaIteratorType(statement.expression, this.checker)) { - // LuaIterators - return this.transformForOfLuaIteratorStatement(statement, body); - } else if ( - tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program) - ) { - // Arrays - return this.transformForOfArrayStatement(statement, body); - } else { - // TS Iterables - return this.transformForOfIteratorStatement(statement, body); - } - } - - public transformForInStatement(statement: ts.ForInStatement): StatementVisitResult { - // Transpile expression - const pairsIdentifier = tstl.createIdentifier("pairs"); - const expression = this.transformExpression(statement.expression); - const pairsCall = tstl.createCallExpression(pairsIdentifier, [expression]); - - if (tsHelper.isArrayType(this.checker.getTypeAtLocation(statement.expression), this.checker, this.program)) { - throw TSTLErrors.ForbiddenForIn(statement); - } - - const body = tstl.createBlock(this.transformLoopBody(statement)); - - // Transform iteration variable - // TODO: After the transformation pipeline refactor we should look at refactoring this together with the - // for-of initializer transformation. - let iterationVariable: tstl.Identifier; - if ( - ts.isVariableDeclarationList(statement.initializer) && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - iterationVariable = this.transformIdentifier(statement.initializer.declarations[0].name); - } else if (ts.isIdentifier(statement.initializer)) { - // Iteration variable becomes ____key - iterationVariable = tstl.createIdentifier("____key"); - // Push variable = ____key to the start of the loop body to match TS scoping - const initializer = tstl.createAssignmentStatement( - this.transformIdentifier(statement.initializer), - iterationVariable - ); - body.statements.unshift(initializer); - } else { - // This should never occur - throw TSTLErrors.UnsupportedForInVariable(statement.initializer); - } - - return tstl.createForInStatement(body, [iterationVariable], [pairsCall], statement); - } - - public transformSwitchStatement(statement: ts.SwitchStatement): StatementVisitResult { - if (this.luaTarget === LuaTarget.Lua51) { - throw TSTLErrors.UnsupportedForTarget("Switch statements", this.luaTarget, statement); - } - - this.pushScope(ScopeType.Switch); - - // Give the switch a unique name to prevent nested switches from acting up. - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - const switchName = `____switch${scope.id}`; - - const expression = this.transformExpression(statement.expression); - const switchVariable = tstl.createIdentifier(switchName); - const switchVariableDeclaration = tstl.createVariableDeclarationStatement(switchVariable, expression); - - let statements: tstl.Statement[] = [switchVariableDeclaration]; - - const caseClauses = statement.caseBlock.clauses.filter(c => ts.isCaseClause(c)) as ts.CaseClause[]; - - for (let i = 0; i < caseClauses.length; i++) { - const clause = caseClauses[i]; - // If the clause condition holds, go to the correct label - const condition = tstl.createBinaryExpression( - switchVariable, - this.transformExpression(clause.expression), - tstl.SyntaxKind.EqualityOperator - ); - const goto = tstl.createGotoStatement(`${switchName}_case_${i}`); - const conditionalGoto = tstl.createIfStatement(condition, tstl.createBlock([goto])); - statements.push(conditionalGoto); - } - - const hasDefaultCase = statement.caseBlock.clauses.some(c => ts.isDefaultClause(c)); - if (hasDefaultCase) { - statements.push(tstl.createGotoStatement(`${switchName}_case_default`)); - } else { - statements.push(tstl.createGotoStatement(`${switchName}_end`)); - } - - for (let i = 0; i < statement.caseBlock.clauses.length; i++) { - const clause = statement.caseBlock.clauses[i]; - const label = ts.isCaseClause(clause) - ? tstl.createLabelStatement(`${switchName}_case_${i}`) - : tstl.createLabelStatement(`${switchName}_case_default`); - - const body = tstl.createDoStatement(this.transformStatements(clause.statements)); - statements.push(label, body); - } - - statements.push(tstl.createLabelStatement(`${switchName}_end`)); - - statements = this.performHoisting(statements); - this.popScope(); - - return statements; - } - - public transformBreakStatement(breakStatement: ts.BreakStatement): StatementVisitResult { - const breakableScope = this.findScope(ScopeType.Loop | ScopeType.Switch); - - if (breakableScope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - if (breakableScope.type === ScopeType.Switch) { - return tstl.createGotoStatement(`____switch${breakableScope.id}_end`); - } else { - return tstl.createBreakStatement(breakStatement); - } - } - - protected transformScopeBlock(block: ts.Block, scopeType: ScopeType): [tstl.Block, Scope] { - this.pushScope(scopeType); - const statements = this.performHoisting(this.transformStatements(block.statements)); - const scope = this.popScope(); - return [tstl.createBlock(statements, block), scope]; - } - - public transformTryStatement(statement: ts.TryStatement): StatementVisitResult { - const [tryBlock, tryScope] = this.transformScopeBlock(statement.tryBlock, ScopeType.Try); - - const tryResultIdentifier = tstl.createIdentifier("____try"); - const returnValueIdentifier = tstl.createIdentifier("____returnValue"); - - const result: tstl.Statement[] = []; - - let returnedIdentifier: tstl.Identifier | undefined; - let returnCondition: tstl.Expression | undefined; - - const pCall = tstl.createIdentifier("pcall"); - const tryCall = tstl.createCallExpression(pCall, [tstl.createFunctionExpression(tryBlock)]); - - if (statement.catchClause && statement.catchClause.block.statements.length > 0) { - // try with catch - let [catchBlock, catchScope] = this.transformScopeBlock(statement.catchClause.block, ScopeType.Catch); - if (statement.catchClause.variableDeclaration) { - // Replace ____returned with catch variable - returnedIdentifier = this.transformIdentifier(statement.catchClause.variableDeclaration - .name as ts.Identifier); - } else if (tryScope.functionReturned || catchScope.functionReturned) { - returnedIdentifier = tstl.createIdentifier("____returned"); - } - - const tryReturnIdentifiers = [tryResultIdentifier]; // ____try - if (returnedIdentifier) { - tryReturnIdentifiers.push(returnedIdentifier); // ____returned or catch variable - if (tryScope.functionReturned || catchScope.functionReturned) { - tryReturnIdentifiers.push(returnValueIdentifier); // ____returnValue - returnCondition = tstl.cloneIdentifier(returnedIdentifier); - } - } - result.push(tstl.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); - - if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { - // Wrap catch in function if try or catch has return - const catchCall = tstl.createCallExpression( - tstl.createParenthesizedExpression(tstl.createFunctionExpression(catchBlock)) - ); - const catchAssign = tstl.createAssignmentStatement( - [tstl.cloneIdentifier(returnedIdentifier), tstl.cloneIdentifier(returnValueIdentifier)], - catchCall - ); - catchBlock = tstl.createBlock([catchAssign]); - } - const notTryCondition = tstl.createUnaryExpression( - tstl.createParenthesizedExpression(tryResultIdentifier), - tstl.SyntaxKind.NotOperator - ); - result.push(tstl.createIfStatement(notTryCondition, catchBlock)); - } else if (tryScope.functionReturned) { - // try with return, but no catch - returnedIdentifier = tstl.createIdentifier("____returned"); - const returnedVariables = [tryResultIdentifier, returnedIdentifier, returnValueIdentifier]; - result.push(tstl.createVariableDeclarationStatement(returnedVariables, tryCall)); - - // change return condition from '____returned' to '____try and ____returned' - returnCondition = tstl.createBinaryExpression( - tstl.cloneIdentifier(tryResultIdentifier), - returnedIdentifier, - tstl.SyntaxKind.AndOperator - ); - } else { - // try without return or catch - result.push(tstl.createExpressionStatement(tryCall)); - } - - if (statement.finallyBlock && statement.finallyBlock.statements.length > 0) { - result.push(...this.statementVisitResultToArray(this.transformBlockAsDoStatement(statement.finallyBlock))); - } - - if (returnCondition && returnedIdentifier) { - // With catch clause: - // if ____returned then return ____returnValue end - // No catch clause: - // if ____try and ____returned then return ____returnValue end - const returnValues: tstl.Expression[] = []; - const parentTryCatch = this.findScope(ScopeType.Function | ScopeType.Try | ScopeType.Catch); - if (parentTryCatch && parentTryCatch.type !== ScopeType.Function) { - // Nested try/catch needs to prefix a 'true' return value - returnValues.push(tstl.createBooleanLiteral(true)); - } - if (tsHelper.isInTupleReturnFunction(statement, this.checker)) { - returnValues.push(this.createUnpackCall(tstl.cloneIdentifier(returnValueIdentifier))); - } else { - returnValues.push(tstl.cloneIdentifier(returnValueIdentifier)); - } - const returnStatement = tstl.createReturnStatement(returnValues); - const ifReturnedStatement = tstl.createIfStatement(returnCondition, tstl.createBlock([returnStatement])); - result.push(ifReturnedStatement); - } - - return tstl.createDoStatement(result, statement); - } - - public transformThrowStatement(statement: ts.ThrowStatement): StatementVisitResult { - const parameters: tstl.Expression[] = []; - - if (statement.expression) { - parameters.push(this.transformExpression(statement.expression)); - parameters.push(tstl.createNumericLiteral(0)); - } - - return tstl.createExpressionStatement( - tstl.createCallExpression(tstl.createIdentifier("error"), parameters), - statement - ); - } - - public transformContinueStatement(statement: ts.ContinueStatement): StatementVisitResult { - if (this.luaTarget === LuaTarget.Lua51) { - throw TSTLErrors.UnsupportedForTarget("Continue statement", this.luaTarget, statement); - } - - const scope = this.findScope(ScopeType.Loop); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - scope.loopContinued = true; - return tstl.createGotoStatement(`__continue${scope.id}`, statement); - } - - public transformEmptyStatement(_statement: ts.EmptyStatement): StatementVisitResult { - return undefined; - } - - // Expressions - public transformExpression(expression: ts.Expression): ExpressionVisitResult { - switch (expression.kind) { - case ts.SyntaxKind.BinaryExpression: - return this.transformBinaryExpression(expression as ts.BinaryExpression); - case ts.SyntaxKind.ConditionalExpression: - return this.transformConditionalExpression(expression as ts.ConditionalExpression); - case ts.SyntaxKind.CallExpression: - return this.transformCallExpression(expression as ts.CallExpression); - case ts.SyntaxKind.PropertyAccessExpression: - return this.transformPropertyAccessExpression(expression as ts.PropertyAccessExpression); - case ts.SyntaxKind.ElementAccessExpression: - return this.transformElementAccessExpression(expression as ts.ElementAccessExpression); - case ts.SyntaxKind.Identifier: - return this.transformIdentifierExpression(expression as ts.Identifier); - case ts.SyntaxKind.StringLiteral: - case ts.SyntaxKind.NoSubstitutionTemplateLiteral: - return this.transformStringLiteral(expression as ts.StringLiteral); - case ts.SyntaxKind.TaggedTemplateExpression: - return this.transformTaggedTemplateExpression(expression as ts.TaggedTemplateExpression); - case ts.SyntaxKind.TemplateExpression: - return this.transformTemplateExpression(expression as ts.TemplateExpression); - case ts.SyntaxKind.NumericLiteral: - return this.transformNumericLiteral(expression as ts.NumericLiteral); - case ts.SyntaxKind.TrueKeyword: - return this.transformTrueKeyword(expression as ts.BooleanLiteral); - case ts.SyntaxKind.FalseKeyword: - return this.transformFalseKeyword(expression as ts.BooleanLiteral); - case ts.SyntaxKind.NullKeyword: - case ts.SyntaxKind.UndefinedKeyword: - return this.transformNullOrUndefinedKeyword(expression); - case ts.SyntaxKind.ThisKeyword: - return this.transformThisKeyword(expression as ts.ThisExpression); - case ts.SyntaxKind.PostfixUnaryExpression: - return this.transformPostfixUnaryExpression(expression as ts.PostfixUnaryExpression); - case ts.SyntaxKind.PrefixUnaryExpression: - return this.transformPrefixUnaryExpression(expression as ts.PrefixUnaryExpression); - case ts.SyntaxKind.ArrayLiteralExpression: - return this.transformArrayLiteral(expression as ts.ArrayLiteralExpression); - case ts.SyntaxKind.ObjectLiteralExpression: - return this.transformObjectLiteral(expression as ts.ObjectLiteralExpression); - case ts.SyntaxKind.OmittedExpression: - return this.transformOmittedExpression(expression as ts.OmittedExpression); - case ts.SyntaxKind.DeleteExpression: - return this.transformDeleteExpression(expression as ts.DeleteExpression); - case ts.SyntaxKind.FunctionExpression: - case ts.SyntaxKind.ArrowFunction: - return this.transformFunctionExpression(expression as ts.ArrowFunction); - case ts.SyntaxKind.NewExpression: - return this.transformNewExpression(expression as ts.NewExpression); - case ts.SyntaxKind.ParenthesizedExpression: - return this.transformParenthesizedExpression(expression as ts.ParenthesizedExpression); - case ts.SyntaxKind.SuperKeyword: - return this.transformSuperKeyword(expression as ts.SuperExpression); - case ts.SyntaxKind.TypeAssertionExpression: - case ts.SyntaxKind.AsExpression: - return this.transformAssertionExpression(expression as ts.AssertionExpression); - case ts.SyntaxKind.TypeOfExpression: - return this.transformTypeOfExpression(expression as ts.TypeOfExpression); - case ts.SyntaxKind.SpreadElement: - return this.transformSpreadElement(expression as ts.SpreadElement); - case ts.SyntaxKind.NonNullExpression: - return this.transformExpression((expression as ts.NonNullExpression).expression); - case ts.SyntaxKind.YieldExpression: - return this.transformYieldExpression(expression as ts.YieldExpression); - case ts.SyntaxKind.ClassExpression: - return this.transformClassExpression(expression as ts.ClassExpression); - case ts.SyntaxKind.PartiallyEmittedExpression: - return this.transformExpression((expression as ts.PartiallyEmittedExpression).expression); - default: - throw TSTLErrors.UnsupportedKind("expression", expression.kind, expression); - } - } - - protected transformBinaryOperation( - left: tstl.Expression, - right: tstl.Expression, - operator: ts.BinaryOperator, - tsOriginal: ts.Node - ): ExpressionVisitResult { - switch (operator) { - case ts.SyntaxKind.AmpersandToken: - case ts.SyntaxKind.BarToken: - case ts.SyntaxKind.CaretToken: - case ts.SyntaxKind.LessThanLessThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return this.transformBinaryBitOperation(tsOriginal, left, right, operator); - default: - const luaOperator = this.transformBinaryOperator(operator, tsOriginal); - if (luaOperator === tstl.SyntaxKind.ConcatOperator) { - left = this.wrapInToStringForConcat(left); - right = this.wrapInToStringForConcat(right); - } - return tstl.createBinaryExpression(left, right, luaOperator, tsOriginal); - } - } - - protected transformTypeOfLiteralComparison( - typeOfExpression: ts.TypeOfExpression, - comparedExpression: tstl.StringLiteral, - operator: ts.BinaryOperator, - tsOriginal: ts.Node - ): ExpressionVisitResult { - if (comparedExpression.value === "object") { - comparedExpression.value = "table"; - } else if (comparedExpression.value === "undefined") { - comparedExpression.value = "nil"; - } - const innerExpression = this.transformExpression(typeOfExpression.expression); - const typeCall = tstl.createCallExpression(tstl.createIdentifier("type"), [innerExpression], typeOfExpression); - return this.transformBinaryOperation(typeCall, comparedExpression, operator, tsOriginal); - } - - protected transformComparisonExpression(expression: ts.BinaryExpression): ExpressionVisitResult { - let left: tstl.Expression | undefined; - let right: tstl.Expression | undefined; - const operator = expression.operatorToken.kind; - - // Custom handling for 'typeof(foo) === "type"' - if (ts.isTypeOfExpression(expression.left)) { - right = this.transformExpression(expression.right); - if (tstl.isStringLiteral(right)) { - return this.transformTypeOfLiteralComparison(expression.left, right, operator, expression); - } - } else if (ts.isTypeOfExpression(expression.right)) { - left = this.transformExpression(expression.left); - if (tstl.isStringLiteral(left)) { - return this.transformTypeOfLiteralComparison(expression.right, left, operator, expression); - } - } - - if (!left) { - left = this.transformExpression(expression.left); - } - if (!right) { - right = this.transformExpression(expression.right); - } - return this.transformBinaryOperation(left, right, operator, expression); - } - - public transformBinaryExpression(expression: ts.BinaryExpression): ExpressionVisitResult { - const operator = expression.operatorToken.kind; - - // Check if this is an assignment token, then handle accordingly - const [isCompound, replacementOperator] = tsHelper.isBinaryAssignmentToken(operator); - if (isCompound && replacementOperator) { - return this.transformCompoundAssignmentExpression( - expression, - expression.left, - expression.right, - replacementOperator, - false - ); - } - - // Transpile operators - switch (operator) { - case ts.SyntaxKind.AmpersandToken: - case ts.SyntaxKind.BarToken: - case ts.SyntaxKind.CaretToken: - case ts.SyntaxKind.LessThanLessThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - case ts.SyntaxKind.PlusToken: - case ts.SyntaxKind.AmpersandAmpersandToken: - case ts.SyntaxKind.BarBarToken: - case ts.SyntaxKind.MinusToken: - case ts.SyntaxKind.AsteriskToken: - case ts.SyntaxKind.AsteriskAsteriskToken: - case ts.SyntaxKind.SlashToken: - case ts.SyntaxKind.PercentToken: { - const lhs = this.transformExpression(expression.left); - const rhs = this.transformExpression(expression.right); - return this.transformBinaryOperation(lhs, rhs, operator, expression); - } - - case ts.SyntaxKind.GreaterThanToken: - case ts.SyntaxKind.GreaterThanEqualsToken: - case ts.SyntaxKind.LessThanToken: - case ts.SyntaxKind.LessThanEqualsToken: - case ts.SyntaxKind.EqualsEqualsToken: - case ts.SyntaxKind.EqualsEqualsEqualsToken: - case ts.SyntaxKind.ExclamationEqualsToken: - case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return this.transformComparisonExpression(expression); - - case ts.SyntaxKind.EqualsToken: - return this.transformAssignmentExpression(expression); - - case ts.SyntaxKind.InKeyword: { - const lhs = this.transformExpression(expression.left); - const rhs = this.transformExpression(expression.right); - const indexExpression = tstl.createTableIndexExpression(rhs, lhs); - return tstl.createBinaryExpression( - indexExpression, - tstl.createNilLiteral(), - tstl.SyntaxKind.InequalityOperator, - expression - ); - } - - case ts.SyntaxKind.InstanceOfKeyword: { - const lhs = this.transformExpression(expression.left); - const rhs = this.transformExpression(expression.right); - const rhsType = this.checker.getTypeAtLocation(expression.right); - const decorators = tsHelper.getCustomDecorators(rhsType, this.checker); - - if (decorators.has(DecoratorKind.Extension) || decorators.has(DecoratorKind.MetaExtension)) { - // Cannot use instanceof on extension classes - throw TSTLErrors.InvalidInstanceOfExtension(expression); - } - - if (decorators.has(DecoratorKind.LuaTable)) { - throw TSTLErrors.InvalidInstanceOfLuaTable(expression); - } - - if (tsHelper.isStandardLibraryType(rhsType, "ObjectConstructor", this.program)) { - return this.transformLuaLibFunction(LuaLibFeature.InstanceOfObject, expression, lhs); - } - - return this.transformLuaLibFunction(LuaLibFeature.InstanceOf, expression, lhs, rhs); - } - - case ts.SyntaxKind.CommaToken: { - const rhs = this.transformExpression(expression.right); - return this.createImmediatelyInvokedFunctionExpression( - this.statementVisitResultToArray(this.transformExpressionStatement(expression.left)), - rhs, - expression - ); - } - - default: - throw TSTLErrors.UnsupportedKind("binary operator", operator, expression); - } - } - - protected transformAssignment(lhs: ts.Expression, right: tstl.Expression, parent?: ts.Expression): tstl.Statement { - if (tsHelper.isArrayLength(lhs, this.checker, this.program)) { - return tstl.createExpressionStatement( - this.transformLuaLibFunction( - LuaLibFeature.ArraySetLength, - parent, - this.transformExpression(lhs.expression), - right - ) - ); - } - - return tstl.createAssignmentStatement( - this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression, - right, - lhs.parent - ); - } - - protected transformAssignmentStatement(expression: ts.BinaryExpression): StatementVisitResult { - // Validate assignment - const rightType = this.checker.getTypeAtLocation(expression.right); - const leftType = this.checker.getTypeAtLocation(expression.left); - this.validateFunctionAssignment(expression.right, rightType, leftType); - this.validatePropertyAssignment(expression); - - if (tsHelper.isDestructuringAssignment(expression)) { - // Destructuring assignment - if ( - ts.isArrayLiteralExpression(expression.left) && - expression.left.elements.every( - e => - (ts.isIdentifier(e) || ts.isPropertyAccessExpression(e) || ts.isElementAccessExpression(e)) && - !tsHelper.isArrayLength(e, this.checker, this.program) - ) - ) { - const rightType = this.checker.getTypeAtLocation(expression.right); - let right = this.transformExpression(expression.right); - if ( - !tsHelper.isTupleReturnCall(expression.right, this.checker) && - tsHelper.isArrayType(rightType, this.checker, this.program) - ) { - right = this.createUnpackCall(right, expression.right); - } - - const left = this.castElements( - expression.left.elements.map(e => this.transformExpression(e)), - tstl.isAssignmentLeftHandSideExpression - ); - - return tstl.createAssignmentStatement(left, right, expression); - } - - let right = this.transformExpression(expression.right); - if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = this.wrapInTable(right); - } - - const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); - return [ - tstl.createVariableDeclarationStatement(rootIdentifier, right), - ...this.transformDestructuringAssignment(expression, rootIdentifier), - ]; - } else { - // Simple assignment - return this.transformAssignment(expression.left, this.transformExpression(expression.right)); - } - } - - protected transformDestructuringAssignment( - node: ts.DestructuringAssignment, - root: tstl.Expression - ): tstl.Statement[] { - switch (node.left.kind) { - case ts.SyntaxKind.ObjectLiteralExpression: - return this.transformObjectDestructuringAssignment(node as ts.ObjectDestructuringAssignment, root); - case ts.SyntaxKind.ArrayLiteralExpression: - return this.transformArrayDestructuringAssignment(node as ts.ArrayDestructuringAssignment, root); - } - } - - protected transformObjectDestructuringAssignment( - node: ts.ObjectDestructuringAssignment, - root: tstl.Expression - ): tstl.Statement[] { - return this.transformObjectLiteralAssignmentPattern(node.left, root); - } - - protected transformArrayDestructuringAssignment( - node: ts.ArrayDestructuringAssignment, - root: tstl.Expression - ): tstl.Statement[] { - return this.transformArrayLiteralAssignmentPattern(node.left, root); - } - - protected transformShorthandPropertyAssignment( - node: ts.ShorthandPropertyAssignment, - root: tstl.Expression - ): tstl.Statement[] { - const result: tstl.Statement[] = []; - const assignmentVariableName = this.transformIdentifier(node.name); - const extractionIndex = tstl.createStringLiteral(node.name.text); - const variableExtractionAssignmentStatement = tstl.createAssignmentStatement( - assignmentVariableName, - tstl.createTableIndexExpression(root, extractionIndex) - ); - - result.push(variableExtractionAssignmentStatement); - - const defaultInitializer = node.objectAssignmentInitializer - ? this.transformExpression(node.objectAssignmentInitializer) - : undefined; - - if (defaultInitializer) { - const nilCondition = tstl.createBinaryExpression( - assignmentVariableName, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ); - - const assignment = tstl.createAssignmentStatement(assignmentVariableName, defaultInitializer); - - const ifBlock = tstl.createBlock([assignment]); - - result.push(tstl.createIfStatement(nilCondition, ifBlock, undefined, node)); - } - - return result; - } - - protected transformSpreadAssignment( - node: ts.SpreadAssignment, - root: tstl.Expression, - properties: ts.NodeArray - ): tstl.Statement[] { - const usedProperties: tstl.TableFieldExpression[] = []; - // TODO: .flatMap - for (const property of properties) { - if ( - (ts.isShorthandPropertyAssignment(property) || ts.isPropertyAssignment(property)) && - !ts.isComputedPropertyName(property.name) - ) { - const name = ts.isIdentifier(property.name) - ? tstl.createStringLiteral(property.name.text) - : this.transformExpression(property.name); - - usedProperties.push(tstl.createTableFieldExpression(tstl.createBooleanLiteral(true), name)); - } - } - - const extractingExpression = this.transformLuaLibFunction( - LuaLibFeature.ObjectRest, - undefined, - root, - tstl.createTableExpression(usedProperties) - ); - - return [this.transformAssignment(node.expression, extractingExpression)]; - } - - protected transformObjectLiteralAssignmentPattern( - node: ts.ObjectLiteralExpression, - root: tstl.Expression - ): tstl.Statement[] { - const result: tstl.Statement[] = []; - - for (const property of node.properties) { - switch (property.kind) { - case ts.SyntaxKind.ShorthandPropertyAssignment: - result.push(...this.transformShorthandPropertyAssignment(property, root)); - break; - case ts.SyntaxKind.PropertyAssignment: - result.push(...this.transformPropertyAssignment(property, root)); - break; - case ts.SyntaxKind.SpreadAssignment: - result.push(...this.transformSpreadAssignment(property, root, node.properties)); - break; - default: - throw TSTLErrors.UnsupportedKind("Object Destructure Property", property.kind, property); - } - } - - return result; - } - - protected transformArrayLiteralAssignmentPattern( - node: ts.ArrayLiteralExpression, - root: tstl.Expression - ): tstl.Statement[] { - const result: tstl.Statement[] = []; - - node.elements.forEach((element, index) => { - const indexedRoot = tstl.createTableIndexExpression(root, tstl.createNumericLiteral(index + 1), element); - - switch (element.kind) { - case ts.SyntaxKind.ObjectLiteralExpression: - result.push( - ...this.transformObjectLiteralAssignmentPattern( - element as ts.ObjectLiteralExpression, - indexedRoot - ) - ); - break; - case ts.SyntaxKind.ArrayLiteralExpression: - result.push( - ...this.transformArrayLiteralAssignmentPattern( - element as ts.ArrayLiteralExpression, - indexedRoot - ) - ); - break; - case ts.SyntaxKind.BinaryExpression: - const assignedVariable = tstl.createIdentifier("____bindingAssignmentValue"); - - const assignedVariableDeclaration = tstl.createVariableDeclarationStatement( - assignedVariable, - indexedRoot - ); - - const nilCondition = tstl.createBinaryExpression( - assignedVariable, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ); - - const defaultAssignmentStatement = this.transformAssignment( - (element as ts.BinaryExpression).left, - this.transformExpression((element as ts.BinaryExpression).right) - ); - - const elseAssignmentStatement = this.transformAssignment( - (element as ts.BinaryExpression).left, - assignedVariable - ); - - const ifBlock = tstl.createBlock([defaultAssignmentStatement]); - - const elseBlock = tstl.createBlock([elseAssignmentStatement]); - - const ifStatement = tstl.createIfStatement(nilCondition, ifBlock, elseBlock, node); - - result.push(assignedVariableDeclaration); - result.push(ifStatement); - break; - case ts.SyntaxKind.Identifier: - case ts.SyntaxKind.PropertyAccessExpression: - case ts.SyntaxKind.ElementAccessExpression: - const assignmentStatement = this.transformAssignment(element, indexedRoot); - - result.push(assignmentStatement); - break; - case ts.SyntaxKind.SpreadElement: - if (index !== node.elements.length - 1) break; - - const restElements = this.transformLuaLibFunction( - LuaLibFeature.ArraySlice, - undefined, - root, - tstl.createNumericLiteral(index) - ); - - result.push(this.transformAssignment((element as ts.SpreadElement).expression, restElements)); - break; - case ts.SyntaxKind.OmittedExpression: - break; - default: - throw TSTLErrors.UnsupportedKind("Array Destructure Assignment Element", element.kind, element); - } - }); - - return result; - } - - protected transformPropertyAssignment(node: ts.PropertyAssignment, root: tstl.Expression): tstl.Statement[] { - const result: tstl.Statement[] = []; - - if (tsHelper.isAssignmentPattern(node.initializer)) { - const propertyAccessString = this.transformPropertyName(node.name); - const newRootAccess = tstl.createTableIndexExpression(root, propertyAccessString); - - if (ts.isObjectLiteralExpression(node.initializer)) { - return this.transformObjectLiteralAssignmentPattern(node.initializer, newRootAccess); - } - - if (ts.isArrayLiteralExpression(node.initializer)) { - return this.transformArrayLiteralAssignmentPattern(node.initializer, newRootAccess); - } - } - - const leftExpression = ts.isBinaryExpression(node.initializer) ? node.initializer.left : node.initializer; - const variableToExtract = this.transformPropertyName(node.name); - const extractingExpression = tstl.createTableIndexExpression(root, variableToExtract); - - const destructureAssignmentStatement = this.transformAssignment(leftExpression, extractingExpression); - - result.push(destructureAssignmentStatement); - - if (ts.isBinaryExpression(node.initializer)) { - const assignmentLeftHandSide = this.transformExpression(node.initializer.left); - - const nilCondition = tstl.createBinaryExpression( - assignmentLeftHandSide, - tstl.createNilLiteral(), - tstl.SyntaxKind.EqualityOperator - ); - - const assignmentStatements = this.statementVisitResultToArray( - this.transformAssignmentStatement(node.initializer) - ); - - const ifBlock = tstl.createBlock(assignmentStatements); - - result.push(tstl.createIfStatement(nilCondition, ifBlock, undefined, node)); - } - - return result; - } - - protected transformAssignmentExpression( - expression: ts.BinaryExpression - ): tstl.CallExpression | tstl.MethodCallExpression { - // Validate assignment - const rightType = this.checker.getTypeAtLocation(expression.right); - const leftType = this.checker.getTypeAtLocation(expression.left); - this.validateFunctionAssignment(expression.right, rightType, leftType); - - if (tsHelper.isArrayLength(expression.left, this.checker, this.program)) { - // array.length = x - return this.transformLuaLibFunction( - LuaLibFeature.ArraySetLength, - expression, - this.transformExpression(expression.left.expression), - this.transformExpression(expression.right) - ); - } - - if (tsHelper.isDestructuringAssignment(expression)) { - // Destructuring assignment - const rootIdentifier = tstl.createAnonymousIdentifier(expression.left); - - let right = this.transformExpression(expression.right); - if (tsHelper.isTupleReturnCall(expression.right, this.checker)) { - right = this.wrapInTable(right); - } - - const statements = [ - tstl.createVariableDeclarationStatement(rootIdentifier, right), - ...this.transformDestructuringAssignment(expression, rootIdentifier), - ]; - - return this.createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); - } - - if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { - // Left is property/element access: cache result while maintaining order of evaluation - // (function(o, i, v) o[i] = v; return v end)(${objExpression}, ${indexExpression}, ${right}) - const objParameter = tstl.createIdentifier("o"); - const indexParameter = tstl.createIdentifier("i"); - const valueParameter = tstl.createIdentifier("v"); - const indexStatement = tstl.createTableIndexExpression(objParameter, indexParameter); - const statements: tstl.Statement[] = [ - tstl.createAssignmentStatement(indexStatement, valueParameter), - tstl.createReturnStatement([valueParameter]), - ]; - const iife = tstl.createFunctionExpression(tstl.createBlock(statements), [ - objParameter, - indexParameter, - valueParameter, - ]); - const objExpression = this.transformExpression(expression.left.expression); - let indexExpression: tstl.Expression; - if (ts.isPropertyAccessExpression(expression.left)) { - // Property access - indexExpression = tstl.createStringLiteral(expression.left.name.text); - } else { - // Element access - indexExpression = this.transformElementAccessArgument(expression.left); - } - - const args = [objExpression, indexExpression, this.transformExpression(expression.right)]; - return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), args, expression); - } else { - // Simple assignment - // (function() ${left} = ${right}; return ${left} end)() - const left = this.transformExpression(expression.left); - const right = this.transformExpression(expression.right); - return this.createImmediatelyInvokedFunctionExpression( - [this.transformAssignment(expression.left, right)], - left, - expression - ); - } - } - - protected transformCompoundAssignmentExpression( - expression: ts.Expression, - lhs: ts.Expression, - rhs: ts.Expression, - replacementOperator: ts.BinaryOperator, - isPostfix: boolean - ): tstl.CallExpression { - const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; - let right = this.transformExpression(rhs); - - const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( - lhs, - this.checker, - this.program - ); - if (hasEffects && objExpression && indexExpression) { - // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects - // local __obj, __index = ${objExpression}, ${indexExpression}; - const obj = tstl.createIdentifier("____obj"); - const index = tstl.createIdentifier("____index"); - const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( - [obj, index], - [this.transformExpression(objExpression), this.transformExpression(indexExpression)] - ); - const accessExpression = tstl.createTableIndexExpression(obj, index); - - const tmp = tstl.createIdentifier("____tmp"); - right = tstl.createParenthesizedExpression(right); - let tmpDeclaration: tstl.VariableDeclarationStatement; - let assignStatement: tstl.AssignmentStatement; - if (isPostfix) { - // local ____tmp = ____obj[____index]; - // ____obj[____index] = ____tmp ${replacementOperator} ${right}; - tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, accessExpression); - const operatorExpression = this.transformBinaryOperation(tmp, right, replacementOperator, expression); - assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); - } else { - // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; - // ____obj[____index] = ____tmp; - const operatorExpression = this.transformBinaryOperation( - accessExpression, - right, - replacementOperator, - expression - ); - tmpDeclaration = tstl.createVariableDeclarationStatement(tmp, operatorExpression); - assignStatement = tstl.createAssignmentStatement(accessExpression, tmp); - } - // return ____tmp - return this.createImmediatelyInvokedFunctionExpression( - [objAndIndexDeclaration, tmpDeclaration, assignStatement], - tmp, - expression - ); - } else if (isPostfix) { - // Postfix expressions need to cache original value in temp - // local ____tmp = ${left}; - // ${left} = ____tmp ${replacementOperator} ${right}; - // return ____tmp - const tmpIdentifier = tstl.createIdentifier("____tmp"); - const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, left); - const operatorExpression = this.transformBinaryOperation( - tmpIdentifier, - right, - replacementOperator, - expression - ); - const assignStatement = this.transformAssignment(lhs, operatorExpression); - return this.createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, assignStatement], - tmpIdentifier, - expression - ); - } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { - // Simple property/element access expressions need to cache in temp to avoid double-evaluation - // local ____tmp = ${left} ${replacementOperator} ${right}; - // ${left} = ____tmp; - // return ____tmp - const tmpIdentifier = tstl.createIdentifier("____tmp"); - const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, expression); - const tmpDeclaration = tstl.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); - const assignStatement = this.transformAssignment(lhs, tmpIdentifier); - return this.createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, assignStatement], - tmpIdentifier, - expression - ); - } else { - // Simple expressions - // ${left} = ${right}; return ${right} - const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, expression); - const assignStatement = this.transformAssignment(lhs, operatorExpression); - return this.createImmediatelyInvokedFunctionExpression([assignStatement], left, expression); - } - } - - public transformBinaryOperator(operator: ts.BinaryOperator, node: ts.Node): tstl.BinaryOperator { - switch (operator) { - // Bitwise operators - case ts.SyntaxKind.BarToken: - return tstl.SyntaxKind.BitwiseOrOperator; - case ts.SyntaxKind.CaretToken: - return tstl.SyntaxKind.BitwiseExclusiveOrOperator; - case ts.SyntaxKind.AmpersandToken: - return tstl.SyntaxKind.BitwiseAndOperator; - case ts.SyntaxKind.LessThanLessThanToken: - return tstl.SyntaxKind.BitwiseLeftShiftOperator; - case ts.SyntaxKind.GreaterThanGreaterThanToken: - throw TSTLErrors.UnsupportedKind("right shift operator (use >>> instead)", operator, node); - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return tstl.SyntaxKind.BitwiseRightShiftOperator; - // Regular operators - case ts.SyntaxKind.AmpersandAmpersandToken: - return tstl.SyntaxKind.AndOperator; - case ts.SyntaxKind.BarBarToken: - return tstl.SyntaxKind.OrOperator; - case ts.SyntaxKind.MinusToken: - return tstl.SyntaxKind.SubtractionOperator; - case ts.SyntaxKind.PlusToken: - if (ts.isBinaryExpression(node)) { - // Check is we need to use string concat operator - const typeLeft = this.checker.getTypeAtLocation(node.left); - const typeRight = this.checker.getTypeAtLocation(node.right); - if ( - tsHelper.isStringType(typeLeft, this.checker, this.program) || - tsHelper.isStringType(typeRight, this.checker, this.program) - ) { - return tstl.SyntaxKind.ConcatOperator; - } - } - return tstl.SyntaxKind.AdditionOperator; - case ts.SyntaxKind.AsteriskToken: - return tstl.SyntaxKind.MultiplicationOperator; - case ts.SyntaxKind.AsteriskAsteriskToken: - return tstl.SyntaxKind.PowerOperator; - case ts.SyntaxKind.SlashToken: - return tstl.SyntaxKind.DivisionOperator; - case ts.SyntaxKind.PercentToken: - return tstl.SyntaxKind.ModuloOperator; - case ts.SyntaxKind.GreaterThanToken: - return tstl.SyntaxKind.GreaterThanOperator; - case ts.SyntaxKind.GreaterThanEqualsToken: - return tstl.SyntaxKind.GreaterEqualOperator; - case ts.SyntaxKind.LessThanToken: - return tstl.SyntaxKind.LessThanOperator; - case ts.SyntaxKind.LessThanEqualsToken: - return tstl.SyntaxKind.LessEqualOperator; - case ts.SyntaxKind.EqualsEqualsToken: - case ts.SyntaxKind.EqualsEqualsEqualsToken: - return tstl.SyntaxKind.EqualityOperator; - case ts.SyntaxKind.ExclamationEqualsToken: - case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return tstl.SyntaxKind.InequalityOperator; - default: - throw TSTLErrors.UnsupportedKind("binary operator", operator, node); - } - } - - public transformClassExpression(expression: ts.ClassLikeDeclaration): ExpressionVisitResult { - const isDefaultExport = tsHelper.hasDefaultExportModifier(expression.modifiers); - - let className: tstl.Identifier; - if (expression.name) { - className = this.transformIdentifier(expression.name); - } else if (isDefaultExport) { - className = this.createDefaultExportIdentifier(expression); - } else { - className = tstl.createAnonymousIdentifier(); - } - - this.pushScope(ScopeType.Function); - const classDeclaration = this.transformClassDeclaration(expression, className); - this.popScope(); - - return this.createImmediatelyInvokedFunctionExpression( - this.statementVisitResultToArray(classDeclaration), - className, - expression - ); - } - - protected transformCompoundAssignmentStatement( - node: ts.Node, - lhs: ts.Expression, - rhs: ts.Expression, - replacementOperator: ts.BinaryOperator - ): tstl.Statement { - const left = this.transformExpression(lhs) as tstl.AssignmentLeftHandSideExpression; - const right = this.transformExpression(rhs); - - const [hasEffects, objExpression, indexExpression] = tsHelper.isAccessExpressionWithEvaluationEffects( - lhs, - this.checker, - this.program - ); - if (hasEffects && objExpression && indexExpression) { - // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects - // local __obj, __index = ${objExpression}, ${indexExpression}; - // ____obj[____index] = ____obj[____index] ${replacementOperator} ${right}; - const obj = tstl.createIdentifier("____obj"); - const index = tstl.createIdentifier("____index"); - const objAndIndexDeclaration = tstl.createVariableDeclarationStatement( - [obj, index], - [this.transformExpression(objExpression), this.transformExpression(indexExpression)] - ); - const accessExpression = tstl.createTableIndexExpression(obj, index); - const operatorExpression = this.transformBinaryOperation( - accessExpression, - tstl.createParenthesizedExpression(right), - replacementOperator, - node - ); - const assignStatement = tstl.createAssignmentStatement(accessExpression, operatorExpression); - return tstl.createDoStatement([objAndIndexDeclaration, assignStatement]); - } else { - // Simple statements - // ${left} = ${left} ${replacementOperator} ${right} - const operatorExpression = this.transformBinaryOperation(left, right, replacementOperator, node); - return this.transformAssignment(lhs, operatorExpression); - } - } - - protected transformUnaryBitLibOperation( - node: ts.Node, - expression: tstl.Expression, - operator: tstl.UnaryBitwiseOperator, - lib: string - ): ExpressionVisitResult { - let bitFunction: string; - switch (operator) { - case tstl.SyntaxKind.BitwiseNotOperator: - bitFunction = "bnot"; - break; - default: - throw TSTLErrors.UnsupportedKind("unary bitwise operator", operator, node); - } - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier(lib), tstl.createStringLiteral(bitFunction)), - [expression], - node - ); - } - - protected transformUnaryBitOperation( - node: ts.Node, - expression: tstl.Expression, - operator: tstl.UnaryBitwiseOperator - ): ExpressionVisitResult { - switch (this.luaTarget) { - case LuaTarget.Lua51: - throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); - - case LuaTarget.Lua52: - return this.transformUnaryBitLibOperation(node, expression, operator, "bit32"); - - case LuaTarget.LuaJIT: - return this.transformUnaryBitLibOperation(node, expression, operator, "bit"); - - default: - return tstl.createUnaryExpression(expression, operator, node); - } - } - - protected transformBinaryBitLibOperation( - node: ts.Node, - left: tstl.Expression, - right: tstl.Expression, - operator: ts.BinaryOperator, - lib: string - ): ExpressionVisitResult { - let bitFunction: string; - switch (operator) { - case ts.SyntaxKind.AmpersandToken: - bitFunction = "band"; - break; - case ts.SyntaxKind.BarToken: - bitFunction = "bor"; - break; - case ts.SyntaxKind.CaretToken: - bitFunction = "bxor"; - break; - case ts.SyntaxKind.LessThanLessThanToken: - bitFunction = "lshift"; - break; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - bitFunction = "rshift"; - break; - case ts.SyntaxKind.GreaterThanGreaterThanToken: - bitFunction = "arshift"; - break; - default: - throw TSTLErrors.UnsupportedKind("binary bitwise operator", operator, node); - } - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier(lib), tstl.createStringLiteral(bitFunction)), - [left, right], - node - ); - } - - protected transformBinaryBitOperation( - node: ts.Node, - left: tstl.Expression, - right: tstl.Expression, - operator: ts.BinaryOperator - ): ExpressionVisitResult { - switch (this.luaTarget) { - case LuaTarget.Lua51: - throw TSTLErrors.UnsupportedForTarget("Bitwise operations", this.luaTarget, node); - - case LuaTarget.Lua52: - return this.transformBinaryBitLibOperation(node, left, right, operator, "bit32"); - - case LuaTarget.LuaJIT: - return this.transformBinaryBitLibOperation(node, left, right, operator, "bit"); - - default: - const luaOperator = this.transformBinaryOperator(operator, node); - return tstl.createBinaryExpression(left, right, luaOperator, node); - } - } - - protected transformProtectedConditionalExpression(expression: ts.ConditionalExpression): tstl.CallExpression { - const condition = tstl.createParenthesizedExpression(this.transformExpression(expression.condition)); - const val1 = this.transformExpression(expression.whenTrue); - const val2 = this.transformExpression(expression.whenFalse); - - const val1Function = this.wrapInFunctionCall(val1); - const val2Function = this.wrapInFunctionCall(val2); - - // (condition and (() => v1) or (() => v2))() - const conditionAnd = tstl.createBinaryExpression(condition, val1Function, tstl.SyntaxKind.AndOperator); - const orExpression = tstl.createBinaryExpression(conditionAnd, val2Function, tstl.SyntaxKind.OrOperator); - return tstl.createCallExpression(tstl.createParenthesizedExpression(orExpression), [], expression); - } - - public transformConditionalExpression(expression: ts.ConditionalExpression): ExpressionVisitResult { - const isStrict = this.options.strict === true || this.options.strictNullChecks === true; - if (tsHelper.isFalsible(this.checker.getTypeAtLocation(expression.whenTrue), isStrict)) { - return this.transformProtectedConditionalExpression(expression); - } - const condition = tstl.createParenthesizedExpression(this.transformExpression(expression.condition)); - const val1 = this.transformExpression(expression.whenTrue); - const val2 = this.transformExpression(expression.whenFalse); - - // condition and v1 or v2 - const conditionAnd = tstl.createBinaryExpression(condition, val1, tstl.SyntaxKind.AndOperator); - return tstl.createBinaryExpression(conditionAnd, val2, tstl.SyntaxKind.OrOperator, expression); - } - - public transformPostfixUnaryExpression(expression: ts.PostfixUnaryExpression): ExpressionVisitResult { - switch (expression.operator) { - case ts.SyntaxKind.PlusPlusToken: - return this.transformCompoundAssignmentExpression( - expression, - expression.operand, - ts.createLiteral(1), - ts.SyntaxKind.PlusToken, - true - ); - - case ts.SyntaxKind.MinusMinusToken: - return this.transformCompoundAssignmentExpression( - expression, - expression.operand, - ts.createLiteral(1), - ts.SyntaxKind.MinusToken, - true - ); - - default: - throw TSTLErrors.UnsupportedKind("unary postfix operator", expression.operator, expression); - } - } - - public transformPrefixUnaryExpression(expression: ts.PrefixUnaryExpression): ExpressionVisitResult { - switch (expression.operator) { - case ts.SyntaxKind.PlusPlusToken: - return this.transformCompoundAssignmentExpression( - expression, - expression.operand, - ts.createLiteral(1), - ts.SyntaxKind.PlusToken, - false - ); - - case ts.SyntaxKind.MinusMinusToken: - return this.transformCompoundAssignmentExpression( - expression, - expression.operand, - ts.createLiteral(1), - ts.SyntaxKind.MinusToken, - false - ); - - case ts.SyntaxKind.PlusToken: - return this.transformExpression(expression.operand); - - case ts.SyntaxKind.MinusToken: - return tstl.createUnaryExpression( - this.transformExpression(expression.operand), - tstl.SyntaxKind.NegationOperator - ); - - case ts.SyntaxKind.ExclamationToken: - return tstl.createUnaryExpression( - this.transformExpression(expression.operand), - tstl.SyntaxKind.NotOperator - ); - - case ts.SyntaxKind.TildeToken: - return this.transformUnaryBitOperation( - expression, - this.transformExpression(expression.operand), - tstl.SyntaxKind.BitwiseNotOperator - ); - - default: - throw TSTLErrors.UnsupportedKind("unary prefix operator", expression.operator, expression); - } - } - - public transformArrayLiteral(expression: ts.ArrayLiteralExpression): ExpressionVisitResult { - const values = expression.elements.map(e => - tstl.createTableFieldExpression(this.transformExpression(e), undefined, e) - ); - - return tstl.createTableExpression(values, expression); - } - - public transformObjectLiteral(expression: ts.ObjectLiteralExpression): ExpressionVisitResult { - let properties: tstl.TableFieldExpression[] = []; - const tableExpressions: tstl.Expression[] = []; - // Add all property assignments - expression.properties.forEach(element => { - const name = element.name ? this.transformPropertyName(element.name) : undefined; - if (ts.isPropertyAssignment(element)) { - const expression = this.transformExpression(element.initializer); - properties.push(tstl.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { - const valueSymbol = this.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - this.trackSymbolReference(valueSymbol, element.name); - } - const identifier = this.createShorthandIdentifier(valueSymbol, element.name); - properties.push(tstl.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { - const expression = this.transformFunctionExpression(element); - properties.push(tstl.createTableFieldExpression(expression, name, element)); - } else if (ts.isSpreadAssignment(element)) { - // Create a table for preceding properties to preserve property order - // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) - if (properties.length > 0) { - const tableExpression = tstl.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); - } - properties = []; - - const type = this.checker.getTypeAtLocation(element.expression); - let tableExpression: tstl.Expression; - if (type && tsHelper.isArrayType(type, this.checker, this.program)) { - tableExpression = this.transformLuaLibFunction( - LuaLibFeature.ArrayToObject, - element.expression, - this.transformExpression(element.expression) - ); - } else { - tableExpression = this.transformExpression(element.expression); - } - tableExpressions.push(tableExpression); - } else { - throw TSTLErrors.UnsupportedKind("object literal element", element.kind, expression); - } - }); - - if (tableExpressions.length === 0) { - return tstl.createTableExpression(properties, expression); - } else { - if (properties.length > 0) { - const tableExpression = tstl.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); - } - - if (tableExpressions[0].kind !== tstl.SyntaxKind.TableExpression) { - tableExpressions.unshift(tstl.createTableExpression(undefined, expression)); - } - - return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...tableExpressions); - } - } - - public transformOmittedExpression(node: ts.OmittedExpression): ExpressionVisitResult { - const isWithinBindingAssignmentStatement = tsHelper.isWithinLiteralAssignmentStatement(node); - return isWithinBindingAssignmentStatement ? tstl.createAnonymousIdentifier() : tstl.createNilLiteral(node); - } - - public transformDeleteExpression(expression: ts.DeleteExpression): ExpressionVisitResult { - const lhs = this.transformExpression(expression.expression) as tstl.AssignmentLeftHandSideExpression; - const assignment = tstl.createAssignmentStatement(lhs, tstl.createNilLiteral(), expression); - - return this.createImmediatelyInvokedFunctionExpression( - [assignment], - [tstl.createBooleanLiteral(true)], - expression - ); - } - - public transformFunctionExpression(node: ts.FunctionLikeDeclaration): ExpressionVisitResult { - const type = this.checker.getTypeAtLocation(node); - - let context: tstl.Identifier | undefined; - if (tsHelper.getFunctionContextType(type, this.program) !== tsHelper.ContextType.Void) { - if (ts.isArrowFunction(node)) { - // dummy context for arrow functions with parameters - if (node.parameters.length > 0) { - context = tstl.createAnonymousIdentifier(); - } - } else { - // self context - context = this.createSelfIdentifier(); - } - } - - // Build parameter string - const [paramNames, dotsLiteral, spreadIdentifier] = this.transformParameters(node.parameters, context); - - let flags = tstl.FunctionExpressionFlags.None; - - if (node.body === undefined) { - throw TSTLErrors.UnsupportedFunctionWithoutBody(node); - } - - let body: ts.Block; - if (ts.isBlock(node.body)) { - body = node.body; - } else { - const returnExpression = ts.createReturn(node.body); - body = ts.createBlock([returnExpression]); - returnExpression.parent = body; - if (node.body) { - body.parent = node.body.parent; - } - flags |= tstl.FunctionExpressionFlags.Inline; - } - - const [transformedBody, scope] = this.transformFunctionBody(node.parameters, body, spreadIdentifier); - - const functionExpression = tstl.createFunctionExpression( - tstl.createBlock(transformedBody), - paramNames, - dotsLiteral, - spreadIdentifier, - flags, - node - ); - - //Handle named function expressions which reference themselves - if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) { - const symbol = this.checker.getSymbolAtLocation(node.name); - if (symbol) { - const symbolId = this.symbolIds.get(symbol); - //Only wrap if the name is actually referenced inside the function - if (symbolId !== undefined && scope.referencedSymbols.has(symbolId)) { - const nameIdentifier = this.transformIdentifier(node.name); - return this.createImmediatelyInvokedFunctionExpression( - [tstl.createVariableDeclarationStatement(nameIdentifier, functionExpression)], - tstl.cloneIdentifier(nameIdentifier) - ); - } - } - } - - return functionExpression; - } - - public transformNewExpression(node: ts.NewExpression): ExpressionVisitResult { - const name = this.transformExpression(node.expression); - const signature = this.checker.getResolvedSignature(node); - const params = node.arguments - ? this.transformArguments(node.arguments, signature) - : [tstl.createBooleanLiteral(true)]; - - const type = this.checker.getTypeAtLocation(node); - const classDecorators = tsHelper.getCustomDecorators(type, this.checker); - - this.checkForLuaLibType(type); - - if (classDecorators.has(DecoratorKind.Extension) || classDecorators.has(DecoratorKind.MetaExtension)) { - throw TSTLErrors.InvalidNewExpressionOnExtension(node); - } - - if (classDecorators.has(DecoratorKind.CustomConstructor)) { - const customDecorator = classDecorators.get(DecoratorKind.CustomConstructor); - if (customDecorator === undefined || customDecorator.args[0] === undefined) { - throw TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, node); - } - - return tstl.createCallExpression( - tstl.createIdentifier(customDecorator.args[0]), - this.transformArguments(node.arguments || []), - node - ); - } - - if (classDecorators.has(DecoratorKind.LuaTable)) { - if (node.arguments && node.arguments.length > 0) { - throw TSTLErrors.ForbiddenLuaTableUseException( - "No parameters are allowed when constructing a LuaTable object.", - node - ); - } else { - return tstl.createTableExpression(); - } - } - - return tstl.createCallExpression( - tstl.createTableIndexExpression(name, tstl.createStringLiteral("new")), - params, - node - ); - } - - public transformParenthesizedExpression(expression: ts.ParenthesizedExpression): ExpressionVisitResult { - return tstl.createParenthesizedExpression(this.transformExpression(expression.expression), expression); - } - - public transformSuperKeyword(expression: ts.SuperExpression): ExpressionVisitResult { - const classDeclaration = this.classStack[this.classStack.length - 1]; - const typeNode = tsHelper.getExtendedTypeNode(classDeclaration, this.checker); - if (typeNode === undefined) { - throw TSTLErrors.UnknownSuperType(expression); - } - - const extendsExpression = typeNode.expression; - let baseClassName: tstl.AssignmentLeftHandSideExpression | undefined; - if (ts.isIdentifier(extendsExpression)) { - const symbol = this.checker.getSymbolAtLocation(extendsExpression); - if (symbol && !this.isSymbolExported(symbol)) { - // Use "baseClassName" if base is a simple identifier - baseClassName = this.transformIdentifier(extendsExpression); - } - } - if (!baseClassName) { - if (classDeclaration.name === undefined) { - throw TSTLErrors.MissingClassName(expression); - } - - // Use "className.____super" if the base is not a simple identifier - baseClassName = tstl.createTableIndexExpression( - this.transformIdentifier(classDeclaration.name), - tstl.createStringLiteral("____super"), - expression - ); - } - return tstl.createTableIndexExpression(baseClassName, tstl.createStringLiteral("prototype")); - } - - public transformCallExpression(expression: ts.CallExpression): ExpressionVisitResult { - // Check for calls on primitives to override - let parameters: tstl.Expression[] = []; - - const isTupleReturn = tsHelper.isTupleReturnCall(expression, this.checker); - const isTupleReturnForward = - expression.parent && - ts.isReturnStatement(expression.parent) && - tsHelper.isInTupleReturnFunction(expression, this.checker); - const isInDestructingAssignment = tsHelper.isInDestructingAssignment(expression); - const isInSpread = expression.parent && ts.isSpreadElement(expression.parent); - const returnValueIsUsed = expression.parent && !ts.isExpressionStatement(expression.parent); - const wrapResult = - isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment && !isInSpread && returnValueIsUsed; - - if (ts.isPropertyAccessExpression(expression.expression)) { - const result = this.transformPropertyCall(expression); - return wrapResult ? this.wrapInTable(result) : result; - } - - if (ts.isElementAccessExpression(expression.expression)) { - const result = this.transformElementCall(expression); - return wrapResult ? this.wrapInTable(result) : result; - } - - const signature = this.checker.getResolvedSignature(expression); - - // Handle super calls properly - if (expression.expression.kind === ts.SyntaxKind.SuperKeyword) { - parameters = this.transformArguments(expression.arguments, signature, ts.createThis()); - - return tstl.createCallExpression( - tstl.createTableIndexExpression( - this.transformSuperKeyword(ts.createSuper()), - tstl.createStringLiteral("____constructor") - ), - parameters - ); - } - - const expressionType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isStandardLibraryType(expressionType, undefined, this.program)) { - this.checkForLuaLibType(expressionType); - const result = this.transformGlobalFunctionCall(expression); - if (result) { - return result; - } - } - - const callPath = this.transformExpression(expression.expression); - const signatureDeclaration = signature && signature.getDeclaration(); - if ( - signatureDeclaration && - tsHelper.getDeclarationContextType(signatureDeclaration, this.program) === tsHelper.ContextType.Void - ) { - parameters = this.transformArguments(expression.arguments, signature); - } else { - const context = this.isStrict ? ts.createNull() : ts.createIdentifier("_G"); - parameters = this.transformArguments(expression.arguments, signature, context); - } - - const callExpression = tstl.createCallExpression(callPath, parameters, expression); - return wrapResult ? this.wrapInTable(callExpression) : callExpression; - } - - protected transformGlobalFunctionCall(node: ts.CallExpression): tstl.Expression | undefined { - const signature = this.checker.getResolvedSignature(node); - const parameters = this.transformArguments(node.arguments, signature); - - const expressionType = this.checker.getTypeAtLocation(node.expression); - const name = expressionType.symbol.name; - switch (name) { - case "SymbolConstructor": - return this.transformLuaLibFunction(LuaLibFeature.Symbol, node, ...parameters); - case "NumberConstructor": - return this.transformLuaLibFunction(LuaLibFeature.Number, node, ...parameters); - case "isNaN": - case "isFinite": - const numberParameters = tsHelper.isNumberType(expressionType, this.checker, this.program) - ? parameters - : [this.transformLuaLibFunction(LuaLibFeature.Number, undefined, ...parameters)]; - - return this.transformLuaLibFunction( - name === "isNaN" ? LuaLibFeature.NumberIsNaN : LuaLibFeature.NumberIsFinite, - node, - ...numberParameters - ); - } - } - - public transformPropertyCall(node: ts.CallExpression): ExpressionVisitResult { - let parameters: tstl.Expression[] = []; - - // Check if call is actually on a property access expression - if (!ts.isPropertyAccessExpression(node.expression)) { - throw TSTLErrors.InvalidPropertyCall(node); - } - - // If the function being called is of type owner.func, get the type of owner - const ownerType = this.checker.getTypeAtLocation(node.expression.expression); - - const signature = this.checker.getResolvedSignature(node); - - if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { - return this.transformMathCallExpression(node); - } - - if (tsHelper.isStandardLibraryType(ownerType, "Console", this.program)) { - return this.transformConsoleCallExpression(node); - } - - if (tsHelper.isStandardLibraryType(ownerType, "StringConstructor", this.program)) { - return tstl.createCallExpression( - this.transformStringExpression(node.expression.name), - this.transformArguments(node.arguments, signature), - node - ); - } - - if (tsHelper.isStandardLibraryType(ownerType, "ObjectConstructor", this.program)) { - return this.transformObjectCallExpression(node); - } - - if (tsHelper.isStandardLibraryType(ownerType, "SymbolConstructor", this.program)) { - return this.transformSymbolCallExpression(node); - } - - if (tsHelper.isStandardLibraryType(ownerType, "NumberConstructor", this.program)) { - return this.transformNumberExpression(node); - } - - const classDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); - - if (classDecorators.has(DecoratorKind.LuaTable)) { - return this.transformLuaTableCallExpression(node); - } - - if (tsHelper.isStringType(ownerType, this.checker, this.program)) { - return this.transformStringCallExpression(node); - } - - if (tsHelper.isNumberType(ownerType, this.checker, this.program)) { - return this.transformNumberCallExpression(node); - } - - // if ownerType is a array, use only supported functions - if (tsHelper.isExplicitArrayType(ownerType, this.checker, this.program)) { - return this.transformArrayCallExpression(node); - } - - // if ownerType inherits from an array, use array calls where appropriate - if ( - tsHelper.isArrayType(ownerType, this.checker, this.program) && - tsHelper.isDefaultArrayCallMethodName(node.expression.name.text) - ) { - return this.transformArrayCallExpression(node); - } - - if (tsHelper.isFunctionType(ownerType, this.checker)) { - return this.transformFunctionCallExpression(node); - } - - // Get the type of the function - if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { - // Super calls take the format of super.call(self,...) - parameters = this.transformArguments(node.arguments, signature, ts.createThis()); - return tstl.createCallExpression(this.transformExpression(node.expression), parameters); - } else { - // Replace last . with : here - const name = node.expression.name.text; - if (name === "toString") { - const toStringIdentifier = tstl.createIdentifier("tostring"); - return tstl.createCallExpression( - toStringIdentifier, - [this.transformExpression(node.expression.expression)], - node - ); - } else if (name === "hasOwnProperty") { - const expr = this.transformExpression(node.expression.expression); - parameters = this.transformArguments(node.arguments, signature); - const rawGetIdentifier = tstl.createIdentifier("rawget"); - const rawGetCall = tstl.createCallExpression(rawGetIdentifier, [expr, ...parameters]); - return tstl.createParenthesizedExpression( - tstl.createBinaryExpression( - rawGetCall, - tstl.createNilLiteral(), - tstl.SyntaxKind.InequalityOperator, - node - ) - ); - } else { - const parameters = this.transformArguments(node.arguments, signature); - const signatureDeclaration = signature && signature.getDeclaration(); - if ( - !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void - ) { - // table:name() - return this.transformContextualCallExpression(node, parameters); - } else { - let table = this.transformExpression(node.expression.expression); - if (tstl.isTableExpression(table)) { - table = tstl.createParenthesizedExpression(table); - } - - // table.name() - const callPath = tstl.createTableIndexExpression( - table, - tstl.createStringLiteral(name), - node.expression - ); - return tstl.createCallExpression(callPath, parameters, node); - } - } - } - } - - public transformElementCall(node: ts.CallExpression): ExpressionVisitResult { - if (!ts.isElementAccessExpression(node.expression) && !ts.isPropertyAccessExpression(node.expression)) { - throw TSTLErrors.InvalidElementCall(node); - } - - const ownerType = this.checker.getTypeAtLocation(node.expression.expression); - const ownerDecorators = tsHelper.getCustomDecorators(ownerType, this.checker); - - if (ownerDecorators.has(DecoratorKind.LuaTable)) { - return this.transformLuaTableCallExpression(node); - } - - const signature = this.checker.getResolvedSignature(node); - const signatureDeclaration = signature && signature.getDeclaration(); - const parameters = this.transformArguments(node.arguments, signature); - if ( - !signatureDeclaration || - tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void - ) { - // A contextual parameter must be given to this call expression - return this.transformContextualCallExpression(node, parameters); - } else { - // No context - let expression = this.transformExpression(node.expression); - if (tstl.isTableExpression(expression)) { - expression = tstl.createParenthesizedExpression(expression); - } - return tstl.createCallExpression(expression, parameters); - } - } - - public transformContextualCallExpression( - node: ts.CallExpression | ts.TaggedTemplateExpression, - transformedArguments: tstl.Expression[] - ): ExpressionVisitResult { - const left = ts.isCallExpression(node) ? node.expression : node.tag; - if ( - ts.isPropertyAccessExpression(left) && - !luaKeywords.has(left.name.text) && - tsHelper.isValidLuaIdentifier(left.name.text) - ) { - // table:name() - let table = this.transformExpression(left.expression); - if (tstl.isTableExpression(table)) { - table = tstl.createParenthesizedExpression(table); - } - return tstl.createMethodCallExpression( - table, - this.transformIdentifier(left.name), - transformedArguments, - node - ); - } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { - const context = this.transformExpression(left.expression); - if (tsHelper.isExpressionWithEvaluationEffect(left.expression)) { - // Inject context parameter - transformedArguments.unshift(tstl.createIdentifier("____self")); - - // Cache left-side if it has effects - //(function() local ____self = context; return ____self[argument](parameters); end)() - const argument = ts.isElementAccessExpression(left) - ? this.transformElementAccessArgument(left) - : tstl.createStringLiteral(left.name.text); - const selfIdentifier = tstl.createIdentifier("____self"); - const selfAssignment = tstl.createVariableDeclarationStatement(selfIdentifier, context); - const index = tstl.createTableIndexExpression(selfIdentifier, argument); - const callExpression = tstl.createCallExpression(index, transformedArguments); - return this.createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); - } else { - const expression = this.transformExpression(left); - return tstl.createCallExpression(expression, [context, ...transformedArguments]); - } - } else if (ts.isIdentifier(left)) { - const context = this.isStrict ? tstl.createNilLiteral() : tstl.createIdentifier("_G"); - transformedArguments.unshift(context); - const expression = this.transformExpression(left); - return tstl.createCallExpression(expression, transformedArguments, node); - } else { - throw TSTLErrors.UnsupportedKind("Left Hand Side Call Expression", left.kind, left); - } - } - - protected transformArguments( - params: readonly ts.Expression[], - sig?: ts.Signature, - context?: T - ): tstl.Expression[] { - const parameters: tstl.Expression[] = []; - - // Add context as first param if present - if (context) { - parameters.push(this.transformExpression(context)); - } - - if (sig && sig.parameters.length >= params.length) { - for (let i = 0; i < params.length; ++i) { - const param = params[i]; - const paramType = this.checker.getTypeAtLocation(param); - const sigType = this.checker.getTypeAtLocation(sig.parameters[i].valueDeclaration); - this.validateFunctionAssignment(param, paramType, sigType, sig.parameters[i].name); - - parameters.push(this.transformExpression(param)); - } - } else { - parameters.push(...params.map(param => this.transformExpression(param))); - } - - return parameters; - } - - public transformPropertyAccessExpression(expression: ts.PropertyAccessExpression): ExpressionVisitResult { - const property = expression.name.text; - - const constEnumValue = this.tryGetConstEnumValue(expression); - if (constEnumValue) { - return constEnumValue; - } - - // Check for primitive types to override - const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isStringType(type, this.checker, this.program)) { - return this.transformStringProperty(expression); - } else if (tsHelper.isArrayType(type, this.checker, this.program)) { - const arrayPropertyAccess = this.transformArrayProperty(expression); - if (arrayPropertyAccess) { - return arrayPropertyAccess; - } - } - - this.checkForLuaLibType(type); - - const decorators = tsHelper.getCustomDecorators(type, this.checker); - // Do not output path for member only enums - if (decorators.has(DecoratorKind.CompileMembersOnly)) { - if (ts.isPropertyAccessExpression(expression.expression)) { - // in case of ...x.enum.y transform to ...x.y - return tstl.createTableIndexExpression( - this.transformExpression(expression.expression.expression), - tstl.createStringLiteral(property), - expression - ); - } else { - return tstl.createIdentifier(property, expression); - } - } - - if (decorators.has(DecoratorKind.LuaTable)) { - return this.transformLuaTableProperty(expression); - } - - // Catch math expressions - if (ts.isIdentifier(expression.expression)) { - const ownerType = this.checker.getTypeAtLocation(expression.expression); - - if (tsHelper.isStandardLibraryType(ownerType, "Math", this.program)) { - return this.transformMathExpression(expression.name); - } else if (tsHelper.isStandardLibraryType(ownerType, "Symbol", this.program)) { - // Pull in Symbol lib - this.importLuaLibFeature(LuaLibFeature.Symbol); - } - } - - let callPath = this.transformExpression(expression.expression); - if (tstl.isTableExpression(callPath)) { - callPath = tstl.createParenthesizedExpression(callPath); - } - return tstl.createTableIndexExpression(callPath, tstl.createStringLiteral(property), expression); - } - - // Transpile a Math._ property - protected transformMathExpression(identifier: ts.Identifier): tstl.Expression { - const name = identifier.text; - switch (name) { - case "PI": - const property = tstl.createStringLiteral("pi"); - const math = tstl.createIdentifier("math"); - return tstl.createTableIndexExpression(math, property, identifier); - - case "E": - case "LN10": - case "LN2": - case "LOG10E": - case "LOG2E": - case "SQRT1_2": - case "SQRT2": - return tstl.createNumericLiteral(Math[name], identifier); - - default: - throw TSTLErrors.UnsupportedProperty("Math", name, identifier); - } - } - - // Transpile a Math._ property - protected transformMathCallExpression(node: ts.CallExpression): tstl.Expression { - const expression = node.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(node); - const params = this.transformArguments(node.arguments, signature); - const expressionName = expression.name.text; - switch (expressionName) { - // math.tan(x / y) - case "atan2": { - const math = tstl.createIdentifier("math"); - const atan = tstl.createStringLiteral("atan"); - const div = tstl.createBinaryExpression(params[0], params[1], tstl.SyntaxKind.DivisionOperator); - return tstl.createCallExpression(tstl.createTableIndexExpression(math, atan), [div], node); - } - - // (math.log(x) / Math.LNe) - case "log10": - case "log2": { - const math = tstl.createIdentifier("math"); - const log1 = tstl.createTableIndexExpression(math, tstl.createStringLiteral("log")); - const logCall1 = tstl.createCallExpression(log1, params); - const e = tstl.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); - const div = tstl.createBinaryExpression(logCall1, e, tstl.SyntaxKind.DivisionOperator); - return tstl.createParenthesizedExpression(div, node); - } - - // math.log(1 + x) - case "log1p": { - const math = tstl.createIdentifier("math"); - const log = tstl.createStringLiteral("log"); - const one = tstl.createNumericLiteral(1); - const add = tstl.createBinaryExpression(one, params[0], tstl.SyntaxKind.AdditionOperator); - return tstl.createCallExpression(tstl.createTableIndexExpression(math, log), [add], node); - } - - // math.floor(x + 0.5) - case "round": { - const math = tstl.createIdentifier("math"); - const floor = tstl.createStringLiteral("floor"); - const half = tstl.createNumericLiteral(0.5); - const add = tstl.createBinaryExpression(params[0], half, tstl.SyntaxKind.AdditionOperator); - return tstl.createCallExpression(tstl.createTableIndexExpression(math, floor), [add], node); - } - - case "abs": - case "acos": - case "asin": - case "atan": - case "ceil": - case "cos": - case "exp": - case "floor": - case "log": - case "max": - case "min": - case "pow": - case "random": - case "sin": - case "sqrt": - case "tan": { - const math = tstl.createIdentifier("math"); - const method = tstl.createStringLiteral(expressionName); - return tstl.createCallExpression(tstl.createTableIndexExpression(math, method), params, node); - } - - default: - throw TSTLErrors.UnsupportedProperty("Math", expressionName, expression); - } - } - - // Transpile access of string properties, only supported properties are allowed - protected transformStringProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression { - switch (node.name.text) { - case "length": - let expression = this.transformExpression(node.expression); - if (ts.isTemplateExpression(node.expression)) { - expression = tstl.createParenthesizedExpression(expression); - } - return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); - default: - throw TSTLErrors.UnsupportedProperty("string", node.name.text, node); - } - } - - // Transpile access of array properties, only supported properties are allowed - protected transformArrayProperty(node: ts.PropertyAccessExpression): tstl.UnaryExpression | undefined { - switch (node.name.text) { - case "length": - let expression = this.transformExpression(node.expression); - if (tstl.isTableExpression(expression)) { - expression = tstl.createParenthesizedExpression(expression); - } - return tstl.createUnaryExpression(expression, tstl.SyntaxKind.LengthOperator, node); - default: - return undefined; - } - } - - protected transformLuaTableProperty(node: ts.PropertyAccessExpression): tstl.Expression { - const [luaTable, propertyName] = this.parseLuaTableExpression(node); - switch (propertyName) { - case "length": - const unaryExpression = tstl.createUnaryExpression(luaTable, tstl.SyntaxKind.LengthOperator, node); - return unaryExpression; - default: - throw TSTLErrors.UnsupportedProperty("LuaTable", propertyName, node); - } - } - - protected transformElementAccessArgument(expression: ts.ElementAccessExpression): tstl.Expression { - const index = this.transformExpression(expression.argumentExpression); - const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); - const type = this.checker.getTypeAtLocation(expression.expression); - if ( - tsHelper.isNumberType(argumentType, this.checker, this.program) && - tsHelper.isArrayType(type, this.checker, this.program) - ) { - return this.expressionPlusOne(index); - } else { - return index; - } - } - - public transformElementAccessExpression(expression: ts.ElementAccessExpression): ExpressionVisitResult { - let table = this.transformExpression(expression.expression); - if (tstl.isTableExpression(table)) { - table = tstl.createParenthesizedExpression(table); - } - - const constEnumValue = this.tryGetConstEnumValue(expression); - if (constEnumValue) { - return constEnumValue; - } - - const argumentType = this.checker.getTypeAtLocation(expression.argumentExpression); - const type = this.checker.getTypeAtLocation(expression.expression); - const decorators = tsHelper.getCustomDecorators(type, this.checker); - if (decorators.has(DecoratorKind.LuaTable)) { - throw TSTLErrors.UnsupportedKind("LuaTable access expression", expression.kind, expression); - } - - if ( - tsHelper.isNumberType(argumentType, this.checker, this.program) && - tsHelper.isStringType(type, this.checker, this.program) - ) { - const index = this.transformExpression(expression.argumentExpression); - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("string"), tstl.createStringLiteral("sub")), - [table, this.expressionPlusOne(index), this.expressionPlusOne(index)], - expression - ); - } - - return tstl.createTableIndexExpression(table, this.transformElementAccessArgument(expression), expression); - } - - private tryGetConstEnumValue( - node: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression - ): tstl.Expression | undefined { - const value = this.checker.getConstantValue(node); - if (typeof value === "string") { - return tstl.createStringLiteral(value, node); - } else if (typeof value === "number") { - return tstl.createNumericLiteral(value, node); - } - } - - protected transformStringCallExpression(node: ts.CallExpression): tstl.Expression { - const expression = node.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(node); - const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); - - const expressionName = expression.name.text; - switch (expressionName) { - case "replace": - return this.transformLuaLibFunction(LuaLibFeature.StringReplace, node, caller, ...params); - case "concat": - return this.transformLuaLibFunction(LuaLibFeature.StringConcat, node, caller, ...params); - case "indexOf": - const stringExpression = this.createStringCall( - "find", - node, - caller, - params[0], - params[1] ? this.expressionPlusOne(params[1]) : tstl.createNilLiteral(), - tstl.createBooleanLiteral(true) - ); - - return tstl.createParenthesizedExpression( - tstl.createBinaryExpression( - tstl.createParenthesizedExpression( - tstl.createBinaryExpression( - stringExpression, - tstl.createNumericLiteral(0), - tstl.SyntaxKind.OrOperator - ) - ), - tstl.createNumericLiteral(1), - tstl.SyntaxKind.SubtractionOperator, - node - ) - ); - case "substr": - if (node.arguments.length === 1) { - const argument = this.transformExpression(node.arguments[0]); - const arg1 = this.expressionPlusOne(argument); - return this.createStringCall("sub", node, caller, arg1); - } else { - const arg1 = params[0]; - const arg2 = params[1]; - const sumArg = tstl.createBinaryExpression( - tstl.createParenthesizedExpression(arg1), - tstl.createParenthesizedExpression(arg2), - tstl.SyntaxKind.AdditionOperator - ); - return this.createStringCall("sub", node, caller, this.expressionPlusOne(arg1), sumArg); - } - case "substring": - if (node.arguments.length === 1) { - const arg1 = this.expressionPlusOne(params[0]); - return this.createStringCall("sub", node, caller, arg1); - } else { - const arg1 = this.expressionPlusOne(params[0]); - const arg2 = params[1]; - return this.createStringCall("sub", node, caller, arg1, arg2); - } - case "slice": - if (node.arguments.length === 0) { - return caller; - } else if (node.arguments.length === 1) { - const arg1 = this.expressionPlusOne(params[0]); - return this.createStringCall("sub", node, caller, arg1); - } else { - const arg1 = this.expressionPlusOne(params[0]); - const arg2 = params[1]; - return this.createStringCall("sub", node, caller, arg1, arg2); - } - case "toLowerCase": - return this.createStringCall("lower", node, caller); - case "toUpperCase": - return this.createStringCall("upper", node, caller); - case "split": - return this.transformLuaLibFunction(LuaLibFeature.StringSplit, node, caller, ...params); - case "charAt": - const firstParamPlusOne = this.expressionPlusOne(params[0]); - return this.createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); - case "charCodeAt": { - const firstParamPlusOne = this.expressionPlusOne(params[0]); - return this.createStringCall("byte", node, caller, firstParamPlusOne); - } - case "startsWith": - return this.transformLuaLibFunction(LuaLibFeature.StringStartsWith, node, caller, ...params); - case "endsWith": - return this.transformLuaLibFunction(LuaLibFeature.StringEndsWith, node, caller, ...params); - case "repeat": - const math = tstl.createIdentifier("math"); - const floor = tstl.createStringLiteral("floor"); - const parameter = tstl.createCallExpression(tstl.createTableIndexExpression(math, floor), [params[0]]); - return this.createStringCall("rep", node, caller, parameter); - case "padStart": - return this.transformLuaLibFunction(LuaLibFeature.StringPadStart, node, caller, ...params); - case "padEnd": - return this.transformLuaLibFunction(LuaLibFeature.StringPadEnd, node, caller, ...params); - case "byte": - case "char": - case "dump": - case "find": - case "format": - case "gmatch": - case "gsub": - case "len": - case "lower": - case "match": - case "pack": - case "packsize": - case "rep": - case "reverse": - case "sub": - case "unpack": - case "upper": - // Allow lua's string instance methods - let stringVariable = this.transformExpression(expression.expression); - if (ts.isStringLiteralLike(expression.expression)) { - // "foo":method() needs to be ("foo"):method() - stringVariable = tstl.createParenthesizedExpression(stringVariable); - } - return tstl.createMethodCallExpression( - stringVariable, - this.transformIdentifier(expression.name), - params, - node - ); - default: - throw TSTLErrors.UnsupportedProperty("string", expressionName, node); - } - } - - protected createStringCall( - methodName: string, - tsOriginal: ts.Node, - ...params: tstl.Expression[] - ): tstl.CallExpression { - const stringIdentifier = tstl.createIdentifier("string"); - return tstl.createCallExpression( - tstl.createTableIndexExpression(stringIdentifier, tstl.createStringLiteral(methodName)), - params, - tsOriginal - ); - } - - protected transformNumberCallExpression(node: ts.CallExpression): tstl.Expression { - const expression = node.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(node); - const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); - - const expressionName = expression.name.text; - switch (expressionName) { - case "toString": - return params.length === 0 - ? tstl.createCallExpression(tstl.createIdentifier("tostring"), [caller], node) - : this.transformLuaLibFunction(LuaLibFeature.NumberToString, node, caller, ...params); - default: - throw TSTLErrors.UnsupportedProperty("number", expressionName, node); - } - } - - // Transpile a String._ property - protected transformStringExpression(identifier: ts.Identifier): ExpressionVisitResult { - const identifierString = identifier.text; - - switch (identifierString) { - case "fromCharCode": - return tstl.createTableIndexExpression( - tstl.createIdentifier("string"), - tstl.createStringLiteral("char") - ); - default: - throw TSTLErrors.UnsupportedProperty("String", identifierString, identifier); - } - } - - // Transpile an Object._ property - protected transformObjectCallExpression(expression: ts.CallExpression): ExpressionVisitResult { - const method = expression.expression as ts.PropertyAccessExpression; - const parameters = this.transformArguments(expression.arguments); - const methodName = method.name.text; - - switch (methodName) { - case "assign": - return this.transformLuaLibFunction(LuaLibFeature.ObjectAssign, expression, ...parameters); - case "entries": - return this.transformLuaLibFunction(LuaLibFeature.ObjectEntries, expression, ...parameters); - case "fromEntries": - return this.transformLuaLibFunction(LuaLibFeature.ObjectFromEntries, expression, ...parameters); - case "keys": - return this.transformLuaLibFunction(LuaLibFeature.ObjectKeys, expression, ...parameters); - case "values": - return this.transformLuaLibFunction(LuaLibFeature.ObjectValues, expression, ...parameters); - default: - throw TSTLErrors.UnsupportedProperty("Object", methodName, expression); - } - } - - protected transformConsoleCallExpression(expression: ts.CallExpression): ExpressionVisitResult { - const method = expression.expression as ts.PropertyAccessExpression; - const methodName = method.name.text; - const signature = this.checker.getResolvedSignature(expression); - - switch (methodName) { - case "log": - if (expression.arguments.length > 0 && this.isStringFormatTemplate(expression.arguments[0])) { - // print(string.format([arguments])) - const stringFormatCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("string"), - tstl.createStringLiteral("format") - ), - this.transformArguments(expression.arguments, signature) - ); - return tstl.createCallExpression(tstl.createIdentifier("print"), [stringFormatCall]); - } - // print([arguments]) - return tstl.createCallExpression( - tstl.createIdentifier("print"), - this.transformArguments(expression.arguments, signature) - ); - case "assert": - const args = this.transformArguments(expression.arguments, signature); - if (expression.arguments.length > 1 && this.isStringFormatTemplate(expression.arguments[1])) { - // assert([condition], string.format([arguments])) - const stringFormatCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("string"), - tstl.createStringLiteral("format") - ), - args.slice(1) - ); - return tstl.createCallExpression(tstl.createIdentifier("assert"), [args[0], stringFormatCall]); - } - // assert() - return tstl.createCallExpression(tstl.createIdentifier("assert"), args); - case "trace": - if (expression.arguments.length > 0 && this.isStringFormatTemplate(expression.arguments[0])) { - // print(debug.traceback(string.format([arguments]))) - const stringFormatCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("string"), - tstl.createStringLiteral("format") - ), - this.transformArguments(expression.arguments, signature) - ); - const debugTracebackCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("debug"), - tstl.createStringLiteral("traceback") - ), - [stringFormatCall] - ); - return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]); - } - // print(debug.traceback([arguments]))) - const debugTracebackCall = tstl.createCallExpression( - tstl.createTableIndexExpression( - tstl.createIdentifier("debug"), - tstl.createStringLiteral("traceback") - ), - this.transformArguments(expression.arguments, signature) - ); - return tstl.createCallExpression(tstl.createIdentifier("print"), [debugTracebackCall]); - default: - throw TSTLErrors.UnsupportedProperty("console", methodName, expression); - } - } - - protected isStringFormatTemplate(expression: ts.Expression): boolean { - return ts.isStringLiteral(expression) && expression.text.match(/\%/g) !== null; - } - - // Transpile a Symbol._ property - protected transformSymbolCallExpression(expression: ts.CallExpression): tstl.CallExpression { - const method = expression.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(expression); - const parameters = this.transformArguments(expression.arguments, signature); - const methodName = method.name.text; - - switch (methodName) { - case "for": - case "keyFor": - this.importLuaLibFeature(LuaLibFeature.SymbolRegistry); - const upperMethodName = methodName[0].toUpperCase() + methodName.slice(1); - const functionIdentifier = tstl.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); - return tstl.createCallExpression(functionIdentifier, parameters, expression); - default: - throw TSTLErrors.UnsupportedProperty("Symbol", methodName, expression); - } - } - - // Transpile a Number._ property - protected transformNumberExpression(expression: ts.CallExpression): tstl.CallExpression { - const method = expression.expression as ts.PropertyAccessExpression; - const parameters = this.transformArguments(expression.arguments); - const methodName = method.name.text; - - switch (methodName) { - case "isNaN": - return this.transformLuaLibFunction(LuaLibFeature.NumberIsNaN, expression, ...parameters); - case "isFinite": - return this.transformLuaLibFunction(LuaLibFeature.NumberIsFinite, expression, ...parameters); - default: - throw TSTLErrors.UnsupportedProperty("Number", methodName, expression); - } - } - - protected validateLuaTableCall( - methodName: string, - callArguments: ts.NodeArray, - original: ts.Node - ): void { - if (callArguments.some(argument => ts.isSpreadElement(argument))) { - throw TSTLErrors.ForbiddenLuaTableUseException("Arguments cannot be spread.", original); - } - - switch (methodName) { - case "get": - if (callArguments.length !== 1) { - throw TSTLErrors.ForbiddenLuaTableUseException("One parameter is required for get().", original); - } - break; - case "set": - if (callArguments.length !== 2) { - throw TSTLErrors.ForbiddenLuaTableUseException("Two parameters are required for set().", original); - } - break; - } - } - - protected transformLuaTableExpressionAsExpressionStatement(expression: ts.CallExpression): tstl.Statement { - const [luaTable, methodName] = this.parseLuaTableExpression(expression.expression); - this.validateLuaTableCall(methodName, expression.arguments, expression); - const signature = this.checker.getResolvedSignature(expression); - const params = this.transformArguments(expression.arguments, signature); - - switch (methodName) { - case "get": - return tstl.createVariableDeclarationStatement( - tstl.createAnonymousIdentifier(expression), - tstl.createTableIndexExpression(luaTable, params[0], expression), - expression - ); - case "set": - return tstl.createAssignmentStatement( - tstl.createTableIndexExpression(luaTable, params[0], expression), - params.splice(1), - expression - ); - default: - throw TSTLErrors.UnsupportedProperty("LuaTable", methodName, expression); - } - } - - protected transformLuaTableCallExpression(expression: ts.CallExpression): tstl.Expression { - const [luaTable, methodName] = this.parseLuaTableExpression(expression.expression); - this.validateLuaTableCall(methodName, expression.arguments, expression); - const signature = this.checker.getResolvedSignature(expression); - const params = this.transformArguments(expression.arguments, signature); - - switch (methodName) { - case "get": - return tstl.createTableIndexExpression(luaTable, params[0], expression); - default: - throw TSTLErrors.UnsupportedProperty("LuaTable", methodName, expression); - } - } - - protected transformArrayCallExpression(node: ts.CallExpression): tstl.CallExpression { - const expression = node.expression as ts.PropertyAccessExpression; - const signature = this.checker.getResolvedSignature(node); - const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); - const expressionName = expression.name.text; - switch (expressionName) { - case "concat": - return this.transformLuaLibFunction(LuaLibFeature.ArrayConcat, node, caller, ...params); - case "push": - return this.transformLuaLibFunction(LuaLibFeature.ArrayPush, node, caller, ...params); - case "reverse": - return this.transformLuaLibFunction(LuaLibFeature.ArrayReverse, node, caller); - case "shift": - return this.transformLuaLibFunction(LuaLibFeature.ArrayShift, node, caller); - case "unshift": - return this.transformLuaLibFunction(LuaLibFeature.ArrayUnshift, node, caller, ...params); - case "sort": - return this.transformLuaLibFunction(LuaLibFeature.ArraySort, node, caller, ...params); - case "pop": - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("remove")), - [caller], - node - ); - case "forEach": - return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, node, caller, ...params); - case "find": - return this.transformLuaLibFunction(LuaLibFeature.ArrayFind, node, caller, ...params); - case "findIndex": - return this.transformLuaLibFunction(LuaLibFeature.ArrayFindIndex, node, caller, ...params); - case "indexOf": - return this.transformLuaLibFunction(LuaLibFeature.ArrayIndexOf, node, caller, ...params); - case "map": - return this.transformLuaLibFunction(LuaLibFeature.ArrayMap, node, caller, ...params); - case "filter": - return this.transformLuaLibFunction(LuaLibFeature.ArrayFilter, node, caller, ...params); - case "reduce": - return this.transformLuaLibFunction(LuaLibFeature.ArrayReduce, node, caller, ...params); - case "reduceRight": - return this.transformLuaLibFunction(LuaLibFeature.ArrayReduceRight, node, caller, ...params); - case "some": - return this.transformLuaLibFunction(LuaLibFeature.ArraySome, node, caller, ...params); - case "every": - return this.transformLuaLibFunction(LuaLibFeature.ArrayEvery, node, caller, ...params); - case "slice": - return this.transformLuaLibFunction(LuaLibFeature.ArraySlice, node, caller, ...params); - case "splice": - return this.transformLuaLibFunction(LuaLibFeature.ArraySplice, node, caller, ...params); - case "join": - const defaultSeparatorLiteral = tstl.createStringLiteral(","); - const parameters = [ - caller, - node.arguments.length === 0 - ? defaultSeparatorLiteral - : tstl.createBinaryExpression(params[0], defaultSeparatorLiteral, tstl.SyntaxKind.OrOperator), - ]; - - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("concat")), - parameters, - node - ); - case "flat": - return this.transformLuaLibFunction(LuaLibFeature.ArrayFlat, node, caller, ...params); - case "flatMap": - return this.transformLuaLibFunction(LuaLibFeature.ArrayFlatMap, node, caller, ...params); - default: - throw TSTLErrors.UnsupportedProperty("array", expressionName, node); - } - } - - protected transformFunctionCallExpression(node: ts.CallExpression): tstl.CallExpression { - const expression = node.expression as ts.PropertyAccessExpression; - const callerType = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.getFunctionContextType(callerType, this.program) === tsHelper.ContextType.Void) { - throw TSTLErrors.UnsupportedSelfFunctionConversion(node); - } - const signature = this.checker.getResolvedSignature(node); - const params = this.transformArguments(node.arguments, signature); - const caller = this.transformExpression(expression.expression); - const expressionName = expression.name.text; - switch (expressionName) { - case "apply": - return this.transformLuaLibFunction(LuaLibFeature.FunctionApply, node, caller, ...params); - case "bind": - return this.transformLuaLibFunction(LuaLibFeature.FunctionBind, node, caller, ...params); - case "call": - return this.transformLuaLibFunction(LuaLibFeature.FunctionCall, node, caller, ...params); - default: - throw TSTLErrors.UnsupportedProperty("function", expressionName, node); - } - } - - public transformArrayBindingElement(name: ts.ArrayBindingElement | ts.Expression): ExpressionVisitResult { - if (ts.isOmittedExpression(name)) { - return this.transformOmittedExpression(name); - } else if (ts.isIdentifier(name)) { - return this.transformIdentifier(name); - } else if (ts.isBindingElement(name) && ts.isIdentifier(name.name)) { - return this.transformIdentifier(name.name); - } else { - throw TSTLErrors.UnsupportedKind("array binding expression", name.kind, name); - } - } - - public transformAssertionExpression(expression: ts.AssertionExpression): ExpressionVisitResult { - if (!ts.isConstTypeReference(expression.type)) { - this.validateFunctionAssignment( - expression, - this.checker.getTypeAtLocation(expression.expression), - this.checker.getTypeAtLocation(expression.type) - ); - } - - return this.transformExpression(expression.expression); - } - - public transformTypeOfExpression(expression: ts.TypeOfExpression): ExpressionVisitResult { - const innerExpression = this.transformExpression(expression.expression); - return this.transformLuaLibFunction(LuaLibFeature.TypeOf, expression, innerExpression); - } - - public transformSpreadElement(expression: ts.SpreadElement): ExpressionVisitResult { - const innerExpression = this.transformExpression(expression.expression); - if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) { - return innerExpression; - } - - if (ts.isIdentifier(expression.expression) && tsHelper.isVarArgType(expression.expression, this.checker)) { - return tstl.createDotsLiteral(expression); - } - - const type = this.checker.getTypeAtLocation(expression.expression); - if (tsHelper.isArrayType(type, this.checker, this.program)) { - return this.createUnpackCall(innerExpression, expression); - } - - return this.transformLuaLibFunction(LuaLibFeature.Spread, expression, innerExpression); - } - - public transformStringLiteral(literal: ts.StringLiteralLike): ExpressionVisitResult { - const text = tsHelper.escapeString(literal.text); - return tstl.createStringLiteral(text, literal); - } - - public transformNumericLiteral(literal: ts.NumericLiteral): ExpressionVisitResult { - const value = Number(literal.text); - return tstl.createNumericLiteral(value, literal); - } - - public transformTrueKeyword(trueKeyword: ts.BooleanLiteral): ExpressionVisitResult { - return tstl.createBooleanLiteral(true, trueKeyword); - } - - public transformFalseKeyword(falseKeyword: ts.BooleanLiteral): ExpressionVisitResult { - return tstl.createBooleanLiteral(false, falseKeyword); - } - - public transformNullOrUndefinedKeyword(originalNode: ts.Node): ExpressionVisitResult { - return tstl.createNilLiteral(originalNode); - } - - public transformThisKeyword(thisKeyword: ts.ThisExpression): ExpressionVisitResult { - return this.createSelfIdentifier(thisKeyword); - } - - public transformTaggedTemplateExpression(expression: ts.TaggedTemplateExpression): ExpressionVisitResult { - const strings: string[] = []; - const rawStrings: string[] = []; - const expressions: ts.Expression[] = []; - - if (ts.isTemplateExpression(expression.template)) { - // Expressions are in the string. - strings.push(expression.template.head.text); - rawStrings.push(tsHelper.getRawLiteral(expression.template.head)); - strings.push(...expression.template.templateSpans.map(span => span.literal.text)); - rawStrings.push(...expression.template.templateSpans.map(span => tsHelper.getRawLiteral(span.literal))); - expressions.push(...expression.template.templateSpans.map(span => span.expression)); - } else { - // No expressions are in the string. - strings.push(expression.template.text); - rawStrings.push(tsHelper.getRawLiteral(expression.template)); - } - - // Construct table with strings and literal strings - const stringTableLiteral = tstl.createTableExpression( - strings.map(partialString => tstl.createTableFieldExpression(tstl.createStringLiteral(partialString))) - ); - const rawStringArray = tstl.createTableExpression( - rawStrings.map(stringLiteral => tstl.createTableFieldExpression(tstl.createStringLiteral(stringLiteral))) - ); - stringTableLiteral.fields.push( - tstl.createTableFieldExpression(rawStringArray, tstl.createStringLiteral("raw")) - ); - - // Evaluate if there is a self parameter to be used. - const signature = this.checker.getResolvedSignature(expression); - const signatureDeclaration = signature && signature.getDeclaration(); - const useSelfParameter = - signatureDeclaration && - tsHelper.getDeclarationContextType(signatureDeclaration, this.program) !== tsHelper.ContextType.Void; - - // Argument evaluation. - const callArguments = this.transformArguments(expressions, signature); - callArguments.unshift(stringTableLiteral); - - if (useSelfParameter) { - return this.transformContextualCallExpression(expression, callArguments); - } - - const leftHandSideExpression = this.transformExpression(expression.tag); - return tstl.createCallExpression(leftHandSideExpression, callArguments); - } - - public transformTemplateExpression(expression: ts.TemplateExpression): ExpressionVisitResult { - const parts: tstl.Expression[] = []; - - const head = tsHelper.escapeString(expression.head.text); - if (head.length > 0) { - parts.push(tstl.createStringLiteral(head, expression.head)); - } - - expression.templateSpans.forEach(span => { - const expression = this.transformExpression(span.expression); - parts.push(this.wrapInToStringForConcat(expression)); - - const text = tsHelper.escapeString(span.literal.text); - if (text.length > 0) { - parts.push(tstl.createStringLiteral(text, span.literal)); - } - }); - - return parts.reduce((prev, current) => - tstl.createBinaryExpression(prev, current, tstl.SyntaxKind.ConcatOperator) - ); - } - - public transformPropertyName(propertyName: ts.PropertyName): ExpressionVisitResult { - if (ts.isComputedPropertyName(propertyName)) { - return this.transformExpression(propertyName.expression); - } else if (ts.isStringLiteral(propertyName)) { - return this.transformStringLiteral(propertyName); - } else if (ts.isNumericLiteral(propertyName)) { - const value = Number(propertyName.text); - return tstl.createNumericLiteral(value, propertyName); - } else { - return tstl.createStringLiteral(propertyName.text); - } - } - - public transformIdentifier(identifier: ts.Identifier): tstl.Identifier { - if (tsHelper.isForRangeType(identifier, this.checker)) { - const callExpression = tsHelper.findFirstNodeAbove(identifier, ts.isCallExpression); - if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { - throw TSTLErrors.InvalidForRangeCall( - identifier, - "@forRange function can only be used as an iterable in a for...of loop." - ); - } - } - - const text = this.hasUnsafeIdentifierName(identifier) ? this.createSafeName(identifier.text) : identifier.text; - - const symbolId = this.getIdentifierSymbolId(identifier); - return tstl.createIdentifier(text, identifier, symbolId, identifier.text); - } - - protected transformIdentifierExpression(expression: ts.Identifier): tstl.Expression { - const identifier = this.transformIdentifier(expression); - - const exportScope = this.getIdentifierExportScope(identifier); - if (exportScope) { - return this.createExportedIdentifier(identifier, exportScope); - } - - if (expression.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { - return tstl.createNilLiteral(); - } - - switch (expression.text) { - case "NaN": - return tstl.createParenthesizedExpression( - tstl.createBinaryExpression( - tstl.createNumericLiteral(0), - tstl.createNumericLiteral(0), - tstl.SyntaxKind.DivisionOperator, - expression - ) - ); - - case "Infinity": - const math = tstl.createIdentifier("math"); - const huge = tstl.createStringLiteral("huge"); - return tstl.createTableIndexExpression(math, huge, expression); - - case "globalThis": - return tstl.createIdentifier("_G", expression, this.getIdentifierSymbolId(expression)); - } - - return identifier; - } - - protected getSymbolFromIdentifier(identifier: tstl.Identifier): ts.Symbol | undefined { - if (identifier.symbolId !== undefined) { - const symbolInfo = this.symbolInfo.get(identifier.symbolId); - if (symbolInfo !== undefined) { - return symbolInfo.symbol; - } - } - return undefined; - } - - protected getIdentifierExportScope(identifier: tstl.Identifier): ts.SourceFile | ts.ModuleDeclaration | undefined { - const symbol = this.getSymbolFromIdentifier(identifier); - if (!symbol) { - return undefined; - } - - return this.getSymbolExportScope(symbol); - } - - protected isSymbolExported(symbol: ts.Symbol): boolean { - return ( - tsHelper.getExportedSymbolDeclaration(symbol) !== undefined || - // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') - this.isSymbolExportedFromScope(symbol, this.currentSourceFile) - ); - } - - protected isSymbolExportedFromScope(symbol: ts.Symbol, scope: ts.SourceFile | ts.ModuleDeclaration): boolean { - if (ts.isSourceFile(scope) && !tsHelper.isFileModule(scope)) { - return false; - } - - let scopeSymbol = this.checker.getSymbolAtLocation(scope); - if (scopeSymbol === undefined) { - scopeSymbol = this.checker.getTypeAtLocation(scope).getSymbol(); - } - - if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { - return false; - } - const scopeSymbolExports = scopeSymbol.exports; - - const it: Iterable = { - [Symbol.iterator]: () => scopeSymbolExports.values(), // Why isn't ts.SymbolTable.values() iterable? - }; - for (const exportedSymbol of it) { - if (exportedSymbol === symbol) { - return true; - } - } - return false; - } - - protected addExportToIdentifier(identifier: tstl.Identifier): tstl.AssignmentLeftHandSideExpression { - const exportScope = this.getIdentifierExportScope(identifier); - if (exportScope) { - return this.createExportedIdentifier(identifier, exportScope); - } - return identifier; - } - - protected createExportedIdentifier( - identifier: tstl.Identifier, - exportScope?: ts.SourceFile | ts.ModuleDeclaration - ): tstl.AssignmentLeftHandSideExpression { - if (!identifier.exportable) { - return identifier; - } - - const exportTable = - exportScope && ts.isModuleDeclaration(exportScope) - ? this.createModuleLocalNameIdentifier(exportScope) - : this.createExportsIdentifier(); - return tstl.createTableIndexExpression(exportTable, tstl.createStringLiteral(identifier.text)); - } - - protected createDefaultExportIdentifier(original: ts.Node): tstl.Identifier { - return tstl.createIdentifier("default", original); - } - - protected createDefaultExportStringLiteral(original: ts.Node): tstl.StringLiteral { - return tstl.createStringLiteral("default", original); - } - - protected getSymbolExportScope(symbol: ts.Symbol): ts.SourceFile | ts.ModuleDeclaration | undefined { - const exportedDeclaration = tsHelper.getExportedSymbolDeclaration(symbol); - if (!exportedDeclaration) { - return undefined; - } - - const scope = tsHelper.findFirstNodeAbove( - exportedDeclaration, - (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) - ); - if (!scope) { - return undefined; - } - - if (!this.isSymbolExportedFromScope(symbol, scope)) { - return undefined; - } - - return scope; - } - - protected parseLuaTableExpression(node: ts.LeftHandSideExpression): [tstl.Expression, string] { - if (ts.isPropertyAccessExpression(node)) { - return [this.transformExpression(node.expression), node.name.text]; - } else { - throw TSTLErrors.UnsupportedKind("LuaTable access expression", node.kind, node); - } - } - - protected transformLuaLibFunction( - func: LuaLibFeature, - tsParent?: ts.Expression, - ...params: tstl.Expression[] - ): tstl.CallExpression { - this.importLuaLibFeature(func); - const functionIdentifier = tstl.createIdentifier(`__TS__${func}`); - return tstl.createCallExpression(functionIdentifier, params, tsParent); - } - - protected checkForLuaLibType(type: ts.Type): void { - if (type.symbol) { - const name = this.checker.getFullyQualifiedName(type.symbol); - switch (name) { - case "Map": - this.importLuaLibFeature(LuaLibFeature.Map); - return; - case "Set": - this.importLuaLibFeature(LuaLibFeature.Set); - return; - case "WeakMap": - this.importLuaLibFeature(LuaLibFeature.WeakMap); - return; - case "WeakSet": - this.importLuaLibFeature(LuaLibFeature.WeakSet); - return; - } - - if (tsHelper.isBuiltinErrorTypeName(name)) { - this.importLuaLibFeature(LuaLibFeature.Error); - } - } - } - - protected importLuaLibFeature(feature: LuaLibFeature): void { - this.luaLibFeatureSet.add(feature); - } - - protected createImmediatelyInvokedFunctionExpression( - statements: tstl.Statement[], - result: tstl.Expression | tstl.Expression[], - tsOriginal?: ts.Node - ): tstl.CallExpression { - const body = statements ? statements.slice(0) : []; - body.push(tstl.createReturnStatement(Array.isArray(result) ? result : [result])); - const flags = statements.length === 0 ? tstl.FunctionExpressionFlags.Inline : tstl.FunctionExpressionFlags.None; - const iife = tstl.createFunctionExpression(tstl.createBlock(body), undefined, undefined, undefined, flags); - return tstl.createCallExpression(tstl.createParenthesizedExpression(iife), [], tsOriginal); - } - - protected createUnpackCall(expression: tstl.Expression | undefined, tsOriginal?: ts.Node): tstl.Expression { - switch (this.luaTarget) { - case LuaTarget.Lua51: - case LuaTarget.LuaJIT: - return tstl.createCallExpression( - tstl.createIdentifier("unpack"), - this.filterUndefined([expression]), - tsOriginal - ); - case LuaTarget.Lua52: - case LuaTarget.Lua53: - default: - return tstl.createCallExpression( - tstl.createTableIndexExpression(tstl.createIdentifier("table"), tstl.createStringLiteral("unpack")), - this.filterUndefined([expression]), - tsOriginal - ); - } - } - - protected createSelfIdentifier(tsOriginal?: ts.Node): tstl.Identifier { - return tstl.createIdentifier("self", tsOriginal, undefined, "this"); - } - - protected createExportsIdentifier(): tstl.Identifier { - return tstl.createIdentifier("____exports"); - } - - protected createLocalOrExportedOrGlobalDeclaration( - lhs: tstl.Identifier | tstl.Identifier[], - rhs?: tstl.Expression | tstl.Expression[], - tsOriginal?: ts.Node, - parent?: tstl.Node, - overrideExportScope?: ts.SourceFile | ts.ModuleDeclaration - ): tstl.Statement[] { - let declaration: tstl.VariableDeclarationStatement | undefined; - let assignment: tstl.AssignmentStatement | undefined; - - const functionDeclaration = tsOriginal && ts.isFunctionDeclaration(tsOriginal) ? tsOriginal : undefined; - - const identifiers = Array.isArray(lhs) ? lhs : [lhs]; - if (identifiers.length === 0) { - return []; - } - - const exportScope = overrideExportScope || this.getIdentifierExportScope(identifiers[0]); - if (exportScope) { - // exported - if (!rhs) { - return []; - } else { - assignment = tstl.createAssignmentStatement( - identifiers.map(i => this.createExportedIdentifier(i, exportScope)), - rhs, - tsOriginal, - parent - ); - } - } else { - const insideFunction = this.findScope(ScopeType.Function) !== undefined; - let isLetOrConst = false; - let isFirstDeclaration = true; // var can have multiple declarations for the same variable :/ - if (tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.parent) { - isLetOrConst = (tsOriginal.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0; - isFirstDeclaration = - isLetOrConst || tsHelper.isFirstDeclaration(tsOriginal, this.checker, this.currentSourceFile); - } - if ((this.isModule || this.currentNamespace || insideFunction || isLetOrConst) && isFirstDeclaration) { - // local - const isPossibleWrappedFunction = - !functionDeclaration && - tsOriginal && - ts.isVariableDeclaration(tsOriginal) && - tsOriginal.initializer && - tsHelper.isFunctionTypeAtLocation(tsOriginal.initializer, this.checker); - if (isPossibleWrappedFunction) { - // Split declaration and assignment for wrapped function types to allow recursion - declaration = tstl.createVariableDeclarationStatement(lhs, undefined, tsOriginal, parent); - assignment = tstl.createAssignmentStatement(lhs, rhs, tsOriginal, parent); - } else { - declaration = tstl.createVariableDeclarationStatement(lhs, rhs, tsOriginal, parent); - } - - if (!this.options.noHoisting) { - // Remember local variable declarations for hoisting later - const scope = - isLetOrConst || functionDeclaration - ? this.peekScope() - : this.findScope(ScopeType.Function | ScopeType.File); - - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } - scope.variableDeclarations.push(declaration); - } - } else if (rhs) { - // global - assignment = tstl.createAssignmentStatement(lhs, rhs, tsOriginal, parent); - } else { - return []; - } - } - - if (!this.options.noHoisting && functionDeclaration) { - // Remember function definitions for hoisting later - const functionSymbolId = (lhs as tstl.Identifier).symbolId; - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - if (functionSymbolId && scope.functionDefinitions) { - const definitions = scope.functionDefinitions.get(functionSymbolId); - if (definitions) { - definitions.definition = declaration || assignment; - } - } - } - - if (declaration && assignment) { - return [declaration, assignment]; - } else if (declaration) { - return [declaration]; - } else if (assignment) { - return [assignment]; - } else { - return []; - } - } - - protected validateFunctionAssignment(node: ts.Node, fromType: ts.Type, toType: ts.Type, toName?: string): void { - if (toType === fromType) { - return; - } - - if ((toType.flags & ts.TypeFlags.Any) !== 0) { - // Assigning to un-typed variable - return; - } - - // Use cache to avoid repeating check for same types (protects against infinite loop in recursive types) - let fromTypeCache = this.typeValidationCache.get(fromType); - if (fromTypeCache) { - if (fromTypeCache.has(toType)) { - return; - } - } else { - fromTypeCache = new Set(); - this.typeValidationCache.set(fromType, fromTypeCache); - } - fromTypeCache.add(toType); - - // Check function assignments - const fromContext = tsHelper.getFunctionContextType(fromType, this.program); - const toContext = tsHelper.getFunctionContextType(toType, this.program); - - if (fromContext === tsHelper.ContextType.Mixed || toContext === tsHelper.ContextType.Mixed) { - throw TSTLErrors.UnsupportedOverloadAssignment(node, toName); - } else if ( - fromContext !== toContext && - fromContext !== tsHelper.ContextType.None && - toContext !== tsHelper.ContextType.None - ) { - if (toContext === tsHelper.ContextType.Void) { - throw TSTLErrors.UnsupportedNoSelfFunctionConversion(node, toName); - } else { - throw TSTLErrors.UnsupportedSelfFunctionConversion(node, toName); - } - } - - const fromTypeNode = this.checker.typeToTypeNode(fromType); - const toTypeNode = this.checker.typeToTypeNode(toType); - if (!fromTypeNode || !toTypeNode) { - return; - } - - if ( - (ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && - (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode)) - ) { - // Recurse into arrays/tuples - const fromTypeArguments = (fromType as ts.TypeReference).typeArguments; - const toTypeArguments = (toType as ts.TypeReference).typeArguments; - - if (fromTypeArguments === undefined || toTypeArguments === undefined) { - return; - } - - const count = Math.min(fromTypeArguments.length, toTypeArguments.length); - for (let i = 0; i < count; ++i) { - this.validateFunctionAssignment(node, fromTypeArguments[i], toTypeArguments[i], toName); - } - } - - if ( - (toType.flags & ts.TypeFlags.Object) !== 0 && - ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0 && - toType.symbol && - toType.symbol.members && - fromType.symbol && - fromType.symbol.members - ) { - // Recurse into interfaces - toType.symbol.members.forEach((toMember, memberName) => { - if (fromType.symbol.members) { - const fromMember = fromType.symbol.members.get(memberName); - if (fromMember) { - const toMemberType = this.checker.getTypeOfSymbolAtLocation(toMember, node); - const fromMemberType = this.checker.getTypeOfSymbolAtLocation(fromMember, node); - this.validateFunctionAssignment( - node, - fromMemberType, - toMemberType, - toName ? `${toName}.${memberName}` : memberName.toString() - ); - } - } - }); - } - } - - protected validatePropertyAssignment(node: ts.Node): void { - if (ts.isBinaryExpression(node) && ts.isPropertyAccessExpression(node.left)) { - const leftType = this.checker.getTypeAtLocation(node.left.expression); - const decorators = tsHelper.getCustomDecorators(leftType, this.checker); - if (decorators.has(DecoratorKind.LuaTable)) { - switch (node.left.name.text) { - case "length": - throw TSTLErrors.ForbiddenLuaTableUseException( - `A LuaTable object's length cannot be re-assigned.`, - node - ); - } - } - } - } - - protected wrapInFunctionCall(expression: tstl.Expression): tstl.FunctionExpression { - const returnStatement = tstl.createReturnStatement([expression]); - return tstl.createFunctionExpression( - tstl.createBlock([returnStatement]), - undefined, - undefined, - undefined, - tstl.FunctionExpressionFlags.Inline - ); - } - - protected wrapInTable(...expressions: tstl.Expression[]): tstl.ParenthesizedExpression { - const fields = expressions.map(e => tstl.createTableFieldExpression(e)); - return tstl.createParenthesizedExpression(tstl.createTableExpression(fields)); - } - - protected wrapInToStringForConcat(expression: tstl.Expression): tstl.Expression { - if ( - tstl.isStringLiteral(expression) || - tstl.isNumericLiteral(expression) || - (tstl.isBinaryExpression(expression) && expression.operator === tstl.SyntaxKind.ConcatOperator) - ) { - return expression; - } - return tstl.createCallExpression(tstl.createIdentifier("tostring"), [expression]); - } - - protected expressionPlusOne(expression: tstl.Expression): tstl.Expression { - if (tstl.isNumericLiteral(expression)) { - const newNode = tstl.cloneNode(expression); - newNode.value += 1; - return newNode; - } - - if (tstl.isBinaryExpression(expression)) { - if ( - expression.operator === tstl.SyntaxKind.SubtractionOperator && - tstl.isNumericLiteral(expression.right) && - expression.right.value === 1 - ) { - return expression.left; - } - - expression = tstl.createParenthesizedExpression(expression); - } - - return tstl.createBinaryExpression(expression, tstl.createNumericLiteral(1), tstl.SyntaxKind.AdditionOperator); - } - - protected createShorthandIdentifier( - valueSymbol: ts.Symbol | undefined, - propertyIdentifier: ts.Identifier - ): tstl.Expression { - let name: string; - if (valueSymbol !== undefined) { - name = this.hasUnsafeSymbolName(valueSymbol, propertyIdentifier) - ? this.createSafeName(valueSymbol.name) - : valueSymbol.name; - } else { - const propertyName = propertyIdentifier.text; - if (luaKeywords.has(propertyName) || !tsHelper.isValidLuaIdentifier(propertyName)) { - // Catch ambient declarations of identifiers with bad names - throw TSTLErrors.InvalidAmbientIdentifierName(propertyIdentifier); - } - name = this.hasUnsafeIdentifierName(propertyIdentifier) ? this.createSafeName(propertyName) : propertyName; - } - - let identifier = this.transformIdentifierExpression(ts.createIdentifier(name)); - tstl.setNodeOriginal(identifier, propertyIdentifier); - if (valueSymbol !== undefined && tstl.isIdentifier(identifier)) { - identifier.symbolId = this.symbolIds.get(valueSymbol); - - const exportScope = this.getSymbolExportScope(valueSymbol); - if (exportScope) { - identifier = this.createExportedIdentifier(identifier, exportScope); - } - } - return identifier; - } - - protected isUnsafeName(name: string): boolean { - return luaKeywords.has(name) || luaBuiltins.has(name) || !tsHelper.isValidLuaIdentifier(name); - } - - protected hasUnsafeSymbolName(symbol: ts.Symbol, tsOriginal?: ts.Identifier): boolean { - const isLuaKeyword = luaKeywords.has(symbol.name); - const isInvalidIdentifier = !tsHelper.isValidLuaIdentifier(symbol.name); - // TODO rework once microsoft/TypeScript#24706 is fixed and remove check for symbol.declarations - const isAmbient = symbol.declarations && symbol.declarations.some(d => tsHelper.isAmbientNode(d)); - if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { - // Catch ambient declarations of identifiers with bad names - throw TSTLErrors.InvalidAmbientIdentifierName(tsOriginal || ts.createIdentifier(symbol.name)); - } - - if (this.isUnsafeName(symbol.name)) { - // only unsafe when non-ambient and not exported - return !isAmbient && !this.isSymbolExported(symbol); - } - return false; - } - - protected hasUnsafeIdentifierName(identifier: ts.Identifier): boolean { - const symbol = this.checker.getSymbolAtLocation(identifier); - if (symbol !== undefined) { - return this.hasUnsafeSymbolName(symbol, identifier); - } else if (luaKeywords.has(identifier.text) || !tsHelper.isValidLuaIdentifier(identifier.text)) { - throw TSTLErrors.InvalidAmbientIdentifierName(identifier); - } - return false; - } - - protected createSafeName(name: string): string { - return "____" + tsHelper.fixInvalidLuaIdentifier(name); - } - - protected trackSymbolReference(symbol: ts.Symbol, identifier: ts.Identifier): tstl.SymbolId | undefined { - // Track first time symbols are seen - let symbolId = this.symbolIds.get(symbol); - if (!symbolId) { - symbolId = this.genSymbolIdCounter++; - - const symbolInfo: SymbolInfo = { symbol, firstSeenAtPos: identifier.pos }; - this.symbolIds.set(symbol, symbolId); - this.symbolInfo.set(symbolId, symbolInfo); - } - - if (this.options.noHoisting) { - // Check for reference-before-declaration - const declaration = tsHelper.getFirstDeclaration(symbol, this.currentSourceFile); - if (declaration && identifier.pos < declaration.pos) { - throw TSTLErrors.ReferencedBeforeDeclaration(identifier); - } - } - - //Mark symbol as seen in all current scopes - for (const scope of this.scopeStack) { - if (!scope.referencedSymbols) { - scope.referencedSymbols = new Map(); - } - let references = scope.referencedSymbols.get(symbolId); - if (!references) { - references = []; - scope.referencedSymbols.set(symbolId, references); - } - references.push(identifier); - } - - return symbolId; - } - - protected getIdentifierSymbolId(identifier: ts.Identifier): tstl.SymbolId | undefined { - const symbol = this.checker.getSymbolAtLocation(identifier); - if (symbol) { - return this.trackSymbolReference(symbol, identifier); - } else { - return undefined; - } - } - - protected findScope(scopeTypes: ScopeType): Scope | undefined { - return this.scopeStack - .slice() - .reverse() - .find(s => (scopeTypes & s.type) !== 0); - } - - protected peekScope(): Scope | undefined { - return this.scopeStack[this.scopeStack.length - 1]; - } - - protected pushScope(scopeType: ScopeType): void { - this.scopeStack.push({ - type: scopeType, - id: this.genVarCounter, - }); - this.genVarCounter++; - } - - protected shouldHoist(symbolId: tstl.SymbolId, scope: Scope): boolean { - const symbolInfo = this.symbolInfo.get(symbolId); - if (!symbolInfo) { - return false; - } - - const declaration = tsHelper.getFirstDeclaration(symbolInfo.symbol, this.currentSourceFile); - if (!declaration) { - return false; - } - - if (symbolInfo.firstSeenAtPos < declaration.pos) { - return true; - } - - if (scope.functionDefinitions) { - for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { - if (functionDefinition.definition === undefined) { - throw TSTLErrors.UndefinedFunctionDefinition(functionSymbolId); - } - - const { line, column } = tstl.getOriginalPos(functionDefinition.definition); - if (line !== undefined && column !== undefined) { - const definitionPos = ts.getPositionOfLineAndCharacter(this.currentSourceFile, line, column); - if ( - functionSymbolId !== symbolId && // Don't recurse into self - declaration.pos < definitionPos && // Ignore functions before symbol declaration - functionDefinition.referencedSymbols.has(symbolId) && - this.shouldHoist(functionSymbolId, scope) - ) { - return true; - } - } - } - } - - return false; - } - - protected replaceStatementInParent(oldNode: tstl.Statement, newNode?: tstl.Statement): void { - if (!oldNode.parent) { - throw new Error("node has not yet been assigned a parent"); - } - - if (tstl.isBlock(oldNode.parent) || tstl.isDoStatement(oldNode.parent)) { - if (newNode) { - oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1, newNode); - } else { - oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1); - } - } else { - throw new Error("unexpected parent type"); - } - } - - protected hoistImportStatements(scope: Scope, statements: tstl.Statement[]): tstl.Statement[] { - if (!scope.importStatements) { - return statements; - } - - return [...scope.importStatements, ...statements]; - } - - protected hoistFunctionDefinitions(scope: Scope, statements: tstl.Statement[]): tstl.Statement[] { - if (!scope.functionDefinitions) { - return statements; - } - - const result = statements.slice(); - const hoistedFunctions: Array = []; - for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { - if (functionDefinition.definition === undefined) { - throw TSTLErrors.UndefinedFunctionDefinition(functionSymbolId); - } - - if (this.shouldHoist(functionSymbolId, scope)) { - const i = result.indexOf(functionDefinition.definition); - result.splice(i, 1); - hoistedFunctions.push(functionDefinition.definition); - } - } - if (hoistedFunctions.length > 0) { - result.unshift(...hoistedFunctions); - } - return result; - } - - protected hoistVariableDeclarations(scope: Scope, statements: tstl.Statement[]): tstl.Statement[] { - if (!scope.variableDeclarations) { - return statements; - } - - const result = statements.slice(); - const hoistedLocals: tstl.Identifier[] = []; - for (const declaration of scope.variableDeclarations) { - const symbols = this.filterUndefined(declaration.left.map(i => i.symbolId)); - if (symbols.some(s => this.shouldHoist(s, scope))) { - let assignment: tstl.AssignmentStatement | undefined; - if (declaration.right) { - assignment = tstl.createAssignmentStatement(declaration.left, declaration.right); - tstl.setNodePosition(assignment, declaration); // Preserve position info for sourcemap - } - const i = result.indexOf(declaration); - if (i >= 0) { - if (assignment) { - result.splice(i, 1, assignment); - } else { - result.splice(i, 1); - } - } else { - // Special case for 'var's declared in child scopes - this.replaceStatementInParent(declaration, assignment); - } - hoistedLocals.push(...declaration.left); - } - } - if (hoistedLocals.length > 0) { - result.unshift(tstl.createVariableDeclarationStatement(hoistedLocals)); - } - return result; - } - - protected performHoisting(statements: tstl.Statement[]): tstl.Statement[] { - if (this.options.noHoisting) { - return statements; - } - - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - let result = this.hoistFunctionDefinitions(scope, statements); - - result = this.hoistVariableDeclarations(scope, result); - - result = this.hoistImportStatements(scope, result); - - return result; - } - - protected popScope(): Scope { - const scope = this.scopeStack.pop(); - - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - - return scope; - } - - protected createHoistableVariableDeclarationStatement( - identifier: tstl.Identifier, - initializer?: tstl.Expression, - tsOriginal?: ts.Node, - parent?: tstl.Node - ): tstl.AssignmentStatement | tstl.VariableDeclarationStatement { - const declaration = tstl.createVariableDeclarationStatement(identifier, initializer, tsOriginal, parent); - if (!this.options.noHoisting && identifier.symbolId) { - const scope = this.peekScope(); - if (scope === undefined) { - throw TSTLErrors.UndefinedScope(); - } - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } - scope.variableDeclarations.push(declaration); - } - return declaration; - } - - protected statementVisitResultToArray(visitResult: StatementVisitResult): tstl.Statement[] { - if (!Array.isArray(visitResult)) { - if (visitResult) { - return [visitResult]; - } - return []; - } - - return this.filterUndefined(visitResult); - } - - public castElements( - items: TOriginal[], - cast: (item: TOriginal) => item is TCast - ): TCast[] { - if (items.every(cast)) { - return items as TCast[]; - } else { - throw TSTLErrors.CouldNotCast(cast.name); - } - } - - protected filterUndefined(items: Array): T[] { - return items.filter(i => i !== undefined) as T[]; - } - - protected filterUndefinedAndCast( - items: Array, - cast: (item: TOriginal) => item is TCast - ): TCast[] { - return this.castElements(this.filterUndefined(items), cast); - } - - protected createConstructorDecorationStatement( - declaration: ts.ClassLikeDeclaration - ): tstl.AssignmentStatement | undefined { - const className = - declaration.name !== undefined - ? this.addExportToIdentifier(this.transformIdentifier(declaration.name)) - : tstl.createAnonymousIdentifier(); - - const decorators = declaration.decorators; - if (!decorators) { - return undefined; - } - - const decoratorExpressions = decorators.map(decorator => { - const expression = decorator.expression; - const type = this.checker.getTypeAtLocation(expression); - const context = tsHelper.getFunctionContextType(type, this.program); - if (context === tsHelper.ContextType.Void) { - throw TSTLErrors.InvalidDecoratorContext(decorator); - } - return this.transformExpression(expression); - }); - - const decoratorArguments: tstl.Expression[] = []; - - const decoratorTable = tstl.createTableExpression( - decoratorExpressions.map(expression => tstl.createTableFieldExpression(expression)) - ); - - decoratorArguments.push(decoratorTable); - decoratorArguments.push(className); - - return tstl.createAssignmentStatement( - className, - this.transformLuaLibFunction(LuaLibFeature.Decorate, undefined, ...decoratorArguments) - ); - } -} diff --git a/src/TSHelper.ts b/src/TSHelper.ts deleted file mode 100644 index 4c0735310..000000000 --- a/src/TSHelper.ts +++ /dev/null @@ -1,1066 +0,0 @@ -import * as ts from "typescript"; -import * as path from "path"; -import { CompilerOptions } from "./CompilerOptions"; -import { Decorator, DecoratorKind } from "./Decorator"; -import * as tstl from "./LuaAST"; -import * as TSTLErrors from "./TSTLErrors"; -import { EmitResolver } from "./LuaTransformer"; -import { formatPathToLuaPath } from "./utils"; - -export enum ContextType { - None, - Void, - NonVoid, - Mixed, -} - -const defaultArrayCallMethodNames = new Set([ - "concat", - "push", - "reverse", - "shift", - "unshift", - "sort", - "pop", - "forEach", - "indexOf", - "map", - "filter", - "some", - "every", - "slice", - "splice", - "join", - "flat", - "flatMap", -]); - -// TODO [2019-09-27/Perry]: Refactor lualib detection to consistent map -const builtinErrorTypeNames = new Set([ - "Error", - "ErrorConstructor", - "RangeError", - "RangeErrorConstructor", - "ReferenceError", - "ReferenceErrorConstructor", - "SyntaxError", - "SyntaxErrorConstructor", - "TypeError", - "TypeErrorConstructor", - "URIError", - "URIErrorConstructor", -]); - -export function getExtendedTypeNode( - node: ts.ClassLikeDeclarationBase, - checker: ts.TypeChecker -): ts.ExpressionWithTypeArguments | undefined { - if (node && node.heritageClauses) { - for (const clause of node.heritageClauses) { - if (clause.token === ts.SyntaxKind.ExtendsKeyword) { - const superType = checker.getTypeAtLocation(clause.types[0]); - const decorators = getCustomDecorators(superType, checker); - if (!decorators.has(DecoratorKind.PureAbstract)) { - return clause.types[0]; - } - } - } - } - return undefined; -} - -export function getExtendedType(node: ts.ClassLikeDeclarationBase, checker: ts.TypeChecker): ts.Type | undefined { - const extendedTypeNode = getExtendedTypeNode(node, checker); - return extendedTypeNode && checker.getTypeAtLocation(extendedTypeNode); -} - -export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { - return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); -} - -export function isDestructuringAssignment(node: ts.Node): node is ts.DestructuringAssignment { - return ( - ts.isBinaryExpression(node) && - node.operatorToken.kind === ts.SyntaxKind.EqualsToken && - isAssignmentPattern(node.left) - ); -} - -export function getExportable(exportSpecifiers: ts.NamedExports, resolver: EmitResolver): ts.ExportSpecifier[] { - return exportSpecifiers.elements.filter(exportSpecifier => resolver.isValueAliasDeclaration(exportSpecifier)); -} - -export function isDefaultExportSpecifier(node: ts.ExportSpecifier): boolean { - return ( - (node.name !== undefined && node.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || - (node.propertyName !== undefined && node.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) - ); -} - -export function hasDefaultExportModifier(modifiers?: ts.NodeArray): boolean { - return modifiers ? modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword) : false; -} - -export function shouldResolveModulePath(moduleSpecifier: ts.Expression, checker: ts.TypeChecker): boolean { - const moduleOwnerSymbol = checker.getSymbolAtLocation(moduleSpecifier); - if (moduleOwnerSymbol) { - const decorators = new Map(); - collectCustomDecorators(moduleOwnerSymbol, checker, decorators); - if (decorators.has(DecoratorKind.NoResolution)) { - return false; - } - } - return true; -} - -export function shouldBeImported( - importNode: ts.ImportClause | ts.ImportSpecifier, - checker: ts.TypeChecker, - resolver: EmitResolver -): boolean { - const decorators = getCustomDecorators(checker.getTypeAtLocation(importNode), checker); - - return ( - resolver.isReferencedAliasDeclaration(importNode) && - !decorators.has(DecoratorKind.Extension) && - !decorators.has(DecoratorKind.MetaExtension) - ); -} - -export function isFileModule(sourceFile: ts.SourceFile): boolean { - return sourceFile.statements.some(isStatementExported); -} - -export function isStatementExported(statement: ts.Statement): boolean { - if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { - return true; - } - if (ts.isVariableStatement(statement)) { - return statement.declarationList.declarations.some( - declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 - ); - } - return isDeclaration(statement) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; -} - -export function getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { - const declarations = symbol.getDeclarations(); - if (declarations) { - return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0); - } - return undefined; -} - -export function isDeclaration(node: ts.Node): node is ts.Declaration { - return ( - ts.isEnumDeclaration(node) || - ts.isClassDeclaration(node) || - ts.isExportDeclaration(node) || - ts.isImportDeclaration(node) || - ts.isMethodDeclaration(node) || - ts.isModuleDeclaration(node) || - ts.isFunctionDeclaration(node) || - ts.isVariableDeclaration(node) || - ts.isInterfaceDeclaration(node) || - ts.isTypeAliasDeclaration(node) || - ts.isNamespaceExportDeclaration(node) - ); -} - -export function isInDestructingAssignment(node: ts.Node): boolean { - return ( - node.parent && - ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || - (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) - ); -} - -// iterate over a type and its bases until the callback returns true. -export function forTypeOrAnySupertype( - type: ts.Type, - checker: ts.TypeChecker, - predicate: (type: ts.Type) => boolean -): boolean { - if (predicate(type)) { - return true; - } - if (!type.isClassOrInterface() && type.symbol) { - type = checker.getDeclaredTypeOfSymbol(type.symbol); - } - const superTypes = type.getBaseTypes(); - if (superTypes) { - for (const superType of superTypes) { - if (forTypeOrAnySupertype(superType, checker, predicate)) { - return true; - } - } - } - return false; -} - -export function isAmbientNode(node: ts.Declaration): boolean { - return !((ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) === 0); -} - -export function isStaticNode(node: ts.Node): boolean { - return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); -} - -export function isTypeWithFlags( - type: ts.Type, - flags: ts.TypeFlags, - checker: ts.TypeChecker, - program: ts.Program -): boolean { - if (type.symbol) { - const baseConstraint = checker.getBaseConstraintOfType(type); - if (baseConstraint && baseConstraint !== type) { - return isTypeWithFlags(baseConstraint, flags, checker, program); - } - } - - if (type.isUnion()) { - return type.types.every(t => isTypeWithFlags(t, flags, checker, program)); - } - - if (type.isIntersection()) { - return type.types.some(t => isTypeWithFlags(t, flags, checker, program)); - } - - return (type.flags & flags) !== 0; -} - -export function isStringType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - return isTypeWithFlags( - type, - ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral, - checker, - program - ); -} - -export function isNumberType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - return isTypeWithFlags( - type, - ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral, - checker, - program - ); -} - -export function isExplicitArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - if (type.symbol) { - const baseConstraint = checker.getBaseConstraintOfType(type); - if (baseConstraint && baseConstraint !== type) { - return isExplicitArrayType(baseConstraint, checker, program); - } - } - - if (type.isUnionOrIntersection()) { - return type.types.some(t => isExplicitArrayType(t, checker, program)); - } - - const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; - let typeNode = checker.typeToTypeNode(type, undefined, flags); - if (typeNode && ts.isTypeOperatorNode(typeNode) && typeNode.operator === ts.SyntaxKind.ReadonlyKeyword) { - typeNode = typeNode.type; - } - - return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); -} - -export function isFunctionType(type: ts.Type, checker: ts.TypeChecker): boolean { - const typeNode = checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); -} - -export function isFunctionTypeAtLocation(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return isFunctionType(type, checker); -} - -export function isArrayType(type: ts.Type, checker: ts.TypeChecker, program: ts.Program): boolean { - return forTypeOrAnySupertype(type, checker, t => isExplicitArrayType(t, checker, program)); -} - -export function isLuaIteratorType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return getCustomDecorators(type, checker).has(DecoratorKind.LuaIterator); -} - -export function isRestParameter(node: ts.Node, checker: ts.TypeChecker): boolean { - const symbol = checker.getSymbolAtLocation(node); - if (!symbol) { - return false; - } - const declarations = symbol.getDeclarations(); - if (!declarations) { - return false; - } - return declarations.some(d => ts.isParameter(d) && d.dotDotDotToken !== undefined); -} - -export function isVarArgType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return type !== undefined && getCustomDecorators(type, checker).has(DecoratorKind.Vararg); -} - -export function isForRangeType(node: ts.Node, checker: ts.TypeChecker): boolean { - const type = checker.getTypeAtLocation(node); - return getCustomDecorators(type, checker).has(DecoratorKind.ForRange); -} - -export function isTupleReturnCall(node: ts.Node, checker: ts.TypeChecker): boolean { - if (ts.isCallExpression(node)) { - const signature = checker.getResolvedSignature(node); - if (signature) { - if (getCustomSignatureDirectives(signature, checker).has(DecoratorKind.TupleReturn)) { - return true; - } - - // Only check function type for directive if it is declared as an interface or type alias - const declaration = signature.getDeclaration(); - const isInterfaceOrAlias = - declaration && - declaration.parent && - ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || - ts.isTypeAliasDeclaration(declaration.parent)); - if (!isInterfaceOrAlias) { - return false; - } - } - - const type = checker.getTypeAtLocation(node.expression); - return getCustomDecorators(type, checker).has(DecoratorKind.TupleReturn); - } else { - return false; - } -} - -export function isInTupleReturnFunction(node: ts.Node, checker: ts.TypeChecker): boolean { - const declaration = findFirstNodeAbove(node, ts.isFunctionLike); - if (declaration) { - let functionType: ts.Type | undefined; - if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = inferAssignedType(declaration, checker); - } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { - // Manually lookup type for object literal properties declared with method syntax - const interfaceType = inferAssignedType(declaration.parent, checker); - const propertySymbol = interfaceType.getProperty(declaration.name.getText()); - if (propertySymbol) { - functionType = checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); - } - } - if (functionType === undefined) { - functionType = checker.getTypeAtLocation(declaration); - } - - // Check all overloads for directive - const signatures = functionType.getCallSignatures(); - if ( - signatures && - signatures.some(s => getCustomSignatureDirectives(s, checker).has(DecoratorKind.TupleReturn)) - ) { - return true; - } - - const decorators = getCustomDecorators(functionType, checker); - return decorators.has(DecoratorKind.TupleReturn); - } else { - return false; - } -} - -export function getContainingFunctionReturnType(node: ts.Node, checker: ts.TypeChecker): ts.Type | undefined { - const declaration = findFirstNodeAbove(node, ts.isFunctionLike); - if (declaration) { - const signature = checker.getSignatureFromDeclaration(declaration); - return signature === undefined ? undefined : checker.getReturnTypeOfSignature(signature); - } - return undefined; -} - -export function collectCustomDecorators( - source: ts.Symbol | ts.Signature, - checker: ts.TypeChecker, - decMap: Map -): void { - const comments = source.getDocumentationComment(checker); - const decorators = comments - .filter(comment => comment.kind === "text") - .map(comment => comment.text.split("\n")) - .reduce((a, b) => a.concat(b), []) - .map(line => line.trim()) - .filter(comment => comment[0] === "!"); - - decorators.forEach(decStr => { - const [decoratorName, ...decoratorArguments] = decStr.split(" "); - if (Decorator.isValid(decoratorName.substr(1))) { - const dec = new Decorator(decoratorName.substr(1), decoratorArguments); - decMap.set(dec.kind, dec); - console.warn(`[Deprecated] Decorators with ! are being deprecated, ` + `use @${decStr.substr(1)} instead`); - } else { - console.warn(`Encountered unknown decorator ${decStr}.`); - } - }); - source.getJsDocTags().forEach(tag => { - if (Decorator.isValid(tag.name)) { - const dec = new Decorator(tag.name, tag.text ? tag.text.split(" ") : []); - decMap.set(dec.kind, dec); - } - }); -} - -export function getCustomDecorators(type: ts.Type, checker: ts.TypeChecker): Map { - const decMap = new Map(); - if (type.symbol) { - collectCustomDecorators(type.symbol, checker, decMap); - } - if (type.aliasSymbol) { - collectCustomDecorators(type.aliasSymbol, checker, decMap); - } - return decMap; -} - -function getCustomNodeDirectives(node: ts.Node): Map { - const directivesMap = new Map(); - - ts.getJSDocTags(node).forEach(tag => { - const tagName = tag.tagName.text; - if (Decorator.isValid(tagName)) { - const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); - directivesMap.set(dec.kind, dec); - } - }); - - return directivesMap; -} - -export function getCustomFileDirectives(file: ts.SourceFile): Map { - const directivesMap = new Map(); - - if (file.statements.length > 0) { - // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment - const jsDoc = file.statements[0].jsDoc; - if (jsDoc) { - // TODO(refactor): flatMap - const tags = jsDoc.reduce((acc, x) => [...acc, ...(x.tags || [])], []); - tags.forEach(tag => { - const tagName = tag.tagName.text; - if (Decorator.isValid(tagName)) { - const dec = new Decorator(tagName, tag.comment ? tag.comment.split(" ") : []); - directivesMap.set(dec.kind, dec); - } - }); - } - } - - return directivesMap; -} - -export function getCustomSignatureDirectives( - signature: ts.Signature, - checker: ts.TypeChecker -): Map { - const directivesMap = new Map(); - collectCustomDecorators(signature, checker, directivesMap); - - // Function properties on interfaces have the JSDoc tags on the parent PropertySignature - const declaration = signature.getDeclaration(); - if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { - const symbol = checker.getSymbolAtLocation(declaration.parent.name); - if (symbol) { - collectCustomDecorators(symbol, checker, directivesMap); - } - } - - return directivesMap; -} - -// Search up until finding a node satisfying the callback -export function findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined { - let current = node; - while (current.parent) { - if (callback(current.parent)) { - return current.parent; - } else { - current = current.parent; - } - } - return undefined; -} - -export function isBinaryAssignmentToken(token: ts.SyntaxKind): [true, ts.BinaryOperator] | [false, undefined] { - switch (token) { - case ts.SyntaxKind.BarEqualsToken: - return [true, ts.SyntaxKind.BarToken]; - case ts.SyntaxKind.PlusEqualsToken: - return [true, ts.SyntaxKind.PlusToken]; - case ts.SyntaxKind.CaretEqualsToken: - return [true, ts.SyntaxKind.CaretToken]; - case ts.SyntaxKind.MinusEqualsToken: - return [true, ts.SyntaxKind.MinusToken]; - case ts.SyntaxKind.SlashEqualsToken: - return [true, ts.SyntaxKind.SlashToken]; - case ts.SyntaxKind.PercentEqualsToken: - return [true, ts.SyntaxKind.PercentToken]; - case ts.SyntaxKind.AsteriskEqualsToken: - return [true, ts.SyntaxKind.AsteriskToken]; - case ts.SyntaxKind.AmpersandEqualsToken: - return [true, ts.SyntaxKind.AmpersandToken]; - case ts.SyntaxKind.AsteriskAsteriskEqualsToken: - return [true, ts.SyntaxKind.AsteriskAsteriskToken]; - case ts.SyntaxKind.LessThanLessThanEqualsToken: - return [true, ts.SyntaxKind.LessThanLessThanToken]; - case ts.SyntaxKind.GreaterThanGreaterThanEqualsToken: - return [true, ts.SyntaxKind.GreaterThanGreaterThanToken]; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken: - return [true, ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]; - } - - return [false, undefined]; -} - -// Returns true for expressions that may have effects when evaluated -export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { - return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); -} - -// If expression is property/element access with possible effects from being evaluated, returns true along with the -// separated object and index expressions. -export function isAccessExpressionWithEvaluationEffects( - node: ts.Expression, - checker: ts.TypeChecker, - program: ts.Program -): [true, ts.Expression, ts.Expression] | [false, undefined, undefined] { - if ( - ts.isElementAccessExpression(node) && - (isExpressionWithEvaluationEffect(node.expression) || isExpressionWithEvaluationEffect(node.argumentExpression)) - ) { - const type = checker.getTypeAtLocation(node.expression); - if (isArrayType(type, checker, program)) { - // Offset arrays by one - const oneLit = ts.createNumericLiteral("1"); - const exp = ts.createParen(node.argumentExpression); - const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); - return [true, node.expression, addExp]; - } else { - return [true, node.expression, node.argumentExpression]; - } - } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { - return [true, node.expression, ts.createStringLiteral(node.name.text)]; - } - return [false, undefined, undefined]; -} - -export function isDefaultArrayCallMethodName(methodName: string): boolean { - return defaultArrayCallMethodNames.has(methodName); -} - -export function getExplicitThisParameter( - signatureDeclaration: ts.SignatureDeclaration -): ts.ParameterDeclaration | undefined { - return signatureDeclaration.parameters.find( - param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword - ); -} - -export function findInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - callback: (classDeclaration: ts.ClassLikeDeclarationBase) => boolean, - checker: ts.TypeChecker -): ts.ClassLikeDeclarationBase | undefined { - if (callback(classDeclaration)) { - return classDeclaration; - } - - const extendsType = getExtendedType(classDeclaration, checker); - if (!extendsType) { - return undefined; - } - - const symbol = extendsType.getSymbol(); - if (symbol === undefined) { - return undefined; - } - - const symbolDeclarations = symbol.getDeclarations(); - if (symbolDeclarations === undefined) { - return undefined; - } - - const declaration = symbolDeclarations.find(ts.isClassLike); - if (!declaration) { - return undefined; - } - - return findInClassOrAncestor(declaration, callback, checker); -} - -export function hasSetAccessorInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - isStatic: boolean, - checker: ts.TypeChecker -): boolean { - return ( - findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isSetAccessor(m) && isStaticNode(m) === isStatic), - checker - ) !== undefined - ); -} - -export function hasGetAccessorInClassOrAncestor( - classDeclaration: ts.ClassLikeDeclarationBase, - isStatic: boolean, - checker: ts.TypeChecker -): boolean { - return ( - findInClassOrAncestor( - classDeclaration, - c => c.members.some(m => ts.isGetAccessor(m) && isStaticNode(m) === isStatic), - checker - ) !== undefined - ); -} - -export function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { - if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { - return propertyName.text; - } else { - return undefined; // TODO: how to handle computed property names? - } -} - -export function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { - const aName = getPropertyName(a); - const bName = getPropertyName(b); - return aName !== undefined && aName === bName; -} - -export function isGetAccessorOverride( - element: ts.ClassElement, - classDeclaration: ts.ClassLikeDeclarationBase, - checker: ts.TypeChecker -): element is ts.GetAccessorDeclaration { - if (!ts.isGetAccessor(element) || isStaticNode(element)) { - return false; - } - - const hasInitializedField = (e: ts.ClassElement) => - ts.isPropertyDeclaration(e) && e.initializer !== undefined && isSamePropertyName(e.name, element.name); - - return findInClassOrAncestor(classDeclaration, c => c.members.some(hasInitializedField), checker) !== undefined; -} - -export function inferAssignedType(expression: ts.Expression, checker: ts.TypeChecker): ts.Type { - return checker.getContextualType(expression) || checker.getTypeAtLocation(expression); -} - -export function getAllCallSignatures(type: ts.Type): ReadonlyArray { - if (type.isUnion()) { - return type.types.map(t => getAllCallSignatures(t)).reduce((a, b) => a.concat(b)); - } - return type.getCallSignatures(); -} - -export function getSignatureDeclarations( - signatures: readonly ts.Signature[], - checker: ts.TypeChecker -): ts.SignatureDeclaration[] { - const signatureDeclarations: ts.SignatureDeclaration[] = []; - for (const signature of signatures) { - const signatureDeclaration = signature.getDeclaration(); - if ( - (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && - !getExplicitThisParameter(signatureDeclaration) - ) { - // Infer type of function expressions/arrow functions - const inferredType = inferAssignedType(signatureDeclaration, checker); - if (inferredType) { - const inferredSignatures = getAllCallSignatures(inferredType); - if (inferredSignatures.length > 0) { - signatureDeclarations.push(...inferredSignatures.map(s => s.getDeclaration())); - continue; - } - } - } - signatureDeclarations.push(signatureDeclaration); - } - return signatureDeclarations; -} - -export function hasNoSelfAncestor(declaration: ts.Declaration, checker: ts.TypeChecker): boolean { - const scopeDeclaration = findFirstNodeAbove( - declaration, - (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) - ); - if (!scopeDeclaration) { - return false; - } - if (ts.isSourceFile(scopeDeclaration)) { - return getCustomFileDirectives(scopeDeclaration).has(DecoratorKind.NoSelfInFile); - } - if (getCustomNodeDirectives(scopeDeclaration).has(DecoratorKind.NoSelf)) { - return true; - } - return hasNoSelfAncestor(scopeDeclaration, checker); -} - -export function getDeclarationContextType( - signatureDeclaration: ts.SignatureDeclaration, - program: ts.Program -): ContextType { - const checker = program.getTypeChecker(); - - const thisParameter = getExplicitThisParameter(signatureDeclaration); - if (thisParameter) { - // Explicit 'this' - return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword - ? ContextType.Void - : ContextType.NonVoid; - } - - if ( - ts.isMethodSignature(signatureDeclaration) || - ts.isMethodDeclaration(signatureDeclaration) || - ts.isConstructSignatureDeclaration(signatureDeclaration) || - ts.isConstructorDeclaration(signatureDeclaration) || - (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || - (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) - ) { - // Class/interface methods only respect @noSelf on their parent - const scopeDeclaration = findFirstNodeAbove( - signatureDeclaration, - (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => - ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) - ); - - if (scopeDeclaration === undefined) { - return ContextType.NonVoid; - } - - if (getCustomNodeDirectives(scopeDeclaration).has(DecoratorKind.NoSelf)) { - return ContextType.Void; - } - return ContextType.NonVoid; - } - - // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. - const options = program.getCompilerOptions() as CompilerOptions; - if (options.noImplicitSelf && program.getRootFileNames().includes(signatureDeclaration.getSourceFile().fileName)) { - return ContextType.Void; - } - - // Walk up to find @noSelf or @noSelfInFile - if (hasNoSelfAncestor(signatureDeclaration, checker)) { - return ContextType.Void; - } - - return ContextType.NonVoid; -} - -export function reduceContextTypes(contexts: ContextType[]): ContextType { - const reducer = (a: ContextType, b: ContextType) => { - if (a === ContextType.None) { - return b; - } else if (b === ContextType.None) { - return a; - } else if (a !== b) { - return ContextType.Mixed; - } else { - return a; - } - }; - return contexts.reduce(reducer, ContextType.None); -} - -export function getFunctionContextType(type: ts.Type, program: ts.Program): ContextType { - const checker = program.getTypeChecker(); - - if (type.isTypeParameter()) { - type = type.getConstraint() || type; - } - - if (type.isUnion()) { - return reduceContextTypes(type.types.map(t => getFunctionContextType(t, program))); - } - - const signatures = checker.getSignaturesOfType(type, ts.SignatureKind.Call); - if (signatures.length === 0) { - return ContextType.None; - } - const signatureDeclarations = getSignatureDeclarations(signatures, checker); - return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(s, program))); -} - -export function escapeString(text: string): string { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String - const escapeSequences: Array<[RegExp, string]> = [ - [/[\\]/g, "\\\\"], - [/[\']/g, "\\'"], - [/[\"]/g, '\\"'], - [/[\n]/g, "\\n"], - [/[\r]/g, "\\r"], - [/[\v]/g, "\\v"], - [/[\t]/g, "\\t"], - [/[\b]/g, "\\b"], - [/[\f]/g, "\\f"], - [/[\0]/g, "\\0"], - ]; - - if (text.length > 0) { - for (const [regex, replacement] of escapeSequences) { - text = text.replace(regex, replacement); - } - } - return text; -} - -export function isValidLuaIdentifier(str: string): boolean { - const match = str.match(/[a-zA-Z_][a-zA-Z0-9_]*/); - return match !== undefined && match !== null && match[0] === str; -} - -export function fixInvalidLuaIdentifier(name: string): string { - return name.replace( - /[^a-zA-Z0-9_]/g, - c => - `_${c - .charCodeAt(0) - .toString(16) - .toUpperCase()}` - ); -} - -// Checks that a name is valid for use in lua function declaration syntax: -// 'foo.bar' => passes ('function foo.bar()' is valid) -// 'getFoo().bar' => fails ('function getFoo().bar()' would be illegal) -export function isValidLuaFunctionDeclarationName(str: string): boolean { - const match = str.match(/[a-zA-Z0-9_\.]+/); - return match !== undefined && match !== null && match[0] === str; -} - -export function isFalsible(type: ts.Type, strictNullChecks: boolean): boolean { - const falsibleFlags = - ts.TypeFlags.Boolean | - ts.TypeFlags.BooleanLiteral | - ts.TypeFlags.Undefined | - ts.TypeFlags.Null | - ts.TypeFlags.Never | - ts.TypeFlags.Void | - ts.TypeFlags.Any; - - if (type.flags & falsibleFlags) { - return true; - } else if (!strictNullChecks && !type.isLiteral()) { - return true; - } else if (type.isUnion()) { - for (const subType of type.types) { - if (isFalsible(subType, strictNullChecks)) { - return true; - } - } - } - - return false; -} - -export function getFirstDeclaration(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { - let declarations = symbol.getDeclarations(); - if (!declarations) { - return undefined; - } - declarations = declarations.filter(d => findFirstNodeAbove(d, ts.isSourceFile) === sourceFile); - return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; -} - -export function getRawLiteral(node: ts.LiteralLikeNode): string { - let text = node.getText(); - const isLast = - node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === ts.SyntaxKind.TemplateTail; - text = text.substring(1, text.length - (isLast ? 1 : 2)); - text = text.replace(/\r\n?/g, "\n").replace(/\\/g, "\\\\"); - return text; -} - -export function isFirstDeclaration( - node: ts.VariableDeclaration, - checker: ts.TypeChecker, - sourceFile: ts.SourceFile -): boolean { - const symbol = checker.getSymbolAtLocation(node.name); - if (!symbol) { - return false; - } - - const firstDeclaration = getFirstDeclaration(symbol, sourceFile); - return firstDeclaration === node; -} - -export function isStandardLibraryDeclaration(declaration: ts.Declaration, program: ts.Program): boolean { - const source = declaration.getSourceFile(); - if (!source) { - return false; - } - return program.isSourceFileDefaultLibrary(source); -} - -export function isStandardLibraryType(type: ts.Type, name: string | undefined, program: ts.Program): boolean { - const symbol = type.getSymbol(); - if (!symbol || (name ? symbol.escapedName !== name : symbol.escapedName === "__type")) { - return false; - } - - const declaration = symbol.valueDeclaration; - if (!declaration) { - return true; - } - - // assume to be lib function if no valueDeclaration exists - return isStandardLibraryDeclaration(declaration, program); -} - -export function isWithinLiteralAssignmentStatement(node: ts.Node): boolean { - if (!node.parent) { - return false; - } - if ( - ts.isArrayLiteralExpression(node.parent) || - ts.isArrayBindingPattern(node.parent) || - ts.isObjectLiteralExpression(node.parent) - ) { - return isWithinLiteralAssignmentStatement(node.parent); - } else if (isInDestructingAssignment(node)) { - return true; - } else if (ts.isBinaryExpression(node.parent) && node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { - return true; - } else { - return false; - } -} - -export function moduleHasEmittedBody( - statement: ts.ModuleDeclaration -): statement is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { - if (statement.body) { - if (ts.isModuleBlock(statement.body)) { - // Ignore if body has no emitted statements - return ( - statement.body.statements.findIndex( - s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s) - ) !== -1 - ); - } else if (ts.isModuleDeclaration(statement.body)) { - return true; - } - } - return false; -} - -export function isArrayLength( - expression: ts.Expression, - checker: ts.TypeChecker, - program: ts.Program -): expression is ts.PropertyAccessExpression | ts.ElementAccessExpression { - if (!ts.isPropertyAccessExpression(expression) && !ts.isElementAccessExpression(expression)) { - return false; - } - - const type = checker.getTypeAtLocation(expression.expression); - if (!isArrayType(type, checker, program)) { - return false; - } - - const name = ts.isPropertyAccessExpression(expression) - ? expression.name.text - : ts.isStringLiteral(expression.argumentExpression) - ? expression.argumentExpression.text - : undefined; - - return name === "length"; -} - -// Returns true if expression contains no function calls -export function isSimpleExpression(expression: tstl.Expression): boolean { - switch (expression.kind) { - case tstl.SyntaxKind.CallExpression: - case tstl.SyntaxKind.MethodCallExpression: - case tstl.SyntaxKind.FunctionExpression: - return false; - - case tstl.SyntaxKind.TableExpression: - const tableExpression = expression as tstl.TableExpression; - return tableExpression.fields.every(e => isSimpleExpression(e)); - - case tstl.SyntaxKind.TableFieldExpression: - const fieldExpression = expression as tstl.TableFieldExpression; - return ( - (!fieldExpression.key || isSimpleExpression(fieldExpression.key)) && - isSimpleExpression(fieldExpression.value) - ); - - case tstl.SyntaxKind.TableIndexExpression: - const indexExpression = expression as tstl.TableIndexExpression; - return isSimpleExpression(indexExpression.table) && isSimpleExpression(indexExpression.index); - - case tstl.SyntaxKind.UnaryExpression: - return isSimpleExpression((expression as tstl.UnaryExpression).operand); - - case tstl.SyntaxKind.BinaryExpression: - const binaryExpression = expression as tstl.BinaryExpression; - return isSimpleExpression(binaryExpression.left) && isSimpleExpression(binaryExpression.right); - - case tstl.SyntaxKind.ParenthesizedExpression: - return isSimpleExpression((expression as tstl.ParenthesizedExpression).innerExpression); - } - return true; -} - -export function getAbsoluteImportPath( - relativePath: string, - directoryPath: string, - options: ts.CompilerOptions -): string { - if (relativePath.charAt(0) !== "." && options.baseUrl) { - return path.resolve(options.baseUrl, relativePath); - } - - return path.resolve(directoryPath, relativePath); -} - -export function getImportPath( - fileName: string, - relativePath: string, - node: ts.Node, - options: ts.CompilerOptions -): string { - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absoluteImportPath = path.format( - path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) - ); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - if (absoluteImportPath.includes(absoluteRootDirPath)) { - return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); - } else { - throw TSTLErrors.UnresolvableRequirePath( - node, - `Cannot create require path. Module does not exist within --rootDir`, - relativePath - ); - } -} - -export function getExportPath(fileName: string, options: ts.CompilerOptions): string { - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); -} - -export function isBuiltinErrorTypeName(name: string): boolean { - return builtinErrorTypeNames.has(name); -} diff --git a/src/Transpile.ts b/src/Transpile.ts index 01d8df15a..57326e404 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -2,12 +2,12 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import { bundleTranspiledFiles } from "./bundle"; import { CompilerOptions, validateOptions } from "./CompilerOptions"; -import * as diagnosticFactories from "./diagnostics"; import { Block } from "./LuaAST"; -import { LuaPrinter } from "./LuaPrinter"; -import { LuaTransformer } from "./LuaTransformer"; -import { TranspileError } from "./TranspileError"; +import { createPrinter } from "./LuaPrinter"; +import { getPlugins, Plugin } from "./plugins"; +import { createVisitorMap, transformSourceFile } from "./transformation"; import { getCustomTransformers } from "./TSTransformers"; +import { isNonNull } from "./utils"; export interface TranspiledFile { fileName: string; @@ -29,8 +29,7 @@ export interface TranspileOptions { program: ts.Program; sourceFiles?: ts.SourceFile[]; customTransformers?: ts.CustomTransformers; - transformer?: LuaTransformer; - printer?: LuaPrinter; + plugins?: Plugin[]; emitHost?: EmitHost; } @@ -43,9 +42,8 @@ export function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, + plugins: pluginsFromOptions = [], emitHost = ts.sys, - transformer = new LuaTransformer(program), - printer = new LuaPrinter(program.getCompilerOptions(), emitHost), }: TranspileOptions): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; @@ -87,22 +85,25 @@ export function transpile({ } } + const plugins = getPlugins(program, diagnostics, pluginsFromOptions); + const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); + const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { - try { - const [luaAst, lualibFeatureSet] = transformer.transform(sourceFile); - if (!options.noEmit && !options.emitDeclarationOnly) { - const [lua, sourceMap, sourceNode] = printer.print(luaAst, lualibFeatureSet, sourceFile.fileName); - updateTranspiledFile(sourceFile.fileName, { luaAst, lua, sourceMap, sourceMapNode: sourceNode }); - } - } catch (err) { - if (!(err instanceof TranspileError)) throw err; - - diagnostics.push(diagnosticFactories.transpileError(err)); - - updateTranspiledFile(sourceFile.fileName, { - lua: `error(${JSON.stringify(err.message)})\n`, - sourceMap: "", - }); + const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformSourceFile( + program, + sourceFile, + visitorMap + ); + diagnostics.push(...transformDiagnostics); + if (!options.noEmit && !options.emitDeclarationOnly) { + const { code, sourceMap, sourceMapNode } = printer( + program, + emitHost, + sourceFile.fileName, + luaAst, + luaLibFeatures + ); + updateTranspiledFile(sourceFile.fileName, { luaAst, lua: code, sourceMap, sourceMapNode }); } }; diff --git a/src/TranspileError.ts b/src/TranspileError.ts deleted file mode 100644 index baeded940..000000000 --- a/src/TranspileError.ts +++ /dev/null @@ -1,8 +0,0 @@ -import * as ts from "typescript"; - -export class TranspileError extends Error { - public name = "TranspileError"; - constructor(message: string, public node: ts.Node) { - super(message); - } -} diff --git a/src/bundle.ts b/src/bundle.ts index b4851e78f..834be2c23 100644 --- a/src/bundle.ts +++ b/src/bundle.ts @@ -1,11 +1,11 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; +import { CompilerOptions } from "./CompilerOptions"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; +import { escapeString } from "./LuaPrinter"; import { EmitHost, TranspiledFile } from "./Transpile"; -import { formatPathToLuaPath, trimExtension, normalizeSlashes } from "./utils"; -import { escapeString } from "./TSHelper"; -import { CompilerOptions } from "./CompilerOptions"; +import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "./utils"; const createModulePath = (baseDir: string, pathToResolve: string) => escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); @@ -56,7 +56,7 @@ local ____modules = {} local ____moduleCache = {} local ____originalRequire = require local function require(file) - if ____moduleCache[file] then + if ____moduleCache[file] then return ____moduleCache[file] end if ____modules[file] then @@ -72,7 +72,7 @@ local function require(file) end\n`; // return require("") - const entryPoint = `return require("${createModulePath(sourceRootDir, resolvedEntryModule)}")\n`; + const entryPoint = `return require(${createModulePath(sourceRootDir, resolvedEntryModule)})\n`; const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); const { code, map } = bundleNode.toStringWithSourceMap(); @@ -89,7 +89,7 @@ end\n`; } function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): SourceNode { - const tableEntryHead = `["${modulePath}"] = function() `; + const tableEntryHead = `[${modulePath}] = function() `; const tableEntryTail = `end,\n`; if (transpiledFile.lua && transpiledFile.sourceMapNode) { diff --git a/src/diagnostics.ts b/src/diagnostics.ts index 9382ca834..3383c3cfd 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -1,15 +1,4 @@ import * as ts from "typescript"; -import { TranspileError } from "./TranspileError"; - -export const transpileError = (error: TranspileError): ts.Diagnostic => ({ - file: error.node.getSourceFile(), - start: error.node.getStart(), - length: error.node.getWidth(), - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: error.message, -}); export const toLoadTransformerItShouldBeTranspiled = (transform: string): ts.Diagnostic => ({ file: undefined, diff --git a/src/index.ts b/src/index.ts index fc686df20..7ed6e4ed0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,9 +14,9 @@ export * from "./Emit"; export * from "./LuaAST"; export { LuaLibFeature } from "./LuaLib"; export * from "./LuaPrinter"; -export * from "./LuaTransformer"; +export * from "./transformation/context"; +export { TranspileError } from "./transformation/utils/errors"; export * from "./Transpile"; -export * from "./TranspileError"; export interface TranspileFilesResult { diagnostics: ts.Diagnostic[]; diff --git a/src/lualib/TypeOf.ts b/src/lualib/TypeOf.ts index af531d732..158062cd4 100644 --- a/src/lualib/TypeOf.ts +++ b/src/lualib/TypeOf.ts @@ -1,5 +1,3 @@ -declare function type(this: void, value: unknown): string; - function __TS__TypeOf(this: void, value: unknown): string { const luaType = type(value); if (luaType === "table") { diff --git a/src/plugins.ts b/src/plugins.ts new file mode 100644 index 000000000..ef2e07a1f --- /dev/null +++ b/src/plugins.ts @@ -0,0 +1,27 @@ +import * as ts from "typescript"; +import { Printer } from "./LuaPrinter"; +import { Visitors } from "./transformation/context"; + +export interface Plugin { + /** + * An augmentation to the map of visitors that transform TypeScript AST to Lua AST. + * + * Key is a `SyntaxKind` of a processed node. + */ + visitors?: Visitors; + + /** + * A function that converts Lua AST to a string. + * + * At most one custom printer can be provided across all plugins. + */ + printer?: Printer; +} + +export function getPlugins( + _program: ts.Program, + _diagnostics: ts.Diagnostic[], + pluginsFromOptions: Plugin[] +): Plugin[] { + return pluginsFromOptions; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts new file mode 100644 index 000000000..cf4bef707 --- /dev/null +++ b/src/transformation/builtins/array.ts @@ -0,0 +1,102 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isExplicitArrayType } from "../utils/typescript"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function transformArrayPrototypeCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | undefined { + const expression = node.expression; + const ownerType = context.checker.getTypeAtLocation(expression.expression); + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + const caller = context.transformExpression(expression.expression); + + const expressionName = expression.name.text; + switch (expressionName) { + case "concat": + return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); + case "push": + return transformLuaLibFunction(context, LuaLibFeature.ArrayPush, node, caller, ...params); + case "reverse": + return transformLuaLibFunction(context, LuaLibFeature.ArrayReverse, node, caller); + case "shift": + return transformLuaLibFunction(context, LuaLibFeature.ArrayShift, node, caller); + case "unshift": + return transformLuaLibFunction(context, LuaLibFeature.ArrayUnshift, node, caller, ...params); + case "sort": + return transformLuaLibFunction(context, LuaLibFeature.ArraySort, node, caller, ...params); + case "pop": + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("remove")), + [caller], + node + ); + case "forEach": + return transformLuaLibFunction(context, LuaLibFeature.ArrayForEach, node, caller, ...params); + case "find": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFind, node, caller, ...params); + case "findIndex": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFindIndex, node, caller, ...params); + case "indexOf": + return transformLuaLibFunction(context, LuaLibFeature.ArrayIndexOf, node, caller, ...params); + case "map": + return transformLuaLibFunction(context, LuaLibFeature.ArrayMap, node, caller, ...params); + case "filter": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFilter, node, caller, ...params); + case "reduce": + return transformLuaLibFunction(context, LuaLibFeature.ArrayReduce, node, caller, ...params); + case "reduceRight": + return transformLuaLibFunction(context, LuaLibFeature.ArrayReduceRight, node, caller, ...params); + case "some": + return transformLuaLibFunction(context, LuaLibFeature.ArraySome, node, caller, ...params); + case "every": + return transformLuaLibFunction(context, LuaLibFeature.ArrayEvery, node, caller, ...params); + case "slice": + return transformLuaLibFunction(context, LuaLibFeature.ArraySlice, node, caller, ...params); + case "splice": + return transformLuaLibFunction(context, LuaLibFeature.ArraySplice, node, caller, ...params); + case "join": + const defaultSeparatorLiteral = lua.createStringLiteral(","); + const parameters = [ + caller, + node.arguments.length === 0 + ? defaultSeparatorLiteral + : lua.createBinaryExpression(params[0], defaultSeparatorLiteral, lua.SyntaxKind.OrOperator), + ]; + + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("concat")), + parameters, + node + ); + case "flat": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFlat, node, caller, ...params); + case "flatMap": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); + default: + if (isExplicitArrayType(context, ownerType)) { + throw UnsupportedProperty("array", expressionName, node); + } + } +} + +export function transformArrayProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.UnaryExpression | undefined { + switch (node.name.text) { + case "length": + let expression = context.transformExpression(node.expression); + if (lua.isTableExpression(expression)) { + expression = lua.createParenthesizedExpression(expression); + } + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + default: + return undefined; + } +} diff --git a/src/transformation/builtins/console.ts b/src/transformation/builtins/console.ts new file mode 100644 index 000000000..23ab2b9be --- /dev/null +++ b/src/transformation/builtins/console.ts @@ -0,0 +1,63 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +const isStringFormatTemplate = (node: ts.Expression) => ts.isStringLiteral(node) && node.text.includes("%"); + +export function transformConsoleCall( + context: TransformationContext, + expression: PropertyCallExpression +): lua.Expression { + const method = expression.expression; + const methodName = method.name.text; + const signature = context.checker.getResolvedSignature(expression); + const parameters = transformArguments(context, expression.arguments, signature); + + switch (methodName) { + case "log": + if (expression.arguments.length > 0 && isStringFormatTemplate(expression.arguments[0])) { + // print(string.format([arguments])) + const stringFormatCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), + parameters + ); + return lua.createCallExpression(lua.createIdentifier("print"), [stringFormatCall]); + } + // print([arguments]) + return lua.createCallExpression(lua.createIdentifier("print"), parameters); + case "assert": + if (expression.arguments.length > 1 && isStringFormatTemplate(expression.arguments[1])) { + // assert([condition], string.format([arguments])) + const stringFormatCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), + parameters.slice(1) + ); + return lua.createCallExpression(lua.createIdentifier("assert"), [parameters[0], stringFormatCall]); + } + // assert() + return lua.createCallExpression(lua.createIdentifier("assert"), parameters); + case "trace": + if (expression.arguments.length > 0 && isStringFormatTemplate(expression.arguments[0])) { + // print(debug.traceback(string.format([arguments]))) + const stringFormatCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), + parameters + ); + const debugTracebackCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("debug"), lua.createStringLiteral("traceback")), + [stringFormatCall] + ); + return lua.createCallExpression(lua.createIdentifier("print"), [debugTracebackCall]); + } + // print(debug.traceback([arguments]))) + const debugTracebackCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("debug"), lua.createStringLiteral("traceback")), + parameters + ); + return lua.createCallExpression(lua.createIdentifier("print"), [debugTracebackCall]); + default: + throw UnsupportedProperty("console", methodName, expression); + } +} diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts new file mode 100644 index 000000000..2eefae340 --- /dev/null +++ b/src/transformation/builtins/function.ts @@ -0,0 +1,32 @@ +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty, UnsupportedSelfFunctionConversion } from "../utils/errors"; +import { ContextType, getFunctionContextType } from "../utils/function-context"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function transformFunctionPrototypeCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression { + const expression = node.expression; + const callerType = context.checker.getTypeAtLocation(expression.expression); + if (getFunctionContextType(context, callerType) === ContextType.Void) { + throw UnsupportedSelfFunctionConversion(node); + } + + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + const caller = context.transformExpression(expression.expression); + const expressionName = expression.name.text; + switch (expressionName) { + case "apply": + return transformLuaLibFunction(context, LuaLibFeature.FunctionApply, node, caller, ...params); + case "bind": + return transformLuaLibFunction(context, LuaLibFeature.FunctionBind, node, caller, ...params); + case "call": + return transformLuaLibFunction(context, LuaLibFeature.FunctionCall, node, caller, ...params); + default: + throw UnsupportedProperty("function", expressionName, node); + } +} diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts new file mode 100644 index 000000000..2021951a5 --- /dev/null +++ b/src/transformation/builtins/global.ts @@ -0,0 +1,34 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isNumberType } from "../utils/typescript"; +import { transformArguments } from "../visitors/call"; + +export function transformGlobalCall( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression | undefined { + const signature = context.checker.getResolvedSignature(node); + const parameters = transformArguments(context, node.arguments, signature); + const expressionType = context.checker.getTypeAtLocation(node.expression); + const name = expressionType.symbol.name; + switch (name) { + case "SymbolConstructor": + return transformLuaLibFunction(context, LuaLibFeature.Symbol, node, ...parameters); + case "NumberConstructor": + return transformLuaLibFunction(context, LuaLibFeature.Number, node, ...parameters); + case "isNaN": + case "isFinite": + const numberParameters = isNumberType(context, expressionType) + ? parameters + : [transformLuaLibFunction(context, LuaLibFeature.Number, undefined, ...parameters)]; + + return transformLuaLibFunction( + context, + name === "isNaN" ? LuaLibFeature.NumberIsNaN : LuaLibFeature.NumberIsFinite, + node, + ...numberParameters + ); + } +} diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts new file mode 100644 index 000000000..bafe16d2a --- /dev/null +++ b/src/transformation/builtins/index.ts @@ -0,0 +1,136 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; +import { getIdentifierSymbolId } from "../utils/symbols"; +import { isArrayType, isFunctionType, isNumberType, isStandardLibraryType, isStringType } from "../utils/typescript"; +import { PropertyCallExpression } from "../visitors/call"; +import { checkForLuaLibType } from "../visitors/class/new"; +import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; +import { transformConsoleCall } from "./console"; +import { transformFunctionPrototypeCall } from "./function"; +import { transformGlobalCall } from "./global"; +import { transformMathCall, transformMathProperty } from "./math"; +import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; +import { transformObjectConstructorCall, transformObjectPrototypeCall } from "./object"; +import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; +import { transformSymbolConstructorCall } from "./symbol"; + +export function transformBuiltinPropertyAccessExpression( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { + const type = context.checker.getTypeAtLocation(node.expression); + if (isStringType(context, type)) { + return transformStringProperty(context, node); + } else if (isArrayType(context, type)) { + const arrayPropertyAccess = transformArrayProperty(context, node); + if (arrayPropertyAccess) { + return arrayPropertyAccess; + } + } + + if (ts.isIdentifier(node.expression)) { + const ownerType = context.checker.getTypeAtLocation(node.expression); + + if (isStandardLibraryType(context, ownerType, "Math")) { + return transformMathProperty(node); + } else if (isStandardLibraryType(context, ownerType, "Symbol")) { + // Pull in Symbol lib + importLuaLibFeature(context, LuaLibFeature.Symbol); + } + } +} + +export function transformBuiltinCallExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression | undefined { + const expressionType = context.checker.getTypeAtLocation(node.expression); + if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, expressionType, undefined)) { + // TODO: + checkForLuaLibType(context, expressionType); + const result = transformGlobalCall(context, node); + if (result) { + return result; + } + } + + if (!ts.isPropertyAccessExpression(node.expression)) { + return; + } + + // TODO(TypeScript 3.7): assume + const propertyCall = node as PropertyCallExpression; + + // If the function being called is of type owner.func, get the type of owner + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + + if (isStandardLibraryType(context, ownerType, undefined)) { + const symbol = ownerType.getSymbol(); + const symbolName = symbol && symbol.name; + switch (symbolName) { + case "Console": + return transformConsoleCall(context, propertyCall); + case "Math": + return transformMathCall(context, propertyCall); + case "StringConstructor": + return transformStringConstructorCall(context, propertyCall); + case "ObjectConstructor": + return transformObjectConstructorCall(context, propertyCall); + case "SymbolConstructor": + return transformSymbolConstructorCall(context, propertyCall); + case "NumberConstructor": + return transformNumberConstructorCall(context, propertyCall); + } + } + + if (isStringType(context, ownerType)) { + return transformStringPrototypeCall(context, propertyCall); + } + + if (isNumberType(context, ownerType)) { + return transformNumberPrototypeCall(context, propertyCall); + } + + if (isArrayType(context, ownerType)) { + const result = transformArrayPrototypeCall(context, propertyCall); + if (result) { + return result; + } + } + + if (isFunctionType(context, ownerType)) { + return transformFunctionPrototypeCall(context, propertyCall); + } + + const objectResult = transformObjectPrototypeCall(context, propertyCall); + if (objectResult) { + return objectResult; + } +} + +export function transformBuiltinIdentifierExpression( + context: TransformationContext, + node: ts.Identifier +): lua.Expression | undefined { + switch (node.text) { + case "NaN": + return lua.createParenthesizedExpression( + lua.createBinaryExpression( + lua.createNumericLiteral(0), + lua.createNumericLiteral(0), + lua.SyntaxKind.DivisionOperator, + node + ) + ); + + case "Infinity": + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, node); + + case "globalThis": + return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node), "globalThis"); + } +} diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts new file mode 100644 index 000000000..5daf2d24a --- /dev/null +++ b/src/transformation/builtins/math.ts @@ -0,0 +1,97 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function transformMathProperty(node: ts.PropertyAccessExpression): lua.Expression { + const name = node.name.text; + switch (name) { + case "PI": + const property = lua.createStringLiteral("pi", node.name); + const math = lua.createIdentifier("math", node.expression); + return lua.createTableIndexExpression(math, property, node); + + case "E": + case "LN10": + case "LN2": + case "LOG10E": + case "LOG2E": + case "SQRT1_2": + case "SQRT2": + return lua.createNumericLiteral(Math[name], node); + + default: + throw UnsupportedProperty("Math", name, node); + } +} + +export function transformMathCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + // math.tan(x / y) + case "atan2": { + const math = lua.createIdentifier("math"); + const atan = lua.createStringLiteral("atan"); + const div = lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.DivisionOperator); + return lua.createCallExpression(lua.createTableIndexExpression(math, atan), [div], node); + } + + // (math.log(x) / Math.LNe) + case "log10": + case "log2": { + const math = lua.createIdentifier("math"); + const log1 = lua.createTableIndexExpression(math, lua.createStringLiteral("log")); + const logCall1 = lua.createCallExpression(log1, params); + const e = lua.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); + const div = lua.createBinaryExpression(logCall1, e, lua.SyntaxKind.DivisionOperator); + return lua.createParenthesizedExpression(div, node); + } + + // math.log(1 + x) + case "log1p": { + const math = lua.createIdentifier("math"); + const log = lua.createStringLiteral("log"); + const one = lua.createNumericLiteral(1); + const add = lua.createBinaryExpression(one, params[0], lua.SyntaxKind.AdditionOperator); + return lua.createCallExpression(lua.createTableIndexExpression(math, log), [add], node); + } + + // math.floor(x + 0.5) + case "round": { + const math = lua.createIdentifier("math"); + const floor = lua.createStringLiteral("floor"); + const half = lua.createNumericLiteral(0.5); + const add = lua.createBinaryExpression(params[0], half, lua.SyntaxKind.AdditionOperator); + return lua.createCallExpression(lua.createTableIndexExpression(math, floor), [add], node); + } + + case "abs": + case "acos": + case "asin": + case "atan": + case "ceil": + case "cos": + case "exp": + case "floor": + case "log": + case "max": + case "min": + case "pow": + case "random": + case "sin": + case "sqrt": + case "tan": { + const math = lua.createIdentifier("math"); + const method = lua.createStringLiteral(expressionName); + return lua.createCallExpression(lua.createTableIndexExpression(math, method), params, node); + } + + default: + throw UnsupportedProperty("Math", expressionName, expression); + } +} diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts new file mode 100644 index 000000000..9200be74a --- /dev/null +++ b/src/transformation/builtins/number.ts @@ -0,0 +1,42 @@ +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function transformNumberPrototypeCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + const caller = context.transformExpression(expression.expression); + + const expressionName = expression.name.text; + switch (expressionName) { + case "toString": + return params.length === 0 + ? lua.createCallExpression(lua.createIdentifier("tostring"), [caller], node) + : transformLuaLibFunction(context, LuaLibFeature.NumberToString, node, caller, ...params); + default: + throw UnsupportedProperty("number", expressionName, node); + } +} + +export function transformNumberConstructorCall( + context: TransformationContext, + expression: PropertyCallExpression +): lua.CallExpression { + const method = expression.expression; + const parameters = transformArguments(context, expression.arguments); + const methodName = method.name.text; + switch (methodName) { + case "isNaN": + return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, expression, ...parameters); + case "isFinite": + return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, expression, ...parameters); + default: + throw UnsupportedProperty("Number", methodName, expression); + } +} diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts new file mode 100644 index 000000000..9f30840ba --- /dev/null +++ b/src/transformation/builtins/object.ts @@ -0,0 +1,56 @@ +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function transformObjectConstructorCall( + context: TransformationContext, + expression: PropertyCallExpression +): lua.Expression { + const method = expression.expression; + const parameters = transformArguments(context, expression.arguments); + const methodName = method.name.text; + + switch (methodName) { + case "assign": + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...parameters); + case "entries": + return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...parameters); + case "fromEntries": + return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...parameters); + case "keys": + return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...parameters); + case "values": + return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...parameters); + default: + throw UnsupportedProperty("Object", methodName, expression); + } +} + +export function transformObjectPrototypeCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + + const name = expression.name.text; + switch (name) { + case "toString": + const toStringIdentifier = lua.createIdentifier("tostring"); + return lua.createCallExpression( + toStringIdentifier, + [context.transformExpression(expression.expression)], + node + ); + case "hasOwnProperty": + const expr = context.transformExpression(expression.expression); + const parameters = transformArguments(context, node.arguments, signature); + const rawGetIdentifier = lua.createIdentifier("rawget"); + const rawGetCall = lua.createCallExpression(rawGetIdentifier, [expr, ...parameters]); + return lua.createParenthesizedExpression( + lua.createBinaryExpression(rawGetCall, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator, node) + ); + } +} diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts new file mode 100644 index 000000000..e1f32a886 --- /dev/null +++ b/src/transformation/builtins/string.ts @@ -0,0 +1,191 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { createExpressionPlusOne } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformIdentifier } from "../visitors/identifier"; + +function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lua.Expression[]): lua.CallExpression { + const stringIdentifier = lua.createIdentifier("string"); + return lua.createCallExpression( + lua.createTableIndexExpression(stringIdentifier, lua.createStringLiteral(methodName)), + params, + tsOriginal + ); +} + +export function transformStringPrototypeCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + const caller = context.transformExpression(expression.expression); + + const expressionName = expression.name.text; + switch (expressionName) { + case "replace": + return transformLuaLibFunction(context, LuaLibFeature.StringReplace, node, caller, ...params); + case "concat": + return transformLuaLibFunction(context, LuaLibFeature.StringConcat, node, caller, ...params); + case "indexOf": + const stringExpression = createStringCall( + "find", + node, + caller, + params[0], + params[1] ? createExpressionPlusOne(params[1]) : lua.createNilLiteral(), + lua.createBooleanLiteral(true) + ); + + return lua.createParenthesizedExpression( + lua.createBinaryExpression( + lua.createParenthesizedExpression( + lua.createBinaryExpression( + stringExpression, + lua.createNumericLiteral(0), + lua.SyntaxKind.OrOperator + ) + ), + lua.createNumericLiteral(1), + lua.SyntaxKind.SubtractionOperator, + node + ) + ); + case "substr": + if (node.arguments.length === 1) { + const argument = context.transformExpression(node.arguments[0]); + const arg1 = createExpressionPlusOne(argument); + return createStringCall("sub", node, caller, arg1); + } else { + const arg1 = params[0]; + const arg2 = params[1]; + const sumArg = lua.createBinaryExpression( + lua.createParenthesizedExpression(arg1), + lua.createParenthesizedExpression(arg2), + lua.SyntaxKind.AdditionOperator + ); + return createStringCall("sub", node, caller, createExpressionPlusOne(arg1), sumArg); + } + case "substring": + if (node.arguments.length === 1) { + const arg1 = createExpressionPlusOne(params[0]); + return createStringCall("sub", node, caller, arg1); + } else { + const arg1 = createExpressionPlusOne(params[0]); + const arg2 = params[1]; + return createStringCall("sub", node, caller, arg1, arg2); + } + case "slice": + if (node.arguments.length === 0) { + return caller; + } else if (node.arguments.length === 1) { + const arg1 = createExpressionPlusOne(params[0]); + return createStringCall("sub", node, caller, arg1); + } else { + const arg1 = createExpressionPlusOne(params[0]); + const arg2 = params[1]; + return createStringCall("sub", node, caller, arg1, arg2); + } + case "toLowerCase": + return createStringCall("lower", node, caller); + case "toUpperCase": + return createStringCall("upper", node, caller); + case "split": + return transformLuaLibFunction(context, LuaLibFeature.StringSplit, node, caller, ...params); + case "charAt": + const firstParamPlusOne = createExpressionPlusOne(params[0]); + return createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); + case "charCodeAt": { + const firstParamPlusOne = createExpressionPlusOne(params[0]); + return createStringCall("byte", node, caller, firstParamPlusOne); + } + case "startsWith": + return transformLuaLibFunction(context, LuaLibFeature.StringStartsWith, node, caller, ...params); + case "endsWith": + return transformLuaLibFunction(context, LuaLibFeature.StringEndsWith, node, caller, ...params); + case "repeat": + const math = lua.createIdentifier("math"); + const floor = lua.createStringLiteral("floor"); + const parameter = lua.createCallExpression(lua.createTableIndexExpression(math, floor), [params[0]]); + return createStringCall("rep", node, caller, parameter); + case "padStart": + return transformLuaLibFunction(context, LuaLibFeature.StringPadStart, node, caller, ...params); + case "padEnd": + return transformLuaLibFunction(context, LuaLibFeature.StringPadEnd, node, caller, ...params); + + case "byte": + case "char": + case "dump": + case "find": + case "format": + case "gmatch": + case "gsub": + case "len": + case "lower": + case "match": + case "pack": + case "packsize": + case "rep": + case "reverse": + case "sub": + case "unpack": + case "upper": + // Allow lua's string instance methods + let stringVariable = context.transformExpression(expression.expression); + if (ts.isStringLiteralLike(expression.expression)) { + // "foo":method() needs to be ("foo"):method() + stringVariable = lua.createParenthesizedExpression(stringVariable); + } + + return lua.createMethodCallExpression( + stringVariable, + transformIdentifier(context, expression.name), + params, + node + ); + default: + throw UnsupportedProperty("string", expressionName, node); + } +} + +export function transformStringConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "fromCharCode": + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("char")), + params, + node + ); + + default: + throw UnsupportedProperty("String", expressionName, node); + } +} + +export function transformStringProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.UnaryExpression { + switch (node.name.text) { + case "length": + let expression = context.transformExpression(node.expression); + if (ts.isTemplateExpression(node.expression)) { + expression = lua.createParenthesizedExpression(expression); + } + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + default: + throw UnsupportedProperty("string", node.name.text, node); + } +} diff --git a/src/transformation/builtins/symbol.ts b/src/transformation/builtins/symbol.ts new file mode 100644 index 000000000..4a6e5e43f --- /dev/null +++ b/src/transformation/builtins/symbol.ts @@ -0,0 +1,26 @@ +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { UnsupportedProperty } from "../utils/errors"; +import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +// Transpile a Symbol._ property +export function transformSymbolConstructorCall( + context: TransformationContext, + expression: PropertyCallExpression +): lua.CallExpression { + const method = expression.expression; + const signature = context.checker.getResolvedSignature(expression); + const parameters = transformArguments(context, expression.arguments, signature); + const methodName = method.name.text; + switch (methodName) { + case "for": + case "keyFor": + importLuaLibFeature(context, LuaLibFeature.SymbolRegistry); + const upperMethodName = methodName[0].toUpperCase() + methodName.slice(1); + const functionIdentifier = lua.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); + return lua.createCallExpression(functionIdentifier, parameters, expression); + default: + throw UnsupportedProperty("Symbol", methodName, expression); + } +} diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts new file mode 100644 index 000000000..9e5cdcfc9 --- /dev/null +++ b/src/transformation/context/context.ts @@ -0,0 +1,96 @@ +import * as ts from "typescript"; +import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; +import * as lua from "../../LuaAST"; +import { flatMap } from "../../utils"; +import { unwrapVisitorResult } from "../utils/lua-ast"; +import { isFileModule } from "../utils/typescript"; +import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; + +export interface EmitResolver { + isValueAliasDeclaration(node: ts.Node): boolean; + isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; + isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; + moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; +} + +export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { + getEmitResolver(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): EmitResolver; +} + +export class TransformationContext { + public readonly checker: DiagnosticsProducingTypeChecker = (this + .program as any).getDiagnosticsProducingTypeChecker(); + public readonly resolver: EmitResolver; + + public readonly options: CompilerOptions = this.program.getCompilerOptions(); + public readonly luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; + public readonly isModule = isFileModule(this.sourceFile); + public readonly isStrict = + this.options.alwaysStrict !== undefined || + (this.options.strict !== undefined && this.options.alwaysStrict !== false) || + (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); + + public constructor(public program: ts.Program, public sourceFile: ts.SourceFile, private visitorMap: VisitorMap) { + // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. + // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` + // and would try to re-analyze the file, which would fail because of replaced nodes. + const originalSourceFile = ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; + this.resolver = this.checker.getEmitResolver(originalSourceFile); + } + + private currentNodeVisitors: Array> = []; + public transformNode(node: ts.Node): lua.Node[] { + // TODO: Move to visitors? + if (node.modifiers && node.modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { + return []; + } + + const nodeVisitors = this.visitorMap.get(node.kind); + if (!nodeVisitors || nodeVisitors.length === 0) { + throw new Error(`${ts.SyntaxKind[node.kind]} is not supported`); + } + + const previousNodeVisitors = this.currentNodeVisitors; + this.currentNodeVisitors = [...nodeVisitors]; + + const visitor = this.currentNodeVisitors.pop()!; + const result = unwrapVisitorResult(visitor.transform(node, this)); + + this.currentNodeVisitors = previousNodeVisitors; + + return result; + } + + public superTransformNode(node: ts.Node): lua.Node[] { + if (this.currentNodeVisitors.length === 0) { + throw new Error(`There is no super transform for ${ts.SyntaxKind[node.kind]} visitor`); + } + + const visitor = this.currentNodeVisitors.pop()!; + return unwrapVisitorResult(visitor.transform(node, this)); + } + + public transformExpression(node: ExpressionLikeNode): lua.Expression { + const [result] = this.transformNode(node); + return result as lua.Expression; + } + + public superTransformExpression(node: ExpressionLikeNode): lua.Expression { + const [result] = this.superTransformNode(node); + return result as lua.Expression; + } + + public transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { + return Array.isArray(node) + ? flatMap(node, n => this.transformStatements(n)) + : // TODO: https://github.com/microsoft/TypeScript/pull/28916 + (this.transformNode(node as StatementLikeNode) as lua.Statement[]); + } + + public superTransformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { + return Array.isArray(node) + ? flatMap(node, n => this.superTransformStatements(n)) + : // TODO: https://github.com/microsoft/TypeScript/pull/28916 + (this.superTransformNode(node as StatementLikeNode) as lua.Statement[]); + } +} diff --git a/src/transformation/context/index.ts b/src/transformation/context/index.ts new file mode 100644 index 000000000..349cb7332 --- /dev/null +++ b/src/transformation/context/index.ts @@ -0,0 +1,2 @@ +export * from "./context"; +export * from "./visitors"; diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts new file mode 100644 index 000000000..7acdba43e --- /dev/null +++ b/src/transformation/context/visitors.ts @@ -0,0 +1,164 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { OneToManyVisitorResult } from "../utils/lua-ast"; +import { TransformationContext } from "./context"; + +type NodesBySyntaxKind = { + // Copied from is* type guards, with JSDoc and TypeNodes removed + [ts.SyntaxKind.NumericLiteral]: ts.NumericLiteral; + [ts.SyntaxKind.BigIntLiteral]: ts.BigIntLiteral; + [ts.SyntaxKind.StringLiteral]: ts.StringLiteral; + [ts.SyntaxKind.JsxText]: ts.JsxText; + [ts.SyntaxKind.RegularExpressionLiteral]: ts.RegularExpressionLiteral; + [ts.SyntaxKind.NoSubstitutionTemplateLiteral]: ts.NoSubstitutionTemplateLiteral; + [ts.SyntaxKind.TemplateHead]: ts.TemplateHead; + [ts.SyntaxKind.TemplateMiddle]: ts.TemplateMiddle; + [ts.SyntaxKind.TemplateTail]: ts.TemplateTail; + [ts.SyntaxKind.Identifier]: ts.Identifier; + [ts.SyntaxKind.QualifiedName]: ts.QualifiedName; + [ts.SyntaxKind.ComputedPropertyName]: ts.ComputedPropertyName; + [ts.SyntaxKind.TypeParameter]: ts.TypeParameterDeclaration; + [ts.SyntaxKind.Parameter]: ts.ParameterDeclaration; + [ts.SyntaxKind.Decorator]: ts.Decorator; + [ts.SyntaxKind.PropertySignature]: ts.PropertySignature; + [ts.SyntaxKind.PropertyDeclaration]: ts.PropertyDeclaration; + [ts.SyntaxKind.MethodSignature]: ts.MethodSignature; + [ts.SyntaxKind.MethodDeclaration]: ts.MethodDeclaration; + [ts.SyntaxKind.Constructor]: ts.ConstructorDeclaration; + [ts.SyntaxKind.GetAccessor]: ts.GetAccessorDeclaration; + [ts.SyntaxKind.SetAccessor]: ts.SetAccessorDeclaration; + [ts.SyntaxKind.CallSignature]: ts.CallSignatureDeclaration; + [ts.SyntaxKind.ConstructSignature]: ts.ConstructSignatureDeclaration; + [ts.SyntaxKind.IndexSignature]: ts.IndexSignatureDeclaration; + [ts.SyntaxKind.ObjectBindingPattern]: ts.ObjectBindingPattern; + [ts.SyntaxKind.ArrayBindingPattern]: ts.ArrayBindingPattern; + [ts.SyntaxKind.BindingElement]: ts.BindingElement; + [ts.SyntaxKind.ArrayLiteralExpression]: ts.ArrayLiteralExpression; + [ts.SyntaxKind.ObjectLiteralExpression]: ts.ObjectLiteralExpression; + [ts.SyntaxKind.PropertyAccessExpression]: ts.PropertyAccessExpression; + [ts.SyntaxKind.ElementAccessExpression]: ts.ElementAccessExpression; + [ts.SyntaxKind.CallExpression]: ts.CallExpression; + [ts.SyntaxKind.NewExpression]: ts.NewExpression; + [ts.SyntaxKind.TaggedTemplateExpression]: ts.TaggedTemplateExpression; + [ts.SyntaxKind.TypeAssertionExpression]: ts.TypeAssertion; + [ts.SyntaxKind.ParenthesizedExpression]: ts.ParenthesizedExpression; + [ts.SyntaxKind.FunctionExpression]: ts.FunctionExpression; + [ts.SyntaxKind.ArrowFunction]: ts.ArrowFunction; + [ts.SyntaxKind.DeleteExpression]: ts.DeleteExpression; + [ts.SyntaxKind.TypeOfExpression]: ts.TypeOfExpression; + [ts.SyntaxKind.VoidExpression]: ts.VoidExpression; + [ts.SyntaxKind.AwaitExpression]: ts.AwaitExpression; + [ts.SyntaxKind.PrefixUnaryExpression]: ts.PrefixUnaryExpression; + [ts.SyntaxKind.PostfixUnaryExpression]: ts.PostfixUnaryExpression; + [ts.SyntaxKind.BinaryExpression]: ts.BinaryExpression; + [ts.SyntaxKind.ConditionalExpression]: ts.ConditionalExpression; + [ts.SyntaxKind.TemplateExpression]: ts.TemplateExpression; + [ts.SyntaxKind.YieldExpression]: ts.YieldExpression; + [ts.SyntaxKind.SpreadElement]: ts.SpreadElement; + [ts.SyntaxKind.ClassExpression]: ts.ClassExpression; + [ts.SyntaxKind.OmittedExpression]: ts.OmittedExpression; + [ts.SyntaxKind.ExpressionWithTypeArguments]: ts.ExpressionWithTypeArguments; + [ts.SyntaxKind.AsExpression]: ts.AsExpression; + [ts.SyntaxKind.NonNullExpression]: ts.NonNullExpression; + [ts.SyntaxKind.MetaProperty]: ts.MetaProperty; + [ts.SyntaxKind.TemplateSpan]: ts.TemplateSpan; + [ts.SyntaxKind.SemicolonClassElement]: ts.SemicolonClassElement; + [ts.SyntaxKind.Block]: ts.Block; + [ts.SyntaxKind.VariableStatement]: ts.VariableStatement; + [ts.SyntaxKind.EmptyStatement]: ts.EmptyStatement; + [ts.SyntaxKind.ExpressionStatement]: ts.ExpressionStatement; + [ts.SyntaxKind.IfStatement]: ts.IfStatement; + [ts.SyntaxKind.DoStatement]: ts.DoStatement; + [ts.SyntaxKind.WhileStatement]: ts.WhileStatement; + [ts.SyntaxKind.ForStatement]: ts.ForStatement; + [ts.SyntaxKind.ForInStatement]: ts.ForInStatement; + [ts.SyntaxKind.ForOfStatement]: ts.ForOfStatement; + [ts.SyntaxKind.ContinueStatement]: ts.ContinueStatement; + [ts.SyntaxKind.BreakStatement]: ts.BreakStatement; + [ts.SyntaxKind.ReturnStatement]: ts.ReturnStatement; + [ts.SyntaxKind.WithStatement]: ts.WithStatement; + [ts.SyntaxKind.SwitchStatement]: ts.SwitchStatement; + [ts.SyntaxKind.LabeledStatement]: ts.LabeledStatement; + [ts.SyntaxKind.ThrowStatement]: ts.ThrowStatement; + [ts.SyntaxKind.TryStatement]: ts.TryStatement; + [ts.SyntaxKind.DebuggerStatement]: ts.DebuggerStatement; + [ts.SyntaxKind.VariableDeclaration]: ts.VariableDeclaration; + [ts.SyntaxKind.VariableDeclarationList]: ts.VariableDeclarationList; + [ts.SyntaxKind.FunctionDeclaration]: ts.FunctionDeclaration; + [ts.SyntaxKind.ClassDeclaration]: ts.ClassDeclaration; + [ts.SyntaxKind.InterfaceDeclaration]: ts.InterfaceDeclaration; + [ts.SyntaxKind.TypeAliasDeclaration]: ts.TypeAliasDeclaration; + [ts.SyntaxKind.EnumDeclaration]: ts.EnumDeclaration; + [ts.SyntaxKind.ModuleDeclaration]: ts.ModuleDeclaration; + [ts.SyntaxKind.ModuleBlock]: ts.ModuleBlock; + [ts.SyntaxKind.CaseBlock]: ts.CaseBlock; + [ts.SyntaxKind.NamespaceExportDeclaration]: ts.NamespaceExportDeclaration; + [ts.SyntaxKind.ImportEqualsDeclaration]: ts.ImportEqualsDeclaration; + [ts.SyntaxKind.ImportDeclaration]: ts.ImportDeclaration; + [ts.SyntaxKind.ImportClause]: ts.ImportClause; + [ts.SyntaxKind.NamespaceImport]: ts.NamespaceImport; + [ts.SyntaxKind.NamedImports]: ts.NamedImports; + [ts.SyntaxKind.ImportSpecifier]: ts.ImportSpecifier; + [ts.SyntaxKind.ExportAssignment]: ts.ExportAssignment; + [ts.SyntaxKind.ExportDeclaration]: ts.ExportDeclaration; + [ts.SyntaxKind.NamedExports]: ts.NamedExports; + [ts.SyntaxKind.ExportSpecifier]: ts.ExportSpecifier; + [ts.SyntaxKind.MissingDeclaration]: ts.MissingDeclaration; + [ts.SyntaxKind.ExternalModuleReference]: ts.ExternalModuleReference; + [ts.SyntaxKind.JsxElement]: ts.JsxElement; + [ts.SyntaxKind.JsxSelfClosingElement]: ts.JsxSelfClosingElement; + [ts.SyntaxKind.JsxOpeningElement]: ts.JsxOpeningElement; + [ts.SyntaxKind.JsxClosingElement]: ts.JsxClosingElement; + [ts.SyntaxKind.JsxFragment]: ts.JsxFragment; + [ts.SyntaxKind.JsxOpeningFragment]: ts.JsxOpeningFragment; + [ts.SyntaxKind.JsxClosingFragment]: ts.JsxClosingFragment; + [ts.SyntaxKind.JsxAttribute]: ts.JsxAttribute; + [ts.SyntaxKind.JsxAttributes]: ts.JsxAttributes; + [ts.SyntaxKind.JsxSpreadAttribute]: ts.JsxSpreadAttribute; + [ts.SyntaxKind.JsxExpression]: ts.JsxExpression; + [ts.SyntaxKind.CaseClause]: ts.CaseClause; + [ts.SyntaxKind.DefaultClause]: ts.DefaultClause; + [ts.SyntaxKind.HeritageClause]: ts.HeritageClause; + [ts.SyntaxKind.CatchClause]: ts.CatchClause; + [ts.SyntaxKind.PropertyAssignment]: ts.PropertyAssignment; + [ts.SyntaxKind.ShorthandPropertyAssignment]: ts.ShorthandPropertyAssignment; + [ts.SyntaxKind.SpreadAssignment]: ts.SpreadAssignment; + [ts.SyntaxKind.EnumMember]: ts.EnumMember; + [ts.SyntaxKind.SourceFile]: ts.SourceFile; + // [ts.SyntaxKind.Bundle]: ts.Bundle; + + // Not included above + [ts.SyntaxKind.TrueKeyword]: ts.BooleanLiteral; + [ts.SyntaxKind.FalseKeyword]: ts.BooleanLiteral; + [ts.SyntaxKind.NullKeyword]: ts.NullLiteral; + [ts.SyntaxKind.SuperKeyword]: ts.SuperExpression; + [ts.SyntaxKind.ThisKeyword]: ts.ThisExpression; +}; + +export type ExpressionLikeNode = ts.Expression | ts.QualifiedName | ts.ExternalModuleReference; +export type StatementLikeNode = ts.Statement; +export type VisitorResult = T extends ExpressionLikeNode + ? lua.Expression + : T extends StatementLikeNode + ? OneToManyVisitorResult + : T extends ts.SourceFile + ? lua.Block + : OneToManyVisitorResult; + +export type Visitor = FunctionVisitor | ObjectVisitor; +export type FunctionVisitor = (node: T, context: TransformationContext) => VisitorResult; +export type ObjectVisitor = { + transform: FunctionVisitor; + + /** + * Visitors with higher priority are called first. + * + * Higher-priority visitors can call lower ones with `context.superTransformNode`. + * + * Standard visitors have the lowest (`-Infinity`) priority. + */ + priority?: number; +}; + +export type Visitors = { [P in keyof NodesBySyntaxKind]?: Visitor }; +export type VisitorMap = Map>>; diff --git a/src/transformation/index.ts b/src/transformation/index.ts new file mode 100644 index 000000000..198a0c9c7 --- /dev/null +++ b/src/transformation/index.ts @@ -0,0 +1,74 @@ +import * as ts from "typescript"; +import * as lua from "../LuaAST"; +import { LuaLibFeature } from "../LuaLib"; +import { getOrUpdate } from "../utils"; +import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; +import { TranspileError } from "./utils/errors"; +import { getUsedLuaLibFeatures } from "./utils/lualib"; +import { standardVisitors } from "./visitors"; + +const transpileErrorDiagnostic = (error: TranspileError): ts.Diagnostic => ({ + file: error.node.getSourceFile(), + start: error.node.getStart(), + length: error.node.getWidth(), + category: ts.DiagnosticCategory.Error, + code: 0, + source: "typescript-to-lua", + messageText: error.message, +}); + +export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { + const visitorMap: VisitorMap = new Map(); + for (const visitors of [standardVisitors, ...customVisitors]) { + const priority = visitors === standardVisitors ? -Infinity : 0; + for (const [syntaxKindKey, visitor] of Object.entries(visitors)) { + if (!visitor) continue; + + const syntaxKind = Number(syntaxKindKey) as ts.SyntaxKind; + const nodeVisitors = getOrUpdate(visitorMap, syntaxKind, () => []); + + const objectVisitor: ObjectVisitor = + typeof visitor === "function" ? { transform: visitor, priority } : visitor; + nodeVisitors.push(objectVisitor); + } + } + + for (const nodeVisitors of visitorMap.values()) { + nodeVisitors.sort((a, b) => (a.priority || 0) - (b.priority || 0)); + } + + return visitorMap; +} + +export interface TransformSourceFileResult { + luaAst: lua.Block; + luaLibFeatures: Set; + diagnostics: ts.Diagnostic[]; +} + +export function transformSourceFile( + program: ts.Program, + sourceFile: ts.SourceFile, + visitorMap: VisitorMap +): TransformSourceFileResult { + const context = new TransformationContext(program, sourceFile, visitorMap); + + try { + const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; + const luaLibFeatures = getUsedLuaLibFeatures(context); + + return { luaAst, luaLibFeatures, diagnostics: [] }; + } catch (error) { + if (!(error instanceof TranspileError)) throw error; + + return { + luaAst: lua.createBlock([ + lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("error"), [lua.createStringLiteral(error.message)]) + ), + ]), + luaLibFeatures: new Set(), + diagnostics: [transpileErrorDiagnostic(error)], + }; + } +} diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts new file mode 100644 index 000000000..509d67826 --- /dev/null +++ b/src/transformation/utils/annotations.ts @@ -0,0 +1,205 @@ +import * as ts from "typescript"; +import { flatMap } from "../../utils"; +import { TransformationContext } from "../context"; +import { findFirstNodeAbove, inferAssignedType } from "./typescript"; + +export enum AnnotationKind { + Extension = "extension", + MetaExtension = "metaExtension", + CustomConstructor = "customConstructor", + CompileMembersOnly = "compileMembersOnly", + NoResolution = "noResolution", + PureAbstract = "pureAbstract", + Phantom = "phantom", + TupleReturn = "tupleReturn", + LuaIterator = "luaIterator", + LuaTable = "luaTable", + NoSelf = "noSelf", + NoSelfInFile = "noSelfInFile", + VarArg = "varArg", + ForRange = "forRange", +} + +export interface Annotation { + kind: AnnotationKind; + args: string[]; +} + +function createAnnotation(name: string, args: string[]): Annotation | undefined { + const kind = Object.values(AnnotationKind).find(k => k.toLowerCase() === name.toLowerCase()); + if (kind !== undefined) { + return { kind, args }; + } +} + +export type AnnotationsMap = Map; + +function collectAnnotations( + context: TransformationContext, + source: ts.Symbol | ts.Signature, + annotationsMap: AnnotationsMap +): void { + const comments = source.getDocumentationComment(context.checker); + const oldStyleAnnotations = comments + .filter(comment => comment.kind === "text") + .map(comment => comment.text.split("\n")) + .reduce((a, b) => a.concat(b), []) + .map(line => line.trim()) + .filter(comment => comment[0] === "!"); + + for (const line of oldStyleAnnotations) { + const [name, ...args] = line.slice(1).split(" "); + const annotation = createAnnotation(name, args); + if (annotation) { + annotationsMap.set(annotation.kind, annotation); + console.warn(`[Deprecated] Annotations with ! are being deprecated, use '@${annotation.kind}' instead`); + } else { + console.warn(`Encountered unknown annotation '${line}'.`); + } + } + + for (const tag of source.getJsDocTags()) { + const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []); + if (annotation) { + annotationsMap.set(annotation.kind, annotation); + } + } +} + +export function getSymbolAnnotations(context: TransformationContext, symbol: ts.Symbol): AnnotationsMap { + const annotationsMap: AnnotationsMap = new Map(); + collectAnnotations(context, symbol, annotationsMap); + return annotationsMap; +} + +export function getTypeAnnotations(context: TransformationContext, type: ts.Type): AnnotationsMap { + const annotationsMap: AnnotationsMap = new Map(); + + if (type.symbol) collectAnnotations(context, type.symbol, annotationsMap); + if (type.aliasSymbol) collectAnnotations(context, type.aliasSymbol, annotationsMap); + + return annotationsMap; +} + +export function getNodeAnnotations(node: ts.Node): AnnotationsMap { + const annotationsMap: AnnotationsMap = new Map(); + + for (const tag of ts.getJSDocTags(node)) { + const tagName = tag.tagName.text; + const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + if (annotation) { + annotationsMap.set(annotation.kind, annotation); + } + } + + return annotationsMap; +} + +export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { + const annotationsMap: AnnotationsMap = new Map(); + + if (sourceFile.statements.length > 0) { + // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment + const jsDoc = sourceFile.statements[0].jsDoc; + if (jsDoc) { + for (const tag of flatMap(jsDoc, x => x.tags || [])) { + const tagName = tag.tagName.text; + const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + if (annotation) { + annotationsMap.set(annotation.kind, annotation); + } + } + } + } + + return annotationsMap; +} + +export function getSignatureAnnotations(context: TransformationContext, signature: ts.Signature): AnnotationsMap { + const annotationsMap: AnnotationsMap = new Map(); + collectAnnotations(context, signature, annotationsMap); + + // Function properties on interfaces have the JSDoc tags on the parent PropertySignature + const declaration = signature.getDeclaration(); + if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { + const symbol = context.checker.getSymbolAtLocation(declaration.parent.name); + if (symbol) { + collectAnnotations(context, symbol, annotationsMap); + } + } + + return annotationsMap; +} + +export function isTupleReturnCall(context: TransformationContext, node: ts.Node): boolean { + if (!ts.isCallExpression(node)) { + return false; + } + + const signature = context.checker.getResolvedSignature(node); + if (signature) { + if (getSignatureAnnotations(context, signature).has(AnnotationKind.TupleReturn)) { + return true; + } + + // Only check function type for directive if it is declared as an interface or type alias + const declaration = signature.getDeclaration(); + const isInterfaceOrAlias = + declaration && + declaration.parent && + ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || + ts.isTypeAliasDeclaration(declaration.parent)); + if (!isInterfaceOrAlias) { + return false; + } + } + + const type = context.checker.getTypeAtLocation(node.expression); + return getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn); +} + +export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; + } + + let functionType: ts.Type | undefined; + if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { + functionType = inferAssignedType(context, declaration); + } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { + // Manually lookup type for object literal properties declared with method syntax + const interfaceType = inferAssignedType(context, declaration.parent); + const propertySymbol = interfaceType.getProperty(declaration.name.getText()); + if (propertySymbol) { + functionType = context.checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); + } + } + + if (functionType === undefined) { + functionType = context.checker.getTypeAtLocation(declaration); + } + + // Check all overloads for directive + const signatures = functionType.getCallSignatures(); + if (signatures && signatures.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { + return true; + } + + return getTypeAnnotations(context, functionType).has(AnnotationKind.TupleReturn); +} + +export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { + const type = context.checker.getTypeAtLocation(node); + return getTypeAnnotations(context, type).has(AnnotationKind.LuaIterator); +} + +export function isVarArgType(context: TransformationContext, node: ts.Node): boolean { + const type = context.checker.getTypeAtLocation(node); + return getTypeAnnotations(context, type).has(AnnotationKind.VarArg); +} + +export function isForRangeType(context: TransformationContext, node: ts.Node): boolean { + const type = context.checker.getTypeAtLocation(node); + return getTypeAnnotations(context, type).has(AnnotationKind.ForRange); +} diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts new file mode 100644 index 000000000..c8a57dc1d --- /dev/null +++ b/src/transformation/utils/assignment-validation.ts @@ -0,0 +1,125 @@ +import * as ts from "typescript"; +import { getOrUpdate } from "../../utils"; +import { TransformationContext } from "../context"; +import { AnnotationKind, getTypeAnnotations } from "./annotations"; +import { + ForbiddenLuaTableUseException, + UnsupportedNoSelfFunctionConversion, + UnsupportedOverloadAssignment, + UnsupportedSelfFunctionConversion, +} from "./errors"; +import { ContextType, getFunctionContextType } from "./function-context"; + +// TODO: Make validateAssignment check symbols? +// TODO: Move to LuaTable plugin? +export function validatePropertyAssignment( + context: TransformationContext, + node: ts.AssignmentExpression +): void { + if (!ts.isPropertyAccessExpression(node.left)) return; + + const leftType = context.checker.getTypeAtLocation(node.left.expression); + const annotations = getTypeAnnotations(context, leftType); + if (annotations.has(AnnotationKind.LuaTable) && node.left.name.text === "length") { + throw ForbiddenLuaTableUseException(`A LuaTable object's length cannot be re-assigned.`, node); + } +} + +// TODO: Clear if types are reused between compilations +const typeValidationCache = new WeakMap>(); + +export function validateAssignment( + context: TransformationContext, + node: ts.Node, + fromType: ts.Type, + toType: ts.Type, + toName?: string +): void { + if (toType === fromType) { + return; + } + + if ((toType.flags & ts.TypeFlags.Any) !== 0) { + // Assigning to un-typed variable + return; + } + + // Use cache to avoid repeating check for same types (protects against infinite loop in recursive types) + const fromTypeCache = getOrUpdate(typeValidationCache, fromType, () => new Set()); + if (fromTypeCache.has(toType)) return; + fromTypeCache.add(toType); + + validateFunctionAssignment(context, node, fromType, toType, toName); + + const fromTypeNode = context.checker.typeToTypeNode(fromType); + const toTypeNode = context.checker.typeToTypeNode(toType); + if (!fromTypeNode || !toTypeNode) { + return; + } + + if ( + (ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && + (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode)) + ) { + // Recurse into arrays/tuples + const fromTypeArguments = (fromType as ts.TypeReference).typeArguments; + const toTypeArguments = (toType as ts.TypeReference).typeArguments; + + if (fromTypeArguments === undefined || toTypeArguments === undefined) { + return; + } + + const count = Math.min(fromTypeArguments.length, toTypeArguments.length); + for (let i = 0; i < count; ++i) { + validateAssignment(context, node, fromTypeArguments[i], toTypeArguments[i], toName); + } + } + + if ( + (toType.flags & ts.TypeFlags.Object) !== 0 && + ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0 && + toType.symbol && + toType.symbol.members && + fromType.symbol && + fromType.symbol.members + ) { + // Recurse into interfaces + toType.symbol.members.forEach((toMember, memberName) => { + if (fromType.symbol.members) { + const fromMember = fromType.symbol.members.get(memberName); + if (fromMember) { + const toMemberType = context.checker.getTypeOfSymbolAtLocation(toMember, node); + const fromMemberType = context.checker.getTypeOfSymbolAtLocation(fromMember, node); + validateAssignment( + context, + node, + fromMemberType, + toMemberType, + toName ? `${toName}.${memberName}` : memberName.toString() + ); + } + } + }); + } +} + +function validateFunctionAssignment( + context: TransformationContext, + node: ts.Node, + fromType: ts.Type, + toType: ts.Type, + toName?: string +): void { + const fromContext = getFunctionContextType(context, fromType); + const toContext = getFunctionContextType(context, toType); + + if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { + throw UnsupportedOverloadAssignment(node, toName); + } else if (fromContext !== toContext && fromContext !== ContextType.None && toContext !== ContextType.None) { + if (toContext === ContextType.Void) { + throw UnsupportedNoSelfFunctionConversion(node, toName); + } else { + throw UnsupportedSelfFunctionConversion(node, toName); + } + } +} diff --git a/src/TSTLErrors.ts b/src/transformation/utils/errors.ts similarity index 57% rename from src/TSTLErrors.ts rename to src/transformation/utils/errors.ts index c32318f45..ea741e967 100644 --- a/src/TSTLErrors.ts +++ b/src/transformation/utils/errors.ts @@ -1,20 +1,23 @@ import * as ts from "typescript"; -import { LuaTarget } from "./CompilerOptions"; -import { TranspileError } from "./TranspileError"; +import { LuaTarget } from "../../CompilerOptions"; -const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); +export class TranspileError extends Error { + public name = "TranspileError"; + constructor(message: string, public node: ts.Node) { + super(message); + } +} -export const CouldNotCast = (castName: string) => - new Error(`Failed to cast all elements to expected type using ${castName}.`); +const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export const ForbiddenForIn = (node: ts.Node) => new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); export const ForbiddenLuaTableNonDeclaration = (node: ts.Node) => - new TranspileError(`Classes with the '@luaTable' decorator must be declared.`, node); + new TranspileError(`Classes with the '@luaTable' annotation must be declared.`, node); export const InvalidExtendsLuaTable = (node: ts.Node) => - new TranspileError(`Cannot extend classes with the decorator '@luaTable'.`, node); + new TranspileError(`Cannot extend classes with the '@luaTable' annotation.`, node); export const InvalidInstanceOfLuaTable = (node: ts.Node) => new TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node); @@ -22,38 +25,32 @@ export const InvalidInstanceOfLuaTable = (node: ts.Node) => export const ForbiddenLuaTableUseException = (description: string, node: ts.Node) => new TranspileError(`Invalid @luaTable usage: ${description}`, node); -export const InvalidDecoratorArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => - new TranspileError(`${name} expects ${expected} argument(s) but got ${got}.`, node); +export const InvalidAnnotationArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => + new TranspileError(`'${name}' expects ${expected} argument(s) but got ${got}.`, node); export const InvalidDecoratorContext = (node: ts.Node) => new TranspileError(`Decorator function cannot have 'this: void'.`, node); export const InvalidExtensionMetaExtension = (node: ts.Node) => - new TranspileError(`Cannot use both '@extension' and '@metaExtension' decorators on the same class.`, node); + new TranspileError(`Cannot use both '@extension' and '@metaExtension' annotations on the same class.`, node); export const InvalidNewExpressionOnExtension = (node: ts.Node) => - new TranspileError(`Cannot construct classes with decorator '@extension' or '@metaExtension'.`, node); + new TranspileError(`Cannot construct classes with '@extension' or '@metaExtension' annotation.`, node); export const InvalidExportDeclaration = (declaration: ts.ExportDeclaration) => new TranspileError("Encountered invalid export declaration without exports and without module.", declaration); export const InvalidExtendsExtension = (node: ts.Node) => - new TranspileError(`Cannot extend classes with decorator '@extension' or '@metaExtension'.`, node); + new TranspileError(`Cannot extend classes with '@extension' or '@metaExtension' annotation.`, node); export const InvalidExportsExtension = (node: ts.Node) => - new TranspileError(`Cannot export classes with decorator '@extension' or '@metaExtension'.`, node); + new TranspileError(`Cannot export classes with '@extension' or '@metaExtension' annotation.`, node); export const InvalidInstanceOfExtension = (node: ts.Node) => - new TranspileError(`Cannot use instanceof on classes with decorator '@extension' or '@metaExtension'.`, node); + new TranspileError(`Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation.`, node); export const InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); -export const InvalidPropertyCall = (node: ts.Node) => - new TranspileError(`Tried to transpile a non-property call as property call.`, node); - -export const InvalidElementCall = (node: ts.Node) => - new TranspileError(`Tried to transpile a non-element call as an element call.`, node); - export const ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); @@ -66,7 +63,7 @@ export const MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => new TranspileError("Unsupported function declaration without name.", declaration); export const MissingMetaExtension = (node: ts.Node) => - new TranspileError(`@metaExtension requires the extension of the metatable class.`, node); + new TranspileError(`'@metaExtension' annotation requires the extension of the metatable class.`, node); export const NonFlattenableDestructure = (node: ts.Node) => new TranspileError(`This node cannot be destructured using a standard Lua assignment statement.`, node); @@ -74,8 +71,8 @@ export const NonFlattenableDestructure = (node: ts.Node) => export const UndefinedFunctionDefinition = (functionSymbolId: number) => new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); -export const UnsupportedForInVariable = (initializer: ts.Node) => - new TranspileError(`Unsuppored for-in variable kind.`, initializer); +export const UnsupportedForInVariable = (node: ts.Node) => + new TranspileError(`Unsupported for-in variable kind.`, node); export const UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); @@ -99,85 +96,58 @@ export const UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) new TranspileError("Functions with undefined bodies are not supported.", node); export const UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unable to convert function with a 'this' parameter to function "${name}" with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node - ); - } else { - return new TranspileError( - `Unable to convert function with a 'this' parameter to function with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node - ); - } + const nameReference = name ? ` '${name}'` : ""; + return new TranspileError( + `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.`, + node + ); }; export const UnsupportedSelfFunctionConversion = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unable to convert function with no 'this' parameter to function "${name}" with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node - ); - } else { - return new TranspileError( - `Unable to convert function with no 'this' parameter to function with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node - ); - } + const nameReference = name ? ` '${name}'` : ""; + return new TranspileError( + `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + + `To fix, wrap in an arrow function or declare with 'this: any'.`, + node + ); }; export const UnsupportedOverloadAssignment = (node: ts.Node, name?: string) => { - if (name) { - return new TranspileError( - `Unsupported assignment of function with different overloaded types for 'this' to "${name}". ` + - `Overloads should all have the same type for 'this'.`, - node - ); - } else { - return new TranspileError( - `Unsupported assignment of function with different overloaded types for 'this'. ` + - `Overloads should all have the same type for 'this'.`, - node - ); - } + const nameReference = name ? ` to '${name}'` : ""; + return new TranspileError( + `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + + "Overloads should all have the same type for 'this'.", + node + ); }; -export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => { - return new TranspileError( - "Unsupported use of lua iterator with TupleReturn decorator in for...of statement. " + +export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => + new TranspileError( + "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + "You must use a destructuring statement to catch results from a lua iterator with " + - "the TupleReturn decorator.", + "the '@tupleReturn' annotation.", node ); -}; -export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => { - return new TranspileError(`${reason}. ` + `TypeScript path: ${path}.`, node); -}; +export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => + new TranspileError(`${reason}. TypeScript path: ${path}.`, node); -export const ReferencedBeforeDeclaration = (node: ts.Identifier) => { - return new TranspileError( +export const ReferencedBeforeDeclaration = (node: ts.Identifier) => + new TranspileError( `Identifier "${node.text}" was referenced before it was declared. The declaration ` + "must be moved before the identifier's use, or hoisting must be enabled.", node ); -}; -export const UnsupportedObjectDestructuringInForOf = (node: ts.Node) => { - return new TranspileError(`Unsupported object destructuring in for...of statement.`, node); -}; +export const UnsupportedObjectDestructuringInForOf = (node: ts.Node) => + new TranspileError(`Unsupported object destructuring in for...of statement.`, node); -export const InvalidAmbientIdentifierName = (node: ts.Identifier) => { - return new TranspileError( +export const InvalidAmbientIdentifierName = (node: ts.Identifier) => + new TranspileError( `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, node ); -}; -export const InvalidForRangeCall = (node: ts.Node, message: string) => { - return new TranspileError(`Invalid @forRange call: ${message}`, node); -}; +export const InvalidForRangeCall = (node: ts.Node, message: string) => + new TranspileError(`Invalid @forRange call: ${message}`, node); diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts new file mode 100644 index 000000000..91f684ecb --- /dev/null +++ b/src/transformation/utils/export.ts @@ -0,0 +1,129 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { createModuleLocalNameIdentifier } from "../visitors/namespace"; +import { createExportsIdentifier } from "./lua-ast"; +import { getSymbolInfo } from "./symbols"; +import { findFirstNodeAbove, isFileModule } from "./typescript"; + +export function hasDefaultExportModifier({ modifiers }: ts.Node): boolean { + return modifiers !== undefined && modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); +} + +export const createDefaultExportIdentifier = (original: ts.Node): lua.Identifier => + lua.createIdentifier("default", original); + +export const createDefaultExportStringLiteral = (original: ts.Node): lua.StringLiteral => + lua.createStringLiteral("default", original); + +export function getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { + const declarations = symbol.getDeclarations(); + if (declarations) { + return declarations.find(d => (ts.getCombinedModifierFlags(d) & ts.ModifierFlags.Export) !== 0); + } +} + +export function getSymbolFromIdentifier( + context: TransformationContext, + identifier: lua.Identifier +): ts.Symbol | undefined { + if (identifier.symbolId !== undefined) { + const symbolInfo = getSymbolInfo(context, identifier.symbolId); + if (symbolInfo !== undefined) { + return symbolInfo.symbol; + } + } +} + +export function getIdentifierExportScope( + context: TransformationContext, + identifier: lua.Identifier +): ts.SourceFile | ts.ModuleDeclaration | undefined { + const symbol = getSymbolFromIdentifier(context, identifier); + if (!symbol) { + return undefined; + } + + return getSymbolExportScope(context, symbol); +} + +export function getSymbolExportScope( + context: TransformationContext, + symbol: ts.Symbol +): ts.SourceFile | ts.ModuleDeclaration | undefined { + const exportedDeclaration = getExportedSymbolDeclaration(symbol); + if (!exportedDeclaration) { + return undefined; + } + + const scope = findFirstNodeAbove( + exportedDeclaration, + (n): n is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(n) || ts.isModuleDeclaration(n) + ); + if (!scope) { + return undefined; + } + + if (!isSymbolExportedFromScope(context, symbol, scope)) { + return undefined; + } + + return scope; +} + +export function isSymbolExported(context: TransformationContext, symbol: ts.Symbol): boolean { + return ( + getExportedSymbolDeclaration(symbol) !== undefined || + // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') + isSymbolExportedFromScope(context, symbol, context.sourceFile) + ); +} + +export function isSymbolExportedFromScope( + context: TransformationContext, + symbol: ts.Symbol, + scope: ts.SourceFile | ts.ModuleDeclaration +): boolean { + if (ts.isSourceFile(scope) && !isFileModule(scope)) { + return false; + } + + let scopeSymbol = context.checker.getSymbolAtLocation(scope); + if (scopeSymbol === undefined) { + // TODO: Necessary? + scopeSymbol = context.checker.getTypeAtLocation(scope).getSymbol(); + } + + if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { + return false; + } + + // ts.Iterator is not a ES6-compatible iterator, because TypeScript targets ES5 + const it: Iterable = { [Symbol.iterator]: () => scopeSymbol!.exports!.values() }; + return [...it].includes(symbol); +} + +export function addExportToIdentifier( + context: TransformationContext, + identifier: lua.Identifier +): lua.AssignmentLeftHandSideExpression { + const exportScope = getIdentifierExportScope(context, identifier); + return exportScope ? createExportedIdentifier(context, identifier, exportScope) : identifier; +} + +export function createExportedIdentifier( + context: TransformationContext, + identifier: lua.Identifier, + exportScope?: ts.SourceFile | ts.ModuleDeclaration +): lua.AssignmentLeftHandSideExpression { + if (!identifier.exportable) { + return identifier; + } + + const exportTable = + exportScope && ts.isModuleDeclaration(exportScope) + ? createModuleLocalNameIdentifier(context, exportScope) + : createExportsIdentifier(); + + return lua.createTableIndexExpression(exportTable, lua.createStringLiteral(identifier.text)); +} diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts new file mode 100644 index 000000000..ca8f27aa8 --- /dev/null +++ b/src/transformation/utils/function-context.ts @@ -0,0 +1,146 @@ +import * as ts from "typescript"; +import { CompilerOptions } from "../../CompilerOptions"; +import { flatMap } from "../../utils"; +import { TransformationContext } from "../context"; +import { AnnotationKind, getFileAnnotations, getNodeAnnotations } from "./annotations"; +import { findFirstNodeAbove, getAllCallSignatures, inferAssignedType } from "./typescript"; + +export enum ContextType { + None, + Void, + NonVoid, + Mixed, +} + +function hasNoSelfAncestor(declaration: ts.Declaration): boolean { + const scopeDeclaration = findFirstNodeAbove( + declaration, + (node): node is ts.SourceFile | ts.ModuleDeclaration => ts.isSourceFile(node) || ts.isModuleDeclaration(node) + ); + + if (!scopeDeclaration) { + return false; + } else if (ts.isSourceFile(scopeDeclaration)) { + return getFileAnnotations(scopeDeclaration).has(AnnotationKind.NoSelfInFile); + } else if (getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) { + return true; + } else { + return hasNoSelfAncestor(scopeDeclaration); + } +} + +function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined { + return signatureDeclaration.parameters.find( + param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword + ); +} + +export function getDeclarationContextType( + { program }: TransformationContext, + signatureDeclaration: ts.SignatureDeclaration +): ContextType { + const thisParameter = getExplicitThisParameter(signatureDeclaration); + if (thisParameter) { + // Explicit 'this' + return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword + ? ContextType.Void + : ContextType.NonVoid; + } + + if ( + ts.isMethodSignature(signatureDeclaration) || + ts.isMethodDeclaration(signatureDeclaration) || + ts.isConstructSignatureDeclaration(signatureDeclaration) || + ts.isConstructorDeclaration(signatureDeclaration) || + (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || + (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) + ) { + // Class/interface methods only respect @noSelf on their parent + const scopeDeclaration = findFirstNodeAbove( + signatureDeclaration, + (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => + ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) + ); + + if (scopeDeclaration === undefined) { + return ContextType.NonVoid; + } + + if (getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) { + return ContextType.Void; + } + + return ContextType.NonVoid; + } + + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. + const options = program.getCompilerOptions() as CompilerOptions; + if (options.noImplicitSelf && program.getRootFileNames().includes(signatureDeclaration.getSourceFile().fileName)) { + return ContextType.Void; + } + + // Walk up to find @noSelf or @noSelfInFile + if (hasNoSelfAncestor(signatureDeclaration)) { + return ContextType.Void; + } + + return ContextType.NonVoid; +} + +function reduceContextTypes(contexts: ContextType[]): ContextType { + const reducer = (a: ContextType, b: ContextType) => { + if (a === ContextType.None) { + return b; + } else if (b === ContextType.None) { + return a; + } else if (a !== b) { + return ContextType.Mixed; + } else { + return a; + } + }; + + return contexts.reduce(reducer, ContextType.None); +} + +function getSignatureDeclarations( + context: TransformationContext, + signatures: readonly ts.Signature[] +): ts.SignatureDeclaration[] { + return flatMap(signatures, signature => { + const signatureDeclaration = signature.getDeclaration(); + if ( + (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && + !getExplicitThisParameter(signatureDeclaration) + ) { + // Infer type of function expressions/arrow functions + const inferredType = inferAssignedType(context, signatureDeclaration); + if (inferredType) { + const inferredSignatures = getAllCallSignatures(inferredType); + if (inferredSignatures.length > 0) { + return inferredSignatures.map(s => s.getDeclaration()); + } + } + } + + return signatureDeclaration; + }); +} + +export function getFunctionContextType(context: TransformationContext, type: ts.Type): ContextType { + if (type.isTypeParameter()) { + type = type.getConstraint() || type; + } + + if (type.isUnion()) { + return reduceContextTypes(type.types.map(t => getFunctionContextType(context, t))); + } + + const signatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Call); + if (signatures.length === 0) { + return ContextType.None; + } + + const signatureDeclarations = getSignatureDeclarations(context, signatures); + return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(context, s))); +} diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts new file mode 100644 index 000000000..5473650b7 --- /dev/null +++ b/src/transformation/utils/lua-ast.ts @@ -0,0 +1,235 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { getCurrentNamespace } from "../visitors/namespace"; +import { UndefinedScope } from "./errors"; +import { createExportedIdentifier, getIdentifierExportScope } from "./export"; +import { findScope, peekScope, ScopeType } from "./scope"; +import { isFirstDeclaration, isFunctionType } from "./typescript"; + +export type OneToManyVisitorResult = T | T[] | undefined; +export function unwrapVisitorResult(result: OneToManyVisitorResult): T[] { + if (result === undefined || result === null) { + return []; + } else if (Array.isArray(result)) { + return result; + } else { + return [result]; + } +} + +export function createSelfIdentifier(tsOriginal?: ts.Node): lua.Identifier { + return lua.createIdentifier("self", tsOriginal, undefined, "this"); +} + +export function createExportsIdentifier(): lua.Identifier { + return lua.createIdentifier("____exports"); +} + +export function replaceStatementInParent(oldNode: lua.Statement, newNode?: lua.Statement): void { + if (!oldNode.parent) { + throw new Error("node has not yet been assigned a parent"); + } + + if (lua.isBlock(oldNode.parent) || lua.isDoStatement(oldNode.parent)) { + if (newNode) { + oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1, newNode); + } else { + oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1); + } + } else { + throw new Error("unexpected parent type"); + } +} + +export function createExpressionPlusOne(expression: lua.Expression): lua.Expression { + if (lua.isNumericLiteral(expression)) { + const newNode = lua.cloneNode(expression); + newNode.value += 1; + return newNode; + } + + if (lua.isBinaryExpression(expression)) { + if ( + expression.operator === lua.SyntaxKind.SubtractionOperator && + lua.isNumericLiteral(expression.right) && + expression.right.value === 1 + ) { + return expression.left; + } + + expression = lua.createParenthesizedExpression(expression); + } + + return lua.createBinaryExpression(expression, lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator); +} + +export function createImmediatelyInvokedFunctionExpression( + statements: lua.Statement[], + result: lua.Expression | lua.Expression[], + tsOriginal?: ts.Node +): lua.CallExpression { + const body = statements ? statements.slice(0) : []; + body.push(lua.createReturnStatement(Array.isArray(result) ? result : [result])); + const flags = statements.length === 0 ? lua.FunctionExpressionFlags.Inline : lua.FunctionExpressionFlags.None; + const iife = lua.createFunctionExpression(lua.createBlock(body), undefined, undefined, undefined, flags); + return lua.createCallExpression(lua.createParenthesizedExpression(iife), [], tsOriginal); +} + +export function createUnpackCall( + context: TransformationContext, + expression: lua.Expression, + tsOriginal?: ts.Node +): lua.Expression { + const unpack = + context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.LuaJIT + ? lua.createIdentifier("unpack") + : lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("unpack")); + + return lua.createCallExpression(unpack, [expression], tsOriginal); +} + +export function wrapInTable(...expressions: lua.Expression[]): lua.ParenthesizedExpression { + const fields = expressions.map(e => lua.createTableFieldExpression(e)); + return lua.createParenthesizedExpression(lua.createTableExpression(fields)); +} + +export function wrapInToStringForConcat(expression: lua.Expression): lua.Expression { + if ( + lua.isStringLiteral(expression) || + lua.isNumericLiteral(expression) || + (lua.isBinaryExpression(expression) && expression.operator === lua.SyntaxKind.ConcatOperator) + ) { + return expression; + } + + return lua.createCallExpression(lua.createIdentifier("tostring"), [expression]); +} + +export function createHoistableVariableDeclarationStatement( + context: TransformationContext, + identifier: lua.Identifier, + initializer?: lua.Expression, + tsOriginal?: ts.Node, + parent?: lua.Node +): lua.AssignmentStatement | lua.VariableDeclarationStatement { + const declaration = lua.createVariableDeclarationStatement(identifier, initializer, tsOriginal, parent); + if (!context.options.noHoisting && identifier.symbolId) { + const scope = peekScope(context); + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } + + scope.variableDeclarations.push(declaration); + } + + return declaration; +} + +export function createLocalOrExportedOrGlobalDeclaration( + context: TransformationContext, + lhs: lua.Identifier | lua.Identifier[], + rhs?: lua.Expression | lua.Expression[], + tsOriginal?: ts.Node, + parent?: lua.Node, + overrideExportScope?: ts.SourceFile | ts.ModuleDeclaration +): lua.Statement[] { + let declaration: lua.VariableDeclarationStatement | undefined; + let assignment: lua.AssignmentStatement | undefined; + + const functionDeclaration = tsOriginal && ts.isFunctionDeclaration(tsOriginal) ? tsOriginal : undefined; + + const identifiers = Array.isArray(lhs) ? lhs : [lhs]; + if (identifiers.length === 0) { + return []; + } + + const exportScope = overrideExportScope || getIdentifierExportScope(context, identifiers[0]); + if (exportScope) { + // exported + if (!rhs) { + return []; + } else { + assignment = lua.createAssignmentStatement( + identifiers.map(identifier => createExportedIdentifier(context, identifier, exportScope)), + rhs, + tsOriginal, + parent + ); + } + } else { + const insideFunction = findScope(context, ScopeType.Function) !== undefined; + let isLetOrConst = false; + let isVariableFirstDeclaration = true; // var can have multiple declarations for the same variable :/ + if (tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.parent) { + isLetOrConst = (tsOriginal.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0; + isVariableFirstDeclaration = isLetOrConst || isFirstDeclaration(context, tsOriginal); + } + + if ( + (context.isModule || getCurrentNamespace(context) || insideFunction || isLetOrConst) && + isVariableFirstDeclaration + ) { + // local + const isPossibleWrappedFunction = + !functionDeclaration && + tsOriginal && + ts.isVariableDeclaration(tsOriginal) && + tsOriginal.initializer && + isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); + if (isPossibleWrappedFunction) { + // Split declaration and assignment for wrapped function types to allow recursion + declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal, parent); + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal, parent); + } else { + declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal, parent); + } + + if (!context.options.noHoisting) { + // Remember local variable declarations for hoisting later + const scope = + isLetOrConst || functionDeclaration + ? peekScope(context) + : findScope(context, ScopeType.Function | ScopeType.File); + + if (scope === undefined) { + throw UndefinedScope(); + } + + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } + + scope.variableDeclarations.push(declaration); + } + } else if (rhs) { + // global + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal, parent); + } else { + return []; + } + } + + if (!context.options.noHoisting && functionDeclaration) { + // Remember function definitions for hoisting later + const functionSymbolId = (lhs as lua.Identifier).symbolId; + const scope = peekScope(context); + if (functionSymbolId && scope.functionDefinitions) { + const definitions = scope.functionDefinitions.get(functionSymbolId); + if (definitions) { + definitions.definition = declaration || assignment; + } + } + } + + if (declaration && assignment) { + return [declaration, assignment]; + } else if (declaration) { + return [declaration]; + } else if (assignment) { + return [assignment]; + } else { + return []; + } +} diff --git a/src/transformation/utils/lualib.ts b/src/transformation/utils/lualib.ts new file mode 100644 index 000000000..583887c7a --- /dev/null +++ b/src/transformation/utils/lualib.ts @@ -0,0 +1,27 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { LuaLibFeature } from "../../LuaLib"; +import { getOrUpdate } from "../../utils"; +import { TransformationContext } from "../context"; + +export { LuaLibFeature }; + +const luaLibFeatures = new WeakMap>(); +export function getUsedLuaLibFeatures(context: TransformationContext): Set { + return getOrUpdate(luaLibFeatures, context, () => new Set()); +} + +export function importLuaLibFeature(context: TransformationContext, feature: LuaLibFeature): void { + getUsedLuaLibFeatures(context).add(feature); +} + +export function transformLuaLibFunction( + context: TransformationContext, + feature: LuaLibFeature, + tsParent?: ts.Expression, + ...params: lua.Expression[] +): lua.CallExpression { + importLuaLibFeature(context, feature); + const functionIdentifier = lua.createIdentifier(`__TS__${feature}`); + return lua.createCallExpression(functionIdentifier, params, tsParent); +} diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts new file mode 100644 index 000000000..9969bd561 --- /dev/null +++ b/src/transformation/utils/safe-names.ts @@ -0,0 +1,102 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../context"; +import { InvalidAmbientIdentifierName } from "./errors"; +import { isAmbientNode } from "./typescript"; +import { isSymbolExported } from "./export"; + +export const luaKeywords: ReadonlySet = new Set([ + "and", + "break", + "do", + "else", + "elseif", + "end", + "false", + "for", + "function", + "goto", + "if", + "in", + "local", + "nil", + "not", + "or", + "repeat", + "return", + "then", + "until", + "while", +]); + +export const luaBuiltins: ReadonlySet = new Set([ + "_G", + "assert", + "coroutine", + "debug", + "error", + "ipairs", + "math", + "pairs", + "pcall", + "print", + "rawget", + "rawset", + "repeat", + "require", + "self", + "string", + "table", + "tostring", + "type", + "unpack", +]); + +export const isValidLuaIdentifier = (str: string) => /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(str); + +export const isUnsafeName = (name: string) => + luaKeywords.has(name) || luaBuiltins.has(name) || !isValidLuaIdentifier(name); + +export function hasUnsafeSymbolName( + context: TransformationContext, + symbol: ts.Symbol, + tsOriginal: ts.Identifier +): boolean { + const isLuaKeyword = luaKeywords.has(symbol.name); + const isInvalidIdentifier = !isValidLuaIdentifier(symbol.name); + const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d)); + if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { + // Catch ambient declarations of identifiers with bad names + throw InvalidAmbientIdentifierName(tsOriginal); + } + + if (isUnsafeName(symbol.name)) { + // only unsafe when non-ambient and not exported + return !isAmbient && !isSymbolExported(context, symbol); + } + + return false; +} + +export function hasUnsafeIdentifierName(context: TransformationContext, identifier: ts.Identifier): boolean { + const symbol = context.checker.getSymbolAtLocation(identifier); + + if (symbol !== undefined) { + return hasUnsafeSymbolName(context, symbol, identifier); + } else if (luaKeywords.has(identifier.text) || !isValidLuaIdentifier(identifier.text)) { + throw InvalidAmbientIdentifierName(identifier); + } + + return false; +} + +const fixInvalidLuaIdentifier = (name: string) => + name.replace( + /[^a-zA-Z0-9_]/g, + c => + `_${c + .charCodeAt(0) + .toString(16) + .toUpperCase()}` + ); + +export const createSafeName = (name: string) => "____" + fixInvalidLuaIdentifier(name); diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts new file mode 100644 index 000000000..31aa9a9fd --- /dev/null +++ b/src/transformation/utils/scope.ts @@ -0,0 +1,221 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { getOrUpdate, isNonNull } from "../../utils"; +import { TransformationContext } from "../context"; +import { UndefinedFunctionDefinition, UndefinedScope } from "./errors"; +import { replaceStatementInParent } from "./lua-ast"; +import { getSymbolInfo } from "./symbols"; +import { getFirstDeclarationInFile } from "./typescript"; + +export enum ScopeType { + File = 1 << 0, + Function = 1 << 1, + Switch = 1 << 2, + Loop = 1 << 3, + Conditional = 1 << 4, + Block = 1 << 5, + Try = 1 << 6, + Catch = 1 << 7, +} + +interface FunctionDefinitionInfo { + referencedSymbols: Map; + definition?: lua.VariableDeclarationStatement | lua.AssignmentStatement; +} + +export interface Scope { + type: ScopeType; + id: number; + referencedSymbols?: Map; + variableDeclarations?: lua.VariableDeclarationStatement[]; + functionDefinitions?: Map; + importStatements?: lua.Statement[]; + loopContinued?: boolean; + functionReturned?: boolean; +} + +const scopeStacks = new WeakMap(); +function getScopeStack(context: TransformationContext): Scope[] { + return getOrUpdate(scopeStacks, context, () => []); +} + +export function* walkScopesUp(context: TransformationContext): IterableIterator { + const scopeStack = getScopeStack(context); + for (let i = scopeStack.length - 1; i >= 0; --i) { + const scope = scopeStack[i]; + yield scope; + } +} + +export function markSymbolAsReferencedInCurrentScopes( + context: TransformationContext, + symbolId: lua.SymbolId, + identifier: ts.Identifier +): void { + for (const scope of getScopeStack(context)) { + if (!scope.referencedSymbols) { + scope.referencedSymbols = new Map(); + } + + const references = getOrUpdate(scope.referencedSymbols, symbolId, () => []); + references.push(identifier); + } +} + +export function peekScope(context: TransformationContext): Scope { + const scopeStack = getScopeStack(context); + const scope = scopeStack[scopeStack.length - 1]; + if (!scope) { + throw UndefinedScope(); + } + + return scope; +} + +export function findScope(context: TransformationContext, scopeTypes: ScopeType): Scope | undefined { + return [...getScopeStack(context)].reverse().find(s => scopeTypes & s.type); +} + +const scopeIdCounters = new WeakMap(); +export function pushScope(context: TransformationContext, scopeType: ScopeType): void { + const nextScopeId = (scopeIdCounters.get(context) || 0) + 1; + scopeIdCounters.set(context, nextScopeId); + + const scopeStack = getScopeStack(context); + scopeStack.push({ type: scopeType, id: nextScopeId }); +} + +export function popScope(context: TransformationContext): Scope { + const scopeStack = getScopeStack(context); + const scope = scopeStack.pop(); + if (!scope) { + throw UndefinedScope(); + } + + return scope; +} + +export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { + if (context.options.noHoisting) { + return statements; + } + + const scope = peekScope(context); + let result = statements; + result = hoistFunctionDefinitions(context, scope, result); + result = hoistVariableDeclarations(context, scope, result); + result = hoistImportStatements(scope, result); + return result; +} + +function shouldHoistSymbol(context: TransformationContext, symbolId: lua.SymbolId, scope: Scope): boolean { + const symbolInfo = getSymbolInfo(context, symbolId); + if (!symbolInfo) { + return false; + } + + const declaration = getFirstDeclarationInFile(symbolInfo.symbol, context.sourceFile); + if (!declaration) { + return false; + } + + if (symbolInfo.firstSeenAtPos < declaration.pos) { + return true; + } + + if (scope.functionDefinitions) { + for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { + if (functionDefinition.definition === undefined) { + throw UndefinedFunctionDefinition(functionSymbolId); + } + + const { line, column } = lua.getOriginalPos(functionDefinition.definition); + if (line !== undefined && column !== undefined) { + const definitionPos = ts.getPositionOfLineAndCharacter(context.sourceFile, line, column); + if ( + functionSymbolId !== symbolId && // Don't recurse into self + declaration.pos < definitionPos && // Ignore functions before symbol declaration + functionDefinition.referencedSymbols.has(symbolId) && + shouldHoistSymbol(context, functionSymbolId, scope) + ) { + return true; + } + } + } + } + + return false; +} + +function hoistVariableDeclarations( + context: TransformationContext, + scope: Scope, + statements: lua.Statement[] +): lua.Statement[] { + if (!scope.variableDeclarations) { + return statements; + } + + const result = [...statements]; + const hoistedLocals: lua.Identifier[] = []; + for (const declaration of scope.variableDeclarations) { + const symbols = declaration.left.map(i => i.symbolId).filter(isNonNull); + if (symbols.some(s => shouldHoistSymbol(context, s, scope))) { + let assignment: lua.AssignmentStatement | undefined; + if (declaration.right) { + assignment = lua.createAssignmentStatement(declaration.left, declaration.right); + lua.setNodePosition(assignment, declaration); // Preserve position info for sourcemap + } + + const index = result.indexOf(declaration); + if (index >= 0) { + if (assignment) { + result.splice(index, 1, assignment); + } else { + result.splice(index, 1); + } + } else { + // Special case for 'var's declared in child scopes + replaceStatementInParent(declaration, assignment); + } + + hoistedLocals.push(...declaration.left); + } + } + + if (hoistedLocals.length > 0) { + result.unshift(lua.createVariableDeclarationStatement(hoistedLocals)); + } + + return result; +} + +function hoistFunctionDefinitions( + context: TransformationContext, + scope: Scope, + statements: lua.Statement[] +): lua.Statement[] { + if (!scope.functionDefinitions) { + return statements; + } + + const result = [...statements]; + const hoistedFunctions: Array = []; + for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { + if (functionDefinition.definition === undefined) { + throw UndefinedFunctionDefinition(functionSymbolId); + } + + if (shouldHoistSymbol(context, functionSymbolId, scope)) { + const index = result.indexOf(functionDefinition.definition); + result.splice(index, 1); + hoistedFunctions.push(functionDefinition.definition); + } + } + + return [...hoistedFunctions, ...result]; +} + +function hoistImportStatements(scope: Scope, statements: lua.Statement[]): lua.Statement[] { + return scope.importStatements ? [...scope.importStatements, ...statements] : statements; +} diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts new file mode 100644 index 000000000..310c09453 --- /dev/null +++ b/src/transformation/utils/symbols.ts @@ -0,0 +1,70 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { getOrUpdate } from "../../utils"; +import { TransformationContext } from "../context"; +import { ReferencedBeforeDeclaration } from "./errors"; +import { markSymbolAsReferencedInCurrentScopes } from "./scope"; +import { getFirstDeclarationInFile } from "./typescript"; + +const symbolIdCounters = new WeakMap(); +function nextSymbolId(context: TransformationContext): lua.SymbolId { + const symbolId = (symbolIdCounters.get(context) || 0) + 1; + symbolIdCounters.set(context, symbolId); + return symbolId as lua.SymbolId; +} + +export interface SymbolInfo { + symbol: ts.Symbol; + firstSeenAtPos: number; +} + +const symbolInfoMap = new WeakMap>(); +const symbolIdMaps = new WeakMap>(); + +export function getSymbolInfo(context: TransformationContext, symbolId: lua.SymbolId): SymbolInfo | undefined { + return getOrUpdate(symbolInfoMap, context, () => new Map()).get(symbolId); +} + +export function getSymbolIdOfSymbol(context: TransformationContext, symbol: ts.Symbol): lua.SymbolId | undefined { + return getOrUpdate(symbolIdMaps, context, () => new Map()).get(symbol); +} + +export function trackSymbolReference( + context: TransformationContext, + symbol: ts.Symbol, + identifier: ts.Identifier +): lua.SymbolId | undefined { + const symbolIds = getOrUpdate(symbolIdMaps, context, () => new Map()); + + // Track first time symbols are seen + let symbolId = symbolIds.get(symbol); + if (symbolId === undefined) { + symbolId = nextSymbolId(context); + + symbolIds.set(symbol, symbolId); + const symbolInfo = getOrUpdate(symbolInfoMap, context, () => new Map()); + symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); + } + + if (context.options.noHoisting) { + // Check for reference-before-declaration + const declaration = getFirstDeclarationInFile(symbol, context.sourceFile); + if (declaration && identifier.pos < declaration.pos) { + throw ReferencedBeforeDeclaration(identifier); + } + } + + markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + + return symbolId; +} + +export function getIdentifierSymbolId( + context: TransformationContext, + identifier: ts.Identifier +): lua.SymbolId | undefined { + const symbol = context.checker.getSymbolAtLocation(identifier); + if (symbol) { + return trackSymbolReference(context, symbol, identifier); + } +} diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts new file mode 100644 index 000000000..7007beaaa --- /dev/null +++ b/src/transformation/utils/typescript/index.ts @@ -0,0 +1,99 @@ +import * as ts from "typescript"; +import { flatMap } from "../../../utils"; +import { TransformationContext } from "../../context"; +import { isDeclaration } from "./nodes"; + +export * from "./nodes"; +export * from "./types"; + +// TODO: Move to separate files? + +export function isFileModule(sourceFile: ts.SourceFile): boolean { + return sourceFile.statements.some(isStatementExported); +} + +function isStatementExported(statement: ts.Statement): boolean { + if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { + return true; + } + if (ts.isVariableStatement(statement)) { + return statement.declarationList.declarations.some( + declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 + ); + } + return isDeclaration(statement) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; +} + +export function hasExportEquals(sourceFile: ts.SourceFile): boolean { + return sourceFile.statements.some(node => ts.isExportAssignment(node) && node.isExportEquals); +} + +/** + * Search up until finding a node satisfying the callback + */ +export function findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined { + let current = node; + while (current.parent) { + if (callback(current.parent)) { + return current.parent; + } else { + current = current.parent; + } + } +} + +export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { + const declarations = (symbol.getDeclarations() || []).filter( + // TODO: getSourceFile? + declaration => findFirstNodeAbove(declaration, ts.isSourceFile) === sourceFile + ); + + return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; +} + +export function isFirstDeclaration(context: TransformationContext, node: ts.VariableDeclaration): boolean { + const symbol = context.checker.getSymbolAtLocation(node.name); + if (!symbol) { + return false; + } + + const firstDeclaration = getFirstDeclarationInFile(symbol, context.sourceFile); + return firstDeclaration === node; +} + +export function isStandardLibraryType( + context: TransformationContext, + type: ts.Type, + name: string | undefined +): boolean { + const symbol = type.getSymbol(); + if (!symbol || (name ? symbol.name !== name : symbol.name === "__type")) { + return false; + } + + // Assume to be lib function if no valueDeclaration exists + const declaration = symbol.valueDeclaration; + if (!declaration) { + return true; + } + + const sourceFile = declaration.getSourceFile(); + if (!sourceFile) { + return false; + } + + return context.program.isSourceFileDefaultLibrary(sourceFile); +} + +export function inferAssignedType(context: TransformationContext, expression: ts.Expression): ts.Type { + return context.checker.getContextualType(expression) || context.checker.getTypeAtLocation(expression); +} + +export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { + return type.isUnion() ? flatMap(type.types, getAllCallSignatures) : type.getCallSignatures(); +} + +// Returns true for expressions that may have effects when evaluated +export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { + return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); +} diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts new file mode 100644 index 000000000..ed84c97a9 --- /dev/null +++ b/src/transformation/utils/typescript/nodes.ts @@ -0,0 +1,41 @@ +import * as ts from "typescript"; + +export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { + return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); +} + +export function isDestructuringAssignment(node: ts.Node): node is ts.DestructuringAssignment { + return ( + ts.isBinaryExpression(node) && + node.operatorToken.kind === ts.SyntaxKind.EqualsToken && + isAssignmentPattern(node.left) + ); +} + +export function isAmbientNode(node: ts.Declaration): boolean { + return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) !== 0; +} + +export function isDeclaration(node: ts.Node): node is ts.Declaration { + return ( + ts.isEnumDeclaration(node) || + ts.isClassDeclaration(node) || + ts.isExportDeclaration(node) || + ts.isImportDeclaration(node) || + ts.isMethodDeclaration(node) || + ts.isModuleDeclaration(node) || + ts.isFunctionDeclaration(node) || + ts.isVariableDeclaration(node) || + ts.isInterfaceDeclaration(node) || + ts.isTypeAliasDeclaration(node) || + ts.isNamespaceExportDeclaration(node) + ); +} + +export function isInDestructingAssignment(node: ts.Node): boolean { + return ( + node.parent && + ((ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) || + (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) + ); +} diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts new file mode 100644 index 000000000..2252e18d7 --- /dev/null +++ b/src/transformation/utils/typescript/types.ts @@ -0,0 +1,78 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../../context"; + +export function isTypeWithFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { + if (type.symbol) { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint && baseConstraint !== type) { + return isTypeWithFlags(context, baseConstraint, flags); + } + } + + if (type.isUnion()) { + return type.types.every(t => isTypeWithFlags(context, t, flags)); + } + + if (type.isIntersection()) { + return type.types.some(t => isTypeWithFlags(context, t, flags)); + } + + return (type.flags & flags) !== 0; +} + +export function isStringType(context: TransformationContext, type: ts.Type): boolean { + return isTypeWithFlags(context, type, ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral); +} + +export function isNumberType(context: TransformationContext, type: ts.Type): boolean { + return isTypeWithFlags(context, type, ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral); +} + +export function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { + if (type.symbol) { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint && baseConstraint !== type) { + return isExplicitArrayType(context, baseConstraint); + } + } + + if (type.isUnionOrIntersection()) { + return type.types.some(t => isExplicitArrayType(context, t)); + } + + const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; + let typeNode = context.checker.typeToTypeNode(type, undefined, flags); + if (typeNode && ts.isTypeOperatorNode(typeNode) && typeNode.operator === ts.SyntaxKind.ReadonlyKeyword) { + typeNode = typeNode.type; + } + + return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); +} + +/** + * Iterate over a type and its bases until the callback returns true. + */ +function forTypeOrAnySupertype( + context: TransformationContext, + type: ts.Type, + predicate: (type: ts.Type) => boolean +): boolean { + if (predicate(type)) { + return true; + } + + if (!type.isClassOrInterface() && type.symbol) { + type = context.checker.getDeclaredTypeOfSymbol(type.symbol); + } + + return (type.getBaseTypes() || []).some(superType => forTypeOrAnySupertype(context, superType, predicate)); +} + +export function isArrayType(context: TransformationContext, type: ts.Type): boolean { + return forTypeOrAnySupertype(context, type, t => isExplicitArrayType(context, t)); +} + +export function isFunctionType(context: TransformationContext, type: ts.Type): boolean { + const typeNode = context.checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); + return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); +} diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts new file mode 100644 index 000000000..747ba0455 --- /dev/null +++ b/src/transformation/visitors/access.ts @@ -0,0 +1,103 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { transformBuiltinPropertyAccessExpression } from "../builtins"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { createExpressionPlusOne } from "../utils/lua-ast"; +import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; +import { tryGetConstEnumValue } from "./enum"; +import { transformLuaTableElementAccessExpression, transformLuaTablePropertyAccessExpression } from "./lua-table"; + +export function transformElementAccessArgument( + context: TransformationContext, + node: ts.ElementAccessExpression +): lua.Expression { + const index = context.transformExpression(node.argumentExpression); + + const type = context.checker.getTypeAtLocation(node.expression); + const argumentType = context.checker.getTypeAtLocation(node.argumentExpression); + if (isNumberType(context, argumentType) && isArrayType(context, type)) { + return createExpressionPlusOne(index); + } + + return index; +} + +export const transformElementAccessExpression: FunctionVisitor = (expression, context) => { + transformLuaTableElementAccessExpression(context, expression); + + const constEnumValue = tryGetConstEnumValue(context, expression); + if (constEnumValue) { + return constEnumValue; + } + + let table = context.transformExpression(expression.expression); + if (lua.isTableExpression(table)) { + table = lua.createParenthesizedExpression(table); + } + + const argumentType = context.checker.getTypeAtLocation(expression.argumentExpression); + const type = context.checker.getTypeAtLocation(expression.expression); + if (isNumberType(context, argumentType) && isStringType(context, type)) { + const index = context.transformExpression(expression.argumentExpression); + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("sub")), + [table, createExpressionPlusOne(index), createExpressionPlusOne(index)], + expression + ); + } + + return lua.createTableIndexExpression(table, transformElementAccessArgument(context, expression), expression); +}; + +export const transformPropertyAccessExpression: FunctionVisitor = ( + expression, + context +) => { + const constEnumValue = tryGetConstEnumValue(context, expression); + if (constEnumValue) { + return constEnumValue; + } + + const luaTableResult = transformLuaTablePropertyAccessExpression(context, expression); + if (luaTableResult) { + return luaTableResult; + } + + const builtinResult = transformBuiltinPropertyAccessExpression(context, expression); + if (builtinResult) { + return builtinResult; + } + + const property = expression.name.text; + const type = context.checker.getTypeAtLocation(expression.expression); + + const annotations = getTypeAnnotations(context, type); + // Do not output path for member only enums + if (annotations.has(AnnotationKind.CompileMembersOnly)) { + if (ts.isPropertyAccessExpression(expression.expression)) { + // in case of ...x.enum.y transform to ...x.y + return lua.createTableIndexExpression( + context.transformExpression(expression.expression.expression), + lua.createStringLiteral(property), + expression + ); + } else { + return lua.createIdentifier(property, expression); + } + } + + let callPath = context.transformExpression(expression.expression); + if (lua.isTableExpression(callPath)) { + callPath = lua.createParenthesizedExpression(callPath); + } + + return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), expression); +}; + +export const transformQualifiedName: FunctionVisitor = (node, context) => { + const right = lua.createStringLiteral(node.right.text, node.right); + const left = context.transformExpression(node.left); + + return lua.createTableIndexExpression(left, right, node); +}; diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts new file mode 100644 index 000000000..acf41aca4 --- /dev/null +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -0,0 +1,163 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { cast, castEach } from "../../../utils"; +import { TransformationContext } from "../../context"; +import { isTupleReturnCall } from "../../utils/annotations"; +import { validateAssignment, validatePropertyAssignment } from "../../utils/assignment-validation"; +import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; +import { transformElementAccessArgument } from "../access"; +import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; + +export function transformAssignment( + context: TransformationContext, + // TODO: Change type to ts.LeftHandSideExpression? + lhs: ts.Expression, + right: lua.Expression, + parent?: ts.Expression +): lua.Statement { + if (isArrayLength(context, lhs)) { + return lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.ArraySetLength, + parent, + context.transformExpression(lhs.expression), + right + ) + ); + } + + return lua.createAssignmentStatement( + cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression), + right, + lhs.parent + ); +} + +export function transformAssignmentExpression( + context: TransformationContext, + expression: ts.AssignmentExpression +): lua.CallExpression | lua.MethodCallExpression { + // Validate assignment + const rightType = context.checker.getTypeAtLocation(expression.right); + const leftType = context.checker.getTypeAtLocation(expression.left); + validateAssignment(context, expression.right, rightType, leftType); + + if (isArrayLength(context, expression.left)) { + // array.length = x + return transformLuaLibFunction( + context, + LuaLibFeature.ArraySetLength, + expression, + context.transformExpression(expression.left.expression), + context.transformExpression(expression.right) + ); + } + + if (isDestructuringAssignment(expression)) { + const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + + let right = context.transformExpression(expression.right); + if (isTupleReturnCall(context, expression.right)) { + right = wrapInTable(right); + } + + const statements = [ + lua.createVariableDeclarationStatement(rootIdentifier, right), + ...transformDestructuringAssignment(context, expression, rootIdentifier), + ]; + + return createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); + } + + if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { + // Left is property/element access: cache result while maintaining order of evaluation + // (function(o, i, v) o[i] = v; return v end)(${objExpression}, ${indexExpression}, ${right}) + const objParameter = lua.createIdentifier("o"); + const indexParameter = lua.createIdentifier("i"); + const valueParameter = lua.createIdentifier("v"); + const indexStatement = lua.createTableIndexExpression(objParameter, indexParameter); + const statements: lua.Statement[] = [ + lua.createAssignmentStatement(indexStatement, valueParameter), + lua.createReturnStatement([valueParameter]), + ]; + const iife = lua.createFunctionExpression(lua.createBlock(statements), [ + objParameter, + indexParameter, + valueParameter, + ]); + const objExpression = context.transformExpression(expression.left.expression); + let indexExpression: lua.Expression; + if (ts.isPropertyAccessExpression(expression.left)) { + // Property access + indexExpression = lua.createStringLiteral(expression.left.name.text); + } else { + // Element access + indexExpression = transformElementAccessArgument(context, expression.left); + } + + const args = [objExpression, indexExpression, context.transformExpression(expression.right)]; + return lua.createCallExpression(lua.createParenthesizedExpression(iife), args, expression); + } else { + // Simple assignment + // (function() ${left} = ${right}; return ${left} end)() + const left = context.transformExpression(expression.left); + const right = context.transformExpression(expression.right); + return createImmediatelyInvokedFunctionExpression( + [transformAssignment(context, expression.left, right)], + left, + expression + ); + } +} + +export function transformAssignmentStatement( + context: TransformationContext, + expression: ts.AssignmentExpression +): lua.Statement[] { + // Validate assignment + const rightType = context.checker.getTypeAtLocation(expression.right); + const leftType = context.checker.getTypeAtLocation(expression.left); + validateAssignment(context, expression.right, rightType, leftType); + validatePropertyAssignment(context, expression); + + if (isDestructuringAssignment(expression)) { + if ( + ts.isArrayLiteralExpression(expression.left) && + expression.left.elements.every( + e => + (ts.isIdentifier(e) || ts.isPropertyAccessExpression(e) || ts.isElementAccessExpression(e)) && + !isArrayLength(context, e) + ) + ) { + const rightType = context.checker.getTypeAtLocation(expression.right); + let right = context.transformExpression(expression.right); + + if (!isTupleReturnCall(context, expression.right) && isArrayType(context, rightType)) { + right = createUnpackCall(context, right, expression.right); + } + + const left = castEach( + expression.left.elements.map(e => context.transformExpression(e)), + lua.isAssignmentLeftHandSideExpression + ); + + return [lua.createAssignmentStatement(left, right, expression)]; + } + + let right = context.transformExpression(expression.right); + if (isTupleReturnCall(context, expression.right)) { + right = wrapInTable(right); + } + + const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + return [ + lua.createVariableDeclarationStatement(rootIdentifier, right), + ...transformDestructuringAssignment(context, expression, rootIdentifier), + ]; + } else { + return [transformAssignment(context, expression.left, context.transformExpression(expression.right))]; + } +} diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts new file mode 100644 index 000000000..e8369e91d --- /dev/null +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -0,0 +1,111 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../../CompilerOptions"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import { UnsupportedForTarget, UnsupportedKind } from "../../utils/errors"; +import { transformBinaryOperator } from "../binary-expression"; + +type BitOperator = ts.ShiftOperator | ts.BitwiseOperator; +function transformBinaryBitLibOperation( + node: ts.Node, + left: lua.Expression, + right: lua.Expression, + operator: BitOperator, + lib: string +): lua.Expression { + let bitFunction: string; + switch (operator) { + case ts.SyntaxKind.AmpersandToken: + bitFunction = "band"; + break; + case ts.SyntaxKind.BarToken: + bitFunction = "bor"; + break; + case ts.SyntaxKind.CaretToken: + bitFunction = "bxor"; + break; + case ts.SyntaxKind.LessThanLessThanToken: + bitFunction = "lshift"; + break; + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + bitFunction = "rshift"; + break; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + bitFunction = "arshift"; + break; + default: + throw UnsupportedKind("binary bitwise operator", operator, node); + } + + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier(lib), lua.createStringLiteral(bitFunction)), + [left, right], + node + ); +} + +export function transformBinaryBitOperation( + context: TransformationContext, + node: ts.Node, + left: lua.Expression, + right: lua.Expression, + operator: BitOperator +): lua.Expression { + switch (context.luaTarget) { + case LuaTarget.Lua51: + throw UnsupportedForTarget("Bitwise operations", LuaTarget.Lua51, node); + + case LuaTarget.Lua52: + return transformBinaryBitLibOperation(node, left, right, operator, "bit32"); + + case LuaTarget.LuaJIT: + return transformBinaryBitLibOperation(node, left, right, operator, "bit"); + + default: + const luaOperator = transformBinaryOperator(context, node, operator); + return lua.createBinaryExpression(left, right, luaOperator, node); + } +} + +function transformUnaryBitLibOperation( + node: ts.Node, + expression: lua.Expression, + operator: lua.UnaryBitwiseOperator, + lib: string +): lua.Expression { + let bitFunction: string; + switch (operator) { + case lua.SyntaxKind.BitwiseNotOperator: + bitFunction = "bnot"; + break; + default: + throw UnsupportedKind("unary bitwise operator", operator, node); + } + + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier(lib), lua.createStringLiteral(bitFunction)), + [expression], + node + ); +} + +export function transformUnaryBitOperation( + context: TransformationContext, + node: ts.Node, + expression: lua.Expression, + operator: lua.UnaryBitwiseOperator +): lua.Expression { + switch (context.luaTarget) { + case LuaTarget.Lua51: + throw UnsupportedForTarget("Bitwise operations", LuaTarget.Lua51, node); + + case LuaTarget.Lua52: + return transformUnaryBitLibOperation(node, expression, operator, "bit32"); + + case LuaTarget.LuaJIT: + return transformUnaryBitLibOperation(node, expression, operator, "bit"); + + default: + return lua.createUnaryExpression(expression, operator, node); + } +} diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts new file mode 100644 index 000000000..b810bc9f8 --- /dev/null +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -0,0 +1,182 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { cast } from "../../../utils"; +import { TransformationContext } from "../../context"; +import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; +import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; +import { transformBinaryOperation } from "../binary-expression"; +import { transformAssignment } from "./assignments"; + +// If expression is property/element access with possible effects from being evaluated, returns separated object and index expressions. +export function parseAccessExpressionWithEvaluationEffects( + context: TransformationContext, + node: ts.Expression +): [ts.Expression, ts.Expression] | [] { + if ( + ts.isElementAccessExpression(node) && + (isExpressionWithEvaluationEffect(node.expression) || isExpressionWithEvaluationEffect(node.argumentExpression)) + ) { + const type = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, type)) { + // Offset arrays by one + const oneLit = ts.createNumericLiteral("1"); + const exp = ts.createParen(node.argumentExpression); + const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); + return [node.expression, addExp]; + } else { + return [node.expression, node.argumentExpression]; + } + } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { + return [node.expression, ts.createStringLiteral(node.name.text)]; + } + + return []; +} + +const compoundToAssignmentTokens: Record = { + [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, + [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, + [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, + [ts.SyntaxKind.MinusEqualsToken]: ts.SyntaxKind.MinusToken, + [ts.SyntaxKind.SlashEqualsToken]: ts.SyntaxKind.SlashToken, + [ts.SyntaxKind.PercentEqualsToken]: ts.SyntaxKind.PercentToken, + [ts.SyntaxKind.AsteriskEqualsToken]: ts.SyntaxKind.AsteriskToken, + [ts.SyntaxKind.AmpersandEqualsToken]: ts.SyntaxKind.AmpersandToken, + [ts.SyntaxKind.AsteriskAsteriskEqualsToken]: ts.SyntaxKind.AsteriskAsteriskToken, + [ts.SyntaxKind.LessThanLessThanEqualsToken]: ts.SyntaxKind.LessThanLessThanToken, + [ts.SyntaxKind.GreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanToken, + [ts.SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken]: ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken, +}; + +export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts.CompoundAssignmentOperator => + (compoundToAssignmentTokens as any)[token] !== undefined; + +export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator) => + compoundToAssignmentTokens[token]; + +export function transformCompoundAssignmentExpression( + context: TransformationContext, + expression: ts.Expression, + // TODO: Change type to ts.LeftHandSideExpression? + lhs: ts.Expression, + rhs: ts.Expression, + replacementOperator: ts.BinaryOperator, + isPostfix: boolean +): lua.CallExpression { + const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); + let right = context.transformExpression(rhs); + + const [objExpression, indexExpression] = parseAccessExpressionWithEvaluationEffects(context, lhs); + if (objExpression && indexExpression) { + // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects + // local __obj, __index = ${objExpression}, ${indexExpression}; + const obj = lua.createIdentifier("____obj"); + const index = lua.createIdentifier("____index"); + const objAndIndexDeclaration = lua.createVariableDeclarationStatement( + [obj, index], + [context.transformExpression(objExpression), context.transformExpression(indexExpression)] + ); + const accessExpression = lua.createTableIndexExpression(obj, index); + + const tmp = lua.createIdentifier("____tmp"); + right = lua.createParenthesizedExpression(right); + let tmpDeclaration: lua.VariableDeclarationStatement; + let assignStatement: lua.AssignmentStatement; + if (isPostfix) { + // local ____tmp = ____obj[____index]; + // ____obj[____index] = ____tmp ${replacementOperator} ${right}; + tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); + const operatorExpression = transformBinaryOperation(context, tmp, right, replacementOperator, expression); + assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); + } else { + // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; + // ____obj[____index] = ____tmp; + const operatorExpression = transformBinaryOperation( + context, + accessExpression, + right, + replacementOperator, + expression + ); + tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); + assignStatement = lua.createAssignmentStatement(accessExpression, tmp); + } + // return ____tmp + return createImmediatelyInvokedFunctionExpression( + [objAndIndexDeclaration, tmpDeclaration, assignStatement], + tmp, + expression + ); + } else if (isPostfix) { + // Postfix expressions need to cache original value in temp + // local ____tmp = ${left}; + // ${left} = ____tmp ${replacementOperator} ${right}; + // return ____tmp + const tmpIdentifier = lua.createIdentifier("____tmp"); + const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); + const operatorExpression = transformBinaryOperation( + context, + tmpIdentifier, + right, + replacementOperator, + expression + ); + const assignStatement = transformAssignment(context, lhs, operatorExpression); + return createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier, expression); + } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { + // Simple property/element access expressions need to cache in temp to avoid double-evaluation + // local ____tmp = ${left} ${replacementOperator} ${right}; + // ${left} = ____tmp; + // return ____tmp + const tmpIdentifier = lua.createIdentifier("____tmp"); + const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); + const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); + const assignStatement = transformAssignment(context, lhs, tmpIdentifier); + return createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier, expression); + } else { + // Simple expressions + // ${left} = ${right}; return ${right} + const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); + const assignStatement = transformAssignment(context, lhs, operatorExpression); + return createImmediatelyInvokedFunctionExpression([assignStatement], left, expression); + } +} + +export function transformCompoundAssignmentStatement( + context: TransformationContext, + node: ts.Node, + lhs: ts.Expression, + rhs: ts.Expression, + replacementOperator: ts.BinaryOperator +): lua.Statement { + const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); + const right = context.transformExpression(rhs); + + const [objExpression, indexExpression] = parseAccessExpressionWithEvaluationEffects(context, lhs); + if (objExpression && indexExpression) { + // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects + // local __obj, __index = ${objExpression}, ${indexExpression}; + // ____obj[____index] = ____obj[____index] ${replacementOperator} ${right}; + const obj = lua.createIdentifier("____obj"); + const index = lua.createIdentifier("____index"); + const objAndIndexDeclaration = lua.createVariableDeclarationStatement( + [obj, index], + [context.transformExpression(objExpression), context.transformExpression(indexExpression)] + ); + const accessExpression = lua.createTableIndexExpression(obj, index); + const operatorExpression = transformBinaryOperation( + context, + accessExpression, + lua.createParenthesizedExpression(right), + replacementOperator, + node + ); + const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); + return lua.createDoStatement([objAndIndexDeclaration, assignStatement]); + } else { + // Simple statements + // ${left} = ${left} ${replacementOperator} ${right} + const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, node); + return transformAssignment(context, lhs, operatorExpression); + } +} diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts new file mode 100644 index 000000000..cb89a3673 --- /dev/null +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -0,0 +1,279 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { flatMap } from "../../../utils"; +import { TransformationContext } from "../../context"; +import { UnsupportedKind } from "../../utils/errors"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isArrayType, isAssignmentPattern } from "../../utils/typescript"; +import { transformIdentifier } from "../identifier"; +import { transformPropertyName } from "../literal"; +import { transformAssignment, transformAssignmentStatement } from "./assignments"; + +export function isArrayLength( + context: TransformationContext, + expression: ts.Expression +): expression is ts.PropertyAccessExpression | ts.ElementAccessExpression { + if (!ts.isPropertyAccessExpression(expression) && !ts.isElementAccessExpression(expression)) { + return false; + } + + const type = context.checker.getTypeAtLocation(expression.expression); + if (!isArrayType(context, type)) { + return false; + } + + const name = ts.isPropertyAccessExpression(expression) + ? expression.name.text + : ts.isStringLiteral(expression.argumentExpression) + ? expression.argumentExpression.text + : undefined; + + return name === "length"; +} + +export function transformDestructuringAssignment( + context: TransformationContext, + node: ts.DestructuringAssignment, + root: lua.Expression +): lua.Statement[] { + switch (node.left.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: + return transformObjectDestructuringAssignment(context, node as ts.ObjectDestructuringAssignment, root); + case ts.SyntaxKind.ArrayLiteralExpression: + return transformArrayDestructuringAssignment(context, node as ts.ArrayDestructuringAssignment, root); + } +} + +function transformArrayDestructuringAssignment( + context: TransformationContext, + node: ts.ArrayDestructuringAssignment, + root: lua.Expression +): lua.Statement[] { + return transformArrayLiteralAssignmentPattern(context, node.left, root); +} + +function transformArrayLiteralAssignmentPattern( + context: TransformationContext, + node: ts.ArrayLiteralExpression, + root: lua.Expression +): lua.Statement[] { + return flatMap(node.elements, (element, index) => { + const indexedRoot = lua.createTableIndexExpression(root, lua.createNumericLiteral(index + 1), element); + + switch (element.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: + return transformObjectLiteralAssignmentPattern( + context, + element as ts.ObjectLiteralExpression, + indexedRoot + ); + case ts.SyntaxKind.ArrayLiteralExpression: + return transformArrayLiteralAssignmentPattern( + context, + element as ts.ArrayLiteralExpression, + indexedRoot + ); + case ts.SyntaxKind.BinaryExpression: + const assignedVariable = lua.createIdentifier("____bindingAssignmentValue"); + + const assignedVariableDeclaration = lua.createVariableDeclarationStatement( + assignedVariable, + indexedRoot + ); + + const nilCondition = lua.createBinaryExpression( + assignedVariable, + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + + const defaultAssignmentStatement = transformAssignment( + context, + (element as ts.BinaryExpression).left, + context.transformExpression((element as ts.BinaryExpression).right) + ); + + const elseAssignmentStatement = transformAssignment( + context, + (element as ts.BinaryExpression).left, + assignedVariable + ); + + const ifBlock = lua.createBlock([defaultAssignmentStatement]); + + const elseBlock = lua.createBlock([elseAssignmentStatement]); + + const ifStatement = lua.createIfStatement(nilCondition, ifBlock, elseBlock, node); + + return [assignedVariableDeclaration, ifStatement]; + case ts.SyntaxKind.Identifier: + case ts.SyntaxKind.PropertyAccessExpression: + case ts.SyntaxKind.ElementAccessExpression: + return transformAssignment(context, element, indexedRoot); + case ts.SyntaxKind.SpreadElement: + if (index !== node.elements.length - 1) return []; + + const restElements = transformLuaLibFunction( + context, + LuaLibFeature.ArraySlice, + undefined, + root, + lua.createNumericLiteral(index) + ); + + return transformAssignment(context, (element as ts.SpreadElement).expression, restElements); + case ts.SyntaxKind.OmittedExpression: + return []; + default: + throw UnsupportedKind("Array Destructure Assignment Element", element.kind, element); + } + }); +} + +function transformObjectDestructuringAssignment( + context: TransformationContext, + node: ts.ObjectDestructuringAssignment, + root: lua.Expression +): lua.Statement[] { + return transformObjectLiteralAssignmentPattern(context, node.left, root); +} + +function transformObjectLiteralAssignmentPattern( + context: TransformationContext, + node: ts.ObjectLiteralExpression, + root: lua.Expression +): lua.Statement[] { + const result: lua.Statement[] = []; + + for (const property of node.properties) { + switch (property.kind) { + case ts.SyntaxKind.ShorthandPropertyAssignment: + result.push(...transformShorthandPropertyAssignment(context, property, root)); + break; + case ts.SyntaxKind.PropertyAssignment: + result.push(...transformPropertyAssignment(context, property, root)); + break; + case ts.SyntaxKind.SpreadAssignment: + result.push(...transformSpreadAssignment(context, property, root, node.properties)); + break; + default: + throw UnsupportedKind("Object Destructure Property", property.kind, property); + } + } + + return result; +} + +function transformShorthandPropertyAssignment( + context: TransformationContext, + node: ts.ShorthandPropertyAssignment, + root: lua.Expression +): lua.Statement[] { + const result: lua.Statement[] = []; + const assignmentVariableName = transformIdentifier(context, node.name); + const extractionIndex = lua.createStringLiteral(node.name.text); + const variableExtractionAssignmentStatement = lua.createAssignmentStatement( + assignmentVariableName, + lua.createTableIndexExpression(root, extractionIndex) + ); + + result.push(variableExtractionAssignmentStatement); + + const defaultInitializer = node.objectAssignmentInitializer + ? context.transformExpression(node.objectAssignmentInitializer) + : undefined; + + if (defaultInitializer) { + const nilCondition = lua.createBinaryExpression( + assignmentVariableName, + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + + const assignment = lua.createAssignmentStatement(assignmentVariableName, defaultInitializer); + + const ifBlock = lua.createBlock([assignment]); + + result.push(lua.createIfStatement(nilCondition, ifBlock, undefined, node)); + } + + return result; +} + +function transformPropertyAssignment( + context: TransformationContext, + node: ts.PropertyAssignment, + root: lua.Expression +): lua.Statement[] { + const result: lua.Statement[] = []; + + if (isAssignmentPattern(node.initializer)) { + const propertyAccessString = transformPropertyName(context, node.name); + const newRootAccess = lua.createTableIndexExpression(root, propertyAccessString); + + if (ts.isObjectLiteralExpression(node.initializer)) { + return transformObjectLiteralAssignmentPattern(context, node.initializer, newRootAccess); + } + + if (ts.isArrayLiteralExpression(node.initializer)) { + return transformArrayLiteralAssignmentPattern(context, node.initializer, newRootAccess); + } + } + + const leftExpression = ts.isBinaryExpression(node.initializer) ? node.initializer.left : node.initializer; + const variableToExtract = transformPropertyName(context, node.name); + const extractingExpression = lua.createTableIndexExpression(root, variableToExtract); + + const destructureAssignmentStatement = transformAssignment(context, leftExpression, extractingExpression); + + result.push(destructureAssignmentStatement); + + if (ts.isBinaryExpression(node.initializer)) { + const assignmentLeftHandSide = context.transformExpression(node.initializer.left); + + const nilCondition = lua.createBinaryExpression( + assignmentLeftHandSide, + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + + const ifBlock = lua.createBlock( + transformAssignmentStatement(context, node.initializer as ts.AssignmentExpression) + ); + + result.push(lua.createIfStatement(nilCondition, ifBlock, undefined, node)); + } + + return result; +} + +function transformSpreadAssignment( + context: TransformationContext, + node: ts.SpreadAssignment, + root: lua.Expression, + properties: ts.NodeArray +): lua.Statement[] { + const usedProperties: lua.TableFieldExpression[] = []; + for (const property of properties) { + if ( + (ts.isShorthandPropertyAssignment(property) || ts.isPropertyAssignment(property)) && + !ts.isComputedPropertyName(property.name) + ) { + const name = ts.isIdentifier(property.name) + ? lua.createStringLiteral(property.name.text) + : context.transformExpression(property.name); + + usedProperties.push(lua.createTableFieldExpression(lua.createBooleanLiteral(true), name)); + } + } + + const extractingExpression = transformLuaLibFunction( + context, + LuaLibFeature.ObjectRest, + undefined, + root, + lua.createTableExpression(usedProperties) + ); + + return [transformAssignment(context, node.expression, extractingExpression)]; +} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts new file mode 100644 index 000000000..2d0621d78 --- /dev/null +++ b/src/transformation/visitors/binary-expression/index.ts @@ -0,0 +1,241 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { InvalidInstanceOfExtension, InvalidInstanceOfLuaTable, UnsupportedKind } from "../../utils/errors"; +import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isStandardLibraryType, isStringType } from "../../utils/typescript"; +import { transformTypeOfBinaryExpression } from "../typeof"; +import { transformAssignmentExpression, transformAssignmentStatement } from "./assignments"; +import { transformBinaryBitOperation } from "./bit"; +import { + isCompoundAssignmentToken, + transformCompoundAssignmentExpression, + transformCompoundAssignmentStatement, + unwrapCompoundAssignmentToken, +} from "./compound"; + +export function transformBinaryOperator( + context: TransformationContext, + node: ts.Node, + operator: ts.BinaryOperator +): lua.BinaryOperator { + switch (operator) { + // Bitwise operators + case ts.SyntaxKind.BarToken: + return lua.SyntaxKind.BitwiseOrOperator; + case ts.SyntaxKind.CaretToken: + return lua.SyntaxKind.BitwiseExclusiveOrOperator; + case ts.SyntaxKind.AmpersandToken: + return lua.SyntaxKind.BitwiseAndOperator; + case ts.SyntaxKind.LessThanLessThanToken: + return lua.SyntaxKind.BitwiseLeftShiftOperator; + case ts.SyntaxKind.GreaterThanGreaterThanToken: + throw UnsupportedKind("right shift operator (use >>> instead)", operator, node); + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return lua.SyntaxKind.BitwiseRightShiftOperator; + // Regular operators + case ts.SyntaxKind.AmpersandAmpersandToken: + return lua.SyntaxKind.AndOperator; + case ts.SyntaxKind.BarBarToken: + return lua.SyntaxKind.OrOperator; + case ts.SyntaxKind.MinusToken: + return lua.SyntaxKind.SubtractionOperator; + case ts.SyntaxKind.PlusToken: + if (ts.isBinaryExpression(node)) { + // Check is we need to use string concat operator + const typeLeft = context.checker.getTypeAtLocation(node.left); + const typeRight = context.checker.getTypeAtLocation(node.right); + if (isStringType(context, typeLeft) || isStringType(context, typeRight)) { + return lua.SyntaxKind.ConcatOperator; + } + } + + return lua.SyntaxKind.AdditionOperator; + case ts.SyntaxKind.AsteriskToken: + return lua.SyntaxKind.MultiplicationOperator; + case ts.SyntaxKind.AsteriskAsteriskToken: + return lua.SyntaxKind.PowerOperator; + case ts.SyntaxKind.SlashToken: + return lua.SyntaxKind.DivisionOperator; + case ts.SyntaxKind.PercentToken: + return lua.SyntaxKind.ModuloOperator; + case ts.SyntaxKind.GreaterThanToken: + return lua.SyntaxKind.GreaterThanOperator; + case ts.SyntaxKind.GreaterThanEqualsToken: + return lua.SyntaxKind.GreaterEqualOperator; + case ts.SyntaxKind.LessThanToken: + return lua.SyntaxKind.LessThanOperator; + case ts.SyntaxKind.LessThanEqualsToken: + return lua.SyntaxKind.LessEqualOperator; + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + return lua.SyntaxKind.EqualityOperator; + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return lua.SyntaxKind.InequalityOperator; + default: + throw UnsupportedKind("binary operator", operator, node); + } +} + +export function transformBinaryOperation( + context: TransformationContext, + left: lua.Expression, + right: lua.Expression, + operator: ts.BinaryOperator, + tsOriginal: ts.Node +): lua.Expression { + switch (operator) { + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.CaretToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return transformBinaryBitOperation(context, tsOriginal, left, right, operator); + default: + const luaOperator = transformBinaryOperator(context, tsOriginal, operator); + if (luaOperator === lua.SyntaxKind.ConcatOperator) { + left = wrapInToStringForConcat(left); + right = wrapInToStringForConcat(right); + } + + return lua.createBinaryExpression(left, right, luaOperator, tsOriginal); + } +} + +export const transformBinaryExpression: FunctionVisitor = (node, context) => { + const typeOfResult = transformTypeOfBinaryExpression(context, node); + if (typeOfResult) { + return typeOfResult; + } + + const operator = node.operatorToken.kind; + + // Check if this is an assignment token, then handle accordingly + if (isCompoundAssignmentToken(operator)) { + return transformCompoundAssignmentExpression( + context, + node, + node.left, + node.right, + unwrapCompoundAssignmentToken(operator), + false + ); + } + + // Transpile operators + switch (operator) { + case ts.SyntaxKind.AmpersandToken: + case ts.SyntaxKind.BarToken: + case ts.SyntaxKind.CaretToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.BarBarToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.AsteriskToken: + case ts.SyntaxKind.AsteriskAsteriskToken: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.PercentToken: + + case ts.SyntaxKind.GreaterThanToken: + case ts.SyntaxKind.GreaterThanEqualsToken: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.LessThanEqualsToken: + case ts.SyntaxKind.EqualsEqualsToken: + case ts.SyntaxKind.EqualsEqualsEqualsToken: + case ts.SyntaxKind.ExclamationEqualsToken: + case ts.SyntaxKind.ExclamationEqualsEqualsToken: + return transformBinaryOperation( + context, + context.transformExpression(node.left), + context.transformExpression(node.right), + operator, + node + ); + + case ts.SyntaxKind.EqualsToken: + return transformAssignmentExpression(context, node as ts.AssignmentExpression); + + case ts.SyntaxKind.InKeyword: { + const lhs = context.transformExpression(node.left); + const rhs = context.transformExpression(node.right); + const indexExpression = lua.createTableIndexExpression(rhs, lhs); + return lua.createBinaryExpression( + indexExpression, + lua.createNilLiteral(), + lua.SyntaxKind.InequalityOperator, + node + ); + } + + case ts.SyntaxKind.InstanceOfKeyword: { + const lhs = context.transformExpression(node.left); + const rhs = context.transformExpression(node.right); + const rhsType = context.checker.getTypeAtLocation(node.right); + const annotations = getTypeAnnotations(context, rhsType); + + if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { + // Cannot use instanceof on extension classes + throw InvalidInstanceOfExtension(node); + } + + if (annotations.has(AnnotationKind.LuaTable)) { + throw InvalidInstanceOfLuaTable(node); + } + + if (isStandardLibraryType(context, rhsType, "ObjectConstructor")) { + return transformLuaLibFunction(context, LuaLibFeature.InstanceOfObject, node, lhs); + } + + return transformLuaLibFunction(context, LuaLibFeature.InstanceOf, node, lhs, rhs); + } + + case ts.SyntaxKind.CommaToken: { + const rhs = context.transformExpression(node.right); + return createImmediatelyInvokedFunctionExpression( + context.transformStatements(ts.createExpressionStatement(node.left)), + rhs, + node + ); + } + + default: + throw UnsupportedKind("binary operator", operator, node); + } +}; + +export function transformBinaryExpressionStatement( + context: TransformationContext, + node: ts.ExpressionStatement +): lua.Statement[] | lua.Statement | undefined { + const { expression } = node; + if (ts.isBinaryExpression(expression)) { + const operator = expression.operatorToken.kind; + + if (isCompoundAssignmentToken(operator)) { + // +=, -=, etc... + return transformCompoundAssignmentStatement( + context, + expression, + expression.left, + expression.right, + unwrapCompoundAssignmentToken(operator) + ); + } else if (operator === ts.SyntaxKind.EqualsToken) { + return transformAssignmentStatement(context, expression as ts.AssignmentExpression); + } else if (operator === ts.SyntaxKind.CommaToken) { + const statements = [ + ...context.transformStatements(ts.createExpressionStatement(expression.left)), + ...context.transformStatements(ts.createExpressionStatement(expression.right)), + ]; + + return lua.createDoStatement(statements, expression); + } + } +} diff --git a/src/transformation/visitors/block.ts b/src/transformation/visitors/block.ts new file mode 100644 index 000000000..c26cc1cea --- /dev/null +++ b/src/transformation/visitors/block.ts @@ -0,0 +1,26 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; + +export function transformBlockOrStatement(context: TransformationContext, statement: ts.Statement): lua.Statement[] { + return context.transformStatements(ts.isBlock(statement) ? statement.statements : statement); +} + +export function transformScopeBlock( + context: TransformationContext, + node: ts.Block, + scopeType: ScopeType +): [lua.Block, Scope] { + pushScope(context, scopeType); + const statements = performHoisting(context, context.transformStatements(node.statements)); + const scope = popScope(context); + return [lua.createBlock(statements, node), scope]; +} + +export const transformBlock: FunctionVisitor = (node, context) => { + pushScope(context, ScopeType.Block); + const statements = performHoisting(context, context.transformStatements(node.statements)); + popScope(context); + return lua.createDoStatement(statements, node); +}; diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts new file mode 100644 index 000000000..49ead1ff6 --- /dev/null +++ b/src/transformation/visitors/break-continue.ts @@ -0,0 +1,33 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { UndefinedScope, UnsupportedForTarget } from "../utils/errors"; +import { findScope, ScopeType } from "../utils/scope"; + +export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { + const breakableScope = findScope(context, ScopeType.Loop | ScopeType.Switch); + if (breakableScope === undefined) { + throw UndefinedScope(); + } + + if (breakableScope.type === ScopeType.Switch) { + return lua.createGotoStatement(`____switch${breakableScope.id}_end`); + } else { + return lua.createBreakStatement(breakStatement); + } +}; + +export const transformContinueStatement: FunctionVisitor = (statement, context) => { + if (context.luaTarget === LuaTarget.Lua51) { + throw UnsupportedForTarget("Continue statement", LuaTarget.Lua51, statement); + } + + const scope = findScope(context, ScopeType.Loop); + if (scope === undefined) { + throw UndefinedScope(); + } + + scope.loopContinued = true; + return lua.createGotoStatement(`__continue${scope.id}`, statement); +}; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts new file mode 100644 index 000000000..6511347c6 --- /dev/null +++ b/src/transformation/visitors/call.ts @@ -0,0 +1,218 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { transformBuiltinCallExpression } from "../builtins"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { isInTupleReturnFunction, isTupleReturnCall, isVarArgType } from "../utils/annotations"; +import { validateAssignment } from "../utils/assignment-validation"; +import { UnsupportedKind } from "../utils/errors"; +import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isValidLuaIdentifier, luaKeywords } from "../utils/safe-names"; +import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; +import { transformElementAccessArgument } from "./access"; +import { transformIdentifier } from "./identifier"; +import { transformLuaTableCallExpression } from "./lua-table"; + +export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; + +export function transformArguments( + context: TransformationContext, + params: readonly ts.Expression[], + signature?: ts.Signature, + callContext?: ts.Expression +): lua.Expression[] { + const parameters = params.map(param => context.transformExpression(param)); + + // Add context as first param if present + if (callContext) { + parameters.unshift(context.transformExpression(callContext)); + } + + if (signature && signature.parameters.length >= params.length) { + for (const [index, param] of params.entries()) { + const signatureParameter = signature.parameters[index]; + const paramType = context.checker.getTypeAtLocation(param); + const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + } + } + + return parameters; +} + +export function transformContextualCallExpression( + context: TransformationContext, + node: ts.CallExpression | ts.TaggedTemplateExpression, + transformedArguments: lua.Expression[] +): lua.Expression { + const left = ts.isCallExpression(node) ? node.expression : node.tag; + if ( + ts.isPropertyAccessExpression(left) && + !luaKeywords.has(left.name.text) && + isValidLuaIdentifier(left.name.text) + ) { + // table:name() + let table = context.transformExpression(left.expression); + if (lua.isTableExpression(table)) { + table = lua.createParenthesizedExpression(table); + } + + return lua.createMethodCallExpression( + table, + transformIdentifier(context, left.name), + transformedArguments, + node + ); + } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { + const callContext = context.transformExpression(left.expression); + if (isExpressionWithEvaluationEffect(left.expression)) { + // Inject context parameter + transformedArguments.unshift(lua.createIdentifier("____self")); + + // Cache left-side if it has effects + //(function() local ____self = context; return ____self[argument](parameters); end)() + const argument = ts.isElementAccessExpression(left) + ? transformElementAccessArgument(context, left) + : lua.createStringLiteral(left.name.text); + const selfIdentifier = lua.createIdentifier("____self"); + const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); + const index = lua.createTableIndexExpression(selfIdentifier, argument); + const callExpression = lua.createCallExpression(index, transformedArguments); + return createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); + } else { + const expression = context.transformExpression(left); + return lua.createCallExpression(expression, [callContext, ...transformedArguments]); + } + } else if (ts.isIdentifier(left)) { + const callContext = context.isStrict ? lua.createNilLiteral() : lua.createIdentifier("_G"); + transformedArguments.unshift(callContext); + const expression = context.transformExpression(left); + return lua.createCallExpression(expression, transformedArguments, node); + } else { + throw UnsupportedKind("Left Hand Side Call Expression", left.kind, left); + } +} + +function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { + const signature = context.checker.getResolvedSignature(node); + + if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { + // Super calls take the format of super.call(self,...) + const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + return lua.createCallExpression(context.transformExpression(node.expression), parameters); + } + + const parameters = transformArguments(context, node.arguments, signature); + const signatureDeclaration = signature && signature.getDeclaration(); + if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + // table:name() + return transformContextualCallExpression(context, node, parameters); + } else { + let table = context.transformExpression(node.expression.expression); + if (lua.isTableExpression(table)) { + table = lua.createParenthesizedExpression(table); + } + + // table.name() + const name = node.expression.name.text; + const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); + return lua.createCallExpression(callPath, parameters, node); + } +} + +function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const signature = context.checker.getResolvedSignature(node); + const signatureDeclaration = signature && signature.getDeclaration(); + const parameters = transformArguments(context, node.arguments, signature); + if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + // A contextual parameter must be given to this call expression + return transformContextualCallExpression(context, node, parameters); + } else { + // No context + let expression = context.transformExpression(node.expression); + if (lua.isTableExpression(expression)) { + expression = lua.createParenthesizedExpression(expression); + } + + return lua.createCallExpression(expression, parameters); + } +} + +export const transformCallExpression: FunctionVisitor = (node, context) => { + const luaTableResult = transformLuaTableCallExpression(context, node); + if (luaTableResult) { + return luaTableResult; + } + + const isTupleReturn = isTupleReturnCall(context, node); + const isTupleReturnForward = + node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); + const isInSpread = node.parent && ts.isSpreadElement(node.parent); + const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); + const wrapResult = + isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; + + const builtinResult = transformBuiltinCallExpression(context, node); + if (builtinResult) { + return wrapResult ? wrapInTable(builtinResult) : builtinResult; + } + + if (ts.isPropertyAccessExpression(node.expression)) { + const result = transformPropertyCall(context, node as PropertyCallExpression); + return wrapResult ? wrapInTable(result) : result; + } + + if (ts.isElementAccessExpression(node.expression)) { + const result = transformElementCall(context, node); + return wrapResult ? wrapInTable(result) : result; + } + + const signature = context.checker.getResolvedSignature(node); + + // Handle super calls properly + if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { + const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + + return lua.createCallExpression( + lua.createTableIndexExpression( + context.transformExpression(ts.createSuper()), + lua.createStringLiteral("____constructor") + ), + parameters + ); + } + + const callPath = context.transformExpression(node.expression); + const signatureDeclaration = signature && signature.getDeclaration(); + + let parameters: lua.Expression[] = []; + if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { + parameters = transformArguments(context, node.arguments, signature); + } else { + const callContext = context.isStrict ? ts.createNull() : ts.createIdentifier("_G"); + parameters = transformArguments(context, node.arguments, signature, callContext); + } + + const callExpression = lua.createCallExpression(callPath, parameters, node); + return wrapResult ? wrapInTable(callExpression) : callExpression; +}; + +// TODO: Currently it's also used as an array member +export const transformSpreadElement: FunctionVisitor = (node, context) => { + const innerExpression = context.transformExpression(node.expression); + if (isTupleReturnCall(context, node.expression)) { + return innerExpression; + } + + if (ts.isIdentifier(node.expression) && isVarArgType(context, node.expression)) { + return lua.createDotsLiteral(node); + } + + const type = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, type)) { + return createUnpackCall(context, innerExpression, node); + } + + return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); +}; diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts new file mode 100644 index 000000000..5c8406209 --- /dev/null +++ b/src/transformation/visitors/class/decorators.ts @@ -0,0 +1,43 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import { InvalidDecoratorContext } from "../../utils/errors"; +import { addExportToIdentifier } from "../../utils/export"; +import { ContextType, getFunctionContextType } from "../../utils/function-context"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { transformIdentifier } from "../identifier"; + +export function createConstructorDecorationStatement( + context: TransformationContext, + declaration: ts.ClassLikeDeclaration +): lua.AssignmentStatement | undefined { + const className = + declaration.name !== undefined + ? addExportToIdentifier(context, transformIdentifier(context, declaration.name)) + : lua.createAnonymousIdentifier(); + + const decorators = declaration.decorators; + if (!decorators) { + return undefined; + } + + const decoratorExpressions = decorators.map(decorator => { + const expression = decorator.expression; + const type = context.checker.getTypeAtLocation(expression); + const callContext = getFunctionContextType(context, type); + if (callContext === ContextType.Void) { + throw InvalidDecoratorContext(decorator); + } + + return context.transformExpression(expression); + }); + + const decoratorTable = lua.createTableExpression( + decoratorExpressions.map(expression => lua.createTableFieldExpression(expression)) + ); + + return lua.createAssignmentStatement( + className, + transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, decoratorTable, className) + ); +} diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts new file mode 100644 index 000000000..6f4192182 --- /dev/null +++ b/src/transformation/visitors/class/index.ts @@ -0,0 +1,363 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { getOrUpdate, isNonNull } from "../../../utils"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { + ForbiddenLuaTableNonDeclaration, + ForbiddenStaticClassPropertyName, + InvalidExportsExtension, + InvalidExtendsExtension, + InvalidExtendsLuaTable, + InvalidExtensionMetaExtension, + MissingClassName, + MissingMetaExtension, + UnknownSuperType, +} from "../../utils/errors"; +import { + createDefaultExportIdentifier, + createExportedIdentifier, + getIdentifierExportScope, + hasDefaultExportModifier, + isSymbolExported, +} from "../../utils/export"; +import { + createImmediatelyInvokedFunctionExpression, + createSelfIdentifier, + OneToManyVisitorResult, + unwrapVisitorResult, +} from "../../utils/lua-ast"; +import { createSafeName, isUnsafeName } from "../../utils/safe-names"; +import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { isAmbientNode } from "../../utils/typescript"; +import { transformIdentifier } from "../identifier"; +import { transformPropertyName } from "../literal"; +import { createConstructorDecorationStatement } from "./decorators"; +import { isGetAccessorOverride, transformAccessorDeclaration } from "./members/accessors"; +import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; +import { transformClassInstanceFields } from "./members/fields"; +import { transformMethodDeclaration } from "./members/method"; +import { checkForLuaLibType } from "./new"; +import { createClassSetup } from "./setup"; +import { getExtendedType, getExtendedTypeNode, isStaticNode } from "./utils"; + +export function transformClassAsExpression( + expression: ts.ClassLikeDeclaration, + context: TransformationContext, + isDefaultExport = false +): lua.Expression { + let className: lua.Identifier; + if (expression.name) { + className = transformIdentifier(context, expression.name); + } else if (isDefaultExport) { + className = createDefaultExportIdentifier(expression); + } else { + className = lua.createAnonymousIdentifier(); + } + + pushScope(context, ScopeType.Function); + const classDeclaration = unwrapVisitorResult(transformClassDeclaration(expression, context, className)); + popScope(context); + + return createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); +} + +const classStacks = new WeakMap(); + +export function transformClassDeclaration( + classDeclaration: ts.ClassLikeDeclaration, + context: TransformationContext, + nameOverride?: lua.Identifier +): OneToManyVisitorResult { + const classStack = getOrUpdate(classStacks, context, () => []); + classStack.push(classDeclaration); + + let className: lua.Identifier; + let classNameText: string; + if (nameOverride !== undefined) { + className = nameOverride; + classNameText = nameOverride.text; + } else if (classDeclaration.name !== undefined) { + className = transformIdentifier(context, classDeclaration.name); + classNameText = classDeclaration.name.text; + } else { + const isDefaultExport = hasDefaultExportModifier(classDeclaration); + if (isDefaultExport) { + const left = createExportedIdentifier(context, createDefaultExportIdentifier(classDeclaration)); + const right = transformClassAsExpression(classDeclaration, context, true); + + return lua.createAssignmentStatement(left, right, classDeclaration); + } else { + throw MissingClassName(classDeclaration); + } + } + + const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(classDeclaration)); + + // Find out if this class is extension of existing class + const extensionDirective = annotations.get(AnnotationKind.Extension); + const isExtension = extensionDirective !== undefined; + const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); + + if (isExtension && isMetaExtension) { + throw InvalidExtensionMetaExtension(classDeclaration); + } + + if ((isExtension || isMetaExtension) && getIdentifierExportScope(context, className) !== undefined) { + // Cannot export extension classes + throw InvalidExportsExtension(classDeclaration); + } + + // Get type that is extended + const extendsType = getExtendedType(context, classDeclaration); + + if (extendsType) { + checkForLuaLibType(context, extendsType); + } + + if (!(isExtension || isMetaExtension) && extendsType) { + // Non-extensions cannot extend extension classes + const extendsAnnotations = getTypeAnnotations(context, extendsType); + if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { + throw InvalidExtendsExtension(classDeclaration); + } + } + + // You cannot extend LuaTable classes + if (extendsType) { + const annotations = getTypeAnnotations(context, extendsType); + if (annotations.has(AnnotationKind.LuaTable)) { + throw InvalidExtendsLuaTable(classDeclaration); + } + } + + // LuaTable classes must be ambient + if (annotations.has(AnnotationKind.LuaTable) && !isAmbientNode(classDeclaration)) { + throw ForbiddenLuaTableNonDeclaration(classDeclaration); + } + + for (const member of classDeclaration.members) { + if (member.name && (ts.isStringLiteral(member.name) || ts.isIdentifier(member.name))) { + if (isStaticNode(member) && member.name.text === "new") { + throw ForbiddenStaticClassPropertyName(member, member.name.text); + } + } + } + + // Get all properties with value + const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); + + // Divide properties into static and non-static + const staticFields = properties.filter(isStaticNode); + const instanceFields = properties.filter(prop => !isStaticNode(prop)); + + const result: lua.Statement[] = []; + + // Overwrite the original className with the class we are overriding for extensions + if (isMetaExtension) { + if (!extendsType) { + throw MissingMetaExtension(classDeclaration); + } + + const extendsName = lua.createStringLiteral(extendsType.symbol.name as string); + className = lua.createIdentifier("__meta__" + extendsName.value); + + // local className = debug.getregistry()["extendsName"] + const assignDebugCallIndex = lua.createVariableDeclarationStatement( + className, + lua.createTableIndexExpression( + lua.createCallExpression( + lua.createTableIndexExpression( + lua.createIdentifier("debug"), + lua.createStringLiteral("getregistry") + ), + [] + ), + extendsName + ), + classDeclaration + ); + + result.push(assignDebugCallIndex); + } + + if (extensionDirective !== undefined) { + const [extensionName] = extensionDirective.args; + if (extensionName) { + className = lua.createIdentifier(extensionName); + } else if (extendsType) { + className = lua.createIdentifier(extendsType.symbol.name); + } + } + + let localClassName: lua.Identifier; + if (isUnsafeName(className.text)) { + localClassName = lua.createIdentifier( + createSafeName(className.text), + undefined, + className.symbolId, + className.text + ); + lua.setNodePosition(localClassName, className); + } else { + localClassName = className; + } + + if (!isExtension && !isMetaExtension) { + result.push( + ...createClassSetup(context, classDeclaration, className, localClassName, classNameText, extendsType) + ); + } else { + for (const f of instanceFields) { + const fieldName = transformPropertyName(context, f.name); + + const value = f.initializer !== undefined ? context.transformExpression(f.initializer) : undefined; + + // className["fieldName"] + const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); + + // className["fieldName"] = value; + const assignClassField = lua.createAssignmentStatement(classField, value); + + result.push(assignClassField); + } + } + + // Find first constructor with body + if (!isExtension && !isMetaExtension) { + const constructor = classDeclaration.members.find( + (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + ); + + if (constructor) { + // Add constructor plus initialization of instance fields + const constructorResult = transformConstructorDeclaration( + context, + constructor, + localClassName, + instanceFields, + classDeclaration + ); + + if (constructorResult) result.push(constructorResult); + } else if (!extendsType) { + // Generate a constructor if none was defined in a base class + const constructorResult = transformConstructorDeclaration( + context, + ts.createConstructor([], [], [], ts.createBlock([], true)), + localClassName, + instanceFields, + classDeclaration + ); + + if (constructorResult) result.push(constructorResult); + } else if ( + instanceFields.length > 0 || + classDeclaration.members.some(m => isGetAccessorOverride(context, m, classDeclaration)) + ) { + // Generate a constructor if none was defined in a class with instance fields that need initialization + // localClassName.prototype.____constructor = function(self, ...) + // baseClassName.prototype.____constructor(self, ...) + // ... + const constructorBody = transformClassInstanceFields(context, classDeclaration, instanceFields); + const superCall = lua.createExpressionStatement( + lua.createCallExpression( + lua.createTableIndexExpression( + context.transformExpression(ts.createSuper()), + lua.createStringLiteral("____constructor") + ), + [createSelfIdentifier(), lua.createDotsLiteral()] + ) + ); + constructorBody.unshift(superCall); + const constructorFunction = lua.createFunctionExpression( + lua.createBlock(constructorBody), + [createSelfIdentifier()], + lua.createDotsLiteral(), + undefined, + lua.FunctionExpressionFlags.Declaration + ); + result.push( + lua.createAssignmentStatement( + createConstructorName(localClassName), + constructorFunction, + classDeclaration + ) + ); + } + } + + // Transform accessors + result.push( + ...classDeclaration.members + .filter(ts.isAccessor) + .map(accessor => transformAccessorDeclaration(context, accessor, localClassName)) + .filter(isNonNull) + ); + + // Transform methods + result.push( + ...classDeclaration.members + .filter(ts.isMethodDeclaration) + .map(m => transformMethodDeclaration(context, m, localClassName, isExtension || isMetaExtension)) + .filter(isNonNull) + ); + + // Add static declarations + for (const field of staticFields) { + const fieldName = transformPropertyName(context, field.name); + const value = field.initializer ? context.transformExpression(field.initializer) : undefined; + + const classField = lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), fieldName); + + const fieldAssign = lua.createAssignmentStatement(classField, value); + + result.push(fieldAssign); + } + + const decorationStatement = createConstructorDecorationStatement(context, classDeclaration); + if (decorationStatement) { + result.push(decorationStatement); + } + + classStack.pop(); + + return result; +} + +export const transformSuperExpression: FunctionVisitor = (expression, context) => { + const classStack = getOrUpdate(classStacks, context, () => []); + const classDeclaration = classStack[classStack.length - 1]; + const typeNode = getExtendedTypeNode(context, classDeclaration); + if (typeNode === undefined) { + throw UnknownSuperType(expression); + } + + const extendsExpression = typeNode.expression; + let baseClassName: lua.AssignmentLeftHandSideExpression | undefined; + + if (ts.isIdentifier(extendsExpression)) { + const symbol = context.checker.getSymbolAtLocation(extendsExpression); + if (symbol && !isSymbolExported(context, symbol)) { + // Use "baseClassName" if base is a simple identifier + baseClassName = transformIdentifier(context, extendsExpression); + } + } + + if (!baseClassName) { + if (classDeclaration.name === undefined) { + throw MissingClassName(expression); + } + + // Use "className.____super" if the base is not a simple identifier + baseClassName = lua.createTableIndexExpression( + transformIdentifier(context, classDeclaration.name), + lua.createStringLiteral("____super"), + expression + ); + } + + return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); +}; + +export const transformThisExpression: FunctionVisitor = node => createSelfIdentifier(node); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts new file mode 100644 index 000000000..2da5f0f70 --- /dev/null +++ b/src/transformation/visitors/class/members/accessors.ts @@ -0,0 +1,104 @@ +import * as ts from "typescript"; +import * as lua from "../../../../LuaAST"; +import { TransformationContext } from "../../../context"; +import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformFunctionBody, transformParameters } from "../../function"; +import { transformIdentifier } from "../../identifier"; +import { getExtendedType, isStaticNode } from "../utils"; + +// TODO: Inline to `hasMemberInClassOrAncestor`? +function* classWithAncestors( + context: TransformationContext, + classDeclaration: ts.ClassLikeDeclarationBase +): Generator { + yield classDeclaration; + + const extendsType = getExtendedType(context, classDeclaration); + if (!extendsType) { + return false; + } + + const symbol = extendsType.getSymbol(); + if (symbol === undefined) { + return false; + } + + const symbolDeclarations = symbol.getDeclarations(); + if (symbolDeclarations === undefined) { + return false; + } + + const declaration = symbolDeclarations.find(ts.isClassLike); + if (!declaration) { + return false; + } + + yield* classWithAncestors(context, declaration); +} + +export const hasMemberInClassOrAncestor = ( + context: TransformationContext, + classDeclaration: ts.ClassLikeDeclarationBase, + callback: (m: ts.ClassElement) => boolean +) => [...classWithAncestors(context, classDeclaration)].some(c => c.members.some(callback)); + +function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { + if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { + return propertyName.text; + } else { + return undefined; // TODO: how to handle computed property names? + } +} + +function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { + const aName = getPropertyName(a); + const bName = getPropertyName(b); + return aName !== undefined && aName === bName; +} + +export function isGetAccessorOverride( + context: TransformationContext, + element: ts.ClassElement, + classDeclaration: ts.ClassLikeDeclarationBase +): element is ts.GetAccessorDeclaration { + if (!ts.isGetAccessor(element) || isStaticNode(element)) { + return false; + } + + return hasMemberInClassOrAncestor( + context, + classDeclaration, + m => ts.isPropertyDeclaration(m) && m.initializer !== undefined && isSamePropertyName(m.name, element.name) + ); +} + +export function transformAccessorDeclaration( + context: TransformationContext, + node: ts.AccessorDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + if (node.body === undefined) { + return undefined; + } + + const name = transformIdentifier(context, node.name as ts.Identifier); + + const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); + const [body] = transformFunctionBody(context, node.parameters, node.body, restParam); + const accessorFunction = lua.createFunctionExpression( + lua.createBlock(body), + params, + dot, + restParam, + lua.FunctionExpressionFlags.Declaration + ); + + const methodTable = isStaticNode(node) + ? lua.cloneIdentifier(className) + : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); + + const classAccessorsName = ts.isGetAccessorDeclaration(node) ? "____getters" : "____setters"; + const classAccessors = lua.createTableIndexExpression(methodTable, lua.createStringLiteral(classAccessorsName)); + const accessorPath = lua.createTableIndexExpression(classAccessors, lua.createStringLiteral(name.text)); + return lua.createAssignmentStatement(accessorPath, accessorFunction, node); +} diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts new file mode 100644 index 000000000..adefb1143 --- /dev/null +++ b/src/transformation/visitors/class/members/constructor.ts @@ -0,0 +1,95 @@ +import * as ts from "typescript"; +import * as lua from "../../../../LuaAST"; +import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformParameters, transformFunctionBodyStatements, transformFunctionBodyHeader } from "../../function"; +import { TransformationContext } from "../../../context"; +import { transformIdentifier } from "../../identifier"; +import { transformClassInstanceFields } from "./fields"; + +export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { + return lua.createTableIndexExpression( + lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), + lua.createStringLiteral("____constructor") + ); +} + +export function transformConstructorDeclaration( + context: TransformationContext, + statement: ts.ConstructorDeclaration, + className: lua.Identifier, + instanceFields: ts.PropertyDeclaration[], + classDeclaration: ts.ClassLikeDeclaration +): lua.Statement | undefined { + // Don't transform methods without body (overload declarations) + if (!statement.body) { + return undefined; + } + + // Transform body + const [body, scope] = transformFunctionBodyStatements(context, statement.body); + + const [params, dotsLiteral, restParamName] = transformParameters( + context, + statement.parameters, + createSelfIdentifier() + ); + + // Make sure default parameters are assigned before fields are initialized + const bodyWithFieldInitializers = transformFunctionBodyHeader(context, scope, statement.parameters, restParamName); + + // Check for field declarations in constructor + const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); + + const classInstanceFields = transformClassInstanceFields(context, classDeclaration, instanceFields); + + // If there are field initializers and the first statement is a super call, + // move super call between default assignments and initializers + if ( + (constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) && + statement.body && + statement.body.statements.length > 0 + ) { + const firstStatement = statement.body.statements[0]; + if ( + ts.isExpressionStatement(firstStatement) && + ts.isCallExpression(firstStatement.expression) && + firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ) { + const superCall = body.shift(); + if (superCall) { + bodyWithFieldInitializers.push(superCall); + } + } + } + + // Add in instance field declarations + for (const declaration of constructorFieldsDeclarations) { + const declarationName = transformIdentifier(context, declaration.name as ts.Identifier); + // self.declarationName = declarationName + const assignment = lua.createAssignmentStatement( + lua.createTableIndexExpression(createSelfIdentifier(), lua.createStringLiteral(declarationName.text)), + declarationName + ); + bodyWithFieldInitializers.push(assignment); + } + + bodyWithFieldInitializers.push(...classInstanceFields); + + bodyWithFieldInitializers.push(...body); + + const block = lua.createBlock(bodyWithFieldInitializers); + + const constructorWasGenerated = statement.pos === -1; + + return lua.createAssignmentStatement( + createConstructorName(className), + lua.createFunctionExpression( + block, + params, + dotsLiteral, + restParamName, + lua.FunctionExpressionFlags.Declaration + ), + constructorWasGenerated ? classDeclaration : statement + ); +} diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts new file mode 100644 index 000000000..c2cf8f95a --- /dev/null +++ b/src/transformation/visitors/class/members/fields.ts @@ -0,0 +1,49 @@ +import * as ts from "typescript"; +import * as lua from "../../../../LuaAST"; +import { TransformationContext } from "../../../context"; +import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformPropertyName } from "../../literal"; +import { isGetAccessorOverride } from "./accessors"; + +export function transformClassInstanceFields( + context: TransformationContext, + classDeclaration: ts.ClassLikeDeclaration, + instanceFields: ts.PropertyDeclaration[] +): lua.Statement[] { + const statements: lua.Statement[] = []; + + for (const f of instanceFields) { + // Get identifier + const fieldName = transformPropertyName(context, f.name); + + const value = f.initializer ? context.transformExpression(f.initializer) : undefined; + + // self[fieldName] + const selfIndex = lua.createTableIndexExpression(createSelfIdentifier(), fieldName); + + // self[fieldName] = value + const assignClassField = lua.createAssignmentStatement(selfIndex, value, f); + + statements.push(assignClassField); + } + + const getOverrides = classDeclaration.members.filter((m): m is ts.GetAccessorDeclaration => + isGetAccessorOverride(context, m, classDeclaration) + ); + + for (const getter of getOverrides) { + const getterName = transformPropertyName(context, getter.name); + + const resetGetter = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("rawset"), [ + createSelfIdentifier(), + getterName, + lua.createNilLiteral(), + ]), + classDeclaration.members.find(ts.isConstructorDeclaration) || classDeclaration + ); + statements.push(resetGetter); + } + + return statements; +} diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts new file mode 100644 index 000000000..fe4d15661 --- /dev/null +++ b/src/transformation/visitors/class/members/method.ts @@ -0,0 +1,51 @@ +import * as ts from "typescript"; +import * as lua from "../../../../LuaAST"; +import { TransformationContext } from "../../../context"; +import { ContextType, getFunctionContextType } from "../../../utils/function-context"; +import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformFunctionBody, transformParameters } from "../../function"; +import { transformPropertyName } from "../../literal"; +import { isStaticNode } from "../utils"; + +export function transformMethodDeclaration( + context: TransformationContext, + node: ts.MethodDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Statement | undefined { + // Don't transform methods without body (overload declarations) + if (!node.body) { + return undefined; + } + + let methodName = transformPropertyName(context, node.name); + if (lua.isStringLiteral(methodName) && methodName.value === "toString") { + methodName = lua.createStringLiteral("__tostring", node.name); + } + + const type = context.checker.getTypeAtLocation(node); + const functionContext = + getFunctionContextType(context, type) !== ContextType.Void ? createSelfIdentifier() : undefined; + const [paramNames, dots, restParamName] = transformParameters(context, node.parameters, functionContext); + + const [body] = transformFunctionBody(context, node.parameters, node.body, restParamName); + const functionExpression = lua.createFunctionExpression( + lua.createBlock(body), + paramNames, + dots, + restParamName, + lua.FunctionExpressionFlags.Declaration, + node.body + ); + + const methodTable = + isStaticNode(node) || noPrototype + ? lua.cloneIdentifier(className) + : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); + + return lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression, + node + ); +} diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts new file mode 100644 index 000000000..a35cad983 --- /dev/null +++ b/src/transformation/visitors/class/new.ts @@ -0,0 +1,86 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { InvalidAnnotationArgumentNumber, InvalidNewExpressionOnExtension } from "../../utils/errors"; +import { importLuaLibFeature, LuaLibFeature } from "../../utils/lualib"; +import { transformArguments } from "../call"; +import { transformLuaTableNewExpression } from "../lua-table"; + +const builtinErrorTypeNames = new Set([ + "Error", + "ErrorConstructor", + "RangeError", + "RangeErrorConstructor", + "ReferenceError", + "ReferenceErrorConstructor", + "SyntaxError", + "SyntaxErrorConstructor", + "TypeError", + "TypeErrorConstructor", + "URIError", + "URIErrorConstructor", +]); + +// TODO: Do it in identifier? +export function checkForLuaLibType(context: TransformationContext, type: ts.Type): void { + if (!type.symbol) return; + + const name = context.checker.getFullyQualifiedName(type.symbol); + switch (name) { + case "Map": + importLuaLibFeature(context, LuaLibFeature.Map); + return; + case "Set": + importLuaLibFeature(context, LuaLibFeature.Set); + return; + case "WeakMap": + importLuaLibFeature(context, LuaLibFeature.WeakMap); + return; + case "WeakSet": + importLuaLibFeature(context, LuaLibFeature.WeakSet); + return; + } + + if (builtinErrorTypeNames.has(name)) { + importLuaLibFeature(context, LuaLibFeature.Error); + } +} + +export const transformNewExpression: FunctionVisitor = (node, context) => { + const luaTableResult = transformLuaTableNewExpression(context, node); + if (luaTableResult) { + return luaTableResult; + } + + const name = context.transformExpression(node.expression); + const signature = context.checker.getResolvedSignature(node); + const params = node.arguments + ? transformArguments(context, node.arguments, signature) + : [lua.createBooleanLiteral(true)]; + + const type = context.checker.getTypeAtLocation(node); + + checkForLuaLibType(context, type); + + const annotations = getTypeAnnotations(context, type); + + if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { + throw InvalidNewExpressionOnExtension(node); + } + + const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); + if (customConstructorAnnotation) { + if (customConstructorAnnotation.args[0] === undefined) { + throw InvalidAnnotationArgumentNumber("@customConstructor", 0, 1, node); + } + + return lua.createCallExpression( + lua.createIdentifier(customConstructorAnnotation.args[0]), + transformArguments(context, node.arguments || []), + node + ); + } + + return lua.createCallExpression(lua.createTableIndexExpression(name, lua.createStringLiteral("new")), params, node); +}; diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts new file mode 100644 index 000000000..5c136d756 --- /dev/null +++ b/src/transformation/visitors/class/setup.ts @@ -0,0 +1,348 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import { UndefinedTypeNode } from "../../utils/errors"; +import { + createDefaultExportStringLiteral, + createExportedIdentifier, + getIdentifierExportScope, + hasDefaultExportModifier, +} from "../../utils/export"; +import { + createExportsIdentifier, + createLocalOrExportedOrGlobalDeclaration, + createSelfIdentifier, +} from "../../utils/lua-ast"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { hasMemberInClassOrAncestor } from "./members/accessors"; +import { getExtendedTypeNode, isStaticNode } from "./utils"; + +export function createClassSetup( + context: TransformationContext, + statement: ts.ClassLikeDeclarationBase, + className: lua.Identifier, + localClassName: lua.Identifier, + classNameText: string, + extendsType?: ts.Type +): lua.Statement[] { + const result: lua.Statement[] = []; + + // [____exports.]className = {} + const classTable: lua.Expression = lua.createTableExpression(); + + const isDefaultExport = hasDefaultExportModifier(statement); + + const defaultExportLeftHandSide = isDefaultExport + ? lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(statement)) + : undefined; + + const classVar = defaultExportLeftHandSide + ? [lua.createAssignmentStatement(defaultExportLeftHandSide, classTable, statement)] + : createLocalOrExportedOrGlobalDeclaration(context, className, classTable, statement); + + result.push(...classVar); + + if (defaultExportLeftHandSide) { + // local localClassName = ____exports.default + result.push(lua.createVariableDeclarationStatement(localClassName, defaultExportLeftHandSide)); + } else { + const exportScope = getIdentifierExportScope(context, className); + if (exportScope) { + // local localClassName = ____exports.className + result.push( + lua.createVariableDeclarationStatement( + localClassName, + createExportedIdentifier(context, lua.cloneIdentifier(className), exportScope) + ) + ); + } + } + + // localClassName.name = className + result.push( + lua.createAssignmentStatement( + lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("name")), + lua.createStringLiteral(classNameText), + statement + ) + ); + + // localClassName.____getters = {} + if (statement.members.some(m => ts.isGetAccessor(m) && isStaticNode(m))) { + const classGetters = lua.createTableIndexExpression( + lua.cloneIdentifier(localClassName), + lua.createStringLiteral("____getters") + ); + const assignClassGetters = lua.createAssignmentStatement(classGetters, lua.createTableExpression(), statement); + result.push(assignClassGetters); + + importLuaLibFeature(context, LuaLibFeature.ClassIndex); + } + + // localClassName.__index = localClassName + const classIndex = lua.createTableIndexExpression( + lua.cloneIdentifier(localClassName), + lua.createStringLiteral("__index") + ); + const assignClassIndex = lua.createAssignmentStatement(classIndex, lua.cloneIdentifier(localClassName), statement); + result.push(assignClassIndex); + + // localClassName.____setters = {} + if (statement.members.some(m => ts.isSetAccessor(m) && isStaticNode(m))) { + const classSetters = lua.createTableIndexExpression( + lua.cloneIdentifier(localClassName), + lua.createStringLiteral("____setters") + ); + const assignClassSetters = lua.createAssignmentStatement(classSetters, lua.createTableExpression(), statement); + result.push(assignClassSetters); + + importLuaLibFeature(context, LuaLibFeature.ClassNewIndex); + } + + // localClassName.prototype = {} + const createClassPrototype = () => + lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("prototype")); + const classPrototypeTable = lua.createTableExpression(); + const assignClassPrototype = lua.createAssignmentStatement(createClassPrototype(), classPrototypeTable, statement); + result.push(assignClassPrototype); + + // localClassName.prototype.____getters = {} + if (statement.members.some(m => ts.isGetAccessor(m) && !isStaticNode(m))) { + const classPrototypeGetters = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("____getters") + ); + const assignClassPrototypeGetters = lua.createAssignmentStatement( + classPrototypeGetters, + lua.createTableExpression(), + statement + ); + result.push(assignClassPrototypeGetters); + } + + const classPrototypeIndex = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("__index") + ); + if (hasMemberInClassOrAncestor(context, statement, m => ts.isGetAccessor(m) && !isStaticNode(m))) { + // localClassName.prototype.__index = __TS__Index(localClassName.prototype) + const assignClassPrototypeIndex = lua.createAssignmentStatement( + classPrototypeIndex, + transformLuaLibFunction(context, LuaLibFeature.Index, undefined, createClassPrototype()), + statement + ); + result.push(assignClassPrototypeIndex); + } else { + // localClassName.prototype.__index = localClassName.prototype + const assignClassPrototypeIndex = lua.createAssignmentStatement( + classPrototypeIndex, + createClassPrototype(), + statement + ); + result.push(assignClassPrototypeIndex); + } + + if (statement.members.some(m => ts.isSetAccessor(m) && !isStaticNode(m))) { + // localClassName.prototype.____setters = {} + const classPrototypeSetters = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("____setters") + ); + const assignClassPrototypeSetters = lua.createAssignmentStatement( + classPrototypeSetters, + lua.createTableExpression(), + statement + ); + result.push(assignClassPrototypeSetters); + } + + if (hasMemberInClassOrAncestor(context, statement, m => ts.isSetAccessor(m) && !isStaticNode(m))) { + // localClassName.prototype.__newindex = __TS__NewIndex(localClassName.prototype) + const classPrototypeNewIndex = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("__newindex") + ); + const assignClassPrototypeIndex = lua.createAssignmentStatement( + classPrototypeNewIndex, + transformLuaLibFunction(context, LuaLibFeature.NewIndex, undefined, createClassPrototype()), + statement + ); + result.push(assignClassPrototypeIndex); + } + + // localClassName.prototype.constructor = localClassName + const classPrototypeConstructor = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("constructor") + ); + const assignClassPrototypeConstructor = lua.createAssignmentStatement( + classPrototypeConstructor, + lua.cloneIdentifier(localClassName), + statement + ); + result.push(assignClassPrototypeConstructor); + + const hasStaticGetters = hasMemberInClassOrAncestor( + context, + statement, + m => ts.isGetAccessor(m) && isStaticNode(m) + ); + const hasStaticSetters = hasMemberInClassOrAncestor( + context, + statement, + m => ts.isSetAccessor(m) && isStaticNode(m) + ); + + if (extendsType) { + const extendedTypeNode = getExtendedTypeNode(context, statement); + if (extendedTypeNode === undefined) { + throw UndefinedTypeNode(statement); + } + + // localClassName.____super = extendsExpression + const createClassBase = () => + lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("____super")); + const assignClassBase = lua.createAssignmentStatement( + createClassBase(), + context.transformExpression(extendedTypeNode.expression), + extendedTypeNode.expression + ); + result.push(assignClassBase); + + if (hasStaticGetters || hasStaticSetters) { + const metatableFields: lua.TableFieldExpression[] = []; + if (hasStaticGetters) { + // __index = __TS__ClassIndex + metatableFields.push( + lua.createTableFieldExpression( + lua.createIdentifier("__TS__ClassIndex"), + lua.createStringLiteral("__index"), + extendedTypeNode.expression + ) + ); + } else { + // __index = localClassName.____super + metatableFields.push( + lua.createTableFieldExpression( + createClassBase(), + lua.createStringLiteral("__index"), + extendedTypeNode.expression + ) + ); + } + + if (hasStaticSetters) { + // __newindex = __TS__ClassNewIndex + metatableFields.push( + lua.createTableFieldExpression( + lua.createIdentifier("__TS__ClassNewIndex"), + lua.createStringLiteral("__newindex"), + extendedTypeNode.expression + ) + ); + } + + const setClassMetatable = lua.createExpressionStatement( + lua.createCallExpression( + lua.createIdentifier("setmetatable"), + [lua.cloneIdentifier(localClassName), lua.createTableExpression(metatableFields)], + extendedTypeNode.expression + ) + ); + result.push(setClassMetatable); + } else { + // setmetatable(localClassName, localClassName.____super) + const setClassMetatable = lua.createExpressionStatement( + lua.createCallExpression( + lua.createIdentifier("setmetatable"), + [lua.cloneIdentifier(localClassName), createClassBase()], + extendedTypeNode.expression + ) + ); + result.push(setClassMetatable); + } + + // setmetatable(localClassName.prototype, localClassName.____super.prototype) + const basePrototype = lua.createTableIndexExpression(createClassBase(), lua.createStringLiteral("prototype")); + const setClassPrototypeMetatable = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("setmetatable"), [createClassPrototype(), basePrototype]), + extendedTypeNode.expression + ); + result.push(setClassPrototypeMetatable); + } else if (hasStaticGetters || hasStaticSetters) { + const metatableFields: lua.TableFieldExpression[] = []; + if (hasStaticGetters) { + // __index = __TS__ClassIndex + metatableFields.push( + lua.createTableFieldExpression( + lua.createIdentifier("__TS__ClassIndex"), + lua.createStringLiteral("__index"), + statement + ) + ); + } + + if (hasStaticSetters) { + // __newindex = __TS__ClassNewIndex + metatableFields.push( + lua.createTableFieldExpression( + lua.createIdentifier("__TS__ClassNewIndex"), + lua.createStringLiteral("__newindex"), + statement + ) + ); + } + + const setClassMetatable = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("setmetatable"), [ + lua.cloneIdentifier(localClassName), + lua.createTableExpression(metatableFields), + ]), + statement + ); + result.push(setClassMetatable); + } + + const newFuncStatements: lua.Statement[] = []; + + // local self = setmetatable({}, localClassName.prototype) + const assignSelf = lua.createVariableDeclarationStatement( + createSelfIdentifier(), + lua.createCallExpression(lua.createIdentifier("setmetatable"), [ + lua.createTableExpression(), + createClassPrototype(), + ]), + statement + ); + newFuncStatements.push(assignSelf); + + // self:____constructor(...) + const callConstructor = lua.createExpressionStatement( + lua.createMethodCallExpression(createSelfIdentifier(), lua.createIdentifier("____constructor"), [ + lua.createDotsLiteral(), + ]), + statement + ); + newFuncStatements.push(callConstructor); + + // return self + const returnSelf = lua.createReturnStatement([createSelfIdentifier()], statement); + newFuncStatements.push(returnSelf); + + // function localClassName.new(construct, ...) ... end + // or function export.localClassName.new(construct, ...) ... end + const newFunc = lua.createAssignmentStatement( + lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("new")), + lua.createFunctionExpression( + lua.createBlock(newFuncStatements), + undefined, + lua.createDotsLiteral(), + undefined, + lua.FunctionExpressionFlags.Declaration + ), + statement + ); + result.push(newFunc); + + return result; +} diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts new file mode 100644 index 000000000..45dec19cf --- /dev/null +++ b/src/transformation/visitors/class/utils.ts @@ -0,0 +1,32 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../../context"; +import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; + +export function isStaticNode(node: ts.Node): boolean { + return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); +} + +export function getExtendedTypeNode( + context: TransformationContext, + node: ts.ClassLikeDeclarationBase +): ts.ExpressionWithTypeArguments | undefined { + if (node && node.heritageClauses) { + for (const clause of node.heritageClauses) { + if (clause.token === ts.SyntaxKind.ExtendsKeyword) { + const superType = context.checker.getTypeAtLocation(clause.types[0]); + const annotations = getTypeAnnotations(context, superType); + if (!annotations.has(AnnotationKind.PureAbstract)) { + return clause.types[0]; + } + } + } + } +} + +export function getExtendedType( + context: TransformationContext, + node: ts.ClassLikeDeclarationBase +): ts.Type | undefined { + const extendedTypeNode = getExtendedTypeNode(context, node); + return extendedTypeNode && context.checker.getTypeAtLocation(extendedTypeNode); +} diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts new file mode 100644 index 000000000..b59c47cec --- /dev/null +++ b/src/transformation/visitors/conditional.ts @@ -0,0 +1,97 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { transformBlockOrStatement } from "./block"; + +function canBeFalsy(context: TransformationContext, type: ts.Type): boolean { + const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; + + const falsyFlags = + ts.TypeFlags.Boolean | + ts.TypeFlags.BooleanLiteral | + ts.TypeFlags.Undefined | + ts.TypeFlags.Null | + ts.TypeFlags.Never | + ts.TypeFlags.Void | + ts.TypeFlags.Any; + + if (type.flags & falsyFlags) { + return true; + } else if (!strictNullChecks && !type.isLiteral()) { + return true; + } else if (type.isUnion()) { + return type.types.some(subType => canBeFalsy(context, subType)); + } else { + return false; + } +} + +function wrapInFunctionCall(expression: lua.Expression): lua.FunctionExpression { + const returnStatement = lua.createReturnStatement([expression]); + + return lua.createFunctionExpression( + lua.createBlock([returnStatement]), + undefined, + undefined, + undefined, + lua.FunctionExpressionFlags.Inline + ); +} + +function transformProtectedConditionalExpression( + context: TransformationContext, + expression: ts.ConditionalExpression +): lua.CallExpression { + const condition = lua.createParenthesizedExpression(context.transformExpression(expression.condition)); + const val1 = context.transformExpression(expression.whenTrue); + const val2 = context.transformExpression(expression.whenFalse); + + const val1Function = wrapInFunctionCall(val1); + const val2Function = wrapInFunctionCall(val2); + + // (condition and (() => v1) or (() => v2))() + const conditionAnd = lua.createBinaryExpression(condition, val1Function, lua.SyntaxKind.AndOperator); + const orExpression = lua.createBinaryExpression(conditionAnd, val2Function, lua.SyntaxKind.OrOperator); + return lua.createCallExpression(lua.createParenthesizedExpression(orExpression), [], expression); +} + +export const transformConditionalExpression: FunctionVisitor = (expression, context) => { + if (canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue))) { + return transformProtectedConditionalExpression(context, expression); + } + + const condition = lua.createParenthesizedExpression(context.transformExpression(expression.condition)); + const val1 = context.transformExpression(expression.whenTrue); + const val2 = context.transformExpression(expression.whenFalse); + + // condition and v1 or v2 + const conditionAnd = lua.createBinaryExpression(condition, val1, lua.SyntaxKind.AndOperator); + return lua.createBinaryExpression(conditionAnd, val2, lua.SyntaxKind.OrOperator, expression); +}; + +export function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): lua.IfStatement { + pushScope(context, ScopeType.Conditional); + const condition = context.transformExpression(statement.expression); + const statements = performHoisting(context, transformBlockOrStatement(context, statement.thenStatement)); + popScope(context); + const ifBlock = lua.createBlock(statements); + + if (statement.elseStatement) { + if (ts.isIfStatement(statement.elseStatement)) { + const elseStatement = transformIfStatement(statement.elseStatement, context); + return lua.createIfStatement(condition, ifBlock, elseStatement); + } else { + pushScope(context, ScopeType.Conditional); + const elseStatements = performHoisting( + context, + transformBlockOrStatement(context, statement.elseStatement) + ); + popScope(context); + const elseBlock = lua.createBlock(elseStatements); + return lua.createIfStatement(condition, ifBlock, elseBlock); + } + } + + return lua.createIfStatement(condition, ifBlock); +} diff --git a/src/transformation/visitors/delete.ts b/src/transformation/visitors/delete.ts new file mode 100644 index 000000000..34e378be8 --- /dev/null +++ b/src/transformation/visitors/delete.ts @@ -0,0 +1,25 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { cast } from "../../utils"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; + +export const transformDeleteExpression: FunctionVisitor = (node, context) => { + const lhs = cast(context.transformExpression(node.expression), lua.isAssignmentLeftHandSideExpression); + const assignment = lua.createAssignmentStatement(lhs, lua.createNilLiteral(), node); + return createImmediatelyInvokedFunctionExpression([assignment], [lua.createBooleanLiteral(true)], node); +}; + +export function transformDeleteExpressionStatement( + context: TransformationContext, + node: ts.ExpressionStatement +): lua.Statement | undefined { + const expression = ts.isExpressionStatement(node) ? node.expression : node; + if (ts.isDeleteExpression(expression)) { + return lua.createAssignmentStatement( + cast(context.transformExpression(expression.expression), lua.isAssignmentLeftHandSideExpression), + lua.createNilLiteral(), + expression + ); + } +} diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts new file mode 100644 index 000000000..e721464eb --- /dev/null +++ b/src/transformation/visitors/enum.ts @@ -0,0 +1,94 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { getSymbolExportScope } from "../utils/export"; +import { createLocalOrExportedOrGlobalDeclaration } from "../utils/lua-ast"; +import { transformIdentifier } from "./identifier"; +import { transformPropertyName } from "./literal"; + +export function tryGetConstEnumValue( + context: TransformationContext, + node: ts.EnumMember | ts.PropertyAccessExpression | ts.ElementAccessExpression +): lua.Expression | undefined { + const value = context.checker.getConstantValue(node); + if (typeof value === "string") { + return lua.createStringLiteral(value, node); + } else if (typeof value === "number") { + return lua.createNumericLiteral(value, node); + } +} + +export const transformEnumDeclaration: FunctionVisitor = (node, context) => { + if (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Const && !context.options.preserveConstEnums) { + return undefined; + } + + const type = context.checker.getTypeAtLocation(node); + const membersOnly = getTypeAnnotations(context, type).has(AnnotationKind.CompileMembersOnly); + const result: lua.Statement[] = []; + + if (!membersOnly) { + const name = transformIdentifier(context, node.name); + const table = lua.createTableExpression(); + result.push(...createLocalOrExportedOrGlobalDeclaration(context, name, table, node)); + } + + const enumReference = context.transformExpression(node.name); + for (const member of node.members) { + const memberName = transformPropertyName(context, member.name); + + let valueExpression: lua.Expression | undefined; + const constEnumValue = tryGetConstEnumValue(context, member); + if (constEnumValue) { + valueExpression = constEnumValue; + } else if (member.initializer) { + if (ts.isIdentifier(member.initializer)) { + const symbol = context.checker.getSymbolAtLocation(member.initializer); + if ( + symbol && + symbol.valueDeclaration && + ts.isEnumMember(symbol.valueDeclaration) && + symbol.valueDeclaration.parent === node + ) { + const otherMemberName = transformPropertyName(context, symbol.valueDeclaration.name); + valueExpression = lua.createTableIndexExpression(enumReference, otherMemberName); + } + } + + if (!valueExpression) { + valueExpression = context.transformExpression(member.initializer); + } + } else { + valueExpression = lua.createNilLiteral(); + } + + if (membersOnly) { + const enumSymbol = context.checker.getSymbolAtLocation(node.name); + const exportScope = enumSymbol ? getSymbolExportScope(context, enumSymbol) : undefined; + + result.push( + ...createLocalOrExportedOrGlobalDeclaration( + context, + lua.isIdentifier(memberName) + ? memberName + : lua.createIdentifier(member.name.getText(), member.name), + valueExpression, + node, + undefined, + exportScope + ) + ); + } else { + const memberAccessor = lua.createTableIndexExpression(enumReference, memberName); + result.push(lua.createAssignmentStatement(memberAccessor, valueExpression, member)); + + if (!lua.isStringLiteral(valueExpression) && !lua.isNilLiteral(valueExpression)) { + const reverseMemberAccessor = lua.createTableIndexExpression(enumReference, memberAccessor); + result.push(lua.createAssignmentStatement(reverseMemberAccessor, memberName, member)); + } + } + } + + return result; +}; diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts new file mode 100644 index 000000000..f8d06c6ed --- /dev/null +++ b/src/transformation/visitors/errors.ts @@ -0,0 +1,120 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { isInTupleReturnFunction } from "../utils/annotations"; +import { createUnpackCall } from "../utils/lua-ast"; +import { findScope, ScopeType } from "../utils/scope"; +import { transformScopeBlock } from "./block"; +import { transformIdentifier } from "./identifier"; + +export const transformTryStatement: FunctionVisitor = (statement, context) => { + const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); + + const tryResultIdentifier = lua.createIdentifier("____try"); + const returnValueIdentifier = lua.createIdentifier("____returnValue"); + + const result: lua.Statement[] = []; + + let returnedIdentifier: lua.Identifier | undefined; + let returnCondition: lua.Expression | undefined; + + const pCall = lua.createIdentifier("pcall"); + const tryCall = lua.createCallExpression(pCall, [lua.createFunctionExpression(tryBlock)]); + + if (statement.catchClause && statement.catchClause.block.statements.length > 0) { + // try with catch + let [catchBlock, catchScope] = transformScopeBlock(context, statement.catchClause.block, ScopeType.Catch); + if (statement.catchClause.variableDeclaration) { + // Replace ____returned with catch variable + returnedIdentifier = transformIdentifier(context, statement.catchClause.variableDeclaration + .name as ts.Identifier); + } else if (tryScope.functionReturned || catchScope.functionReturned) { + returnedIdentifier = lua.createIdentifier("____returned"); + } + + const tryReturnIdentifiers = [tryResultIdentifier]; // ____try + if (returnedIdentifier) { + tryReturnIdentifiers.push(returnedIdentifier); // ____returned or catch variable + if (tryScope.functionReturned || catchScope.functionReturned) { + tryReturnIdentifiers.push(returnValueIdentifier); // ____returnValue + returnCondition = lua.cloneIdentifier(returnedIdentifier); + } + } + result.push(lua.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); + + if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { + // Wrap catch in function if try or catch has return + const catchCall = lua.createCallExpression( + lua.createParenthesizedExpression(lua.createFunctionExpression(catchBlock)) + ); + const catchAssign = lua.createAssignmentStatement( + [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], + catchCall + ); + catchBlock = lua.createBlock([catchAssign]); + } + const notTryCondition = lua.createUnaryExpression( + lua.createParenthesizedExpression(tryResultIdentifier), + lua.SyntaxKind.NotOperator + ); + result.push(lua.createIfStatement(notTryCondition, catchBlock)); + } else if (tryScope.functionReturned) { + // try with return, but no catch + returnedIdentifier = lua.createIdentifier("____returned"); + const returnedVariables = [tryResultIdentifier, returnedIdentifier, returnValueIdentifier]; + result.push(lua.createVariableDeclarationStatement(returnedVariables, tryCall)); + + // change return condition from '____returned' to '____try and ____returned' + returnCondition = lua.createBinaryExpression( + lua.cloneIdentifier(tryResultIdentifier), + returnedIdentifier, + lua.SyntaxKind.AndOperator + ); + } else { + // try without return or catch + result.push(lua.createExpressionStatement(tryCall)); + } + + if (statement.finallyBlock && statement.finallyBlock.statements.length > 0) { + result.push(...context.transformStatements(statement.finallyBlock)); + } + + if (returnCondition && returnedIdentifier) { + // With catch clause: + // if ____returned then return ____returnValue end + // No catch clause: + // if ____try and ____returned then return ____returnValue end + const returnValues: lua.Expression[] = []; + const parentTryCatch = findScope(context, ScopeType.Function | ScopeType.Try | ScopeType.Catch); + if (parentTryCatch && parentTryCatch.type !== ScopeType.Function) { + // Nested try/catch needs to prefix a 'true' return value + returnValues.push(lua.createBooleanLiteral(true)); + } + + if (isInTupleReturnFunction(context, statement)) { + returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); + } else { + returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); + } + + const returnStatement = lua.createReturnStatement(returnValues); + const ifReturnedStatement = lua.createIfStatement(returnCondition, lua.createBlock([returnStatement])); + result.push(ifReturnedStatement); + } + + return lua.createDoStatement(result, statement); +}; + +export const transformThrowStatement: FunctionVisitor = (statement, context) => { + const parameters: lua.Expression[] = []; + + if (statement.expression) { + parameters.push(context.transformExpression(statement.expression)); + parameters.push(lua.createNumericLiteral(0)); + } + + return lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("error"), parameters), + statement + ); +}; diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts new file mode 100644 index 000000000..0b338be6f --- /dev/null +++ b/src/transformation/visitors/expression-statement.ts @@ -0,0 +1,36 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { transformBinaryExpressionStatement } from "./binary-expression"; +import { transformDeleteExpressionStatement } from "./delete"; +import { transformLuaTableExpressionStatement } from "./lua-table"; +import { transformUnaryExpressionStatement } from "./unary-expression"; + +export const transformExpressionStatement: FunctionVisitor = (node, context) => { + const luaTableResult = transformLuaTableExpressionStatement(context, node); + if (luaTableResult) { + return luaTableResult; + } + + const unaryExpressionResult = transformUnaryExpressionStatement(context, node); + if (unaryExpressionResult) { + return unaryExpressionResult; + } + + const binaryExpressionResult = transformBinaryExpressionStatement(context, node); + if (binaryExpressionResult) { + return binaryExpressionResult; + } + + const deleteExpressionResult = transformDeleteExpressionStatement(context, node); + if (deleteExpressionResult) { + return deleteExpressionResult; + } + + const expression = ts.isExpressionStatement(node) ? node.expression : node; + const result = context.transformExpression(expression); + return lua.isCallExpression(result) || lua.isMethodCallExpression(result) + ? lua.createExpressionStatement(result) + : // Assign expression statements to dummy to make sure they're legal Lua + lua.createVariableDeclarationStatement(lua.createAnonymousIdentifier(), result); +}; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts new file mode 100644 index 000000000..10e3dbea3 --- /dev/null +++ b/src/transformation/visitors/function.ts @@ -0,0 +1,284 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { isVarArgType } from "../utils/annotations"; +import { MissingFunctionName, UnsupportedFunctionWithoutBody } from "../utils/errors"; +import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; +import { ContextType, getFunctionContextType } from "../utils/function-context"; +import { + createExportsIdentifier, + createImmediatelyInvokedFunctionExpression, + createLocalOrExportedOrGlobalDeclaration, + createSelfIdentifier, + wrapInTable, +} from "../utils/lua-ast"; +import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; +import { getSymbolIdOfSymbol } from "../utils/symbols"; +import { transformGeneratorFunctionBody } from "./generator"; +import { transformIdentifier } from "./identifier"; +import { transformBindingPattern } from "./variable-declaration"; + +function transformParameterDefaultValueDeclaration( + context: TransformationContext, + parameterName: lua.Identifier, + value?: ts.Expression, + tsOriginal?: ts.Node +): lua.Statement { + const parameterValue = value ? context.transformExpression(value) : undefined; + const assignment = lua.createAssignmentStatement(parameterName, parameterValue); + + const nilCondition = lua.createBinaryExpression( + parameterName, + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + + const ifBlock = lua.createBlock([assignment]); + + return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); +} + +function isRestParameterReferenced(context: TransformationContext, identifier: lua.Identifier, scope: Scope): boolean { + if (!identifier.symbolId) { + return true; + } + if (scope.referencedSymbols === undefined) { + return false; + } + const references = scope.referencedSymbols.get(identifier.symbolId); + if (!references) { + return false; + } + // Ignore references to @vararg types in spread elements + return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarArgType(context, r)); +} + +export function transformFunctionBodyStatements( + context: TransformationContext, + body: ts.Block +): [lua.Statement[], Scope] { + pushScope(context, ScopeType.Function); + const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); + const scope = popScope(context); + return [bodyStatements, scope]; +} + +export function transformFunctionBodyHeader( + context: TransformationContext, + bodyScope: Scope, + parameters: ts.NodeArray, + spreadIdentifier?: lua.Identifier +): lua.Statement[] { + const headerStatements = []; + + // Add default parameters and object binding patterns + const bindingPatternDeclarations: lua.Statement[] = []; + let bindPatternIndex = 0; + for (const declaration of parameters) { + if (ts.isObjectBindingPattern(declaration.name) || ts.isArrayBindingPattern(declaration.name)) { + const identifier = lua.createIdentifier(`____bindingPattern${bindPatternIndex++}`); + if (declaration.initializer !== undefined) { + // Default binding parameter + headerStatements.push( + transformParameterDefaultValueDeclaration(context, identifier, declaration.initializer) + ); + } + + // Binding pattern + bindingPatternDeclarations.push(...transformBindingPattern(context, declaration.name, identifier)); + } else if (declaration.initializer !== undefined) { + // Default parameter + headerStatements.push( + transformParameterDefaultValueDeclaration( + context, + transformIdentifier(context, declaration.name), + declaration.initializer + ) + ); + } + } + + // Push spread operator here + if (spreadIdentifier && isRestParameterReferenced(context, spreadIdentifier, bodyScope)) { + const spreadTable = wrapInTable(lua.createDotsLiteral()); + headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); + } + + // Binding pattern statements need to be after spread table is declared + headerStatements.push(...bindingPatternDeclarations); + + return headerStatements; +} + +export function transformFunctionBody( + context: TransformationContext, + parameters: ts.NodeArray, + body: ts.Block, + spreadIdentifier?: lua.Identifier +): [lua.Statement[], Scope] { + const [bodyStatements, scope] = transformFunctionBodyStatements(context, body); + const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); + return [[...headerStatements, ...bodyStatements], scope]; +} + +export function transformParameters( + context: TransformationContext, + parameters: ts.NodeArray, + functionContext?: lua.Identifier +): [lua.Identifier[], lua.DotsLiteral | undefined, lua.Identifier | undefined] { + // Build parameter string + const paramNames: lua.Identifier[] = []; + if (functionContext) { + paramNames.push(functionContext); + } + + let restParamName: lua.Identifier | undefined; + let dotsLiteral: lua.DotsLiteral | undefined; + let identifierIndex = 0; + + // Only push parameter name to paramName array if it isn't a spread parameter + for (const param of parameters) { + if (ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + continue; + } + + // Binding patterns become ____bindingPattern0, ____bindingPattern1, etc as function parameters + // See transformFunctionBody for how these values are destructured + const paramName = + ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) + ? lua.createIdentifier(`____bindingPattern${identifierIndex++}`) + : transformIdentifier(context, param.name as ts.Identifier); + + // This parameter is a spread parameter (...param) + if (!param.dotDotDotToken) { + paramNames.push(paramName); + } else { + restParamName = paramName; + // Push the spread operator into the paramNames array + dotsLiteral = lua.createDotsLiteral(); + } + } + + return [paramNames, dotsLiteral, restParamName]; +} + +export function transformFunctionLikeDeclaration( + node: ts.FunctionLikeDeclaration, + context: TransformationContext +): lua.Expression { + const type = context.checker.getTypeAtLocation(node); + + let functionContext: lua.Identifier | undefined; + if (getFunctionContextType(context, type) !== ContextType.Void) { + if (ts.isArrowFunction(node)) { + // dummy context for arrow functions with parameters + if (node.parameters.length > 0) { + functionContext = lua.createAnonymousIdentifier(); + } + } else { + // self context + functionContext = createSelfIdentifier(); + } + } + + // Build parameter string + const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); + + let flags = lua.FunctionExpressionFlags.None; + + if (node.body === undefined) { + throw UnsupportedFunctionWithoutBody(node); + } + + let body: ts.Block; + if (ts.isBlock(node.body)) { + body = node.body; + } else { + const returnExpression = ts.createReturn(node.body); + body = ts.createBlock([returnExpression]); + returnExpression.parent = body; + if (node.body) { + body.parent = node.body.parent; + } + flags |= lua.FunctionExpressionFlags.Inline; + } + + const [transformedBody, scope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); + + const functionExpression = lua.createFunctionExpression( + lua.createBlock(transformedBody), + paramNames, + dotsLiteral, + spreadIdentifier, + flags, + node + ); + + // Handle named function expressions which reference themselves + if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) { + const symbol = context.checker.getSymbolAtLocation(node.name); + if (symbol) { + const symbolId = getSymbolIdOfSymbol(context, symbol); + // Only wrap if the name is actually referenced inside the function + if (symbolId !== undefined && scope.referencedSymbols.has(symbolId)) { + const nameIdentifier = transformIdentifier(context, node.name); + return createImmediatelyInvokedFunctionExpression( + [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], + lua.cloneIdentifier(nameIdentifier) + ); + } + } + } + + return functionExpression; +} + +export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { + // Don't transform functions without body (overload declarations) + if (!node.body) { + return undefined; + } + + const type = context.checker.getTypeAtLocation(node); + const functionContext = + getFunctionContextType(context, type) !== ContextType.Void ? createSelfIdentifier() : undefined; + const [params, dotsLiteral, restParamName] = transformParameters(context, node.parameters, functionContext); + + const [body, functionScope] = node.asteriskToken + ? transformGeneratorFunctionBody(context, node.parameters, node.body, restParamName) + : transformFunctionBody(context, node.parameters, node.body, restParamName); + + const block = lua.createBlock(body); + const functionExpression = lua.createFunctionExpression( + block, + params, + dotsLiteral, + restParamName, + lua.FunctionExpressionFlags.Declaration + ); + + const name = node.name ? transformIdentifier(context, node.name) : undefined; + + const isDefaultExport = hasDefaultExportModifier(node); + if (isDefaultExport) { + return lua.createAssignmentStatement( + lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(node)), + transformFunctionLikeDeclaration(node, context) + ); + } else if (!name) { + throw MissingFunctionName(node); + } + + // Remember symbols referenced in this function for hoisting later + if (!context.options.noHoisting && name.symbolId !== undefined) { + const scope = peekScope(context); + if (!scope.functionDefinitions) { + scope.functionDefinitions = new Map(); + } + + const functionInfo = { referencedSymbols: functionScope.referencedSymbols || new Map() }; + scope.functionDefinitions.set(name.symbolId, functionInfo); + } + + return createLocalOrExportedOrGlobalDeclaration(context, name, functionExpression, node); +}; diff --git a/src/transformation/visitors/generator.ts b/src/transformation/visitors/generator.ts new file mode 100644 index 000000000..835cc30fd --- /dev/null +++ b/src/transformation/visitors/generator.ts @@ -0,0 +1,115 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { wrapInTable } from "../utils/lua-ast"; +import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; +import { Scope } from "../utils/scope"; +import { transformFunctionBody } from "./function"; + +export function transformGeneratorFunctionBody( + context: TransformationContext, + parameters: ts.NodeArray, + body: ts.Block, + spreadIdentifier?: lua.Identifier +): [lua.Statement[], Scope] { + importLuaLibFeature(context, LuaLibFeature.Symbol); + const [functionBody, functionScope] = transformFunctionBody(context, parameters, body); + + const coroutineIdentifier = lua.createIdentifier("____co"); + const valueIdentifier = lua.createIdentifier("____value"); + const errIdentifier = lua.createIdentifier("____err"); + const itIdentifier = lua.createIdentifier("____it"); + + // local ____co = coroutine.create(originalFunction) + const coroutine = lua.createVariableDeclarationStatement( + coroutineIdentifier, + lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("create")), + [lua.createFunctionExpression(lua.createBlock(functionBody))] + ) + ); + + const nextBody = []; + // coroutine.resume(__co, ...) + const resumeCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("resume")), + [coroutineIdentifier, lua.createDotsLiteral()] + ); + + // ____err, ____value = coroutine.resume(____co, ...) + nextBody.push(lua.createVariableDeclarationStatement([errIdentifier, valueIdentifier], resumeCall)); + + // if(not ____err){error(____value)} + const errorCheck = lua.createIfStatement( + lua.createUnaryExpression(errIdentifier, lua.SyntaxKind.NotOperator), + lua.createBlock([ + lua.createExpressionStatement(lua.createCallExpression(lua.createIdentifier("error"), [valueIdentifier])), + ]) + ); + nextBody.push(errorCheck); + + // coroutine.status(____co) == "dead"; + const coStatus = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("status")), + [coroutineIdentifier] + ); + const status = lua.createBinaryExpression( + coStatus, + lua.createStringLiteral("dead"), + lua.SyntaxKind.EqualityOperator + ); + + // {done = coroutine.status(____co) == "dead"; value = ____value} + const iteratorResult = lua.createTableExpression([ + lua.createTableFieldExpression(status, lua.createStringLiteral("done")), + lua.createTableFieldExpression(valueIdentifier, lua.createStringLiteral("value")), + ]); + nextBody.push(lua.createReturnStatement([iteratorResult])); + + // function(____, ...) + const nextFunctionDeclaration = lua.createFunctionExpression( + lua.createBlock(nextBody), + [lua.createAnonymousIdentifier()], + lua.createDotsLiteral() + ); + + // ____it = {next = function(____, ...)} + const iterator = lua.createVariableDeclarationStatement( + itIdentifier, + lua.createTableExpression([ + lua.createTableFieldExpression(nextFunctionDeclaration, lua.createStringLiteral("next")), + ]) + ); + + const symbolIterator = lua.createTableIndexExpression( + lua.createIdentifier("Symbol"), + lua.createStringLiteral("iterator") + ); + + const block = [ + coroutine, + iterator, + //____it[Symbol.iterator] = {return ____it} + lua.createAssignmentStatement( + lua.createTableIndexExpression(itIdentifier, symbolIterator), + lua.createFunctionExpression(lua.createBlock([lua.createReturnStatement([itIdentifier])])) + ), + //return ____it + lua.createReturnStatement([itIdentifier]), + ]; + + if (spreadIdentifier) { + const spreadTable = wrapInTable(lua.createDotsLiteral()); + block.unshift(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); + } + + return [block, functionScope]; +} + +export const transformYieldExpression: FunctionVisitor = (expression, context) => { + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), + expression.expression ? [context.transformExpression(expression.expression)] : [], + expression + ); +}; diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts new file mode 100644 index 000000000..565c0625b --- /dev/null +++ b/src/transformation/visitors/identifier.ts @@ -0,0 +1,48 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { transformBuiltinIdentifierExpression } from "../builtins"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { isForRangeType } from "../utils/annotations"; +import { InvalidForRangeCall } from "../utils/errors"; +import { createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; +import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; +import { getIdentifierSymbolId } from "../utils/symbols"; +import { findFirstNodeAbove } from "../utils/typescript"; + +export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { + if (isForRangeType(context, identifier)) { + const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); + if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { + throw InvalidForRangeCall( + identifier, + "@forRange function can only be used as an iterable in a for...of loop." + ); + } + } + + const text = hasUnsafeIdentifierName(context, identifier) ? createSafeName(identifier.text) : identifier.text; + + const symbolId = getIdentifierSymbolId(context, identifier); + return lua.createIdentifier(text, identifier, symbolId, identifier.text); +} + +export const transformIdentifierExpression: FunctionVisitor = (node, context) => { + // TODO: Move below to avoid extra transforms? + const identifier = transformIdentifier(context, node); + + const exportScope = getIdentifierExportScope(context, identifier); + if (exportScope) { + return createExportedIdentifier(context, identifier, exportScope); + } + + if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + return lua.createNilLiteral(); + } + + const builtinResult = transformBuiltinIdentifierExpression(context, node); + if (builtinResult) { + return builtinResult; + } + + return identifier; +}; diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts new file mode 100644 index 000000000..404eea987 --- /dev/null +++ b/src/transformation/visitors/index.ts @@ -0,0 +1,100 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, Visitors } from "../context"; +import { transformElementAccessExpression, transformPropertyAccessExpression, transformQualifiedName } from "./access"; +import { transformBinaryExpression } from "./binary-expression"; +import { transformBlock } from "./block"; +import { transformBreakStatement, transformContinueStatement } from "./break-continue"; +import { transformCallExpression, transformSpreadElement } from "./call"; +import { + transformClassAsExpression, + transformClassDeclaration, + transformSuperExpression, + transformThisExpression, +} from "./class"; +import { transformNewExpression } from "./class/new"; +import { transformConditionalExpression, transformIfStatement } from "./conditional"; +import { transformDeleteExpression } from "./delete"; +import { transformEnumDeclaration } from "./enum"; +import { transformThrowStatement, transformTryStatement } from "./errors"; +import { transformExpressionStatement } from "./expression-statement"; +import { transformFunctionDeclaration, transformFunctionLikeDeclaration } from "./function"; +import { transformYieldExpression } from "./generator"; +import { transformIdentifierExpression } from "./identifier"; +import { literalVisitors } from "./literal"; +import { transformDoStatement, transformWhileStatement } from "./loops/do-while"; +import { transformForStatement } from "./loops/for"; +import { transformForInStatement } from "./loops/for-in"; +import { transformForOfStatement } from "./loops/for-of"; +import { transformExportAssignment, transformExportDeclaration } from "./modules/export"; +import { + transformExternalModuleReference, + transformImportDeclaration, + transformImportEqualsDeclaration, +} from "./modules/import"; +import { transformModuleDeclaration } from "./namespace"; +import { transformReturnStatement } from "./return"; +import { transformSourceFileNode } from "./sourceFile"; +import { transformSwitchStatement } from "./switch"; +import { transformTaggedTemplateExpression, transformTemplateExpression } from "./template"; +import { transformTypeOfExpression } from "./typeof"; +import { typescriptVisitors } from "./typescript"; +import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; +import { transformVariableStatement } from "./variable-declaration"; + +const transformEmptyStatement: FunctionVisitor = () => undefined; +const transformParenthesizedExpression: FunctionVisitor = (node, context) => + lua.createParenthesizedExpression(context.transformExpression(node.expression), node); + +export const standardVisitors: Visitors = { + ...literalVisitors, + ...typescriptVisitors, + [ts.SyntaxKind.ArrowFunction]: transformFunctionLikeDeclaration, + [ts.SyntaxKind.BinaryExpression]: transformBinaryExpression, + [ts.SyntaxKind.Block]: transformBlock, + [ts.SyntaxKind.BreakStatement]: transformBreakStatement, + [ts.SyntaxKind.CallExpression]: transformCallExpression, + [ts.SyntaxKind.ClassDeclaration]: transformClassDeclaration, + [ts.SyntaxKind.ClassExpression]: transformClassAsExpression, + [ts.SyntaxKind.ConditionalExpression]: transformConditionalExpression, + [ts.SyntaxKind.ContinueStatement]: transformContinueStatement, + [ts.SyntaxKind.DeleteExpression]: transformDeleteExpression, + [ts.SyntaxKind.DoStatement]: transformDoStatement, + [ts.SyntaxKind.ElementAccessExpression]: transformElementAccessExpression, + [ts.SyntaxKind.EmptyStatement]: transformEmptyStatement, + [ts.SyntaxKind.EnumDeclaration]: transformEnumDeclaration, + [ts.SyntaxKind.ExportAssignment]: transformExportAssignment, + [ts.SyntaxKind.ExportDeclaration]: transformExportDeclaration, + [ts.SyntaxKind.ExpressionStatement]: transformExpressionStatement, + [ts.SyntaxKind.ExternalModuleReference]: transformExternalModuleReference, + [ts.SyntaxKind.ForInStatement]: transformForInStatement, + [ts.SyntaxKind.ForOfStatement]: transformForOfStatement, + [ts.SyntaxKind.ForStatement]: transformForStatement, + [ts.SyntaxKind.FunctionDeclaration]: transformFunctionDeclaration, + [ts.SyntaxKind.FunctionExpression]: transformFunctionLikeDeclaration, + [ts.SyntaxKind.Identifier]: transformIdentifierExpression, + [ts.SyntaxKind.IfStatement]: transformIfStatement, + [ts.SyntaxKind.ImportDeclaration]: transformImportDeclaration, + [ts.SyntaxKind.ImportEqualsDeclaration]: transformImportEqualsDeclaration, + [ts.SyntaxKind.ModuleDeclaration]: transformModuleDeclaration, + [ts.SyntaxKind.NewExpression]: transformNewExpression, + [ts.SyntaxKind.ParenthesizedExpression]: transformParenthesizedExpression, + [ts.SyntaxKind.PostfixUnaryExpression]: transformPostfixUnaryExpression, + [ts.SyntaxKind.PrefixUnaryExpression]: transformPrefixUnaryExpression, + [ts.SyntaxKind.PropertyAccessExpression]: transformPropertyAccessExpression, + [ts.SyntaxKind.QualifiedName]: transformQualifiedName, + [ts.SyntaxKind.ReturnStatement]: transformReturnStatement, + [ts.SyntaxKind.SourceFile]: transformSourceFileNode, + [ts.SyntaxKind.SpreadElement]: transformSpreadElement, + [ts.SyntaxKind.SuperKeyword]: transformSuperExpression, + [ts.SyntaxKind.SwitchStatement]: transformSwitchStatement, + [ts.SyntaxKind.TaggedTemplateExpression]: transformTaggedTemplateExpression, + [ts.SyntaxKind.TemplateExpression]: transformTemplateExpression, + [ts.SyntaxKind.ThisKeyword]: transformThisExpression, + [ts.SyntaxKind.ThrowStatement]: transformThrowStatement, + [ts.SyntaxKind.TryStatement]: transformTryStatement, + [ts.SyntaxKind.TypeOfExpression]: transformTypeOfExpression, + [ts.SyntaxKind.VariableStatement]: transformVariableStatement, + [ts.SyntaxKind.WhileStatement]: transformWhileStatement, + [ts.SyntaxKind.YieldExpression]: transformYieldExpression, +}; diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts new file mode 100644 index 000000000..281f70ec6 --- /dev/null +++ b/src/transformation/visitors/literal.ts @@ -0,0 +1,150 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext, Visitors } from "../context"; +import { InvalidAmbientIdentifierName, UnsupportedKind } from "../utils/errors"; +import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { + createSafeName, + hasUnsafeIdentifierName, + hasUnsafeSymbolName, + isValidLuaIdentifier, + luaKeywords, +} from "../utils/safe-names"; +import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; +import { isArrayType } from "../utils/typescript"; +import { transformFunctionLikeDeclaration } from "./function"; + +// TODO: Move to object-literal.ts? +export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { + if (ts.isComputedPropertyName(node)) { + return context.transformExpression(node.expression); + } else if (ts.isIdentifier(node)) { + return lua.createStringLiteral(node.text); + } else { + return context.transformExpression(node); + } +} + +export function createShorthandIdentifier( + context: TransformationContext, + valueSymbol: ts.Symbol | undefined, + propertyIdentifier: ts.Identifier +): lua.Expression { + let name: string; + if (valueSymbol !== undefined) { + name = hasUnsafeSymbolName(context, valueSymbol, propertyIdentifier) + ? createSafeName(valueSymbol.name) + : valueSymbol.name; + } else { + const propertyName = propertyIdentifier.text; + if (luaKeywords.has(propertyName) || !isValidLuaIdentifier(propertyName)) { + // Catch ambient declarations of identifiers with bad names + throw InvalidAmbientIdentifierName(propertyIdentifier); + } + + name = hasUnsafeIdentifierName(context, propertyIdentifier) ? createSafeName(propertyName) : propertyName; + } + + let identifier = context.transformExpression(ts.createIdentifier(name)); + lua.setNodeOriginal(identifier, propertyIdentifier); + if (valueSymbol !== undefined && lua.isIdentifier(identifier)) { + identifier.symbolId = getSymbolIdOfSymbol(context, valueSymbol); + + const exportScope = getSymbolExportScope(context, valueSymbol); + if (exportScope) { + identifier = createExportedIdentifier(context, identifier, exportScope); + } + } + + return identifier; +} + +const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { + let properties: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; + + for (const element of expression.properties) { + const name = element.name ? transformPropertyName(context, element.name) : undefined; + + if (ts.isPropertyAssignment(element)) { + const expression = context.transformExpression(element.initializer); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + trackSymbolReference(context, valueSymbol, element.name); + } + + const identifier = createShorthandIdentifier(context, valueSymbol, element.name); + properties.push(lua.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { + const expression = transformFunctionLikeDeclaration(element, context); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + properties = []; + } + + const type = context.checker.getTypeAtLocation(element.expression); + let tableExpression: lua.Expression; + if (isArrayType(context, type)) { + tableExpression = transformLuaLibFunction( + context, + LuaLibFeature.ArrayToObject, + element.expression, + context.transformExpression(element.expression) + ); + } else { + tableExpression = context.transformExpression(element.expression); + } + + tableExpressions.push(tableExpression); + } else { + // TODO: Accessors + throw UnsupportedKind("object literal element", element.kind, expression); + } + } + + if (tableExpressions.length === 0) { + return lua.createTableExpression(properties, expression); + } else { + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + } + + if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { + tableExpressions.unshift(lua.createTableExpression(undefined, expression)); + } + + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); + } +}; + +const transformArrayLiteralExpression: FunctionVisitor = (expression, context) => { + const values = expression.elements.map(element => + lua.createTableFieldExpression( + ts.isOmittedExpression(element) ? lua.createNilLiteral(element) : context.transformExpression(element), + undefined, + element + ) + ); + + return lua.createTableExpression(values, expression); +}; + +export const literalVisitors: Visitors = { + [ts.SyntaxKind.NullKeyword]: node => lua.createNilLiteral(node), + [ts.SyntaxKind.TrueKeyword]: node => lua.createBooleanLiteral(true, node), + [ts.SyntaxKind.FalseKeyword]: node => lua.createBooleanLiteral(false, node), + [ts.SyntaxKind.NumericLiteral]: node => lua.createNumericLiteral(Number(node.text), node), + [ts.SyntaxKind.StringLiteral]: node => lua.createStringLiteral(node.text, node), + [ts.SyntaxKind.NoSubstitutionTemplateLiteral]: node => lua.createStringLiteral(node.text, node), + [ts.SyntaxKind.ObjectLiteralExpression]: transformObjectLiteralExpression, + [ts.SyntaxKind.ArrayLiteralExpression]: transformArrayLiteralExpression, +}; diff --git a/src/transformation/visitors/loops/body.ts b/src/transformation/visitors/loops/body.ts new file mode 100644 index 000000000..e46c4112d --- /dev/null +++ b/src/transformation/visitors/loops/body.ts @@ -0,0 +1,25 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import { performHoisting, popScope, pushScope, ScopeType } from "../../utils/scope"; +import { transformBlockOrStatement } from "../block"; + +export function transformLoopBody( + context: TransformationContext, + loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement +): lua.Statement[] { + pushScope(context, ScopeType.Loop); + const body = performHoisting(context, transformBlockOrStatement(context, loop.statement)); + const scope = popScope(context); + const scopeId = scope.id; + + if (!scope.loopContinued) { + return body; + } + + const baseResult: lua.Statement[] = [lua.createDoStatement(body)]; + const continueLabel = lua.createLabelStatement(`__continue${scopeId}`); + baseResult.push(continueLabel); + + return baseResult; +} diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts new file mode 100644 index 000000000..e1a56c496 --- /dev/null +++ b/src/transformation/visitors/loops/do-while.ts @@ -0,0 +1,24 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { FunctionVisitor } from "../../context"; +import { transformLoopBody } from "./body"; + +export const transformWhileStatement: FunctionVisitor = (statement, context) => { + return lua.createWhileStatement( + lua.createBlock(transformLoopBody(context, statement)), + context.transformExpression(statement.expression), + statement + ); +}; + +export const transformDoStatement: FunctionVisitor = (statement, context) => { + const body = lua.createDoStatement(transformLoopBody(context, statement)); + let condition = context.transformExpression(statement.expression); + if (lua.isUnaryExpression(condition) && condition.operator === lua.SyntaxKind.NotOperator) { + condition = condition.operand; + } else { + condition = lua.createUnaryExpression(lua.createParenthesizedExpression(condition), lua.SyntaxKind.NotOperator); + } + + return lua.createRepeatStatement(lua.createBlock([body]), condition, statement); +}; diff --git a/src/transformation/visitors/loops/for-in.ts b/src/transformation/visitors/loops/for-in.ts new file mode 100644 index 000000000..b79f18ccf --- /dev/null +++ b/src/transformation/visitors/loops/for-in.ts @@ -0,0 +1,45 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { FunctionVisitor } from "../../context"; +import { ForbiddenForIn, UnsupportedForInVariable } from "../../utils/errors"; +import { isArrayType } from "../../utils/typescript"; +import { transformIdentifier } from "../identifier"; +import { transformLoopBody } from "./body"; + +export const transformForInStatement: FunctionVisitor = (statement, context) => { + if (isArrayType(context, context.checker.getTypeAtLocation(statement.expression))) { + throw ForbiddenForIn(statement); + } + + // Transpile expression + const pairsIdentifier = lua.createIdentifier("pairs"); + const expression = context.transformExpression(statement.expression); + const pairsCall = lua.createCallExpression(pairsIdentifier, [expression]); + + const body = lua.createBlock(transformLoopBody(context, statement)); + + // Transform iteration variable + // TODO: After the transformation pipeline refactor we should look at refactoring this together with the + // for-of initializer transformation. + let iterationVariable: lua.Identifier; + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { + iterationVariable = transformIdentifier(context, statement.initializer.declarations[0].name); + } else if (ts.isIdentifier(statement.initializer)) { + // Iteration variable becomes ____key + iterationVariable = lua.createIdentifier("____key"); + // Push variable = ____key to the start of the loop body to match TS scoping + const initializer = lua.createAssignmentStatement( + transformIdentifier(context, statement.initializer), + iterationVariable + ); + body.statements.unshift(initializer); + } else { + // This should never occur + throw UnsupportedForInVariable(statement.initializer); + } + + return lua.createForInStatement(body, [iterationVariable], [pairsCall], statement); +}; diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts new file mode 100644 index 000000000..868b2c03d --- /dev/null +++ b/src/transformation/visitors/loops/for-of.ts @@ -0,0 +1,270 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { cast, castEach } from "../../../utils"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; +import { + InvalidForRangeCall, + MissingForOfVariables, + UnsupportedNonDestructuringLuaIterator, + UnsupportedObjectDestructuringInForOf, +} from "../../utils/errors"; +import { createUnpackCall } from "../../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isArrayType, isNumberType } from "../../utils/typescript"; +import { transformArguments } from "../call"; +import { transformIdentifier } from "../identifier"; +import { transformArrayBindingElement, transformVariableDeclaration } from "../variable-declaration"; +import { transformLoopBody } from "./body"; + +function transformForOfInitializer( + context: TransformationContext, + initializer: ts.ForInitializer, + expression: lua.Expression +): lua.Statement | undefined { + if (ts.isVariableDeclarationList(initializer)) { + // Declaration of new variable + if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { + if (initializer.declarations[0].name.elements.length === 0) { + // Ignore empty destructuring assignment + return undefined; + } + + expression = createUnpackCall(context, expression, initializer); + } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { + throw UnsupportedObjectDestructuringInForOf(initializer); + } + + const variableStatements = transformVariableDeclaration(context, initializer.declarations[0]); + if (variableStatements[0]) { + // we can safely assume that for vars are not exported and therefore declarationstatenents + return lua.createVariableDeclarationStatement( + (variableStatements[0] as lua.VariableDeclarationStatement).left, + expression + ); + } else { + throw MissingForOfVariables(initializer); + } + } else { + // Assignment to existing variable + let variables: lua.AssignmentLeftHandSideExpression | lua.AssignmentLeftHandSideExpression[]; + if (ts.isArrayLiteralExpression(initializer)) { + if (initializer.elements.length > 0) { + expression = createUnpackCall(context, expression, initializer); + variables = castEach( + initializer.elements.map(e => context.transformExpression(e)), + lua.isAssignmentLeftHandSideExpression + ); + } else { + // Ignore empty destructring assignment + return undefined; + } + } else if (ts.isObjectLiteralExpression(initializer)) { + throw UnsupportedObjectDestructuringInForOf(initializer); + } else { + variables = cast(context.transformExpression(initializer), lua.isAssignmentLeftHandSideExpression); + } + + return lua.createAssignmentStatement(variables, expression); + } +} + +function transformForRangeStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + if (!ts.isCallExpression(statement.expression)) { + throw InvalidForRangeCall(statement.expression, "Expression must be a call expression."); + } + + if (statement.expression.arguments.length < 2 || statement.expression.arguments.length > 3) { + throw InvalidForRangeCall(statement.expression, "@forRange function must take 2 or 3 arguments."); + } + + if (statement.expression.arguments.some(a => !isNumberType(context, context.checker.getTypeAtLocation(a)))) { + throw InvalidForRangeCall(statement.expression, "@forRange arguments must be number types."); + } + + if (!ts.isVariableDeclarationList(statement.initializer)) { + throw InvalidForRangeCall(statement.initializer, "@forRange loop must declare its own control variable."); + } + + const controlDeclaration = statement.initializer.declarations[0]; + if (!ts.isIdentifier(controlDeclaration.name)) { + throw InvalidForRangeCall(statement.initializer, "@forRange loop cannot use destructuring."); + } + + if (!isNumberType(context, context.checker.getTypeAtLocation(controlDeclaration))) { + throw InvalidForRangeCall( + statement.expression, + "@forRange function must return Iterable or Array." + ); + } + + const control = transformIdentifier(context, controlDeclaration.name); + const signature = context.checker.getResolvedSignature(statement.expression); + const [start, limit, step] = transformArguments(context, statement.expression.arguments, signature); + return lua.createForStatement(block, control, start, limit, step, statement); +} + +function transformForOfLuaIteratorStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const luaIterator = context.transformExpression(statement.expression); + const type = context.checker.getTypeAtLocation(statement.expression); + const tupleReturn = getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn); + if (tupleReturn) { + // LuaIterator + TupleReturn + if (ts.isVariableDeclarationList(statement.initializer)) { + // Variables declared in for loop + // for ${initializer} in ${iterable} do + const initializerVariable = statement.initializer.declarations[0].name; + if (ts.isArrayBindingPattern(initializerVariable)) { + const identifiers = castEach( + initializerVariable.elements.map(e => transformArrayBindingElement(context, e)), + lua.isIdentifier + ); + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); + } + return lua.createForInStatement(block, identifiers, [luaIterator]); + } else { + // Single variable is not allowed + throw UnsupportedNonDestructuringLuaIterator(statement.initializer); + } + } else { + // Variables NOT declared in for loop - catch iterator values in temps and assign + // for ____value0 in ${iterable} do + // ${initializer} = ____value0 + if (ts.isArrayLiteralExpression(statement.initializer)) { + const tmps = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (tmps.length > 0) { + const assign = lua.createAssignmentStatement( + castEach( + statement.initializer.elements.map(e => context.transformExpression(e)), + lua.isAssignmentLeftHandSideExpression + ), + tmps + ); + block.statements.splice(0, 0, assign); + } else { + tmps.push(lua.createAnonymousIdentifier()); + } + return lua.createForInStatement(block, tmps, [luaIterator]); + } else { + // Single variable is not allowed + throw UnsupportedNonDestructuringLuaIterator(statement.initializer); + } + } + } else { + // LuaIterator (no TupleReturn) + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { + // Single variable declared in for loop + // for ${initializer} in ${iterator} do + return lua.createForInStatement( + block, + [transformIdentifier(context, statement.initializer.declarations[0].name)], + [luaIterator] + ); + } else { + // Destructuring or variable NOT declared in for loop + // for ____value in ${iterator} do + // local ${initializer} = unpack(____value) + const valueVariable = lua.createIdentifier("____value"); + const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); + if (initializer) { + block.statements.splice(0, 0, initializer); + } + return lua.createForInStatement(block, [valueVariable], [luaIterator]); + } + } +} + +function transformForOfArrayStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + let valueVariable: lua.Identifier; + if (ts.isVariableDeclarationList(statement.initializer)) { + // Declaration of new variable + const variables = statement.initializer.declarations[0].name; + if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { + valueVariable = lua.createIdentifier("____values"); + const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); + if (initializer) { + block.statements.unshift(initializer); + } + } else { + valueVariable = transformIdentifier(context, variables); + } + } else { + // Assignment to existing variable + valueVariable = lua.createIdentifier("____value"); + const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); + if (initializer) { + block.statements.unshift(initializer); + } + } + + const ipairsCall = lua.createCallExpression(lua.createIdentifier("ipairs"), [ + context.transformExpression(statement.expression), + ]); + + return lua.createForInStatement(block, [lua.createAnonymousIdentifier(), valueVariable], [ipairsCall], statement); +} + +function transformForOfIteratorStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const iterable = context.transformExpression(statement.expression); + if ( + ts.isVariableDeclarationList(statement.initializer) && + ts.isIdentifier(statement.initializer.declarations[0].name) + ) { + // Single variable declared in for loop + // for ${initializer} in __TS__iterator(${iterator}) do + return lua.createForInStatement( + block, + [transformIdentifier(context, statement.initializer.declarations[0].name as ts.Identifier)], + [transformLuaLibFunction(context, LuaLibFeature.Iterator, statement.expression, iterable)] + ); + } else { + // Destructuring or variable NOT declared in for loop + // for ____value in __TS__iterator(${iterator}) do + // local ${initializer} = ____value + const valueVariable = lua.createIdentifier("____value"); + const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); + if (initializer) { + block.statements.unshift(initializer); + } + + return lua.createForInStatement( + block, + [valueVariable], + [transformLuaLibFunction(context, LuaLibFeature.Iterator, statement.expression, iterable)] + ); + } +} + +export const transformForOfStatement: FunctionVisitor = (node, context) => { + const body = lua.createBlock(transformLoopBody(context, node)); + + if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { + return transformForRangeStatement(context, node, body); + } else if (isLuaIteratorType(context, node.expression)) { + return transformForOfLuaIteratorStatement(context, node, body); + } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { + return transformForOfArrayStatement(context, node, body); + } else { + return transformForOfIteratorStatement(context, node, body); + } +}; diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts new file mode 100644 index 000000000..6d167ce03 --- /dev/null +++ b/src/transformation/visitors/loops/for.ts @@ -0,0 +1,35 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { flatMap } from "../../../utils"; +import { FunctionVisitor } from "../../context"; +import { transformVariableDeclaration } from "../variable-declaration"; +import { transformLoopBody } from "./body"; + +export const transformForStatement: FunctionVisitor = (statement, context) => { + const result: lua.Statement[] = []; + + if (statement.initializer) { + if (ts.isVariableDeclarationList(statement.initializer)) { + // local initializer = value + result.push(...flatMap(statement.initializer.declarations, d => transformVariableDeclaration(context, d))); + } else { + result.push(...context.transformStatements(ts.createExpressionStatement(statement.initializer))); + } + } + + const condition = statement.condition + ? context.transformExpression(statement.condition) + : lua.createBooleanLiteral(true); + + // Add body + const body: lua.Statement[] = transformLoopBody(context, statement); + + if (statement.incrementor) { + body.push(...context.transformStatements(ts.createExpressionStatement(statement.incrementor))); + } + + // while (condition) do ... end + result.push(lua.createWhileStatement(lua.createBlock(body), condition)); + + return lua.createDoStatement(result, statement); +}; diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts new file mode 100644 index 000000000..ceee50e34 --- /dev/null +++ b/src/transformation/visitors/lua-table.ts @@ -0,0 +1,145 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { ForbiddenLuaTableUseException, UnsupportedKind, UnsupportedProperty } from "../utils/errors"; +import { transformArguments } from "./call"; + +function parseLuaTableExpression( + context: TransformationContext, + node: ts.LeftHandSideExpression +): [lua.Expression, string] { + if (ts.isPropertyAccessExpression(node)) { + return [context.transformExpression(node.expression), node.name.text]; + } else { + throw UnsupportedKind("LuaTable access expression", node.kind, node); + } +} + +function validateLuaTableCall(methodName: string, callArguments: ts.NodeArray, original: ts.Node): void { + if (callArguments.some(argument => ts.isSpreadElement(argument))) { + throw ForbiddenLuaTableUseException("Arguments cannot be spread.", original); + } + + switch (methodName) { + case "get": + if (callArguments.length !== 1) { + throw ForbiddenLuaTableUseException("One parameter is required for get().", original); + } + break; + + case "set": + if (callArguments.length !== 2) { + throw ForbiddenLuaTableUseException("Two parameters are required for set().", original); + } + break; + } +} + +function transformLuaTableExpressionAsExpressionStatement( + context: TransformationContext, + expression: ts.CallExpression +): lua.Statement { + const [luaTable, methodName] = parseLuaTableExpression(context, expression.expression); + validateLuaTableCall(methodName, expression.arguments, expression); + const signature = context.checker.getResolvedSignature(expression); + const params = transformArguments(context, expression.arguments, signature); + + switch (methodName) { + case "get": + return lua.createVariableDeclarationStatement( + lua.createAnonymousIdentifier(expression), + lua.createTableIndexExpression(luaTable, params[0], expression), + expression + ); + case "set": + return lua.createAssignmentStatement( + lua.createTableIndexExpression(luaTable, params[0], expression), + params.splice(1), + expression + ); + default: + throw UnsupportedProperty("LuaTable", methodName, expression); + } +} + +export function transformLuaTableExpressionStatement( + context: TransformationContext, + node: ts.ExpressionStatement +): lua.Statement | undefined { + const expression = ts.isExpressionStatement(node) ? node.expression : node; + + if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { + const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); + const annotations = getTypeAnnotations(context, ownerType); + if (annotations.has(AnnotationKind.LuaTable)) { + return transformLuaTableExpressionAsExpressionStatement(context, expression); + } + } +} + +export function transformLuaTableCallExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression | undefined { + if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const annotations = getTypeAnnotations(context, ownerType); + + if (annotations.has(AnnotationKind.LuaTable)) { + const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); + validateLuaTableCall(methodName, node.arguments, node); + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + switch (methodName) { + case "get": + return lua.createTableIndexExpression(luaTable, params[0], node); + default: + throw UnsupportedProperty("LuaTable", methodName, node); + } + } + } +} + +export function transformLuaTablePropertyAccessExpression( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { + const type = context.checker.getTypeAtLocation(node.expression); + const annotations = getTypeAnnotations(context, type); + if (annotations.has(AnnotationKind.LuaTable)) { + const [luaTable, propertyName] = parseLuaTableExpression(context, node); + switch (node.name.text) { + case "length": + return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); + default: + throw UnsupportedProperty("LuaTable", propertyName, node); + } + } +} + +export function transformLuaTableElementAccessExpression( + context: TransformationContext, + node: ts.ElementAccessExpression +): void { + const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node.expression)); + if (annotations.has(AnnotationKind.LuaTable)) { + throw UnsupportedKind("LuaTable access expression", node.kind, node); + } +} + +export function transformLuaTableNewExpression( + context: TransformationContext, + node: ts.NewExpression +): lua.Expression | undefined { + const type = context.checker.getTypeAtLocation(node); + const annotations = getTypeAnnotations(context, type); + if (annotations.has(AnnotationKind.LuaTable)) { + if (node.arguments && node.arguments.length > 0) { + throw ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", node); + } else { + return lua.createTableExpression(); + } + } +} diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts new file mode 100644 index 000000000..b3a9f3433 --- /dev/null +++ b/src/transformation/visitors/modules/export.ts @@ -0,0 +1,148 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { InvalidExportDeclaration } from "../../utils/errors"; +import { + createDefaultExportIdentifier, + createDefaultExportStringLiteral, + createExportedIdentifier, +} from "../../utils/export"; +import { createExportsIdentifier } from "../../utils/lua-ast"; +import { ScopeType } from "../../utils/scope"; +import { transformScopeBlock } from "../block"; +import { transformIdentifier } from "../identifier"; +import { createShorthandIdentifier } from "../literal"; +import { createModuleRequire } from "./import"; + +export const transformExportAssignment: FunctionVisitor = (node, context) => { + if (!context.resolver.isValueAliasDeclaration(node)) { + return undefined; + } + + const exportedValue = context.transformExpression(node.expression); + + // export = [expression]; + // ____exports = [expression]; + if (node.isExportEquals) { + return lua.createVariableDeclarationStatement(createExportsIdentifier(), exportedValue, node); + } else { + // export default [expression]; + // ____exports.default = [expression]; + return lua.createAssignmentStatement( + lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(node)), + exportedValue, + node + ); + } +}; + +function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { + if (node.moduleSpecifier === undefined) { + throw InvalidExportDeclaration(node); + } + + if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { + return undefined; + } + + const moduleRequire = createModuleRequire(context, node.moduleSpecifier); + const tempModuleIdentifier = lua.createIdentifier("____export"); + + const declaration = lua.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + + const forKey = lua.createIdentifier("____exportKey"); + const forValue = lua.createIdentifier("____exportValue"); + + const body = lua.createBlock([ + lua.createAssignmentStatement(lua.createTableIndexExpression(createExportsIdentifier(), forKey), forValue), + ]); + + const pairsIdentifier = lua.createIdentifier("pairs"); + const forIn = lua.createForInStatement( + body, + [lua.cloneIdentifier(forKey), lua.cloneIdentifier(forValue)], + [lua.createCallExpression(pairsIdentifier, [lua.cloneIdentifier(tempModuleIdentifier)])] + ); + + // Wrap this in a DoStatement to prevent polluting the scope. + return lua.createDoStatement([declaration, forIn], node); +} + +const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => + (node.name && node.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || + (node.propertyName && node.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword); + +function transformExportSpecifier(context: TransformationContext, node: ts.ExportSpecifier): lua.AssignmentStatement { + const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); + const exportedIdentifier = node.propertyName ? node.propertyName : node.name; + const exportedExpression = createShorthandIdentifier(context, exportedSymbol, exportedIdentifier); + + const isDefault = isDefaultExportSpecifier(node); + const identifierToExport = isDefault + ? createDefaultExportIdentifier(node) + : transformIdentifier(context, node.name); + const exportAssignmentLeftHandSide = createExportedIdentifier(context, identifierToExport); + + return lua.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); +} + +function transformExportSpecifiersFrom( + context: TransformationContext, + statement: ts.ExportDeclaration, + moduleSpecifier: ts.Expression, + exportSpecifiers: ts.ExportSpecifier[] +): lua.Statement { + // First transpile as import clause + const importClause = ts.createImportClause( + undefined, + ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) + ); + + const importDeclaration = ts.createImportDeclaration( + statement.decorators, + statement.modifiers, + importClause, + moduleSpecifier + ); + + // Wrap in block to prevent imports from hoisting out of `do` statement + const [block] = transformScopeBlock(context, ts.createBlock([importDeclaration]), ScopeType.Block); + const result = block.statements; + + // Now the module is imported, add the imports to the export table + for (const specifier of exportSpecifiers) { + result.push( + lua.createAssignmentStatement( + createExportedIdentifier(context, transformIdentifier(context, specifier.name)), + transformIdentifier(context, specifier.name) + ) + ); + } + + // Wrap this in a DoStatement to prevent polluting the scope. + return lua.createDoStatement(result, statement); +} + +export const getExported = (context: TransformationContext, exportSpecifiers: ts.NamedExports) => + exportSpecifiers.elements.filter(exportSpecifier => context.resolver.isValueAliasDeclaration(exportSpecifier)); + +export const transformExportDeclaration: FunctionVisitor = (node, context) => { + if (!node.exportClause) { + // export * from "..."; + return transformExportAllFrom(context, node); + } + + if (!context.resolver.isValueAliasDeclaration(node)) { + return undefined; + } + + const exportSpecifiers = getExported(context, node.exportClause); + + // export { ... }; + if (!node.moduleSpecifier) { + return exportSpecifiers.map(exportSpecifier => transformExportSpecifier(context, exportSpecifier)); + } + + // export { ... } from "..."; + return transformExportSpecifiersFrom(context, node, node.moduleSpecifier, exportSpecifiers); +}; diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts new file mode 100644 index 000000000..2dd390b6f --- /dev/null +++ b/src/transformation/visitors/modules/import.ts @@ -0,0 +1,207 @@ +import * as path from "path"; +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { formatPathToLuaPath } from "../../../utils"; +import { FunctionVisitor, TransformationContext } from "../../context"; +import { AnnotationKind, getSymbolAnnotations, getTypeAnnotations } from "../../utils/annotations"; +import { UnresolvableRequirePath } from "../../utils/errors"; +import { createDefaultExportStringLiteral } from "../../utils/export"; +import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; +import { createSafeName } from "../../utils/safe-names"; +import { peekScope } from "../../utils/scope"; +import { transformIdentifier } from "../identifier"; +import { transformPropertyName } from "../literal"; + +const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => + relativePath[0] !== "." && options.baseUrl + ? path.resolve(options.baseUrl, relativePath) + : path.resolve(directoryPath, relativePath); + +function getImportPath(fileName: string, relativePath: string, node: ts.Node, options: ts.CompilerOptions): string { + const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); + + const absoluteImportPath = path.format( + path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) + ); + const absoluteRootDirPath = path.format(path.parse(rootDir)); + if (absoluteImportPath.includes(absoluteRootDirPath)) { + return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); + } else { + throw UnresolvableRequirePath( + node, + `Cannot create require path. Module does not exist within --rootDir`, + relativePath + ); + } +} + +function shouldResolveModulePath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { + const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier); + if (!moduleOwnerSymbol) return true; + + const annotations = getSymbolAnnotations(context, moduleOwnerSymbol); + return !annotations.has(AnnotationKind.NoResolution); +} + +export function createModuleRequire( + context: TransformationContext, + moduleSpecifier: ts.Expression, + tsOriginal: ts.Node = moduleSpecifier +): lua.CallExpression { + const params: lua.Expression[] = []; + if (ts.isStringLiteral(moduleSpecifier)) { + const modulePath = shouldResolveModulePath(context, moduleSpecifier) + ? getImportPath( + context.sourceFile.fileName, + moduleSpecifier.text.replace(/"/g, ""), + moduleSpecifier, + context.options + ) + : moduleSpecifier.text; + + params.push(lua.createStringLiteral(modulePath)); + } + + return lua.createCallExpression(lua.createIdentifier("require"), params, tsOriginal); +} + +function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean { + const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(importNode)); + + return ( + context.resolver.isReferencedAliasDeclaration(importNode) && + !annotations.has(AnnotationKind.Extension) && + !annotations.has(AnnotationKind.MetaExtension) + ); +} + +function transformImportSpecifier( + context: TransformationContext, + importSpecifier: ts.ImportSpecifier, + moduleTableName: lua.Identifier +): lua.VariableDeclarationStatement { + const leftIdentifier = transformIdentifier(context, importSpecifier.name); + const propertyName = transformPropertyName( + context, + importSpecifier.propertyName ? importSpecifier.propertyName : importSpecifier.name + ); + + return lua.createVariableDeclarationStatement( + leftIdentifier, + lua.createTableIndexExpression(moduleTableName, propertyName), + importSpecifier + ); +} + +export const transformImportDeclaration: FunctionVisitor = (statement, context) => { + const scope = peekScope(context); + + if (!context.options.noHoisting && !scope.importStatements) { + scope.importStatements = []; + } + + const result: lua.Statement[] = []; + const requireCall = createModuleRequire(context, statement.moduleSpecifier); + + // import "./module"; + // require("module") + if (statement.importClause === undefined) { + result.push(lua.createExpressionStatement(requireCall)); + + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } + } + + const importPath = ts.isStringLiteral(statement.moduleSpecifier) + ? statement.moduleSpecifier.text.replace(/"/g, "") + : "module"; + + // Create the require statement to extract values. + // local ____module = require("module") + const importUniqueName = lua.createIdentifier(createSafeName(path.basename(importPath))); + + let usingRequireStatement = false; + + // import defaultValue from "./module"; + // local defaultValue = __module.default + if (statement.importClause.name) { + if (shouldBeImported(context, statement.importClause)) { + const propertyName = createDefaultExportStringLiteral(statement.importClause.name); + const defaultImportAssignmentStatement = lua.createVariableDeclarationStatement( + transformIdentifier(context, statement.importClause.name), + lua.createTableIndexExpression(importUniqueName, propertyName), + statement.importClause.name + ); + + result.push(defaultImportAssignmentStatement); + usingRequireStatement = true; + } + } + + // import * as module from "./module"; + // local module = require("module") + if (statement.importClause.namedBindings && ts.isNamespaceImport(statement.importClause.namedBindings)) { + if (context.resolver.isReferencedAliasDeclaration(statement.importClause.namedBindings)) { + const requireStatement = lua.createVariableDeclarationStatement( + transformIdentifier(context, statement.importClause.namedBindings.name), + requireCall, + statement + ); + + result.push(requireStatement); + } + } + + // import { a, b, c } from "./module"; + // local a = __module.a + // local b = __module.b + // local c = __module.c + if (statement.importClause.namedBindings && ts.isNamedImports(statement.importClause.namedBindings)) { + const assignmentStatements = statement.importClause.namedBindings.elements + .filter(importSpecifier => shouldBeImported(context, importSpecifier)) + .map(importSpecifier => transformImportSpecifier(context, importSpecifier, importUniqueName)); + + if (assignmentStatements.length > 0) { + usingRequireStatement = true; + } + + result.push(...assignmentStatements); + } + + if (result.length === 0) { + return undefined; + } + + if (usingRequireStatement) { + result.unshift(lua.createVariableDeclarationStatement(importUniqueName, requireCall, statement)); + } + + if (scope.importStatements) { + scope.importStatements.push(...result); + return undefined; + } else { + return result; + } +}; + +export const transformExternalModuleReference: FunctionVisitor = (node, context) => + createModuleRequire(context, node.expression, node); + +export const transformImportEqualsDeclaration: FunctionVisitor = (node, context) => { + if ( + !context.resolver.isReferencedAliasDeclaration(node) && + (ts.isExternalModuleReference(node.moduleReference) || + ts.isExternalModule(context.sourceFile) || + !context.resolver.isTopLevelValueImportEqualsWithEntityName(node)) + ) { + return undefined; + } + + const name = transformIdentifier(context, node.name); + const expression = context.transformExpression(node.moduleReference); + return createHoistableVariableDeclarationStatement(context, name, expression, node); +}; diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts new file mode 100644 index 000000000..5835f9112 --- /dev/null +++ b/src/transformation/visitors/namespace.ts @@ -0,0 +1,133 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; +import { + createHoistableVariableDeclarationStatement, + createLocalOrExportedOrGlobalDeclaration, +} from "../utils/lua-ast"; +import { createSafeName, isUnsafeName } from "../utils/safe-names"; +import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { getSymbolIdOfSymbol } from "../utils/symbols"; +import { transformIdentifier } from "./identifier"; + +export function createModuleLocalNameIdentifier( + context: TransformationContext, + declaration: ts.ModuleDeclaration +): lua.Identifier { + const moduleSymbol = context.checker.getSymbolAtLocation(declaration.name); + if (moduleSymbol !== undefined && isUnsafeName(moduleSymbol.name)) { + return lua.createIdentifier( + createSafeName(declaration.name.text), + declaration.name, + moduleSymbol && getSymbolIdOfSymbol(context, moduleSymbol), + declaration.name.text + ); + } + + // TODO: Should synthetic name nodes be escaped as well? + return transformIdentifier(context, declaration.name as ts.Identifier); +} + +// TODO: Do it based on transform result? +function moduleHasEmittedBody( + node: ts.ModuleDeclaration +): node is ts.ModuleDeclaration & { body: ts.ModuleBlock | ts.ModuleDeclaration } { + if (node.body) { + if (ts.isModuleBlock(node.body)) { + // Ignore if body has no emitted statements + return node.body.statements.some(s => !ts.isInterfaceDeclaration(s) && !ts.isTypeAliasDeclaration(s)); + } else if (ts.isModuleDeclaration(node.body)) { + return true; + } + } + + return false; +} + +const currentNamespaces = new WeakMap(); +export const getCurrentNamespace = (context: TransformationContext) => currentNamespaces.get(context); + +export const transformModuleDeclaration: FunctionVisitor = (node, context) => { + const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node)); + // If phantom namespace elide the declaration and return the body + if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { + return context.transformStatements(node.body.statements); + } + + const currentNamespace = currentNamespaces.get(context); + const result: lua.Statement[] = []; + + const symbol = context.checker.getSymbolAtLocation(node.name); + const hasExports = symbol !== undefined && context.checker.getExportsOfModule(symbol).length > 0; + const nameIdentifier = transformIdentifier(context, node.name as ts.Identifier); + const exportScope = getIdentifierExportScope(context, nameIdentifier); + + // Non-module namespace could be merged if: + // - is top level + // - is nested and exported + const isNonModuleMergeable = !context.isModule && (!currentNamespace || exportScope); + + // This is NOT the first declaration if: + // - declared as a module before this (ignore interfaces with same name) + // - declared as a class or function at all (TS requires these to be before module, unless module is empty) + const isFirstDeclaration = + symbol === undefined || + (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && + node === symbol.declarations.find(ts.isModuleDeclaration)); + + if (isNonModuleMergeable) { + // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' + const localDeclaration = createLocalOrExportedOrGlobalDeclaration( + context, + nameIdentifier, + lua.createBinaryExpression( + addExportToIdentifier(context, nameIdentifier), + lua.createTableExpression(), + lua.SyntaxKind.OrOperator + ) + ); + + result.push(...localDeclaration); + } else if (isFirstDeclaration) { + // local NS = {} or exportTable.NS = {} + const localDeclaration = createLocalOrExportedOrGlobalDeclaration( + context, + nameIdentifier, + lua.createTableExpression() + ); + + result.push(...localDeclaration); + } + + if ((isNonModuleMergeable || isFirstDeclaration) && exportScope && hasExports && moduleHasEmittedBody(node)) { + // local NS = exportTable.NS + const localDeclaration = createHoistableVariableDeclarationStatement( + context, + createModuleLocalNameIdentifier(context, node), + createExportedIdentifier(context, nameIdentifier, exportScope) + ); + + result.push(localDeclaration); + } + + // Set current namespace for nested NS + // Keep previous namespace to reset after block transpilation + currentNamespaces.set(context, node); + + // Transform moduleblock to block and visit it + if (moduleHasEmittedBody(node)) { + pushScope(context, ScopeType.Block); + const statements = performHoisting( + context, + context.transformStatements(ts.isModuleBlock(node.body) ? node.body.statements : node.body) + ); + popScope(context); + result.push(lua.createDoStatement(statements)); + } + + currentNamespaces.set(context, currentNamespace); + + return result; +}; diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts new file mode 100644 index 000000000..970db6be0 --- /dev/null +++ b/src/transformation/visitors/return.ts @@ -0,0 +1,63 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { validateAssignment } from "../utils/assignment-validation"; +import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { ScopeType, walkScopesUp } from "../utils/scope"; +import { isArrayType } from "../utils/typescript"; + +export const transformReturnStatement: FunctionVisitor = (statement, context) => { + // Bubble up explicit return flag and check if we're inside a try/catch block + let insideTryCatch = false; + for (const scope of walkScopesUp(context)) { + scope.functionReturned = true; + + if (scope.type === ScopeType.Function) { + break; + } + + insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; + } + + let results: lua.Expression[]; + + if (statement.expression) { + const expressionType = context.checker.getTypeAtLocation(statement.expression); + const returnType = context.checker.getContextualType(statement.expression); + if (returnType) { + validateAssignment(context, statement, expressionType, returnType); + } + + if (isInTupleReturnFunction(context, statement)) { + // Parent function is a TupleReturn function + if (ts.isArrayLiteralExpression(statement.expression)) { + // If return expression is an array literal, leave out brackets. + results = statement.expression.elements.map(e => context.transformExpression(e)); + } else if (!isTupleReturnCall(context, statement.expression) && isArrayType(context, expressionType)) { + // If return expression is an array-type and not another TupleReturn call, unpack it + results = [ + createUnpackCall(context, context.transformExpression(statement.expression), statement.expression), + ]; + } else { + results = [context.transformExpression(statement.expression)]; + } + + // Wrap tupleReturn results when returning inside try/catch + if (insideTryCatch) { + results = [wrapInTable(...results)]; + } + } else { + results = [context.transformExpression(statement.expression)]; + } + } else { + // Empty return + results = []; + } + + if (insideTryCatch) { + results.unshift(lua.createBooleanLiteral(true)); + } + + return lua.createReturnStatement(results, statement); +}; diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts new file mode 100644 index 000000000..064b5200f --- /dev/null +++ b/src/transformation/visitors/sourceFile.ts @@ -0,0 +1,38 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { InvalidJsonFileContent } from "../utils/errors"; +import { createExportsIdentifier } from "../utils/lua-ast"; +import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { hasExportEquals } from "../utils/typescript"; + +export const transformSourceFileNode: FunctionVisitor = (node, context) => { + let statements: lua.Statement[] = []; + if (node.flags & ts.NodeFlags.JsonFile) { + const [statement] = node.statements; + if (!statement || !ts.isExpressionStatement(statement)) { + throw InvalidJsonFileContent(node); + } + + statements.push(lua.createReturnStatement([context.transformExpression(statement.expression)])); + } else { + pushScope(context, ScopeType.File); + statements = performHoisting(context, context.transformStatements(node.statements)); + popScope(context); + + if (context.isModule) { + // If export equals was not used. Create the exports table. + // local ____exports = {} + if (!hasExportEquals(node)) { + statements.unshift( + lua.createVariableDeclarationStatement(createExportsIdentifier(), lua.createTableExpression()) + ); + } + + // return ____exports + statements.push(lua.createReturnStatement([createExportsIdentifier()])); + } + } + + return lua.createBlock(statements, node); +}; diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts new file mode 100644 index 000000000..0c6ece043 --- /dev/null +++ b/src/transformation/visitors/switch.ts @@ -0,0 +1,61 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { UnsupportedForTarget } from "../utils/errors"; +import { peekScope, performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; + +export const transformSwitchStatement: FunctionVisitor = (statement, context) => { + if (context.luaTarget === LuaTarget.Lua51) { + throw UnsupportedForTarget("Switch statements", LuaTarget.Lua51, statement); + } + + pushScope(context, ScopeType.Switch); + + // Give the switch a unique name to prevent nested switches from acting up. + const scope = peekScope(context); + const switchName = `____switch${scope.id}`; + + const expression = context.transformExpression(statement.expression); + const switchVariable = lua.createIdentifier(switchName); + const switchVariableDeclaration = lua.createVariableDeclarationStatement(switchVariable, expression); + + let statements: lua.Statement[] = [switchVariableDeclaration]; + + const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); + for (const [index, clause] of caseClauses.entries()) { + // If the clause condition holds, go to the correct label + const condition = lua.createBinaryExpression( + switchVariable, + context.transformExpression(clause.expression), + lua.SyntaxKind.EqualityOperator + ); + + const goto = lua.createGotoStatement(`${switchName}_case_${index}`); + const conditionalGoto = lua.createIfStatement(condition, lua.createBlock([goto])); + statements.push(conditionalGoto); + } + + const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause); + if (hasDefaultCase) { + statements.push(lua.createGotoStatement(`${switchName}_case_default`)); + } else { + statements.push(lua.createGotoStatement(`${switchName}_end`)); + } + + for (const [index, clause] of statement.caseBlock.clauses.entries()) { + const label = ts.isCaseClause(clause) + ? lua.createLabelStatement(`${switchName}_case_${index}`) + : lua.createLabelStatement(`${switchName}_case_default`); + + const body = lua.createDoStatement(context.transformStatements(clause.statements)); + statements.push(label, body); + } + + statements.push(lua.createLabelStatement(`${switchName}_end`)); + + statements = performHoisting(context, statements); + popScope(context); + + return statements; +}; diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts new file mode 100644 index 000000000..e47c3906b --- /dev/null +++ b/src/transformation/visitors/template.ts @@ -0,0 +1,87 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor } from "../context"; +import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { wrapInToStringForConcat } from "../utils/lua-ast"; +import { transformArguments, transformContextualCallExpression } from "./call"; + +// TODO: Source positions +function getRawLiteral(node: ts.LiteralLikeNode): string { + let text = node.getText(); + const isLast = + node.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === ts.SyntaxKind.TemplateTail; + text = text.substring(1, text.length - (isLast ? 1 : 2)); + text = text.replace(/\r\n?/g, "\n"); + return text; +} + +export const transformTemplateExpression: FunctionVisitor = (node, context) => { + const parts: lua.Expression[] = []; + + const head = node.head.text; + if (head.length > 0) { + parts.push(lua.createStringLiteral(head, node.head)); + } + + for (const span of node.templateSpans) { + const expression = context.transformExpression(span.expression); + parts.push(wrapInToStringForConcat(expression)); + + const text = span.literal.text; + if (text.length > 0) { + parts.push(lua.createStringLiteral(text, span.literal)); + } + } + + return parts.reduce((prev, current) => lua.createBinaryExpression(prev, current, lua.SyntaxKind.ConcatOperator)); +}; + +export const transformTaggedTemplateExpression: FunctionVisitor = ( + expression, + context +) => { + const strings: string[] = []; + const rawStrings: string[] = []; + const expressions: ts.Expression[] = []; + + if (ts.isTemplateExpression(expression.template)) { + // Expressions are in the string. + strings.push(expression.template.head.text); + rawStrings.push(getRawLiteral(expression.template.head)); + strings.push(...expression.template.templateSpans.map(span => span.literal.text)); + rawStrings.push(...expression.template.templateSpans.map(span => getRawLiteral(span.literal))); + expressions.push(...expression.template.templateSpans.map(span => span.expression)); + } else { + // No expressions are in the string. + strings.push(expression.template.text); + rawStrings.push(getRawLiteral(expression.template)); + } + + // Construct table with strings and literal strings + + const rawStringsTable = lua.createTableExpression( + rawStrings.map(text => lua.createTableFieldExpression(lua.createStringLiteral(text))) + ); + + const stringTableLiteral = lua.createTableExpression([ + ...strings.map(partialString => lua.createTableFieldExpression(lua.createStringLiteral(partialString))), + lua.createTableFieldExpression(rawStringsTable, lua.createStringLiteral("raw")), + ]); + + // Evaluate if there is a self parameter to be used. + const signature = context.checker.getResolvedSignature(expression); + const signatureDeclaration = signature && signature.getDeclaration(); + const useSelfParameter = + signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; + + // Argument evaluation. + const callArguments = transformArguments(context, expressions, signature); + callArguments.unshift(stringTableLiteral); + + if (useSelfParameter) { + return transformContextualCallExpression(context, expression, callArguments); + } + + const leftHandSideExpression = context.transformExpression(expression.tag); + return lua.createCallExpression(leftHandSideExpression, callArguments); +}; diff --git a/src/transformation/visitors/typeof.ts b/src/transformation/visitors/typeof.ts new file mode 100644 index 000000000..585746ca4 --- /dev/null +++ b/src/transformation/visitors/typeof.ts @@ -0,0 +1,51 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { LuaLibFeature } from "../../LuaLib"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { transformLuaLibFunction } from "../utils/lualib"; +import { transformBinaryOperation } from "./binary-expression"; + +export const transformTypeOfExpression: FunctionVisitor = (node, context) => { + const innerExpression = context.transformExpression(node.expression); + return transformLuaLibFunction(context, LuaLibFeature.TypeOf, node, innerExpression); +}; + +export function transformTypeOfBinaryExpression( + context: TransformationContext, + node: ts.BinaryExpression +): lua.Expression | undefined { + const operator = node.operatorToken.kind; + function transformTypeOfLiteralComparison( + typeOfExpression: ts.TypeOfExpression, + comparedExpression: lua.StringLiteral + ): lua.Expression { + if (comparedExpression.value === "object") { + comparedExpression.value = "table"; + } else if (comparedExpression.value === "undefined") { + comparedExpression.value = "nil"; + } + + const innerExpression = context.transformExpression(typeOfExpression.expression); + const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression); + return transformBinaryOperation(context, typeCall, comparedExpression, operator, node); + } + + if ( + operator === ts.SyntaxKind.EqualsEqualsToken || + operator === ts.SyntaxKind.EqualsEqualsEqualsToken || + operator === ts.SyntaxKind.ExclamationEqualsToken || + operator === ts.SyntaxKind.ExclamationEqualsEqualsToken + ) { + if (ts.isTypeOfExpression(node.left)) { + const right = context.transformExpression(node.right); + if (lua.isStringLiteral(right)) { + return transformTypeOfLiteralComparison(node.left, right); + } + } else if (ts.isTypeOfExpression(node.right)) { + const left = context.transformExpression(node.left); + if (lua.isStringLiteral(left)) { + return transformTypeOfLiteralComparison(node.right, left); + } + } + } +} diff --git a/src/transformation/visitors/typescript.ts b/src/transformation/visitors/typescript.ts new file mode 100644 index 000000000..4ff855f2e --- /dev/null +++ b/src/transformation/visitors/typescript.ts @@ -0,0 +1,25 @@ +import * as ts from "typescript"; +import { FunctionVisitor, Visitors } from "../context"; +import { validateAssignment } from "../utils/assignment-validation"; + +const transformAssertionExpression: FunctionVisitor = (expression, context) => { + if (!ts.isConstTypeReference(expression.type)) { + validateAssignment( + context, + expression, + context.checker.getTypeAtLocation(expression.expression), + context.checker.getTypeAtLocation(expression.type) + ); + } + + return context.transformExpression(expression.expression); +}; + +export const typescriptVisitors: Visitors = { + [ts.SyntaxKind.TypeAliasDeclaration]: () => undefined, + [ts.SyntaxKind.InterfaceDeclaration]: () => undefined, + + [ts.SyntaxKind.NonNullExpression]: (node, context) => context.transformExpression(node.expression), + [ts.SyntaxKind.AsExpression]: transformAssertionExpression, + [ts.SyntaxKind.TypeAssertionExpression]: transformAssertionExpression, +}; diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts new file mode 100644 index 000000000..e4c8dfad2 --- /dev/null +++ b/src/transformation/visitors/unary-expression.ts @@ -0,0 +1,122 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { UnsupportedKind } from "../utils/errors"; +import { transformUnaryBitOperation } from "./binary-expression/bit"; +import { + transformCompoundAssignmentExpression, + transformCompoundAssignmentStatement, +} from "./binary-expression/compound"; + +export function transformUnaryExpressionStatement( + context: TransformationContext, + node: ts.ExpressionStatement +): lua.Statement | undefined { + const expression = ts.isExpressionStatement(node) ? node.expression : node; + if ( + ts.isPrefixUnaryExpression(expression) && + (expression.operator === ts.SyntaxKind.PlusPlusToken || expression.operator === ts.SyntaxKind.MinusMinusToken) + ) { + // ++i, --i + const replacementOperator = + expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken; + + return transformCompoundAssignmentStatement( + context, + expression, + expression.operand, + ts.createLiteral(1), + replacementOperator + ); + } else if (ts.isPostfixUnaryExpression(expression)) { + // i++, i-- + const replacementOperator = + expression.operator === ts.SyntaxKind.PlusPlusToken ? ts.SyntaxKind.PlusToken : ts.SyntaxKind.MinusToken; + + return transformCompoundAssignmentStatement( + context, + expression, + expression.operand, + ts.createLiteral(1), + replacementOperator + ); + } +} + +export const transformPostfixUnaryExpression: FunctionVisitor = (expression, context) => { + switch (expression.operator) { + case ts.SyntaxKind.PlusPlusToken: + return transformCompoundAssignmentExpression( + context, + expression, + expression.operand, + ts.createLiteral(1), + ts.SyntaxKind.PlusToken, + true + ); + + case ts.SyntaxKind.MinusMinusToken: + return transformCompoundAssignmentExpression( + context, + expression, + expression.operand, + ts.createLiteral(1), + ts.SyntaxKind.MinusToken, + true + ); + + default: + throw UnsupportedKind("unary postfix operator", expression.operator, expression); + } +}; + +export const transformPrefixUnaryExpression: FunctionVisitor = (expression, context) => { + switch (expression.operator) { + case ts.SyntaxKind.PlusPlusToken: + return transformCompoundAssignmentExpression( + context, + expression, + expression.operand, + ts.createLiteral(1), + ts.SyntaxKind.PlusToken, + false + ); + + case ts.SyntaxKind.MinusMinusToken: + return transformCompoundAssignmentExpression( + context, + expression, + expression.operand, + ts.createLiteral(1), + ts.SyntaxKind.MinusToken, + false + ); + + case ts.SyntaxKind.PlusToken: + // TODO: Wrap with `Number` + return context.transformExpression(expression.operand); + + case ts.SyntaxKind.MinusToken: + return lua.createUnaryExpression( + context.transformExpression(expression.operand), + lua.SyntaxKind.NegationOperator + ); + + case ts.SyntaxKind.ExclamationToken: + return lua.createUnaryExpression( + context.transformExpression(expression.operand), + lua.SyntaxKind.NotOperator + ); + + case ts.SyntaxKind.TildeToken: + return transformUnaryBitOperation( + context, + expression, + context.transformExpression(expression.operand), + lua.SyntaxKind.BitwiseNotOperator + ); + + default: + throw UnsupportedKind("unary prefix operator", expression.operator, expression); + } +}; diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts new file mode 100644 index 000000000..9175ba7c5 --- /dev/null +++ b/src/transformation/visitors/variable-declaration.ts @@ -0,0 +1,226 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { assertNever, flatMap } from "../../utils"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { isTupleReturnCall } from "../utils/annotations"; +import { validateAssignment } from "../utils/assignment-validation"; +import { UnsupportedKind } from "../utils/errors"; +import { addExportToIdentifier } from "../utils/export"; +import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { transformIdentifier } from "./identifier"; +import { transformPropertyName } from "./literal"; + +export function transformArrayBindingElement( + context: TransformationContext, + name: ts.ArrayBindingElement | ts.Expression +): lua.Identifier { + if (ts.isOmittedExpression(name)) { + return lua.createAnonymousIdentifier(name); + } else if (ts.isIdentifier(name)) { + return transformIdentifier(context, name); + } else if (ts.isBindingElement(name) && ts.isIdentifier(name.name)) { + return transformIdentifier(context, name.name); + } else { + throw UnsupportedKind("array binding expression", name.kind, name); + } +} + +export function transformBindingPattern( + context: TransformationContext, + pattern: ts.BindingPattern, + table: lua.Identifier, + propertyAccessStack: ts.PropertyName[] = [] +): lua.Statement[] { + const result: lua.Statement[] = []; + const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); + + for (const [index, element] of pattern.elements.entries()) { + if (ts.isOmittedExpression(element)) continue; + + if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { + // nested binding pattern + const propertyName = isObjectBindingPattern + ? element.propertyName + : ts.createNumericLiteral(String(index + 1)); + + if (propertyName !== undefined) { + propertyAccessStack.push(propertyName); + } + + result.push(...transformBindingPattern(context, element.name, table, propertyAccessStack)); + continue; + } + + // Build the path to the table + const tableExpression = propertyAccessStack.reduce( + (path, property) => lua.createTableIndexExpression(path, transformPropertyName(context, property)), + table + ); + + // The identifier of the new variable + const variableName = transformIdentifier(context, element.name as ts.Identifier); + // The field to extract + const propertyName = transformPropertyName(context, element.propertyName || element.name); + + let expression: lua.Expression; + if (element.dotDotDotToken) { + if (index !== pattern.elements.length - 1) continue; + + if (isObjectBindingPattern) { + const elements = pattern.elements as ts.NodeArray; + const usedProperties = elements.map(e => + lua.createTableFieldExpression( + lua.createBooleanLiteral(true), + lua.createStringLiteral( + ((e.propertyName || e.name) as ts.Identifier).text, + e.propertyName || e.name + ) + ) + ); + + expression = transformLuaLibFunction( + context, + LuaLibFeature.ObjectRest, + undefined, + tableExpression, + lua.createTableExpression(usedProperties) + ); + } else { + expression = transformLuaLibFunction( + context, + LuaLibFeature.ArraySlice, + undefined, + tableExpression, + lua.createNumericLiteral(index) + ); + } + } else { + expression = lua.createTableIndexExpression( + tableExpression, + isObjectBindingPattern ? propertyName : lua.createNumericLiteral(index + 1) + ); + } + + result.push(...createLocalOrExportedOrGlobalDeclaration(context, variableName, expression)); + if (element.initializer) { + const identifier = addExportToIdentifier(context, variableName); + result.push( + lua.createIfStatement( + lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), + lua.createBlock([ + lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)), + ]) + ) + ); + } + } + + propertyAccessStack.pop(); + return result; +} + +// TODO: FunctionVisitor +export function transformVariableDeclaration( + context: TransformationContext, + statement: ts.VariableDeclaration +): lua.Statement[] { + if (statement.initializer && statement.type) { + const initializerType = context.checker.getTypeAtLocation(statement.initializer); + const varType = context.checker.getTypeFromTypeNode(statement.type); + validateAssignment(context, statement.initializer, initializerType, varType); + } + + if (ts.isIdentifier(statement.name)) { + // Find variable identifier + const identifierName = transformIdentifier(context, statement.name); + const value = statement.initializer && context.transformExpression(statement.initializer); + return createLocalOrExportedOrGlobalDeclaration(context, identifierName, value, statement); + } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { + const statements: lua.Statement[] = []; + + // For object, nested or rest bindings fall back to transformBindingPattern + if ( + ts.isObjectBindingPattern(statement.name) || + statement.name.elements.some(e => ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken)) + ) { + let table: lua.Identifier; + if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { + table = transformIdentifier(context, statement.initializer); + } else { + // Contain the expression in a temporary variable + table = lua.createAnonymousIdentifier(); + if (statement.initializer) { + statements.push( + lua.createVariableDeclarationStatement( + table, + context.transformExpression(statement.initializer) + ) + ); + } + } + statements.push(...transformBindingPattern(context, statement.name, table)); + return statements; + } + + const vars = + statement.name.elements.length > 0 + ? statement.name.elements.map(e => transformArrayBindingElement(context, e)) + : lua.createAnonymousIdentifier(statement.name); + + if (statement.initializer) { + if (isTupleReturnCall(context, statement.initializer)) { + // Don't unpack @tupleReturn annotated functions + statements.push( + ...createLocalOrExportedOrGlobalDeclaration( + context, + vars, + context.transformExpression(statement.initializer), + statement + ) + ); + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Don't unpack array literals + const values = + statement.initializer.elements.length > 0 + ? statement.initializer.elements.map(e => context.transformExpression(e)) + : lua.createNilLiteral(); + statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, values, statement)); + } else { + // local vars = this.transpileDestructingAssignmentValue(node.initializer); + const initializer = createUnpackCall( + context, + context.transformExpression(statement.initializer), + statement.initializer + ); + statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, initializer, statement)); + } + } else { + statements.push( + ...createLocalOrExportedOrGlobalDeclaration(context, vars, lua.createNilLiteral(), statement) + ); + } + + for (const element of statement.name.elements) { + if (!ts.isOmittedExpression(element) && element.initializer) { + const variableName = transformIdentifier(context, element.name as ts.Identifier); + const identifier = addExportToIdentifier(context, variableName); + statements.push( + lua.createIfStatement( + lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), + lua.createBlock([ + lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)), + ]) + ) + ); + } + } + + return statements; + } else { + return assertNever(statement.name); + } +} + +export const transformVariableStatement: FunctionVisitor = (node, context) => + flatMap(node.declarationList.declarations, declaration => transformVariableDeclaration(context, declaration)); diff --git a/src/utils.ts b/src/utils.ts index 16997a549..8bf18a21a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,7 +1,6 @@ import * as path from "path"; export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); - export const trimExtension = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); export function formatPathToLuaPath(filePath: string): string { @@ -27,3 +26,47 @@ export function flatMap(array: readonly T[], callback: (value: T, index: n return result; } + +type NoInfer = [T][T extends any ? 0 : never]; + +export function getOrUpdate( + map: Map | (K extends object ? WeakMap : never), + key: K, + getDefaultValue: () => NoInfer +): V { + if (!map.has(key)) { + map.set(key, getDefaultValue()); + } + + return map.get(key)!; +} + +export function isNonNull(value: T | undefined | null): value is T { + return value !== undefined && value !== null; +} + +export function cast( + item: TOriginal, + cast: (item: TOriginal) => item is TCast +): TCast { + if (cast(item)) { + return item; + } else { + throw new Error(`Failed to cast value to expected type using ${cast.name}.`); + } +} + +export function castEach( + items: TOriginal[], + cast: (item: TOriginal) => item is TCast +): TCast[] { + if (items.every(cast)) { + return items as TCast[]; + } else { + throw new Error(`Failed to cast all elements to expected type using ${cast.name}.`); + } +} + +export function assertNever(_value: never): never { + throw new Error("Value is expected to be never"); +} diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index 4b9815d17..8715fbe62 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -3,7 +3,7 @@ import * as fs from "fs"; import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../src"; -import * as tsHelper from "../src/TSHelper"; +import { formatPathToLuaPath } from "../src/utils"; export function transpileString( str: string | { [filename: string]: string }, @@ -104,6 +104,14 @@ export function transpileAndExecute( return executeLua(lua); } +function getExportPath(fileName: string, options: ts.CompilerOptions): string { + const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); + + const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); + const absoluteRootDirPath = path.format(path.parse(rootDir)); + return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); +} + export function transpileAndExecuteProjectReturningMainExport( typeScriptFiles: Record, exportName: string, @@ -117,7 +125,7 @@ export function transpileAndExecuteProjectReturningMainExport( const joinedTranspiledFiles = Object.keys(typeScriptFiles) .filter(typeScriptFileName => typeScriptFileName !== "main.ts") .map(typeScriptFileName => { - const modulePath = tsHelper.getExportPath(typeScriptFileName, options); + const modulePath = getExportPath(typeScriptFileName, options); const tsCode = typeScriptFiles[typeScriptFileName]; const luaCode = transpileString(tsCode, options); return `package.preload["${modulePath}"] = function() diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 044e1bf82..45f7a2d4a 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,17 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Transformation (characterEscapeSequence) 1`] = ` -"local quoteInDoubleQuotes = \\"\\\\' \\\\' \\\\'\\" -local quoteInTemplateString = \\"\\\\' \\\\' \\\\'\\" +"local quoteInDoubleQuotes = \\"' ' '\\" +local quoteInTemplateString = \\"' ' '\\" local doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" local doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" local doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" local backQuoteInQuotes = \\"\` \` \`\\" local backQuoteInDoubleQuotes = \\"\` \` \`\\" local backQuoteInTemplateString = \\"\` \` \`\\" -local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\" -local escapedCharsInDoubleQUotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\'\\" -local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" \\\\' \`\\" +local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" +local escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" +local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\"" `; diff --git a/test/translation/transformation/characterEscapeSequence.ts b/test/translation/transformation/characterEscapeSequence.ts index 8a7fec33e..eebf8f293 100644 --- a/test/translation/transformation/characterEscapeSequence.ts +++ b/test/translation/transformation/characterEscapeSequence.ts @@ -10,7 +10,7 @@ let backQuoteInDoubleQuotes = "` ` `"; let backQuoteInTemplateString = `\` \` \``; let escapedCharsInQuotes = '\\ \0 \b \t \n \v \f \" \' \`'; -let escapedCharsInDoubleQUotes = "\\ \0 \b \t \n \v \f \" \'"; +let escapedCharsInDoubleQuotes = "\\ \0 \b \t \n \v \f \" \' \`"; let escapedCharsInTemplateString = `\\ \0 \b \t \n \v \f \" \' \``; let nonEmptyTemplateString = `Level 0: \n\t ${`Level 1: \n\t\t ${`Level 3: \n\t\t\t ${"Last level \n --"} \n --`} \n --`} \n --`; diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index d08f846e9..d43797e43 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -1,5 +1,5 @@ import * as tstl from "../../../src"; -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { UnsupportedProperty } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; describe("luaLibImport", () => { @@ -42,12 +42,12 @@ describe("Unknown builtin property", () => { test("access", () => { util.testExpression`Math.unknownProperty` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("Math", "unknownProperty", util.nodeStub)); + .expectToHaveDiagnosticOfError(UnsupportedProperty("Math", "unknownProperty", util.nodeStub)); }); test("function call", () => { util.testExpression`[].unknownFunction()` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("array", "unknownFunction", util.nodeStub)); + .expectToHaveDiagnosticOfError(UnsupportedProperty("array", "unknownFunction", util.nodeStub)); }); }); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 9e6f73e28..7f92a2805 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -1,10 +1,10 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { UnsupportedProperty } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("Unsupported string function", () => { util.testExpression`"test".testThisIsNoMember()` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); + .expectToHaveDiagnosticOfError(UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); }); test("Supported lua string function", () => { diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 343ad75ad..cfb1451aa 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { ForbiddenStaticClassPropertyName } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("ClassFieldInitializer", () => { @@ -537,14 +537,6 @@ test("methodDefaultParameters", () => { expect(result).toBe(9); }); -test("Class without name error", () => { - const transformer = util.makeTestTransformer(); - - expect(() => transformer.transformClassDeclaration({} as ts.ClassDeclaration)).toThrowExactError( - TSTLErrors.MissingClassName(util.nodeStub) - ); -}); - test("CallSuperMethodNoArgs", () => { const result = util.transpileAndExecute( `class a { @@ -846,7 +838,7 @@ test("Class cannot have static new method", () => { static new() {} }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message + ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -856,7 +848,7 @@ test("Class cannot have static new property", () => { static new = "foobar"; }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message + ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -866,7 +858,7 @@ test("Class cannot have static new get accessor", () => { static get new() { return "foobar" } }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message + ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); @@ -876,6 +868,6 @@ test("Class cannot have static new set accessor", () => { static set new(value: string) {} }`; expect(() => util.transpileAndExecute(code)).toThrow( - TSTLErrors.ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message + ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message ); }); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index e5c44e51d..7d4223ecd 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -1,4 +1,4 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { InvalidDecoratorContext } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("Class decorator with no parameters", () => { @@ -109,7 +109,7 @@ test("Throws error if decorator function has void context", () => { @SetBool class TestClass {} - `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidDecoratorContext(util.nodeStub)); + `.expectToHaveDiagnosticOfError(InvalidDecoratorContext(util.nodeStub)); }); test("Exported class decorator", () => { diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index a359535bb..d33d39fdd 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,5 @@ import * as tstl from "../../src"; -import * as TSTLErrors from "../../src/TSTLErrors"; +import { UnsupportedForTarget } from "../../src/transformation/utils/errors"; import * as util from "../util"; test.each([0, 1])("if (%p)", inp => { @@ -278,9 +278,7 @@ test("switch not allowed in 5.1", () => { switch ("abc") {} ` .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectToHaveDiagnosticOfError( - TSTLErrors.UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub) - ); + .expectToHaveDiagnosticOfError(UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub)); }); test.each([ diff --git a/test/unit/decorators/customConstructor.spec.ts b/test/unit/decorators/customConstructor.spec.ts index 48c473943..856a566f0 100644 --- a/test/unit/decorators/customConstructor.spec.ts +++ b/test/unit/decorators/customConstructor.spec.ts @@ -1,4 +1,4 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { InvalidAnnotationArgumentNumber } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("CustomCreate", () => { @@ -36,5 +36,5 @@ test("IncorrectUsage", () => { } return new Point2D(1, 2).x; `); - }).toThrowExactError(TSTLErrors.InvalidDecoratorArgumentNumber("@customConstructor", 0, 1, util.nodeStub)); + }).toThrowExactError(InvalidAnnotationArgumentNumber("@customConstructor", 0, 1, util.nodeStub)); }); diff --git a/test/unit/decorators/extension.spec.ts b/test/unit/decorators/extension.spec.ts index e7717792e..18e41719c 100644 --- a/test/unit/decorators/extension.spec.ts +++ b/test/unit/decorators/extension.spec.ts @@ -1,4 +1,8 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { + InvalidExtendsExtension, + InvalidInstanceOfExtension, + InvalidNewExpressionOnExtension, +} from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { @@ -8,7 +12,7 @@ test.each(["extension", "metaExtension"])("Class extends extension (%p)", extens class B extends A {} class C extends B {} `; - expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.InvalidExtendsExtension(util.nodeStub)); + expect(() => util.transpileString(code)).toThrowExactError(InvalidExtendsExtension(util.nodeStub)); }); test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { @@ -18,9 +22,7 @@ test.each(["extension", "metaExtension"])("Class construct extension (%p)", exte class B extends A {} const b = new B(); `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub) - ); + expect(() => util.transpileString(code)).toThrowExactError(InvalidNewExpressionOnExtension(util.nodeStub)); }); test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { @@ -30,5 +32,5 @@ test.each(["extension", "metaExtension"])("instanceof extension (%p)", extension class B extends A {} declare const foo: any; const result = foo instanceof B; - `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidInstanceOfExtension(util.nodeStub)); + `.expectToHaveDiagnosticOfError(InvalidInstanceOfExtension(util.nodeStub)); }); diff --git a/test/unit/decorators/forRange.spec.ts b/test/unit/decorators/forRange.spec.ts index 11f8aec85..ee5cb74d0 100644 --- a/test/unit/decorators/forRange.spec.ts +++ b/test/unit/decorators/forRange.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { InvalidForRangeCall } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test.each([ @@ -26,7 +26,7 @@ test("invalid non-ambient @forRange function", () => { for (const i of luaRange(1, 10, 2)) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( + InvalidForRangeCall( ts.createEmptyStatement(), "@forRange function can only be used as an iterable in a for...of loop." ).message @@ -39,8 +39,7 @@ test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => { for (const i of luaRange(${args})) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.") - .message + InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.").message ); }); @@ -51,10 +50,7 @@ test("invalid @forRange control variable", () => { for (i of luaRange(1, 10, 2)) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange loop must declare its own control variable." - ).message + InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop must declare its own control variable.").message ); }); @@ -64,7 +60,7 @@ test("invalid @forRange argument type", () => { for (const i of luaRange("foo", 2)) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message + InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message ); }); @@ -74,7 +70,7 @@ test("invalid @forRange destructuring", () => { for (const [i] of luaRange(1, 10, 2)) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message + InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message ); }); @@ -84,7 +80,7 @@ test("invalid @forRange return type", () => { for (const i of luaRange(1, 10)) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( + InvalidForRangeCall( ts.createEmptyStatement(), "@forRange function must return Iterable or Array." ).message @@ -104,7 +100,7 @@ test.each([ ${statement}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.InvalidForRangeCall( + InvalidForRangeCall( ts.createEmptyStatement(), "@forRange function can only be used as an iterable in a for...of loop." ).message diff --git a/test/unit/decorators/luaIterator.spec.ts b/test/unit/decorators/luaIterator.spec.ts index 6f25320d7..122c6e7fb 100644 --- a/test/unit/decorators/luaIterator.spec.ts +++ b/test/unit/decorators/luaIterator.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../../src"; -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { UnsupportedNonDestructuringLuaIterator } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("forof lua iterator", () => { @@ -188,7 +188,7 @@ test("forof lua iterator tuple-return single variable", () => { target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) + UnsupportedNonDestructuringLuaIterator(util.nodeStub) ); }); @@ -209,7 +209,7 @@ test("forof lua iterator tuple-return single existing variable", () => { target: ts.ScriptTarget.ES2015, }; expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - TSTLErrors.UnsupportedNonDestructuringLuaIterator(util.nodeStub) + UnsupportedNonDestructuringLuaIterator(util.nodeStub) ); }); diff --git a/test/unit/decorators/luaTable.spec.ts b/test/unit/decorators/luaTable.spec.ts index e7559f7c0..95813e5ce 100644 --- a/test/unit/decorators/luaTable.spec.ts +++ b/test/unit/decorators/luaTable.spec.ts @@ -1,5 +1,12 @@ import * as ts from "typescript"; -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { + ForbiddenLuaTableNonDeclaration, + ForbiddenLuaTableUseException, + InvalidExtendsLuaTable, + InvalidInstanceOfLuaTable, + UnsupportedKind, + UnsupportedProperty, +} from "../../../src/transformation/utils/errors"; import * as util from "../../util"; const tableLibClass = ` @@ -28,10 +35,7 @@ declare let tbl: Table; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { expect(() => util.transpileString(tableLib + `const table = new Table(true);`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException( - "No parameters are allowed when constructing a LuaTable object.", - util.nodeStub - ) + ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", util.nodeStub) ); }); @@ -39,20 +43,20 @@ test.each([tableLibClass, tableLibInterface])( "LuaTable set() cannot be used in a LuaTable call expression", tableLib => { expect(() => util.transpileString(tableLib + `const exp = tbl.set("value", 5)`)).toThrowExactError( - TSTLErrors.UnsupportedProperty("LuaTable", "set", util.nodeStub) + UnsupportedProperty("LuaTable", "set", util.nodeStub) ); } ); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { expect(() => util.transpileString(tableLib + `tbl.other()`)).toThrowExactError( - TSTLErrors.UnsupportedProperty("LuaTable", "other", util.nodeStub) + UnsupportedProperty("LuaTable", "other", util.nodeStub) ); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { expect(() => util.transpileString(tableLib + `let x = tbl.other()`)).toThrowExactError( - TSTLErrors.UnsupportedProperty("LuaTable", "other", util.nodeStub) + UnsupportedProperty("LuaTable", "other", util.nodeStub) ); }); @@ -69,7 +73,7 @@ test.each([tableLibClass])("LuaTable length", tableLib => { test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { expect(() => util.transpileString(tableLib + `tbl.length = 2;`)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException("A LuaTable object's length cannot be re-assigned.", util.nodeStub) + ForbiddenLuaTableUseException("A LuaTable object's length cannot be re-assigned.", util.nodeStub) ); }); @@ -83,7 +87,7 @@ test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib [`tbl.set("field", ...[0, 1])`, "Arguments cannot be spread."], ])("Forbidden LuaTable use (%p)", (invalidCode, errorDescription) => { expect(() => util.transpileString(tableLib + invalidCode)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableUseException(errorDescription, util.nodeStub) + ForbiddenLuaTableUseException(errorDescription, util.nodeStub) ); }); }); @@ -93,7 +97,7 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { "Cannot extend LuaTable class (%p)", code => { expect(() => util.transpileString(tableLib + code)).toThrowExactError( - TSTLErrors.InvalidExtendsLuaTable(util.nodeStub) + InvalidExtendsLuaTable(util.nodeStub) ); } ); @@ -104,16 +108,12 @@ test.each([ `/** @luaTable */ export class Table {}`, `/** @luaTable */ const c = class Table {}`, ])("LuaTable classes must be ambient (%p)", code => { - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.ForbiddenLuaTableNonDeclaration(util.nodeStub) - ); + expect(() => util.transpileString(code)).toThrowExactError(ForbiddenLuaTableNonDeclaration(util.nodeStub)); }); test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each([`tbl instanceof Table`])("Cannot use instanceof on a LuaTable class (%p)", code => { - expect(() => util.transpileString(tableLib + code)).toThrowExactError( - TSTLErrors.InvalidInstanceOfLuaTable(util.nodeStub) - ); + expect(() => util.transpileString(tableLib + code)).toThrowExactError(InvalidInstanceOfLuaTable(util.nodeStub)); }); }); @@ -122,11 +122,7 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio "Cannot use ElementAccessExpression on a LuaTable (%p)", code => { expect(() => util.transpileString(tableLib + code)).toThrowExactError( - TSTLErrors.UnsupportedKind( - "LuaTable access expression", - ts.SyntaxKind.ElementAccessExpression, - util.nodeStub - ) + UnsupportedKind("LuaTable access expression", ts.SyntaxKind.ElementAccessExpression, util.nodeStub) ); } ); @@ -135,7 +131,7 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { test.each([`set`, `get`])("Cannot isolate LuaTable method (%p)", propertyName => { expect(() => util.transpileString(`${tableLib} let property = tbl.${propertyName}`)).toThrowExactError( - TSTLErrors.UnsupportedProperty("LuaTable", propertyName, util.nodeStub) + UnsupportedProperty("LuaTable", propertyName, util.nodeStub) ); }); }); diff --git a/test/unit/decorators/metaExtension.spec.ts b/test/unit/decorators/metaExtension.spec.ts index cac222c97..76b40c791 100644 --- a/test/unit/decorators/metaExtension.spec.ts +++ b/test/unit/decorators/metaExtension.spec.ts @@ -1,4 +1,4 @@ -import * as TSTLErrors from "../../../src/TSTLErrors"; +import { InvalidNewExpressionOnExtension, MissingMetaExtension } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("MetaExtension", () => { @@ -35,7 +35,7 @@ test("IncorrectUsage", () => { } } `); - }).toThrowExactError(TSTLErrors.MissingMetaExtension(util.nodeStub)); + }).toThrowExactError(MissingMetaExtension(util.nodeStub)); }); test("DontAllowInstantiation", () => { @@ -47,5 +47,5 @@ test("DontAllowInstantiation", () => { } const e = new Ext(); `); - }).toThrowExactError(TSTLErrors.InvalidNewExpressionOnExtension(util.nodeStub)); + }).toThrowExactError(InvalidNewExpressionOnExtension(util.nodeStub)); }); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index e1959abb8..b58d488ad 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -329,7 +329,7 @@ test.each([...builtinErrors, "CustomError"])("get stack from %s", errorType => { function innerFunction() { stack = new ${errorType}().stack; } function outerFunction() { innerFunction(); } outerFunction(); - + return stack; `.getLuaExecutionResult(); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 5209bb59c..c65c1ebbc 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import * as TSTLErrors from "../../src/TSTLErrors"; +import { UnsupportedForTarget, UnsupportedKind } from "../../src/transformation/utils/errors"; import * as util from "../util"; // TODO: @@ -67,9 +67,7 @@ test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua51, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() - .expectToHaveDiagnosticOfError( - TSTLErrors.UnsupportedForTarget("Bitwise operations", tstl.LuaTarget.Lua51, util.nodeStub) - ); + .expectToHaveDiagnosticOfError(UnsupportedForTarget("Bitwise operations", tstl.LuaTarget.Lua51, util.nodeStub)); }); test.each(allBinaryOperators)("Bitop [JIT] (%p)", input => { @@ -98,7 +96,7 @@ test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() .expectToHaveDiagnosticOfError( - TSTLErrors.UnsupportedKind( + UnsupportedKind( "right shift operator (use >>> instead)", ts.SyntaxKind.GreaterThanGreaterThanToken, util.nodeStub diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index f0f6fd6e0..9cc7bb468 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -1,5 +1,3 @@ -import * as ts from "typescript"; -import * as TSTLErrors from "../../../src/TSTLErrors"; import * as util from "../../util"; test("Arrow Function Expression", () => { @@ -196,18 +194,6 @@ test("Function call", () => { `.expectToMatchJsResult(); }); -test("Invalid property access call transpilation", () => { - const transformer = util.makeTestTransformer(); - - const mockObject: any = { - expression: ts.createLiteral("abc"), - }; - - expect(() => transformer.transformPropertyCall(mockObject as ts.CallExpression)).toThrowExactError( - TSTLErrors.InvalidPropertyCall(util.nodeStub) - ); -}); - test("Recursive function definition", () => { util.testFunction` function f() { return typeof f; }; diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 06050ac5e..4f2e385be 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -1,4 +1,8 @@ -import * as TSTLErrors from "../../../../src/TSTLErrors"; +import { + UnsupportedNoSelfFunctionConversion, + UnsupportedOverloadAssignment, + UnsupportedSelfFunctionConversion, +} from "../../../../src/transformation/utils/errors"; import * as util from "../../../util"; import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; @@ -10,8 +14,8 @@ test.each(invalidTestFunctionAssignments)( const fn: ${functionType} = ${testFunction.value}; `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + ? UnsupportedSelfFunctionConversion(util.nodeStub) + : UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -25,8 +29,8 @@ test.each(invalidTestFunctionAssignments)( fn = ${testFunction.value}; `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + ? UnsupportedSelfFunctionConversion(util.nodeStub) + : UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -40,8 +44,8 @@ test.each(invalidTestFunctionCasts)( fn = ${castedFunction}; `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + ? UnsupportedSelfFunctionConversion(util.nodeStub) + : UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -55,8 +59,8 @@ test.each(invalidTestFunctionAssignments)( takesFunction(${testFunction.value}); `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + ? UnsupportedSelfFunctionConversion(util.nodeStub, "fn") + : UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -67,7 +71,7 @@ test("Invalid lua lib function argument", () => { declare const a: string[]; a.forEach(foo); `; - const err = TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "callbackfn"); + const err = UnsupportedSelfFunctionConversion(util.nodeStub, "callbackfn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); }); @@ -79,9 +83,11 @@ test.each(invalidTestFunctionCasts)( declare function takesFunction(fn: typeof ${testFunction.value}); takesFunction(${castedFunction}); `; + // TODO: Changed in #705 because of order change in `transformArguments`. + // After #412 both errors should be reported. const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + ? UnsupportedNoSelfFunctionConversion(util.nodeStub) + : UnsupportedSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -95,8 +101,8 @@ test.each(invalidTestFunctionAssignments)( takesFunction(${testFunction.value}); `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub, "fn") - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); + ? UnsupportedSelfFunctionConversion(util.nodeStub, "fn") + : UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -111,8 +117,8 @@ test.each(invalidTestFunctionAssignments)( } `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + ? UnsupportedSelfFunctionConversion(util.nodeStub) + : UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -127,8 +133,8 @@ test.each(invalidTestFunctionCasts)( } `; const err = isSelfConversion - ? TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - : TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub); + ? UnsupportedSelfFunctionConversion(util.nodeStub) + : UnsupportedNoSelfFunctionConversion(util.nodeStub); expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); } ); @@ -157,9 +163,7 @@ test("Invalid function tuple assignment", () => { declare function getTuple(): [number, Meth]; let [i, f]: [number, Func] = getTuple(); `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub) - ); + expect(() => util.transpileString(code)).toThrowExactError(UnsupportedNoSelfFunctionConversion(util.nodeStub)); }); test("Invalid method tuple assignment", () => { @@ -169,9 +173,7 @@ test("Invalid method tuple assignment", () => { declare function getTuple(): [number, Func]; let [i, f]: [number, Meth] = getTuple(); `; - expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedSelfFunctionConversion(util.nodeStub) - ); + expect(() => util.transpileString(code)).toThrowExactError(UnsupportedSelfFunctionConversion(util.nodeStub)); }); test("Invalid interface method assignment", () => { @@ -182,7 +184,7 @@ test("Invalid interface method assignment", () => { const b: B = a; `; expect(() => util.transpileString(code)).toThrowExactError( - TSTLErrors.UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn") + UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn") ); }); @@ -200,5 +202,5 @@ test.each([ declare const o: O; let f: ${assignType} = o; `; - expect(() => util.transpileString(code)).toThrowExactError(TSTLErrors.UnsupportedOverloadAssignment(util.nodeStub)); + expect(() => util.transpileString(code)).toThrowExactError(UnsupportedOverloadAssignment(util.nodeStub)); }); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index c5ad0a1c9..19dce6516 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import * as TSTLErrors from "../../src/TSTLErrors"; +import { ReferencedBeforeDeclaration } from "../../src/transformation/utils/errors"; import * as util from "../util"; test("Var Hoisting", () => { @@ -238,7 +238,7 @@ test.each([ { code: `function setBar() { const bar = { foo }; } let foo = "foo";`, identifier: "foo" }, ])("No Hoisting (%p)", ({ code, identifier }) => { expect(() => util.transpileString(code, { noHoisting: true })).toThrowExactError( - TSTLErrors.ReferencedBeforeDeclaration(ts.createIdentifier(identifier)) + ReferencedBeforeDeclaration(ts.createIdentifier(identifier)) ); }); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 3cd3753f6..88c5cc23b 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; +import { InvalidAmbientIdentifierName } from "../../src/transformation/utils/errors"; +import { luaKeywords } from "../../src/transformation/utils/safe-names"; import * as util from "../util"; -import { luaKeywords } from "../../src/LuaKeywords"; -import * as TSTLErrors from "../../src/TSTLErrors"; const invalidLuaCharNames = ["$$$", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"]; const validTsInvalidLuaKeywordNames = [ @@ -17,7 +17,7 @@ const validTsInvalidLuaKeywordNames = [ "then", "until", ]; -const invalidLuaNames = [...invalidLuaCharNames, ...luaKeywords.values()]; +const invalidLuaNames = [...invalidLuaCharNames, ...luaKeywords]; const validTsInvalidLuaNames = [...invalidLuaCharNames, ...validTsInvalidLuaKeywordNames]; test.each(validTsInvalidLuaNames)("invalid lua identifier name (%p)", name => { @@ -83,7 +83,7 @@ test.each([ local; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("local"))); + .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier("local"))); }); test.each([ @@ -100,7 +100,7 @@ test.each([ util.testModule` declare ${statement} $$$; - `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier("$$$"))); + `.expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier("$$$"))); }); test.each(validTsInvalidLuaNames)( @@ -109,7 +109,7 @@ test.each(validTsInvalidLuaNames)( util.testModule` declare var ${name}: any; const foo = { ${name} }; - `.expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); + `.expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); } ); @@ -118,7 +118,7 @@ test.each(validTsInvalidLuaNames)("undeclared identifier must be a valid lua ide const foo = ${name}; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); + .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); }); test.each(validTsInvalidLuaNames)( @@ -128,7 +128,7 @@ test.each(validTsInvalidLuaNames)( const foo = { ${name} }; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(TSTLErrors.InvalidAmbientIdentifierName(ts.createIdentifier(name))); + .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); } ); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index e822fc1ae..b7b7c27e5 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,6 +1,6 @@ -import * as TSTLErrors from "../../src/TSTLErrors"; -import * as util from "../util"; import * as ts from "typescript"; +import { InvalidJsonFileContent } from "../../src/transformation/utils/errors"; +import * as util from "../util"; const jsonOptions = { resolveJsonModule: true, @@ -19,5 +19,5 @@ test("Empty JSON", () => { util.testModule("") .setOptions(jsonOptions) .setMainFileName("main.json") - .expectToHaveDiagnosticOfError(TSTLErrors.InvalidJsonFileContent(util.nodeStub)); + .expectToHaveDiagnosticOfError(InvalidJsonFileContent(util.nodeStub)); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 5e137bdc5..fe5ce7461 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,6 +1,10 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import * as TSTLErrors from "../../src/TSTLErrors"; +import { + ForbiddenForIn, + UnsupportedForTarget, + UnsupportedObjectDestructuringInForOf, +} from "../../src/transformation/utils/errors"; import * as util from "../util"; test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("while (%p)", ({ inp, expected }) => { @@ -239,7 +243,7 @@ test.each([{ inp: [1, 2, 3] }])("forin[Array] (%p)", ({ inp }) => { arrTest[key]++; }` ) - ).toThrowExactError(TSTLErrors.ForbiddenForIn(util.nodeStub)); + ).toThrowExactError(ForbiddenForIn(util.nodeStub)); }); test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( @@ -482,7 +486,7 @@ test.each([ for (${initializer} of arr) {}`; expect(() => util.transpileString(code)).toThrow( - TSTLErrors.UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message + UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message ); }); @@ -590,11 +594,11 @@ test.each([ const luajit = { luaTarget: tstl.LuaTarget.LuaJIT }; expect(() => util.transpileString(loop, lua51)).toThrowExactError( - TSTLErrors.UnsupportedForTarget("Continue statement", tstl.LuaTarget.Lua51, ts.createContinue()) + UnsupportedForTarget("Continue statement", tstl.LuaTarget.Lua51, ts.createContinue()) ); - expect(util.transpileString(loop, lua52).indexOf("::__continue1::") !== -1).toBe(true); - expect(util.transpileString(loop, lua53).indexOf("::__continue1::") !== -1).toBe(true); - expect(util.transpileString(loop, luajit).indexOf("::__continue1::") !== -1).toBe(true); + expect(util.transpileString(loop, lua52).indexOf("::__continue2::") !== -1).toBe(true); + expect(util.transpileString(loop, lua53).indexOf("::__continue2::") !== -1).toBe(true); + expect(util.transpileString(loop, luajit).indexOf("::__continue2::") !== -1).toBe(true); }); test("do...while", () => { diff --git a/test/unit/tshelper.spec.ts b/test/unit/tshelper.spec.ts deleted file mode 100644 index 6cc1a809b..000000000 --- a/test/unit/tshelper.spec.ts +++ /dev/null @@ -1,143 +0,0 @@ -import * as ts from "typescript"; -import { DecoratorKind } from "../../src/Decorator"; -import * as tsHelper from "../../src/TSHelper"; -import * as util from "../util"; - -test("GetCustomDecorators single", () => { - const source = ` - /** @compileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1; - `; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - - if (util.expectToBeDefined(identifier)) { - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - expect(decorators.size).toBe(1); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } -}); - -test("GetCustomDecorators multiple", () => { - const source = ` - /** @compileMembersOnly - * @Phantom */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1; - `; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - - if (util.expectToBeDefined(identifier)) { - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - } -}); - -test("GetCustomDecorators single jsdoc", () => { - const source = ` - /** @compileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1; - `; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - - if (util.expectToBeDefined(identifier)) { - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - expect(decorators.size).toBe(1); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } -}); - -test("GetCustomDecorators multiple jsdoc", () => { - const source = ` - /** @phantom - * @CompileMembersOnly */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1; - `; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - - if (util.expectToBeDefined(identifier)) { - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } -}); - -test("GetCustomDecorators multiple default jsdoc", () => { - const source = ` - /** - * @description abc - * @phantom - * @compileMembersOnly - */ - enum TestEnum { - val1 = 0, - val2 = 2, - val3, - val4 = "bye", - } - - const a = TestEnum.val1; - `; - - const [sourceFile, typeChecker] = util.parseTypeScript(source); - const identifier = util.findFirstChild(sourceFile, ts.isEnumDeclaration); - - if (util.expectToBeDefined(identifier)) { - const enumType = typeChecker.getTypeAtLocation(identifier); - - const decorators = tsHelper.getCustomDecorators(enumType, typeChecker); - - expect(decorators.size).toBe(2); - expect(decorators.has(DecoratorKind.Phantom)).toBeTruthy(); - expect(decorators.has(DecoratorKind.CompileMembersOnly)).toBeTruthy(); - } -}); diff --git a/test/unit/typeof.spec.ts b/test/unit/typeof.spec.ts index 1541884b1..d85e8f8c1 100644 --- a/test/unit/typeof.spec.ts +++ b/test/unit/typeof.spec.ts @@ -16,11 +16,17 @@ test.each(["{}", "[]"])("typeof object literal (%p)", inp => { util.testExpression`typeof ${inp}`.expectToMatchJsResult(); }); +test("typeof class", () => { + util.testFunction` + class MyClass {} + return typeof MyClass; + `.expectToEqual("object"); +}); + test("typeof class instance", () => { util.testFunction` - class myClass {} - let inst = new myClass(); - return typeof inst; + class MyClass {} + return typeof new MyClass(); `.expectToMatchJsResult(); }); @@ -28,49 +34,66 @@ test("typeof function", () => { util.testExpression`typeof (() => 3)`.expectToMatchJsResult(); }); -test.each(["null", "undefined"])("typeof undefined (%p)", inp => { +test.each(["null", "undefined"])("typeof %s", inp => { util.testExpression`typeof ${inp}`.expectToEqual("undefined"); }); -test.each([ - { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, - { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, - { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, - { expression: "1", operator: "===", compareTo: "number", expectResult: true }, - { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, - { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, -])("typeof literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { - const code = ` - let val = ${expression}; - return typeof val ${operator} "${compareTo}";`; +interface ComparisonCase { + expression: string; + operator: string; + compareTo: string; +} - expect(util.transpileString(code)).not.toMatch("__TS__TypeOf"); - expect(util.transpileAndExecute(code)).toBe(expectResult); -}); +const equalityComparisonCases: ComparisonCase[] = [ + { expression: "{}", operator: "===", compareTo: "object" }, + { expression: "{}", operator: "!==", compareTo: "object" }, + { expression: "{}", operator: "==", compareTo: "object" }, + { expression: "{}", operator: "!=", compareTo: "object" }, + { expression: "undefined", operator: "===", compareTo: "undefined" }, + { expression: "() => {}", operator: "===", compareTo: "function" }, + { expression: "1", operator: "===", compareTo: "number" }, + { expression: "true", operator: "===", compareTo: "boolean" }, + { expression: `"foo"`, operator: "===", compareTo: "string" }, +]; + +const relationalComparisonCases: ComparisonCase[] = [ + { expression: "undefined", operator: "<=", compareTo: "object" }, + { expression: "undefined", operator: "<", compareTo: "object" }, + { expression: "undefined", operator: ">=", compareTo: "object" }, + { expression: "undefined", operator: ">", compareTo: "object" }, +]; -test.each([ - { expression: "{}", operator: "===", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!==", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "==", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "!=", compareTo: "object", expectResult: false }, - { expression: "{}", operator: "<=", compareTo: "object", expectResult: true }, - { expression: "{}", operator: "<", compareTo: "object", expectResult: false }, - { expression: "undefined", operator: "===", compareTo: "undefined", expectResult: true }, - { expression: "() => {}", operator: "===", compareTo: "function", expectResult: true }, - { expression: "1", operator: "===", compareTo: "number", expectResult: true }, - { expression: "true", operator: "===", compareTo: "boolean", expectResult: true }, - { expression: `"foo"`, operator: "===", compareTo: "string", expectResult: true }, -])("typeof non-literal comparison (%p)", ({ expression, operator, compareTo, expectResult }) => { - const code = ` - let val = ${expression}; - let compareTo = "${compareTo}"; - return typeof val ${operator} compareTo;`; +const expectTypeOfHelper: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch("__TS__TypeOf"); +const expectNoTypeOfHelper: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).not.toMatch("__TS__TypeOf"); - expect(util.transpileString(code)).toMatch("__TS__TypeOf"); - expect(util.transpileAndExecute(code)).toBe(expectResult); +test.each(equalityComparisonCases)("typeof literal equality comparison (%p)", ({ expression, operator, compareTo }) => { + util.testFunction` + const value = ${expression}; + return typeof value ${operator} "${compareTo}"; + ` + .tap(expectNoTypeOfHelper) + .expectToMatchJsResult(); }); + +test.each(relationalComparisonCases)("typeof literal comparison (%p)", ({ expression, operator, compareTo }) => { + util.testFunction` + const value = ${expression}; + return typeof value ${operator} "${compareTo}"; + ` + .tap(expectTypeOfHelper) + .expectToMatchJsResult(); +}); + +test.each([...equalityComparisonCases, ...relationalComparisonCases])( + "typeof non-literal comparison (%p)", + ({ expression, operator, compareTo }) => { + util.testFunction` + const value = ${expression}; + const compareTo = "${compareTo}"; + return typeof value ${operator} compareTo; + ` + .tap(expectTypeOfHelper) + .expectToMatchJsResult(); + } +); diff --git a/test/util.ts b/test/util.ts index b1dc96934..ef7c8c4bd 100644 --- a/test/util.ts +++ b/test/util.ts @@ -11,11 +11,6 @@ export * from "./legacy-utils"; export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); -// Get a mock transformer to use for testing -export function makeTestTransformer(luaTarget = tstl.LuaTarget.Lua53): tstl.LuaTransformer { - return new tstl.LuaTransformer(ts.createProgram([], { luaTarget })); -} - export function parseTypeScript( typescript: string, target: tstl.LuaTarget = tstl.LuaTarget.Lua53 From dc18e470f5c2ae2e487fb210295003e44f1a8008 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 8 Dec 2019 19:42:43 +0500 Subject: [PATCH 198/764] Upgrade dependencies (#763) * Upgrade dependencies * Format with Prettier * Fix jest `Matchers` declaration * Fix tslint warning * Fix `isStrict` detection logic --- package-lock.json | 1993 +++++++---------- package.json | 22 +- src/Emit.ts | 4 +- src/LuaAST.ts | 12 +- src/LuaPrinter.ts | 62 +- src/TSTransformers.ts | 14 +- src/bundle.ts | 2 +- src/cli/information.ts | 2 +- src/transformation/builtins/index.ts | 26 +- src/transformation/context/context.ts | 9 +- src/transformation/index.ts | 2 +- src/transformation/utils/annotations.ts | 2 +- src/transformation/utils/export.ts | 4 +- src/transformation/utils/function-context.ts | 2 +- src/transformation/utils/lua-ast.ts | 4 +- src/transformation/utils/scope.ts | 2 +- src/transformation/utils/symbols.ts | 2 +- src/transformation/utils/typescript/index.ts | 4 +- src/transformation/utils/typescript/types.ts | 2 +- .../visitors/binary-expression/compound.ts | 2 +- .../visitors/class/members/fields.ts | 2 +- src/transformation/visitors/class/new.ts | 2 +- src/transformation/visitors/class/utils.ts | 2 +- src/transformation/visitors/errors.ts | 6 +- src/transformation/visitors/function.ts | 2 +- .../visitors/variable-declaration.ts | 6 +- src/tstl.ts | 2 +- src/utils.ts | 2 + test/setup.ts | 2 +- test/unit/builtins/array.spec.ts | 43 +- test/unit/builtins/string.spec.ts | 70 +- test/unit/classes/classes.spec.ts | 26 +- test/unit/functions/functions.spec.ts | 43 +- test/unit/hoisting.spec.ts | 16 +- test/unit/loops.spec.ts | 49 +- test/unit/transformers/utils.ts | 2 +- test/util.ts | 4 +- 37 files changed, 1078 insertions(+), 1373 deletions(-) diff --git a/package-lock.json b/package-lock.json index fdc631602..ff7c19908 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,107 +5,49 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", - "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/core": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.0.tgz", - "integrity": "sha512-Dzl7U0/T69DFOTwqz/FJdnOSWS57NpjNfCwMKHABr589Lg8uX1RrlBIJ7L5Dubt/xkLsx0xH5EBFzlBVes1ayA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", - "@babel/helpers": "^7.4.0", - "@babel/parser": "^7.4.0", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.0", - "@babel/types": "^7.4.0", - "convert-source-map": "^1.1.0", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", + "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.4", + "@babel/helpers": "^7.7.4", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4", + "convert-source-map": "^1.7.0", "debug": "^4.1.0", "json5": "^2.1.0", - "lodash": "^4.17.11", + "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { - "@babel/generator": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", - "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", - "dev": true, - "requires": { - "@babel/types": "^7.4.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", - "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", - "dev": true, - "requires": { - "@babel/types": "^7.4.0" - } - }, - "@babel/parser": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.2.tgz", - "integrity": "sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==", - "dev": true - }, - "@babel/template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", - "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0" - } - }, - "@babel/traverse": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.0.tgz", - "integrity": "sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", - "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" + "ms": "^2.1.1" } }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "source-map": { @@ -117,16 +59,15 @@ } }, "@babel/generator": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", - "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", + "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", "dev": true, "requires": { - "@babel/types": "^7.3.2", + "@babel/types": "^7.7.4", "jsesc": "^2.5.1", - "lodash": "^4.17.10", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" + "lodash": "^4.17.13", + "source-map": "^0.5.0" }, "dependencies": { "source-map": { @@ -138,23 +79,23 @@ } }, "@babel/helper-function-name": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", - "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", + "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.0.0", - "@babel/template": "^7.1.0", - "@babel/types": "^7.0.0" + "@babel/helper-get-function-arity": "^7.7.4", + "@babel/template": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/helper-get-function-arity": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", - "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", + "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.4" } }, "@babel/helper-plugin-utils": { @@ -164,199 +105,104 @@ "dev": true }, "@babel/helper-split-export-declaration": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", - "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", + "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", "dev": true, "requires": { - "@babel/types": "^7.0.0" + "@babel/types": "^7.7.4" } }, "@babel/helpers": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.2.tgz", - "integrity": "sha512-gQR1eQeroDzFBikhrCccm5Gs2xBjZ57DNjGbqTaHo911IpmSxflOQWMAHPw/TXk8L3isv7s9lYzUkexOeTQUYg==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", + "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", "dev": true, "requires": { - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.0", - "@babel/types": "^7.4.0" - }, - "dependencies": { - "@babel/generator": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.0.tgz", - "integrity": "sha512-/v5I+a1jhGSKLgZDcmAUZ4K/VePi43eRkUs3yePW1HB1iANOD5tqJXwGSG4BZhSksP8J9ejSlwGeTiiOFZOrXQ==", - "dev": true, - "requires": { - "@babel/types": "^7.4.0", - "jsesc": "^2.5.1", - "lodash": "^4.17.11", - "source-map": "^0.5.0", - "trim-right": "^1.0.1" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.0.tgz", - "integrity": "sha512-7Cuc6JZiYShaZnybDmfwhY4UYHzI6rlqhWjaIqbsJGsIqPimEYy5uh3akSRLMg65LSdSEnJ8a8/bWQN6u2oMGw==", - "dev": true, - "requires": { - "@babel/types": "^7.4.0" - } - }, - "@babel/parser": { - "version": "7.4.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.2.tgz", - "integrity": "sha512-9fJTDipQFvlfSVdD/JBtkiY0br9BtfvW2R8wo6CX/Ej2eMuV0gWPk1M67Mt3eggQvBqYW1FCEk8BN7WvGm/g5g==", - "dev": true - }, - "@babel/template": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.0.tgz", - "integrity": "sha512-SOWwxxClTTh5NdbbYZ0BmaBVzxzTh2tO/TeLTbF6MO6EzVhHTnff8CdBXx3mEtazFBoysmEM6GU/wF+SuSx4Fw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0" - } - }, - "@babel/traverse": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.0.tgz", - "integrity": "sha512-/DtIHKfyg2bBKnIN+BItaIlEg5pjAnzHOIQe5w+rHAw/rg9g0V7T4rqPX8BJPfW11kt3koyjAnTNwCzb28Y1PA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.4.0", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.0", - "@babel/parser": "^7.4.0", - "@babel/types": "^7.4.0", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.11" - } - }, - "@babel/types": { - "version": "7.4.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.0.tgz", - "integrity": "sha512-aPvkXyU2SPOnztlgo8n9cEiXW755mgyvueUPcpStqdzoSPm0fjO0vQBjLkt3JKJW7ufikfcnMTTPsN1xaTsBPA==", - "dev": true, - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.11", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/highlight": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", - "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, "@babel/parser": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", - "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "version": "7.7.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", + "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", "dev": true }, "@babel/plugin-syntax-object-rest-spread": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", - "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", + "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0" } }, "@babel/template": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", - "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", + "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.2.2", - "@babel/types": "^7.2.2" + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4" } }, "@babel/traverse": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", - "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", + "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/generator": "^7.2.2", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.0.0", - "@babel/parser": "^7.2.3", - "@babel/types": "^7.2.2", + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.7.4", + "@babel/helper-function-name": "^7.7.4", + "@babel/helper-split-export-declaration": "^7.7.4", + "@babel/parser": "^7.7.4", + "@babel/types": "^7.7.4", "debug": "^4.1.0", "globals": "^11.1.0", - "lodash": "^4.17.10" + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } } }, "@babel/types": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", - "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", + "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", "dev": true, "requires": { "esutils": "^2.0.2", - "lodash": "^4.17.10", + "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, @@ -371,84 +217,85 @@ } }, "@jest/console": { - "version": "24.7.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz", - "integrity": "sha512-iNhtIy2M8bXlAOULWVTUxmnelTLFneTNEkHCgPmgd+zNwy9zVddJ6oS5rZ9iwoscNdT5mMwUd0C51v/fSlzItg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", + "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", "dev": true, "requires": { - "@jest/source-map": "^24.3.0", + "@jest/source-map": "^24.9.0", "chalk": "^2.0.1", "slash": "^2.0.0" } }, "@jest/core": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.8.0.tgz", - "integrity": "sha512-R9rhAJwCBQzaRnrRgAdVfnglUuATXdwTRsYqs6NMdVcAl5euG8LtWDe+fVkN27YfKVBW61IojVsXKaOmSnqd/A==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", + "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", "dev": true, "requires": { "@jest/console": "^24.7.1", - "@jest/reporters": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/reporters": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", "exit": "^0.1.2", "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.8.0", - "jest-config": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-message-util": "^24.8.0", + "jest-changed-files": "^24.9.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", "jest-regex-util": "^24.3.0", - "jest-resolve-dependencies": "^24.8.0", - "jest-runner": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", - "jest-watcher": "^24.8.0", + "jest-resolve": "^24.9.0", + "jest-resolve-dependencies": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", + "jest-watcher": "^24.9.0", "micromatch": "^3.1.10", "p-each-series": "^1.0.0", - "pirates": "^4.0.1", "realpath-native": "^1.1.0", "rimraf": "^2.5.4", + "slash": "^2.0.0", "strip-ansi": "^5.0.0" } }, "@jest/environment": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.8.0.tgz", - "integrity": "sha512-vlGt2HLg7qM+vtBrSkjDxk9K0YtRBi7HfRFaDxoRtyi+DyVChzhF20duvpdAnKVBV6W5tym8jm0U9EfXbDk1tw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", + "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", "dev": true, "requires": { - "@jest/fake-timers": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0" + "@jest/fake-timers": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0" } }, "@jest/fake-timers": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.8.0.tgz", - "integrity": "sha512-2M4d5MufVXwi6VzZhJ9f5S/wU4ud2ck0kxPof1Iz3zWx6Y+V2eJrES9jEktB6O3o/oEyk+il/uNu9PvASjWXQw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", + "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", "dev": true, "requires": { - "@jest/types": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0" + "@jest/types": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0" } }, "@jest/reporters": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.8.0.tgz", - "integrity": "sha512-eZ9TyUYpyIIXfYCrw0UHUWUvE35vx5I92HGMgS93Pv7du+GHIzl+/vh8Qj9MCWFK/4TqyttVBPakWMOfZRIfxw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", + "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", "dev": true, "requires": { - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", "exit": "^0.1.2", "glob": "^7.1.2", @@ -456,13 +303,13 @@ "istanbul-lib-instrument": "^3.0.1", "istanbul-lib-report": "^2.0.4", "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.1.1", - "jest-haste-map": "^24.8.0", - "jest-resolve": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-util": "^24.8.0", + "istanbul-reports": "^2.2.6", + "jest-haste-map": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", "jest-worker": "^24.6.0", - "node-notifier": "^5.2.1", + "node-notifier": "^5.4.2", "slash": "^2.0.0", "source-map": "^0.6.0", "string-length": "^2.0.0" @@ -477,9 +324,9 @@ } }, "@jest/source-map": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.3.0.tgz", - "integrity": "sha512-zALZt1t2ou8le/crCeeiRYzvdnTzaIlpOWaet45lNSqNJUnXbppUUFR4ZUAlzgDmKee4Q5P/tKXypI1RiHwgag==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", + "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", "dev": true, "requires": { "callsites": "^3.0.0", @@ -496,53 +343,46 @@ } }, "@jest/test-result": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.8.0.tgz", - "integrity": "sha512-+YdLlxwizlfqkFDh7Mc7ONPQAhA4YylU1s529vVM1rsf67vGZH/2GGm5uO8QzPeVyaVMobCQ7FTxl38QrKRlng==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", + "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/types": "^24.8.0", + "@jest/console": "^24.9.0", + "@jest/types": "^24.9.0", "@types/istanbul-lib-coverage": "^2.0.0" - }, - "dependencies": { - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - } } }, "@jest/test-sequencer": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.8.0.tgz", - "integrity": "sha512-OzL/2yHyPdCHXEzhoBuq37CE99nkme15eHkAzXRVqthreWZamEMA0WoetwstsQBCXABhczpK03JNbc4L01vvLg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", + "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", "dev": true, "requires": { - "@jest/test-result": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-runner": "^24.8.0", - "jest-runtime": "^24.8.0" + "@jest/test-result": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-runner": "^24.9.0", + "jest-runtime": "^24.9.0" } }, "@jest/transform": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.8.0.tgz", - "integrity": "sha512-xBMfFUP7TortCs0O+Xtez2W7Zu1PLH9bvJgtraN1CDST6LBM/eTOZ9SfwS/lvV8yOfcDpFmwf9bq5cYbXvqsvA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", + "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "babel-plugin-istanbul": "^5.1.0", "chalk": "^2.0.1", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.8.0", - "jest-regex-util": "^24.3.0", - "jest-util": "^24.8.0", + "jest-haste-map": "^24.9.0", + "jest-regex-util": "^24.9.0", + "jest-util": "^24.9.0", "micromatch": "^3.1.10", + "pirates": "^4.0.1", "realpath-native": "^1.1.0", "slash": "^2.0.0", "source-map": "^0.6.1", @@ -558,28 +398,20 @@ } }, "@jest/types": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.8.0.tgz", - "integrity": "sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", + "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^12.0.9" - }, - "dependencies": { - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true - } + "@types/yargs": "^13.0.0" } }, "@types/babel__core": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.2.tgz", - "integrity": "sha512-cfCCrFmiGY/yq0NuKNxIQvZFy9kY/1immpSpTngOnyIbD4+eJOG5mxphhHDv3CHL9GltO4GcKr54kGBg3RNdbg==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", + "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -590,9 +422,9 @@ } }, "@types/babel__generator": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.0.2.tgz", - "integrity": "sha512-NHcOfab3Zw4q5sEE2COkpfXjoE7o+PmqD9DQW4koUT3roNxwziUdXGnRndMat/LJNUtePwn1TlP4do3uoe3KZQ==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", + "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -609,9 +441,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.7.tgz", - "integrity": "sha512-CeBpmX1J8kWLcDEnI3Cl2Eo6RfbGvzUctA+CjZUhOKDFbLfcr7fc4usEqLNWetrlJd7RhAkyYe2czXop4fICpw==", + "version": "7.0.8", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", + "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -644,9 +476,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.0.tgz", - "integrity": "sha512-ohkhb9LehJy+PA40rDtGAji61NCgdtKLAlFoYp4cnuuQEswwdK3vz9SOIkkyc3wrk8dzjphQApNs56yyXLStaQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", "dev": true }, "@types/istanbul-lib-report": { @@ -669,20 +501,14 @@ } }, "@types/jest": { - "version": "24.0.15", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.15.tgz", - "integrity": "sha512-MU1HIvWUme74stAoc3mgAi+aMlgKOudgEvQDIm1v4RkrDudBh1T+NFp5sftpBAdXdx1J0PbdpJ+M2EsSOi1djA==", + "version": "24.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.23.tgz", + "integrity": "sha512-L7MBvwfNpe7yVPTXLn32df/EK+AMBFAFvZrRuArGs7npEWnlziUXK+5GMIUTI4NIuwok3XibsjXCs5HxviYXjg==", "dev": true, "requires": { - "@types/jest-diff": "*" + "jest-diff": "^24.3.0" } }, - "@types/jest-diff": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/@types/jest-diff/-/jest-diff-20.0.1.tgz", - "integrity": "sha512-yALhelO3i0hqZwhjtcr6dYyaLoCHbAMshwtj6cGxTvHZAKXHsYGdff6E8EPw3xLKY0ELUTQ69Q1rQiJENnccMA==", - "dev": true - }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -690,9 +516,9 @@ "dev": true }, "@types/node": { - "version": "11.13.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.14.tgz", - "integrity": "sha512-9NjFOB6UUGjJLNANmyIouuaN8YPsPgC4DCOd5lU+DL7HSX/RCfzz0JOtHlspEJq1Ll/JUu/8Cm4wzxpZ8w5sjQ==", + "version": "12.12.14", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", + "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==", "dev": true }, "@types/resolve": { @@ -711,15 +537,24 @@ "dev": true }, "@types/yargs": { - "version": "12.0.10", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-12.0.10.tgz", - "integrity": "sha512-WsVzTPshvCSbHThUduGGxbmnwcpkgSctHGHTqzWyFg4lYAuV5qXlyFPOsP3OWqCINfmg/8VXP+zJaa4OxEsBQQ==", + "version": "13.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", + "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz", + "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", "dev": true }, "abab": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", - "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", "dev": true }, "acorn": { @@ -729,9 +564,9 @@ "dev": true }, "acorn-globals": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", - "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { "acorn": "^6.0.1", @@ -739,9 +574,9 @@ }, "dependencies": { "acorn": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.1.tgz", - "integrity": "sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", + "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", "dev": true } } @@ -771,9 +606,9 @@ "dev": true }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "ansi-styles": { @@ -795,6 +630,12 @@ "normalize-path": "^2.1.1" } }, + "arg": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", + "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", + "dev": true + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -842,12 +683,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -876,9 +711,9 @@ "dev": true }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, "asynckit": { @@ -900,54 +735,55 @@ "dev": true }, "aws4": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", + "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", "dev": true }, "babel-jest": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.8.0.tgz", - "integrity": "sha512-+5/kaZt4I9efoXzPlZASyK/lN9qdRKmmUav9smVc0ruPQD7IsfucQ87gpOE8mn2jbDuS6M/YOW6n3v9ZoIfgnw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", + "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", "dev": true, "requires": { - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", "@types/babel__core": "^7.1.0", "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.6.0", + "babel-preset-jest": "^24.9.0", "chalk": "^2.4.2", "slash": "^2.0.0" } }, "babel-plugin-istanbul": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.1.1.tgz", - "integrity": "sha512-RNNVv2lsHAXJQsEJ5jonQwrJVWK8AcZpG1oxhnjCUaAjL7xahYLANhPUZbzEQHjKy1NMYUwn+0NPKQc8iSY4xQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", + "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", "dev": true, "requires": { + "@babel/helper-plugin-utils": "^7.0.0", "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.0.0", - "test-exclude": "^5.0.0" + "istanbul-lib-instrument": "^3.3.0", + "test-exclude": "^5.2.3" } }, "babel-plugin-jest-hoist": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.6.0.tgz", - "integrity": "sha512-3pKNH6hMt9SbOv0F3WVmy5CWQ4uogS3k0GY5XLyQHJ9EGpAT9XWkFd2ZiXXtkwFHdAHa5j7w7kfxSP5lAIwu7w==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", + "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", "dev": true, "requires": { "@types/babel__traverse": "^7.0.6" } }, "babel-preset-jest": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.6.0.tgz", - "integrity": "sha512-pdZqLEdmy1ZK5kyRUfvBb2IfTPb2BUvIJczlPspS8fWmBQslNNDBqVfh7BW5leOVJMDZKzjD8XEyABTk6gQ5yw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", + "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", "dev": true, "requires": { "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.6.0" + "babel-plugin-jest-hoist": "^24.9.0" } }, "balanced-match": { @@ -1092,9 +928,9 @@ } }, "bser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", - "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "requires": { "node-int64": "^0.4.0" @@ -1130,9 +966,9 @@ } }, "callsites": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz", - "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, "camelcase": { @@ -1197,25 +1033,14 @@ } }, "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" } }, "co": { @@ -1224,12 +1049,6 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1241,18 +1060,18 @@ } }, "color-convert": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz", - "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==", + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { - "color-name": "1.1.1" + "color-name": "1.1.3" } }, "color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "combined-stream": { @@ -1265,15 +1084,15 @@ } }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, "concat-map": { @@ -1283,9 +1102,9 @@ "dev": true }, "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -1352,9 +1171,9 @@ }, "dependencies": { "whatwg-url": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", - "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -1365,12 +1184,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "decamelize": { @@ -1454,15 +1273,15 @@ "dev": true }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", "dev": true }, "diff-sequences": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.3.0.tgz", - "integrity": "sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", + "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", "dev": true }, "domexception": { @@ -1484,10 +1303,16 @@ "safer-buffer": "^2.1.0" } }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "requires": { "once": "^1.4.0" @@ -1503,23 +1328,27 @@ } }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", + "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", + "has-symbols": "^1.0.1", "is-callable": "^1.1.4", "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" } }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -1534,9 +1363,9 @@ "dev": true }, "escodegen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", - "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", + "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", "dev": true, "requires": { "esprima": "^3.1.3", @@ -1546,12 +1375,6 @@ "source-map": "~0.6.1" }, "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1562,27 +1385,27 @@ } }, "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", "dev": true }, "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, "exec-sh": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.2.tgz", - "integrity": "sha512-9sLAvzhI5nc8TpuQUh4ahMdCrWT00wPWz7j47/emR5+2qEfoZP5zzUXvx+vdx+H6ohhnsYC31iX04QLYJK8zTg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", "dev": true }, "execa": { @@ -1621,15 +1444,6 @@ "to-regex": "^3.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -1647,27 +1461,21 @@ "requires": { "is-extendable": "^0.1.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "expect": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.8.0.tgz", - "integrity": "sha512-/zYvP8iMDrzaaxHVa724eJBCKqSHmO0FA7EDkBiRHxg6OipmMn1fN+C8T9L9K8yr7UONkOifu6+LLH+z76CnaA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", + "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "ansi-styles": "^3.2.0", - "jest-get-type": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-regex-util": "^24.3.0" + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-regex-util": "^24.9.0" } }, "extend": { @@ -1787,12 +1595,12 @@ "dev": true }, "fb-watchman": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", - "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, "requires": { - "bser": "^2.0.0" + "bser": "2.1.1" } }, "fengari": { @@ -2450,9 +2258,9 @@ "dev": true }, "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "get-stream": { @@ -2480,9 +2288,9 @@ } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2494,9 +2302,9 @@ } }, "globals": { - "version": "11.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", - "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "graceful-fs": { @@ -2512,9 +2320,9 @@ "dev": true }, "handlebars": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.2.tgz", - "integrity": "sha512-29Zxv/cynYB7mkT1rVWQnV7mGX6v7H/miQ6dbEpYTKq5eJBN7PsRB+ViYJlcT6JINTSu4dVB9kOqEun78h6Exg==", + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", + "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "dev": true, "requires": { "neo-async": "^2.6.0", @@ -2563,9 +2371,9 @@ "dev": true }, "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, "has-value": { @@ -2601,9 +2409,9 @@ } }, "hosted-git-info": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", + "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", "dev": true }, "html-encoding-sniffer": { @@ -2662,9 +2470,9 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, "invariant": { @@ -2676,12 +2484,6 @@ "loose-envify": "^1.0.0" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, "is-accessor-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", @@ -2787,9 +2589,9 @@ "dev": true }, "is-generator-fn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.0.0.tgz", - "integrity": "sha512-elzyIdM7iKoFHzcrndIqjYomImhxrFRnGP3galODoII4TB9gI7mZ+FnlLQmmjf27SxHS2gKEeyhX5/+YRS6H9g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, "is-number": { @@ -2837,12 +2639,12 @@ "dev": true }, "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { - "has-symbols": "^1.0.0" + "has-symbols": "^1.0.1" } }, "is-typedarray": { @@ -2888,24 +2690,32 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", + "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-instrument": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", - "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", + "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { - "@babel/generator": "^7.0.0", - "@babel/parser": "^7.0.0", - "@babel/template": "^7.0.0", - "@babel/traverse": "^7.0.0", - "@babel/types": "^7.0.0", - "istanbul-lib-coverage": "^2.0.3", - "semver": "^5.5.0" + "@babel/generator": "^7.4.0", + "@babel/parser": "^7.4.3", + "@babel/template": "^7.4.0", + "@babel/traverse": "^7.4.3", + "@babel/types": "^7.4.0", + "istanbul-lib-coverage": "^2.0.5", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "istanbul-lib-report": { @@ -2919,12 +2729,6 @@ "supports-color": "^6.1.0" }, "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", - "dev": true - }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -2949,10 +2753,19 @@ "source-map": "^0.6.1" }, "dependencies": { - "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, "source-map": { @@ -2973,245 +2786,246 @@ } }, "javascript-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.0.tgz", - "integrity": "sha512-zzK8+ByrzvOL6N92hRewwUKL0wN0TOaIuUjX0Jj8lraxWvr5wHYs2YTjaj2lstF+8qMv5cmPPef47va8NT8lDw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", + "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", "dev": true }, "jest": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.8.0.tgz", - "integrity": "sha512-o0HM90RKFRNWmAWvlyV8i5jGZ97pFwkeVoGvPW1EtLTgJc2+jcuqcbbqcSZLE/3f2S5pt0y2ZBETuhpWNl1Reg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", + "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", "dev": true, "requires": { "import-local": "^2.0.0", - "jest-cli": "^24.8.0" + "jest-cli": "^24.9.0" }, "dependencies": { "jest-cli": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.8.0.tgz", - "integrity": "sha512-+p6J00jSMPQ116ZLlHJJvdf8wbjNbZdeSX9ptfHX06/MSNaXmKihQzx5vQcw0q2G6JsdVkUIdWbOWtSnaYs3yA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", + "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", "dev": true, "requires": { - "@jest/core": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/core": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", "exit": "^0.1.2", "import-local": "^2.0.0", "is-ci": "^2.0.0", - "jest-config": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", + "jest-config": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", "prompts": "^2.0.1", "realpath-native": "^1.1.0", - "yargs": "^12.0.2" + "yargs": "^13.3.0" } } } }, "jest-changed-files": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.8.0.tgz", - "integrity": "sha512-qgANC1Yrivsq+UrLXsvJefBKVoCsKB0Hv+mBb6NMjjZ90wwxCDmU3hsCXBya30cH+LnPYjwgcU65i6yJ5Nfuug==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", + "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "execa": "^1.0.0", "throat": "^4.0.0" } }, "jest-circus": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.8.0.tgz", - "integrity": "sha512-2QASG3QuDdk0SMP2O73D8u3/lc/A/E2G7q23v5WhbUR+hCGzWZXwRMKif18f11dSLfL1wcrMbwE4IorvV0DRVw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.9.0.tgz", + "integrity": "sha512-dwkvwFtRc9Anmk1XTc+bonVL8rVMZ3CeGMoFWmv1oaQThdAgvfI9bwaFlZp+gLVphNVz6ZLfCWo3ERhS5CeVvA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", "co": "^4.6.0", - "expect": "^24.8.0", + "expect": "^24.9.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", "stack-utils": "^1.0.1", "throat": "^4.0.0" } }, "jest-config": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.8.0.tgz", - "integrity": "sha512-Czl3Nn2uEzVGsOeaewGWoDPD8GStxCpAe0zOYs2x2l0fZAgPbCr3uwUkgNKV3LwE13VXythM946cd5rdGkkBZw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", + "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.8.0", - "@jest/types": "^24.8.0", - "babel-jest": "^24.8.0", + "@jest/test-sequencer": "^24.9.0", + "@jest/types": "^24.9.0", + "babel-jest": "^24.9.0", "chalk": "^2.0.1", "glob": "^7.1.1", - "jest-environment-jsdom": "^24.8.0", - "jest-environment-node": "^24.8.0", - "jest-get-type": "^24.8.0", - "jest-jasmine2": "^24.8.0", + "jest-environment-jsdom": "^24.9.0", + "jest-environment-node": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-jasmine2": "^24.9.0", "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", + "jest-resolve": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", "micromatch": "^3.1.10", - "pretty-format": "^24.8.0", + "pretty-format": "^24.9.0", "realpath-native": "^1.1.0" } }, "jest-diff": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.8.0.tgz", - "integrity": "sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", + "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", "dev": true, "requires": { "chalk": "^2.0.1", - "diff-sequences": "^24.3.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" + "diff-sequences": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, "jest-docblock": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.3.0.tgz", - "integrity": "sha512-nlANmF9Yq1dufhFlKG9rasfQlrY7wINJbo3q01tu56Jv5eBU5jirylhF2O5ZBnLxzOVBGRDz/9NAwNyBtG4Nyg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", + "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", "dev": true, "requires": { "detect-newline": "^2.1.0" } }, "jest-each": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.8.0.tgz", - "integrity": "sha512-NrwK9gaL5+XgrgoCsd9svsoWdVkK4gnvyhcpzd6m487tXHqIdYeykgq3MKI1u4I+5Zf0tofr70at9dWJDeb+BA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", + "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", - "jest-get-type": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0" + "jest-get-type": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0" } }, "jest-environment-jsdom": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.8.0.tgz", - "integrity": "sha512-qbvgLmR7PpwjoFjM/sbuqHJt/NCkviuq9vus9NBn/76hhSidO+Z6Bn9tU8friecegbJL8gzZQEMZBQlFWDCwAQ==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", + "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", "dev": true, "requires": { - "@jest/environment": "^24.8.0", - "@jest/fake-timers": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-util": "^24.8.0", + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0", "jsdom": "^11.5.1" } }, "jest-environment-node": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.8.0.tgz", - "integrity": "sha512-vIGUEScd1cdDgR6sqn2M08sJTRLQp6Dk/eIkCeO4PFHxZMOgy+uYLPMC4ix3PEfM5Au/x3uQ/5Tl0DpXXZsJ/Q==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", + "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", "dev": true, "requires": { - "@jest/environment": "^24.8.0", - "@jest/fake-timers": "^24.8.0", - "@jest/types": "^24.8.0", - "jest-mock": "^24.8.0", - "jest-util": "^24.8.0" + "@jest/environment": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/types": "^24.9.0", + "jest-mock": "^24.9.0", + "jest-util": "^24.9.0" } }, "jest-get-type": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.8.0.tgz", - "integrity": "sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", + "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", "dev": true }, "jest-haste-map": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.8.0.tgz", - "integrity": "sha512-ZBPRGHdPt1rHajWelXdqygIDpJx8u3xOoLyUBWRW28r3tagrgoepPrzAozW7kW9HrQfhvmiv1tncsxqHJO1onQ==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", + "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "anymatch": "^2.0.0", "fb-watchman": "^2.0.0", "fsevents": "^1.2.7", "graceful-fs": "^4.1.15", "invariant": "^2.2.4", - "jest-serializer": "^24.4.0", - "jest-util": "^24.8.0", - "jest-worker": "^24.6.0", + "jest-serializer": "^24.9.0", + "jest-util": "^24.9.0", + "jest-worker": "^24.9.0", "micromatch": "^3.1.10", "sane": "^4.0.3", "walker": "^1.0.7" } }, "jest-jasmine2": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.8.0.tgz", - "integrity": "sha512-cEky88npEE5LKd5jPpTdDCLvKkdyklnaRycBXL6GNmpxe41F0WN44+i7lpQKa/hcbXaQ+rc9RMaM4dsebrYong==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", + "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", "co": "^4.6.0", - "expect": "^24.8.0", + "expect": "^24.9.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "pretty-format": "^24.8.0", + "jest-each": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "pretty-format": "^24.9.0", "throat": "^4.0.0" } }, "jest-leak-detector": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.8.0.tgz", - "integrity": "sha512-cG0yRSK8A831LN8lIHxI3AblB40uhv0z+SsQdW3GoMMVcK+sJwrIIyax5tu3eHHNJ8Fu6IMDpnLda2jhn2pD/g==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", + "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", "dev": true, "requires": { - "pretty-format": "^24.8.0" + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, "jest-matcher-utils": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.8.0.tgz", - "integrity": "sha512-lex1yASY51FvUuHgm0GOVj7DCYEouWSlIYmCW7APSqB9v8mXmKSn5+sWVF0MhuASG0bnYY106/49JU1FZNl5hw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", + "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", "dev": true, "requires": { "chalk": "^2.0.1", - "jest-diff": "^24.8.0", - "jest-get-type": "^24.8.0", - "pretty-format": "^24.8.0" + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "pretty-format": "^24.9.0" } }, "jest-message-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.8.0.tgz", - "integrity": "sha512-p2k71rf/b6ns8btdB0uVdljWo9h0ovpnEe05ZKWceQGfXYr4KkzgKo3PBi8wdnd9OtNh46VpNIJynUn/3MKm1g==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", + "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "@types/stack-utils": "^1.0.1", "chalk": "^2.0.1", "micromatch": "^3.1.10", @@ -3220,12 +3034,12 @@ } }, "jest-mock": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz", - "integrity": "sha512-6kWugwjGjJw+ZkK4mDa0Df3sDlUTsV47MSrT0nGQ0RBWJbpODDQ8MHDVtGtUYBne3IwZUhtB7elxHspU79WH3A==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", + "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", "dev": true, "requires": { - "@jest/types": "^24.8.0" + "@jest/types": "^24.9.0" } }, "jest-pnp-resolver": { @@ -3235,18 +3049,18 @@ "dev": true }, "jest-regex-util": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.3.0.tgz", - "integrity": "sha512-tXQR1NEOyGlfylyEjg1ImtScwMq8Oh3iJbGTjN7p0J23EuVX1MA8rwU69K4sLbCmwzgCUbVkm0FkSF9TdzOhtg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", + "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", "dev": true }, "jest-resolve": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.8.0.tgz", - "integrity": "sha512-+hjSzi1PoRvnuOICoYd5V/KpIQmkAsfjFO71458hQ2Whi/yf1GDeBOFj8Gxw4LrApHsVJvn5fmjcPdmoUHaVKw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", + "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "browser-resolve": "^1.11.3", "chalk": "^2.0.1", "jest-pnp-resolver": "^1.2.1", @@ -3254,111 +3068,120 @@ } }, "jest-resolve-dependencies": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.8.0.tgz", - "integrity": "sha512-hyK1qfIf/krV+fSNyhyJeq3elVMhK9Eijlwy+j5jqmZ9QsxwKBiP6qukQxaHtK8k6zql/KYWwCTQ+fDGTIJauw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", + "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.8.0" + "jest-snapshot": "^24.9.0" } }, "jest-runner": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.8.0.tgz", - "integrity": "sha512-utFqC5BaA3JmznbissSs95X1ZF+d+4WuOWwpM9+Ak356YtMhHE/GXUondZdcyAAOTBEsRGAgH/0TwLzfI9h7ow==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", + "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", "dev": true, "requires": { "@jest/console": "^24.7.1", - "@jest/environment": "^24.8.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/environment": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "chalk": "^2.4.2", "exit": "^0.1.2", "graceful-fs": "^4.1.15", - "jest-config": "^24.8.0", + "jest-config": "^24.9.0", "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.8.0", - "jest-jasmine2": "^24.8.0", - "jest-leak-detector": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", - "jest-runtime": "^24.8.0", - "jest-util": "^24.8.0", + "jest-haste-map": "^24.9.0", + "jest-jasmine2": "^24.9.0", + "jest-leak-detector": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", + "jest-runtime": "^24.9.0", + "jest-util": "^24.9.0", "jest-worker": "^24.6.0", "source-map-support": "^0.5.6", "throat": "^4.0.0" } }, "jest-runtime": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.8.0.tgz", - "integrity": "sha512-Mq0aIXhvO/3bX44ccT+czU1/57IgOMyy80oM0XR/nyD5zgBcesF84BPabZi39pJVA6UXw+fY2Q1N+4BiVUBWOA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", + "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", "dev": true, "requires": { "@jest/console": "^24.7.1", - "@jest/environment": "^24.8.0", + "@jest/environment": "^24.9.0", "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/yargs": "^12.0.2", + "@jest/transform": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", "chalk": "^2.0.1", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.1.15", - "jest-config": "^24.8.0", - "jest-haste-map": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-mock": "^24.8.0", + "jest-config": "^24.9.0", + "jest-haste-map": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-mock": "^24.9.0", "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.8.0", - "jest-snapshot": "^24.8.0", - "jest-util": "^24.8.0", - "jest-validate": "^24.8.0", + "jest-resolve": "^24.9.0", + "jest-snapshot": "^24.9.0", + "jest-util": "^24.9.0", + "jest-validate": "^24.9.0", "realpath-native": "^1.1.0", "slash": "^2.0.0", "strip-bom": "^3.0.0", - "yargs": "^12.0.2" + "yargs": "^13.3.0" } }, "jest-serializer": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.4.0.tgz", - "integrity": "sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", + "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", "dev": true }, "jest-snapshot": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.8.0.tgz", - "integrity": "sha512-5ehtWoc8oU9/cAPe6fez6QofVJLBKyqkY2+TlKTOf0VllBB/mqUNdARdcjlZrs9F1Cv+/HKoCS/BknT0+tmfPg==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", + "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "chalk": "^2.0.1", - "expect": "^24.8.0", - "jest-diff": "^24.8.0", - "jest-matcher-utils": "^24.8.0", - "jest-message-util": "^24.8.0", - "jest-resolve": "^24.8.0", + "expect": "^24.9.0", + "jest-diff": "^24.9.0", + "jest-get-type": "^24.9.0", + "jest-matcher-utils": "^24.9.0", + "jest-message-util": "^24.9.0", + "jest-resolve": "^24.9.0", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^24.8.0", - "semver": "^5.5.0" + "pretty-format": "^24.9.0", + "semver": "^6.2.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, "jest-util": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.8.0.tgz", - "integrity": "sha512-DYZeE+XyAnbNt0BG1OQqKy/4GVLPtzwGx5tsnDrFcax36rVE3lTA5fbvgmbVPUZf9w77AJ8otqR4VBbfFJkUZA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", + "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/fake-timers": "^24.8.0", - "@jest/source-map": "^24.3.0", - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", + "@jest/console": "^24.9.0", + "@jest/fake-timers": "^24.9.0", + "@jest/source-map": "^24.9.0", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", "callsites": "^3.0.0", "chalk": "^2.0.1", "graceful-fs": "^4.1.15", @@ -3377,41 +3200,41 @@ } }, "jest-validate": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.8.0.tgz", - "integrity": "sha512-+/N7VOEMW1Vzsrk3UWBDYTExTPwf68tavEPKDnJzrC6UlHtUDU/fuEdXqFoHzv9XnQ+zW6X3qMZhJ3YexfeLDA==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", + "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", "dev": true, "requires": { - "@jest/types": "^24.8.0", - "camelcase": "^5.0.0", + "@jest/types": "^24.9.0", + "camelcase": "^5.3.1", "chalk": "^2.0.1", - "jest-get-type": "^24.8.0", - "leven": "^2.1.0", - "pretty-format": "^24.8.0" + "jest-get-type": "^24.9.0", + "leven": "^3.1.0", + "pretty-format": "^24.9.0" } }, "jest-watcher": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.8.0.tgz", - "integrity": "sha512-SBjwHt5NedQoVu54M5GEx7cl7IGEFFznvd/HNT8ier7cCAx/Qgu9ZMlaTQkvK22G1YOpcWBLQPFSImmxdn3DAw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", + "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", "dev": true, "requires": { - "@jest/test-result": "^24.8.0", - "@jest/types": "^24.8.0", - "@types/yargs": "^12.0.9", + "@jest/test-result": "^24.9.0", + "@jest/types": "^24.9.0", + "@types/yargs": "^13.0.0", "ansi-escapes": "^3.0.0", "chalk": "^2.0.1", - "jest-util": "^24.8.0", + "jest-util": "^24.9.0", "string-length": "^2.0.0" } }, "jest-worker": { - "version": "24.6.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.6.0.tgz", - "integrity": "sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", + "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", "dev": true, "requires": { - "merge-stream": "^1.0.1", + "merge-stream": "^2.0.0", "supports-color": "^6.1.0" }, "dependencies": { @@ -3427,9 +3250,9 @@ } }, "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, "js-yaml": { @@ -3440,6 +3263,14 @@ "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } } }, "jsbn": { @@ -3513,9 +3344,9 @@ "dev": true }, "json5": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", - "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -3554,15 +3385,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, "left-pad": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", @@ -3570,9 +3392,9 @@ "dev": true }, "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, "levn": { @@ -3613,6 +3435,12 @@ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -3643,12 +3471,6 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true } } }, @@ -3667,15 +3489,6 @@ "tmpl": "1.0.x" } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", @@ -3691,25 +3504,11 @@ "object-visit": "^1.0.0" } }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, "merge-stream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", - "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true }, "micromatch": { "version": "3.1.10", @@ -3733,26 +3532,20 @@ } }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "version": "1.42.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", + "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", "dev": true }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.25", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", + "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", "dev": true, "requires": { - "mime-db": "1.40.0" + "mime-db": "1.42.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3807,15 +3600,15 @@ } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "nan": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz", - "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", "dev": true, "optional": true }, @@ -3869,9 +3662,9 @@ "dev": true }, "node-notifier": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", - "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", "dev": true, "requires": { "growly": "^1.3.0", @@ -3891,23 +3684,6 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true - }, - "resolve": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", - "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - } } }, "normalize-path": { @@ -3928,16 +3704,10 @@ "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nwsapi": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, "oauth-sign": { @@ -3977,10 +3747,16 @@ } } }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, "object-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.0.tgz", - "integrity": "sha512-6OO5X1+2tYkNyNEx6TsCxEqFfRWaqx6EtMiSbGrw8Ob8v9Ne+Hl8rBAgLBZn5wjEz3s/s6U1WXFUFOcxxAwUpg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, "object-visit": { @@ -4039,36 +3815,17 @@ } }, "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", + "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - }, - "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - } - } - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" + "word-wrap": "~1.2.3" } }, "os-tmpdir": { @@ -4077,12 +3834,6 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, "p-each-series": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", @@ -4098,16 +3849,10 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", + "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4129,9 +3874,9 @@ "dev": true }, "p-try": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", - "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-json": { @@ -4237,51 +3982,37 @@ "dev": true }, "prettier": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", - "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "dev": true }, "pretty-format": { - "version": "24.8.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.8.0.tgz", - "integrity": "sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==", + "version": "24.9.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", + "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", "dev": true, "requires": { - "@jest/types": "^24.8.0", + "@jest/types": "^24.9.0", "ansi-regex": "^4.0.0", "ansi-styles": "^3.2.0", "react-is": "^16.8.4" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } } }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, "prompts": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.1.0.tgz", - "integrity": "sha512-+x5TozgqYdOwWsQFZizE/Tra3fKvAoy037kOyU6cgz84n8f6zxngLOV4O32kTwt9FcLCxAqw0P/c8rOr9y+Gfg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", + "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", "dev": true, "requires": { - "kleur": "^3.0.2", - "sisteransi": "^1.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.3" } }, "psl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz", - "integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", + "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", "dev": true }, "pump": { @@ -4307,9 +4038,9 @@ "dev": true }, "react-is": { - "version": "16.8.4", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.4.tgz", - "integrity": "sha512-PVadd+WaUDOAciICm/J1waJaSvgq+4rHE/K70j0PFqKhkTBsPv/82UGQJNXAngz1fOQLLxI6z1sEDmJDQhCTAA==", + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", "dev": true }, "read-pkg": { @@ -4333,21 +4064,6 @@ "read-pkg": "^3.0.0" } }, - "readable-stream": { - "version": "2.3.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, "readline-sync": { "version": "1.4.9", "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", @@ -4425,12 +4141,6 @@ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", - "dev": true - }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -4444,21 +4154,21 @@ } }, "request-promise-core": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", - "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", "dev": true, "requires": { - "lodash": "^4.17.11" + "lodash": "^4.17.15" } }, "request-promise-native": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", - "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", "dev": true, "requires": { - "request-promise-core": "1.1.2", + "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" } @@ -4470,15 +4180,15 @@ "dev": true }, "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", - "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", + "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", "requires": { "path-parse": "^1.0.6" } @@ -4511,24 +4221,24 @@ "dev": true }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } }, "rsvp": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.4.tgz", - "integrity": "sha512-6FomvYPfs+Jy9TfXmBpBuMWNH94SgCsZmJKcanySzgNNP6LjWxBvyLTa9KaMfDDM5oxRfrKDB0r/qeRsLwnBfA==", + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safe-regex": { @@ -4570,9 +4280,9 @@ "dev": true }, "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true }, "set-blocking": { @@ -4632,9 +4342,9 @@ "dev": true }, "sisteransi": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.2.tgz", - "integrity": "sha512-ZcYcZcT69nSLAR2oLN2JwNmLkJEKGooFMCdvOkFrToUt/WfcRWqhIg4P4KwY4dmLbuyXIx4o4YmPsvMRJYJd/w==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", + "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==", "dev": true }, "slash": { @@ -4659,15 +4369,6 @@ "use": "^3.1.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -4686,12 +4387,6 @@ "is-extendable": "^0.1.0" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4840,9 +4535,9 @@ } }, "spdx-license-ids": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "dev": true }, "split-string": { @@ -4920,6 +4615,12 @@ "strip-ansi": "^4.0.0" }, "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -4932,33 +4633,34 @@ } }, "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { + "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } + "strip-ansi": "^5.1.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" } }, "strip-ansi": { @@ -4968,14 +4670,6 @@ "dev": true, "requires": { "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } } }, "strip-bom": { @@ -5006,15 +4700,15 @@ "dev": true }, "test-exclude": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.1.0.tgz", - "integrity": "sha512-gwf0S2fFsANC55fSeSqpb8BYk6w3FDvwZxfNjeF6FRgvFa43r+7wRiA/Q0IxoRU37wB/LE8IQ4221BsNucTaCA==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", + "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { - "arrify": "^1.0.1", + "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", - "require-main-filename": "^1.0.1" + "require-main-filename": "^2.0.0" } }, "throat": { @@ -5105,22 +4799,17 @@ "punycode": "^2.1.0" } }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, "ts-jest": { - "version": "24.0.2", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.0.2.tgz", - "integrity": "sha512-h6ZCZiA1EQgjczxq+uGLXQlNgeg02WWJBbeT8j6nyIBRQdglqbvzDoHahTEIiS6Eor6x8mK6PfZ7brQ9Q6tzHw==", + "version": "24.2.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.2.0.tgz", + "integrity": "sha512-Yc+HLyldlIC9iIK8xEN7tV960Or56N49MDP7hubCZUeI7EbIOTsas6rXCMB4kQjLACJ7eDOF4xWEO5qumpKsag==", "dev": true, "requires": { "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", "json5": "2.x", + "lodash.memoize": "4.x", "make-error": "1.x", "mkdirp": "0.x", "resolve": "1.x", @@ -5146,19 +4835,16 @@ } }, "ts-node": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz", - "integrity": "sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==", + "version": "8.5.4", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", + "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", "dev": true, "requires": { - "arrify": "^1.0.0", - "buffer-from": "^1.1.0", - "diff": "^3.1.0", + "arg": "^4.1.0", + "diff": "^4.0.1", "make-error": "^1.1.1", - "minimist": "^1.2.0", - "mkdirp": "^0.5.1", "source-map-support": "^0.5.6", - "yn": "^2.0.0" + "yn": "^3.0.0" } }, "tslib": { @@ -5168,16 +4854,16 @@ "dev": true }, "tslint": { - "version": "5.17.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.17.0.tgz", - "integrity": "sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w==", + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "builtin-modules": "^1.1.1", "chalk": "^2.3.0", "commander": "^2.12.1", - "diff": "^3.2.0", + "diff": "^4.0.1", "glob": "^7.1.1", "js-yaml": "^3.13.1", "minimatch": "^3.0.4", @@ -5186,6 +4872,14 @@ "semver": "^5.3.0", "tslib": "^1.8.0", "tsutils": "^2.29.0" + }, + "dependencies": { + "diff": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", + "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "dev": true + } } }, "tsutils": { @@ -5222,14 +4916,14 @@ } }, "typescript": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.2.tgz", - "integrity": "sha512-lmQ4L+J6mnu3xweP8+rOrUwzmN+MRAj7TgtJtDaXE5PMyX2kCrklhg3rvOsOIfNeAWMQWO2F1GPc1kMD2vLAfw==" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==" }, "uglify-js": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.9.tgz", - "integrity": "sha512-pcnnhaoG6RtrvHJ1dFncAe8Od6Nuy30oaJ82ts6//sGSXOP5UjBMEthiProjXmMNHOfd93sqlkztifFMcb+4yw==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", + "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==", "dev": true, "optional": true, "requires": { @@ -5237,13 +4931,6 @@ "source-map": "~0.6.1" }, "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "optional": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -5332,12 +5019,6 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, "util.promisify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", @@ -5349,9 +5030,9 @@ } }, "uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", + "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, "validate-npm-package-license": { @@ -5440,6 +5121,12 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -5447,50 +5134,14 @@ "dev": true }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" } }, "wrappy": { @@ -5532,29 +5183,27 @@ "dev": true }, "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", "dev": true, "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", + "cliui": "^5.0.0", "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", + "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", + "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^2.0.0", + "string-width": "^3.0.0", "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" } }, "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -5562,9 +5211,9 @@ } }, "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true } } diff --git a/package.json b/package.json index b7c1f469a..1f58ae98a 100644 --- a/package.json +++ b/package.json @@ -39,24 +39,24 @@ "node": ">=8.5.0" }, "dependencies": { - "resolve": "^1.11.0", + "resolve": "^1.13.1", "source-map": "^0.7.3", - "typescript": "^3.6.2" + "typescript": "^3.7.3" }, "devDependencies": { "@types/fs-extra": "^8.0.1", "@types/glob": "^7.1.1", - "@types/jest": "^24.0.15", - "@types/node": "^11.13.14", + "@types/jest": "^24.0.23", + "@types/node": "^12.12.14", "@types/resolve": "0.0.8", "fengari": "^0.1.4", "fs-extra": "^8.1.0", - "javascript-stringify": "^2.0.0", - "jest": "^24.8.0", - "jest-circus": "^24.8.0", - "prettier": "^1.18.2", - "ts-jest": "^24.0.2", - "ts-node": "^7.0.1", - "tslint": "^5.17.0" + "javascript-stringify": "^2.0.1", + "jest": "^24.9.0", + "jest-circus": "^24.9.0", + "prettier": "^1.19.1", + "ts-jest": "^24.2.0", + "ts-node": "^8.5.4", + "tslint": "^5.20.1" } } diff --git a/src/Emit.ts b/src/Emit.ts index dd3208eb9..160ca49ff 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -19,7 +19,7 @@ export function emitTranspiledFiles( let { outDir, luaLibImport, luaBundle } = options; const rootDir = program.getCommonSourceDirectory(); - outDir = outDir || rootDir; + outDir = outDir ?? rootDir; const files: OutputFile[] = []; for (const { fileName, lua, sourceMap, declaration, declarationMap } of transpiledFiles) { @@ -54,7 +54,7 @@ export function emitTranspiledFiles( luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) ) { - const lualibRequired = files.some(f => f.text && f.text.includes(`require("lualib_bundle")`)); + const lualibRequired = files.some(f => f.text?.includes(`require("lualib_bundle")`)); if (lualibRequired) { if (lualibContent === undefined) { const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 2ef2310dd..10c7b44b3 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -186,7 +186,7 @@ export function setParent(node: Node | Node[] | undefined, parent: Node): void { } function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { - if (sourceNode !== undefined && sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { + if (sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition( sourceNode.getSourceFile(), sourceNode.pos + sourceNode.getLeadingTriviaWidth() @@ -901,12 +901,7 @@ export type FunctionDefinition = (VariableDeclarationStatement | AssignmentState export function isFunctionDefinition( statement: VariableDeclarationStatement | AssignmentStatement ): statement is FunctionDefinition { - return ( - statement.left.length === 1 && - statement.right !== undefined && - statement.right.length === 1 && - isFunctionExpression(statement.right[0]) - ); + return statement.left.length === 1 && statement.right?.length === 1 && isFunctionExpression(statement.right[0]); } export type InlineFunctionExpression = FunctionExpression & { @@ -915,8 +910,7 @@ export type InlineFunctionExpression = FunctionExpression & { export function isInlineFunctionExpression(expression: FunctionExpression): expression is InlineFunctionExpression { return ( - expression.body.statements !== undefined && - expression.body.statements.length === 1 && + expression.body.statements?.length === 1 && isReturnStatement(expression.body.statements[0]) && (expression.body.statements[0] as ReturnStatement).expressions !== undefined && (expression.flags & FunctionExpressionFlags.Inline) !== 0 diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 2d8a2ac20..38440698c 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -23,8 +23,7 @@ const escapeStringMap: Record = { "\0": "\\0", }; -export const escapeString = (value: string) => - `"${value.replace(escapeStringRegExp, char => escapeStringMap[char] || char)}"`; +export const escapeString = (value: string) => `"${value.replace(escapeStringRegExp, char => escapeStringMap[char])}"`; /** * Checks that a name is valid for use in lua function declaration syntax: @@ -198,7 +197,7 @@ export class LuaPrinter { header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`; } - const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Require; + const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if ( luaLibImport === LuaLibImportKind.Always || (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) @@ -341,11 +340,21 @@ export class LuaPrinter { // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion chunks.push(this.printFunctionDefinition(statement)); } else { - chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + statement.left.map(e => this.printExpression(e)) + ) + ); if (statement.right) { chunks.push(" = "); - chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + statement.right.map(e => this.printExpression(e)) + ) + ); } } @@ -369,9 +378,19 @@ export class LuaPrinter { } } - chunks.push(...this.joinChunks(", ", statement.left.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + statement.left.map(e => this.printExpression(e)) + ) + ); chunks.push(" = "); - chunks.push(...this.joinChunks(", ", statement.right.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + statement.right.map(e => this.printExpression(e)) + ) + ); return this.createSourceNode(statement, chunks); } @@ -458,8 +477,14 @@ export class LuaPrinter { } public printForInStatement(statement: lua.ForInStatement): SourceNode { - const names = this.joinChunks(", ", statement.names.map(i => this.printIdentifier(i))); - const expressions = this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e))); + const names = this.joinChunks( + ", ", + statement.names.map(i => this.printIdentifier(i)) + ); + const expressions = this.joinChunks( + ", ", + statement.expressions.map(e => this.printExpression(e)) + ); const chunks: SourceChunk[] = []; @@ -488,7 +513,12 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; - chunks.push(...this.joinChunks(", ", statement.expressions.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + statement.expressions.map(e => this.printExpression(e)) + ) + ); return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } @@ -588,7 +618,10 @@ export class LuaPrinter { chunks.push(" "); const returnNode: SourceChunk[] = [ "return ", - ...this.joinChunks(", ", returnStatement.expressions.map(e => this.printExpression(e))), + ...this.joinChunks( + ", ", + returnStatement.expressions.map(e => this.printExpression(e)) + ), ]; chunks.push(this.createSourceNode(returnStatement, returnNode)); chunks.push(this.createSourceNode(expression, " end")); @@ -780,7 +813,12 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; if (expressions.every(isSimpleExpression)) { - chunks.push(...this.joinChunks(", ", expressions.map(e => this.printExpression(e)))); + chunks.push( + ...this.joinChunks( + ", ", + expressions.map(e => this.printExpression(e)) + ) + ); } else { chunks.push("\n"); this.pushIndent(); diff --git a/src/TSTransformers.ts b/src/TSTransformers.ts index 710e3ac0e..a2b606465 100644 --- a/src/TSTransformers.ts +++ b/src/TSTransformers.ts @@ -20,8 +20,8 @@ export function getCustomTransformers( const transformersFromOptions = loadTransformersFromOptions(program, diagnostics); const afterDeclarations = [ - ...(transformersFromOptions.afterDeclarations || []), - ...(customTransformers.afterDeclarations || []), + ...(transformersFromOptions.afterDeclarations ?? []), + ...(customTransformers.afterDeclarations ?? []), ]; const options = program.getCompilerOptions() as CompilerOptions; @@ -32,11 +32,11 @@ export function getCustomTransformers( return { afterDeclarations, before: [ - ...(customTransformers.before || []), - ...(transformersFromOptions.before || []), + ...(customTransformers.before ?? []), + ...(transformersFromOptions.before ?? []), - ...(transformersFromOptions.after || []), - ...(customTransformers.after || []), + ...(transformersFromOptions.after ?? []), + ...(customTransformers.after ?? []), luaTransformer, ], }; @@ -197,7 +197,7 @@ function loadTransformer( } else { const isValidGroupTransformer = typeof transformer === "object" && - (transformer.before || transformer.after || transformer.afterDeclarations); + (transformer.before ?? transformer.after ?? transformer.afterDeclarations) !== undefined; if (!isValidGroupTransformer) { return { error: diagnosticFactories.transformerShouldBeATsTransformerFactory(transform) }; diff --git a/src/bundle.ts b/src/bundle.ts index 834be2c23..e0ea3249b 100644 --- a/src/bundle.ts +++ b/src/bundle.ts @@ -41,7 +41,7 @@ export function bundleTranspiledFiles( ); // If any of the modules contains a require for lualib_bundle, add it to the module table. - const lualibRequired = transpiledFiles.some(f => f.lua && f.lua.includes(`require("lualib_bundle")`)); + const lualibRequired = transpiledFiles.some(f => f.lua?.includes(`require("lualib_bundle")`)); if (lualibRequired) { const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); moduleTableEntries.push(`["lualib_bundle"] = function() ${lualibBundle} end,\n`); diff --git a/src/cli/information.ts b/src/cli/information.ts index df39c0ecd..08ffb12f4 100644 --- a/src/cli/information.ts +++ b/src/cli/information.ts @@ -19,7 +19,7 @@ export function getHelpString(): string { result += "Options:\n"; for (const option of optionDeclarations) { - const aliasStrings = (option.aliases || []).map(a => "-" + a); + const aliasStrings = (option.aliases ?? []).map(a => "-" + a); const optionString = aliasStrings.concat(["--" + option.name]).join("|"); const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index bafe16d2a..22ff84fa3 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; +import { assume } from "../../utils"; import { TransformationContext } from "../context"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { getIdentifierSymbolId } from "../utils/symbols"; @@ -60,8 +61,7 @@ export function transformBuiltinCallExpression( return; } - // TODO(TypeScript 3.7): assume - const propertyCall = node as PropertyCallExpression; + assume(node); // If the function being called is of type owner.func, get the type of owner const ownerType = context.checker.getTypeAtLocation(node.expression.expression); @@ -71,40 +71,40 @@ export function transformBuiltinCallExpression( const symbolName = symbol && symbol.name; switch (symbolName) { case "Console": - return transformConsoleCall(context, propertyCall); + return transformConsoleCall(context, node); case "Math": - return transformMathCall(context, propertyCall); + return transformMathCall(context, node); case "StringConstructor": - return transformStringConstructorCall(context, propertyCall); + return transformStringConstructorCall(context, node); case "ObjectConstructor": - return transformObjectConstructorCall(context, propertyCall); + return transformObjectConstructorCall(context, node); case "SymbolConstructor": - return transformSymbolConstructorCall(context, propertyCall); + return transformSymbolConstructorCall(context, node); case "NumberConstructor": - return transformNumberConstructorCall(context, propertyCall); + return transformNumberConstructorCall(context, node); } } if (isStringType(context, ownerType)) { - return transformStringPrototypeCall(context, propertyCall); + return transformStringPrototypeCall(context, node); } if (isNumberType(context, ownerType)) { - return transformNumberPrototypeCall(context, propertyCall); + return transformNumberPrototypeCall(context, node); } if (isArrayType(context, ownerType)) { - const result = transformArrayPrototypeCall(context, propertyCall); + const result = transformArrayPrototypeCall(context, node); if (result) { return result; } } if (isFunctionType(context, ownerType)) { - return transformFunctionPrototypeCall(context, propertyCall); + return transformFunctionPrototypeCall(context, node); } - const objectResult = transformObjectPrototypeCall(context, propertyCall); + const objectResult = transformObjectPrototypeCall(context, node); if (objectResult) { return objectResult; } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 9e5cdcfc9..5d9a7ef22 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -23,25 +23,24 @@ export class TransformationContext { public readonly resolver: EmitResolver; public readonly options: CompilerOptions = this.program.getCompilerOptions(); - public readonly luaTarget = this.options.luaTarget || LuaTarget.LuaJIT; + public readonly luaTarget = this.options.luaTarget ?? LuaTarget.LuaJIT; public readonly isModule = isFileModule(this.sourceFile); public readonly isStrict = - this.options.alwaysStrict !== undefined || - (this.options.strict !== undefined && this.options.alwaysStrict !== false) || + (this.options.alwaysStrict ?? this.options.strict) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); public constructor(public program: ts.Program, public sourceFile: ts.SourceFile, private visitorMap: VisitorMap) { // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` // and would try to re-analyze the file, which would fail because of replaced nodes. - const originalSourceFile = ts.getParseTreeNode(sourceFile, ts.isSourceFile) || sourceFile; + const originalSourceFile = ts.getParseTreeNode(sourceFile, ts.isSourceFile) ?? sourceFile; this.resolver = this.checker.getEmitResolver(originalSourceFile); } private currentNodeVisitors: Array> = []; public transformNode(node: ts.Node): lua.Node[] { // TODO: Move to visitors? - if (node.modifiers && node.modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { + if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { return []; } diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 198a0c9c7..a720a8ffd 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -34,7 +34,7 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { } for (const nodeVisitors of visitorMap.values()) { - nodeVisitors.sort((a, b) => (a.priority || 0) - (b.priority || 0)); + nodeVisitors.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0)); } return visitorMap; diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 509d67826..985a4ec26 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -102,7 +102,7 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment const jsDoc = sourceFile.statements[0].jsDoc; if (jsDoc) { - for (const tag of flatMap(jsDoc, x => x.tags || [])) { + for (const tag of flatMap(jsDoc, x => x.tags ?? [])) { const tagName = tag.tagName.text; const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); if (annotation) { diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index 91f684ecb..5d7d74c91 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -6,8 +6,8 @@ import { createExportsIdentifier } from "./lua-ast"; import { getSymbolInfo } from "./symbols"; import { findFirstNodeAbove, isFileModule } from "./typescript"; -export function hasDefaultExportModifier({ modifiers }: ts.Node): boolean { - return modifiers !== undefined && modifiers.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); +export function hasDefaultExportModifier(node: ts.Node): boolean { + return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); } export const createDefaultExportIdentifier = (original: ts.Node): lua.Identifier => diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index ca8f27aa8..84f19d17a 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -129,7 +129,7 @@ function getSignatureDeclarations( export function getFunctionContextType(context: TransformationContext, type: ts.Type): ContextType { if (type.isTypeParameter()) { - type = type.getConstraint() || type; + type = type.getConstraint() ?? type; } if (type.isUnion()) { diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 5473650b7..6043a4c07 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -145,7 +145,7 @@ export function createLocalOrExportedOrGlobalDeclaration( return []; } - const exportScope = overrideExportScope || getIdentifierExportScope(context, identifiers[0]); + const exportScope = overrideExportScope ?? getIdentifierExportScope(context, identifiers[0]); if (exportScope) { // exported if (!rhs) { @@ -218,7 +218,7 @@ export function createLocalOrExportedOrGlobalDeclaration( if (functionSymbolId && scope.functionDefinitions) { const definitions = scope.functionDefinitions.get(functionSymbolId); if (definitions) { - definitions.definition = declaration || assignment; + definitions.definition = declaration ?? assignment; } } } diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 31aa9a9fd..5077bcc42 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -78,7 +78,7 @@ export function findScope(context: TransformationContext, scopeTypes: ScopeType) const scopeIdCounters = new WeakMap(); export function pushScope(context: TransformationContext, scopeType: ScopeType): void { - const nextScopeId = (scopeIdCounters.get(context) || 0) + 1; + const nextScopeId = (scopeIdCounters.get(context) ?? 0) + 1; scopeIdCounters.set(context, nextScopeId); const scopeStack = getScopeStack(context); diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index 310c09453..a08197c72 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -8,7 +8,7 @@ import { getFirstDeclarationInFile } from "./typescript"; const symbolIdCounters = new WeakMap(); function nextSymbolId(context: TransformationContext): lua.SymbolId { - const symbolId = (symbolIdCounters.get(context) || 0) + 1; + const symbolId = (symbolIdCounters.get(context) ?? 0) + 1; symbolIdCounters.set(context, symbolId); return symbolId as lua.SymbolId; } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 7007beaaa..b6b5e6a1a 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -43,7 +43,7 @@ export function findFirstNodeAbove(node: ts.Node, callback: ( } export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { - const declarations = (symbol.getDeclarations() || []).filter( + const declarations = (symbol.getDeclarations() ?? []).filter( // TODO: getSourceFile? declaration => findFirstNodeAbove(declaration, ts.isSourceFile) === sourceFile ); @@ -86,7 +86,7 @@ export function isStandardLibraryType( } export function inferAssignedType(context: TransformationContext, expression: ts.Expression): ts.Type { - return context.checker.getContextualType(expression) || context.checker.getTypeAtLocation(expression); + return context.checker.getContextualType(expression) ?? context.checker.getTypeAtLocation(expression); } export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 2252e18d7..b6bea5bbb 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -65,7 +65,7 @@ function forTypeOrAnySupertype( type = context.checker.getDeclaredTypeOfSymbol(type.symbol); } - return (type.getBaseTypes() || []).some(superType => forTypeOrAnySupertype(context, superType, predicate)); + return (type.getBaseTypes() ?? []).some(superType => forTypeOrAnySupertype(context, superType, predicate)); } export function isArrayType(context: TransformationContext, type: ts.Type): boolean { diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index b810bc9f8..70340fbeb 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -49,7 +49,7 @@ const compoundToAssignmentTokens: Record - (compoundToAssignmentTokens as any)[token] !== undefined; + token in compoundToAssignmentTokens; export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator) => compoundToAssignmentTokens[token]; diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index c2cf8f95a..87b91e235 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -40,7 +40,7 @@ export function transformClassInstanceFields( getterName, lua.createNilLiteral(), ]), - classDeclaration.members.find(ts.isConstructorDeclaration) || classDeclaration + classDeclaration.members.find(ts.isConstructorDeclaration) ?? classDeclaration ); statements.push(resetGetter); } diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index a35cad983..06236c39e 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -77,7 +77,7 @@ export const transformNewExpression: FunctionVisitor = (node, return lua.createCallExpression( lua.createIdentifier(customConstructorAnnotation.args[0]), - transformArguments(context, node.arguments || []), + transformArguments(context, node.arguments ?? []), node ); } diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 45dec19cf..b75d1855b 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -3,7 +3,7 @@ import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; export function isStaticNode(node: ts.Node): boolean { - return node.modifiers !== undefined && node.modifiers.some(m => m.kind === ts.SyntaxKind.StaticKeyword); + return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); } export function getExtendedTypeNode( diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index f8d06c6ed..c41e4aff7 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -26,8 +26,10 @@ export const transformTryStatement: FunctionVisitor = (statemen let [catchBlock, catchScope] = transformScopeBlock(context, statement.catchClause.block, ScopeType.Catch); if (statement.catchClause.variableDeclaration) { // Replace ____returned with catch variable - returnedIdentifier = transformIdentifier(context, statement.catchClause.variableDeclaration - .name as ts.Identifier); + returnedIdentifier = transformIdentifier( + context, + statement.catchClause.variableDeclaration.name as ts.Identifier + ); } else if (tryScope.functionReturned || catchScope.functionReturned) { returnedIdentifier = lua.createIdentifier("____returned"); } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 10e3dbea3..070097db9 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -276,7 +276,7 @@ export const transformFunctionDeclaration: FunctionVisitor( export function assertNever(_value: never): never { throw new Error("Value is expected to be never"); } + +export function assume(_value: any): asserts _value is T {} diff --git a/test/setup.ts b/test/setup.ts index dff900cb9..8305ec264 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -3,7 +3,7 @@ import * as util from "./util"; declare global { namespace jest { - interface Matchers { + interface Matchers { toThrowExactError(error: Error): R; toHaveDiagnostics(): R; } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 56d144e02..6c439a920 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -144,16 +144,17 @@ describe("array.length", () => { }); describe("set", () => { - test.each([{ length: 0, newLength: 0 }, { length: 1, newLength: 1 }, { length: 7, newLength: 3 }])( - "removes extra elements", - ({ length, newLength }) => { - util.testFunction` - const array = [1, 2, 3]; - array.length = ${length}; - return array.length; - `.expectToEqual(newLength); - } - ); + test.each([ + { length: 0, newLength: 0 }, + { length: 1, newLength: 1 }, + { length: 7, newLength: 3 }, + ])("removes extra elements", ({ length, newLength }) => { + util.testFunction` + const array = [1, 2, 3]; + array.length = ${length}; + return array.length; + `.expectToEqual(newLength); + }); test.each([0, 1, 7])("returns right-hand side value", length => { util.testExpression`[1, 2, 3].length = ${length}`.expectToEqual(length); @@ -422,17 +423,17 @@ test.each([{ args: [1] }, { args: [1, 2, 3] }])("array.push (%p)", ({ args }) => `.expectToMatchJsResult(); }); -// tslint:disable-next-line: no-null-keyword -test.each([{ array: [1, 2, 3], expected: [3, 2] }, { array: [1, 2, 3, null], expected: [3, 2] }])( - "array.pop (%p)", - ({ array, expected }) => { - util.testFunction` - const array = ${util.formatCode(array)}; - const value = array.pop(); - return [value, array.length]; - `.expectToEqual(expected); - } -); +test.each([ + { array: [1, 2, 3], expected: [3, 2] }, + // tslint:disable-next-line: no-null-keyword + { array: [1, 2, 3, null], expected: [3, 2] }, +])("array.pop (%p)", ({ array, expected }) => { + util.testFunction` + const array = ${util.formatCode(array)}; + const value = array.pop(); + return [value, array.length]; + `.expectToEqual(expected); +}); test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { array: [] }])( "array.reverse (%p)", diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 7f92a2805..7ecf860c7 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -64,12 +64,15 @@ test.each([ util.testExpression`"${inp}".replace(${util.formatCode(searchValue, replaceValue)})`.expectToMatchJsResult(); }); -test.each([["", ""], ["hello", "test"], ["hello", "test", "bye"], ["hello", 42], [42, "hello"]])( - "string.concat[+] (%p)", - (...elements) => { - util.testExpression(elements.map(e => util.formatCode(e)).join(" + ")).expectToMatchJsResult(); - } -); +test.each([ + ["", ""], + ["hello", "test"], + ["hello", "test", "bye"], + ["hello", 42], + [42, "hello"], +])("string.concat[+] (%p)", (...elements) => { + util.testExpression(elements.map(e => util.formatCode(e)).join(" + ")).expectToMatchJsResult(); +}); test.each([ { str: "", args: ["", ""] }, @@ -99,12 +102,12 @@ test.each([ util.testExpressionTemplate`${inp}.indexOf(${searchValue}, ${offset})`.expectToMatchJsResult(); }); -test.each([{ inp: "hello test", searchValue: "t", x: 4, y: 3 }, { inp: "hello test", searchValue: "h", x: 3, y: 4 }])( - "string.indexOf with offset expression (%p)", - ({ inp, searchValue, x, y }) => { - util.testExpressionTemplate`${inp}.indexOf(${searchValue}, 2 > 1 && ${x} || ${y})`.expectToMatchJsResult(); - } -); +test.each([ + { inp: "hello test", searchValue: "t", x: 4, y: 3 }, + { inp: "hello test", searchValue: "h", x: 3, y: 4 }, +])("string.indexOf with offset expression (%p)", ({ inp, searchValue, x, y }) => { + util.testExpressionTemplate`${inp}.indexOf(${searchValue}, 2 > 1 && ${x} || ${y})`.expectToMatchJsResult(); +}); test.each([ { inp: "hello test", args: [] }, @@ -125,13 +128,13 @@ test.each([ util.testExpression`"${inp}".substring(${util.formatCode(...args)})`.expectToMatchJsResult(); }); -test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 5 }])( - "string.substring with expression (%p)", - ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - util.testExpression`"${inp}".substring(${paramStr})`.expectToMatchJsResult(); - } -); +test.each([ + { inp: "hello test", start: 1, ignored: 0 }, + { inp: "hello test", start: 3, ignored: 0, end: 5 }, +])("string.substring with expression (%p)", ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + util.testExpression`"${inp}".substring(${paramStr})`.expectToMatchJsResult(); +}); test.each([ { inp: "hello test", args: [0] }, @@ -142,15 +145,15 @@ test.each([ util.testExpression`"${inp}".substr(${util.formatCode(...args)})`.expectToMatchJsResult(); }); -test.each([{ inp: "hello test", start: 1, ignored: 0 }, { inp: "hello test", start: 3, ignored: 0, end: 2 }])( - "string.substr with expression (%p)", - ({ inp, start, ignored, end }) => { - const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); +test.each([ + { inp: "hello test", start: 1, ignored: 0 }, + { inp: "hello test", start: 3, ignored: 0, end: 2 }, +])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { + const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); + const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - expect(result).toBe(inp.substr(start, end)); - } -); + expect(result).toBe(inp.substr(start, end)); +}); test.each(["", "h", "hello"])("string.length (%p)", input => { util.testExpressionTemplate`${input}.length`.expectToMatchJsResult(); @@ -185,12 +188,13 @@ test.each([ util.testExpressionTemplate`${inp}.charAt(${index})`.expectToMatchJsResult(); }); -test.each([{ inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }])( - "string.charCodeAt (%p)", - ({ inp, index }) => { - util.testExpressionTemplate`${inp}.charCodeAt(${index})`.expectToMatchJsResult(); - } -); +test.each([ + { inp: "hello test", index: 1 }, + { inp: "hello test", index: 2 }, + { inp: "hello test", index: 3 }, +])("string.charCodeAt (%p)", ({ inp, index }) => { + util.testExpressionTemplate`${inp}.charCodeAt(${index})`.expectToMatchJsResult(); +}); test.each([ { inp: "hello test", index: 1, ignored: 0 }, diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index cfb1451aa..d2155ce18 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -730,19 +730,19 @@ test("Exported class super call", () => { expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("bar"); }); -test.each([{ input: "(new Foo())", expectResult: "foo" }, { input: "Foo", expectResult: "bar" }])( - "Class method name collision (%p)", - ({ input, expectResult }) => { - const code = ` - class Foo { - public method() { return "foo"; } - public static method() { return "bar"; } - } - return ${input}.method(); - `; - expect(util.transpileAndExecute(code)).toBe(expectResult); - } -); +test.each([ + { input: "(new Foo())", expectResult: "foo" }, + { input: "Foo", expectResult: "bar" }, +])("Class method name collision (%p)", ({ input, expectResult }) => { + const code = ` + class Foo { + public method() { return "foo"; } + public static method() { return "bar"; } + } + return ${input}.method(); + `; + expect(util.transpileAndExecute(code)).toBe(expectResult); +}); test("Class static instance of self", () => { const code = ` diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 9cc7bb468..c9553f96e 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -237,26 +237,26 @@ test("Object method declaration", () => { `.expectToMatchJsResult(); }); -test.each([{ args: ["bar"], expected: "foobar" }, { args: ["baz", "bar"], expected: "bazbar" }])( - "Function overload (%p)", - ({ args, expected }) => { - util.testFunction` - class O { - prop = "foo"; - method(s: string): string; - method(this: void, s1: string, s2: string): string; - method(s1: string) { - if (typeof this === "string") { - return this + s1; - } - return this.prop + s1; +test.each([ + { args: ["bar"], expected: "foobar" }, + { args: ["baz", "bar"], expected: "bazbar" }, +])("Function overload (%p)", ({ args, expected }) => { + util.testFunction` + class O { + prop = "foo"; + method(s: string): string; + method(this: void, s1: string, s2: string): string; + method(s1: string) { + if (typeof this === "string") { + return this + s1; } - }; - const o = new O(); - return o.method(${util.formatCode(...args)}); - `.expectToEqual(expected); - } -); + return this.prop + s1; + } + }; + const o = new O(); + return o.method(${util.formatCode(...args)}); + `.expectToEqual(expected); +}); test("Nested Function", () => { util.testFunction` @@ -276,7 +276,10 @@ test("Nested Function", () => { `.expectToMatchJsResult(); }); -test.each([{ s1: "abc", s2: "abc" }, { s1: "abc", s2: "def" }])("Dot vs Colon method call (%p)", ({ s1, s2 }) => { +test.each([ + { s1: "abc", s2: "abc" }, + { s1: "abc", s2: "def" }, +])("Dot vs Colon method call (%p)", ({ s1, s2 }) => { util.testFunction` class MyClass { dotMethod(this: void, s: string) { diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 19dce6516..e8ee28947 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -116,10 +116,11 @@ test.each([ expect(result).toBe(expectResult); }); -test.each([{ initializer: "", expectResult: "foofoo" }, { initializer: ' = "bar"', expectResult: "barbar" }])( - "Var hoisting from child scope (%p)", - ({ initializer, expectResult }) => { - const code = ` +test.each([ + { initializer: "", expectResult: "foofoo" }, + { initializer: ' = "bar"', expectResult: "barbar" }, +])("Var hoisting from child scope (%p)", ({ initializer, expectResult }) => { + const code = ` foo = "foo"; let result: string; if (true) { @@ -128,10 +129,9 @@ test.each([{ initializer: "", expectResult: "foofoo" }, { initializer: ' = "bar" } return foo + result; `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); - } -); + const result = util.transpileAndExecute(code); + expect(result).toBe(expectResult); +}); test("Hoisting due to reference from hoisted function", () => { const code = ` diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index fe5ce7461..6e67074d3 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -301,7 +301,16 @@ test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof existing variable (% expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])("forof destructing (%p)", ({ inp, expected }) => { +test.each([ + { + inp: [ + [1, 2], + [2, 3], + [3, 4], + ], + expected: [3, 5, 7], + }, +])("forof destructing (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( `let objTest = ${JSON.stringify(inp)}; let arrResultTest = []; @@ -314,23 +323,29 @@ test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])("forof destr expect(result).toBe(JSON.stringify(expected)); }); -test.each([{ inp: [[1, 2], [2, 3], [3, 4]], expected: [3, 5, 7] }])( - "forof destructing with existing variables (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; - let arrResultTest = []; - let a: number; - let b: number; - for ([a,b] of objTest) { - arrResultTest.push(a + b) - } - return JSONStringify(arrResultTest);` - ); +test.each([ + { + inp: [ + [1, 2], + [2, 3], + [3, 4], + ], + expected: [3, 5, 7], + }, +])("forof destructing with existing variables (%p)", ({ inp, expected }) => { + const result = util.transpileAndExecute(` + let objTest = ${JSON.stringify(inp)}; + let arrResultTest = []; + let a: number; + let b: number; + for ([a,b] of objTest) { + arrResultTest.push(a + b) + } + return JSONStringify(arrResultTest); + `); - expect(result).toBe(JSON.stringify(expected)); - } -); + expect(result).toBe(JSON.stringify(expected)); +}); test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])("forof with continue (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( diff --git a/test/unit/transformers/utils.ts b/test/unit/transformers/utils.ts index 603248dc3..3e1503ba0 100644 --- a/test/unit/transformers/utils.ts +++ b/test/unit/transformers/utils.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; export function visitAndReplace(context: ts.TransformationContext, node: T, visitor: ts.Visitor): T { - const visit: ts.Visitor = node => visitor(node) || ts.visitEachChild(node, visit, context); + const visit: ts.Visitor = node => visitor(node) ?? ts.visitEachChild(node, visit, context); return ts.visitNode(node, visit); } diff --git a/test/util.ts b/test/util.ts index ef7c8c4bd..6ca57509b 100644 --- a/test/util.ts +++ b/test/util.ts @@ -476,9 +476,7 @@ const createTestBuilderFactory = ( substitutions = substitutions.map(s => formatCode(s)); } - tsCode = template - .map((chunk, index) => (substitutions[index - 1] !== undefined ? substitutions[index - 1] : "") + chunk) - .join(""); + tsCode = template.map((chunk, index) => (substitutions[index - 1] ?? "") + chunk).join(""); } return new builder(tsCode); From 45ea0134ff499de6f3877b340c8d76c4f0851655 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 8 Dec 2019 20:29:59 +0500 Subject: [PATCH 199/764] Move `new` operator and some class setup boilerplate to lualib (#759) * Move `new` utility to lualib * Move some class setup boilerplate to lualib * Fix failing tests * Remove duplicated `@tupleReturn` tests * Move `Class.prototype.__index = Class.prototype` to helper * Add helper call to sourcemap tests --- src/LuaLib.ts | 4 +- src/lualib/Class.ts | 8 ++ src/lualib/New.ts | 5 + src/lualib/declarations/tstl.d.ts | 2 + src/transformation/utils/errors.ts | 3 - src/transformation/utils/lualib.ts | 2 +- src/transformation/visitors/class/index.ts | 24 +--- src/transformation/visitors/class/new.ts | 4 +- src/transformation/visitors/class/setup.ts | 107 +++--------------- .../__snapshots__/transformation.spec.ts.snap | 52 ++------- test/unit/classes/classes.spec.ts | 42 ------- test/unit/decorators/tupleReturn.spec.ts | 102 +---------------- test/unit/printer/sourcemaps.spec.ts | 7 +- 13 files changed, 54 insertions(+), 308 deletions(-) create mode 100644 src/lualib/Class.ts create mode 100644 src/lualib/New.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index b50ab1e75..b7e8c2a6b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -24,6 +24,7 @@ export enum LuaLibFeature { ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", + Class = "Class", ClassIndex = "ClassIndex", ClassNewIndex = "ClassNewIndex", Decorate = "Decorate", @@ -36,6 +37,7 @@ export enum LuaLibFeature { InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", Map = "Map", + New = "New", NewIndex = "NewIndex", Number = "Number", NumberIsFinite = "NumberIsFinite", @@ -67,7 +69,7 @@ export enum LuaLibFeature { const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], - Error: [LuaLibFeature.FunctionCall], + Error: [LuaLibFeature.New, LuaLibFeature.FunctionCall], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/lualib/Class.ts b/src/lualib/Class.ts new file mode 100644 index 000000000..14aa98587 --- /dev/null +++ b/src/lualib/Class.ts @@ -0,0 +1,8 @@ +function __TS__Class(): LuaClass { + const c = {} as LuaClass; + c.__index = c; + c.prototype = {}; + c.prototype.__index = c.prototype; + c.prototype.constructor = c; + return c; +} diff --git a/src/lualib/New.ts b/src/lualib/New.ts new file mode 100644 index 000000000..47e25694d --- /dev/null +++ b/src/lualib/New.ts @@ -0,0 +1,5 @@ +function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { + const instance: any = setmetatable({}, target.prototype); + instance.____constructor(...args); + return instance; +} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 7a7a8bf4f..9216870f2 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -11,10 +11,12 @@ interface LuaClass { ____super?: LuaClass; ____getters?: { [key: string]: (self: LuaClass) => any }; ____setters?: { [key: string]: (self: LuaClass, val: any) => void }; + __index?: any; } interface LuaObject { constructor: LuaClass; ____getters?: { [key: string]: (self: LuaObject) => any }; ____setters?: { [key: string]: (self: LuaObject, val: any) => void }; + __index?: any; } diff --git a/src/transformation/utils/errors.ts b/src/transformation/utils/errors.ts index ea741e967..bb3f3ce79 100644 --- a/src/transformation/utils/errors.ts +++ b/src/transformation/utils/errors.ts @@ -51,9 +51,6 @@ export const InvalidInstanceOfExtension = (node: ts.Node) => export const InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); -export const ForbiddenStaticClassPropertyName = (node: ts.Node, name: string) => - new TranspileError(`Cannot use "${name}" as a static class property or method name.`, node); - export const MissingClassName = (node: ts.Node) => new TranspileError(`Class declarations must have a name.`, node); export const MissingForOfVariables = (node: ts.Node) => diff --git a/src/transformation/utils/lualib.ts b/src/transformation/utils/lualib.ts index 583887c7a..3c2d0ec1b 100644 --- a/src/transformation/utils/lualib.ts +++ b/src/transformation/utils/lualib.ts @@ -18,7 +18,7 @@ export function importLuaLibFeature(context: TransformationContext, feature: Lua export function transformLuaLibFunction( context: TransformationContext, feature: LuaLibFeature, - tsParent?: ts.Expression, + tsParent?: ts.Node, ...params: lua.Expression[] ): lua.CallExpression { importLuaLibFeature(context, feature); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 6f4192182..e9c8c108c 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -5,7 +5,6 @@ import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { ForbiddenLuaTableNonDeclaration, - ForbiddenStaticClassPropertyName, InvalidExportsExtension, InvalidExtendsExtension, InvalidExtendsLuaTable, @@ -80,16 +79,13 @@ export function transformClassDeclaration( } else if (classDeclaration.name !== undefined) { className = transformIdentifier(context, classDeclaration.name); classNameText = classDeclaration.name.text; + } else if (hasDefaultExportModifier(classDeclaration)) { + const left = createExportedIdentifier(context, createDefaultExportIdentifier(classDeclaration)); + const right = transformClassAsExpression(classDeclaration, context, true); + + return lua.createAssignmentStatement(left, right, classDeclaration); } else { - const isDefaultExport = hasDefaultExportModifier(classDeclaration); - if (isDefaultExport) { - const left = createExportedIdentifier(context, createDefaultExportIdentifier(classDeclaration)); - const right = transformClassAsExpression(classDeclaration, context, true); - - return lua.createAssignmentStatement(left, right, classDeclaration); - } else { - throw MissingClassName(classDeclaration); - } + throw MissingClassName(classDeclaration); } const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(classDeclaration)); @@ -136,14 +132,6 @@ export function transformClassDeclaration( throw ForbiddenLuaTableNonDeclaration(classDeclaration); } - for (const member of classDeclaration.members) { - if (member.name && (ts.isStringLiteral(member.name) || ts.isIdentifier(member.name))) { - if (isStaticNode(member) && member.name.text === "new") { - throw ForbiddenStaticClassPropertyName(member, member.name.text); - } - } - } - // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 06236c39e..f83329b7a 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { InvalidAnnotationArgumentNumber, InvalidNewExpressionOnExtension } from "../../utils/errors"; -import { importLuaLibFeature, LuaLibFeature } from "../../utils/lualib"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { transformLuaTableNewExpression } from "../lua-table"; @@ -82,5 +82,5 @@ export const transformNewExpression: FunctionVisitor = (node, ); } - return lua.createCallExpression(lua.createTableIndexExpression(name, lua.createStringLiteral("new")), params, node); + return transformLuaLibFunction(context, LuaLibFeature.New, node, name, ...params); }; diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts index 5c136d756..2a4a1c8d0 100644 --- a/src/transformation/visitors/class/setup.ts +++ b/src/transformation/visitors/class/setup.ts @@ -8,11 +8,7 @@ import { getIdentifierExportScope, hasDefaultExportModifier, } from "../../utils/export"; -import { - createExportsIdentifier, - createLocalOrExportedOrGlobalDeclaration, - createSelfIdentifier, -} from "../../utils/lua-ast"; +import { createExportsIdentifier, createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { hasMemberInClassOrAncestor } from "./members/accessors"; import { getExtendedTypeNode, isStaticNode } from "./utils"; @@ -27,20 +23,19 @@ export function createClassSetup( ): lua.Statement[] { const result: lua.Statement[] = []; - // [____exports.]className = {} - const classTable: lua.Expression = lua.createTableExpression(); - - const isDefaultExport = hasDefaultExportModifier(statement); + // __TS__Class() + const classInitializer = transformLuaLibFunction(context, LuaLibFeature.Class, statement); - const defaultExportLeftHandSide = isDefaultExport + const defaultExportLeftHandSide = hasDefaultExportModifier(statement) ? lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(statement)) : undefined; - const classVar = defaultExportLeftHandSide - ? [lua.createAssignmentStatement(defaultExportLeftHandSide, classTable, statement)] - : createLocalOrExportedOrGlobalDeclaration(context, className, classTable, statement); - - result.push(...classVar); + // [____exports.]className = __TS__Class() + if (defaultExportLeftHandSide) { + result.push(lua.createAssignmentStatement(defaultExportLeftHandSide, classInitializer, statement)); + } else { + result.push(...createLocalOrExportedOrGlobalDeclaration(context, className, classInitializer, statement)); + } if (defaultExportLeftHandSide) { // local localClassName = ____exports.default @@ -79,14 +74,6 @@ export function createClassSetup( importLuaLibFeature(context, LuaLibFeature.ClassIndex); } - // localClassName.__index = localClassName - const classIndex = lua.createTableIndexExpression( - lua.cloneIdentifier(localClassName), - lua.createStringLiteral("__index") - ); - const assignClassIndex = lua.createAssignmentStatement(classIndex, lua.cloneIdentifier(localClassName), statement); - result.push(assignClassIndex); - // localClassName.____setters = {} if (statement.members.some(m => ts.isSetAccessor(m) && isStaticNode(m))) { const classSetters = lua.createTableIndexExpression( @@ -99,12 +86,9 @@ export function createClassSetup( importLuaLibFeature(context, LuaLibFeature.ClassNewIndex); } - // localClassName.prototype = {} + // localClassName.prototype const createClassPrototype = () => lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("prototype")); - const classPrototypeTable = lua.createTableExpression(); - const assignClassPrototype = lua.createAssignmentStatement(createClassPrototype(), classPrototypeTable, statement); - result.push(assignClassPrototype); // localClassName.prototype.____getters = {} if (statement.members.some(m => ts.isGetAccessor(m) && !isStaticNode(m))) { @@ -120,23 +104,15 @@ export function createClassSetup( result.push(assignClassPrototypeGetters); } - const classPrototypeIndex = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("__index") - ); if (hasMemberInClassOrAncestor(context, statement, m => ts.isGetAccessor(m) && !isStaticNode(m))) { // localClassName.prototype.__index = __TS__Index(localClassName.prototype) - const assignClassPrototypeIndex = lua.createAssignmentStatement( - classPrototypeIndex, - transformLuaLibFunction(context, LuaLibFeature.Index, undefined, createClassPrototype()), - statement + const classPrototypeIndex = lua.createTableIndexExpression( + createClassPrototype(), + lua.createStringLiteral("__index") ); - result.push(assignClassPrototypeIndex); - } else { - // localClassName.prototype.__index = localClassName.prototype const assignClassPrototypeIndex = lua.createAssignmentStatement( classPrototypeIndex, - createClassPrototype(), + transformLuaLibFunction(context, LuaLibFeature.Index, undefined, createClassPrototype()), statement ); result.push(assignClassPrototypeIndex); @@ -170,18 +146,6 @@ export function createClassSetup( result.push(assignClassPrototypeIndex); } - // localClassName.prototype.constructor = localClassName - const classPrototypeConstructor = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("constructor") - ); - const assignClassPrototypeConstructor = lua.createAssignmentStatement( - classPrototypeConstructor, - lua.cloneIdentifier(localClassName), - statement - ); - result.push(assignClassPrototypeConstructor); - const hasStaticGetters = hasMemberInClassOrAncestor( context, statement, @@ -303,46 +267,5 @@ export function createClassSetup( result.push(setClassMetatable); } - const newFuncStatements: lua.Statement[] = []; - - // local self = setmetatable({}, localClassName.prototype) - const assignSelf = lua.createVariableDeclarationStatement( - createSelfIdentifier(), - lua.createCallExpression(lua.createIdentifier("setmetatable"), [ - lua.createTableExpression(), - createClassPrototype(), - ]), - statement - ); - newFuncStatements.push(assignSelf); - - // self:____constructor(...) - const callConstructor = lua.createExpressionStatement( - lua.createMethodCallExpression(createSelfIdentifier(), lua.createIdentifier("____constructor"), [ - lua.createDotsLiteral(), - ]), - statement - ); - newFuncStatements.push(callConstructor); - - // return self - const returnSelf = lua.createReturnStatement([createSelfIdentifier()], statement); - newFuncStatements.push(returnSelf); - - // function localClassName.new(construct, ...) ... end - // or function export.localClassName.new(construct, ...) ... end - const newFunc = lua.createAssignmentStatement( - lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("new")), - lua.createFunctionExpression( - lua.createBlock(newFuncStatements), - undefined, - lua.createDotsLiteral(), - undefined, - lua.FunctionExpressionFlags.Declaration - ), - statement - ); - result.push(newFunc); - return result; } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 45f7a2d4a..55ad7a99c 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -40,17 +40,9 @@ end" `; exports[`Transformation (classPureAbstract) 1`] = ` -"ClassB = {} +"require(\\"lualib_bundle\\"); +ClassB = __TS__Class() ClassB.name = \\"ClassB\\" -ClassB.__index = ClassB -ClassB.prototype = {} -ClassB.prototype.__index = ClassB.prototype -ClassB.prototype.constructor = ClassB -function ClassB.new(...) - local self = setmetatable({}, ClassB.prototype) - self:____constructor(...) - return self -end function ClassB.prototype.____constructor(self) end" `; @@ -82,17 +74,9 @@ return ____exports" `; exports[`Transformation (methodRestArguments) 1`] = ` -"MyClass = {} +"require(\\"lualib_bundle\\"); +MyClass = __TS__Class() MyClass.name = \\"MyClass\\" -MyClass.__index = MyClass -MyClass.prototype = {} -MyClass.prototype.__index = MyClass.prototype -MyClass.prototype.constructor = MyClass -function MyClass.new(...) - local self = setmetatable({}, MyClass.prototype) - self:____constructor(...) - return self -end function MyClass.prototype.____constructor(self) end function MyClass.prototype.varargsFunction(self, a, ...) @@ -106,38 +90,22 @@ return ____exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"local ____exports = {} -____exports.TestClass = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} +____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass TestClass.name = \\"TestClass\\" -TestClass.__index = TestClass -TestClass.prototype = {} -TestClass.prototype.__index = TestClass.prototype -TestClass.prototype.constructor = TestClass -function TestClass.new(...) - local self = setmetatable({}, TestClass.prototype) - self:____constructor(...) - return self -end function TestClass.prototype.____constructor(self) end return ____exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"local ____exports = {} -____exports.TestClass = {} +"require(\\"lualib_bundle\\"); +local ____exports = {} +____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass TestClass.name = \\"TestClass\\" -TestClass.__index = TestClass -TestClass.prototype = {} -TestClass.prototype.__index = TestClass.prototype -TestClass.prototype.constructor = TestClass -function TestClass.new(...) - local self = setmetatable({}, TestClass.prototype) - self:____constructor(...) - return self -end function TestClass.prototype.____constructor(self) end function TestClass.prototype.memberFunc(self) diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index d2155ce18..12751fd40 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -1,5 +1,3 @@ -import * as ts from "typescript"; -import { ForbiddenStaticClassPropertyName } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; test("ClassFieldInitializer", () => { @@ -831,43 +829,3 @@ test("Class field override in subclass with constructors", () => { return (new Foo()).field + (new Bar()).field;`; expect(util.transpileAndExecute(code)).toBe("foobar"); }); - -test("Class cannot have static new method", () => { - const code = ` - class Foo { - static new() {} - }`; - expect(() => util.transpileAndExecute(code)).toThrow( - ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message - ); -}); - -test("Class cannot have static new property", () => { - const code = ` - class Foo { - static new = "foobar"; - }`; - expect(() => util.transpileAndExecute(code)).toThrow( - ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message - ); -}); - -test("Class cannot have static new get accessor", () => { - const code = ` - class Foo { - static get new() { return "foobar" } - }`; - expect(() => util.transpileAndExecute(code)).toThrow( - ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message - ); -}); - -test("Class cannot have static new set accessor", () => { - const code = ` - class Foo { - static set new(value: string) {} - }`; - expect(() => util.transpileAndExecute(code)).toThrow( - ForbiddenStaticClassPropertyName(ts.createEmptyStatement(), "new").message - ); -}); diff --git a/test/unit/decorators/tupleReturn.spec.ts b/test/unit/decorators/tupleReturn.spec.ts index 66df74aba..803acad4a 100644 --- a/test/unit/decorators/tupleReturn.spec.ts +++ b/test/unit/decorators/tupleReturn.spec.ts @@ -404,107 +404,7 @@ test("TupleReturn method assignment", () => { `; const lua = util.transpileString(code); - expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); -}); - -test("TupleReturn functional", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const [a, b] = abc(); - return b + a; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); - -test("TupleReturn single", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const res = abc(); - return res.length - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe(2); -}); - -test("TupleReturn in expression", () => { - const code = ` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - return abc()[1] + abc()[0]; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); -}); - -test("TupleReturn assignment", () => { - const code = ` - /** @tupleReturn */ - declare function abc(this: void): number[] - let [a,b] = abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = abc()"); -}); - -test("TupleReturn Single assignment", () => { - const code = ` - /** @tupleReturn */ - declare function abc(this: void): [number, string]; - let a = abc(); - a = abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); -}); - -test("TupleReturn interface assignment", () => { - const code = ` - interface def { - /** @tupleReturn */ - abc(); - } declare const jkl : def; - let [a,b] = jkl.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = jkl:abc()"); -}); - -test("TupleReturn namespace assignment", () => { - const code = ` - declare namespace def { - /** @tupleReturn */ - function abc(this: void) {} - } - let [a,b] = def.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = def.abc()"); -}); - -test("TupleReturn method assignment", () => { - const code = ` - declare class def { - /** @tupleReturn */ - abc() { return [1,2,3]; } - } const jkl = new def(); - let [a,b] = jkl.abc(); - `; - - const lua = util.transpileString(code); - expect(lua).toBe("local jkl = def.new()\nlocal a, b = jkl:abc()"); + expect(lua).toBe('require("lualib_bundle");\nlocal jkl = __TS__New(def)\nlocal a, b = jkl:abc()'); }); test("TupleReturn functional", () => { diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 4023dad19..918d430d1 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -84,16 +84,11 @@ test.each([ `, assertPatterns: [ - { luaPattern: "Bar = {}", typeScriptPattern: "class Bar" }, + { luaPattern: "Bar = __TS__Class()", typeScriptPattern: "class Bar" }, { luaPattern: "Bar.name =", typeScriptPattern: "class Bar" }, - { luaPattern: "Bar.__index =", typeScriptPattern: "class Bar" }, - { luaPattern: "Bar.prototype =", typeScriptPattern: "class Bar" }, - { luaPattern: "Bar.prototype.__index =", typeScriptPattern: "class Bar" }, - { luaPattern: "Bar.prototype.constructor =", typeScriptPattern: "class Bar" }, { luaPattern: "Bar.____super = Foo", typeScriptPattern: "Foo {" }, { luaPattern: "setmetatable(Bar,", typeScriptPattern: "Foo {" }, { luaPattern: "setmetatable(Bar.prototype,", typeScriptPattern: "Foo {" }, - { luaPattern: "function Bar.new", typeScriptPattern: "class Bar" }, { luaPattern: "function Bar.prototype.____constructor", typeScriptPattern: "constructor" }, ], }, From 105ff7bee4e7169edb9e0532ce4b9298acfbf1b1 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 8 Dec 2019 20:32:59 +0500 Subject: [PATCH 200/764] Move transpilation-related code to a subdirectory (#760) * Move transpilation-related code to a subdirectory * Move `lualib_bundle` loading to `LuaLib.ts` --- src/LuaLib.ts | 23 ++++- src/LuaPrinter.ts | 2 +- src/NoImplicitSelfTransformer.ts | 10 -- src/index.ts | 91 +------------------ src/{ => transpilation}/bundle.ts | 12 +-- src/{ => transpilation}/diagnostics.ts | 0 src/{Emit.ts => transpilation/emit.ts} | 19 +--- src/transpilation/index.ts | 90 ++++++++++++++++++ src/{ => transpilation}/plugins.ts | 4 +- .../transformers.ts} | 18 +++- .../transpile.ts} | 12 +-- test/unit/bundle.spec.ts | 2 +- 12 files changed, 146 insertions(+), 137 deletions(-) delete mode 100644 src/NoImplicitSelfTransformer.ts rename src/{ => transpilation}/bundle.ts (92%) rename src/{ => transpilation}/diagnostics.ts (100%) rename src/{Emit.ts => transpilation/emit.ts} (75%) create mode 100644 src/transpilation/index.ts rename src/{ => transpilation}/plugins.ts (86%) rename src/{TSTransformers.ts => transpilation/transformers.ts} (91%) rename src/{Transpile.ts => transpilation/transpile.ts} (94%) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index b7e8c2a6b..c3a5e0c61 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,5 +1,5 @@ import * as path from "path"; -import { EmitHost } from "./Transpile"; +import { EmitHost } from "./transpilation"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -95,12 +95,12 @@ export function loadLuaLibFeatures(features: Iterable, emitHost: dependencies.forEach(load); } - const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - const luaLibFeature = emitHost.readFile(featureFile); + const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); + const luaLibFeature = emitHost.readFile(featurePath); if (luaLibFeature !== undefined) { result += luaLibFeature + "\n"; } else { - throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`); + throw new Error(`Could not load lualib feature from '${featurePath}'`); } } @@ -110,3 +110,18 @@ export function loadLuaLibFeatures(features: Iterable, emitHost: return result; } + +let luaLibBundleContent: string; +export function getLuaLibBundle(emitHost: EmitHost): string { + if (luaLibBundleContent === undefined) { + const lualibPath = path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"); + const result = emitHost.readFile(lualibPath); + if (result !== undefined) { + luaLibBundleContent = result; + } else { + throw new Error(`Could not load lualib bundle from '${lualibPath}'`); + } + } + + return luaLibBundleContent; +} diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 38440698c..fda6e89ff 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -5,7 +5,7 @@ import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier, luaKeywords } from "./transformation/utils/safe-names"; -import { EmitHost } from "./Transpile"; +import { EmitHost } from "./transpilation"; import { trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html diff --git a/src/NoImplicitSelfTransformer.ts b/src/NoImplicitSelfTransformer.ts deleted file mode 100644 index 1b77c4070..000000000 --- a/src/NoImplicitSelfTransformer.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as ts from "typescript"; - -const transformSourceFile: ts.Transformer = node => { - const empty = ts.createNotEmittedStatement(undefined!); - ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); - return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); -}; - -export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => - ts.isBundle(node) ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) : transformSourceFile(node); diff --git a/src/index.ts b/src/index.ts index 7ed6e4ed0..8b0159a9c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,99 +1,10 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import { parseConfigFileWithSystem } from "./cli/tsconfig"; -import { CompilerOptions } from "./CompilerOptions"; -import { emitTranspiledFiles, OutputFile } from "./Emit"; -import { transpile, TranspiledFile, TranspileResult } from "./Transpile"; - export { version } from "./cli/information"; export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./cli/parse"; export * from "./cli/report"; export * from "./CompilerOptions"; -export * from "./Emit"; export * from "./LuaAST"; export { LuaLibFeature } from "./LuaLib"; export * from "./LuaPrinter"; export * from "./transformation/context"; export { TranspileError } from "./transformation/utils/errors"; -export * from "./Transpile"; - -export interface TranspileFilesResult { - diagnostics: ts.Diagnostic[]; - emitResult: OutputFile[]; -} - -export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult { - const program = ts.createProgram(rootNames, options); - const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); - const emitResult = emitTranspiledFiles(program, transpiledFiles); - - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...transpileDiagnostics, - ]); - - return { diagnostics: [...diagnostics], emitResult }; -} - -export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult { - const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend); - if (parseResult.errors.length > 0) { - return { diagnostics: parseResult.errors, emitResult: [] }; - } - - return transpileFiles(parseResult.fileNames, parseResult.options); -} - -const libCache: { [key: string]: ts.SourceFile } = {}; - -/** @internal */ -export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { - const compilerHost: ts.CompilerHost = { - fileExists: () => true, - getCanonicalFileName: fileName => fileName, - getCurrentDirectory: () => "", - getDefaultLibFileName: ts.getDefaultLibFileName, - readFile: () => "", - getNewLine: () => "\n", - useCaseSensitiveFileNames: () => false, - writeFile: () => {}, - - getSourceFile: filename => { - if (filename in input) { - return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); - } - - if (filename.startsWith("lib.")) { - if (libCache[filename]) return libCache[filename]; - const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, filename); - const content = fs.readFileSync(filePath, "utf8"); - - libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); - - return libCache[filename]; - } - }, - }; - - return ts.createProgram(Object.keys(input), options, compilerHost); -} - -export function transpileVirtualProject(files: Record, options: CompilerOptions = {}): TranspileResult { - const program = createVirtualProgram(files, options); - const result = transpile({ program }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]); - - return { ...result, diagnostics: [...diagnostics] }; -} - -export interface TranspileStringResult { - diagnostics: ts.Diagnostic[]; - file?: TranspiledFile; -} - -export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult { - const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); - return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") }; -} +export * from "./transpilation"; diff --git a/src/bundle.ts b/src/transpilation/bundle.ts similarity index 92% rename from src/bundle.ts rename to src/transpilation/bundle.ts index e0ea3249b..7c587055c 100644 --- a/src/bundle.ts +++ b/src/transpilation/bundle.ts @@ -1,11 +1,12 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions } from "./CompilerOptions"; +import { CompilerOptions } from "../CompilerOptions"; +import { getLuaLibBundle } from "../LuaLib"; +import { escapeString } from "../LuaPrinter"; +import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; -import { escapeString } from "./LuaPrinter"; -import { EmitHost, TranspiledFile } from "./Transpile"; -import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "./utils"; +import { EmitHost, TranspiledFile } from "./transpile"; const createModulePath = (baseDir: string, pathToResolve: string) => escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); @@ -43,8 +44,7 @@ export function bundleTranspiledFiles( // If any of the modules contains a require for lualib_bundle, add it to the module table. const lualibRequired = transpiledFiles.some(f => f.lua?.includes(`require("lualib_bundle")`)); if (lualibRequired) { - const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); - moduleTableEntries.push(`["lualib_bundle"] = function() ${lualibBundle} end,\n`); + moduleTableEntries.push(`["lualib_bundle"] = function() ${getLuaLibBundle(emitHost)} end,\n`); } // Create ____modules table containing all entries from moduleTableEntries diff --git a/src/diagnostics.ts b/src/transpilation/diagnostics.ts similarity index 100% rename from src/diagnostics.ts rename to src/transpilation/diagnostics.ts diff --git a/src/Emit.ts b/src/transpilation/emit.ts similarity index 75% rename from src/Emit.ts rename to src/transpilation/emit.ts index 160ca49ff..0b6cef269 100644 --- a/src/Emit.ts +++ b/src/transpilation/emit.ts @@ -1,15 +1,15 @@ import * as path from "path"; import * as ts from "typescript"; -import { LuaLibImportKind } from "./CompilerOptions"; -import { EmitHost, TranspiledFile } from "./Transpile"; -import { normalizeSlashes, trimExtension } from "./utils"; +import { LuaLibImportKind } from "../CompilerOptions"; +import { getLuaLibBundle } from "../LuaLib"; +import { normalizeSlashes, trimExtension } from "../utils"; +import { EmitHost, TranspiledFile } from "./transpile"; export interface OutputFile { name: string; text: string; } -let lualibContent: string; export function emitTranspiledFiles( program: ts.Program, transpiledFiles: TranspiledFile[], @@ -56,21 +56,12 @@ export function emitTranspiledFiles( ) { const lualibRequired = files.some(f => f.text?.includes(`require("lualib_bundle")`)); if (lualibRequired) { - if (lualibContent === undefined) { - const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); - if (lualibBundle !== undefined) { - lualibContent = lualibBundle; - } else { - throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua"); - } - } - let outPath = path.resolve(rootDir, "lualib_bundle.lua"); if (outDir !== rootDir) { outPath = path.join(outDir, path.relative(rootDir, outPath)); } - files.push({ name: normalizeSlashes(outPath), text: lualibContent }); + files.push({ name: normalizeSlashes(outPath), text: getLuaLibBundle(emitHost) }); } } diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts new file mode 100644 index 000000000..530fbdd4c --- /dev/null +++ b/src/transpilation/index.ts @@ -0,0 +1,90 @@ +import * as fs from "fs"; +import * as path from "path"; +import * as ts from "typescript"; +import { parseConfigFileWithSystem } from "../cli/tsconfig"; +import { CompilerOptions } from "../CompilerOptions"; +import { emitTranspiledFiles, OutputFile } from "./emit"; +import { transpile, TranspiledFile, TranspileResult } from "./transpile"; + +export * from "./emit"; +export * from "./transpile"; + +export interface TranspileFilesResult { + diagnostics: ts.Diagnostic[]; + emitResult: OutputFile[]; +} + +export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult { + const program = ts.createProgram(rootNames, options); + const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); + const emitResult = emitTranspiledFiles(program, transpiledFiles); + + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...transpileDiagnostics, + ]); + + return { diagnostics: [...diagnostics], emitResult }; +} + +export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult { + const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend); + if (parseResult.errors.length > 0) { + return { diagnostics: parseResult.errors, emitResult: [] }; + } + + return transpileFiles(parseResult.fileNames, parseResult.options); +} + +const libCache: { [key: string]: ts.SourceFile } = {}; + +/** @internal */ +export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { + const compilerHost: ts.CompilerHost = { + fileExists: () => true, + getCanonicalFileName: fileName => fileName, + getCurrentDirectory: () => "", + getDefaultLibFileName: ts.getDefaultLibFileName, + readFile: () => "", + getNewLine: () => "\n", + useCaseSensitiveFileNames: () => false, + writeFile: () => {}, + + getSourceFile: filename => { + if (filename in input) { + return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); + } + + if (filename.startsWith("lib.")) { + if (libCache[filename]) return libCache[filename]; + const typeScriptDir = path.dirname(require.resolve("typescript")); + const filePath = path.join(typeScriptDir, filename); + const content = fs.readFileSync(filePath, "utf8"); + + libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); + + return libCache[filename]; + } + }, + }; + + return ts.createProgram(Object.keys(input), options, compilerHost); +} + +export function transpileVirtualProject(files: Record, options: CompilerOptions = {}): TranspileResult { + const program = createVirtualProgram(files, options); + const result = transpile({ program }); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]); + + return { ...result, diagnostics: [...diagnostics] }; +} + +export interface TranspileStringResult { + diagnostics: ts.Diagnostic[]; + file?: TranspiledFile; +} + +export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult { + const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); + return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") }; +} diff --git a/src/plugins.ts b/src/transpilation/plugins.ts similarity index 86% rename from src/plugins.ts rename to src/transpilation/plugins.ts index ef2e07a1f..8731211d6 100644 --- a/src/plugins.ts +++ b/src/transpilation/plugins.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; -import { Printer } from "./LuaPrinter"; -import { Visitors } from "./transformation/context"; +import { Printer } from "../LuaPrinter"; +import { Visitors } from "../transformation/context"; export interface Plugin { /** diff --git a/src/TSTransformers.ts b/src/transpilation/transformers.ts similarity index 91% rename from src/TSTransformers.ts rename to src/transpilation/transformers.ts index a2b606465..71371e208 100644 --- a/src/TSTransformers.ts +++ b/src/transpilation/transformers.ts @@ -1,10 +1,22 @@ import * as path from "path"; import * as resolve from "resolve"; import * as ts from "typescript"; -import * as cliDiagnostics from "./cli/diagnostics"; -import { CompilerOptions, TransformerImport } from "./CompilerOptions"; +// TODO: Don't depend on CLI? +import * as cliDiagnostics from "../cli/diagnostics"; +import { CompilerOptions, TransformerImport } from "../CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; -import { noImplicitSelfTransformer } from "./NoImplicitSelfTransformer"; + +export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => { + const transformSourceFile: ts.Transformer = node => { + const empty = ts.createNotEmittedStatement(undefined!); + ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); + return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); + }; + + return ts.isBundle(node) + ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) + : transformSourceFile(node); +}; export function getCustomTransformers( program: ts.Program, diff --git a/src/Transpile.ts b/src/transpilation/transpile.ts similarity index 94% rename from src/Transpile.ts rename to src/transpilation/transpile.ts index 57326e404..df8214718 100644 --- a/src/Transpile.ts +++ b/src/transpilation/transpile.ts @@ -1,13 +1,13 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; +import { CompilerOptions, validateOptions } from "../CompilerOptions"; +import { Block } from "../LuaAST"; +import { createPrinter } from "../LuaPrinter"; +import { createVisitorMap, transformSourceFile } from "../transformation"; +import { isNonNull } from "../utils"; import { bundleTranspiledFiles } from "./bundle"; -import { CompilerOptions, validateOptions } from "./CompilerOptions"; -import { Block } from "./LuaAST"; -import { createPrinter } from "./LuaPrinter"; import { getPlugins, Plugin } from "./plugins"; -import { createVisitorMap, transformSourceFile } from "./transformation"; -import { getCustomTransformers } from "./TSTransformers"; -import { isNonNull } from "./utils"; +import { getCustomTransformers } from "./transformers"; export interface TranspiledFile { fileName: string; diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index 7bca27ae5..582b79177 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -2,7 +2,7 @@ import * as path from "path"; import * as ts from "typescript"; import { DiagnosticCategory } from "typescript"; import { LuaLibImportKind } from "../../src"; -import { couldNotFindBundleEntryPoint } from "../../src/diagnostics"; +import { couldNotFindBundleEntryPoint } from "../../src/transpilation/diagnostics"; import * as util from "../util"; test("no entry point", () => { From 3bd4333f994add15f3582bb5cf29e7c56f3d3a3e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Dec 2019 21:51:04 +0100 Subject: [PATCH 201/764] Transpile console.error/info/warn to regular print like console.log (#766) * Transpile console.error to regular print like console.log * Added console.info and console.warn too --- src/transformation/builtins/console.ts | 3 + .../__snapshots__/console.spec.ts.snap | 132 ++++++++++++++++++ test/unit/builtins/console.spec.ts | 36 +++++ 3 files changed, 171 insertions(+) diff --git a/src/transformation/builtins/console.ts b/src/transformation/builtins/console.ts index 23ab2b9be..988aba1b3 100644 --- a/src/transformation/builtins/console.ts +++ b/src/transformation/builtins/console.ts @@ -16,7 +16,10 @@ export function transformConsoleCall( const parameters = transformArguments(context, expression.arguments, signature); switch (methodName) { + case "error": + case "info": case "log": + case "warn": if (expression.arguments.length > 0 && isStringFormatTemplate(expression.arguments[0])) { // print(string.format([arguments])) const stringFormatCall = lua.createCallExpression( diff --git a/test/unit/builtins/__snapshots__/console.spec.ts.snap b/test/unit/builtins/__snapshots__/console.spec.ts.snap index 64baea0f4..f06d99dae 100644 --- a/test/unit/builtins/__snapshots__/console.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/console.spec.ts.snap @@ -46,6 +46,94 @@ end return ____exports" `; +exports[`console.error ("console.error()") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print() +end +return ____exports" +`; + +exports[`console.error ("console.error(\\"Hello %%s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %%s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.error ("console.error(\\"Hello %s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.error ("console.error(\\"Hello\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\") +end +return ____exports" +`; + +exports[`console.error ("console.error(\\"Hello\\", \\"There\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\", \\"There\\") +end +return ____exports" +`; + +exports[`console.info ("console.info()") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print() +end +return ____exports" +`; + +exports[`console.info ("console.info(\\"Hello %%s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %%s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.info ("console.info(\\"Hello %s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.info ("console.info(\\"Hello\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\") +end +return ____exports" +`; + +exports[`console.info ("console.info(\\"Hello\\", \\"There\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\", \\"There\\") +end +return ____exports" +`; + exports[`console.log ("console.log()") 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -143,3 +231,47 @@ function ____exports.__main(self) end return ____exports" `; + +exports[`console.warn ("console.warn()") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print() +end +return ____exports" +`; + +exports[`console.warn ("console.warn(\\"Hello %%s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %%s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.warn ("console.warn(\\"Hello %s\\", \\"there\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print( + string.format(\\"Hello %s\\", \\"there\\") + ) +end +return ____exports" +`; + +exports[`console.warn ("console.warn(\\"Hello\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\") +end +return ____exports" +`; + +exports[`console.warn ("console.warn(\\"Hello\\", \\"There\\")") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + print(\\"Hello\\", \\"There\\") +end +return ____exports" +`; diff --git a/test/unit/builtins/console.spec.ts b/test/unit/builtins/console.spec.ts index 7e7f68e9e..6cf4e6139 100644 --- a/test/unit/builtins/console.spec.ts +++ b/test/unit/builtins/console.spec.ts @@ -14,6 +14,42 @@ test.each([ .expectLuaToMatchSnapshot(); }); +test.each([ + "console.info()", + 'console.info("Hello")', + 'console.info("Hello %s", "there")', + 'console.info("Hello %%s", "there")', + 'console.info("Hello", "There")', +])("console.info (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + +test.each([ + "console.error()", + 'console.error("Hello")', + 'console.error("Hello %s", "there")', + 'console.error("Hello %%s", "there")', + 'console.error("Hello", "There")', +])("console.error (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + +test.each([ + "console.warn()", + 'console.warn("Hello")', + 'console.warn("Hello %s", "there")', + 'console.warn("Hello %%s", "there")', + 'console.warn("Hello", "There")', +])("console.warn (%p)", code => { + util.testFunction(code) + .setOptions(compilerOptions) + .expectLuaToMatchSnapshot(); +}); + test.each([ "console.trace()", 'console.trace("message")', From 6800dc8eb2f2a0294240d77b7c29f013c2dba259 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 10 Dec 2019 02:14:14 +0500 Subject: [PATCH 202/764] Use Node.js 12 features (#768) --- .github/workflows/ci.yml | 6 ++-- .github/workflows/release.yml | 1 - package.json | 2 +- src/transformation/context/context.ts | 5 ++- src/transformation/utils/annotations.ts | 3 +- src/transformation/utils/function-context.ts | 3 +- src/transformation/utils/typescript/index.ts | 3 +- .../destructuring-assignments.ts | 3 +- src/transformation/visitors/loops/for.ts | 3 +- .../visitors/variable-declaration.ts | 4 +-- src/utils.ts | 15 -------- test/tsconfig.json | 4 +-- test/unit/builtins/array.spec.ts | 36 +++++++++---------- test/unit/builtins/numbers.spec.ts | 3 +- test/unit/builtins/object.spec.ts | 16 ++++----- tsconfig.json | 4 +-- 16 files changed, 40 insertions(+), 71 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 95cb25965..35c7ec129 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,6 @@ jobs: steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 - - run: npm install --global npm@6 - run: npm ci - run: npm run lint env: @@ -28,11 +27,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Use Node.js 8.5.0 + - name: Use Node.js 12.13.1 uses: actions/setup-node@v1 with: - node-version: 8.5.0 - - run: npm install --global npm@6 + node-version: 12.13.1 - run: npm ci - run: npm run build - run: npx jest --maxWorkers 2 --coverage diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 55f5b96f5..e3edaabbe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,6 @@ jobs: - uses: actions/setup-node@v1 with: registry-url: "https://registry.npmjs.org" - - run: npm install --global npm@6 - run: npm ci - run: npm run build - run: npm publish diff --git a/package.json b/package.json index 1f58ae98a..a7f6ba498 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "tstl": "./dist/tstl.js" }, "engines": { - "node": ">=8.5.0" + "node": ">=12.13.0" }, "dependencies": { "resolve": "^1.13.1", diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 5d9a7ef22..07d16f143 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -1,7 +1,6 @@ import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; -import { flatMap } from "../../utils"; import { unwrapVisitorResult } from "../utils/lua-ast"; import { isFileModule } from "../utils/typescript"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; @@ -81,14 +80,14 @@ export class TransformationContext { public transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { return Array.isArray(node) - ? flatMap(node, n => this.transformStatements(n)) + ? node.flatMap(n => this.transformStatements(n)) : // TODO: https://github.com/microsoft/TypeScript/pull/28916 (this.transformNode(node as StatementLikeNode) as lua.Statement[]); } public superTransformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { return Array.isArray(node) - ? flatMap(node, n => this.superTransformStatements(n)) + ? node.flatMap(n => this.superTransformStatements(n)) : // TODO: https://github.com/microsoft/TypeScript/pull/28916 (this.superTransformNode(node as StatementLikeNode) as lua.Statement[]); } diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 985a4ec26..8c7f4ea12 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -1,5 +1,4 @@ import * as ts from "typescript"; -import { flatMap } from "../../utils"; import { TransformationContext } from "../context"; import { findFirstNodeAbove, inferAssignedType } from "./typescript"; @@ -102,7 +101,7 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment const jsDoc = sourceFile.statements[0].jsDoc; if (jsDoc) { - for (const tag of flatMap(jsDoc, x => x.tags ?? [])) { + for (const tag of jsDoc.flatMap(x => x.tags ?? [])) { const tagName = tag.tagName.text; const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); if (annotation) { diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 84f19d17a..6a2113d6a 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import { CompilerOptions } from "../../CompilerOptions"; -import { flatMap } from "../../utils"; import { TransformationContext } from "../context"; import { AnnotationKind, getFileAnnotations, getNodeAnnotations } from "./annotations"; import { findFirstNodeAbove, getAllCallSignatures, inferAssignedType } from "./typescript"; @@ -107,7 +106,7 @@ function getSignatureDeclarations( context: TransformationContext, signatures: readonly ts.Signature[] ): ts.SignatureDeclaration[] { - return flatMap(signatures, signature => { + return signatures.flatMap(signature => { const signatureDeclaration = signature.getDeclaration(); if ( (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index b6b5e6a1a..3869a4635 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -1,5 +1,4 @@ import * as ts from "typescript"; -import { flatMap } from "../../../utils"; import { TransformationContext } from "../../context"; import { isDeclaration } from "./nodes"; @@ -90,7 +89,7 @@ export function inferAssignedType(context: TransformationContext, expression: ts } export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { - return type.isUnion() ? flatMap(type.types, getAllCallSignatures) : type.getCallSignatures(); + return type.isUnion() ? type.types.flatMap(getAllCallSignatures) : type.getCallSignatures(); } // Returns true for expressions that may have effects when evaluated diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index cb89a3673..7ed1d92d7 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { flatMap } from "../../../utils"; import { TransformationContext } from "../../context"; import { UnsupportedKind } from "../../utils/errors"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; @@ -57,7 +56,7 @@ function transformArrayLiteralAssignmentPattern( node: ts.ArrayLiteralExpression, root: lua.Expression ): lua.Statement[] { - return flatMap(node.elements, (element, index) => { + return node.elements.flatMap((element, index) => { const indexedRoot = lua.createTableIndexExpression(root, lua.createNumericLiteral(index + 1), element); switch (element.kind) { diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 6d167ce03..517852fdf 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { flatMap } from "../../../utils"; import { FunctionVisitor } from "../../context"; import { transformVariableDeclaration } from "../variable-declaration"; import { transformLoopBody } from "./body"; @@ -11,7 +10,7 @@ export const transformForStatement: FunctionVisitor = (statemen if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { // local initializer = value - result.push(...flatMap(statement.initializer.declarations, d => transformVariableDeclaration(context, d))); + result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { result.push(...context.transformStatements(ts.createExpressionStatement(statement.initializer))); } diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 074198af1..9b932eef3 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { assertNever, flatMap } from "../../utils"; +import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; @@ -223,4 +223,4 @@ export function transformVariableDeclaration( } export const transformVariableStatement: FunctionVisitor = (node, context) => - flatMap(node.declarationList.declarations, declaration => transformVariableDeclaration(context, declaration)); + node.declarationList.declarations.flatMap(declaration => transformVariableDeclaration(context, declaration)); diff --git a/src/utils.ts b/src/utils.ts index 7b29b553a..6baad413a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -12,21 +12,6 @@ export function formatPathToLuaPath(filePath: string): string { return filePath.replace(/\.\//g, "").replace(/\//g, "."); } -export function flatMap(array: readonly T[], callback: (value: T, index: number) => U | readonly U[]): U[] { - const result: U[] = []; - - for (const [index, value] of array.entries()) { - const mappedValue = callback(value, index); - if (Array.isArray(mappedValue)) { - result.push(...mappedValue); - } else { - result[result.length] = mappedValue as U; - } - } - - return result; -} - type NoInfer = [T][T extends any ? 0 : never]; export function getOrUpdate( diff --git a/test/tsconfig.json b/test/tsconfig.json index 63542f392..ecdd3263e 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -5,8 +5,8 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "target": "es2017", - "lib": ["es2017"], + "target": "es2019", + "lib": ["es2019"], "types": ["node", "jest"], "experimentalDecorators": true, diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 6c439a920..463d0d1dc 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -488,28 +488,26 @@ test.each([ }); test.each([ - { array: [[]], expected: [] }, - { array: [{ a: 1 }, { a: 2 }, { a: 3 }], expected: [{ a: 1 }, { a: 2 }, { a: 3 }] }, - { array: [1, [2, 3], 4], expected: [1, 2, 3, 4] }, - { array: [1, [2, 3], 4], depth: 0, expected: [1, [2, 3], 4] }, - { array: [1, [[2], [3]], 4], expected: [1, [2], [3], 4] }, - { array: [1, [[[2], [3]]], 4], depth: Infinity, expected: [1, 2, 3, 4] }, -])("array.flat (%p)", ({ array, depth, expected }) => { - // TODO: Node 12 - util.testExpressionTemplate`${array}.flat(${depth})`.expectToEqual(expected); + { array: [[]] }, + { array: [{ a: 1 }, { a: 2 }, { a: 3 }] }, + { array: [1, [2, 3], 4] }, + { array: [1, [2, 3], 4], depth: 0 }, + { array: [1, [[2], [3]], 4] }, + { array: [1, [[[2], [3]]], 4], depth: Infinity }, +])("array.flat (%p)", ({ array, depth }) => { + util.testExpressionTemplate`${array}.flat(${depth})`.expectToMatchJsResult(); }); test.each([ - { array: [[]], map: (v: T) => v, expected: [] }, - { array: [1, 2, 3], map: (v: number) => ({ a: v * 2 }), expected: [{ a: 2 }, { a: 4 }, { a: 6 }] }, - { array: [1, [2, 3], [4]], map: (value: T) => value, expected: [1, 2, 3, 4] }, - { array: [1, 2, 3], map: (v: number) => v * 2, expected: [2, 4, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, v * 2], expected: [1, 2, 2, 4, 3, 6] }, - { array: [1, 2, 3], map: (v: number) => [v, [v]], expected: [1, [1], 2, [2], 3, [3]] }, - { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i], expected: [0, 4, 12] }, -])("array.flatMap (%p)", ({ array, map, expected }) => { - // TODO: Node 12 - util.testExpressionTemplate`${array}.flatMap(${map})`.expectToEqual(expected); + { array: [[]], map: (v: T) => v }, + { array: [1, 2, 3], map: (v: number) => ({ a: v * 2 }) }, + { array: [1, [2, 3], [4]], map: (value: T) => value }, + { array: [1, 2, 3], map: (v: number) => v * 2 }, + { array: [1, 2, 3], map: (v: number) => [v, v * 2] }, + { array: [1, 2, 3], map: (v: number) => [v, [v]] }, + { array: [1, 2, 3], map: (v: number, i: number) => [v * 2 * i] }, +])("array.flatMap (%p)", ({ array, map }) => { + util.testExpressionTemplate`${array}.flatMap(${map})`.expectToMatchJsResult(); }); describe.each(["reduce", "reduceRight"])("array.%s", reduce => { diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 7a5d5c731..94334376c 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -1,4 +1,3 @@ -import { flatMap } from "../../../src/utils"; import * as util from "../../util"; test.each([ @@ -51,7 +50,7 @@ describe("Number", () => { const toStringRadixes = [undefined, 10, 2, 8, 9, 16, 17, 36, 36.9]; const toStringValues = [-1, 0, 1, 1.5, 1024, 1.2]; -const toStringPairs = flatMap(toStringValues, value => toStringRadixes.map(radix => [value, radix] as const)); +const toStringPairs = toStringValues.flatMap(value => toStringRadixes.map(radix => [value, radix] as const)); test.each(toStringPairs)("(%p).toString(%p)", (value, radix) => { util.testExpressionTemplate`(${value}).toString(${radix})`.expectToMatchJsResult(); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 5e0a973a4..067da81f6 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -22,13 +22,9 @@ test.each([{}, { abc: "def" }, { abc: 3, def: "xyz" }])("Object.values (%p)", ob util.testExpressionTemplate`Object.values(${obj})`.expectToMatchJsResult(); }); -// TODO: Jest 25: as const -test.each<[string, object]>([ - ["[]", []], - ['[["a", 1], ["b", 2]]', { a: 1, b: 2 }], - ['[["a", 1], ["a", 2]]', { a: 2 }], - ['new Map([["foo", "bar"]])', { foo: "bar" }], -])("Object.fromEntries(%s)", (entries, expected) => { - // TODO: Node 12 - util.testExpression`Object.fromEntries(${entries})`.expectToEqual(expected); -}); +test.each(["[]", '[["a", 1], ["b", 2]]', '[["a", 1], ["a", 2]]', 'new Map([["foo", "bar"]])'])( + "Object.fromEntries(%s)", + entries => { + util.testExpression`Object.fromEntries(${entries})`.expectToMatchJsResult(); + } +); diff --git a/tsconfig.json b/tsconfig.json index 8f1275d19..d16784b37 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,8 +7,8 @@ "outDir": "./dist", "declaration": true, "sourceMap": true, - "target": "es2017", - "lib": ["es2017"], + "target": "es2019", + "lib": ["es2019"], "module": "commonjs", "stripInternal": true }, From 9f829543c50775a3df61ae96e14d3e4bb7550dd3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 11 Dec 2019 21:59:19 +0100 Subject: [PATCH 203/764] Added string.trim, string.trim{Left,Right,StartEnd} (#767) * Added string.trim, string.trimLeft, string.trimRight, string.trimStart and string.trimEnd * Updated node version * Added tests for newline characters getting trimmed * Added some final testcases for trim * Added support for BOM and non-breaking space * Changed up test cases, removed curly braces from Lua pattern --- src/LuaLib.ts | 3 +++ src/lualib/StringTrim.ts | 5 +++++ src/lualib/StringTrimEnd.ts | 5 +++++ src/lualib/StringTrimStart.ts | 5 +++++ src/transformation/builtins/string.ts | 8 ++++++++ test/unit/builtins/string.spec.ts | 22 ++++++++++++++++++++++ 6 files changed, 48 insertions(+) create mode 100644 src/lualib/StringTrim.ts create mode 100644 src/lualib/StringTrimEnd.ts create mode 100644 src/lualib/StringTrimStart.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index c3a5e0c61..efafbab50 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -61,6 +61,9 @@ export enum LuaLibFeature { StringReplace = "StringReplace", StringSplit = "StringSplit", StringStartsWith = "StringStartsWith", + StringTrim = "StringTrim", + StringTrimEnd = "StringTrimEnd", + StringTrimStart = "StringTrimStart", Symbol = "Symbol", SymbolRegistry = "SymbolRegistry", TypeOf = "TypeOf", diff --git a/src/lualib/StringTrim.ts b/src/lualib/StringTrim.ts new file mode 100644 index 000000000..8a231118a --- /dev/null +++ b/src/lualib/StringTrim.ts @@ -0,0 +1,5 @@ +function __TS__StringTrim(this: string): string { + // http://lua-users.org/wiki/StringTrim + const [result] = string.gsub(this, "^[%s\xA0\uFEFF]*(.-)[%s\xA0\uFEFF]*$", "%1"); + return result; +} diff --git a/src/lualib/StringTrimEnd.ts b/src/lualib/StringTrimEnd.ts new file mode 100644 index 000000000..c45238235 --- /dev/null +++ b/src/lualib/StringTrimEnd.ts @@ -0,0 +1,5 @@ +function __TS__StringTrimEnd(this: string): string { + // http://lua-users.org/wiki/StringTrim + const [result] = string.gsub(this, "[%s\xA0\uFEFF]*$", ""); + return result; +} diff --git a/src/lualib/StringTrimStart.ts b/src/lualib/StringTrimStart.ts new file mode 100644 index 000000000..47e6e8a66 --- /dev/null +++ b/src/lualib/StringTrimStart.ts @@ -0,0 +1,5 @@ +function __TS__StringTrimStart(this: string): string { + // http://lua-users.org/wiki/StringTrim + const [result] = string.gsub(this, "^[%s\xA0\uFEFF]*", ""); + return result; +} diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index e1f32a886..d405287a3 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -94,6 +94,14 @@ export function transformStringPrototypeCall( return createStringCall("lower", node, caller); case "toUpperCase": return createStringCall("upper", node, caller); + case "trim": + return transformLuaLibFunction(context, LuaLibFeature.StringTrim, node, caller); + case "trimEnd": + case "trimRight": + return transformLuaLibFunction(context, LuaLibFeature.StringTrimEnd, node, caller); + case "trimStart": + case "trimLeft": + return transformLuaLibFunction(context, LuaLibFeature.StringTrimStart, node, caller); case "split": return transformLuaLibFunction(context, LuaLibFeature.StringSplit, node, caller, ...params); case "charAt": diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 7ecf860c7..b135e528c 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -265,3 +265,25 @@ test.each([ `; expect(util.transpileAndExecute(code)).toBe(6); }); + +const trimTestCases = [ + "", + " ", + "\t", + "\t \t", + " foo ", + "\tfoo\t", + "\ffoo\f", + "\vfoo\v", + "\uFEFFFoo\uFEFF", + "\xA0Foo\xA0", + " \t foo \t ", + " foo bar ", + "\r\nfoo\n\r\n", + "\r\nfoo\nbar\n\r\n", +]; +describe.each(["trim", "trimEnd", "trimRight", "trimStart", "trimLeft"])("string.%s", trim => { + test.each(trimTestCases)("matches JS result (%p)", testString => { + util.testExpression`${util.formatCode(testString)}.${trim}()`.expectToMatchJsResult(); + }); +}); From c1485afe3c89eb196229ce46f1de5f3721860e4f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Thu, 19 Dec 2019 05:41:29 +1000 Subject: [PATCH 204/764] fix back assignment (#764) * fix back assignment * fix modules reassignment test indentation * use cast for leftHandSideExpression * Add and fix export test case for shadowed identifiers * Support 'export as' reassignment with side effects * Use transformAssignment in destructuring * Fix modules test formatting and cut out weak test cases * Use symbol.name in assignments, not escapedName * Use node and element instead of expression for canBeTransformed * Use Statement[] for transformAssignment * Refactor for getDependenciesOfSymbol * Use lua.Statement[] for component and unary expression * Inline createAssignment to transformAssignment --- src/transformation/utils/export.ts | 44 +++++++--- .../visitors/binary-expression/assignments.ts | 88 ++++++++++++++----- .../visitors/binary-expression/compound.ts | 27 ++++-- .../destructuring-assignments.ts | 34 +++---- .../visitors/unary-expression.ts | 2 +- test/unit/modules/modules.spec.ts | 44 ++++++++++ 6 files changed, 178 insertions(+), 61 deletions(-) diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index 5d7d74c91..ca1b4be69 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -71,21 +71,12 @@ export function getSymbolExportScope( return scope; } -export function isSymbolExported(context: TransformationContext, symbol: ts.Symbol): boolean { - return ( - getExportedSymbolDeclaration(symbol) !== undefined || - // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') - isSymbolExportedFromScope(context, symbol, context.sourceFile) - ); -} - -export function isSymbolExportedFromScope( +export function getExportedSymbolsFromScope( context: TransformationContext, - symbol: ts.Symbol, scope: ts.SourceFile | ts.ModuleDeclaration -): boolean { +): ts.Symbol[] { if (ts.isSourceFile(scope) && !isFileModule(scope)) { - return false; + return []; } let scopeSymbol = context.checker.getSymbolAtLocation(scope); @@ -95,12 +86,37 @@ export function isSymbolExportedFromScope( } if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { - return false; + return []; } // ts.Iterator is not a ES6-compatible iterator, because TypeScript targets ES5 const it: Iterable = { [Symbol.iterator]: () => scopeSymbol!.exports!.values() }; - return [...it].includes(symbol); + return [...it]; +} + +export function getDependenciesOfSymbol(context: TransformationContext, originalSymbol: ts.Symbol): ts.Symbol[] { + return getExportedSymbolsFromScope(context, context.sourceFile).filter(exportSymbol => + exportSymbol.declarations + .filter(ts.isExportSpecifier) + .map(context.checker.getExportSpecifierLocalTargetSymbol) + .includes(originalSymbol) + ); +} + +export function isSymbolExported(context: TransformationContext, symbol: ts.Symbol): boolean { + return ( + getExportedSymbolDeclaration(symbol) !== undefined || + // Symbol may have been exported separately (e.g. 'const foo = "bar"; export { foo }') + isSymbolExportedFromScope(context, symbol, context.sourceFile) + ); +} + +export function isSymbolExportedFromScope( + context: TransformationContext, + symbol: ts.Symbol, + scope: ts.SourceFile | ts.ModuleDeclaration +): boolean { + return getExportedSymbolsFromScope(context, scope).includes(symbol); } export function addExportToIdentifier( diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index acf41aca4..3561cfa33 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -1,24 +1,37 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast, castEach } from "../../../utils"; +import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { isTupleReturnCall } from "../../utils/annotations"; import { validateAssignment, validatePropertyAssignment } from "../../utils/assignment-validation"; +import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; +export function transformAssignmentLeftHandSideExpression( + context: TransformationContext, + node: ts.Expression +): lua.AssignmentLeftHandSideExpression { + const symbol = context.checker.getSymbolAtLocation(node); + const left = context.transformExpression(node); + + return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) + ? createExportedIdentifier(context, left) + : cast(left, lua.isAssignmentLeftHandSideExpression); +} + export function transformAssignment( context: TransformationContext, // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, right: lua.Expression, parent?: ts.Expression -): lua.Statement { +): lua.Statement[] { if (isArrayLength(context, lhs)) { - return lua.createExpressionStatement( + const arrayLengthAssignment = lua.createExpressionStatement( transformLuaLibFunction( context, LuaLibFeature.ArraySetLength, @@ -27,13 +40,28 @@ export function transformAssignment( right ) ); + + return [arrayLengthAssignment]; } - return lua.createAssignmentStatement( - cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression), - right, - lhs.parent - ); + const symbol = ts.isShorthandPropertyAssignment(lhs.parent) + ? context.checker.getShorthandAssignmentValueSymbol(lhs.parent) + : context.checker.getSymbolAtLocation(lhs); + + const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; + + const left = transformAssignmentLeftHandSideExpression(context, lhs); + + const rootAssignment = lua.createAssignmentStatement(left, right, lhs.parent); + + return [ + rootAssignment, + ...dependentSymbols.map(symbol => { + const [left] = rootAssignment.left; + const identifierToAssign = createExportedIdentifier(context, lua.createIdentifier(symbol.name)); + return lua.createAssignmentStatement(identifierToAssign, left); + }), + ]; } export function transformAssignmentExpression( @@ -106,13 +134,39 @@ export function transformAssignmentExpression( const left = context.transformExpression(expression.left); const right = context.transformExpression(expression.right); return createImmediatelyInvokedFunctionExpression( - [transformAssignment(context, expression.left, right)], + transformAssignment(context, expression.left, right), left, expression ); } } +const canBeTransformedToLuaAssignmentStatement = ( + context: TransformationContext, + node: ts.DestructuringAssignment +): node is ts.ArrayDestructuringAssignment => { + return ( + ts.isArrayLiteralExpression(node.left) && + node.left.elements.every(element => { + if (isArrayLength(context, element)) { + return false; + } + + if (ts.isPropertyAccessExpression(element) || ts.isElementAccessExpression(element)) { + return true; + } + + if (ts.isIdentifier(element)) { + const symbol = context.checker.getSymbolAtLocation(element); + if (symbol) { + const aliases = getDependenciesOfSymbol(context, symbol); + return aliases.length === 0; + } + } + }) + ); +}; + export function transformAssignmentStatement( context: TransformationContext, expression: ts.AssignmentExpression @@ -124,14 +178,7 @@ export function transformAssignmentStatement( validatePropertyAssignment(context, expression); if (isDestructuringAssignment(expression)) { - if ( - ts.isArrayLiteralExpression(expression.left) && - expression.left.elements.every( - e => - (ts.isIdentifier(e) || ts.isPropertyAccessExpression(e) || ts.isElementAccessExpression(e)) && - !isArrayLength(context, e) - ) - ) { + if (canBeTransformedToLuaAssignmentStatement(context, expression)) { const rightType = context.checker.getTypeAtLocation(expression.right); let right = context.transformExpression(expression.right); @@ -139,10 +186,7 @@ export function transformAssignmentStatement( right = createUnpackCall(context, right, expression.right); } - const left = castEach( - expression.left.elements.map(e => context.transformExpression(e)), - lua.isAssignmentLeftHandSideExpression - ); + const left = expression.left.elements.map(e => transformAssignmentLeftHandSideExpression(context, e)); return [lua.createAssignmentStatement(left, right, expression)]; } @@ -158,6 +202,6 @@ export function transformAssignmentStatement( ...transformDestructuringAssignment(context, expression, rootIdentifier), ]; } else { - return [transformAssignment(context, expression.left, context.transformExpression(expression.right))]; + return transformAssignment(context, expression.left, context.transformExpression(expression.right)); } } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 70340fbeb..65ad5d1ec 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -121,8 +121,12 @@ export function transformCompoundAssignmentExpression( replacementOperator, expression ); - const assignStatement = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier, expression); + const assignStatements = transformAssignment(context, lhs, operatorExpression); + return createImmediatelyInvokedFunctionExpression( + [tmpDeclaration, ...assignStatements], + tmpIdentifier, + expression + ); } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____tmp = ${left} ${replacementOperator} ${right}; @@ -131,14 +135,18 @@ export function transformCompoundAssignmentExpression( const tmpIdentifier = lua.createIdentifier("____tmp"); const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); - const assignStatement = transformAssignment(context, lhs, tmpIdentifier); - return createImmediatelyInvokedFunctionExpression([tmpDeclaration, assignStatement], tmpIdentifier, expression); + const assignStatements = transformAssignment(context, lhs, tmpIdentifier); + return createImmediatelyInvokedFunctionExpression( + [tmpDeclaration, ...assignStatements], + tmpIdentifier, + expression + ); } else { // Simple expressions // ${left} = ${right}; return ${right} const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); - const assignStatement = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression([assignStatement], left, expression); + const assignStatements = transformAssignment(context, lhs, operatorExpression); + return createImmediatelyInvokedFunctionExpression(assignStatements, left, expression); } } @@ -148,7 +156,7 @@ export function transformCompoundAssignmentStatement( lhs: ts.Expression, rhs: ts.Expression, replacementOperator: ts.BinaryOperator -): lua.Statement { +): lua.Statement[] { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const right = context.transformExpression(rhs); @@ -172,11 +180,12 @@ export function transformCompoundAssignmentStatement( node ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); - return lua.createDoStatement([objAndIndexDeclaration, assignStatement]); + return [objAndIndexDeclaration, assignStatement]; } else { // Simple statements // ${left} = ${left} ${replacementOperator} ${right} const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, node); - return transformAssignment(context, lhs, operatorExpression); + const assignmentStatements = transformAssignment(context, lhs, operatorExpression); + return assignmentStatements; } } diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index 7ed1d92d7..d5d8b3fe2 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -4,9 +4,12 @@ import { TransformationContext } from "../../context"; import { UnsupportedKind } from "../../utils/errors"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isAssignmentPattern } from "../../utils/typescript"; -import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { transformAssignment, transformAssignmentStatement } from "./assignments"; +import { + transformAssignment, + transformAssignmentLeftHandSideExpression, + transformAssignmentStatement, +} from "./assignments"; export function isArrayLength( context: TransformationContext, @@ -86,21 +89,21 @@ function transformArrayLiteralAssignmentPattern( lua.SyntaxKind.EqualityOperator ); - const defaultAssignmentStatement = transformAssignment( + const defaultAssignmentStatements = transformAssignment( context, (element as ts.BinaryExpression).left, context.transformExpression((element as ts.BinaryExpression).right) ); - const elseAssignmentStatement = transformAssignment( + const elseAssignmentStatements = transformAssignment( context, (element as ts.BinaryExpression).left, assignedVariable ); - const ifBlock = lua.createBlock([defaultAssignmentStatement]); + const ifBlock = lua.createBlock(defaultAssignmentStatements); - const elseBlock = lua.createBlock([elseAssignmentStatement]); + const elseBlock = lua.createBlock(elseAssignmentStatements); const ifStatement = lua.createIfStatement(nilCondition, ifBlock, elseBlock, node); @@ -169,14 +172,15 @@ function transformShorthandPropertyAssignment( root: lua.Expression ): lua.Statement[] { const result: lua.Statement[] = []; - const assignmentVariableName = transformIdentifier(context, node.name); + const assignmentVariableName = transformAssignmentLeftHandSideExpression(context, node.name); const extractionIndex = lua.createStringLiteral(node.name.text); - const variableExtractionAssignmentStatement = lua.createAssignmentStatement( - assignmentVariableName, + const variableExtractionAssignmentStatements = transformAssignment( + context, + node.name, lua.createTableIndexExpression(root, extractionIndex) ); - result.push(variableExtractionAssignmentStatement); + result.push(...variableExtractionAssignmentStatements); const defaultInitializer = node.objectAssignmentInitializer ? context.transformExpression(node.objectAssignmentInitializer) @@ -189,9 +193,9 @@ function transformShorthandPropertyAssignment( lua.SyntaxKind.EqualityOperator ); - const assignment = lua.createAssignmentStatement(assignmentVariableName, defaultInitializer); + const assignmentStatements = transformAssignment(context, node.name, defaultInitializer); - const ifBlock = lua.createBlock([assignment]); + const ifBlock = lua.createBlock(assignmentStatements); result.push(lua.createIfStatement(nilCondition, ifBlock, undefined, node)); } @@ -223,9 +227,9 @@ function transformPropertyAssignment( const variableToExtract = transformPropertyName(context, node.name); const extractingExpression = lua.createTableIndexExpression(root, variableToExtract); - const destructureAssignmentStatement = transformAssignment(context, leftExpression, extractingExpression); + const destructureAssignmentStatements = transformAssignment(context, leftExpression, extractingExpression); - result.push(destructureAssignmentStatement); + result.push(...destructureAssignmentStatements); if (ts.isBinaryExpression(node.initializer)) { const assignmentLeftHandSide = context.transformExpression(node.initializer.left); @@ -274,5 +278,5 @@ function transformSpreadAssignment( lua.createTableExpression(usedProperties) ); - return [transformAssignment(context, node.expression, extractingExpression)]; + return transformAssignment(context, node.expression, extractingExpression); } diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index e4c8dfad2..cf0d44312 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -11,7 +11,7 @@ import { export function transformUnaryExpressionStatement( context: TransformationContext, node: ts.ExpressionStatement -): lua.Statement | undefined { +): lua.Statement[] | undefined { const expression = ts.isExpressionStatement(node) ? node.expression : node; if ( ts.isPrefixUnaryExpression(expression) && diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 9209a0819..6b5a86068 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -209,3 +209,47 @@ test("Export Equals", () => { expect(result).toBe(true); }); + +const reassignmentTestCases = [ + "x = 1", + "x++", + "(x = 1)", + "[x] = [1]", + "[[x]] = [[1]]", + "({ x } = { x: 1 })", + "({ y: x } = { y: 1 })", + "({ x = 1 } = { x: undefined })", +]; + +test.each(reassignmentTestCases)("export specifier with reassignment afterwards (%p)", reassignment => { + util.testModule` + let x = 0; + export { x }; + ${reassignment}; + `.expectToMatchJsResult(); +}); + +test.each(reassignmentTestCases)("export specifier fork (%p)", reassignment => { + util.testModule` + let x = 0; + export { x as a }; + export { x as b }; + ${reassignment}; + `.expectToMatchJsResult(); +}); + +test("does not export shadowed identifiers", () => { + util.testModule` + export let a = 1; + { let a = 2; a = 3 }; + `.expectToMatchJsResult(); +}); + +test("export as specifier shouldn't effect local vars", () => { + util.testModule` + let x = false; + export { x as a }; + let a = 5; + a = 6; + `.expectToMatchJsResult(); +}); From 10ff5f73f789447f9a70063034c1a2ba86141d4a Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Thu, 19 Dec 2019 05:42:22 +1000 Subject: [PATCH 205/764] Use lua's math.atan2 for Math.atan2 (#765) * use lua's math.atan2 for Math.atan2 * use math.atan for Lua 5.3 * use snapshots for tests * use tap and testEachVersion for math.atan testing * Move Math.atan2 transformation down to switch case * Move math atan2 transformation back to top of switch * Remove unneeded whitespace change * Improve math.atan2 comment Co-Authored-By: Perry van Wesel * Use methodName for Math method transformation * Add Math.atan2 Lua5.3 comparison test, fix math.atan taps * Update test/unit/builtins/math.spec.ts Co-Authored-By: ark120202 * Update test/unit/builtins/math.spec.ts Co-Authored-By: ark120202 --- src/transformation/builtins/math.ts | 10 ++++++---- .../builtins/__snapshots__/math.spec.ts.snap | 8 -------- test/unit/builtins/math.spec.ts | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 5daf2d24a..311ae1201 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; +import { LuaTarget } from "../../CompilerOptions"; import { TransformationContext } from "../context"; import { UnsupportedProperty } from "../utils/errors"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; @@ -33,12 +34,13 @@ export function transformMathCall(context: TransformationContext, node: Property const expressionName = expression.name.text; switch (expressionName) { - // math.tan(x / y) + // Lua 5.3: math.atan(y, x) + // Otherwise: math.atan2(y, x) case "atan2": { const math = lua.createIdentifier("math"); - const atan = lua.createStringLiteral("atan"); - const div = lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.DivisionOperator); - return lua.createCallExpression(lua.createTableIndexExpression(math, atan), [div], node); + const methodName = context.options.luaTarget === LuaTarget.Lua53 ? "atan" : expressionName; + const method = lua.createStringLiteral(methodName); + return lua.createCallExpression(lua.createTableIndexExpression(math, method), params, node); } // (math.log(x) / Math.LNe) diff --git a/test/unit/builtins/__snapshots__/math.spec.ts.snap b/test/unit/builtins/__snapshots__/math.spec.ts.snap index 65d6680d8..62881275f 100644 --- a/test/unit/builtins/__snapshots__/math.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/math.spec.ts.snap @@ -8,14 +8,6 @@ end return ____exports" `; -exports[`Math.atan2(2, 3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.atan(2 / 3) -end -return ____exports" -`; - exports[`Math.cos() 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 6dcd0749a..163095d9d 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -1,10 +1,10 @@ +import * as tstl from "../../../src"; import * as util from "../../util"; test.each([ "Math.cos()", "Math.sin()", "Math.min()", - "Math.atan2(2, 3)", "Math.log2(3)", "Math.log10(3)", "const x = Math.log2(3)", @@ -24,3 +24,17 @@ test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s" expect(builder.getLuaExecutionResult()).toBeCloseTo(builder.getJsExecutionResult()); }); }); + +const expectMathAtan2: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan2("); +const expectMathAtan: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan("); + +util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, { + [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), +}); + +test("Math.atan2(4, 5)", () => { + util.testExpression`Math.atan2(4, 5)`.expectToMatchJsResult(); +}); From 0284f9111dba0fa2c5e58541e48796306282d8ec Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 26 Dec 2019 19:05:25 +0500 Subject: [PATCH 206/764] Assume files with imports to be modules (#776) --- src/transformation/context/context.ts | 3 +- src/transformation/utils/export.ts | 15 +---- src/transformation/utils/typescript/index.ts | 17 ----- src/transformation/utils/typescript/nodes.ts | 16 ----- .../__snapshots__/transformation.spec.ts.snap | 42 ++++++++---- .../__snapshots__/project.spec.ts.snap | 2 + test/unit/hoisting.spec.ts | 66 ++++++++----------- 7 files changed, 63 insertions(+), 98 deletions(-) diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 07d16f143..e192348b3 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { unwrapVisitorResult } from "../utils/lua-ast"; -import { isFileModule } from "../utils/typescript"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; export interface EmitResolver { @@ -23,7 +22,7 @@ export class TransformationContext { public readonly options: CompilerOptions = this.program.getCompilerOptions(); public readonly luaTarget = this.options.luaTarget ?? LuaTarget.LuaJIT; - public readonly isModule = isFileModule(this.sourceFile); + public readonly isModule = ts.isExternalModule(this.sourceFile); public readonly isStrict = (this.options.alwaysStrict ?? this.options.strict) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index ca1b4be69..d509504d2 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -4,7 +4,7 @@ import { TransformationContext } from "../context"; import { createModuleLocalNameIdentifier } from "../visitors/namespace"; import { createExportsIdentifier } from "./lua-ast"; import { getSymbolInfo } from "./symbols"; -import { findFirstNodeAbove, isFileModule } from "./typescript"; +import { findFirstNodeAbove } from "./typescript"; export function hasDefaultExportModifier(node: ts.Node): boolean { return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); @@ -75,17 +75,8 @@ export function getExportedSymbolsFromScope( context: TransformationContext, scope: ts.SourceFile | ts.ModuleDeclaration ): ts.Symbol[] { - if (ts.isSourceFile(scope) && !isFileModule(scope)) { - return []; - } - - let scopeSymbol = context.checker.getSymbolAtLocation(scope); - if (scopeSymbol === undefined) { - // TODO: Necessary? - scopeSymbol = context.checker.getTypeAtLocation(scope).getSymbol(); - } - - if (scopeSymbol === undefined || scopeSymbol.exports === undefined) { + const scopeSymbol = context.checker.getSymbolAtLocation(ts.isSourceFile(scope) ? scope : scope.name); + if (scopeSymbol?.exports === undefined) { return []; } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 3869a4635..a947a1457 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -1,28 +1,11 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; -import { isDeclaration } from "./nodes"; export * from "./nodes"; export * from "./types"; // TODO: Move to separate files? -export function isFileModule(sourceFile: ts.SourceFile): boolean { - return sourceFile.statements.some(isStatementExported); -} - -function isStatementExported(statement: ts.Statement): boolean { - if (ts.isExportAssignment(statement) || ts.isExportDeclaration(statement)) { - return true; - } - if (ts.isVariableStatement(statement)) { - return statement.declarationList.declarations.some( - declaration => (ts.getCombinedModifierFlags(declaration) & ts.ModifierFlags.Export) !== 0 - ); - } - return isDeclaration(statement) && (ts.getCombinedModifierFlags(statement) & ts.ModifierFlags.Export) !== 0; -} - export function hasExportEquals(sourceFile: ts.SourceFile): boolean { return sourceFile.statements.some(node => ts.isExportAssignment(node) && node.isExportEquals); } diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index ed84c97a9..db0f85641 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -16,22 +16,6 @@ export function isAmbientNode(node: ts.Declaration): boolean { return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Ambient) !== 0; } -export function isDeclaration(node: ts.Node): node is ts.Declaration { - return ( - ts.isEnumDeclaration(node) || - ts.isClassDeclaration(node) || - ts.isExportDeclaration(node) || - ts.isImportDeclaration(node) || - ts.isMethodDeclaration(node) || - ts.isModuleDeclaration(node) || - ts.isFunctionDeclaration(node) || - ts.isVariableDeclaration(node) || - ts.isInterfaceDeclaration(node) || - ts.isTypeAliasDeclaration(node) || - ts.isNamespaceExportDeclaration(node) - ); -} - export function isInDestructingAssignment(node: ts.Node): boolean { return ( node.parent && diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 55ad7a99c..6d64751eb 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -126,18 +126,23 @@ end" `; exports[`Transformation (modulesImportAll) 1`] = ` -"local Test = require(\\"test\\") -local ____ = Test" +"local ____exports = {} +local Test = require(\\"test\\") +local ____ = Test +return ____exports" `; exports[`Transformation (modulesImportNamed) 1`] = ` -"local ____test = require(\\"test\\") +"local ____exports = {} +local ____test = require(\\"test\\") local TestClass = ____test.TestClass -local ____ = TestClass" +local ____ = TestClass +return ____exports" `; exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` -"local ____kebab_2Dmodule = require(\\"kebab-module\\") +"local ____exports = {} +local ____kebab_2Dmodule = require(\\"kebab-module\\") local TestClass1 = ____kebab_2Dmodule.TestClass1 local ____dollar_24module = require(\\"dollar$module\\") local TestClass2 = ____dollar_24module.TestClass2 @@ -151,17 +156,21 @@ local ____ = TestClass1 local ____ = TestClass2 local ____ = TestClass3 local ____ = TestClass4 -local ____ = TestClass5" +local ____ = TestClass5 +return ____exports" `; exports[`Transformation (modulesImportRenamed) 1`] = ` -"local ____test = require(\\"test\\") +"local ____exports = {} +local ____test = require(\\"test\\") local RenamedClass = ____test.TestClass -local ____ = RenamedClass" +local ____ = RenamedClass +return ____exports" `; exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` -"local ____kebab_2Dmodule = require(\\"kebab-module\\") +"local ____exports = {} +local ____kebab_2Dmodule = require(\\"kebab-module\\") local RenamedClass1 = ____kebab_2Dmodule.TestClass local ____dollar_24module = require(\\"dollar$module\\") local RenamedClass2 = ____dollar_24module.TestClass @@ -175,10 +184,15 @@ local ____ = RenamedClass1 local ____ = RenamedClass2 local ____ = RenamedClass3 local ____ = RenamedClass4 -local ____ = RenamedClass5" +local ____ = RenamedClass5 +return ____exports" `; -exports[`Transformation (modulesImportWithoutFromClause) 1`] = `"require(\\"test\\")"`; +exports[`Transformation (modulesImportWithoutFromClause) 1`] = ` +"local ____exports = {} +require(\\"test\\") +return ____exports" +`; exports[`Transformation (modulesNamespaceExport) 1`] = ` "local ____exports = {} @@ -244,6 +258,8 @@ end" `; exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` -"local x = require(\\"module\\") -local ____ = x" +"local ____exports = {} +local x = require(\\"module\\") +local ____ = x +return ____exports" `; diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 498b36d47..387a60fc6 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -15,10 +15,12 @@ return ____exports Object { "name": "index.lua", "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] +local ____exports = {} local ____otherFile = require(\\"otherFile\\") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) SetAPIValue(myNumber * 5) +return ____exports ", }, ] diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index e8ee28947..a54e28c6f 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -243,55 +243,45 @@ test.each([ }); test("Import hoisting (named)", () => { - const importCode = ` - const bar = foo; - import {foo} from "myMod";`; - const luaHeader = ` - package.loaded["myMod"] = {foo = "foobar"} - ${util.transpileString(importCode)}`; - const tsHeader = "declare const bar: any;"; - const code = "return bar;"; - expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); + util.testBundle` + export const result = foo; + import { foo } from "./module"; + ` + .addExtraFile("module.ts", "export const foo = true;") + .expectToEqual({ result: true }); }); test("Import hoisting (namespace)", () => { - const importCode = ` - const bar = myMod.foo; - import * as myMod from "myMod";`; - const luaHeader = ` - package.loaded["myMod"] = {foo = "foobar"} - ${util.transpileString(importCode)}`; - const tsHeader = "declare const bar: any;"; - const code = "return bar;"; - expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); + util.testBundle` + export const result = module.foo; + import * as module from "./module"; + ` + .addExtraFile("module.ts", "export const foo = true;") + .expectToEqual({ result: true }); }); test("Import hoisting (side-effect)", () => { - const importCode = ` - const bar = foo; - import "myMod";`; - const luaHeader = ` - package.loaded["myMod"] = {_ = (function() foo = "foobar" end)()} - ${util.transpileString(importCode)}`; - const tsHeader = "declare const bar: any;"; - const code = "return bar;"; - expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); + util.testBundle` + export const result = (globalThis as any).result; + import "./module"; + ` + .addExtraFile("module.ts", "(globalThis as any).result = true; export {};") + .expectToEqual({ result: true }); }); test("Import hoisted before function", () => { - const importCode = ` - let bar: any; - import {foo} from "myMod"; + util.testBundle` + export let result: any; + baz(); function baz() { - bar = foo; - }`; - const luaHeader = ` - package.loaded["myMod"] = {foo = "foobar"} - ${util.transpileString(importCode)}`; - const tsHeader = "declare const bar: any;"; - const code = "return bar;"; - expect(util.transpileAndExecute(code, undefined, luaHeader, tsHeader)).toBe("foobar"); + result = foo; + } + + import { foo } from "./module"; + ` + .addExtraFile("module.ts", "export const foo = true;") + .expectToEqual({ result: true }); }); test("Hoisting Shorthand Property", () => { From 084e228e1b8119fe9cbac51a613cf4fc9c554230 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 26 Dec 2019 19:32:31 +0500 Subject: [PATCH 207/764] Drop `var` declarations support (#762) * Drop `var` declarations support * Fix `Function using global as this` test * Error on vars in loop variable declarations * Move `transformLoopBody` to the new utils file * Add test for #761 * Revert unrelated test change --- src/LuaAST.ts | 241 ++++++------------ src/LuaPrinter.ts | 7 +- src/transformation/utils/errors.ts | 3 + src/transformation/utils/lua-ast.ts | 63 +---- src/transformation/utils/scope.ts | 14 +- src/transformation/visitors/enum.ts | 1 - src/transformation/visitors/loops/do-while.ts | 2 +- src/transformation/visitors/loops/for-in.ts | 14 +- src/transformation/visitors/loops/for-of.ts | 36 +-- src/transformation/visitors/loops/for.ts | 5 +- .../visitors/loops/{body.ts => utils.ts} | 11 + .../visitors/variable-declaration.ts | 14 +- test/unit/assignments.spec.ts | 40 ++- test/unit/builtins/map.spec.ts | 22 +- test/unit/builtins/set.spec.ts | 18 +- test/unit/functions/functions.spec.ts | 11 +- test/unit/hoisting.spec.ts | 66 ++--- test/unit/identifiers.spec.ts | 12 +- 18 files changed, 221 insertions(+), 359 deletions(-) rename src/transformation/visitors/loops/{body.ts => utils.ts} (73%) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 10c7b44b3..2b3401614 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -130,19 +130,18 @@ export interface TextRange { export interface Node extends TextRange { kind: SyntaxKind; - parent?: Node; } -export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node, parent?: Node): Node { +export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node): Node { if (tsOriginal === undefined) { - return { kind, parent }; + return { kind }; } const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { - return { kind, parent, line: sourcePosition.line, column: sourcePosition.column }; + return { kind, line: sourcePosition.line, column: sourcePosition.column }; } else { - return { kind, parent }; + return { kind }; } } @@ -172,19 +171,6 @@ export function setNodeOriginal(node: T | undefined, tsOriginal: return node; } -export function setParent(node: Node | Node[] | undefined, parent: Node): void { - if (!node) { - return; - } - if (Array.isArray(node)) { - node.forEach(n => { - n.parent = parent; - }); - } else { - node.parent = parent; - } -} - function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { if (sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition( @@ -209,9 +195,8 @@ export function isBlock(node: Node): node is Block { return node.kind === SyntaxKind.Block; } -export function createBlock(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): Block { - const block = createNode(SyntaxKind.Block, tsOriginal, parent) as Block; - setParent(statements, block); +export function createBlock(statements: Statement[], tsOriginal?: ts.Node): Block { + const block = createNode(SyntaxKind.Block, tsOriginal) as Block; block.statements = statements; return block; } @@ -229,9 +214,8 @@ export function isDoStatement(node: Node): node is DoStatement { return node.kind === SyntaxKind.DoStatement; } -export function createDoStatement(statements: Statement[], tsOriginal?: ts.Node, parent?: Node): DoStatement { - const statement = createNode(SyntaxKind.DoStatement, tsOriginal, parent) as DoStatement; - setParent(statements, statement); +export function createDoStatement(statements: Statement[], tsOriginal?: ts.Node): DoStatement { + const statement = createNode(SyntaxKind.DoStatement, tsOriginal) as DoStatement; statement.statements = statements; return statement; } @@ -250,26 +234,17 @@ export function isVariableDeclarationStatement(node: Node): node is VariableDecl export function createVariableDeclarationStatement( left: Identifier | Identifier[], right?: Expression | Expression[], - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): VariableDeclarationStatement { - const statement = createNode( - SyntaxKind.VariableDeclarationStatement, - tsOriginal, - parent - ) as VariableDeclarationStatement; - setParent(left, statement); - if (Array.isArray(left)) { - statement.left = left; - } else { - statement.left = [left]; - } - setParent(right, statement); + const statement = createNode(SyntaxKind.VariableDeclarationStatement, tsOriginal) as VariableDeclarationStatement; + statement.left = Array.isArray(left) ? left : [left]; + if (Array.isArray(right)) { statement.right = right; } else if (right) { statement.right = [right]; } + return statement; } @@ -287,22 +262,17 @@ export function isAssignmentStatement(node: Node): node is AssignmentStatement { export function createAssignmentStatement( left: AssignmentLeftHandSideExpression | AssignmentLeftHandSideExpression[], right?: Expression | Expression[], - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): AssignmentStatement { - const statement = createNode(SyntaxKind.AssignmentStatement, tsOriginal, parent) as AssignmentStatement; - setParent(left, statement); - if (Array.isArray(left)) { - statement.left = left; - } else { - statement.left = [left]; - } - setParent(right, statement); + const statement = createNode(SyntaxKind.AssignmentStatement, tsOriginal) as AssignmentStatement; + statement.left = Array.isArray(left) ? left : [left]; + if (Array.isArray(right)) { statement.right = right; } else { statement.right = right ? [right] : []; } + return statement; } @@ -321,15 +291,11 @@ export function createIfStatement( condition: Expression, ifBlock: Block, elseBlock?: Block | IfStatement, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): IfStatement { - const statement = createNode(SyntaxKind.IfStatement, tsOriginal, parent) as IfStatement; - setParent(condition, statement); + const statement = createNode(SyntaxKind.IfStatement, tsOriginal) as IfStatement; statement.condition = condition; - setParent(ifBlock, statement); statement.ifBlock = ifBlock; - setParent(elseBlock, statement); statement.elseBlock = elseBlock; return statement; } @@ -356,16 +322,9 @@ export function isWhileStatement(node: Node): node is WhileStatement { return node.kind === SyntaxKind.WhileStatement; } -export function createWhileStatement( - body: Block, - condition: Expression, - tsOriginal?: ts.Node, - parent?: Node -): WhileStatement { - const statement = createNode(SyntaxKind.WhileStatement, tsOriginal, parent) as WhileStatement; - setParent(body, statement); +export function createWhileStatement(body: Block, condition: Expression, tsOriginal?: ts.Node): WhileStatement { + const statement = createNode(SyntaxKind.WhileStatement, tsOriginal) as WhileStatement; statement.body = body; - setParent(condition, statement); statement.condition = condition; return statement; } @@ -379,16 +338,9 @@ export function isRepeatStatement(node: Node): node is RepeatStatement { return node.kind === SyntaxKind.RepeatStatement; } -export function createRepeatStatement( - body: Block, - condition: Expression, - tsOriginal?: ts.Node, - parent?: Node -): RepeatStatement { - const statement = createNode(SyntaxKind.RepeatStatement, tsOriginal, parent) as RepeatStatement; - setParent(body, statement); +export function createRepeatStatement(body: Block, condition: Expression, tsOriginal?: ts.Node): RepeatStatement { + const statement = createNode(SyntaxKind.RepeatStatement, tsOriginal) as RepeatStatement; statement.body = body; - setParent(condition, statement); statement.condition = condition; return statement; } @@ -412,19 +364,13 @@ export function createForStatement( controlVariableInitializer: Expression, limitExpression: Expression, stepExpression?: Expression, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): ForStatement { - const statement = createNode(SyntaxKind.ForStatement, tsOriginal, parent) as ForStatement; - setParent(body, statement); + const statement = createNode(SyntaxKind.ForStatement, tsOriginal) as ForStatement; statement.body = body; - setParent(controlVariable, statement); statement.controlVariable = controlVariable; - setParent(controlVariableInitializer, statement); statement.controlVariableInitializer = controlVariableInitializer; - setParent(limitExpression, statement); statement.limitExpression = limitExpression; - setParent(stepExpression, statement); statement.stepExpression = stepExpression; return statement; } @@ -443,15 +389,11 @@ export function createForInStatement( body: Block, names: Identifier[], expressions: Expression[], - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): ForInStatement { - const statement = createNode(SyntaxKind.ForInStatement, tsOriginal, parent) as ForInStatement; - setParent(body, statement); + const statement = createNode(SyntaxKind.ForInStatement, tsOriginal) as ForInStatement; statement.body = body; - setParent(names, statement); statement.names = names; - setParent(expressions, statement); statement.expressions = expressions; return statement; } @@ -465,8 +407,8 @@ export function isGotoStatement(node: Node): node is GotoStatement { return node.kind === SyntaxKind.GotoStatement; } -export function createGotoStatement(label: string, tsOriginal?: ts.Node, parent?: Node): GotoStatement { - const statement = createNode(SyntaxKind.GotoStatement, tsOriginal, parent) as GotoStatement; +export function createGotoStatement(label: string, tsOriginal?: ts.Node): GotoStatement { + const statement = createNode(SyntaxKind.GotoStatement, tsOriginal) as GotoStatement; statement.label = label; return statement; } @@ -480,8 +422,8 @@ export function isLabelStatement(node: Node): node is LabelStatement { return node.kind === SyntaxKind.LabelStatement; } -export function createLabelStatement(name: string, tsOriginal?: ts.Node, parent?: Node): LabelStatement { - const statement = createNode(SyntaxKind.LabelStatement, tsOriginal, parent) as LabelStatement; +export function createLabelStatement(name: string, tsOriginal?: ts.Node): LabelStatement { + const statement = createNode(SyntaxKind.LabelStatement, tsOriginal) as LabelStatement; statement.name = name; return statement; } @@ -495,13 +437,8 @@ export function isReturnStatement(node: Node): node is ReturnStatement { return node.kind === SyntaxKind.ReturnStatement; } -export function createReturnStatement( - expressions?: Expression[], - tsOriginal?: ts.Node, - parent?: Node -): ReturnStatement { - const statement = createNode(SyntaxKind.ReturnStatement, tsOriginal, parent) as ReturnStatement; - setParent(expressions, statement); +export function createReturnStatement(expressions?: Expression[], tsOriginal?: ts.Node): ReturnStatement { + const statement = createNode(SyntaxKind.ReturnStatement, tsOriginal) as ReturnStatement; statement.expressions = expressions; return statement; } @@ -514,8 +451,8 @@ export function isBreakStatement(node: Node): node is BreakStatement { return node.kind === SyntaxKind.BreakStatement; } -export function createBreakStatement(tsOriginal?: ts.Node, parent?: Node): BreakStatement { - return createNode(SyntaxKind.BreakStatement, tsOriginal, parent) as BreakStatement; +export function createBreakStatement(tsOriginal?: ts.Node): BreakStatement { + return createNode(SyntaxKind.BreakStatement, tsOriginal) as BreakStatement; } export interface ExpressionStatement extends Statement { @@ -527,13 +464,8 @@ export function isExpressionStatement(node: Node): node is ExpressionStatement { return node.kind === SyntaxKind.ExpressionStatement; } -export function createExpressionStatement( - expressions: Expression, - tsOriginal?: ts.Node, - parent?: Node -): ExpressionStatement { - const statement = createNode(SyntaxKind.ExpressionStatement, tsOriginal, parent) as ExpressionStatement; - setParent(expressions, statement); +export function createExpressionStatement(expressions: Expression, tsOriginal?: ts.Node): ExpressionStatement { + const statement = createNode(SyntaxKind.ExpressionStatement, tsOriginal) as ExpressionStatement; statement.expression = expressions; return statement; } @@ -552,8 +484,8 @@ export function isNilLiteral(node: Node): node is NilLiteral { return node.kind === SyntaxKind.NilKeyword; } -export function createNilLiteral(tsOriginal?: ts.Node, parent?: Node): NilLiteral { - return createNode(SyntaxKind.NilKeyword, tsOriginal, parent) as NilLiteral; +export function createNilLiteral(tsOriginal?: ts.Node): NilLiteral { + return createNode(SyntaxKind.NilKeyword, tsOriginal) as NilLiteral; } export interface BooleanLiteral extends Expression { @@ -564,11 +496,11 @@ export function isBooleanLiteral(node: Node): node is BooleanLiteral { return node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword; } -export function createBooleanLiteral(value: boolean, tsOriginal?: ts.Node, parent?: Node): BooleanLiteral { +export function createBooleanLiteral(value: boolean, tsOriginal?: ts.Node): BooleanLiteral { if (value) { - return createNode(SyntaxKind.TrueKeyword, tsOriginal, parent) as BooleanLiteral; + return createNode(SyntaxKind.TrueKeyword, tsOriginal) as BooleanLiteral; } else { - return createNode(SyntaxKind.FalseKeyword, tsOriginal, parent) as BooleanLiteral; + return createNode(SyntaxKind.FalseKeyword, tsOriginal) as BooleanLiteral; } } @@ -581,8 +513,8 @@ export function isDotsLiteral(node: Node): node is DotsLiteral { return node.kind === SyntaxKind.DotsKeyword; } -export function createDotsLiteral(tsOriginal?: ts.Node, parent?: Node): DotsLiteral { - return createNode(SyntaxKind.DotsKeyword, tsOriginal, parent) as DotsLiteral; +export function createDotsLiteral(tsOriginal?: ts.Node): DotsLiteral { + return createNode(SyntaxKind.DotsKeyword, tsOriginal) as DotsLiteral; } // StringLiteral / NumberLiteral @@ -599,8 +531,8 @@ export function isNumericLiteral(node: Node): node is NumericLiteral { return node.kind === SyntaxKind.NumericLiteral; } -export function createNumericLiteral(value: number, tsOriginal?: ts.Node, parent?: Node): NumericLiteral { - const expression = createNode(SyntaxKind.NumericLiteral, tsOriginal, parent) as NumericLiteral; +export function createNumericLiteral(value: number, tsOriginal?: ts.Node): NumericLiteral { + const expression = createNode(SyntaxKind.NumericLiteral, tsOriginal) as NumericLiteral; expression.value = value; return expression; } @@ -614,8 +546,8 @@ export function isStringLiteral(node: Node): node is StringLiteral { return node.kind === SyntaxKind.StringLiteral; } -export function createStringLiteral(value: string, tsOriginal?: ts.Node, parent?: Node): StringLiteral { - const expression = createNode(SyntaxKind.StringLiteral, tsOriginal, parent) as StringLiteral; +export function createStringLiteral(value: string, tsOriginal?: ts.Node): StringLiteral { + const expression = createNode(SyntaxKind.StringLiteral, tsOriginal) as StringLiteral; expression.value = value; return expression; } @@ -645,17 +577,12 @@ export function createFunctionExpression( dots?: DotsLiteral, restParamName?: Identifier, flags = FunctionExpressionFlags.None, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): FunctionExpression { - const expression = createNode(SyntaxKind.FunctionExpression, tsOriginal, parent) as FunctionExpression; - setParent(body, expression); + const expression = createNode(SyntaxKind.FunctionExpression, tsOriginal) as FunctionExpression; expression.body = body; - setParent(params, expression); expression.params = params; - setParent(dots, expression); expression.dots = dots; - setParent(restParamName, expression); expression.restParamName = restParamName; expression.flags = flags; return expression; @@ -674,13 +601,10 @@ export function isTableFieldExpression(node: Node): node is TableFieldExpression export function createTableFieldExpression( value: Expression, key?: Expression, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): TableFieldExpression { - const expression = createNode(SyntaxKind.TableFieldExpression, tsOriginal, parent) as TableFieldExpression; - setParent(value, expression); + const expression = createNode(SyntaxKind.TableFieldExpression, tsOriginal) as TableFieldExpression; expression.value = value; - setParent(key, expression); expression.key = key; return expression; } @@ -694,13 +618,8 @@ export function isTableExpression(node: Node): node is TableExpression { return node.kind === SyntaxKind.TableExpression; } -export function createTableExpression( - fields: TableFieldExpression[] = [], - tsOriginal?: ts.Node, - parent?: Node -): TableExpression { - const expression = createNode(SyntaxKind.TableExpression, tsOriginal, parent) as TableExpression; - setParent(fields, expression); +export function createTableExpression(fields: TableFieldExpression[] = [], tsOriginal?: ts.Node): TableExpression { + const expression = createNode(SyntaxKind.TableExpression, tsOriginal) as TableExpression; expression.fields = fields; return expression; } @@ -718,11 +637,9 @@ export function isUnaryExpression(node: Node): node is UnaryExpression { export function createUnaryExpression( operand: Expression, operator: UnaryOperator, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): UnaryExpression { - const expression = createNode(SyntaxKind.UnaryExpression, tsOriginal, parent) as UnaryExpression; - setParent(operand, expression); + const expression = createNode(SyntaxKind.UnaryExpression, tsOriginal) as UnaryExpression; expression.operand = operand; expression.operator = operator; return expression; @@ -743,13 +660,10 @@ export function createBinaryExpression( left: Expression, right: Expression, operator: BinaryOperator, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): BinaryExpression { - const expression = createNode(SyntaxKind.BinaryExpression, tsOriginal, parent) as BinaryExpression; - setParent(left, expression); + const expression = createNode(SyntaxKind.BinaryExpression, tsOriginal) as BinaryExpression; expression.left = left; - setParent(right, expression); expression.right = right; expression.operator = operator; return expression; @@ -766,11 +680,9 @@ export function isParenthesizedExpression(node: Node): node is ParenthesizedExpr export function createParenthesizedExpression( innerExpression: Expression, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): ParenthesizedExpression { - const expression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal, parent) as ParenthesizedExpression; - setParent(innerExpression, expression); + const expression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal) as ParenthesizedExpression; expression.innerExpression = innerExpression; return expression; } @@ -788,13 +700,10 @@ export function isCallExpression(node: Node): node is CallExpression { export function createCallExpression( expression: Expression, params?: Expression[], - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): CallExpression { - const callExpression = createNode(SyntaxKind.CallExpression, tsOriginal, parent) as CallExpression; - setParent(expression, callExpression); + const callExpression = createNode(SyntaxKind.CallExpression, tsOriginal) as CallExpression; callExpression.expression = expression; - setParent(params, expression); callExpression.params = params; return callExpression; } @@ -814,15 +723,11 @@ export function createMethodCallExpression( prefixExpression: Expression, name: Identifier, params?: Expression[], - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): MethodCallExpression { - const callExpression = createNode(SyntaxKind.MethodCallExpression, tsOriginal, parent) as MethodCallExpression; - setParent(prefixExpression, callExpression); + const callExpression = createNode(SyntaxKind.MethodCallExpression, tsOriginal) as MethodCallExpression; callExpression.prefixExpression = prefixExpression; - setParent(name, callExpression); callExpression.name = name; - setParent(params, callExpression); callExpression.params = params; return callExpression; } @@ -843,10 +748,9 @@ export function createIdentifier( text: string, tsOriginal?: ts.Node, symbolId?: SymbolId, - originalName?: string, - parent?: Node + originalName?: string ): Identifier { - const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; + const expression = createNode(SyntaxKind.Identifier, tsOriginal) as Identifier; expression.exportable = true; expression.text = text; expression.symbolId = symbolId; @@ -858,8 +762,8 @@ export function cloneIdentifier(identifier: Identifier, tsOriginal?: ts.Node): I return createIdentifier(identifier.text, tsOriginal, identifier.symbolId, identifier.originalName); } -export function createAnonymousIdentifier(tsOriginal?: ts.Node, parent?: Node): Identifier { - const expression = createNode(SyntaxKind.Identifier, tsOriginal, parent) as Identifier; +export function createAnonymousIdentifier(tsOriginal?: ts.Node): Identifier { + const expression = createNode(SyntaxKind.Identifier, tsOriginal) as Identifier; expression.exportable = false; expression.text = "____"; return expression; @@ -878,13 +782,10 @@ export function isTableIndexExpression(node: Node): node is TableIndexExpression export function createTableIndexExpression( table: Expression, index: Expression, - tsOriginal?: ts.Node, - parent?: Node + tsOriginal?: ts.Node ): TableIndexExpression { - const expression = createNode(SyntaxKind.TableIndexExpression, tsOriginal, parent) as TableIndexExpression; - setParent(table, expression); + const expression = createNode(SyntaxKind.TableIndexExpression, tsOriginal) as TableIndexExpression; expression.table = table; - setParent(index, expression); expression.index = index; return expression; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index fda6e89ff..e94269734 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -395,13 +395,10 @@ export class LuaPrinter { return this.createSourceNode(statement, chunks); } - public printIfStatement(statement: lua.IfStatement): SourceNode { + public printIfStatement(statement: lua.IfStatement, isElseIf = false): SourceNode { const chunks: SourceChunk[] = []; - const isElseIf = statement.parent !== undefined && lua.isIfStatement(statement.parent); - const prefix = isElseIf ? "elseif" : "if"; - chunks.push(this.indent(prefix + " "), this.printExpression(statement.condition), " then\n"); this.pushIndent(); @@ -410,7 +407,7 @@ export class LuaPrinter { if (statement.elseBlock) { if (lua.isIfStatement(statement.elseBlock)) { - chunks.push(this.printIfStatement(statement.elseBlock)); + chunks.push(this.printIfStatement(statement.elseBlock, true)); } else { chunks.push(this.indent("else\n")); this.pushIndent(); diff --git a/src/transformation/utils/errors.ts b/src/transformation/utils/errors.ts index bb3f3ce79..09634fcc8 100644 --- a/src/transformation/utils/errors.ts +++ b/src/transformation/utils/errors.ts @@ -148,3 +148,6 @@ export const InvalidAmbientIdentifierName = (node: ts.Identifier) => export const InvalidForRangeCall = (node: ts.Node, message: string) => new TranspileError(`Invalid @forRange call: ${message}`, node); + +export const UnsupportedVarDeclaration = (node: ts.Node) => + new TranspileError("`var` declarations are not supported. Use `let` or `const` instead.", node); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 6043a4c07..15488d982 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -3,10 +3,9 @@ import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { getCurrentNamespace } from "../visitors/namespace"; -import { UndefinedScope } from "./errors"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; import { findScope, peekScope, ScopeType } from "./scope"; -import { isFirstDeclaration, isFunctionType } from "./typescript"; +import { isFunctionType } from "./typescript"; export type OneToManyVisitorResult = T | T[] | undefined; export function unwrapVisitorResult(result: OneToManyVisitorResult): T[] { @@ -27,22 +26,6 @@ export function createExportsIdentifier(): lua.Identifier { return lua.createIdentifier("____exports"); } -export function replaceStatementInParent(oldNode: lua.Statement, newNode?: lua.Statement): void { - if (!oldNode.parent) { - throw new Error("node has not yet been assigned a parent"); - } - - if (lua.isBlock(oldNode.parent) || lua.isDoStatement(oldNode.parent)) { - if (newNode) { - oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1, newNode); - } else { - oldNode.parent.statements.splice(oldNode.parent.statements.indexOf(oldNode), 1); - } - } else { - throw new Error("unexpected parent type"); - } -} - export function createExpressionPlusOne(expression: lua.Expression): lua.Expression { if (lua.isNumericLiteral(expression)) { const newNode = lua.cloneNode(expression); @@ -111,10 +94,9 @@ export function createHoistableVariableDeclarationStatement( context: TransformationContext, identifier: lua.Identifier, initializer?: lua.Expression, - tsOriginal?: ts.Node, - parent?: lua.Node + tsOriginal?: ts.Node ): lua.AssignmentStatement | lua.VariableDeclarationStatement { - const declaration = lua.createVariableDeclarationStatement(identifier, initializer, tsOriginal, parent); + const declaration = lua.createVariableDeclarationStatement(identifier, initializer, tsOriginal); if (!context.options.noHoisting && identifier.symbolId) { const scope = peekScope(context); if (!scope.variableDeclarations) { @@ -132,13 +114,13 @@ export function createLocalOrExportedOrGlobalDeclaration( lhs: lua.Identifier | lua.Identifier[], rhs?: lua.Expression | lua.Expression[], tsOriginal?: ts.Node, - parent?: lua.Node, overrideExportScope?: ts.SourceFile | ts.ModuleDeclaration ): lua.Statement[] { let declaration: lua.VariableDeclarationStatement | undefined; let assignment: lua.AssignmentStatement | undefined; - const functionDeclaration = tsOriginal && ts.isFunctionDeclaration(tsOriginal) ? tsOriginal : undefined; + const isVariableDeclaration = tsOriginal !== undefined && ts.isVariableDeclaration(tsOriginal); + const isFunctionDeclaration = tsOriginal !== undefined && ts.isFunctionDeclaration(tsOriginal); const identifiers = Array.isArray(lhs) ? lhs : [lhs]; if (identifiers.length === 0) { @@ -154,48 +136,31 @@ export function createLocalOrExportedOrGlobalDeclaration( assignment = lua.createAssignmentStatement( identifiers.map(identifier => createExportedIdentifier(context, identifier, exportScope)), rhs, - tsOriginal, - parent + tsOriginal ); } } else { const insideFunction = findScope(context, ScopeType.Function) !== undefined; - let isLetOrConst = false; - let isVariableFirstDeclaration = true; // var can have multiple declarations for the same variable :/ - if (tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.parent) { - isLetOrConst = (tsOriginal.parent.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) !== 0; - isVariableFirstDeclaration = isLetOrConst || isFirstDeclaration(context, tsOriginal); - } - if ( - (context.isModule || getCurrentNamespace(context) || insideFunction || isLetOrConst) && - isVariableFirstDeclaration - ) { + if (context.isModule || getCurrentNamespace(context) || insideFunction || isVariableDeclaration) { // local const isPossibleWrappedFunction = - !functionDeclaration && + !isFunctionDeclaration && tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.initializer && isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); if (isPossibleWrappedFunction) { // Split declaration and assignment for wrapped function types to allow recursion - declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal, parent); - assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal, parent); + declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } else { - declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal, parent); + declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } if (!context.options.noHoisting) { // Remember local variable declarations for hoisting later - const scope = - isLetOrConst || functionDeclaration - ? peekScope(context) - : findScope(context, ScopeType.Function | ScopeType.File); - - if (scope === undefined) { - throw UndefinedScope(); - } + const scope = peekScope(context); if (!scope.variableDeclarations) { scope.variableDeclarations = []; @@ -205,13 +170,13 @@ export function createLocalOrExportedOrGlobalDeclaration( } } else if (rhs) { // global - assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal, parent); + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } else { return []; } } - if (!context.options.noHoisting && functionDeclaration) { + if (!context.options.noHoisting && isFunctionDeclaration) { // Remember function definitions for hoisting later const functionSymbolId = (lhs as lua.Identifier).symbolId; const scope = peekScope(context); diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 5077bcc42..55fa88bd7 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -1,9 +1,9 @@ +import * as assert from "assert"; import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { getOrUpdate, isNonNull } from "../../utils"; import { TransformationContext } from "../context"; import { UndefinedFunctionDefinition, UndefinedScope } from "./errors"; -import { replaceStatementInParent } from "./lua-ast"; import { getSymbolInfo } from "./symbols"; import { getFirstDeclarationInFile } from "./typescript"; @@ -168,15 +168,11 @@ function hoistVariableDeclarations( } const index = result.indexOf(declaration); - if (index >= 0) { - if (assignment) { - result.splice(index, 1, assignment); - } else { - result.splice(index, 1); - } + assert(index > -1); + if (assignment) { + result.splice(index, 1, assignment); } else { - // Special case for 'var's declared in child scopes - replaceStatementInParent(declaration, assignment); + result.splice(index, 1); } hoistedLocals.push(...declaration.left); diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index e721464eb..8c3a82213 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -75,7 +75,6 @@ export const transformEnumDeclaration: FunctionVisitor = (no : lua.createIdentifier(member.name.getText(), member.name), valueExpression, node, - undefined, exportScope ) ); diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index e1a56c496..8e219b6b8 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; -import { transformLoopBody } from "./body"; +import { transformLoopBody } from "./utils"; export const transformWhileStatement: FunctionVisitor = (statement, context) => { return lua.createWhileStatement( diff --git a/src/transformation/visitors/loops/for-in.ts b/src/transformation/visitors/loops/for-in.ts index b79f18ccf..f4365ac23 100644 --- a/src/transformation/visitors/loops/for-in.ts +++ b/src/transformation/visitors/loops/for-in.ts @@ -4,7 +4,7 @@ import { FunctionVisitor } from "../../context"; import { ForbiddenForIn, UnsupportedForInVariable } from "../../utils/errors"; import { isArrayType } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; -import { transformLoopBody } from "./body"; +import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; export const transformForInStatement: FunctionVisitor = (statement, context) => { if (isArrayType(context, context.checker.getTypeAtLocation(statement.expression))) { @@ -22,11 +22,13 @@ export const transformForInStatement: FunctionVisitor = (stat // TODO: After the transformation pipeline refactor we should look at refactoring this together with the // for-of initializer transformation. let iterationVariable: lua.Identifier; - if ( - ts.isVariableDeclarationList(statement.initializer) && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - iterationVariable = transformIdentifier(context, statement.initializer.declarations[0].name); + if (ts.isVariableDeclarationList(statement.initializer)) { + const binding = getVariableDeclarationBinding(statement.initializer); + if (!ts.isIdentifier(binding)) { + throw UnsupportedForInVariable(statement.initializer); + } + + iterationVariable = transformIdentifier(context, binding); } else if (ts.isIdentifier(statement.initializer)) { // Iteration variable becomes ____key iterationVariable = lua.createIdentifier("____key"); diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 868b2c03d..6689e19e5 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -15,7 +15,7 @@ import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; import { transformArrayBindingElement, transformVariableDeclaration } from "../variable-declaration"; -import { transformLoopBody } from "./body"; +import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; function transformForOfInitializer( context: TransformationContext, @@ -23,15 +23,16 @@ function transformForOfInitializer( expression: lua.Expression ): lua.Statement | undefined { if (ts.isVariableDeclarationList(initializer)) { + const binding = getVariableDeclarationBinding(initializer); // Declaration of new variable - if (ts.isArrayBindingPattern(initializer.declarations[0].name)) { - if (initializer.declarations[0].name.elements.length === 0) { + if (ts.isArrayBindingPattern(binding)) { + if (binding.elements.length === 0) { // Ignore empty destructuring assignment return undefined; } expression = createUnpackCall(context, expression, initializer); - } else if (ts.isObjectBindingPattern(initializer.declarations[0].name)) { + } else if (ts.isObjectBindingPattern(binding)) { throw UnsupportedObjectDestructuringInForOf(initializer); } @@ -90,19 +91,19 @@ function transformForRangeStatement( throw InvalidForRangeCall(statement.initializer, "@forRange loop must declare its own control variable."); } - const controlDeclaration = statement.initializer.declarations[0]; - if (!ts.isIdentifier(controlDeclaration.name)) { + const binding = getVariableDeclarationBinding(statement.initializer); + if (!ts.isIdentifier(binding)) { throw InvalidForRangeCall(statement.initializer, "@forRange loop cannot use destructuring."); } - if (!isNumberType(context, context.checker.getTypeAtLocation(controlDeclaration))) { + if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { throw InvalidForRangeCall( statement.expression, "@forRange function must return Iterable or Array." ); } - const control = transformIdentifier(context, controlDeclaration.name); + const control = transformIdentifier(context, binding); const signature = context.checker.getResolvedSignature(statement.expression); const [start, limit, step] = transformArguments(context, statement.expression.arguments, signature); return lua.createForStatement(block, control, start, limit, step, statement); @@ -121,12 +122,9 @@ function transformForOfLuaIteratorStatement( if (ts.isVariableDeclarationList(statement.initializer)) { // Variables declared in for loop // for ${initializer} in ${iterable} do - const initializerVariable = statement.initializer.declarations[0].name; - if (ts.isArrayBindingPattern(initializerVariable)) { - const identifiers = castEach( - initializerVariable.elements.map(e => transformArrayBindingElement(context, e)), - lua.isIdentifier - ); + const binding = getVariableDeclarationBinding(statement.initializer); + if (ts.isArrayBindingPattern(binding)) { + const identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); if (identifiers.length === 0) { identifiers.push(lua.createAnonymousIdentifier()); } @@ -163,6 +161,7 @@ function transformForOfLuaIteratorStatement( // LuaIterator (no TupleReturn) if ( ts.isVariableDeclarationList(statement.initializer) && + statement.initializer.declarations.length > 0 && ts.isIdentifier(statement.initializer.declarations[0].name) ) { // Single variable declared in for loop @@ -194,15 +193,15 @@ function transformForOfArrayStatement( let valueVariable: lua.Identifier; if (ts.isVariableDeclarationList(statement.initializer)) { // Declaration of new variable - const variables = statement.initializer.declarations[0].name; - if (ts.isArrayBindingPattern(variables) || ts.isObjectBindingPattern(variables)) { + const binding = getVariableDeclarationBinding(statement.initializer); + if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { valueVariable = lua.createIdentifier("____values"); const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); if (initializer) { block.statements.unshift(initializer); } } else { - valueVariable = transformIdentifier(context, variables); + valueVariable = transformIdentifier(context, binding); } } else { // Assignment to existing variable @@ -228,13 +227,14 @@ function transformForOfIteratorStatement( const iterable = context.transformExpression(statement.expression); if ( ts.isVariableDeclarationList(statement.initializer) && + statement.initializer.declarations.length > 0 && ts.isIdentifier(statement.initializer.declarations[0].name) ) { // Single variable declared in for loop // for ${initializer} in __TS__iterator(${iterator}) do return lua.createForInStatement( block, - [transformIdentifier(context, statement.initializer.declarations[0].name as ts.Identifier)], + [transformIdentifier(context, statement.initializer.declarations[0].name)], [transformLuaLibFunction(context, LuaLibFeature.Iterator, statement.expression, iterable)] ); } else { diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 517852fdf..970c2f045 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -1,14 +1,15 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; -import { transformVariableDeclaration } from "../variable-declaration"; -import { transformLoopBody } from "./body"; +import { checkVariableDeclarationList, transformVariableDeclaration } from "../variable-declaration"; +import { transformLoopBody } from "./utils"; export const transformForStatement: FunctionVisitor = (statement, context) => { const result: lua.Statement[] = []; if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { + checkVariableDeclarationList(statement.initializer); // local initializer = value result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { diff --git a/src/transformation/visitors/loops/body.ts b/src/transformation/visitors/loops/utils.ts similarity index 73% rename from src/transformation/visitors/loops/body.ts rename to src/transformation/visitors/loops/utils.ts index e46c4112d..639c0de95 100644 --- a/src/transformation/visitors/loops/body.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -3,6 +3,7 @@ import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { performHoisting, popScope, pushScope, ScopeType } from "../../utils/scope"; import { transformBlockOrStatement } from "../block"; +import { checkVariableDeclarationList } from "../variable-declaration"; export function transformLoopBody( context: TransformationContext, @@ -23,3 +24,13 @@ export function transformLoopBody( return baseResult; } + +export function getVariableDeclarationBinding(node: ts.VariableDeclarationList): ts.BindingName { + checkVariableDeclarationList(node); + + if (node.declarations.length === 0) { + return ts.createIdentifier("____"); + } + + return node.declarations[0].name; +} diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 9b932eef3..c02d8ab1d 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -4,7 +4,7 @@ import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; -import { UnsupportedKind } from "../utils/errors"; +import { UnsupportedKind, UnsupportedVarDeclaration } from "../utils/errors"; import { addExportToIdentifier } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; @@ -222,5 +222,13 @@ export function transformVariableDeclaration( } } -export const transformVariableStatement: FunctionVisitor = (node, context) => - node.declarationList.declarations.flatMap(declaration => transformVariableDeclaration(context, declaration)); +export function checkVariableDeclarationList(node: ts.VariableDeclarationList): void { + if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) === 0) { + throw UnsupportedVarDeclaration(node); + } +} + +export const transformVariableStatement: FunctionVisitor = (node, context) => { + checkVariableDeclarationList(node.declarationList); + return node.declarationList.declarations.flatMap(declaration => transformVariableDeclaration(context, declaration)); +}; diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 9bb53c78c..c559690d0 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1,27 +1,43 @@ import * as util from "../util"; -test("Const assignment (%p)", () => { +test("const declaration", () => { const lua = util.transpileString(`const foo = true;`); expect(lua).toBe(`local foo = true`); }); -test("Let assignment (%p)", () => { +test("let declaration", () => { const lua = util.transpileString(`let foo = true;`); expect(lua).toBe(`local foo = true`); }); -test("Var assignment (%p)", () => { - const lua = util.transpileString(`var foo = true;`); - expect(lua).toBe(`foo = true`); +test("var declaration is disallowed", () => { + util.testFunction` + var foo = true; + `.expectToHaveDiagnostics(); }); -test.each(["var myvar;", "let myvar;", "const myvar = null;", "const myvar = undefined;"])( - "Null assignments (%p)", - declaration => { - const result = util.transpileAndExecute(declaration + " return myvar;"); - expect(result).toBe(undefined); - } -); +test("var declaration in for loop is disallowed", () => { + util.testFunction` + for (var foo = 0;;) {} + `.expectToHaveDiagnostics(); +}); + +test("var declaration in for...in loop is disallowed", () => { + util.testFunction` + for (var foo in {}) {} + `.expectToHaveDiagnostics(); +}); + +test("var declaration in for...of loop is disallowed", () => { + util.testFunction` + for (var foo of []) {} + `.expectToHaveDiagnostics(); +}); + +test.each(["let myvar;", "const myvar = null;", "const myvar = undefined;"])("Null assignments (%p)", declaration => { + const result = util.transpileAndExecute(declaration + " return myvar;"); + expect(result).toBe(undefined); +}); test.each(["x = y", "x += y"])("Assignment expressions (%p)", expression => { util.testFunction` diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index cc5d1eb9c..f12810b3e 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -43,7 +43,7 @@ test("map entries", () => { const result = util.transpileAndExecute( `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; - for (var [key, value] of mymap.entries()) { count += key + value; } + for (const [key, value] of mymap.entries()) { count += key + value; } return count;` ); expect(result).toBe(27); @@ -120,7 +120,7 @@ test("map keys", () => { const result = util.transpileAndExecute( `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; - for (var key of mymap.keys()) { count += key; } + for (const key of mymap.keys()) { count += key; } return count;` ); @@ -140,7 +140,7 @@ test("map values", () => { const result = util.transpileAndExecute( `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; - for (var value of mymap.values()) { count += value; } + for (const value of mymap.values()) { count += value; } return count;` ); @@ -160,14 +160,14 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM test("basic", () => { util.testFunction` const mymap = new Map(); - + mymap.set("x", 1); mymap.set("a", 2); mymap.set(4, 3); mymap.set("b", 6); mymap.set(1, 4); mymap.set("a", 5); - + mymap.delete("b"); return [...mymap.${iterationMethod}()]; @@ -177,11 +177,11 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM test("after removing last", () => { util.testFunction` const mymap = new Map(); - + mymap.set("x", 1); mymap.set("a", 2); mymap.set(4, 3); - + mymap.delete(4); return [...mymap.${iterationMethod}()]; @@ -191,11 +191,11 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM test("after removing first", () => { util.testFunction` const mymap = new Map(); - + mymap.set("x", 1); mymap.set("a", 2); mymap.set(4, 3); - + mymap.delete("x"); return [...mymap.${iterationMethod}()]; @@ -205,10 +205,10 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM test("after removing all", () => { util.testFunction` const mymap = new Map(); - + mymap.set("x", 1); mymap.set("a", 2); - + mymap.delete("a"); mymap.delete("x"); diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index c2e2fe433..cbd8cb3f4 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -49,7 +49,7 @@ test("set entries", () => { util.testFunction` let myset = new Set([5, 6, 7]); let count = 0; - for (var [key, value] of myset.entries()) { count += key + value; } + for (const [key, value] of myset.entries()) { count += key + value; } return count; `.expectToMatchJsResult(); }); @@ -138,14 +138,14 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM test("basic", () => { util.testFunction` const myset = new Set(); - + myset.add("x"); myset.add("a"); myset.add(4); myset.add("b"); myset.add(1); myset.add("a"); - + myset.delete("b"); return [...myset.${iterationMethod}()]; @@ -155,11 +155,11 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM test("after removing last", () => { util.testFunction` const myset = new Set(); - + myset.add("x"); myset.add("a"); myset.add(4); - + myset.delete(4); return [...myset.${iterationMethod}()]; @@ -169,11 +169,11 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM test("after removing first", () => { util.testFunction` const myset = new Set(); - + myset.add("x"); myset.add("a"); myset.add(4); - + myset.delete("x"); return [...myset.${iterationMethod}()]; @@ -183,10 +183,10 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM test("after removing all", () => { util.testFunction` const myset = new Set(); - + myset.add("x"); myset.add("a"); - + myset.delete("a"); myset.delete("x"); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index c9553f96e..1a94507a2 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -410,14 +410,17 @@ test("Function local overriding export", () => { }); test("Function using global as this", () => { - const tsHeader = ` - var foo = "foo"; + // Value is provided with top-level return with ts-ignore, because modules are always strict. + // TODO: Provide a different builder kind for such tests? + util.testModule` + (globalThis as any).foo = "foo"; function bar(this: any) { return this.foo; } - `; - util.testExpression`foo`.setTsHeader(tsHeader).expectToMatchJsResult(); + // @ts-ignore + return bar(); + `.expectToEqual("foo"); }); test("Function rest binding pattern", () => { diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index a54e28c6f..880908793 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -2,25 +2,6 @@ import * as ts from "typescript"; import { ReferencedBeforeDeclaration } from "../../src/transformation/utils/errors"; import * as util from "../util"; -test("Var Hoisting", () => { - const code = ` - foo = "foo"; - var foo; - return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); -}); - -test("Exported Var Hoisting", () => { - const code = ` - foo = "foo"; - export var foo; - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); -}); - test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { const code = ` let bar: string; @@ -98,37 +79,19 @@ test("Exported Namespace Function Hoisting", () => { }); test.each([ - { varType: "var", expectResult: "foo" }, { varType: "let", expectResult: "bar" }, { varType: "const", expectResult: "bar" }, ])("Hoisting in Non-Function Scope (%p)", ({ varType, expectResult }) => { const code = ` - function foo() { - ${varType} bar = "bar"; - for (let i = 0; i < 1; ++i) { - ${varType} bar = "foo"; + function foo() { + ${varType} bar = "bar"; + for (let i = 0; i < 1; ++i) { + ${varType} bar = "foo"; + } + return bar; } - return bar; - } - return foo(); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); -}); - -test.each([ - { initializer: "", expectResult: "foofoo" }, - { initializer: ' = "bar"', expectResult: "barbar" }, -])("Var hoisting from child scope (%p)", ({ initializer, expectResult }) => { - const code = ` - foo = "foo"; - let result: string; - if (true) { - var foo${initializer}; - result = foo; - } - return foo + result; - `; + return foo(); + `; const result = util.transpileAndExecute(code); expect(result).toBe(expectResult); }); @@ -175,19 +138,20 @@ test("Exported Namespace Hoisting", () => { }); test("Nested Namespace Hoisting", () => { - const code = ` - export namespace Outer { + util.testModule` + const Inner = 0; + namespace Outer { export function bar() { return Inner.foo; } namespace Inner { - export let foo = "foo"; + export const foo = "foo"; } } + export const foo = Outer.bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + export { Inner }; + `.expectToMatchJsResult(); }); test("Class Hoisting", () => { diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 88c5cc23b..5f647a013 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -505,17 +505,13 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { }); test("variable (_G)", () => { - const tsHeader = ` - var foobar = "foo";`; - const code = ` const _G = "bar"; - function foo(this: any) { - return this.foobar + _G; - } - return foo();`; + (globalThis as any).foo = "foo"; + return (globalThis as any).foo + _G; + `; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("foobar"); + expect(util.transpileAndExecute(code)).toBe("foobar"); }); test("function parameter", () => { From ed86bbd2df1ec34fc5b02922a493e1c21f0faed3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 30 Dec 2019 21:14:54 +0100 Subject: [PATCH 208/764] Added true as lua keyword (#784) --- src/transformation/utils/safe-names.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index 9969bd561..dbd8f3071 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -24,6 +24,7 @@ export const luaKeywords: ReadonlySet = new Set([ "repeat", "return", "then", + "true", "until", "while", ]); From 96c3f8db40d348d4019299096eb7ba35a21a3781 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 2 Jan 2020 00:01:53 +0500 Subject: [PATCH 209/764] Share scope between all switch cases (#775) * Share scope between all switch cases * Readd `do` blocks around cases and enable dead code elemination * Use `pushScope` return value (from #783) * Special-case switch scope hoisting * Add test from PR feedback --- src/LuaPrinter.ts | 33 ++++++++----------- src/transformation/utils/lua-ast.ts | 15 ++++++--- src/transformation/utils/scope.ts | 20 ++++++------ src/transformation/visitors/switch.ts | 29 ++++++----------- test/unit/conditionals.spec.ts | 46 ++++++++++++++++++++++++--- 5 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e94269734..35bb46aba 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -273,16 +273,24 @@ export class LuaPrinter { protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; - statements = this.removeDeadAndEmptyStatements(statements); - statements.forEach((s, i) => { - const node = this.printStatement(s); + for (const [index, statement] of statements.entries()) { + if (this.isStatementEmpty(statement)) continue; - if (i > 0 && this.statementMayRequireSemiColon(statements[i - 1]) && this.nodeStartsWithParenthesis(node)) { - statementNodes[i - 1].add(";"); + const node = this.printStatement(statement); + + if ( + index > 0 && + this.statementMayRequireSemiColon(statements[index - 1]) && + this.nodeStartsWithParenthesis(node) + ) { + statementNodes[index - 1].add(";"); } statementNodes.push(node); - }); + + if (lua.isReturnStatement(statement)) break; + } + return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; } @@ -778,19 +786,6 @@ export class LuaPrinter { return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } - protected removeDeadAndEmptyStatements(statements: lua.Statement[]): lua.Statement[] { - const aliveStatements = []; - for (const statement of statements) { - if (!this.isStatementEmpty(statement)) { - aliveStatements.push(statement); - } - if (lua.isReturnStatement(statement)) { - break; - } - } - return aliveStatements; - } - protected isStatementEmpty(statement: lua.Statement): boolean { return lua.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); } diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 15488d982..a04c69035 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import * as assert from "assert"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; @@ -99,6 +100,8 @@ export function createHoistableVariableDeclarationStatement( const declaration = lua.createVariableDeclarationStatement(identifier, initializer, tsOriginal); if (!context.options.noHoisting && identifier.symbolId) { const scope = peekScope(context); + assert(scope.type !== ScopeType.Switch); + if (!scope.variableDeclarations) { scope.variableDeclarations = []; } @@ -143,14 +146,16 @@ export function createLocalOrExportedOrGlobalDeclaration( const insideFunction = findScope(context, ScopeType.Function) !== undefined; if (context.isModule || getCurrentNamespace(context) || insideFunction || isVariableDeclaration) { - // local + const scope = peekScope(context); + const isPossibleWrappedFunction = !isFunctionDeclaration && tsOriginal && ts.isVariableDeclaration(tsOriginal) && tsOriginal.initializer && isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); - if (isPossibleWrappedFunction) { + + if (isPossibleWrappedFunction || scope.type === ScopeType.Switch) { // Split declaration and assignment for wrapped function types to allow recursion declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); @@ -160,13 +165,15 @@ export function createLocalOrExportedOrGlobalDeclaration( if (!context.options.noHoisting) { // Remember local variable declarations for hoisting later - const scope = peekScope(context); - if (!scope.variableDeclarations) { scope.variableDeclarations = []; } scope.variableDeclarations.push(declaration); + + if (scope.type === ScopeType.Switch) { + declaration = undefined; + } } } else if (rhs) { // global diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 55fa88bd7..5f23d2984 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -77,12 +77,14 @@ export function findScope(context: TransformationContext, scopeTypes: ScopeType) } const scopeIdCounters = new WeakMap(); -export function pushScope(context: TransformationContext, scopeType: ScopeType): void { +export function pushScope(context: TransformationContext, scopeType: ScopeType): Scope { const nextScopeId = (scopeIdCounters.get(context) ?? 0) + 1; scopeIdCounters.set(context, nextScopeId); const scopeStack = getScopeStack(context); - scopeStack.push({ type: scopeType, id: nextScopeId }); + const scope: Scope = { type: scopeType, id: nextScopeId }; + scopeStack.push(scope); + return scope; } export function popScope(context: TransformationContext): Scope { @@ -161,20 +163,20 @@ function hoistVariableDeclarations( for (const declaration of scope.variableDeclarations) { const symbols = declaration.left.map(i => i.symbolId).filter(isNonNull); if (symbols.some(s => shouldHoistSymbol(context, s, scope))) { - let assignment: lua.AssignmentStatement | undefined; - if (declaration.right) { - assignment = lua.createAssignmentStatement(declaration.left, declaration.right); - lua.setNodePosition(assignment, declaration); // Preserve position info for sourcemap - } - const index = result.indexOf(declaration); assert(index > -1); - if (assignment) { + + if (declaration.right) { + const assignment = lua.createAssignmentStatement(declaration.left, declaration.right); + lua.setNodePosition(assignment, declaration); // Preserve position info for sourcemap result.splice(index, 1, assignment); } else { result.splice(index, 1); } + hoistedLocals.push(...declaration.left); + } else if (scope.type === ScopeType.Switch) { + assert(!declaration.right); hoistedLocals.push(...declaration.left); } } diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 0c6ece043..74bd4a7a9 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -3,24 +3,19 @@ import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { UnsupportedForTarget } from "../utils/errors"; -import { peekScope, performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { if (context.luaTarget === LuaTarget.Lua51) { throw UnsupportedForTarget("Switch statements", LuaTarget.Lua51, statement); } - pushScope(context, ScopeType.Switch); - + const scope = pushScope(context, ScopeType.Switch); // Give the switch a unique name to prevent nested switches from acting up. - const scope = peekScope(context); const switchName = `____switch${scope.id}`; - - const expression = context.transformExpression(statement.expression); const switchVariable = lua.createIdentifier(switchName); - const switchVariableDeclaration = lua.createVariableDeclarationStatement(switchVariable, expression); - let statements: lua.Statement[] = [switchVariableDeclaration]; + let statements: lua.Statement[] = []; const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); for (const [index, clause] of caseClauses.entries()) { @@ -37,19 +32,12 @@ export const transformSwitchStatement: FunctionVisitor = (st } const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause); - if (hasDefaultCase) { - statements.push(lua.createGotoStatement(`${switchName}_case_default`)); - } else { - statements.push(lua.createGotoStatement(`${switchName}_end`)); - } + statements.push(lua.createGotoStatement(`${switchName}_${hasDefaultCase ? "case_default" : "end"}`)); for (const [index, clause] of statement.caseBlock.clauses.entries()) { - const label = ts.isCaseClause(clause) - ? lua.createLabelStatement(`${switchName}_case_${index}`) - : lua.createLabelStatement(`${switchName}_case_default`); - - const body = lua.createDoStatement(context.transformStatements(clause.statements)); - statements.push(label, body); + const labelName = `${switchName}_case_${ts.isCaseClause(clause) ? index : "default"}`; + statements.push(lua.createLabelStatement(labelName)); + statements.push(lua.createDoStatement(context.transformStatements(clause.statements))); } statements.push(lua.createLabelStatement(`${switchName}_end`)); @@ -57,5 +45,8 @@ export const transformSwitchStatement: FunctionVisitor = (st statements = performHoisting(context, statements); popScope(context); + const expression = context.transformExpression(statement.expression); + statements.unshift(lua.createVariableDeclarationStatement(switchVariable, expression)); + return statements; }; diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index d33d39fdd..54534e9c8 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -157,7 +157,46 @@ test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { `.expectToMatchJsResult(); }); -test.each([0, 1, 2])("switchLocalScope (%p)", inp => { +test("switch cases scope", () => { + util.testFunction` + switch (0 as number) { + case 0: + let foo: number | undefined = 1; + case 1: + foo = 2; + case 2: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("variable in nested scope does not interfere with case scope", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: { + let foo = 1; + } + + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test.only("switch using variable re-declared in cases", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: + let foo = true; + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { util.testFunction` let result: number = -1; @@ -183,8 +222,6 @@ test.each([0, 1, 2])("switchLocalScope (%p)", inp => { test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { util.testFunction` - const result: number = -1; - switch (${inp}) { case 0: return 0; @@ -195,7 +232,8 @@ test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { return 2; break; } - return result; + + return -1; `.expectToMatchJsResult(); }); From 295d907c0a11d0645b09055def0562ff3a6ad959 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 2 Jan 2020 22:38:28 +0100 Subject: [PATCH 210/764] Fixed incorrect error on intersected number and string types (#786) * Fixed incorrect error on intersected number and string types * PR feedback * Removed lua string method check * Removed undefined union return * Removed some code duplication from printMethodCallExpression print method * Removed export from isExplicitArrayType --- src/LuaPrinter.ts | 4 ++- src/transformation/builtins/array.ts | 8 ++--- src/transformation/builtins/index.ts | 22 ++++++++------ src/transformation/builtins/string.ts | 32 -------------------- src/transformation/utils/typescript/index.ts | 23 +++++++++++--- src/transformation/utils/typescript/types.ts | 2 +- test/unit/builtins/loading.spec.ts | 6 ---- test/unit/builtins/numbers.spec.ts | 7 +++++ test/unit/builtins/string.spec.ts | 14 ++++----- 9 files changed, 51 insertions(+), 67 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 35bb46aba..1fd14f937 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -742,7 +742,9 @@ export class LuaPrinter { public printMethodCallExpression(expression: lua.MethodCallExpression): SourceNode { const chunks = []; - const prefix = this.printExpression(expression.prefixExpression); + const prefix = lua.isStringLiteral(expression.prefixExpression) + ? this.printExpression(lua.createParenthesizedExpression(expression.prefixExpression)) + : this.printExpression(expression.prefixExpression); const name = this.printIdentifier(expression.name); diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index cf4bef707..5cc0ca01e 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -3,15 +3,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { UnsupportedProperty } from "../utils/errors"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { isExplicitArrayType } from "../utils/typescript"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.CallExpression | undefined { +): lua.CallExpression { const expression = node.expression; - const ownerType = context.checker.getTypeAtLocation(expression.expression); const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); const caller = context.transformExpression(expression.expression); @@ -79,9 +77,7 @@ export function transformArrayPrototypeCall( case "flatMap": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); default: - if (isExplicitArrayType(context, ownerType)) { - throw UnsupportedProperty("array", expressionName, node); - } + throw UnsupportedProperty("array", expressionName, node); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 22ff84fa3..fe55a5058 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -4,7 +4,14 @@ import { assume } from "../../utils"; import { TransformationContext } from "../context"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { getIdentifierSymbolId } from "../utils/symbols"; -import { isArrayType, isFunctionType, isNumberType, isStandardLibraryType, isStringType } from "../utils/typescript"; +import { + hasStandardLibrarySignature, + isArrayType, + isFunctionType, + isNumberType, + isStandardLibraryType, + isStringType, +} from "../utils/typescript"; import { PropertyCallExpression } from "../visitors/call"; import { checkForLuaLibType } from "../visitors/class/new"; import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; @@ -85,22 +92,19 @@ export function transformBuiltinCallExpression( } } - if (isStringType(context, ownerType)) { + if (isStringType(context, ownerType) && hasStandardLibrarySignature(context, node)) { return transformStringPrototypeCall(context, node); } - if (isNumberType(context, ownerType)) { + if (isNumberType(context, ownerType) && hasStandardLibrarySignature(context, node)) { return transformNumberPrototypeCall(context, node); } - if (isArrayType(context, ownerType)) { - const result = transformArrayPrototypeCall(context, node); - if (result) { - return result; - } + if (isArrayType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + return transformArrayPrototypeCall(context, node); } - if (isFunctionType(context, ownerType)) { + if (isFunctionType(context, ownerType) && hasStandardLibrarySignature(context, node)) { return transformFunctionPrototypeCall(context, node); } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index d405287a3..abe79ac76 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -5,7 +5,6 @@ import { UnsupportedProperty } from "../utils/errors"; import { createExpressionPlusOne } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; -import { transformIdentifier } from "../visitors/identifier"; function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lua.Expression[]): lua.CallExpression { const stringIdentifier = lua.createIdentifier("string"); @@ -124,37 +123,6 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringPadStart, node, caller, ...params); case "padEnd": return transformLuaLibFunction(context, LuaLibFeature.StringPadEnd, node, caller, ...params); - - case "byte": - case "char": - case "dump": - case "find": - case "format": - case "gmatch": - case "gsub": - case "len": - case "lower": - case "match": - case "pack": - case "packsize": - case "rep": - case "reverse": - case "sub": - case "unpack": - case "upper": - // Allow lua's string instance methods - let stringVariable = context.transformExpression(expression.expression); - if (ts.isStringLiteralLike(expression.expression)) { - // "foo":method() needs to be ("foo"):method() - stringVariable = lua.createParenthesizedExpression(stringVariable); - } - - return lua.createMethodCallExpression( - stringVariable, - transformIdentifier(context, expression.name), - params, - node - ); default: throw UnsupportedProperty("string", expressionName, node); } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index a947a1457..4348dd54d 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -43,6 +43,15 @@ export function isFirstDeclaration(context: TransformationContext, node: ts.Vari return firstDeclaration === node; } +function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { + const sourceFile = declaration.getSourceFile(); + if (!sourceFile) { + return false; + } + + return context.program.isSourceFileDefaultLibrary(sourceFile); +} + export function isStandardLibraryType( context: TransformationContext, type: ts.Type, @@ -59,12 +68,16 @@ export function isStandardLibraryType( return true; } - const sourceFile = declaration.getSourceFile(); - if (!sourceFile) { - return false; - } + return isStandardLibraryDeclaration(context, declaration); +} - return context.program.isSourceFileDefaultLibrary(sourceFile); +export function hasStandardLibrarySignature( + context: TransformationContext, + callExpression: ts.CallExpression +): boolean { + const signature = context.checker.getResolvedSignature(callExpression); + + return signature && signature.declaration ? isStandardLibraryDeclaration(context, signature.declaration) : false; } export function inferAssignedType(context: TransformationContext, expression: ts.Expression): ts.Type { diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index b6bea5bbb..ba7f1b790 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -28,7 +28,7 @@ export function isNumberType(context: TransformationContext, type: ts.Type): boo return isTypeWithFlags(context, type, ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral); } -export function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { +function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { if (type.symbol) { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (baseConstraint && baseConstraint !== type) { diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index d43797e43..d1e5c204a 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -44,10 +44,4 @@ describe("Unknown builtin property", () => { .disableSemanticCheck() .expectToHaveDiagnosticOfError(UnsupportedProperty("Math", "unknownProperty", util.nodeStub)); }); - - test("function call", () => { - util.testExpression`[].unknownFunction()` - .disableSemanticCheck() - .expectToHaveDiagnosticOfError(UnsupportedProperty("array", "unknownFunction", util.nodeStub)); - }); }); diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 94334376c..ac4303c18 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -67,3 +67,10 @@ test.each(cases)("isNaN(%p)", value => { test.each(cases)("isFinite(%p)", value => { util.testExpressionTemplate`isFinite(${value} as any)`.expectToMatchJsResult(); }); + +test("number intersected method", () => { + util.testFunction` + type Vector = number & { normalize(): Vector }; + return ({ normalize: () => 3 } as Vector).normalize(); + `.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index b135e528c..2c61645c0 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -1,12 +1,5 @@ -import { UnsupportedProperty } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; -test("Unsupported string function", () => { - util.testExpression`"test".testThisIsNoMember()` - .disableSemanticCheck() - .expectToHaveDiagnosticOfError(UnsupportedProperty("string", "testThisIsNoMember", util.nodeStub)); -}); - test("Supported lua string function", () => { const tsHeader = ` declare global { @@ -287,3 +280,10 @@ describe.each(["trim", "trimEnd", "trimRight", "trimStart", "trimLeft"])("string util.testExpression`${util.formatCode(testString)}.${trim}()`.expectToMatchJsResult(); }); }); + +test("string intersected method", () => { + util.testFunction` + type Vector = string & { abc(): Vector }; + return ({ abc: () => "a" } as Vector).abc(); + `.expectToMatchJsResult(); +}); From 8241018606e5b69d541d22f91cd88f1f5a0bfe5f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 2 Jan 2020 22:46:43 +0100 Subject: [PATCH 211/764] Bugfix/loop destructuring (#783) * Use general destructuring logic for loop variable destructuring * Fixed destructuring variables from function headers not being local * Reworked transformation of for initializers a little to pass tests * PR feedback * Refactored destruction logic slightly * Upgraded some tests * changed parameter type * renamed methods, updated tests * inlined test input * Fixed incorrect handling of empty binding patterns * Fixed problem in new test * Removed superfluous pattern length check --- .../visitors/class/members/constructor.ts | 6 +- src/transformation/visitors/function.ts | 13 +- src/transformation/visitors/loops/for-of.ts | 39 +- src/transformation/visitors/switch.ts | 1 + .../visitors/variable-declaration.ts | 167 +++---- test/unit/decorators/tupleReturn.spec.ts | 35 +- test/unit/destructuring.spec.ts | 18 + test/unit/loops.spec.ts | 432 ++++++++---------- 8 files changed, 343 insertions(+), 368 deletions(-) diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index adefb1143..27be76333 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -5,6 +5,7 @@ import { transformParameters, transformFunctionBodyStatements, transformFunction import { TransformationContext } from "../../../context"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; +import { pushScope, ScopeType, popScope } from "../../../utils/scope"; export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { return lua.createTableIndexExpression( @@ -26,7 +27,8 @@ export function transformConstructorDeclaration( } // Transform body - const [body, scope] = transformFunctionBodyStatements(context, statement.body); + const scope = pushScope(context, ScopeType.Function); + const body = transformFunctionBodyStatements(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( context, @@ -81,6 +83,8 @@ export function transformConstructorDeclaration( const constructorWasGenerated = statement.pos === -1; + popScope(context); + return lua.createAssignmentStatement( createConstructorName(className), lua.createFunctionExpression( diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 070097db9..d39caf1ba 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -53,14 +53,9 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarArgType(context, r)); } -export function transformFunctionBodyStatements( - context: TransformationContext, - body: ts.Block -): [lua.Statement[], Scope] { - pushScope(context, ScopeType.Function); +export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] { const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); - const scope = popScope(context); - return [bodyStatements, scope]; + return bodyStatements; } export function transformFunctionBodyHeader( @@ -116,8 +111,10 @@ export function transformFunctionBody( body: ts.Block, spreadIdentifier?: lua.Identifier ): [lua.Statement[], Scope] { - const [bodyStatements, scope] = transformFunctionBodyStatements(context, body); + const scope = pushScope(context, ScopeType.Function); + const bodyStatements = transformFunctionBodyStatements(context, body); const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); + popScope(context); return [[...headerStatements, ...bodyStatements], scope]; } diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 6689e19e5..a2ae887d6 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -14,24 +14,28 @@ import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; -import { transformArrayBindingElement, transformVariableDeclaration } from "../variable-declaration"; +import { + transformBindingPattern, + transformArrayBindingElement, + transformVariableDeclaration, +} from "../variable-declaration"; import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; function transformForOfInitializer( context: TransformationContext, initializer: ts.ForInitializer, - expression: lua.Expression -): lua.Statement | undefined { + expression: lua.Identifier +): lua.Statement[] { if (ts.isVariableDeclarationList(initializer)) { const binding = getVariableDeclarationBinding(initializer); // Declaration of new variable if (ts.isArrayBindingPattern(binding)) { if (binding.elements.length === 0) { // Ignore empty destructuring assignment - return undefined; + return []; } - expression = createUnpackCall(context, expression, initializer); + return transformBindingPattern(context, binding, expression); } else if (ts.isObjectBindingPattern(binding)) { throw UnsupportedObjectDestructuringInForOf(initializer); } @@ -39,26 +43,29 @@ function transformForOfInitializer( const variableStatements = transformVariableDeclaration(context, initializer.declarations[0]); if (variableStatements[0]) { // we can safely assume that for vars are not exported and therefore declarationstatenents - return lua.createVariableDeclarationStatement( - (variableStatements[0] as lua.VariableDeclarationStatement).left, - expression - ); + return [ + lua.createVariableDeclarationStatement( + (variableStatements[0] as lua.VariableDeclarationStatement).left, + expression + ), + ]; } else { throw MissingForOfVariables(initializer); } } else { // Assignment to existing variable let variables: lua.AssignmentLeftHandSideExpression | lua.AssignmentLeftHandSideExpression[]; + let valueExpression: lua.Expression = expression; if (ts.isArrayLiteralExpression(initializer)) { if (initializer.elements.length > 0) { - expression = createUnpackCall(context, expression, initializer); + valueExpression = createUnpackCall(context, expression, initializer); variables = castEach( initializer.elements.map(e => context.transformExpression(e)), lua.isAssignmentLeftHandSideExpression ); } else { // Ignore empty destructring assignment - return undefined; + return []; } } else if (ts.isObjectLiteralExpression(initializer)) { throw UnsupportedObjectDestructuringInForOf(initializer); @@ -66,7 +73,7 @@ function transformForOfInitializer( variables = cast(context.transformExpression(initializer), lua.isAssignmentLeftHandSideExpression); } - return lua.createAssignmentStatement(variables, expression); + return [lua.createAssignmentStatement(variables, valueExpression)]; } } @@ -178,7 +185,7 @@ function transformForOfLuaIteratorStatement( const valueVariable = lua.createIdentifier("____value"); const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); if (initializer) { - block.statements.splice(0, 0, initializer); + block.statements.splice(0, 0, ...initializer); } return lua.createForInStatement(block, [valueVariable], [luaIterator]); } @@ -198,7 +205,7 @@ function transformForOfArrayStatement( valueVariable = lua.createIdentifier("____values"); const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); if (initializer) { - block.statements.unshift(initializer); + block.statements.unshift(...initializer); } } else { valueVariable = transformIdentifier(context, binding); @@ -208,7 +215,7 @@ function transformForOfArrayStatement( valueVariable = lua.createIdentifier("____value"); const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); if (initializer) { - block.statements.unshift(initializer); + block.statements.unshift(...initializer); } } @@ -244,7 +251,7 @@ function transformForOfIteratorStatement( const valueVariable = lua.createIdentifier("____value"); const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); if (initializer) { - block.statements.unshift(initializer); + block.statements.unshift(...initializer); } return lua.createForInStatement( diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 74bd4a7a9..d198362ba 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -11,6 +11,7 @@ export const transformSwitchStatement: FunctionVisitor = (st } const scope = pushScope(context, ScopeType.Switch); + // Give the switch a unique name to prevent nested switches from acting up. const switchName = `____switch${scope.id}`; const switchVariable = lua.createIdentifier(switchName); diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index c02d8ab1d..95b7a5c24 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -120,6 +120,92 @@ export function transformBindingPattern( return result; } +export function transformBindingVariableDeclaration( + context: TransformationContext, + bindingPattern: ts.BindingPattern, + initializer?: ts.Expression +): lua.Statement[] { + const statements: lua.Statement[] = []; + + // For object, nested or rest bindings fall back to transformBindingPattern + const isComplexBindingElement = (e: ts.ArrayBindingElement) => + ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken); + + if (ts.isObjectBindingPattern(bindingPattern) || bindingPattern.elements.some(isComplexBindingElement)) { + let table: lua.Identifier; + if (initializer !== undefined && ts.isIdentifier(initializer)) { + table = transformIdentifier(context, initializer); + } else { + // Contain the expression in a temporary variable + table = lua.createAnonymousIdentifier(); + if (initializer) { + statements.push( + lua.createVariableDeclarationStatement(table, context.transformExpression(initializer)) + ); + } + } + statements.push(...transformBindingPattern(context, bindingPattern, table)); + return statements; + } + + const vars = + bindingPattern.elements.length > 0 + ? bindingPattern.elements.map(e => transformArrayBindingElement(context, e)) + : lua.createAnonymousIdentifier(); + + if (initializer) { + if (isTupleReturnCall(context, initializer)) { + // Don't unpack @tupleReturn annotated functions + statements.push( + ...createLocalOrExportedOrGlobalDeclaration( + context, + vars, + context.transformExpression(initializer), + initializer + ) + ); + } else if (ts.isArrayLiteralExpression(initializer)) { + // Don't unpack array literals + const values = + initializer.elements.length > 0 + ? initializer.elements.map(e => context.transformExpression(e)) + : lua.createNilLiteral(); + statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, values, initializer)); + } else { + // local vars = this.transpileDestructingAssignmentValue(node.initializer); + const unpackedInitializer = createUnpackCall( + context, + context.transformExpression(initializer), + initializer + ); + statements.push( + ...createLocalOrExportedOrGlobalDeclaration(context, vars, unpackedInitializer, initializer) + ); + } + } else { + statements.push( + ...createLocalOrExportedOrGlobalDeclaration(context, vars, lua.createNilLiteral(), initializer) + ); + } + + for (const element of bindingPattern.elements) { + if (!ts.isOmittedExpression(element) && element.initializer) { + const variableName = transformIdentifier(context, element.name as ts.Identifier); + const identifier = addExportToIdentifier(context, variableName); + statements.push( + lua.createIfStatement( + lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), + lua.createBlock([ + lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)), + ]) + ) + ); + } + } + + return statements; +} + // TODO: FunctionVisitor export function transformVariableDeclaration( context: TransformationContext, @@ -137,86 +223,7 @@ export function transformVariableDeclaration( const value = statement.initializer && context.transformExpression(statement.initializer); return createLocalOrExportedOrGlobalDeclaration(context, identifierName, value, statement); } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { - const statements: lua.Statement[] = []; - - // For object, nested or rest bindings fall back to transformBindingPattern - if ( - ts.isObjectBindingPattern(statement.name) || - statement.name.elements.some(e => ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken)) - ) { - let table: lua.Identifier; - if (statement.initializer !== undefined && ts.isIdentifier(statement.initializer)) { - table = transformIdentifier(context, statement.initializer); - } else { - // Contain the expression in a temporary variable - table = lua.createAnonymousIdentifier(); - if (statement.initializer) { - statements.push( - lua.createVariableDeclarationStatement( - table, - context.transformExpression(statement.initializer) - ) - ); - } - } - statements.push(...transformBindingPattern(context, statement.name, table)); - return statements; - } - - const vars = - statement.name.elements.length > 0 - ? statement.name.elements.map(e => transformArrayBindingElement(context, e)) - : lua.createAnonymousIdentifier(statement.name); - - if (statement.initializer) { - if (isTupleReturnCall(context, statement.initializer)) { - // Don't unpack @tupleReturn annotated functions - statements.push( - ...createLocalOrExportedOrGlobalDeclaration( - context, - vars, - context.transformExpression(statement.initializer), - statement - ) - ); - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Don't unpack array literals - const values = - statement.initializer.elements.length > 0 - ? statement.initializer.elements.map(e => context.transformExpression(e)) - : lua.createNilLiteral(); - statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, values, statement)); - } else { - // local vars = this.transpileDestructingAssignmentValue(node.initializer); - const initializer = createUnpackCall( - context, - context.transformExpression(statement.initializer), - statement.initializer - ); - statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, initializer, statement)); - } - } else { - statements.push( - ...createLocalOrExportedOrGlobalDeclaration(context, vars, lua.createNilLiteral(), statement) - ); - } - - for (const element of statement.name.elements) { - if (!ts.isOmittedExpression(element) && element.initializer) { - const variableName = transformIdentifier(context, element.name as ts.Identifier); - const identifier = addExportToIdentifier(context, variableName); - statements.push( - lua.createIfStatement( - lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), - lua.createBlock([ - lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)), - ]) - ) - ); - } - } - - return statements; + return transformBindingVariableDeclaration(context, statement.name, statement.initializer); } else { return assertNever(statement.name); } diff --git a/test/unit/decorators/tupleReturn.spec.ts b/test/unit/decorators/tupleReturn.spec.ts index 803acad4a..ca234cfbc 100644 --- a/test/unit/decorators/tupleReturn.spec.ts +++ b/test/unit/decorators/tupleReturn.spec.ts @@ -346,65 +346,60 @@ test("Tuple Return vs Non-Tuple Return Overload", () => { }); test("TupleReturn assignment", () => { - const code = ` + const lua = util.testFunction` /** @tupleReturn */ declare function abc(this: void): number[] let [a,b] = abc(); - `; + `.getMainLuaCodeChunk(); - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = abc()"); + expect(lua).toContain("local a, b = abc()"); }); test("TupleReturn Single assignment", () => { - const code = ` + const lua = util.testFunction` /** @tupleReturn */ declare function abc(this: void): [number, string]; let a = abc(); a = abc(); - `; + `.getMainLuaCodeChunk(); - const lua = util.transpileString(code); - expect(lua).toBe("local a = ({\n abc()\n})\na = ({\n abc()\n})"); + expect(lua).toContain(`local a = ({\n abc()\n })\n a = ({\n abc()\n })`); }); test("TupleReturn interface assignment", () => { - const code = ` + const lua = util.testFunction` interface def { /** @tupleReturn */ abc(); } declare const jkl : def; let [a,b] = jkl.abc(); - `; + `.getMainLuaCodeChunk(); - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = jkl:abc()"); + expect(lua).toContain("local a, b = jkl:abc()"); }); test("TupleReturn namespace assignment", () => { - const code = ` + const lua = util.testFunction` declare namespace def { /** @tupleReturn */ function abc(this: void) {} } let [a,b] = def.abc(); - `; + `.getMainLuaCodeChunk(); - const lua = util.transpileString(code); - expect(lua).toBe("local a, b = def.abc()"); + expect(lua).toContain("local a, b = def.abc()"); }); test("TupleReturn method assignment", () => { - const code = ` + const lua = util.testFunction` declare class def { /** @tupleReturn */ abc() { return [1,2,3]; } } const jkl = new def(); let [a,b] = jkl.abc(); - `; + `.getMainLuaCodeChunk(); - const lua = util.transpileString(code); - expect(lua).toBe('require("lualib_bundle");\nlocal jkl = __TS__New(def)\nlocal a, b = jkl:abc()'); + expect(lua).toContain("local a, b = jkl:abc()"); }); test("TupleReturn functional", () => { diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index ed6d5219d..9ff2c746a 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -41,6 +41,16 @@ test.each([ `.expectToMatchJsResult(); }); +test("in function parameter creates local variables", () => { + const builder = util.testModule` + function test({ a, b }: any) {} + `; + + const code = builder.getMainLuaCodeChunk(); + expect(code).toContain("local a ="); + expect(code).toContain("local b ="); +}); + test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { util.testFunction` let ${allBindings}; @@ -78,6 +88,14 @@ test.each(assignmentTestCases)("in assignment expression (%p)", ({ binding, valu `.expectToMatchJsResult(); }); +test.each(["[]", "{}"])("empty binding pattern", bindingPattern => { + util.testFunction` + let i = 1; + const ${bindingPattern} = [i++]; + return i; + `.expectToMatchJsResult(); +}); + describe("array destructuring optimization", () => { // TODO: Try to generalize optimization logic between declaration and assignment and make more generic tests diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 6e67074d3..edf381148 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -7,174 +7,156 @@ import { } from "../../src/transformation/utils/errors"; import * as util from "../util"; -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("while (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test("while", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; let i = 0; while (i < arrTest.length) { arrTest[i] = arrTest[i] + 1; i++; } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])("while with continue (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; - while (i < arrTest.length) { - if (i % 2 == 0) { - i++; +test("while with continue", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3, 4]; + let i = 0; + while (i < arrTest.length) { + if (i % 2 == 0) { + i++; + continue; + } + let j = 2; + while (j > 0) { + if (j == 2) { + j-- continue; } - let j = 2; - while (j > 0) { - if (j == 2) { - j-- - continue; - } - arrTest[i] = j; - j--; - } - - i++; + arrTest[i] = j; + j--; } - return JSONStringify(arrTest);` - ); - expect(result).toBe(JSON.stringify(expected)); + i++; + } + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 1, 2, 1, 4] }])("dowhile with continue (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; +test("dowhile with continue", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3, 4]; + let i = 0; + do { + if (i % 2 == 0) { + i++; + continue; + } + let j = 2; do { - if (i % 2 == 0) { - i++; + if (j == 2) { + j-- continue; } - let j = 2; - do { - if (j == 2) { - j-- - continue; - } - arrTest[i] = j; - j--; - } while (j > 0) + arrTest[i] = j; + j--; + } while (j > 0) - i++; - } while (i < arrTest.length) - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + i++; + } while (i < arrTest.length) + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test("for", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; for (let i = 0; i < arrTest.length; ++i) { arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` - ); - expect(result).toBe(JSON.stringify(expected)); + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("for with expression (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i: number; - for (i = 0 * 1; i < arrTest.length; ++i) { - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); - expect(result).toBe(JSON.stringify(expected)); +test("for with expression", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; + let i: number; + for (i = 0 * 1; i < arrTest.length; ++i) { + arrTest[i] = arrTest[i] + 1; + } + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])("for with continue (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - for (let i = 0; i < arrTest.length; i++) { - if (i % 2 == 0) { - continue; - } +test("for with continue", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3, 4]; + for (let i = 0; i < arrTest.length; i++) { + if (i % 2 == 0) { + continue; + } - for (let j = 0; j < 2; j++) { - if (j == 1) { - continue; - } - arrTest[i] = j; + for (let j = 0; j < 2; j++) { + if (j == 1) { + continue; } + arrTest[i] = j; } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + } + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forMirror (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - for (let i = 0; arrTest.length > i; i++) { - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); +test("forMirror", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; + for (let i = 0; arrTest.length > i; i++) { + arrTest[i] = arrTest[i] + 1; + } + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [0, 1, 2, 3] }])("forBreak (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; +test("forBreak", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; for (let i = 0; i < arrTest.length; ++i) { break; arrTest[i] = arrTest[i] + 1; } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoDeclarations (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; - for (; i < arrTest.length; ++i) { - arrTest[i] = arrTest[i] + 1; - } - return JSONStringify(arrTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); +test("forNoDeclarations", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; + let i = 0; + for (; i < arrTest.length; ++i) { + arrTest[i] = arrTest[i] + 1; + } + return arrTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3], expected: [1, 2, 3, 4] }])("forNoCondition (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let arrTest = ${JSON.stringify(inp)}; - let i = 0; - for (;; ++i) { - if (i >= arrTest.length) { - break; - } - - arrTest[i] = arrTest[i] + 1; +test("forNoCondition", () => { + util.testFunction` + let arrTest = [0, 1, 2, 3]; + let i = 0; + for (;; ++i) { + if (i >= arrTest.length) { + break; } - return JSONStringify(arrTest);` - ); - expect(result).toBe(JSON.stringify(expected)); + arrTest[i] = arrTest[i] + 1; + } + return arrTest; + `.expectToMatchJsResult(); }); -test("forNoPostExpression (%p)", () => { +test("forNoPostExpression", () => { util.testFunction` let arrTest = [0, 1, 2, 3]; let i = 0; @@ -202,7 +184,7 @@ test.each([ { inp: [0, 1, 2, 3], header: "let i = arrTest.length - 1; i > 0; i -= 2" }, ])("forheader (%p)", ({ inp, header }) => { util.testFunction` - let arrTest = ${JSON.stringify(inp)}; + let arrTest = ${util.formatCode(inp)}; for (${header}) { arrTest[i] = arrTest[i] + 1; } @@ -287,92 +269,78 @@ test("Tuple loop", () => { `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof existing variable (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; - let arrResultTest = []; - let value: number; - for (value of objTest) { - arrResultTest.push(value + 1) - } - return JSONStringify(arrResultTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); +test("forof existing variable", () => { + util.testFunction` + let objTest = [0, 1, 2]; + let arrResultTest = []; + let value: number; + for (value of objTest) { + arrResultTest.push(value + 1) + } + return arrResultTest; + `.expectToMatchJsResult(); }); -test.each([ - { - inp: [ - [1, 2], - [2, 3], - [3, 4], - ], - expected: [3, 5, 7], - }, -])("forof destructing (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; - let arrResultTest = []; - for (let [a,b] of objTest) { - arrResultTest.push(a + b) - } - return JSONStringify(arrResultTest);` - ); +test("forof destructing", () => { + const input = [ + [1, 2], + [2, 3], + [3, 4], + ]; - expect(result).toBe(JSON.stringify(expected)); + util.testFunction` + let objTest = ${util.formatCode(input)}; + let arrResultTest = []; + for (let [a,b] of objTest) { + arrResultTest.push(a + b) + } + return arrResultTest; + `.expectToMatchJsResult(); }); -test.each([ - { - inp: [ - [1, 2], - [2, 3], - [3, 4], - ], - expected: [3, 5, 7], - }, -])("forof destructing with existing variables (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute(` - let objTest = ${JSON.stringify(inp)}; +test("forof destructing with existing variables", () => { + const input = [ + [1, 2], + [2, 3], + [3, 4], + ]; + + util.testFunction` + let objTest = ${util.formatCode(input)}; let arrResultTest = []; let a: number; let b: number; for ([a,b] of objTest) { arrResultTest.push(a + b) } - return JSONStringify(arrResultTest); - `); - - expect(result).toBe(JSON.stringify(expected)); + return arrResultTest; + `.expectToMatchJsResult(); }); -test.each([{ inp: [0, 1, 2, 3, 4], expected: [0, 0, 2, 0, 4] }])("forof with continue (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let testArr = ${JSON.stringify(inp)}; - let a = 0; - for (let i of testArr) { - if (i % 2 == 0) { - a++; - continue; - } - - for (let j of [0, 1]) { - if (j == 1) { - continue; - } - testArr[a] = j; - } +test("forof with continue", () => { + util.testFunction` + let testArr = [0, 1, 2, 3, 4]; + let a = 0; + for (let i of testArr) { + if (i % 2 == 0) { a++; + continue; } - return JSONStringify(testArr);` - ); - expect(result).toBe(JSON.stringify(expected)); + for (let j of [0, 1]) { + if (j == 1) { + continue; + } + testArr[a] = j; + } + a++; + } + return testArr; + `.expectToMatchJsResult(); }); test("forof with iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; function iter(): IterableIterator { let i = 0; @@ -386,18 +354,11 @@ test("forof with iterator", () => { result += e; } return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); + `.expectToMatchJsResult(); }); test("forof with iterator and existing variable", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; function iter(): IterableIterator { let i = 0; @@ -412,18 +373,11 @@ test("forof with iterator and existing variable", () => { result += e; } return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("abc"); + `.expectToMatchJsResult(); }); test("forof destructuring with iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; function iter(): IterableIterator<[string, string]> { let i = 0; @@ -437,18 +391,11 @@ test("forof destructuring with iterator", () => { result += a + b; } return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); + `.expectToMatchJsResult(); }); test("forof destructuring with iterator and existing variables", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; function iter(): IterableIterator<[string, string]> { let i = 0; @@ -464,18 +411,11 @@ test("forof destructuring with iterator and existing variables", () => { result += a + b; } return result; - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); - expect(result).toBe("0a1b2c"); + `.expectToMatchJsResult(); }); test("forof array which modifies length", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; let result = ""; for (const v of arr) { @@ -484,9 +424,8 @@ test("forof array which modifies length", () => { } result += v; } - return result;`; - - expect(util.transpileAndExecute(code)).toBe("abcd"); + return result; + `.expectToMatchJsResult(); }); test.each([ @@ -505,8 +444,18 @@ test.each([ ); }); +test("forof nested destructuring", () => { + util.testFunction` + let result = 0; + for (const [[x]] of [[[1]]]) { + result = x; + } + return result; + `.expectToMatchJsResult(); +}); + test("forof with array typed as iterable", () => { - const code = ` + util.testFunction` function foo(): Iterable { return ["A", "B", "C"]; } @@ -515,8 +464,7 @@ test("forof with array typed as iterable", () => { result += x; } return result; - `; - expect(util.transpileAndExecute(code)).toBe("ABC"); + `.expectToMatchJsResult(); }); describe("for...of empty destructuring", () => { @@ -617,18 +565,17 @@ test.each([ }); test("do...while", () => { - const code = ` + util.testFunction` let result = 0; do { ++result; } while (result < 2); return result; - `; - expect(util.transpileAndExecute(code)).toBe(2); + `.expectToMatchJsResult(); }); test("do...while scoping", () => { - const code = ` + util.testFunction` let x = 0; let result = 0; do { @@ -636,20 +583,19 @@ test("do...while scoping", () => { ++result; } while (x === 0 && result < 2); return result; - `; - expect(util.transpileAndExecute(code)).toBe(2); + `.expectToMatchJsResult(); }); test("do...while double-negation", () => { - const code = ` + const builder = util.testFunction` let result = 0; do { ++result; } while (!(result >= 2)); return result; - `; - expect(util.transpileString(code)).not.toMatch("not"); - expect(util.transpileAndExecute(code)).toBe(2); + `.expectToMatchJsResult(); + + expect(builder.getMainLuaCodeChunk()).not.toMatch("not"); }); test("for...in with pre-defined variable", () => { From 70394c7d2f3e52c889e78c8bf42691384a9a9a66 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 2 Jan 2020 22:58:10 +0100 Subject: [PATCH 212/764] 0.30.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff7c19908..4c3aaaff7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.29.1", + "version": "0.30.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a7f6ba498..ae9381834 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.29.1", + "version": "0.30.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From a852f9cf77ce610ffc413bbcc6f99ee0dbf56724 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 2 Jan 2020 23:11:27 +0100 Subject: [PATCH 213/764] fixed some workflow issues --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 6 ++++-- test/tsconfig.json | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 35c7ec129..4fe1d6dcf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: Use Node.js 12.13.1 uses: actions/setup-node@v1 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e3edaabbe..e6e9f26fd 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,9 +10,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v2 + - name: Use Node.js 12.13.1 + uses: actions/setup-node@v1 with: + node-version: 12.13.1 registry-url: "https://registry.npmjs.org" - run: npm ci - run: npm run build diff --git a/test/tsconfig.json b/test/tsconfig.json index ecdd3263e..5388f9434 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -5,6 +5,7 @@ "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, + "newLine": "LF", "target": "es2019", "lib": ["es2019"], "types": ["node", "jest"], From 7c58f2371f1e86d64941f1ca8f24f2728da4c8a4 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 2 Jan 2020 23:11:41 +0100 Subject: [PATCH 214/764] CHANGELOG.md 0.30.0 --- CHANGELOG.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5b257bee..301a8ebda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## 0.30.0 + +- **Breaking:** We dropped support for `var` variables. If you still have any `var` variable declarations, they will not break compilation, but they will behave as if they were declared using `let`. +- **Breaking:** We now depend on Node.js >= 12.13.0 +- Added support for string `trimLeft`, `trimRight`, `trimStart` and `trimEnd`. +- Added support for `console.error`, `console.warn` and `console.info` , they will all be transpiled to Lua's `print`. +- Avoided exporting anonymous identifiers. +- Fixed an issue when assigning to an already-exported variable. +- Math.atan2 will now be transpiled to the correct Lua atan2 (or atan for 5.3) method. +- Fixed various destructuring issues. +- Fixed incorrect error for intersection types containing built-ins (like `number` or `string`) +- Modules containing `import` or `export` will now always be recognized as module to match TypeScript's logic. +- Fixed `true` not being recognized as lua keyword. +- Fixed inaccuracies in switch case variable scoping. +- Fixed various problems with variables being global instead of local. + +### Internal: + +- Refactored transformation pipeline from one big LuaTransformer class to many small modules. +- Moved class construction methods from transformer to LuaLib. +- Upgraded dependencies. + ## 0.29.0 - Added bundling support using options `luaBundle` and `luaBundleEntry` (so **not** TS's outFile). This will bundle all output files into one single bundle file, with _luaBundleEntry_ as entry point. For more information on these options see https://github.com/TypeScriptToLua/TypeScriptToLua/wiki#tstl-specific-options From d830d357c4774913483631cd5ed9de70dd781dae Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 2 Jan 2020 23:18:42 +0100 Subject: [PATCH 215/764] 0.30.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c3aaaff7..00e190417 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.30.0", + "version": "0.30.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index ae9381834..fa3892d38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.30.0", + "version": "0.30.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 13817df0c6d32c16a45e5157a28f55a0f9cbb837 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 2 Jan 2020 23:33:08 +0100 Subject: [PATCH 216/764] Fixed error in 0.30.0 changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 301a8ebda..d21cd0d6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.30.0 -- **Breaking:** We dropped support for `var` variables. If you still have any `var` variable declarations, they will not break compilation, but they will behave as if they were declared using `let`. +- **Breaking:** We dropped support for `var` variables. If you still have any `var` variable declarations, please use `let` or `const` instead. - **Breaking:** We now depend on Node.js >= 12.13.0 - Added support for string `trimLeft`, `trimRight`, `trimStart` and `trimEnd`. - Added support for `console.error`, `console.warn` and `console.info` , they will all be transpiled to Lua's `print`. From 17bb60fddb4a7007ceaa5359c5a1f7df078e263f Mon Sep 17 00:00:00 2001 From: Kirill Artemov Date: Thu, 9 Jan 2020 20:54:52 +0100 Subject: [PATCH 217/764] Switch case goto chain is now transpiled to an elseif chain (#791) * Switch case goto chain is now transpiled to an elseif chain instead of multiple ifs * Switch case goto chain is now transpiled to an elseif chain instead of multiple ifs --- src/transformation/visitors/switch.ts | 11 +++-- .../__snapshots__/conditionals.spec.ts.snap | 41 +++++++++++++++++++ test/unit/conditionals.spec.ts | 31 +++++++++++++- 3 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 test/unit/__snapshots__/conditionals.spec.ts.snap diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index d198362ba..941d8182d 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -19,7 +19,9 @@ export const transformSwitchStatement: FunctionVisitor = (st let statements: lua.Statement[] = []; const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); - for (const [index, clause] of caseClauses.entries()) { + + // Starting from the back, concatenating ifs into one big if/elseif statement + const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => { // If the clause condition holds, go to the correct label const condition = lua.createBinaryExpression( switchVariable, @@ -28,8 +30,11 @@ export const transformSwitchStatement: FunctionVisitor = (st ); const goto = lua.createGotoStatement(`${switchName}_case_${index}`); - const conditionalGoto = lua.createIfStatement(condition, lua.createBlock([goto])); - statements.push(conditionalGoto); + return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition); + }, undefined as lua.IfStatement | undefined); + + if (concatenatedIf) { + statements.push(concatenatedIf); } const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause); diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/conditionals.spec.ts.snap new file mode 100644 index 000000000..e1c59f48f --- /dev/null +++ b/test/unit/__snapshots__/conditionals.spec.ts.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`array 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = -1 + local ____switch3 = 2 + if ____switch3 == 0 then + goto ____switch3_case_0 + elseif ____switch3 == 1 then + goto ____switch3_case_1 + elseif ____switch3 == 2 then + goto ____switch3_case_2 + end + goto ____switch3_end + ::____switch3_case_0:: + do + do + result = 200 + goto ____switch3_end + end + end + ::____switch3_case_1:: + do + do + result = 100 + goto ____switch3_end + end + end + ::____switch3_case_2:: + do + do + result = 1 + goto ____switch3_end + end + end + ::____switch3_end:: + return result +end +return ____exports" +`; diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 54534e9c8..a11fd0595 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -184,7 +184,7 @@ test("variable in nested scope does not interfere with case scope", () => { `.expectToMatchJsResult(); }); -test.only("switch using variable re-declared in cases", () => { +test("switch using variable re-declared in cases", () => { util.testFunction` let foo: number = 0; switch (foo) { @@ -311,6 +311,35 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { `.expectToMatchJsResult(); }); +test("switch uses elseif", () => { + test("array", () => { + util.testFunction` + let result: number = -1; + + switch (2 as number) { + case 0: { + result = 200; + break; + } + + case 1: { + result = 100; + break; + } + + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); +}); + test("switch not allowed in 5.1", () => { util.testFunction` switch ("abc") {} From ea07f801b5a00f344d71a25923a754644212d43e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Jan 2020 22:14:57 +0100 Subject: [PATCH 218/764] Feature/array includes (#796) * Added tests * Implemented array.includes * PR feedback --- src/LuaLib.ts | 1 + src/lualib/ArrayIncludes.ts | 21 +++++++++++++++++++ src/transformation/builtins/array.ts | 2 ++ test/unit/builtins/array.spec.ts | 31 ++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 src/lualib/ArrayIncludes.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index efafbab50..5087bd7d0 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -8,6 +8,7 @@ export enum LuaLibFeature { ArrayForEach = "ArrayForEach", ArrayFind = "ArrayFind", ArrayFindIndex = "ArrayFindIndex", + ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts new file mode 100644 index 000000000..a9ff19ba4 --- /dev/null +++ b/src/lualib/ArrayIncludes.ts @@ -0,0 +1,21 @@ +// https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.includes +function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boolean { + const len = this.length; + let k = fromIndex; + + if (fromIndex < 0) { + k = len + fromIndex; + } + + if (k < 0) { + k = 0; + } + + for (const i of forRange(k, len)) { + if (this[i] === searchElement) { + return true; + } + } + + return false; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 5cc0ca01e..a13d500aa 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -40,6 +40,8 @@ export function transformArrayPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.ArrayFind, node, caller, ...params); case "findIndex": return transformLuaLibFunction(context, LuaLibFeature.ArrayFindIndex, node, caller, ...params); + case "includes": + return transformLuaLibFunction(context, LuaLibFeature.ArrayIncludes, node, caller, ...params); case "indexOf": return transformLuaLibFunction(context, LuaLibFeature.ArrayIndexOf, node, caller, ...params); case "map": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 463d0d1dc..be3774d54 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -389,6 +389,37 @@ test.each([ `.expectToMatchJsResult(); }); +test.each([ + { array: [1, 2, 3], includes: 2 }, + { array: [1, 2, 3, 2, 2], includes: 2 }, + { array: [1, 2, 3], includes: 4 }, + { array: ["a", "b", "c"], includes: "d" }, + { array: [[1], [2], [3]], includes: [2] }, + { array: [1, [2], 3], includes: 2 }, +])("array.includes (%p)", ({ array, includes }) => { + util.testExpressionTemplate`${array}.includes(${includes})`.expectToMatchJsResult(); +}); + +test("array.includes reference", () => { + util.testFunction` + const inst = [2]; + return [[1], [3], inst].includes(inst); + `.expectToMatchJsResult(); +}); + +test.each([ + { array: [1, 2, 3], includes: 2, fromIndex: 0 }, + { array: [1, 2, 3], includes: 2, fromIndex: 1 }, + { array: [1, 2, 3], includes: 2, fromIndex: 2 }, + { array: [1, 2, 3], includes: 2, fromIndex: 3 }, + { array: [1, 2, 3], includes: 2, fromIndex: -1 }, + { array: [1, 2, 3], includes: 2, fromIndex: -2 }, + { array: [1, 2, 3], includes: 2, fromIndex: -3 }, + { array: [1, 2, 3], includes: 2, fromIndex: -4 }, +])("array.includes with fromIndex (%p)", ({ array, includes, fromIndex }) => { + util.testExpressionTemplate`${array}.includes(${includes}, ${fromIndex})`.expectToMatchJsResult(); +}); + test.each([ { array: [] }, { array: ["test1"] }, From 0f82db63ff25c2e362386cd8f990be565d2277e9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 17 Jan 2020 18:24:54 +0100 Subject: [PATCH 219/764] Fixed inconsistent scoping of top-level variable declarations (#795) * Fixed inconsistent scoping of top-level variable declarations * Added let variables in transformation test * Added handling for variables in block scope, addressed some PR feedback * simplified ast declaration logic * reverted if statement refactor, some changes to tests * Added functional test to check local variables are not in scope * Made object literal tests functional * PR comments * Removed no longer needed getCurrentNamespace * Removed obsolete tests --- src/transformation/utils/lua-ast.ts | 13 ++-- src/transformation/visitors/namespace.ts | 2 +- .../__snapshots__/transformation.spec.ts.snap | 48 +++++++++---- .../transformation/blockScopeVariables.ts | 5 ++ .../transformation/topLevelVariables.ts | 11 +++ test/unit/assignments.spec.ts | 20 ++++-- test/unit/objectLiteral.spec.ts | 67 +++++++++---------- 7 files changed, 104 insertions(+), 62 deletions(-) create mode 100644 test/translation/transformation/blockScopeVariables.ts create mode 100644 test/translation/transformation/topLevelVariables.ts diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index a04c69035..effc18814 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -1,11 +1,10 @@ -import * as ts from "typescript"; import * as assert from "assert"; +import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { getCurrentNamespace } from "../visitors/namespace"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; -import { findScope, peekScope, ScopeType } from "./scope"; +import { peekScope, ScopeType } from "./scope"; import { isFunctionType } from "./typescript"; export type OneToManyVisitorResult = T | T[] | undefined; @@ -122,7 +121,6 @@ export function createLocalOrExportedOrGlobalDeclaration( let declaration: lua.VariableDeclarationStatement | undefined; let assignment: lua.AssignmentStatement | undefined; - const isVariableDeclaration = tsOriginal !== undefined && ts.isVariableDeclaration(tsOriginal); const isFunctionDeclaration = tsOriginal !== undefined && ts.isFunctionDeclaration(tsOriginal); const identifiers = Array.isArray(lhs) ? lhs : [lhs]; @@ -143,11 +141,10 @@ export function createLocalOrExportedOrGlobalDeclaration( ); } } else { - const insideFunction = findScope(context, ScopeType.Function) !== undefined; - - if (context.isModule || getCurrentNamespace(context) || insideFunction || isVariableDeclaration) { - const scope = peekScope(context); + const scope = peekScope(context); + const isTopLevelVariable = scope.type === ScopeType.File; + if (context.isModule || !isTopLevelVariable) { const isPossibleWrappedFunction = !isFunctionDeclaration && tsOriginal && diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 5835f9112..fc269f5e7 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -46,8 +46,8 @@ function moduleHasEmittedBody( return false; } +// Static context -> namespace dictionary keeping the current namespace for each transformation context const currentNamespaces = new WeakMap(); -export const getCurrentNamespace = (context: TransformationContext) => currentNamespaces.get(context); export const transformModuleDeclaration: FunctionVisitor = (node, context) => { const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node)); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 6d64751eb..f4e2ce661 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,18 +1,27 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Transformation (blockScopeVariables) 1`] = ` +"do + local a = 1 + local b = 1 + local ____ = {c = 1} + local c = ____.c +end" +`; + exports[`Transformation (characterEscapeSequence) 1`] = ` -"local quoteInDoubleQuotes = \\"' ' '\\" -local quoteInTemplateString = \\"' ' '\\" -local doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -local doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -local doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" -local backQuoteInQuotes = \\"\` \` \`\\" -local backQuoteInDoubleQuotes = \\"\` \` \`\\" -local backQuoteInTemplateString = \\"\` \` \`\\" -local escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -local escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -local escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -local nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\"" +"quoteInDoubleQuotes = \\"' ' '\\" +quoteInTemplateString = \\"' ' '\\" +doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" +doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" +doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" +backQuoteInQuotes = \\"\` \` \`\\" +backQuoteInDoubleQuotes = \\"\` \` \`\\" +backQuoteInTemplateString = \\"\` \` \`\\" +escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" +escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" +escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" +nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\"" `; exports[`Transformation (classExtension1) 1`] = ` @@ -244,7 +253,7 @@ ____exports.foo = \\"bar\\" return ____exports" `; -exports[`Transformation (modulesVariableNoExport) 1`] = `"local foo = \\"bar\\""`; +exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; exports[`Transformation (namespacePhantom) 1`] = ` "function nsMember(self) @@ -257,6 +266,19 @@ exports[`Transformation (returnDefault) 1`] = ` end" `; +exports[`Transformation (topLevelVariables) 1`] = ` +"obj = {value1 = 1, value2 = 2} +value1 = obj.value1 +value2 = obj.value2 +obj2 = {value3 = 1, value4 = 2} +value3 = obj2.value3 +value4 = obj2.value4 +function fun1(self) +end +fun2 = function() +end" +`; + exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` "local ____exports = {} local x = require(\\"module\\") diff --git a/test/translation/transformation/blockScopeVariables.ts b/test/translation/transformation/blockScopeVariables.ts new file mode 100644 index 000000000..7623f0efa --- /dev/null +++ b/test/translation/transformation/blockScopeVariables.ts @@ -0,0 +1,5 @@ +{ + const a = 1; + const [b] = [1]; + const { c } = { c: 1 }; +} diff --git a/test/translation/transformation/topLevelVariables.ts b/test/translation/transformation/topLevelVariables.ts new file mode 100644 index 000000000..5782c4cf4 --- /dev/null +++ b/test/translation/transformation/topLevelVariables.ts @@ -0,0 +1,11 @@ +const obj = { value1: 1, value2: 2 }; +const value1 = obj.value1; +const { value2 } = obj; + +let noValueLet; +let obj2 = { value3: 1, value4: 2 }; +let value3 = obj2.value3; +let { value4 } = obj2; + +function fun1(): void {} +const fun2 = () => {}; diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index c559690d0..ce7abd622 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1,13 +1,21 @@ import * as util from "../util"; -test("const declaration", () => { - const lua = util.transpileString(`const foo = true;`); - expect(lua).toBe(`local foo = true`); +test.each(["const", "let"])("%s declaration not top-level is not global", declarationKind => { + util.testModule` + { + ${declarationKind} foo = true; + } + // @ts-ignore + return (globalThis as any).foo; + `.expectToEqual(undefined); }); -test("let declaration", () => { - const lua = util.transpileString(`let foo = true;`); - expect(lua).toBe(`local foo = true`); +test.each(["const", "let"])("%s declaration top-level is global", declarationKind => { + util.testModule` + ${declarationKind} foo = true; + // @ts-ignore + return (globalThis as any).foo; + `.expectToEqual(true); }); test("var declaration is disallowed", () => { diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index b4bcb3d4e..203b05780 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -1,66 +1,65 @@ import * as util from "../util"; -test.each([ - { inp: `{a:3,b:"4"}`, out: '{a = 3, b = "4"}' }, - { inp: `{"a":3,b:"4"}`, out: '{a = 3, b = "4"}' }, - { inp: `{["a"]:3,b:"4"}`, out: '{a = 3, b = "4"}' }, - { inp: `{["a"+123]:3,b:"4"}`, out: '{["a" .. 123] = 3, b = "4"}' }, - { inp: `{[myFunc()]:3,b:"4"}`, out: '{\n [myFunc(_G)] = 3,\n b = "4"\n}' }, - { inp: `{x}`, out: `{x = x}` }, -])("Object Literal (%p)", ({ inp, out }) => { - const lua = util.transpileString(`const myvar = ${inp};`); - expect(lua).toBe(`local myvar = ${out}`); +test.each([`{ a: 3, b: "4" }`, `{ "a": 3, b: "4" }`, `{ ["a"]: 3, b: "4" }`, `{ ["a" + 123]: 3, b: "4" }`])( + "Object Literal (%p)", + inp => { + util.testExpression(inp).expectToMatchJsResult(); + } +); + +test("object literal with function call to get key", () => { + util.testFunction` + const myFunc = () => "a"; + return { [myFunc() + "b"]: 3 }; + `.expectToMatchJsResult(); +}); + +test("object literal with shorthand property", () => { + util.testFunction` + const x = 5; + return { x }; + `.expectToMatchJsResult(); }); describe("property shorthand", () => { test("should support property shorthand", () => { - const result = util.transpileAndExecute(` + util.testFunction` const x = 1; const o = { x }; return o.x; - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test.each([NaN, Infinity])("should support %p shorthand", identifier => { - const result = util.transpileAndExecute(`return ({ ${identifier} }).${identifier}`); - - expect(result).toBe(identifier); + util.testExpression`({ ${identifier} }).${identifier}`.expectToMatchJsResult(); }); test("should support _G shorthand", () => { - const result = util.transpileAndExecute( - `return ({ _G })._G.foobar;`, - undefined, - `foobar = "foobar"`, - "declare const _G: any;" - ); - - expect(result).toBe("foobar"); + util.testExpression`({ _G })._G.foobar` + .setTsHeader(`declare const _G: any;`) + .setLuaHeader(`foobar = "foobar"`) + .expectToEqual("foobar"); }); test("should support export property shorthand", () => { - const code = ` + util.testModule` export const x = 1; const o = { x }; export const y = o.x; - `; - expect(util.transpileExecuteAndReturnExport(code, "y")).toBe(1); + `.expectToMatchJsResult(); }); }); test("undefined as object key", () => { - const code = `const foo = {undefined: "foo"}; - return foo.undefined;`; - expect(util.transpileAndExecute(code)).toBe("foo"); + util.testFunction` + const foo = {undefined: "foo"}; + return foo.undefined; + `.expectToMatchJsResult(); }); test.each([`({x: "foobar"}.x)`, `({x: "foobar"}["x"])`, `({x: () => "foobar"}.x())`, `({x: () => "foobar"}["x"]())`])( "object literal property access (%p)", expression => { - const code = `return ${expression}`; - const expectResult = eval(expression); - expect(util.transpileAndExecute(code)).toBe(expectResult); + util.testExpression(expression).expectToMatchJsResult(); } ); From 722268dc7a941b2cd6917c70ed5a8ec2a022c588 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 18 Jan 2020 18:43:49 +0500 Subject: [PATCH 220/764] Drop support for legacy annotations syntax (#805) * Drop support for legacy annotations syntax * Rename `decorators` test directory to `annotations` --- src/transformation/utils/annotations.ts | 49 +++++-------------- .../utils/assignment-validation.ts | 2 +- src/transformation/visitors/access.ts | 2 +- .../visitors/binary-expression/index.ts | 2 +- src/transformation/visitors/class/index.ts | 6 +-- src/transformation/visitors/class/new.ts | 2 +- src/transformation/visitors/class/utils.ts | 2 +- src/transformation/visitors/enum.ts | 2 +- src/transformation/visitors/loops/for-of.ts | 2 +- src/transformation/visitors/lua-table.ts | 10 ++-- src/transformation/visitors/modules/import.ts | 4 +- src/transformation/visitors/namespace.ts | 2 +- .../compileMembersOnly.spec.ts | 0 .../customConstructor.spec.ts | 0 .../extension.spec.ts | 0 .../forRange.spec.ts | 0 .../luaIterator.spec.ts | 0 .../luaTable.spec.ts | 0 .../metaExtension.spec.ts | 0 .../tupleReturn.spec.ts | 0 .../vararg.spec.ts | 0 21 files changed, 31 insertions(+), 54 deletions(-) rename test/unit/{decorators => annotations}/compileMembersOnly.spec.ts (100%) rename test/unit/{decorators => annotations}/customConstructor.spec.ts (100%) rename test/unit/{decorators => annotations}/extension.spec.ts (100%) rename test/unit/{decorators => annotations}/forRange.spec.ts (100%) rename test/unit/{decorators => annotations}/luaIterator.spec.ts (100%) rename test/unit/{decorators => annotations}/luaTable.spec.ts (100%) rename test/unit/{decorators => annotations}/metaExtension.spec.ts (100%) rename test/unit/{decorators => annotations}/tupleReturn.spec.ts (100%) rename test/unit/{decorators => annotations}/vararg.spec.ts (100%) diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 8c7f4ea12..b3b2c0697 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -33,30 +33,7 @@ function createAnnotation(name: string, args: string[]): Annotation | undefined export type AnnotationsMap = Map; -function collectAnnotations( - context: TransformationContext, - source: ts.Symbol | ts.Signature, - annotationsMap: AnnotationsMap -): void { - const comments = source.getDocumentationComment(context.checker); - const oldStyleAnnotations = comments - .filter(comment => comment.kind === "text") - .map(comment => comment.text.split("\n")) - .reduce((a, b) => a.concat(b), []) - .map(line => line.trim()) - .filter(comment => comment[0] === "!"); - - for (const line of oldStyleAnnotations) { - const [name, ...args] = line.slice(1).split(" "); - const annotation = createAnnotation(name, args); - if (annotation) { - annotationsMap.set(annotation.kind, annotation); - console.warn(`[Deprecated] Annotations with ! are being deprecated, use '@${annotation.kind}' instead`); - } else { - console.warn(`Encountered unknown annotation '${line}'.`); - } - } - +function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void { for (const tag of source.getJsDocTags()) { const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []); if (annotation) { @@ -65,17 +42,17 @@ function collectAnnotations( } } -export function getSymbolAnnotations(context: TransformationContext, symbol: ts.Symbol): AnnotationsMap { +export function getSymbolAnnotations(symbol: ts.Symbol): AnnotationsMap { const annotationsMap: AnnotationsMap = new Map(); - collectAnnotations(context, symbol, annotationsMap); + collectAnnotations(symbol, annotationsMap); return annotationsMap; } -export function getTypeAnnotations(context: TransformationContext, type: ts.Type): AnnotationsMap { +export function getTypeAnnotations(type: ts.Type): AnnotationsMap { const annotationsMap: AnnotationsMap = new Map(); - if (type.symbol) collectAnnotations(context, type.symbol, annotationsMap); - if (type.aliasSymbol) collectAnnotations(context, type.aliasSymbol, annotationsMap); + if (type.symbol) collectAnnotations(type.symbol, annotationsMap); + if (type.aliasSymbol) collectAnnotations(type.aliasSymbol, annotationsMap); return annotationsMap; } @@ -116,14 +93,14 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { export function getSignatureAnnotations(context: TransformationContext, signature: ts.Signature): AnnotationsMap { const annotationsMap: AnnotationsMap = new Map(); - collectAnnotations(context, signature, annotationsMap); + collectAnnotations(signature, annotationsMap); // Function properties on interfaces have the JSDoc tags on the parent PropertySignature const declaration = signature.getDeclaration(); if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { const symbol = context.checker.getSymbolAtLocation(declaration.parent.name); if (symbol) { - collectAnnotations(context, symbol, annotationsMap); + collectAnnotations(symbol, annotationsMap); } } @@ -154,7 +131,7 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) } const type = context.checker.getTypeAtLocation(node.expression); - return getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn); + return getTypeAnnotations(type).has(AnnotationKind.TupleReturn); } export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { @@ -185,20 +162,20 @@ export function isInTupleReturnFunction(context: TransformationContext, node: ts return true; } - return getTypeAnnotations(context, functionType).has(AnnotationKind.TupleReturn); + return getTypeAnnotations(functionType).has(AnnotationKind.TupleReturn); } export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(context, type).has(AnnotationKind.LuaIterator); + return getTypeAnnotations(type).has(AnnotationKind.LuaIterator); } export function isVarArgType(context: TransformationContext, node: ts.Node): boolean { const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(context, type).has(AnnotationKind.VarArg); + return getTypeAnnotations(type).has(AnnotationKind.VarArg); } export function isForRangeType(context: TransformationContext, node: ts.Node): boolean { const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(context, type).has(AnnotationKind.ForRange); + return getTypeAnnotations(type).has(AnnotationKind.ForRange); } diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index c8a57dc1d..a9944b260 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -19,7 +19,7 @@ export function validatePropertyAssignment( if (!ts.isPropertyAccessExpression(node.left)) return; const leftType = context.checker.getTypeAtLocation(node.left.expression); - const annotations = getTypeAnnotations(context, leftType); + const annotations = getTypeAnnotations(leftType); if (annotations.has(AnnotationKind.LuaTable) && node.left.name.text === "length") { throw ForbiddenLuaTableUseException(`A LuaTable object's length cannot be re-assigned.`, node); } diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 747ba0455..b939dfe64 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -72,7 +72,7 @@ export const transformPropertyAccessExpression: FunctionVisitor = ( const lhs = context.transformExpression(node.left); const rhs = context.transformExpression(node.right); const rhsType = context.checker.getTypeAtLocation(node.right); - const annotations = getTypeAnnotations(context, rhsType); + const annotations = getTypeAnnotations(rhsType); if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { // Cannot use instanceof on extension classes diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index e9c8c108c..8f4049399 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -88,7 +88,7 @@ export function transformClassDeclaration( throw MissingClassName(classDeclaration); } - const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(classDeclaration)); + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); // Find out if this class is extension of existing class const extensionDirective = annotations.get(AnnotationKind.Extension); @@ -113,7 +113,7 @@ export function transformClassDeclaration( if (!(isExtension || isMetaExtension) && extendsType) { // Non-extensions cannot extend extension classes - const extendsAnnotations = getTypeAnnotations(context, extendsType); + const extendsAnnotations = getTypeAnnotations(extendsType); if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { throw InvalidExtendsExtension(classDeclaration); } @@ -121,7 +121,7 @@ export function transformClassDeclaration( // You cannot extend LuaTable classes if (extendsType) { - const annotations = getTypeAnnotations(context, extendsType); + const annotations = getTypeAnnotations(extendsType); if (annotations.has(AnnotationKind.LuaTable)) { throw InvalidExtendsLuaTable(classDeclaration); } diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index f83329b7a..d1181a284 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -63,7 +63,7 @@ export const transformNewExpression: FunctionVisitor = (node, checkForLuaLibType(context, type); - const annotations = getTypeAnnotations(context, type); + const annotations = getTypeAnnotations(type); if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { throw InvalidNewExpressionOnExtension(node); diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index b75d1855b..a1639e24b 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -14,7 +14,7 @@ export function getExtendedTypeNode( for (const clause of node.heritageClauses) { if (clause.token === ts.SyntaxKind.ExtendsKeyword) { const superType = context.checker.getTypeAtLocation(clause.types[0]); - const annotations = getTypeAnnotations(context, superType); + const annotations = getTypeAnnotations(superType); if (!annotations.has(AnnotationKind.PureAbstract)) { return clause.types[0]; } diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index 8c3a82213..89c68e9d6 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -25,7 +25,7 @@ export const transformEnumDeclaration: FunctionVisitor = (no } const type = context.checker.getTypeAtLocation(node); - const membersOnly = getTypeAnnotations(context, type).has(AnnotationKind.CompileMembersOnly); + const membersOnly = getTypeAnnotations(type).has(AnnotationKind.CompileMembersOnly); const result: lua.Statement[] = []; if (!membersOnly) { diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index a2ae887d6..a4df8f1d7 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -123,7 +123,7 @@ function transformForOfLuaIteratorStatement( ): lua.Statement { const luaIterator = context.transformExpression(statement.expression); const type = context.checker.getTypeAtLocation(statement.expression); - const tupleReturn = getTypeAnnotations(context, type).has(AnnotationKind.TupleReturn); + const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); if (tupleReturn) { // LuaIterator + TupleReturn if (ts.isVariableDeclarationList(statement.initializer)) { diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts index ceee50e34..471dba4e3 100644 --- a/src/transformation/visitors/lua-table.ts +++ b/src/transformation/visitors/lua-table.ts @@ -71,7 +71,7 @@ export function transformLuaTableExpressionStatement( if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); - const annotations = getTypeAnnotations(context, ownerType); + const annotations = getTypeAnnotations(ownerType); if (annotations.has(AnnotationKind.LuaTable)) { return transformLuaTableExpressionAsExpressionStatement(context, expression); } @@ -84,7 +84,7 @@ export function transformLuaTableCallExpression( ): lua.Expression | undefined { if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { const ownerType = context.checker.getTypeAtLocation(node.expression.expression); - const annotations = getTypeAnnotations(context, ownerType); + const annotations = getTypeAnnotations(ownerType); if (annotations.has(AnnotationKind.LuaTable)) { const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); @@ -107,7 +107,7 @@ export function transformLuaTablePropertyAccessExpression( node: ts.PropertyAccessExpression ): lua.Expression | undefined { const type = context.checker.getTypeAtLocation(node.expression); - const annotations = getTypeAnnotations(context, type); + const annotations = getTypeAnnotations(type); if (annotations.has(AnnotationKind.LuaTable)) { const [luaTable, propertyName] = parseLuaTableExpression(context, node); switch (node.name.text) { @@ -123,7 +123,7 @@ export function transformLuaTableElementAccessExpression( context: TransformationContext, node: ts.ElementAccessExpression ): void { - const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node.expression)); + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); if (annotations.has(AnnotationKind.LuaTable)) { throw UnsupportedKind("LuaTable access expression", node.kind, node); } @@ -134,7 +134,7 @@ export function transformLuaTableNewExpression( node: ts.NewExpression ): lua.Expression | undefined { const type = context.checker.getTypeAtLocation(node); - const annotations = getTypeAnnotations(context, type); + const annotations = getTypeAnnotations(type); if (annotations.has(AnnotationKind.LuaTable)) { if (node.arguments && node.arguments.length > 0) { throw ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", node); diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 2dd390b6f..109bf3781 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -39,7 +39,7 @@ function shouldResolveModulePath(context: TransformationContext, moduleSpecifier const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier); if (!moduleOwnerSymbol) return true; - const annotations = getSymbolAnnotations(context, moduleOwnerSymbol); + const annotations = getSymbolAnnotations(moduleOwnerSymbol); return !annotations.has(AnnotationKind.NoResolution); } @@ -66,7 +66,7 @@ export function createModuleRequire( } function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean { - const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(importNode)); + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(importNode)); return ( context.resolver.isReferencedAliasDeclaration(importNode) && diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index fc269f5e7..35190705f 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -50,7 +50,7 @@ function moduleHasEmittedBody( const currentNamespaces = new WeakMap(); export const transformModuleDeclaration: FunctionVisitor = (node, context) => { - const annotations = getTypeAnnotations(context, context.checker.getTypeAtLocation(node)); + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { return context.transformStatements(node.body.statements); diff --git a/test/unit/decorators/compileMembersOnly.spec.ts b/test/unit/annotations/compileMembersOnly.spec.ts similarity index 100% rename from test/unit/decorators/compileMembersOnly.spec.ts rename to test/unit/annotations/compileMembersOnly.spec.ts diff --git a/test/unit/decorators/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts similarity index 100% rename from test/unit/decorators/customConstructor.spec.ts rename to test/unit/annotations/customConstructor.spec.ts diff --git a/test/unit/decorators/extension.spec.ts b/test/unit/annotations/extension.spec.ts similarity index 100% rename from test/unit/decorators/extension.spec.ts rename to test/unit/annotations/extension.spec.ts diff --git a/test/unit/decorators/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts similarity index 100% rename from test/unit/decorators/forRange.spec.ts rename to test/unit/annotations/forRange.spec.ts diff --git a/test/unit/decorators/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts similarity index 100% rename from test/unit/decorators/luaIterator.spec.ts rename to test/unit/annotations/luaIterator.spec.ts diff --git a/test/unit/decorators/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts similarity index 100% rename from test/unit/decorators/luaTable.spec.ts rename to test/unit/annotations/luaTable.spec.ts diff --git a/test/unit/decorators/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts similarity index 100% rename from test/unit/decorators/metaExtension.spec.ts rename to test/unit/annotations/metaExtension.spec.ts diff --git a/test/unit/decorators/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts similarity index 100% rename from test/unit/decorators/tupleReturn.spec.ts rename to test/unit/annotations/tupleReturn.spec.ts diff --git a/test/unit/decorators/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts similarity index 100% rename from test/unit/decorators/vararg.spec.ts rename to test/unit/annotations/vararg.spec.ts From c920bb3533d1eb672fb324bd81c29ff4e2dbe864 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 20 Jan 2020 00:48:11 +1000 Subject: [PATCH 221/764] Stop prefixing identifiers from global augs (#804) * Stop prefixing identifiers from global augs * Check for GlobalAug inside getSymbolExportScope --- src/transformation/utils/export.ts | 8 ++++++++ .../translation/__snapshots__/transformation.spec.ts.snap | 5 +++++ test/translation/transformation/globalAugmentation.ts | 5 +++++ 3 files changed, 18 insertions(+) create mode 100644 test/translation/transformation/globalAugmentation.ts diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index d509504d2..5922a9fc5 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -47,6 +47,10 @@ export function getIdentifierExportScope( return getSymbolExportScope(context, symbol); } +function isGlobalAugmentation(module: ts.ModuleDeclaration): boolean { + return (module.flags & ts.NodeFlags.GlobalAugmentation) !== 0; +} + export function getSymbolExportScope( context: TransformationContext, symbol: ts.Symbol @@ -64,6 +68,10 @@ export function getSymbolExportScope( return undefined; } + if (ts.isModuleDeclaration(scope) && isGlobalAugmentation(scope)) { + return undefined; + } + if (!isSymbolExportedFromScope(context, symbol, scope)) { return undefined; } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index f4e2ce661..dda4cea2f 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -82,6 +82,11 @@ end return ____exports" `; +exports[`Transformation (globalAugmentation) 1`] = ` +"local ____exports = globalVariable +return ____exports" +`; + exports[`Transformation (methodRestArguments) 1`] = ` "require(\\"lualib_bundle\\"); MyClass = __TS__Class() diff --git a/test/translation/transformation/globalAugmentation.ts b/test/translation/transformation/globalAugmentation.ts new file mode 100644 index 000000000..03f2c5af2 --- /dev/null +++ b/test/translation/transformation/globalAugmentation.ts @@ -0,0 +1,5 @@ +declare global { + export const globalVariable: number; +} + +export = globalVariable; From 8504525542093f2587e6d1b6315ef6ec9bbfdd13 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 19 Jan 2020 20:09:54 +0500 Subject: [PATCH 222/764] Fix function hoisting with synthetic source file (#807) --- src/transformation/context/visitors.ts | 1 + src/transformation/utils/typescript/index.ts | 16 ++------------ src/transformation/visitors/typescript.ts | 1 + test/unit/hoisting.spec.ts | 22 ++++++++++++++++++++ test/util.ts | 9 +++++++- 5 files changed, 34 insertions(+), 15 deletions(-) diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index 7acdba43e..48db4223a 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -133,6 +133,7 @@ type NodesBySyntaxKind = { [ts.SyntaxKind.NullKeyword]: ts.NullLiteral; [ts.SyntaxKind.SuperKeyword]: ts.SuperExpression; [ts.SyntaxKind.ThisKeyword]: ts.ThisExpression; + [ts.SyntaxKind.NotEmittedStatement]: ts.NotEmittedStatement; }; export type ExpressionLikeNode = ts.Expression | ts.QualifiedName | ts.ExternalModuleReference; diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 4348dd54d..fa4115614 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -25,24 +25,12 @@ export function findFirstNodeAbove(node: ts.Node, callback: ( } export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { - const declarations = (symbol.getDeclarations() ?? []).filter( - // TODO: getSourceFile? - declaration => findFirstNodeAbove(declaration, ts.isSourceFile) === sourceFile - ); + const originalSourceFile = ts.getParseTreeNode(sourceFile) ?? sourceFile; + const declarations = (symbol.getDeclarations() ?? []).filter(d => d.getSourceFile() === originalSourceFile); return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; } -export function isFirstDeclaration(context: TransformationContext, node: ts.VariableDeclaration): boolean { - const symbol = context.checker.getSymbolAtLocation(node.name); - if (!symbol) { - return false; - } - - const firstDeclaration = getFirstDeclarationInFile(symbol, context.sourceFile); - return firstDeclaration === node; -} - function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { const sourceFile = declaration.getSourceFile(); if (!sourceFile) { diff --git a/src/transformation/visitors/typescript.ts b/src/transformation/visitors/typescript.ts index 4ff855f2e..ab6c940f6 100644 --- a/src/transformation/visitors/typescript.ts +++ b/src/transformation/visitors/typescript.ts @@ -22,4 +22,5 @@ export const typescriptVisitors: Visitors = { [ts.SyntaxKind.NonNullExpression]: (node, context) => context.transformExpression(node.expression), [ts.SyntaxKind.AsExpression]: transformAssertionExpression, [ts.SyntaxKind.TypeAssertionExpression]: transformAssertionExpression, + [ts.SyntaxKind.NotEmittedStatement]: () => undefined, }; diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 880908793..fcae25e17 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -109,6 +109,28 @@ test("Hoisting due to reference from hoisted function", () => { expect(result).toBe("foo"); }); +test("Hoisting with synthetic source file node", () => { + util.testModule` + export const foo = bar(); + function bar() { return "bar"; } + ` + .setCustomTransformers({ + before: [ + () => sourceFile => + ts.updateSourceFileNode( + sourceFile, + [ts.createNotEmittedStatement(undefined!), ...sourceFile.statements], + sourceFile.isDeclarationFile, + sourceFile.referencedFiles, + sourceFile.typeReferenceDirectives, + sourceFile.hasNoDefaultLib, + sourceFile.libReferenceDirectives + ), + ], + }) + .expectToMatchJsResult(); +}); + test("Namespace Hoisting", () => { const code = ` function bar() { diff --git a/test/util.ts b/test/util.ts index 6ca57509b..582e526b6 100644 --- a/test/util.ts +++ b/test/util.ts @@ -212,6 +212,13 @@ export abstract class TestBuilder { return this; } + private customTransformers?: ts.CustomTransformers; + public setCustomTransformers(customTransformers?: ts.CustomTransformers): this { + expect(this.hasProgram).toBe(false); + this.customTransformers = customTransformers; + return this; + } + // Transpilation and execution public getTsCode(): string { @@ -228,7 +235,7 @@ export abstract class TestBuilder { @memoize public getLuaResult(): tstl.TranspileResult { const program = this.getProgram(); - const result = tstl.transpile({ program }); + const result = tstl.transpile({ program, customTransformers: this.customTransformers }); const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...ts.getPreEmitDiagnostics(program), ...result.diagnostics, From e2ef63d5a0fd651c5b9dc5f7236649f4621faf9f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 19 Jan 2020 18:00:20 +0100 Subject: [PATCH 223/764] Feature/move parenthesis handling to printer (#801) * Moved parenthesis logic from transformer to printer * Updated snapshots * Fixed remaining issue with object literal access * Removed lua.ParenthesizedExpression and let printer figure it out --- src/LuaAST.ts | 19 ------- src/LuaPrinter.ts | 52 ++++++++----------- src/transformation/builtins/array.ts | 5 +- src/transformation/builtins/index.ts | 12 ++--- src/transformation/builtins/math.ts | 3 +- src/transformation/builtins/object.ts | 7 ++- src/transformation/builtins/string.ts | 33 +++--------- src/transformation/utils/lua-ast.ts | 8 ++- src/transformation/visitors/access.ts | 11 +--- .../visitors/binary-expression/assignments.ts | 2 +- .../visitors/binary-expression/compound.ts | 5 +- src/transformation/visitors/call.ts | 16 ++---- src/transformation/visitors/conditional.ts | 6 +-- src/transformation/visitors/errors.ts | 9 +--- src/transformation/visitors/index.ts | 3 +- src/transformation/visitors/loops/do-while.ts | 2 +- .../__snapshots__/transformation.spec.ts.snap | 4 +- .../__snapshots__/expressions.spec.ts.snap | 4 +- test/unit/annotations/tupleReturn.spec.ts | 32 ++++++------ .../builtins/__snapshots__/math.spec.ts.snap | 8 +-- test/unit/expressions.spec.ts | 8 +++ test/unit/objectLiteral.spec.ts | 2 +- 22 files changed, 93 insertions(+), 158 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 2b3401614..8ab4f7417 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -36,7 +36,6 @@ export enum SyntaxKind { TableExpression, UnaryExpression, BinaryExpression, - ParenthesizedExpression, CallExpression, MethodCallExpression, Identifier, @@ -669,24 +668,6 @@ export function createBinaryExpression( return expression; } -export interface ParenthesizedExpression extends Expression { - kind: SyntaxKind.ParenthesizedExpression; - innerExpression: Expression; -} - -export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { - return node.kind === SyntaxKind.ParenthesizedExpression; -} - -export function createParenthesizedExpression( - innerExpression: Expression, - tsOriginal?: ts.Node -): ParenthesizedExpression { - const expression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal) as ParenthesizedExpression; - expression.innerExpression = innerExpression; - return expression; -} - export interface CallExpression extends Expression { kind: SyntaxKind.CallExpression; expression: Expression; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 1fd14f937..d37179765 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -64,9 +64,6 @@ function isSimpleExpression(expression: lua.Expression): boolean { case lua.SyntaxKind.BinaryExpression: const binaryExpression = expression as lua.BinaryExpression; return isSimpleExpression(binaryExpression.left) && isSimpleExpression(binaryExpression.right); - - case lua.SyntaxKind.ParenthesizedExpression: - return isSimpleExpression((expression as lua.ParenthesizedExpression).innerExpression); } return true; @@ -560,8 +557,6 @@ export class LuaPrinter { return this.printUnaryExpression(expression as lua.UnaryExpression); case lua.SyntaxKind.BinaryExpression: return this.printBinaryExpression(expression as lua.BinaryExpression); - case lua.SyntaxKind.ParenthesizedExpression: - return this.printParenthesizedExpression(expression as lua.ParenthesizedExpression); case lua.SyntaxKind.CallExpression: return this.printCallExpression(expression as lua.CallExpression); case lua.SyntaxKind.MethodCallExpression: @@ -689,7 +684,7 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); - chunks.push(this.printExpression(expression.operand)); + chunks.push(this.printExpressionInParenthesesIfNeeded(expression.operand)); return this.createSourceNode(expression, chunks); } @@ -697,38 +692,32 @@ export class LuaPrinter { public printBinaryExpression(expression: lua.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; - chunks.push(this.printExpression(expression.left)); + chunks.push(this.printExpressionInParenthesesIfNeeded(expression.left)); chunks.push(" ", this.printOperator(expression.operator), " "); - chunks.push(this.printExpression(expression.right)); + chunks.push(this.printExpressionInParenthesesIfNeeded(expression.right)); return this.createSourceNode(expression, chunks); } - private canStripParenthesis(expression: lua.Expression): boolean { - return ( - lua.isParenthesizedExpression(expression) || - lua.isTableIndexExpression(expression) || - lua.isCallExpression(expression) || - lua.isMethodCallExpression(expression) || - lua.isIdentifier(expression) || - lua.isNilLiteral(expression) || - lua.isNumericLiteral(expression) || - lua.isBooleanLiteral(expression) - ); + private printExpressionInParenthesesIfNeeded(expression: lua.Expression): SourceNode { + return this.needsParenthesis(expression) + ? this.createSourceNode(expression, ["(", this.printExpression(expression), ")"]) + : this.printExpression(expression); } - public printParenthesizedExpression(expression: lua.ParenthesizedExpression): SourceNode { - const innerExpression = this.printExpression(expression.innerExpression); - if (this.canStripParenthesis(expression.innerExpression)) { - return this.createSourceNode(expression, innerExpression); - } - return this.createSourceNode(expression, ["(", innerExpression, ")"]); + private needsParenthesis(expression: lua.Expression): boolean { + return ( + lua.isBinaryExpression(expression) || + lua.isFunctionExpression(expression) || + lua.isTableExpression(expression) || + (lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator) + ); } public printCallExpression(expression: lua.CallExpression): SourceNode { const chunks = []; - chunks.push(this.printExpression(expression.expression), "("); + chunks.push(this.printExpressionInParenthesesIfNeeded(expression.expression), "("); if (expression.params) { chunks.push(...this.printExpressionList(expression.params)); @@ -742,13 +731,14 @@ export class LuaPrinter { public printMethodCallExpression(expression: lua.MethodCallExpression): SourceNode { const chunks = []; - const prefix = lua.isStringLiteral(expression.prefixExpression) - ? this.printExpression(lua.createParenthesizedExpression(expression.prefixExpression)) - : this.printExpression(expression.prefixExpression); + const prefix = + this.needsParenthesis(expression.prefixExpression) || lua.isStringLiteral(expression.prefixExpression) + ? ["(", this.printExpression(expression.prefixExpression), ")"] + : [this.printExpression(expression.prefixExpression)]; const name = this.printIdentifier(expression.name); - chunks.push(prefix, ":", name, "("); + chunks.push(...prefix, ":", name, "("); if (expression.params) { chunks.push(...this.printExpressionList(expression.params)); @@ -770,7 +760,7 @@ export class LuaPrinter { public printTableIndexExpression(expression: lua.TableIndexExpression): SourceNode { const chunks: SourceChunk[] = []; - chunks.push(this.printExpression(expression.table)); + chunks.push(this.printExpressionInParenthesesIfNeeded(expression.table)); if ( lua.isStringLiteral(expression.index) && isValidLuaIdentifier(expression.index.value) && diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index a13d500aa..af4f674bd 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -89,10 +89,7 @@ export function transformArrayProperty( ): lua.UnaryExpression | undefined { switch (node.name.text) { case "length": - let expression = context.transformExpression(node.expression); - if (lua.isTableExpression(expression)) { - expression = lua.createParenthesizedExpression(expression); - } + const expression = context.transformExpression(node.expression); return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); default: return undefined; diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index fe55a5058..0958d0145 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -120,13 +120,11 @@ export function transformBuiltinIdentifierExpression( ): lua.Expression | undefined { switch (node.text) { case "NaN": - return lua.createParenthesizedExpression( - lua.createBinaryExpression( - lua.createNumericLiteral(0), - lua.createNumericLiteral(0), - lua.SyntaxKind.DivisionOperator, - node - ) + return lua.createBinaryExpression( + lua.createNumericLiteral(0), + lua.createNumericLiteral(0), + lua.SyntaxKind.DivisionOperator, + node ); case "Infinity": diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 311ae1201..9f5b4a1a3 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -50,8 +50,7 @@ export function transformMathCall(context: TransformationContext, node: Property const log1 = lua.createTableIndexExpression(math, lua.createStringLiteral("log")); const logCall1 = lua.createCallExpression(log1, params); const e = lua.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); - const div = lua.createBinaryExpression(logCall1, e, lua.SyntaxKind.DivisionOperator); - return lua.createParenthesizedExpression(div, node); + return lua.createBinaryExpression(logCall1, e, lua.SyntaxKind.DivisionOperator, node); } // math.log(1 + x) diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 9f30840ba..acd468bd4 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -49,8 +49,11 @@ export function transformObjectPrototypeCall( const parameters = transformArguments(context, node.arguments, signature); const rawGetIdentifier = lua.createIdentifier("rawget"); const rawGetCall = lua.createCallExpression(rawGetIdentifier, [expr, ...parameters]); - return lua.createParenthesizedExpression( - lua.createBinaryExpression(rawGetCall, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator, node) + return lua.createBinaryExpression( + rawGetCall, + lua.createNilLiteral(), + lua.SyntaxKind.InequalityOperator, + node ); } } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index abe79ac76..ea755b707 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -40,19 +40,11 @@ export function transformStringPrototypeCall( lua.createBooleanLiteral(true) ); - return lua.createParenthesizedExpression( - lua.createBinaryExpression( - lua.createParenthesizedExpression( - lua.createBinaryExpression( - stringExpression, - lua.createNumericLiteral(0), - lua.SyntaxKind.OrOperator - ) - ), - lua.createNumericLiteral(1), - lua.SyntaxKind.SubtractionOperator, - node - ) + return lua.createBinaryExpression( + lua.createBinaryExpression(stringExpression, lua.createNumericLiteral(0), lua.SyntaxKind.OrOperator), + lua.createNumericLiteral(1), + lua.SyntaxKind.SubtractionOperator, + node ); case "substr": if (node.arguments.length === 1) { @@ -60,14 +52,8 @@ export function transformStringPrototypeCall( const arg1 = createExpressionPlusOne(argument); return createStringCall("sub", node, caller, arg1); } else { - const arg1 = params[0]; - const arg2 = params[1]; - const sumArg = lua.createBinaryExpression( - lua.createParenthesizedExpression(arg1), - lua.createParenthesizedExpression(arg2), - lua.SyntaxKind.AdditionOperator - ); - return createStringCall("sub", node, caller, createExpressionPlusOne(arg1), sumArg); + const sumArg = lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.AdditionOperator); + return createStringCall("sub", node, caller, createExpressionPlusOne(params[0]), sumArg); } case "substring": if (node.arguments.length === 1) { @@ -156,10 +142,7 @@ export function transformStringProperty( ): lua.UnaryExpression { switch (node.name.text) { case "length": - let expression = context.transformExpression(node.expression); - if (ts.isTemplateExpression(node.expression)) { - expression = lua.createParenthesizedExpression(expression); - } + const expression = context.transformExpression(node.expression); return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); default: throw UnsupportedProperty("string", node.name.text, node); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index effc18814..3f4794d8a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -41,8 +41,6 @@ export function createExpressionPlusOne(expression: lua.Expression): lua.Express ) { return expression.left; } - - expression = lua.createParenthesizedExpression(expression); } return lua.createBinaryExpression(expression, lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator); @@ -57,7 +55,7 @@ export function createImmediatelyInvokedFunctionExpression( body.push(lua.createReturnStatement(Array.isArray(result) ? result : [result])); const flags = statements.length === 0 ? lua.FunctionExpressionFlags.Inline : lua.FunctionExpressionFlags.None; const iife = lua.createFunctionExpression(lua.createBlock(body), undefined, undefined, undefined, flags); - return lua.createCallExpression(lua.createParenthesizedExpression(iife), [], tsOriginal); + return lua.createCallExpression(iife, [], tsOriginal); } export function createUnpackCall( @@ -73,9 +71,9 @@ export function createUnpackCall( return lua.createCallExpression(unpack, [expression], tsOriginal); } -export function wrapInTable(...expressions: lua.Expression[]): lua.ParenthesizedExpression { +export function wrapInTable(...expressions: lua.Expression[]): lua.TableExpression { const fields = expressions.map(e => lua.createTableFieldExpression(e)); - return lua.createParenthesizedExpression(lua.createTableExpression(fields)); + return lua.createTableExpression(fields); } export function wrapInToStringForConcat(expression: lua.Expression): lua.Expression { diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index b939dfe64..4043a56a0 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -31,10 +31,7 @@ export const transformElementAccessExpression: FunctionVisitor v1) or (() => v2))() const conditionAnd = lua.createBinaryExpression(condition, val1Function, lua.SyntaxKind.AndOperator); const orExpression = lua.createBinaryExpression(conditionAnd, val2Function, lua.SyntaxKind.OrOperator); - return lua.createCallExpression(lua.createParenthesizedExpression(orExpression), [], expression); + return lua.createCallExpression(orExpression, [], expression); } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { @@ -61,7 +61,7 @@ export const transformConditionalExpression: FunctionVisitor = (statemen if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { // Wrap catch in function if try or catch has return - const catchCall = lua.createCallExpression( - lua.createParenthesizedExpression(lua.createFunctionExpression(catchBlock)) - ); + const catchCall = lua.createCallExpression(lua.createFunctionExpression(catchBlock)); const catchAssign = lua.createAssignmentStatement( [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], catchCall ); catchBlock = lua.createBlock([catchAssign]); } - const notTryCondition = lua.createUnaryExpression( - lua.createParenthesizedExpression(tryResultIdentifier), - lua.SyntaxKind.NotOperator - ); + const notTryCondition = lua.createUnaryExpression(tryResultIdentifier, lua.SyntaxKind.NotOperator); result.push(lua.createIfStatement(notTryCondition, catchBlock)); } else if (tryScope.functionReturned) { // try with return, but no catch diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 404eea987..17b25ffd7 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -1,5 +1,4 @@ import * as ts from "typescript"; -import * as lua from "../../LuaAST"; import { FunctionVisitor, Visitors } from "../context"; import { transformElementAccessExpression, transformPropertyAccessExpression, transformQualifiedName } from "./access"; import { transformBinaryExpression } from "./binary-expression"; @@ -44,7 +43,7 @@ import { transformVariableStatement } from "./variable-declaration"; const transformEmptyStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => - lua.createParenthesizedExpression(context.transformExpression(node.expression), node); + context.transformExpression(node.expression); export const standardVisitors: Visitors = { ...literalVisitors, diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index 8e219b6b8..58c37b421 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -17,7 +17,7 @@ export const transformDoStatement: FunctionVisitor = (statement, if (lua.isUnaryExpression(condition) && condition.operator === lua.SyntaxKind.NotOperator) { condition = condition.operand; } else { - condition = lua.createUnaryExpression(lua.createParenthesizedExpression(condition), lua.SyntaxKind.NotOperator); + condition = lua.createUnaryExpression(condition, lua.SyntaxKind.NotOperator); } return lua.createRepeatStatement(lua.createBlock([body]), condition, statement); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index dda4cea2f..942f17aa2 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -21,7 +21,7 @@ backQuoteInTemplateString = \\"\` \` \`\\" escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -nonEmptyTemplateString = \\"Level 0: \\\\n\\\\t \\" .. \\"Level 1: \\\\n\\\\t\\\\t \\" .. \\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\" .. \\" \\\\n --\\"" +nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. ((\\"Level 1: \\\\n\\\\t\\\\t \\" .. ((\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\"" `; exports[`Transformation (classExtension1) 1`] = ` @@ -229,7 +229,7 @@ end return ____exports" `; -exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or {}"`; +exports[`Transformation (modulesNamespaceNoExport) 1`] = `"TestSpace = TestSpace or ({})"`; exports[`Transformation (modulesNamespaceWithMemberExport) 1`] = ` "local ____exports = {} diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index db8863e35..7095c91a8 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -14,13 +14,13 @@ return ____exports" exports[`Binary expressions ordering parentheses ("1*(3+4*2)") 1`] = ` "local ____exports = {} -____exports.__result = 1 * (3 + 4 * 2) +____exports.__result = 1 * (3 + (4 * 2)) return ____exports" `; exports[`Binary expressions ordering parentheses ("1*30+4") 1`] = ` "local ____exports = {} -____exports.__result = 1 * 30 + 4 +____exports.__result = (1 * 30) + 4 return ____exports" `; diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts index ca234cfbc..7c7c7ae9b 100644 --- a/test/unit/annotations/tupleReturn.spec.ts +++ b/test/unit/annotations/tupleReturn.spec.ts @@ -346,31 +346,33 @@ test("Tuple Return vs Non-Tuple Return Overload", () => { }); test("TupleReturn assignment", () => { - const lua = util.testFunction` + util.testFunction` /** @tupleReturn */ - declare function abc(this: void): number[] - let [a,b] = abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = abc()"); + function abc(this: void): number[] { + return [3, 5]; + } + let [a, b] = abc(); + return { a, b }; + `.expectToMatchJsResult(); }); test("TupleReturn Single assignment", () => { - const lua = util.testFunction` + util.testFunction` /** @tupleReturn */ - declare function abc(this: void): [number, string]; + function abc(this: void): [number, string] { + return [3, "foo"]; + } let a = abc(); a = abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain(`local a = ({\n abc()\n })\n a = ({\n abc()\n })`); + return a; + `.expectToMatchJsResult(); }); test("TupleReturn interface assignment", () => { const lua = util.testFunction` interface def { - /** @tupleReturn */ - abc(); + /** @tupleReturn */ + abc(); } declare const jkl : def; let [a,b] = jkl.abc(); `.getMainLuaCodeChunk(); @@ -381,8 +383,8 @@ test("TupleReturn interface assignment", () => { test("TupleReturn namespace assignment", () => { const lua = util.testFunction` declare namespace def { - /** @tupleReturn */ - function abc(this: void) {} + /** @tupleReturn */ + function abc(this: void) {} } let [a,b] = def.abc(); `.getMainLuaCodeChunk(); diff --git a/test/unit/builtins/__snapshots__/math.spec.ts.snap b/test/unit/builtins/__snapshots__/math.spec.ts.snap index 62881275f..cb324c9c9 100644 --- a/test/unit/builtins/__snapshots__/math.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/math.spec.ts.snap @@ -27,7 +27,7 @@ return ____exports" exports[`Math.log2(3) 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____ = (math.log(3) / 0.6931471805599453) + local ____ = math.log(3) / 0.6931471805599453 end return ____exports" `; @@ -35,7 +35,7 @@ return ____exports" exports[`Math.log10(3) 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____ = (math.log(3) / 2.302585092994046) + local ____ = math.log(3) / 2.302585092994046 end return ____exports" `; @@ -67,7 +67,7 @@ return ____exports" exports[`const x = Math.log2(3) 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = (math.log(3) / 0.6931471805599453) + local x = math.log(3) / 0.6931471805599453 end return ____exports" `; @@ -75,7 +75,7 @@ return ____exports" exports[`const x = Math.log10(3) 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = (math.log(3) / 2.302585092994046) + local x = math.log(3) / 2.302585092994046 end return ____exports" `; diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index c65c1ebbc..8f3121c86 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -111,6 +111,14 @@ test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( } ); +test("Assignment order of operations is preserved", () => { + util.testFunction` + let x = 0; + x *= 2 + 3; + return x; + `.expectToMatchJsResult(); +}); + test.each(["bar(),foo()", "foo(),bar()", "foo(),bar(),baz()"])("Binary Comma (%p)", input => { util.testFunction` function foo() { return 1; } diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 203b05780..2dfdfa1d0 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -57,7 +57,7 @@ test("undefined as object key", () => { `.expectToMatchJsResult(); }); -test.each([`({x: "foobar"}.x)`, `({x: "foobar"}["x"])`, `({x: () => "foobar"}.x())`, `({x: () => "foobar"}["x"]())`])( +test.each([`{x: "foobar"}.x`, `{x: "foobar"}["x"]`, `{x: () => "foobar"}.x()`, `{x: () => "foobar"}["x"]()`])( "object literal property access (%p)", expression => { util.testExpression(expression).expectToMatchJsResult(); From be969b02b5cec9bb775e73421a161b996ef98d5a Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 Jan 2020 18:08:27 +0100 Subject: [PATCH 224/764] 0.31.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 00e190417..93482cc2f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.30.1", + "version": "0.31.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index fa3892d38..f0bdfceda 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.30.1", + "version": "0.31.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 29632f34c84aac9a7aec28291392db71d6ea7931 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 Jan 2020 18:25:42 +0100 Subject: [PATCH 225/764] Changelog 0.31.0 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d21cd0d6d..ac2e2d9f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 0.31.0 + +- **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: + + `/** @varArg */`. + +- **Breaking:** Fixed some cases where variables were **incorrectly** not labeled `local`. The only variables that are implicitly put in the global context are _top-level variables in non-module files, without any imports or exports in their file_. + +- Moved handling of parentheses out of the transformers and unified this logic in the printer. This might result in some more parentheses in the generated code, but also makes it more correct and fixes some related bugs. + +- Added support for `array.includes`. + +- Fixed a bug breaking global augmentation. + +- Fixed hoisting breaking if there were synthetic nodes in the AST (i.e. when a TS transformer modified the AST). + ## 0.30.0 - **Breaking:** We dropped support for `var` variables. If you still have any `var` variable declarations, please use `let` or `const` instead. From b019174372aa250b3e7dd3ef414db93ea5a1e0da Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 22 Jan 2020 01:02:19 +0500 Subject: [PATCH 226/764] Remove `noHoisting` option (#808) * Remove `noHoisting` option * Remove unused declarations * Remove `noHoisting` references from `vararg` tests * Fix vararg tests * Use test builder in `@vararg global` test * Fix bundle tests --- src/CompilerOptions.ts | 1 - src/cli/parse.ts | 5 - src/transformation/utils/errors.ts | 7 -- src/transformation/utils/lua-ast.ts | 20 ++-- src/transformation/utils/scope.ts | 4 - src/transformation/utils/symbols.ts | 10 -- src/transformation/visitors/function.ts | 2 +- src/transformation/visitors/modules/import.ts | 2 +- test/cli/parse.spec.ts | 8 +- test/unit/annotations/vararg.spec.ts | 58 ++++----- test/unit/functions/functions.spec.ts | 54 ++++----- test/unit/hoisting.spec.ts | 25 ---- test/util.ts | 113 +++++++++--------- 13 files changed, 119 insertions(+), 190 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index be3aa09b4..0887efd81 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -24,7 +24,6 @@ export type CompilerOptions = OmitIndexSignature & { luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; - noHoisting?: boolean; sourceMapTraceback?: boolean; plugins?: Array; [option: string]: ts.CompilerOptions[string] | Array; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 40f564268..9f05f2f9c 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -61,11 +61,6 @@ export const optionDeclarations: CommandLineOption[] = [ description: "Specify if a header will be added to compiled files.", type: "boolean", }, - { - name: "noHoisting", - description: "Disables hoisting.", - type: "boolean", - }, { name: "sourceMapTraceback", description: "Applies the source map to show source TS files and lines in error tracebacks.", diff --git a/src/transformation/utils/errors.ts b/src/transformation/utils/errors.ts index 09634fcc8..91b07159b 100644 --- a/src/transformation/utils/errors.ts +++ b/src/transformation/utils/errors.ts @@ -130,13 +130,6 @@ export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => new TranspileError(`${reason}. TypeScript path: ${path}.`, node); -export const ReferencedBeforeDeclaration = (node: ts.Identifier) => - new TranspileError( - `Identifier "${node.text}" was referenced before it was declared. The declaration ` + - "must be moved before the identifier's use, or hoisting must be enabled.", - node - ); - export const UnsupportedObjectDestructuringInForOf = (node: ts.Node) => new TranspileError(`Unsupported object destructuring in for...of statement.`, node); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 3f4794d8a..c72ec2d74 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -95,7 +95,7 @@ export function createHoistableVariableDeclarationStatement( tsOriginal?: ts.Node ): lua.AssignmentStatement | lua.VariableDeclarationStatement { const declaration = lua.createVariableDeclarationStatement(identifier, initializer, tsOriginal); - if (!context.options.noHoisting && identifier.symbolId) { + if (identifier.symbolId !== undefined) { const scope = peekScope(context); assert(scope.type !== ScopeType.Switch); @@ -158,17 +158,15 @@ export function createLocalOrExportedOrGlobalDeclaration( declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } - if (!context.options.noHoisting) { - // Remember local variable declarations for hoisting later - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } + // Remember local variable declarations for hoisting later + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } - scope.variableDeclarations.push(declaration); + scope.variableDeclarations.push(declaration); - if (scope.type === ScopeType.Switch) { - declaration = undefined; - } + if (scope.type === ScopeType.Switch) { + declaration = undefined; } } else if (rhs) { // global @@ -178,7 +176,7 @@ export function createLocalOrExportedOrGlobalDeclaration( } } - if (!context.options.noHoisting && isFunctionDeclaration) { + if (isFunctionDeclaration) { // Remember function definitions for hoisting later const functionSymbolId = (lhs as lua.Identifier).symbolId; const scope = peekScope(context); diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 5f23d2984..44430f763 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -98,10 +98,6 @@ export function popScope(context: TransformationContext): Scope { } export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { - if (context.options.noHoisting) { - return statements; - } - const scope = peekScope(context); let result = statements; result = hoistFunctionDefinitions(context, scope, result); diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index a08197c72..c99b41a25 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -2,9 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; -import { ReferencedBeforeDeclaration } from "./errors"; import { markSymbolAsReferencedInCurrentScopes } from "./scope"; -import { getFirstDeclarationInFile } from "./typescript"; const symbolIdCounters = new WeakMap(); function nextSymbolId(context: TransformationContext): lua.SymbolId { @@ -46,14 +44,6 @@ export function trackSymbolReference( symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); } - if (context.options.noHoisting) { - // Check for reference-before-declaration - const declaration = getFirstDeclarationInFile(symbol, context.sourceFile); - if (declaration && identifier.pos < declaration.pos) { - throw ReferencedBeforeDeclaration(identifier); - } - } - markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); return symbolId; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index d39caf1ba..dc7a1b0a4 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -267,7 +267,7 @@ export const transformFunctionDeclaration: FunctionVisitor = (statement, context) => { const scope = peekScope(context); - if (!context.options.noHoisting && !scope.importStatements) { + if (!scope.importStatements) { scope.importStatements = []; } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index ae95751e9..3ce9b35ba 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -82,11 +82,11 @@ describe("command line", () => { }); test("shouldn't parse following arguments as values", () => { - const result = tstl.parseCommandLine(["--noHeader", "--noHoisting"]); + const result = tstl.parseCommandLine(["--noHeader", "--noImplicitSelf"]); expect(result.errors).not.toHaveDiagnostics(); expect(result.options.noHeader).toBe(true); - expect(result.options.noHoisting).toBe(true); + expect(result.options.noImplicitSelf).toBe(true); }); test("shouldn't parse following files as values", () => { @@ -101,8 +101,6 @@ describe("command line", () => { test.each<[string, string, tstl.CompilerOptions]>([ ["noHeader", "false", { noHeader: false }], ["noHeader", "true", { noHeader: true }], - ["noHoisting", "false", { noHoisting: false }], - ["noHoisting", "true", { noHoisting: true }], ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], @@ -209,8 +207,6 @@ describe("tsconfig", () => { test.each<[string, any, tstl.CompilerOptions]>([ ["noHeader", false, { noHeader: false }], ["noHeader", true, { noHeader: true }], - ["noHoisting", false, { noHoisting: false }], - ["noHoisting", true, { noHoisting: true }], ["sourceMapTraceback", false, { sourceMapTraceback: false }], ["sourceMapTraceback", true, { sourceMapTraceback: true }], diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts index 2a99fa4a7..982109261 100644 --- a/test/unit/annotations/vararg.spec.ts +++ b/test/unit/annotations/vararg.spec.ts @@ -1,8 +1,13 @@ import * as util from "../../util"; -test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; +const varargDeclaration = ` + /** @vararg */ + type LuaVarArg = A & { __luaVararg?: never }; +`; + +test("@vararg", () => { + util.testFunction` + ${varargDeclaration} function foo(a: unknown, ...b: LuaVarArg) { const c = [...b]; return c.join(""); @@ -11,45 +16,30 @@ test.each([{}, { noHoisting: true }])("@vararg", compilerOptions => { return foo(a, ...b); } return bar("A", "B", "C", "D"); - `; - - const lua = util.transpileString(code, compilerOptions); - expect(lua).not.toMatch("b = ({...})"); - expect(lua).not.toMatch("unpack"); - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("@vararg array access", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; +test("@vararg array access", () => { + util.testFunction` + ${varargDeclaration} function foo(a: unknown, ...b: LuaVarArg) { const c = [...b]; return c.join("") + b[0]; } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCDB"); + `.expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("@vararg global", compilerOptions => { - const code = ` - /** @vararg */ type LuaVarArg = A & { __luaVarArg?: never }; +test("@vararg global", () => { + util.testModule` + ${varargDeclaration} declare const arg: LuaVarArg; - const arr = [...arg]; - const result = arr.join(""); - `; - - const luaBody = util.transpileString(code, compilerOptions, false); - expect(luaBody).not.toMatch("unpack"); - - const lua = ` - function test(...) - ${luaBody} - return result - end - return test("A", "B", "C", "D") - `; - - expect(util.executeLua(lua)).toBe("ABCD"); + export const result = [...arg].join(""); + ` + .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .expectToEqual({ result: "ABCD" }); }); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 1a94507a2..aab7b151a 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -432,19 +432,17 @@ test("Function rest binding pattern", () => { `.expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("Function rest parameter", compilerOptions => { - const code = ` +test("Function rest parameter", () => { + util.testFunction` function foo(a: unknown, ...b: string[]) { return b.join(""); } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); + `.expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("Function nested rest parameter", compilerOptions => { - const code = ` +test("Function nested rest parameter", () => { + util.testFunction` function foo(a: unknown, ...b: string[]) { function bar() { return b.join(""); @@ -452,13 +450,11 @@ test.each([{}, { noHoisting: true }])("Function nested rest parameter", compiler return bar(); } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); + `.expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("Function nested rest spread", compilerOptions => { - const code = ` +test("Function nested rest spread", () => { + util.testFunction` function foo(a: unknown, ...b: string[]) { function bar() { const c = [...b]; @@ -467,40 +463,36 @@ test.each([{}, { noHoisting: true }])("Function nested rest spread", compilerOpt return bar(); } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); + `.expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("Function rest parameter (unreferenced)", compilerOptions => { - const code = ` +test("Function rest parameter (unreferenced)", () => { + util.testFunction` function foo(a: unknown, ...b: string[]) { return "foobar"; } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileString(code, compilerOptions)).not.toMatch("b = ({...})"); - expect(util.transpileAndExecute(code, compilerOptions)).toBe("foobar"); + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("{...}")) + .expectToMatchJsResult(); }); -test.each([{}, { noHoisting: true }])("Function rest parameter (referenced in property shorthand)", compilerOptions => { - const code = ` +test("Function rest parameter (referenced in property shorthand)", () => { + util.testFunction` function foo(a: unknown, ...b: string[]) { const c = { b }; return c.b.join(""); } return foo("A", "B", "C", "D"); - `; - - expect(util.transpileAndExecute(code, compilerOptions)).toBe("BCD"); + `.expectToMatchJsResult(); }); test("named function expression reference", () => { - const code = ` - const y = function x(inp: string) { - return inp + typeof x; + util.testFunction` + const y = function x() { + return { x: typeof x, y: typeof y }; }; - return y("foo-");`; - expect(util.transpileAndExecute(code)).toBe("foo-function"); + + return y(); + `.expectToMatchJsResult(); }); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index fcae25e17..997c53f73 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -1,5 +1,4 @@ import * as ts from "typescript"; -import { ReferencedBeforeDeclaration } from "../../src/transformation/utils/errors"; import * as util from "../util"; test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { @@ -204,30 +203,6 @@ test("Enum Hoisting", () => { expect(result).toBe("foo"); }); -test.each([ - { code: `foo = "foo"; var foo;`, identifier: "foo" }, - { code: `foo = "foo"; export var foo;`, identifier: "foo" }, - { code: `function setBar() { const bar = foo; } let foo = "foo";`, identifier: "foo" }, - { code: `function setBar() { const bar = foo; } const foo = "foo";`, identifier: "foo" }, - { code: `function setBar() { const bar = foo; } export let foo = "foo";`, identifier: "foo" }, - { code: `function setBar() { const bar = foo; } export const foo = "foo";`, identifier: "foo" }, - { code: `const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, - { code: `export const foo = bar(); function bar() { return "bar"; }`, identifier: "bar" }, - { code: `const foo = bar(); export function bar() { return "bar"; }`, identifier: "bar" }, - { code: `function bar() { return NS.foo; } namespace NS { export let foo = "foo"; }`, identifier: "NS" }, - { - code: `export namespace O { export function f() { return I.foo; } namespace I { export let foo = "foo"; } }`, - identifier: "I", - }, - { code: `function makeFoo() { return new Foo(); } class Foo {}`, identifier: "Foo" }, - { code: `function bar() { return E.A; } enum E { A = "foo" }`, identifier: "E" }, - { code: `function setBar() { const bar = { foo }; } let foo = "foo";`, identifier: "foo" }, -])("No Hoisting (%p)", ({ code, identifier }) => { - expect(() => util.transpileString(code, { noHoisting: true })).toThrowExactError( - ReferencedBeforeDeclaration(ts.createIdentifier(identifier)) - ); -}); - test("Import hoisting (named)", () => { util.testBundle` export const result = foo; diff --git a/test/util.ts b/test/util.ts index 582e526b6..a4e84f4b1 100644 --- a/test/util.ts +++ b/test/util.ts @@ -123,8 +123,53 @@ function executeLua(code: string): any { } } +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); export function executeLuaModule(code: string): any { - return executeLua(`${minimalTestLib}return JSONStringify((function()\n${code}\nend)())`); + const lualibImport = code.includes('require("lualib_bundle")') + ? `package.preload.lualib_bundle = function()\n${lualibContent}\nend` + : ""; + + return executeLua(`${minimalTestLib}\n${lualibImport}\nreturn JSONStringify((function()\n${code}\nend)())`); +} + +function executeJsModule(code: string): any { + const exports = {}; + const context = vm.createContext({ exports, module: { exports } }); + context.global = context; + let result: unknown; + try { + result = vm.runInContext(code, context); + } catch (error) { + return new ExecutionError(error.message); + } + + function transform(currentValue: any): any { + if (currentValue === null) { + return undefined; + } + + if (Array.isArray(currentValue)) { + return currentValue.map(transform); + } + + if (typeof currentValue === "object") { + for (const [key, value] of Object.entries(currentValue)) { + currentValue[key] = transform(value); + if (currentValue[key] === undefined) { + delete currentValue[key]; + } + } + + if (Object.keys(currentValue).length === 0) { + return []; + } + } + + return currentValue; + } + + return transform(result); } const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { @@ -177,6 +222,13 @@ export abstract class TestBuilder { return this; } + protected abstract getLuaCodeWithWrapper: (code: string) => string; + public setLuaFactory(luaFactory: (code: string) => string): this { + expect(this.hasProgram).toBe(false); + this.getLuaCodeWithWrapper = luaFactory; + return this; + } + private semanticCheck = true; public disableSemanticCheck(): this { expect(this.hasProgram).toBe(false); @@ -260,11 +312,9 @@ export abstract class TestBuilder { return header + this.getMainLuaFileResult().lua.trimRight(); } - public abstract getLuaCodeWithWrapper(): string; - @memoize public getLuaExecutionResult(): any { - return executeLua(this.getLuaCodeWithWrapper()); + return executeLuaModule(this.getLuaCodeWithWrapper(this.getMainLuaCodeChunk())); } @memoize @@ -288,42 +338,7 @@ export abstract class TestBuilder { @memoize public getJsExecutionResult(): any { - const exports = {}; - const context = vm.createContext({ exports, module: { exports } }); - context.global = context; - let result: unknown; - try { - result = vm.runInContext(this.getJsCodeWithWrapper(), context); - } catch (error) { - return new ExecutionError(error.message); - } - - function transform(currentValue: any): any { - if (currentValue === null) { - return undefined; - } - - if (Array.isArray(currentValue)) { - return currentValue.map(transform); - } - - if (typeof currentValue === "object") { - for (const [key, value] of Object.entries(currentValue)) { - currentValue[key] = transform(value); - if (currentValue[key] === undefined) { - delete currentValue[key]; - } - } - - if (Object.keys(currentValue).length === 0) { - return []; - } - } - - return currentValue; - } - - return transform(result); + return executeJsModule(this.getJsCodeWithWrapper()); } // Utilities @@ -336,9 +351,9 @@ export abstract class TestBuilder { // Actions public debug(): this { - const luaCode = this.getMainLuaCodeChunk().replace(/(^|\n)/g, "\n "); - const value = prettyFormat(this.getLuaExecutionResult()); - console.log(`Lua Code:${luaCode}\nValue: ${value}`); + const luaCode = this.getMainLuaCodeChunk().replace(/^/gm, " "); + const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); + console.log(`Lua Code:\n${luaCode}\n\nValue:\n${value}`); return this; } @@ -415,20 +430,10 @@ export abstract class TestBuilder { } } -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; class AccessorTestBuilder extends TestBuilder { protected accessor = ""; - @memoize - public getLuaCodeWithWrapper(): string { - let code = this.getMainLuaCodeChunk(); - if (code.includes('require("lualib_bundle")')) { - code = `package.preload.lualib_bundle = function()\n${lualibContent}\nend\n${code}`; - } - - return `${minimalTestLib}\nreturn JSONStringify((function()\n${code}\nend)()${this.accessor})`; - } + protected getLuaCodeWithWrapper = (code: string) => `return (function()\n${code}\nend)()${this.accessor}`; @memoize protected getJsCodeWithWrapper(): string { From ac6b4c50f46e5e1e9003cf83411f52db9a016283 Mon Sep 17 00:00:00 2001 From: "D. L" <1613158+dlbd@users.noreply.github.com> Date: Fri, 14 Feb 2020 20:48:57 +0200 Subject: [PATCH 227/764] Error LuaLibFeature should depend on Class (#824) --- src/LuaLib.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 5087bd7d0..7b1926912 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -73,7 +73,7 @@ export enum LuaLibFeature { const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], - Error: [LuaLibFeature.New, LuaLibFeature.FunctionCall], + Error: [LuaLibFeature.New, LuaLibFeature.Class, LuaLibFeature.FunctionCall], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], From 592c27518203ae67ad68120ab7250b6fa4ea80dd Mon Sep 17 00:00:00 2001 From: Oliver Leve Date: Thu, 20 Feb 2020 21:01:07 +0100 Subject: [PATCH 228/764] added wow to typescript declarations (#825) --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b1438a222..d8c929e23 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,8 @@ The real power of this transpiler is usage together with good declarations for t - [Dota 2 Modding](https://github.com/ModDota/API/tree/master/declarations/server) - [Defold Game Engine Scripting](https://github.com/dasannikov/DefoldTypeScript/blob/master/defold.d.ts) - [LÖVE 2D Game Development](https://github.com/hazzard993/love-typescript-definitions) +- [World of Warcraft - Addon Development](https://github.com/wartoshika/wow-declarations) +- [World of Warcraft Classic - Addon Development](https://github.com/wartoshika/wow-classic-declarations) ## Sublime Text integration From f98a33e2a994d6a26427086df148f045bc699ed7 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Tue, 25 Feb 2020 07:10:57 +1000 Subject: [PATCH 229/764] Resolve exported identifiers in for-in loops (#829) --- src/transformation/visitors/loops/for-in.ts | 12 ++++++++---- test/unit/modules/modules.spec.ts | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/loops/for-in.ts b/src/transformation/visitors/loops/for-in.ts index f4365ac23..8631391d0 100644 --- a/src/transformation/visitors/loops/for-in.ts +++ b/src/transformation/visitors/loops/for-in.ts @@ -4,6 +4,7 @@ import { FunctionVisitor } from "../../context"; import { ForbiddenForIn, UnsupportedForInVariable } from "../../utils/errors"; import { isArrayType } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; +import { transformAssignment } from "../binary-expression/assignments"; import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; export const transformForInStatement: FunctionVisitor = (statement, context) => { @@ -33,11 +34,14 @@ export const transformForInStatement: FunctionVisitor = (stat // Iteration variable becomes ____key iterationVariable = lua.createIdentifier("____key"); // Push variable = ____key to the start of the loop body to match TS scoping - const initializer = lua.createAssignmentStatement( - transformIdentifier(context, statement.initializer), - iterationVariable + const assignment = transformAssignment( + context, + statement.initializer, + iterationVariable, + statement.initializer ); - body.statements.unshift(initializer); + + body.statements.unshift(...assignment); } else { // This should never occur throw UnsupportedForInVariable(statement.initializer); diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 6b5a86068..141c2d6e2 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -253,3 +253,22 @@ test("export as specifier shouldn't effect local vars", () => { a = 6; `.expectToMatchJsResult(); }); + +test("export modified in for in loop", () => { + util.testModule` + export let foo = ''; + for (foo in { x: true }) {} + ` + .setReturnExport("x") + .expectToMatchJsResult(); +}); + +test("export dependency modified in for in loop", () => { + util.testModule` + let foo = ''; + export { foo as bar }; + for (foo in { x: true }) {} + ` + .setReturnExport("bar") + .expectToEqual("x"); +}); From bb02542872ab8c62cc31f4d5c75a8cbd2eae0adb Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Tue, 25 Feb 2020 07:21:47 +1000 Subject: [PATCH 230/764] Print numbers overflowing the float limit as math.huge (#828) --- src/transformation/visitors/literal.ts | 12 +++++++++++- test/unit/builtins/numbers.spec.ts | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 281f70ec6..6149e476f 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -60,6 +60,16 @@ export function createShorthandIdentifier( return identifier; } +const transformNumericLiteralExpression: FunctionVisitor = expression => { + if (expression.text === "Infinity") { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, expression); + } + + return lua.createNumericLiteral(Number(expression.text), expression); +}; + const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { let properties: lua.TableFieldExpression[] = []; const tableExpressions: lua.Expression[] = []; @@ -142,7 +152,7 @@ export const literalVisitors: Visitors = { [ts.SyntaxKind.NullKeyword]: node => lua.createNilLiteral(node), [ts.SyntaxKind.TrueKeyword]: node => lua.createBooleanLiteral(true, node), [ts.SyntaxKind.FalseKeyword]: node => lua.createBooleanLiteral(false, node), - [ts.SyntaxKind.NumericLiteral]: node => lua.createNumericLiteral(Number(node.text), node), + [ts.SyntaxKind.NumericLiteral]: transformNumericLiteralExpression, [ts.SyntaxKind.StringLiteral]: node => lua.createStringLiteral(node.text, node), [ts.SyntaxKind.NoSubstitutionTemplateLiteral]: node => lua.createStringLiteral(node.text, node), [ts.SyntaxKind.ObjectLiteralExpression]: transformObjectLiteralExpression, diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index ac4303c18..2f52c1d7d 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -74,3 +74,7 @@ test("number intersected method", () => { return ({ normalize: () => 3 } as Vector).normalize(); `.expectToMatchJsResult(); }); + +test("numbers overflowing the float limit become math.huge", () => { + util.testExpression`1e309`.expectToMatchJsResult(); +}); From 770d5ffdc5cd1021fab3a248f0e391fd88307a27 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 24 Feb 2020 22:29:10 +0100 Subject: [PATCH 231/764] fixed issue in exported for in variable test --- test/unit/modules/modules.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 141c2d6e2..6b9f09c54 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -259,7 +259,7 @@ test("export modified in for in loop", () => { export let foo = ''; for (foo in { x: true }) {} ` - .setReturnExport("x") + .setReturnExport("foo") .expectToMatchJsResult(); }); From 8733a3e6529aae7a0772eff65c4fc67649e664da Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Fri, 28 Feb 2020 06:13:29 +1000 Subject: [PATCH 232/764] Fix default exports reference bug (#830) * Use escaped symbol names to reference default exports * Update src/transformation/visitors/identifier.ts Co-Authored-By: ark120202 * Move logic to transformIdentifierExpression * Use extra if in identifier expression Co-authored-by: ark120202 --- src/transformation/visitors/identifier.ts | 20 ++++++++++++-------- test/unit/modules/modules.spec.ts | 21 +++++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 565c0625b..b9097b962 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -4,7 +4,7 @@ import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; import { InvalidForRangeCall } from "../utils/errors"; -import { createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; +import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; @@ -27,12 +27,16 @@ export function transformIdentifier(context: TransformationContext, identifier: } export const transformIdentifierExpression: FunctionVisitor = (node, context) => { - // TODO: Move below to avoid extra transforms? - const identifier = transformIdentifier(context, node); - - const exportScope = getIdentifierExportScope(context, identifier); - if (exportScope) { - return createExportedIdentifier(context, identifier, exportScope); + const symbol = context.checker.getSymbolAtLocation(node); + if (symbol) { + const exportScope = getSymbolExportScope(context, symbol); + if (exportScope) { + const name = symbol.name; + const text = hasUnsafeIdentifierName(context, node) ? createSafeName(name) : name; + const symbolId = getIdentifierSymbolId(context, node); + const identifier = lua.createIdentifier(text, node, symbolId, name); + return createExportedIdentifier(context, identifier, exportScope); + } } if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { @@ -44,5 +48,5 @@ export const transformIdentifierExpression: FunctionVisitor = (no return builtinResult; } - return identifier; + return transformIdentifier(context, node); }; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 6b9f09c54..14cea1337 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -272,3 +272,24 @@ test("export dependency modified in for in loop", () => { .setReturnExport("bar") .expectToEqual("x"); }); + +test("export default class with future reference", () => { + util.testModule` + export default class Default {} + const d = new Default(); + export const result = d.constructor.name; + ` + .setReturnExport("result") + .expectToMatchJsResult(); +}); + +test("export default function with future reference", () => { + util.testModule` + export default function defaultFunction() { + return true; + } + export const result = defaultFunction(); + ` + .setReturnExport("result") + .expectToMatchJsResult(); +}); From 50817f8b39e1740a99053f85f571e8e204e3709e Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Fri, 28 Feb 2020 07:03:18 +1000 Subject: [PATCH 233/764] Support all for-of assignments and patterns (#831) * Support all for-of initializers * Add unit tests * Merge reuse transformAssignmentPattern * Move destructure tests from loops to destructuring * Use testCases in destructuring * Update src/transformation/visitors/loops/for-of.ts Co-Authored-By: ark120202 * Add reference to TS bug in destructuring * Move tests above array destructuring optimization * Remove any cast from assignment dependency test Co-authored-by: ark120202 --- src/transformation/utils/errors.ts | 3 -- .../destructuring-assignments.ts | 26 ++++------ src/transformation/visitors/loops/for-of.ts | 47 +++++-------------- test/unit/destructuring.spec.ts | 28 +++++++++++ test/unit/loops.spec.ts | 22 +-------- 5 files changed, 49 insertions(+), 77 deletions(-) diff --git a/src/transformation/utils/errors.ts b/src/transformation/utils/errors.ts index 91b07159b..370e27daa 100644 --- a/src/transformation/utils/errors.ts +++ b/src/transformation/utils/errors.ts @@ -130,9 +130,6 @@ export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => new TranspileError(`${reason}. TypeScript path: ${path}.`, node); -export const UnsupportedObjectDestructuringInForOf = (node: ts.Node) => - new TranspileError(`Unsupported object destructuring in for...of statement.`, node); - export const InvalidAmbientIdentifierName = (node: ts.Identifier) => new TranspileError( `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index d5d8b3fe2..088243cb4 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -38,20 +38,20 @@ export function transformDestructuringAssignment( node: ts.DestructuringAssignment, root: lua.Expression ): lua.Statement[] { - switch (node.left.kind) { - case ts.SyntaxKind.ObjectLiteralExpression: - return transformObjectDestructuringAssignment(context, node as ts.ObjectDestructuringAssignment, root); - case ts.SyntaxKind.ArrayLiteralExpression: - return transformArrayDestructuringAssignment(context, node as ts.ArrayDestructuringAssignment, root); - } + return transformAssignmentPattern(context, node.left, root); } -function transformArrayDestructuringAssignment( +export function transformAssignmentPattern( context: TransformationContext, - node: ts.ArrayDestructuringAssignment, + node: ts.AssignmentPattern, root: lua.Expression ): lua.Statement[] { - return transformArrayLiteralAssignmentPattern(context, node.left, root); + switch (node.kind) { + case ts.SyntaxKind.ObjectLiteralExpression: + return transformObjectLiteralAssignmentPattern(context, node, root); + case ts.SyntaxKind.ArrayLiteralExpression: + return transformArrayLiteralAssignmentPattern(context, node, root); + } } function transformArrayLiteralAssignmentPattern( @@ -132,14 +132,6 @@ function transformArrayLiteralAssignmentPattern( }); } -function transformObjectDestructuringAssignment( - context: TransformationContext, - node: ts.ObjectDestructuringAssignment, - root: lua.Expression -): lua.Statement[] { - return transformObjectLiteralAssignmentPattern(context, node.left, root); -} - function transformObjectLiteralAssignmentPattern( context: TransformationContext, node: ts.ObjectLiteralExpression, diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index a4df8f1d7..9c0596fb8 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -1,17 +1,11 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast, castEach } from "../../../utils"; +import { castEach } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { - InvalidForRangeCall, - MissingForOfVariables, - UnsupportedNonDestructuringLuaIterator, - UnsupportedObjectDestructuringInForOf, -} from "../../utils/errors"; -import { createUnpackCall } from "../../utils/lua-ast"; +import { InvalidForRangeCall, MissingForOfVariables, UnsupportedNonDestructuringLuaIterator } from "../../utils/errors"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { isArrayType, isNumberType } from "../../utils/typescript"; +import { isArrayType, isNumberType, isAssignmentPattern } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; import { @@ -20,6 +14,8 @@ import { transformVariableDeclaration, } from "../variable-declaration"; import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; +import { transformAssignment } from "../binary-expression/assignments"; +import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; function transformForOfInitializer( context: TransformationContext, @@ -29,15 +25,8 @@ function transformForOfInitializer( if (ts.isVariableDeclarationList(initializer)) { const binding = getVariableDeclarationBinding(initializer); // Declaration of new variable - if (ts.isArrayBindingPattern(binding)) { - if (binding.elements.length === 0) { - // Ignore empty destructuring assignment - return []; - } - + if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { return transformBindingPattern(context, binding, expression); - } else if (ts.isObjectBindingPattern(binding)) { - throw UnsupportedObjectDestructuringInForOf(initializer); } const variableStatements = transformVariableDeclaration(context, initializer.declarations[0]); @@ -53,27 +42,13 @@ function transformForOfInitializer( throw MissingForOfVariables(initializer); } } else { - // Assignment to existing variable - let variables: lua.AssignmentLeftHandSideExpression | lua.AssignmentLeftHandSideExpression[]; - let valueExpression: lua.Expression = expression; - if (ts.isArrayLiteralExpression(initializer)) { - if (initializer.elements.length > 0) { - valueExpression = createUnpackCall(context, expression, initializer); - variables = castEach( - initializer.elements.map(e => context.transformExpression(e)), - lua.isAssignmentLeftHandSideExpression - ); - } else { - // Ignore empty destructring assignment - return []; - } - } else if (ts.isObjectLiteralExpression(initializer)) { - throw UnsupportedObjectDestructuringInForOf(initializer); - } else { - variables = cast(context.transformExpression(initializer), lua.isAssignmentLeftHandSideExpression); + // Assignment to existing variable(s) + + if (isAssignmentPattern(initializer)) { + return transformAssignmentPattern(context, initializer, expression); } - return [lua.createAssignmentStatement(variables, valueExpression)]; + return transformAssignment(context, initializer, expression); } } diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 9ff2c746a..761930ec2 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -96,6 +96,34 @@ test.each(["[]", "{}"])("empty binding pattern", bindingPattern => { `.expectToMatchJsResult(); }); +// TODO: https://github.com/microsoft/TypeScript/pull/35906 +// Adjust this test to use expectToMatchJsResult() and testCases when this issue is fixed. +test.each([ + ["foo", "['bar']"], + ["[foo]", "[['bar']]"], + ["[foo = 'bar']", "[[]]"], + ["{ foo }", "[{ foo: 'bar' }]"], + ["{ x: foo }", "[{ x: 'bar' }]"], + ["{ foo = 'bar' }", "[{}] as { foo?: string }[]"], +])("forof assignment updates dependencies", (initializer, expression) => { + util.testModule` + let foo = ''; + export { foo }; + for (${initializer} of ${expression}) {} + ` + .setReturnExport("foo") + .expectToEqual("bar"); +}); + +test.each(testCases)("forof variable declaration binding patterns (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + for (const ${binding} of [${value} as any]) { + return { ${allBindings} }; + } + `.expectToMatchJsResult(); +}); + describe("array destructuring optimization", () => { // TODO: Try to generalize optimization logic between declaration and assignment and make more generic tests diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index edf381148..e73f85359 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,10 +1,6 @@ import * as ts from "typescript"; import * as tstl from "../../src"; -import { - ForbiddenForIn, - UnsupportedForTarget, - UnsupportedObjectDestructuringInForOf, -} from "../../src/transformation/utils/errors"; +import { ForbiddenForIn, UnsupportedForTarget } from "../../src/transformation/utils/errors"; import * as util from "../util"; test("while", () => { @@ -428,22 +424,6 @@ test("forof array which modifies length", () => { `.expectToMatchJsResult(); }); -test.each([ - { initializer: "const {a, b}", vars: "" }, - { initializer: "const {a: x, b: y}", vars: "" }, - { initializer: "{a, b}", vars: "let a: string, b: string;" }, - { initializer: "{a: c, b: d}", vars: "let c: string, d: string;" }, -])("forof object destructuring (%p)", ({ initializer, vars }) => { - const code = ` - declare const arr: {a: string, b: string}[]; - ${vars} - for (${initializer} of arr) {}`; - - expect(() => util.transpileString(code)).toThrow( - UnsupportedObjectDestructuringInForOf(ts.createEmptyStatement()).message - ); -}); - test("forof nested destructuring", () => { util.testFunction` let result = 0; From 170317055de9b307f1fadee1b335fe2b7ab46d6a Mon Sep 17 00:00:00 2001 From: Gengxin Wang <793493083@qq.com> Date: Tue, 10 Mar 2020 03:46:48 +0800 Subject: [PATCH 234/764] fix debug.traceback() return nil in lua5.1 (#818) --- src/lualib/SourceMapTraceBack.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index edad12c45..3a264ead9 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -7,7 +7,12 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li if (globalThis.__TS__originalTraceback === undefined) { globalThis.__TS__originalTraceback = debug.traceback; debug.traceback = (thread, message, level) => { - const trace = globalThis.__TS__originalTraceback(thread, message, level); + let trace: string; + if (thread === undefined && message === undefined && level === undefined) { + trace = globalThis.__TS__originalTraceback(); + } else { + trace = globalThis.__TS__originalTraceback(thread, message, level); + } if (typeof trace !== "string") { return trace; From c05029b1809d63ccfd385e38e4cd237c0c251cdf Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 12 Mar 2020 02:19:08 +0500 Subject: [PATCH 235/764] Upgrade dependencies (#834) * Upgrade dependencies * Fix TypeScript errors * Use V8 code coverage * Revert "Use V8 code coverage" This reverts commit ac39a6bf846f3731f8734aa775766c0a047bcc68. * Add changelog * Add workaround for changed symbol ids * Upgrade codecov-action --- .github/workflows/ci.yml | 5 +- CHANGELOG.md | 4 + package-lock.json | 3508 ++++++++--------- package.json | 22 +- src/CompilerOptions.ts | 2 +- .../destructuring-assignments.ts | 3 +- src/transformation/visitors/call.ts | 1 + src/transformation/visitors/function.ts | 9 +- src/transformation/visitors/literal.ts | 2 + src/transformation/visitors/modules/export.ts | 5 + test/legacy-utils.ts | 2 +- test/unit/annotations/forRange.spec.ts | 4 +- test/unit/builtins/string.spec.ts | 2 +- 13 files changed, 1632 insertions(+), 1937 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4fe1d6dcf..ae6be450f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,4 @@ jobs: env: CI: true - if: matrix.os == 'ubuntu-latest' - continue-on-error: true - uses: codecov/codecov-action@v1.0.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} + uses: codecov/codecov-action@v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index ac2e2d9f8..78a3ae137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- TypeScript has been updated to 3.8. See [release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) for details. + ## 0.31.0 - **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: diff --git a/package-lock.json b/package-lock.json index 93482cc2f..ded7a98f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,29 +5,30 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.8.3" } }, "@babel/core": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.5.tgz", - "integrity": "sha512-M42+ScN4+1S9iB6f+TL7QBpoQETxbclx+KNoKJABghnKYE+fMzSGqst0BZJc8CpI625bwPwYgUyRvxZ+0mZzpw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", + "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.4", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", @@ -35,21 +36,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -59,12 +45,12 @@ } }, "@babel/generator": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.4.tgz", - "integrity": "sha512-m5qo2WgdOJeyYngKImbkyQrnUN1mPceaG5BV+G0E3gWsa4l/jCSryWJdM2x8OuGAOyh+3d5pVYfZWCiNFtynxg==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", "dev": true, "requires": { - "@babel/types": "^7.7.4", + "@babel/types": "^7.8.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -79,126 +65,170 @@ } }, "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { - "@babel/types": "^7.7.4" + "@babel/types": "^7.8.3" } }, "@babel/helper-plugin-utils": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", - "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { - "@babel/types": "^7.7.4" + "@babel/types": "^7.8.3" } }, "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", "dev": true, "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" } }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/parser": { - "version": "7.7.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.5.tgz", - "integrity": "sha512-KNlOe9+/nk4i29g0VXgl8PEXIRms5xKLJeuZ6UptN0fHv+jDiriG+y94X6qAgWTR0h3KaoM1wK5G5h7MHFRSig==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", "dev": true }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, "@babel/plugin-syntax-object-rest-spread": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.7.4.tgz", - "integrity": "sha512-mObR+r+KZq0XhRVS2BrBKBpr5jqrqzlPvS9C9vuOf5ilSwzloAl7RPWLrgKdWS6IreaVrjHxTjtyqFiOisaCwg==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.0.0" + "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } } }, "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -206,113 +236,160 @@ "to-fast-properties": "^2.0.0" } }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", "dev": true, "requires": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", + "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" } }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, "@jest/console": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-24.9.0.tgz", - "integrity": "sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", + "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", "dev": true, "requires": { - "@jest/source-map": "^24.9.0", - "chalk": "^2.0.1", - "slash": "^2.0.0" + "@jest/source-map": "^25.1.0", + "chalk": "^3.0.0", + "jest-util": "^25.1.0", + "slash": "^3.0.0" } }, "@jest/core": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-24.9.0.tgz", - "integrity": "sha512-Fogg3s4wlAr1VX7q+rhV9RVnUv5tD7VuWfYy1+whMiWUrvl7U3QJSJyWcDio9Lq2prqYsZaeTv2Rz24pWGkJ2A==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/reporters": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz", + "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==", + "dev": true, + "requires": { + "@jest/console": "^25.1.0", + "@jest/reporters": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-changed-files": "^24.9.0", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-resolve-dependencies": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "jest-watcher": "^24.9.0", - "micromatch": "^3.1.10", - "p-each-series": "^1.0.0", + "graceful-fs": "^4.2.3", + "jest-changed-files": "^25.1.0", + "jest-config": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-resolve-dependencies": "^25.1.0", + "jest-runner": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "jest-watcher": "^25.1.0", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", "realpath-native": "^1.1.0", - "rimraf": "^2.5.4", - "slash": "^2.0.0", - "strip-ansi": "^5.0.0" + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } } }, "@jest/environment": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-24.9.0.tgz", - "integrity": "sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz", + "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==", "dev": true, "requires": { - "@jest/fake-timers": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0" + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0" } }, "@jest/fake-timers": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-24.9.0.tgz", - "integrity": "sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz", + "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0" + "@jest/types": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^25.1.0", + "lolex": "^5.0.0" } }, "@jest/reporters": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-24.9.0.tgz", - "integrity": "sha512-mu4X0yjaHrffOsWmVLzitKmmmWSQ3GGuefgNscUSWNiUNcEOSEQk9k3pERKEQVBb0Cnn88+UESIsZEMH3o88Gw==", - "dev": true, - "requires": { - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", + "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", - "istanbul-lib-coverage": "^2.0.2", - "istanbul-lib-instrument": "^3.0.1", - "istanbul-lib-report": "^2.0.4", - "istanbul-lib-source-maps": "^3.0.1", - "istanbul-reports": "^2.2.6", - "jest-haste-map": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", - "node-notifier": "^5.4.2", - "slash": "^2.0.0", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.0", + "jest-haste-map": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "node-notifier": "^6.0.0", + "slash": "^3.0.0", "source-map": "^0.6.0", - "string-length": "^2.0.0" + "string-length": "^3.1.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.0.1" }, "dependencies": { "source-map": { @@ -324,16 +401,22 @@ } }, "@jest/source-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-24.9.0.tgz", - "integrity": "sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", + "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", "dev": true, "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.1.15", + "graceful-fs": "^4.2.3", "source-map": "^0.6.0" }, "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -343,52 +426,60 @@ } }, "@jest/test-result": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-24.9.0.tgz", - "integrity": "sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", + "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", "dev": true, "requires": { - "@jest/console": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/istanbul-lib-coverage": "^2.0.0" + "@jest/console": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-24.9.0.tgz", - "integrity": "sha512-6qqsU4o0kW1dvA95qfNog8v8gkRN9ph6Lz7r96IvZpHdNipP2cBcb07J1Z45mz/VIS01OHJ3pY8T5fUY38tg4A==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", + "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", "dev": true, "requires": { - "@jest/test-result": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-runner": "^24.9.0", - "jest-runtime": "^24.9.0" + "@jest/test-result": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-runner": "^25.1.0", + "jest-runtime": "^25.1.0" } }, "@jest/transform": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-24.9.0.tgz", - "integrity": "sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", + "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/types": "^24.9.0", - "babel-plugin-istanbul": "^5.1.0", - "chalk": "^2.0.1", + "@jest/types": "^25.1.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.1.15", - "jest-haste-map": "^24.9.0", - "jest-regex-util": "^24.9.0", - "jest-util": "^24.9.0", - "micromatch": "^3.1.10", + "graceful-fs": "^4.2.3", + "jest-haste-map": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-util": "^25.1.0", + "micromatch": "^4.0.2", "pirates": "^4.0.1", "realpath-native": "^1.1.0", - "slash": "^2.0.0", + "slash": "^3.0.0", "source-map": "^0.6.1", - "write-file-atomic": "2.4.1" + "write-file-atomic": "^3.0.0" }, "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -398,20 +489,30 @@ } }, "@jest/types": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-24.9.0.tgz", - "integrity": "sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", + "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^13.0.0" + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", + "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" } }, "@types/babel__core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", - "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", + "integrity": "sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -422,9 +523,9 @@ } }, "@types/babel__generator": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.0.tgz", - "integrity": "sha512-c1mZUu4up5cp9KROs/QAw0gTeHrw/x7m52LcnvMxxOZ03DmLwPV0MlGmlgzV3cnSdjhJOZsj7E7FHeioai+egw==", + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -441,14 +542,20 @@ } }, "@types/babel__traverse": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", - "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", + "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -456,9 +563,9 @@ "dev": true }, "@types/fs-extra": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.0.1.tgz", - "integrity": "sha512-J00cVDALmi/hJOYsunyT52Hva5TnJeKP5yd1r+mH/ZU0mbYZflR0Z5kw5kITtKTRYMhm1JMClOFYdHnQszEvqw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", "dev": true, "requires": { "@types/node": "*" @@ -482,9 +589,9 @@ "dev": true }, "@types/istanbul-lib-report": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz", - "integrity": "sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" @@ -501,12 +608,13 @@ } }, "@types/jest": { - "version": "24.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.23.tgz", - "integrity": "sha512-L7MBvwfNpe7yVPTXLn32df/EK+AMBFAFvZrRuArGs7npEWnlziUXK+5GMIUTI4NIuwok3XibsjXCs5HxviYXjg==", + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", + "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", "dev": true, "requires": { - "jest-diff": "^24.3.0" + "jest-diff": "^25.1.0", + "pretty-format": "^25.1.0" } }, "@types/minimatch": { @@ -516,15 +624,15 @@ "dev": true }, "@types/node": { - "version": "12.12.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.14.tgz", - "integrity": "sha512-u/SJDyXwuihpwjXy7hOOghagLEV1KdAST6syfnOk6QZAMzZuWZqXy5aYYZbh8Jdpd4escVFP0MvftHNDb9pruA==", + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", + "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", "dev": true }, "@types/resolve": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz", - "integrity": "sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", "dev": true, "requires": { "@types/node": "*" @@ -537,18 +645,18 @@ "dev": true }, "@types/yargs": { - "version": "13.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-13.0.3.tgz", - "integrity": "sha512-K8/LfZq2duW33XW/tFwEAfnZlqIfVsoyRB3kfXdPXYhl0nfM8mmh7GS0jg7WrX2Dgq/0Ha/pR1PaR+BvmWwjiQ==", + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "13.1.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-13.1.0.tgz", - "integrity": "sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==", + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, "abab": { @@ -558,9 +666,9 @@ "dev": true }, "acorn": { - "version": "5.7.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", + "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", "dev": true }, "acorn-globals": { @@ -588,52 +696,56 @@ "dev": true }, "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", "dev": true, "requires": { - "fast-deep-equal": "^2.0.1", + "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" } }, "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, "arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { @@ -710,12 +822,6 @@ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, - "async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -735,55 +841,57 @@ "dev": true }, "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, "babel-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-24.9.0.tgz", - "integrity": "sha512-ntuddfyiN+EhMw58PTNL1ph4C9rECiQXjI4nMMBKBaNjXvqLdkXpPRcMSr4iyBrJg/+wz9brFUD6RhOAT6r4Iw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", + "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", "dev": true, "requires": { - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^5.1.0", - "babel-preset-jest": "^24.9.0", - "chalk": "^2.4.2", - "slash": "^2.0.0" + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.1.0", + "chalk": "^3.0.0", + "slash": "^3.0.0" } }, "babel-plugin-istanbul": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz", - "integrity": "sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.0.0", - "find-up": "^3.0.0", - "istanbul-lib-instrument": "^3.3.0", - "test-exclude": "^5.2.3" + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" } }, "babel-plugin-jest-hoist": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-24.9.0.tgz", - "integrity": "sha512-2EMA2P8Vp7lG0RAzr4HXqtYwacfMErOuv1U3wrvxHX6rD1sV6xS3WXG3r8TRQ2r6w8OhvSdWt+z41hQNwNm3Xw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", + "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", "dev": true, "requires": { "@types/babel__traverse": "^7.0.6" } }, "babel-preset-jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-24.9.0.tgz", - "integrity": "sha512-izTUuhE4TMfTRPF92fFwD2QfdXaZW08qvWTFCI51V8rW5x00UuPgc3ajRoWofXOuxjfcOM5zzSYsQS3H8KGCAg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", + "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", "dev": true, "requires": { + "@babel/plugin-syntax-bigint": "^7.0.0", "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^24.9.0" + "babel-plugin-jest-hoist": "^25.1.0" } }, "balanced-match": { @@ -867,32 +975,12 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "fill-range": "^7.0.1" } }, "browser-process-hrtime": { @@ -993,14 +1081,13 @@ "dev": true }, "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "ci-info": { @@ -1033,14 +1120,14 @@ } }, "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, "co": { @@ -1049,6 +1136,12 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, + "collect-v8-coverage": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz", + "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==", + "dev": true + }, "collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -1060,18 +1153,18 @@ } }, "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "color-name": "~1.1.4" } }, "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "combined-stream": { @@ -1136,18 +1229,26 @@ } }, "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, "cssstyle": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", - "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", + "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", "dev": true, "requires": { - "cssom": "0.3.x" + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } } }, "dashdash": { @@ -1168,28 +1269,15 @@ "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", "whatwg-url": "^7.0.0" - }, - "dependencies": { - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - } } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "decamelize": { @@ -1267,21 +1355,21 @@ "dev": true }, "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "diff-sequences": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz", - "integrity": "sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", "dev": true }, "domexception": { @@ -1304,9 +1392,9 @@ } }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "end-of-stream": { @@ -1318,31 +1406,23 @@ "once": "^1.4.0" } }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, "es-abstract": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.3.tgz", - "integrity": "sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw==", + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", - "string.prototype.trimleft": "^2.1.0", - "string.prototype.trimright": "^2.1.0" + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { @@ -1363,12 +1443,12 @@ "dev": true }, "escodegen": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", - "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", "dev": true, "requires": { - "esprima": "^3.1.3", + "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", @@ -1385,9 +1465,9 @@ } }, "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "estraverse": { @@ -1444,6 +1524,15 @@ "to-regex": "^3.0.1" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -1461,21 +1550,27 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true } } }, "expect": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-24.9.0.tgz", - "integrity": "sha512-wvVAx8XIol3Z5m9zvZXiyZOQ+sRJqNTIm6sGjdWlaZIeupQGO3WbYI+15D/AmEwZywL6wtJkbAbJtzkOfBuR0Q==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.1.0.tgz", + "integrity": "sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-styles": "^3.2.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-regex-util": "^24.9.0" + "@jest/types": "^25.1.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-regex-util": "^25.1.0" } }, "extend": { @@ -1577,15 +1672,15 @@ "dev": true }, "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, "fast-levenshtein": { @@ -1615,35 +1710,22 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } + "to-regex-range": "^5.0.1" } }, "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "for-in": { @@ -1704,569 +1786,34 @@ "dev": true }, "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -2311,33 +1858,15 @@ "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true + "dev": true, + "optional": true }, "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true - }, - "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", "dev": true, - "requires": { - "neo-async": "^2.6.0", - "optimist": "^0.6.1", - "source-map": "^0.6.1", - "uglify-js": "^3.1.4" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } + "optional": true }, "har-schema": { "version": "2.0.0", @@ -2365,9 +1894,9 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-symbols": { @@ -2397,6 +1926,26 @@ "kind-of": "^4.0.0" }, "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, "kind-of": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", @@ -2408,12 +1957,6 @@ } } }, - "hosted-git-info": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", - "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==", - "dev": true - }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -2423,6 +1966,12 @@ "whatwg-encoding": "^1.0.1" } }, + "html-escaper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", + "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "dev": true + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -2434,6 +1983,12 @@ "sshpk": "^1.7.0" } }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2444,13 +1999,13 @@ } }, "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true, "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" } }, "imurmurhash": { @@ -2475,14 +2030,11 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dev": true, - "requires": { - "loose-envify": "^1.0.0" - } + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true }, "is-accessor-descriptor": { "version": "0.1.6", @@ -2504,12 +2056,6 @@ } } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -2517,9 +2063,9 @@ "dev": true }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", "dev": true }, "is-ci": { @@ -2552,9 +2098,9 @@ } }, "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-descriptor": { @@ -2583,9 +2129,9 @@ "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-generator-fn": { @@ -2595,24 +2141,10 @@ "dev": true }, "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-plain-object": { "version": "2.0.4", @@ -2624,12 +2156,12 @@ } }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", "dev": true, "requires": { - "has": "^1.0.1" + "has": "^1.0.3" } }, "is-stream": { @@ -2660,10 +2192,11 @@ "dev": true }, "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", + "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "dev": true, + "optional": true }, "isarray": { "version": "1.0.0", @@ -2690,24 +2223,24 @@ "dev": true }, "istanbul-lib-coverage": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", - "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true }, "istanbul-lib-instrument": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", - "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", + "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", "dev": true, "requires": { - "@babel/generator": "^7.4.0", - "@babel/parser": "^7.4.3", - "@babel/template": "^7.4.0", - "@babel/traverse": "^7.4.3", - "@babel/types": "^7.4.0", - "istanbul-lib-coverage": "^2.0.5", - "semver": "^6.0.0" + "@babel/core": "^7.7.5", + "@babel/parser": "^7.7.5", + "@babel/template": "^7.7.4", + "@babel/traverse": "^7.7.4", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "dependencies": { "semver": { @@ -2719,55 +2252,27 @@ } }, "istanbul-lib-report": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", - "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "requires": { - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" } }, "istanbul-lib-source-maps": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", - "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "dev": true, "requires": { "debug": "^4.1.1", - "istanbul-lib-coverage": "^2.0.5", - "make-dir": "^2.1.0", - "rimraf": "^2.6.3", + "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" }, "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -2777,12 +2282,13 @@ } }, "istanbul-reports": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", - "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", "dev": true, "requires": { - "handlebars": "^4.1.2" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" } }, "javascript-stringify": { @@ -2792,254 +2298,354 @@ "dev": true }, "jest": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-24.9.0.tgz", - "integrity": "sha512-YvkBL1Zm7d2B1+h5fHEOdyjCG+sGMz4f8D86/0HiqJ6MB4MnDc8FgP5vdWsGnemOQro7lnYo8UakZ3+5A0jxGw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", + "integrity": "sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w==", "dev": true, "requires": { - "import-local": "^2.0.0", - "jest-cli": "^24.9.0" + "@jest/core": "^25.1.0", + "import-local": "^3.0.2", + "jest-cli": "^25.1.0" }, "dependencies": { "jest-cli": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-24.9.0.tgz", - "integrity": "sha512-+VLRKyitT3BWoMeSUIHRxV/2g8y9gw91Jh5z2UmXZzkZKpbC08CSehVxgHUwTpy+HwGcns/tqafQDJW7imYvGg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.1.0.tgz", + "integrity": "sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg==", "dev": true, "requires": { - "@jest/core": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", + "@jest/core": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "exit": "^0.1.2", - "import-local": "^2.0.0", + "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", + "jest-config": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", "prompts": "^2.0.1", "realpath-native": "^1.1.0", - "yargs": "^13.3.0" + "yargs": "^15.0.0" } } } }, "jest-changed-files": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-24.9.0.tgz", - "integrity": "sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.1.0.tgz", + "integrity": "sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "execa": "^1.0.0", - "throat": "^4.0.0" + "@jest/types": "^25.1.0", + "execa": "^3.2.0", + "throat": "^5.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", + "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "jest-circus": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-24.9.0.tgz", - "integrity": "sha512-dwkvwFtRc9Anmk1XTc+bonVL8rVMZ3CeGMoFWmv1oaQThdAgvfI9bwaFlZp+gLVphNVz6ZLfCWo3ERhS5CeVvA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", + "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^24.9.0", + "expect": "^25.1.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", + "jest-each": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0", "stack-utils": "^1.0.1", - "throat": "^4.0.0" + "throat": "^5.0.0" } }, "jest-config": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-24.9.0.tgz", - "integrity": "sha512-RATtQJtVYQrp7fvWg6f5y3pEFj9I+H8sWw4aKxnDZ96mob5i5SD6ZEGWgMLXQ4LE8UurrjbdlLWdUeo+28QpfQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.1.0.tgz", + "integrity": "sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^24.9.0", - "@jest/types": "^24.9.0", - "babel-jest": "^24.9.0", - "chalk": "^2.0.1", + "@jest/test-sequencer": "^25.1.0", + "@jest/types": "^25.1.0", + "babel-jest": "^25.1.0", + "chalk": "^3.0.0", "glob": "^7.1.1", - "jest-environment-jsdom": "^24.9.0", - "jest-environment-node": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", - "micromatch": "^3.1.10", - "pretty-format": "^24.9.0", + "jest-environment-jsdom": "^25.1.0", + "jest-environment-node": "^25.1.0", + "jest-get-type": "^25.1.0", + "jest-jasmine2": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.1.0", "realpath-native": "^1.1.0" } }, "jest-diff": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-24.9.0.tgz", - "integrity": "sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", "dev": true, "requires": { - "chalk": "^2.0.1", - "diff-sequences": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" } }, "jest-docblock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-24.9.0.tgz", - "integrity": "sha512-F1DjdpDMJMA1cN6He0FNYNZlo3yYmOtRUnktrT9Q37njYzC5WEaDdmbynIgy0L/IvXvvgsG8OsqhLPXTpfmZAA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.1.0.tgz", + "integrity": "sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA==", "dev": true, "requires": { - "detect-newline": "^2.1.0" + "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-24.9.0.tgz", - "integrity": "sha512-ONi0R4BvW45cw8s2Lrx8YgbeXL1oCQ/wIDwmsM3CqM/nlblNCPmnC3IPQlMbRFZu3wKdQ2U8BqM6lh3LJ5Bsog==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", + "integrity": "sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0" + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0" } }, "jest-environment-jsdom": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-24.9.0.tgz", - "integrity": "sha512-Zv9FV9NBRzLuALXjvRijO2351DRQeLYXtpD4xNvfoVFw21IOKNhZAEUKcbiEtjTkm2GsJ3boMVgkaR7rN8qetA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz", + "integrity": "sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ==", "dev": true, "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0", - "jsdom": "^11.5.1" + "@jest/environment": "^25.1.0", + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^25.1.0", + "jsdom": "^15.1.1" } }, "jest-environment-node": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-24.9.0.tgz", - "integrity": "sha512-6d4V2f4nxzIzwendo27Tr0aFm+IXWa0XEUnaH6nU0FMaozxovt+sfRvh4J47wL1OvF83I3SSTu0XK+i4Bqe7uA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.1.0.tgz", + "integrity": "sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw==", "dev": true, "requires": { - "@jest/environment": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/types": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-util": "^24.9.0" + "@jest/environment": "^25.1.0", + "@jest/fake-timers": "^25.1.0", + "@jest/types": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-util": "^25.1.0" } }, "jest-get-type": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-24.9.0.tgz", - "integrity": "sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", "dev": true }, "jest-haste-map": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.9.0.tgz", - "integrity": "sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", + "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "anymatch": "^2.0.0", + "@jest/types": "^25.1.0", + "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^1.2.7", - "graceful-fs": "^4.1.15", - "invariant": "^2.2.4", - "jest-serializer": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.9.0", - "micromatch": "^3.1.10", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.3", + "jest-serializer": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", + "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } } }, "jest-jasmine2": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-24.9.0.tgz", - "integrity": "sha512-Cq7vkAgaYKp+PsX+2/JbTarrk0DmNhsEtqBXNwUHkdlbrTBLtMJINADf2mf5FkowNsq8evbPc07/qFO0AdKTzw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz", + "integrity": "sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", + "@jest/environment": "^25.1.0", + "@jest/source-map": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^24.9.0", + "expect": "^25.1.0", "is-generator-fn": "^2.0.0", - "jest-each": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "pretty-format": "^24.9.0", - "throat": "^4.0.0" + "jest-each": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0", + "throat": "^5.0.0" } }, "jest-leak-detector": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-24.9.0.tgz", - "integrity": "sha512-tYkFIDsiKTGwb2FG1w8hX9V0aUb2ot8zY/2nFg087dUageonw1zrLMP4W6zsRO59dPkTSKie+D4rhMuP9nRmrA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz", + "integrity": "sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w==", "dev": true, "requires": { - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" } }, "jest-matcher-utils": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz", - "integrity": "sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", "dev": true, "requires": { - "chalk": "^2.0.1", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "pretty-format": "^24.9.0" + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" } }, "jest-message-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.9.0.tgz", - "integrity": "sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", + "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", "@types/stack-utils": "^1.0.1", - "chalk": "^2.0.1", - "micromatch": "^3.1.10", - "slash": "^2.0.0", + "chalk": "^3.0.0", + "micromatch": "^4.0.2", + "slash": "^3.0.0", "stack-utils": "^1.0.1" } }, "jest-mock": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.9.0.tgz", - "integrity": "sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz", + "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==", "dev": true, "requires": { - "@jest/types": "^24.9.0" + "@jest/types": "^25.1.0" } }, "jest-pnp-resolver": { @@ -3049,204 +2655,194 @@ "dev": true }, "jest-regex-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-24.9.0.tgz", - "integrity": "sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", + "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==", "dev": true }, "jest-resolve": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-24.9.0.tgz", - "integrity": "sha512-TaLeLVL1l08YFZAt3zaPtjiVvyy4oSA6CRe+0AFPPVX3Q/VI0giIWWoAvoS5L96vj9Dqxj4fB5p2qrHCmTU/MQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", + "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", + "@jest/types": "^25.1.0", "browser-resolve": "^1.11.3", - "chalk": "^2.0.1", + "chalk": "^3.0.0", "jest-pnp-resolver": "^1.2.1", "realpath-native": "^1.1.0" } }, "jest-resolve-dependencies": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-24.9.0.tgz", - "integrity": "sha512-Fm7b6AlWnYhT0BXy4hXpactHIqER7erNgIsIozDXWl5dVm+k8XdGVe1oTg1JyaFnOxarMEbax3wyRJqGP2Pq+g==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz", + "integrity": "sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-snapshot": "^24.9.0" + "@jest/types": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-snapshot": "^25.1.0" } }, "jest-runner": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-24.9.0.tgz", - "integrity": "sha512-KksJQyI3/0mhcfspnxxEOBueGrd5E4vV7ADQLT9ESaCzz02WnbdbKWIf5Mkaucoaj7obQckYPVX6JJhgUcoWWg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.1.0.tgz", + "integrity": "sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w==", "dev": true, "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "chalk": "^2.4.2", + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-docblock": "^24.3.0", - "jest-haste-map": "^24.9.0", - "jest-jasmine2": "^24.9.0", - "jest-leak-detector": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", - "jest-runtime": "^24.9.0", - "jest-util": "^24.9.0", - "jest-worker": "^24.6.0", + "graceful-fs": "^4.2.3", + "jest-config": "^25.1.0", + "jest-docblock": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-jasmine2": "^25.1.0", + "jest-leak-detector": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-runtime": "^25.1.0", + "jest-util": "^25.1.0", + "jest-worker": "^25.1.0", "source-map-support": "^0.5.6", - "throat": "^4.0.0" + "throat": "^5.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } } }, "jest-runtime": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-24.9.0.tgz", - "integrity": "sha512-8oNqgnmF3v2J6PVRM2Jfuj8oX3syKmaynlDMMKQ4iyzbQzIG6th5ub/lM2bCMTmoTKM3ykcUYI2Pw9xwNtjMnw==", - "dev": true, - "requires": { - "@jest/console": "^24.7.1", - "@jest/environment": "^24.9.0", - "@jest/source-map": "^24.3.0", - "@jest/transform": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "chalk": "^2.0.1", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.1.0.tgz", + "integrity": "sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA==", + "dev": true, + "requires": { + "@jest/console": "^25.1.0", + "@jest/environment": "^25.1.0", + "@jest/source-map": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/transform": "^25.1.0", + "@jest/types": "^25.1.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.1.15", - "jest-config": "^24.9.0", - "jest-haste-map": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-mock": "^24.9.0", - "jest-regex-util": "^24.3.0", - "jest-resolve": "^24.9.0", - "jest-snapshot": "^24.9.0", - "jest-util": "^24.9.0", - "jest-validate": "^24.9.0", + "graceful-fs": "^4.2.3", + "jest-config": "^25.1.0", + "jest-haste-map": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-mock": "^25.1.0", + "jest-regex-util": "^25.1.0", + "jest-resolve": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "jest-validate": "^25.1.0", "realpath-native": "^1.1.0", - "slash": "^2.0.0", - "strip-bom": "^3.0.0", - "yargs": "^13.3.0" + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + } } }, "jest-serializer": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.9.0.tgz", - "integrity": "sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", + "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==", "dev": true }, "jest-snapshot": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-24.9.0.tgz", - "integrity": "sha512-uI/rszGSs73xCM0l+up7O7a40o90cnrk429LOiK3aeTvfC0HHmldbd81/B7Ix81KSFe1lwkbl7GnBGG4UfuDew==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz", + "integrity": "sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^24.9.0", - "chalk": "^2.0.1", - "expect": "^24.9.0", - "jest-diff": "^24.9.0", - "jest-get-type": "^24.9.0", - "jest-matcher-utils": "^24.9.0", - "jest-message-util": "^24.9.0", - "jest-resolve": "^24.9.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "expect": "^25.1.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-resolve": "^25.1.0", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "pretty-format": "^24.9.0", - "semver": "^6.2.0" + "pretty-format": "^25.1.0", + "semver": "^7.1.1" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", + "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", "dev": true } } }, "jest-util": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.9.0.tgz", - "integrity": "sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", + "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", "dev": true, "requires": { - "@jest/console": "^24.9.0", - "@jest/fake-timers": "^24.9.0", - "@jest/source-map": "^24.9.0", - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "callsites": "^3.0.0", - "chalk": "^2.0.1", - "graceful-fs": "^4.1.15", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", "is-ci": "^2.0.0", - "mkdirp": "^0.5.1", - "slash": "^2.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "mkdirp": "^0.5.1" } }, "jest-validate": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-24.9.0.tgz", - "integrity": "sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.1.0.tgz", + "integrity": "sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA==", "dev": true, "requires": { - "@jest/types": "^24.9.0", + "@jest/types": "^25.1.0", "camelcase": "^5.3.1", - "chalk": "^2.0.1", - "jest-get-type": "^24.9.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.1.0", "leven": "^3.1.0", - "pretty-format": "^24.9.0" + "pretty-format": "^25.1.0" } }, "jest-watcher": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-24.9.0.tgz", - "integrity": "sha512-+/fLOfKPXXYJDYlks62/4R4GoT+GU1tYZed99JSCOsmzkkF7727RqKrjNAxtfO4YpGv11wybgRvCjR73lK2GZw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", + "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==", "dev": true, "requires": { - "@jest/test-result": "^24.9.0", - "@jest/types": "^24.9.0", - "@types/yargs": "^13.0.0", - "ansi-escapes": "^3.0.0", - "chalk": "^2.0.1", - "jest-util": "^24.9.0", - "string-length": "^2.0.0" + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "jest-util": "^25.1.0", + "string-length": "^3.1.0" } }, "jest-worker": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.9.0.tgz", - "integrity": "sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", + "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", "dev": true, "requires": { "merge-stream": "^2.0.0", - "supports-color": "^6.1.0" - }, - "dependencies": { - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "supports-color": "^7.0.0" } }, "js-tokens": { @@ -3263,14 +2859,6 @@ "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" - }, - "dependencies": { - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - } } }, "jsbn": { @@ -3280,36 +2868,36 @@ "dev": true }, "jsdom": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", - "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", "dev": true, "requires": { "abab": "^2.0.0", - "acorn": "^5.5.3", - "acorn-globals": "^4.1.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", "array-equal": "^1.0.0", - "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": "^1.0.0", - "data-urls": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", "domexception": "^1.0.1", - "escodegen": "^1.9.1", + "escodegen": "^1.11.1", "html-encoding-sniffer": "^1.0.2", - "left-pad": "^1.3.0", - "nwsapi": "^2.0.7", - "parse5": "4.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", "pn": "^1.1.0", - "request": "^2.87.0", - "request-promise-native": "^1.0.5", - "sax": "^1.2.4", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", "symbol-tree": "^3.2.2", - "tough-cookie": "^2.3.4", + "tough-cookie": "^3.0.1", "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.3", - "whatwg-mimetype": "^2.1.0", - "whatwg-url": "^6.4.1", - "ws": "^5.2.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", "xml-name-validator": "^3.0.0" } }, @@ -3319,12 +2907,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -3350,6 +2932,14 @@ "dev": true, "requires": { "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } } }, "jsonfile": { @@ -3374,9 +2964,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "kleur": { @@ -3385,12 +2975,6 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "left-pad": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", - "dev": true - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -3407,26 +2991,13 @@ "type-check": "~0.3.2" } }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - } - }, "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "^4.1.0" } }, "lodash": { @@ -3447,37 +3018,36 @@ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "@sinonjs/commons": "^1.7.0" } }, "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", "dev": true, "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" + "semver": "^6.0.0" }, "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "makeerror": { @@ -3511,41 +3081,36 @@ "dev": true }, "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==", + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", "dev": true }, "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", "dev": true, "requires": { - "mime-db": "1.42.0" + "mime-db": "1.43.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -3556,9 +3121,9 @@ } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "mixin-deep": { @@ -3589,29 +3154,14 @@ "dev": true, "requires": { "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -3637,12 +3187,6 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -3662,38 +3206,33 @@ "dev": true }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", + "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", "dev": true, + "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.1.1", + "semver": "^6.3.0", "shellwords": "^0.1.1", - "which": "^1.3.0" - } - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "which": "^1.3.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "optional": true + } } }, "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true }, "npm-run-path": { "version": "2.0.2", @@ -3768,14 +3307,26 @@ "isobject": "^3.0.0" } }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "object.pick": { @@ -3796,22 +3347,13 @@ "wrappy": "1" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - }, - "dependencies": { - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - } + "requires": { + "mimic-fn": "^2.1.0" } }, "optionator": { @@ -3835,13 +3377,10 @@ "dev": true }, "p-each-series": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-1.0.0.tgz", - "integrity": "sha1-kw89Et0fUOdDRFeiLNbwSsatf3E=", - "dev": true, - "requires": { - "p-reduce": "^1.0.0" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true }, "p-finally": { "version": "1.0.0", @@ -3850,49 +3389,33 @@ "dev": true }, "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "^2.2.0" } }, - "p-reduce": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-1.0.0.tgz", - "integrity": "sha1-GMKw3ZNqRpClKfgjH1ig/bakffo=", - "dev": true - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "parse5": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", "dev": true }, "pascalcase": { @@ -3902,9 +3425,9 @@ "dev": true }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { @@ -3924,25 +3447,16 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", "dev": true }, "pirates": { @@ -3955,12 +3469,12 @@ } }, "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "find-up": "^3.0.0" + "find-up": "^4.0.0" } }, "pn": { @@ -3988,31 +3502,31 @@ "dev": true }, "pretty-format": { - "version": "24.9.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.9.0.tgz", - "integrity": "sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==", + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", "dev": true, "requires": { - "@jest/types": "^24.9.0", - "ansi-regex": "^4.0.0", - "ansi-styles": "^3.2.0", - "react-is": "^16.8.4" + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" } }, "prompts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", - "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", + "integrity": "sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.3" + "sisteransi": "^1.0.4" } }, "psl": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.6.0.tgz", - "integrity": "sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", "dev": true }, "pump": { @@ -4043,27 +3557,6 @@ "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", "dev": true }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", - "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", - "dev": true, - "requires": { - "find-up": "^3.0.0", - "read-pkg": "^3.0.0" - } - }, "readline-sync": { "version": "1.4.9", "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", @@ -4108,9 +3601,9 @@ "dev": true }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "dev": true, "requires": { "aws-sign2": "~0.7.0", @@ -4120,7 +3613,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -4130,25 +3623,19 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" }, "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" + "psl": "^1.1.28", + "punycode": "^2.1.1" } } } @@ -4171,6 +3658,18 @@ "request-promise-core": "1.1.3", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "require-directory": { @@ -4186,26 +3685,26 @@ "dev": true }, "resolve": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.13.1.tgz", - "integrity": "sha512-CxqObCX8K8YtAhOBRg+lrcdn+LK+WYOS8tSjqSFbjtrI5PnS63QPhZl4+yKfrU9tdsbMu9Anr/amegT87M9Z6w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "requires": { "path-parse": "^1.0.6" } }, "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "requires": { - "resolve-from": "^3.0.0" + "resolve-from": "^5.0.0" } }, "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true }, "resolve-url": { @@ -4221,9 +3720,9 @@ "dev": true }, "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { "glob": "^7.1.3" @@ -4271,13 +3770,146 @@ "micromatch": "^3.1.4", "minimist": "^1.1.1", "walker": "~1.0.5" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } } }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "dev": true, + "requires": { + "xmlchars": "^2.1.1" + } }, "semver": { "version": "5.7.1", @@ -4333,7 +3965,8 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true + "dev": true, + "optional": true }, "signal-exit": { "version": "3.0.2", @@ -4348,9 +3981,9 @@ "dev": true }, "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "snapdragon": { @@ -4369,6 +4002,15 @@ "use": "^3.1.0" }, "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, "define-property": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", @@ -4387,6 +4029,12 @@ "is-extendable": "^0.1.0" } }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -4472,12 +4120,12 @@ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "requires": { - "atob": "^2.1.1", + "atob": "^2.1.2", "decode-uri-component": "^0.2.0", "resolve-url": "^0.2.1", "source-map-url": "^0.4.0", @@ -4508,38 +4156,6 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, - "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -4606,47 +4222,47 @@ "dev": true }, "string-length": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", - "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", + "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", "dev": true, "requires": { "astral-regex": "^1.0.0", - "strip-ansi": "^4.0.0" + "strip-ansi": "^5.2.0" }, "dependencies": { "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^3.0.0" + "ansi-regex": "^4.1.0" } } } }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "string.prototype.trimleft": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", - "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -4654,9 +4270,9 @@ } }, "string.prototype.trimright": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", - "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", "dev": true, "requires": { "define-properties": "^1.1.3", @@ -4664,18 +4280,18 @@ } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, "strip-eof": { @@ -4684,13 +4300,29 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" } }, "symbol-tree": { @@ -4699,22 +4331,31 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, "test-exclude": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", - "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "requires": { - "glob": "^7.1.3", - "minimatch": "^3.0.4", - "read-pkg-up": "^4.0.0", - "require-main-filename": "^2.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" } }, "throat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", - "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, "tmp": { @@ -4771,21 +4412,21 @@ } }, "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "requires": { + "ip-regex": "^2.1.0", "psl": "^1.1.28", "punycode": "^2.1.1" } @@ -4800,9 +4441,9 @@ } }, "ts-jest": { - "version": "24.2.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-24.2.0.tgz", - "integrity": "sha512-Yc+HLyldlIC9iIK8xEN7tV960Or56N49MDP7hubCZUeI7EbIOTsas6rXCMB4kQjLACJ7eDOF4xWEO5qumpKsag==", + "version": "25.2.1", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.2.1.tgz", + "integrity": "sha512-TnntkEEjuXq/Gxpw7xToarmHbAafgCaAzOpnajnFC6jI7oo1trMzAHA04eWpc3MhV6+yvhE8uUBAmN+teRJh0A==", "dev": true, "requires": { "bs-logger": "0.x", @@ -4814,49 +4455,32 @@ "mkdirp": "0.x", "resolve": "1.x", "semver": "^5.5", - "yargs-parser": "10.x" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } + "yargs-parser": "^16.1.0" } }, "ts-node": { - "version": "8.5.4", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.5.4.tgz", - "integrity": "sha512-izbVCRV68EasEPQ8MSIGBNK9dc/4sYJJKYA+IarMQct1RtEot6Xp0bXuClsbUSnKpg50ho+aOAx8en5c+y4OFw==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.6", - "yn": "^3.0.0" + "yn": "3.1.1" } }, "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", "dev": true }, "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.0.0.tgz", + "integrity": "sha512-9nLya8GBtlFmmFMW7oXXwoXS1NkrccqTqAtwXzdPV9e2mqSEvCki6iHL/Fbzi5oqbugshzgGPk7KBb2qNP1DSA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -4870,15 +4494,59 @@ "mkdirp": "^0.5.1", "resolve": "^1.3.2", "semver": "^5.3.0", - "tslib": "^1.8.0", + "tslib": "^1.10.0", "tsutils": "^2.29.0" }, "dependencies": { - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, @@ -4915,31 +4583,32 @@ "prelude-ls": "~1.1.2" } }, - "typescript": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", - "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==" + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true }, - "uglify-js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", - "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==", + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, - "optional": true, "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } + "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", + "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -5020,29 +4689,32 @@ "dev": true }, "util.promisify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", - "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "object.getownpropertydescriptors": "^2.0.3" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" } }, "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "v8-to-istanbul": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz", + "integrity": "sha512-G9R+Hpw0ITAmPSr47lSlc5A1uekSYzXxTMlFxso2xoffwo4jQnzbv1p9yXIinO8UMZKfAFewaCHwWvnH4Jb4Ug==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" } }, "verror": { @@ -5065,6 +4737,17 @@ "browser-process-hrtime": "^0.1.2" } }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", @@ -5096,9 +4779,9 @@ "dev": true }, "whatwg-url": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", - "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -5127,21 +4810,15 @@ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true }, - "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", - "dev": true - }, "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" } }, "wrappy": { @@ -5151,24 +4828,22 @@ "dev": true }, "write-file-atomic": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.1.tgz", - "integrity": "sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { - "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, "ws": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", - "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, - "requires": { - "async-limiter": "~1.0.0" - } + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", + "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==", + "dev": true }, "xml-name-validator": { "version": "3.0.0", @@ -5176,6 +4851,12 @@ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", "dev": true }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", @@ -5183,27 +4864,28 @@ "dev": true }, "yargs": { - "version": "13.3.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", - "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", + "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", "dev": true, "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", - "string-width": "^3.0.0", + "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^16.1.0" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index f0bdfceda..b19aaf950 100644 --- a/package.json +++ b/package.json @@ -39,24 +39,24 @@ "node": ">=12.13.0" }, "dependencies": { - "resolve": "^1.13.1", + "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "^3.7.3" + "typescript": "^3.8.3" }, "devDependencies": { - "@types/fs-extra": "^8.0.1", + "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", - "@types/jest": "^24.0.23", - "@types/node": "^12.12.14", - "@types/resolve": "0.0.8", + "@types/jest": "^25.1.3", + "@types/node": "^13.7.7", + "@types/resolve": "1.14.0", "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^24.9.0", - "jest-circus": "^24.9.0", + "jest": "^25.1.0", + "jest-circus": "^25.1.0", "prettier": "^1.19.1", - "ts-jest": "^24.2.0", - "ts-node": "^8.5.4", - "tslint": "^5.20.1" + "ts-jest": "^25.2.1", + "ts-node": "^8.6.2", + "tslint": "^6.0.0" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 0887efd81..788f15d76 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -26,7 +26,7 @@ export type CompilerOptions = OmitIndexSignature & { luaLibImport?: LuaLibImportKind; sourceMapTraceback?: boolean; plugins?: Array; - [option: string]: ts.CompilerOptions[string] | Array; + [option: string]: any; }; export enum LuaLibImportKind { diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index 088243cb4..e255cbf70 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -252,7 +252,8 @@ function transformSpreadAssignment( for (const property of properties) { if ( (ts.isShorthandPropertyAssignment(property) || ts.isPropertyAssignment(property)) && - !ts.isComputedPropertyName(property.name) + !ts.isComputedPropertyName(property.name) && + !ts.isPrivateIdentifier(property.name) ) { const name = ts.isIdentifier(property.name) ? lua.createStringLiteral(property.name.text) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 7656ed01d..75e2a95b2 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -49,6 +49,7 @@ export function transformContextualCallExpression( const left = ts.isCallExpression(node) ? node.expression : node.tag; if ( ts.isPropertyAccessExpression(left) && + ts.isIdentifier(left.name) && !luaKeywords.has(left.name.text) && isValidLuaIdentifier(left.name.text) ) { diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index dc7a1b0a4..1d81a0e45 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -13,7 +13,6 @@ import { wrapInTable, } from "../utils/lua-ast"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; -import { getSymbolIdOfSymbol } from "../utils/symbols"; import { transformGeneratorFunctionBody } from "./generator"; import { transformIdentifier } from "./identifier"; import { transformBindingPattern } from "./variable-declaration"; @@ -215,9 +214,13 @@ export function transformFunctionLikeDeclaration( if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) { const symbol = context.checker.getSymbolAtLocation(node.name); if (symbol) { - const symbolId = getSymbolIdOfSymbol(context, symbol); + // TODO: Not using symbol ids because of https://github.com/microsoft/TypeScript/issues/37131 + const isReferenced = [...scope.referencedSymbols].some(([, nodes]) => + nodes.some(n => context.checker.getSymbolAtLocation(n)?.valueDeclaration === symbol.valueDeclaration) + ); + // Only wrap if the name is actually referenced inside the function - if (symbolId !== undefined && scope.referencedSymbols.has(symbolId)) { + if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); return createImmediatelyInvokedFunctionExpression( [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 6149e476f..28e90d0c0 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -21,6 +21,8 @@ export function transformPropertyName(context: TransformationContext, node: ts.P return context.transformExpression(node.expression); } else if (ts.isIdentifier(node)) { return lua.createStringLiteral(node.text); + } else if (ts.isPrivateIdentifier(node)) { + throw new Error("PrivateIdentifier is not supported"); } else { return context.transformExpression(node); } diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index b3a9f3433..c6b83fcde 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -136,6 +136,11 @@ export const transformExportDeclaration: FunctionVisitor = return undefined; } + if (ts.isNamespaceExport(node.exportClause)) { + // export * as ns from "..."; + throw new Error("NamespaceExport is not supported"); + } + const exportSpecifiers = getExported(context, node.exportClause); // export { ... }; diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index 8715fbe62..35918aabe 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -23,7 +23,7 @@ export function transpileStringsAsProject( input: Record, options: tstl.CompilerOptions = {} ): tstl.TranspileResult { - const optionsWithDefaults = { + const optionsWithDefaults: tstl.CompilerOptions = { luaTarget: tstl.LuaTarget.Lua53, noHeader: true, skipLibCheck: true, diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts index ee5cb74d0..d49fa5c1c 100644 --- a/test/unit/annotations/forRange.spec.ts +++ b/test/unit/annotations/forRange.spec.ts @@ -33,10 +33,10 @@ test("invalid non-ambient @forRange function", () => { ); }); -test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", args => { +test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", (...args) => { const code = ` /** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; } - for (const i of luaRange(${args})) {}`; + for (const i of luaRange(${util.formatCode(...args)})) {}`; expect(() => util.transpileString(code)).toThrow( InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.").message diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 2c61645c0..a9b6afba4 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -63,7 +63,7 @@ test.each([ ["hello", "test", "bye"], ["hello", 42], [42, "hello"], -])("string.concat[+] (%p)", (...elements) => { +])("string.concat[+] (%p)", (...elements: any[]) => { util.testExpression(elements.map(e => util.formatCode(e)).join(" + ")).expectToMatchJsResult(); }); From 1a1e36906fb2777ab6e6bfa8a873a796d2b6ad59 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Fri, 13 Mar 2020 01:35:28 +0500 Subject: [PATCH 236/764] Generalize class accessors transform (#774) * Generalize class accessors transform * Remove `rawset` from the list of used builtins * Fix sourcemaps * Improve class extends test case * Improve lualib types * Add few comments to lualib * Temporary revert getter property override removal * Add changelog * Change sourcemap class extends mapping pattern --- CHANGELOG.md | 48 ++++ src/LuaLib.ts | 6 +- src/lualib/Class.ts | 4 +- src/lualib/ClassExtends.ts | 19 ++ src/lualib/ClassIndex.ts | 21 -- src/lualib/ClassNewIndex.ts | 17 -- src/lualib/Descriptors.ts | 75 ++++++ src/lualib/Index.ts | 26 --- src/lualib/InstanceOf.ts | 2 +- src/lualib/NewIndex.ts | 24 -- src/lualib/declarations/tstl.d.ts | 19 +- src/transformation/context/context.ts | 8 + src/transformation/utils/safe-names.ts | 1 - src/transformation/visitors/class/index.ts | 52 +++-- .../visitors/class/members/accessors.ts | 83 ++++--- .../visitors/class/members/fields.ts | 2 + src/transformation/visitors/class/setup.ts | 213 ++---------------- src/transformation/visitors/class/utils.ts | 27 +-- test/unit/identifiers.spec.ts | 15 -- test/unit/printer/sourcemaps.spec.ts | 5 +- 20 files changed, 272 insertions(+), 395 deletions(-) create mode 100644 src/lualib/ClassExtends.ts delete mode 100644 src/lualib/ClassIndex.ts delete mode 100644 src/lualib/ClassNewIndex.ts create mode 100644 src/lualib/Descriptors.ts delete mode 100644 src/lualib/Index.ts delete mode 100644 src/lualib/NewIndex.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a3ae137..6936a691c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,54 @@ - TypeScript has been updated to 3.8. See [release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) for details. +- Fixed class accessors not working when base class is lacking type information (#725) + +- Class extension code has been extracted to lualib + + ```ts + class A {} + class B extends A {} + ``` + + ```diff + A = __TS__Class() + B = __TS__Class() + -B.____super = A + -setmetatable(B, B.____super) + -setmetatable(B.prototype, B.____super.prototype) + +__TS__ClassExtends(A, B) + ``` + +- Generated code for class accessors is more dynamic now + + ```ts + class A { + get a() { + return true; + } + } + ``` + + ```diff + A = __TS__Class() + -A.prototype.____getters = {} + -A.prototype.__index = __TS__Index(A.prototype) + -function A.prototype.____getters.a(self) + - return true + -end + +__TS__SetDescriptor( + + A.prototype, + + "a", + + { + + get = function(self) + + return true + + end + + } + +) + ``` + + This change simplifies our codebase and opens a path to object accessors implementation + ## 0.31.0 - **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7b1926912..38e978fb3 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -26,20 +26,18 @@ export enum LuaLibFeature { ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", Class = "Class", - ClassIndex = "ClassIndex", - ClassNewIndex = "ClassNewIndex", + ClassExtends = "ClassExtends", Decorate = "Decorate", + Descriptors = "Descriptors", Error = "Error", FunctionApply = "FunctionApply", FunctionBind = "FunctionBind", FunctionCall = "FunctionCall", - Index = "Index", InstanceOf = "InstanceOf", InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", Map = "Map", New = "New", - NewIndex = "NewIndex", Number = "Number", NumberIsFinite = "NumberIsFinite", NumberIsNaN = "NumberIsNaN", diff --git a/src/lualib/Class.ts b/src/lualib/Class.ts index 14aa98587..d5d7af93d 100644 --- a/src/lualib/Class.ts +++ b/src/lualib/Class.ts @@ -1,7 +1,5 @@ function __TS__Class(): LuaClass { - const c = {} as LuaClass; - c.__index = c; - c.prototype = {}; + const c: LuaClass = { prototype: {} }; c.prototype.__index = c.prototype; c.prototype.constructor = c; return c; diff --git a/src/lualib/ClassExtends.ts b/src/lualib/ClassExtends.ts new file mode 100644 index 000000000..e297cba93 --- /dev/null +++ b/src/lualib/ClassExtends.ts @@ -0,0 +1,19 @@ +function __TS__ClassExtends(this: void, target: LuaClass, base: LuaClass): void { + target.____super = base; + + // Set base class as a metatable, because descriptors use `getmetatable` to get extended prototype + const staticMetatable: any = setmetatable({ __index: base }, base); + setmetatable(target, staticMetatable); + + const baseMetatable = getmetatable(base); + if (baseMetatable) { + // Re-add metatable events defined by descriptors + if (typeof baseMetatable.__index === "function") staticMetatable.__index = baseMetatable.__index; + if (typeof baseMetatable.__newindex === "function") staticMetatable.__newindex = baseMetatable.__newindex; + } + + setmetatable(target.prototype, base.prototype); + // Re-add metatable events defined by accessors with `__TS__SetDescriptor` + if (typeof base.prototype.__index === "function") target.prototype.__index = base.prototype.__index; + if (typeof base.prototype.__newindex === "function") target.prototype.__newindex = base.prototype.__newindex; +} diff --git a/src/lualib/ClassIndex.ts b/src/lualib/ClassIndex.ts deleted file mode 100644 index 0f753e3bb..000000000 --- a/src/lualib/ClassIndex.ts +++ /dev/null @@ -1,21 +0,0 @@ -function __TS__ClassIndex(this: void, classTable: LuaClass, key: any): any { - while (true) { - const getters = rawget(classTable, "____getters"); - if (getters) { - const getter = getters[key]; - if (getter) { - return getter(classTable); - } - } - - classTable = rawget(classTable, "____super"); - if (!classTable) { - break; - } - - const val = rawget(classTable, key); - if (val !== null) { - return val; - } - } -} diff --git a/src/lualib/ClassNewIndex.ts b/src/lualib/ClassNewIndex.ts deleted file mode 100644 index 99205093c..000000000 --- a/src/lualib/ClassNewIndex.ts +++ /dev/null @@ -1,17 +0,0 @@ -function __TS__ClassNewIndex(this: void, classTable: LuaClass, key: any, val: any): void { - let tbl = classTable; - do { - const setters = rawget(tbl, "____setters"); - if (setters) { - const setter = setters[key]; - if (setter) { - setter(tbl, val); - return; - } - } - - tbl = rawget(tbl, "____super"); - } while (tbl); - - rawset(classTable, key, val); -} diff --git a/src/lualib/Descriptors.ts b/src/lualib/Descriptors.ts new file mode 100644 index 000000000..eb5198408 --- /dev/null +++ b/src/lualib/Descriptors.ts @@ -0,0 +1,75 @@ +function ____descriptorIndex(this: any, key: string): void { + const value = rawget(this, key); + if (value !== null) { + return value; + } + + let metatable = getmetatable(this); + while (metatable) { + const rawResult = rawget(metatable, key); + if (rawResult !== undefined) { + return rawResult; + } + + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor) { + if (descriptor.get) { + return descriptor.get.call(this); + } + + return; + } + } + + metatable = getmetatable(metatable); + } +} + +function ____descriptorNewindex(this: any, key: string, value: any): void { + let metatable = getmetatable(this); + while (metatable) { + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor) { + if (descriptor.set) { + descriptor.set.call(this, value); + } + + return; + } + } + + metatable = getmetatable(metatable); + } + + rawset(this, key, value); +} + +// It's also used directly in class transform to add descriptors to the prototype +function __TS__SetDescriptor(this: void, metatable: Metatable, prop: string, descriptor: PropertyDescriptor): void { + if (!metatable._descriptors) metatable._descriptors = {}; + metatable._descriptors[prop] = descriptor; + + if (descriptor.get) metatable.__index = ____descriptorIndex; + if (descriptor.set) metatable.__newindex = ____descriptorNewindex; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty +function __TS__ObjectDefineProperty( + this: void, + object: T, + prop: string, + descriptor: PropertyDescriptor +): T { + let metatable = getmetatable(object); + if (!metatable) { + metatable = {}; + setmetatable(object, metatable); + } + + __TS__SetDescriptor(metatable, prop, descriptor); + return object; +} diff --git a/src/lualib/Index.ts b/src/lualib/Index.ts deleted file mode 100644 index ee7c2b9c7..000000000 --- a/src/lualib/Index.ts +++ /dev/null @@ -1,26 +0,0 @@ -function __TS__Index(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: any) => any { - return (tbl, key) => { - let proto = classProto; - while (true) { - const val = rawget(proto, key); - if (val !== null) { - return val; - } - - const getters = rawget(proto, "____getters"); - if (getters) { - const getter = getters[key]; - if (getter) { - return getter(tbl); - } - } - - const base = rawget(rawget(proto, "constructor"), "____super"); - if (!base) { - break; - } - - proto = rawget(base, "prototype"); - } - }; -} diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index b9b47f707..b856ddaa9 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -1,4 +1,4 @@ -function __TS__InstanceOf(this: void, obj: LuaObject, classTbl: LuaClass): boolean { +function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: LuaClass): boolean { if (typeof classTbl !== "object") { // tslint:disable-next-line: no-string-throw throw "Right-hand side of 'instanceof' is not an object"; diff --git a/src/lualib/NewIndex.ts b/src/lualib/NewIndex.ts deleted file mode 100644 index da0d4d12a..000000000 --- a/src/lualib/NewIndex.ts +++ /dev/null @@ -1,24 +0,0 @@ -function __TS__NewIndex(this: void, classProto: LuaObject): (this: void, tbl: LuaObject, key: any, val: any) => void { - return (tbl, key, val) => { - let proto = classProto; - while (true) { - const setters = rawget(proto, "____setters"); - if (setters) { - const setter = setters[key]; - if (setter) { - setter(tbl, val); - return; - } - } - - const base = rawget(rawget(proto, "constructor"), "____super"); - if (!base) { - break; - } - - proto = rawget(base, "prototype"); - } - - rawset(tbl, key, val); - }; -} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 9216870f2..11c34c809 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -6,17 +6,18 @@ interface Vararg extends Array {} /** @forRange */ declare function forRange(start: number, limit: number, step?: number): number[]; -interface LuaClass { - prototype: LuaObject; - ____super?: LuaClass; - ____getters?: { [key: string]: (self: LuaClass) => any }; - ____setters?: { [key: string]: (self: LuaClass, val: any) => void }; +interface Metatable { + _descriptors?: Record; __index?: any; + __newindex?: any; } -interface LuaObject { +interface LuaClass extends Metatable { + prototype: LuaClassInstance; + [Symbol.hasInstance]?(instance: LuaClassInstance): any; + ____super?: LuaClass; +} + +interface LuaClassInstance extends Metatable { constructor: LuaClass; - ____getters?: { [key: string]: (self: LuaObject) => any }; - ____setters?: { [key: string]: (self: LuaObject, val: any) => void }; - __index?: any; } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index e192348b3..0b34da260 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -4,11 +4,19 @@ import * as lua from "../../LuaAST"; import { unwrapVisitorResult } from "../utils/lua-ast"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; +export interface AllAccessorDeclarations { + firstAccessor: ts.AccessorDeclaration; + secondAccessor: ts.AccessorDeclaration | undefined; + getAccessor: ts.GetAccessorDeclaration | undefined; + setAccessor: ts.SetAccessorDeclaration | undefined; +} + export interface EmitResolver { isValueAliasDeclaration(node: ts.Node): boolean; isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; + getAllAccessorDeclarations(declaration: ts.AccessorDeclaration): AllAccessorDeclarations; } export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index dbd8f3071..ed95f0d44 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -41,7 +41,6 @@ export const luaBuiltins: ReadonlySet = new Set([ "pcall", "print", "rawget", - "rawset", "repeat", "require", "self", diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 8f4049399..bf11c8748 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -32,13 +32,13 @@ import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; import { createConstructorDecorationStatement } from "./decorators"; -import { isGetAccessorOverride, transformAccessorDeclaration } from "./members/accessors"; +import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; import { transformClassInstanceFields } from "./members/fields"; import { transformMethodDeclaration } from "./members/method"; import { checkForLuaLibType } from "./new"; import { createClassSetup } from "./setup"; -import { getExtendedType, getExtendedTypeNode, isStaticNode } from "./utils"; +import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, @@ -105,23 +105,23 @@ export function transformClassDeclaration( } // Get type that is extended - const extendsType = getExtendedType(context, classDeclaration); + const extendedType = getExtendedType(context, classDeclaration); - if (extendsType) { - checkForLuaLibType(context, extendsType); + if (extendedType) { + checkForLuaLibType(context, extendedType); } - if (!(isExtension || isMetaExtension) && extendsType) { + if (!(isExtension || isMetaExtension) && extendedType) { // Non-extensions cannot extend extension classes - const extendsAnnotations = getTypeAnnotations(extendsType); + const extendsAnnotations = getTypeAnnotations(extendedType); if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { throw InvalidExtendsExtension(classDeclaration); } } // You cannot extend LuaTable classes - if (extendsType) { - const annotations = getTypeAnnotations(extendsType); + if (extendedType) { + const annotations = getTypeAnnotations(extendedType); if (annotations.has(AnnotationKind.LuaTable)) { throw InvalidExtendsLuaTable(classDeclaration); } @@ -143,11 +143,11 @@ export function transformClassDeclaration( // Overwrite the original className with the class we are overriding for extensions if (isMetaExtension) { - if (!extendsType) { + if (!extendedType) { throw MissingMetaExtension(classDeclaration); } - const extendsName = lua.createStringLiteral(extendsType.symbol.name as string); + const extendsName = lua.createStringLiteral(extendedType.symbol.name as string); className = lua.createIdentifier("__meta__" + extendsName.value); // local className = debug.getregistry()["extendsName"] @@ -173,8 +173,8 @@ export function transformClassDeclaration( const [extensionName] = extensionDirective.args; if (extensionName) { className = lua.createIdentifier(extensionName); - } else if (extendsType) { - className = lua.createIdentifier(extendsType.symbol.name); + } else if (extendedType) { + className = lua.createIdentifier(extendedType.symbol.name); } } @@ -193,7 +193,7 @@ export function transformClassDeclaration( if (!isExtension && !isMetaExtension) { result.push( - ...createClassSetup(context, classDeclaration, className, localClassName, classNameText, extendsType) + ...createClassSetup(context, classDeclaration, className, localClassName, classNameText, extendedType) ); } else { for (const f of instanceFields) { @@ -228,7 +228,7 @@ export function transformClassDeclaration( ); if (constructorResult) result.push(constructorResult); - } else if (!extendsType) { + } else if (!extendedType) { // Generate a constructor if none was defined in a base class const constructorResult = transformConstructorDeclaration( context, @@ -276,12 +276,16 @@ export function transformClassDeclaration( } // Transform accessors - result.push( - ...classDeclaration.members - .filter(ts.isAccessor) - .map(accessor => transformAccessorDeclaration(context, accessor, localClassName)) - .filter(isNonNull) - ); + for (const member of classDeclaration.members) { + if (!ts.isAccessor(member)) continue; + const accessors = context.resolver.getAllAccessorDeclarations(member); + if (accessors.firstAccessor !== member) continue; + + const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); + if (accessorsResult) { + result.push(accessorsResult); + } + } // Transform methods result.push( @@ -316,12 +320,12 @@ export function transformClassDeclaration( export const transformSuperExpression: FunctionVisitor = (expression, context) => { const classStack = getOrUpdate(classStacks, context, () => []); const classDeclaration = classStack[classStack.length - 1]; - const typeNode = getExtendedTypeNode(context, classDeclaration); - if (typeNode === undefined) { + const extendedNode = getExtendedNode(context, classDeclaration); + if (extendedNode === undefined) { throw UnknownSuperType(expression); } - const extendsExpression = typeNode.expression; + const extendsExpression = extendedNode.expression; let baseClassName: lua.AssignmentLeftHandSideExpression | undefined; if (ts.isIdentifier(extendsExpression)) { diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 2da5f0f70..50cc8a10f 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -1,12 +1,58 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; -import { TransformationContext } from "../../../context"; +import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { importLuaLibFeature, LuaLibFeature } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; -import { transformIdentifier } from "../../identifier"; +import { transformPropertyName } from "../../literal"; import { getExtendedType, isStaticNode } from "../utils"; -// TODO: Inline to `hasMemberInClassOrAncestor`? +function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { + const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); + const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; + return lua.createFunctionExpression( + lua.createBlock(body), + params, + dot, + restParam, + lua.FunctionExpressionFlags.Declaration + ); +} + +export function transformAccessorDeclarations( + context: TransformationContext, + { firstAccessor, getAccessor, setAccessor }: AllAccessorDeclarations, + className: lua.Identifier +): lua.Statement | undefined { + const propertyName = transformPropertyName(context, firstAccessor.name); + const descriptor = lua.createTableExpression([]); + + if (getAccessor) { + const getterFunction = transformAccessor(context, getAccessor); + descriptor.fields.push(lua.createTableFieldExpression(getterFunction, lua.createStringLiteral("get"))); + } + + if (setAccessor) { + const setterFunction = transformAccessor(context, setAccessor); + descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); + } + + importLuaLibFeature(context, LuaLibFeature.Descriptors); + const call = isStaticNode(firstAccessor) + ? lua.createCallExpression(lua.createIdentifier(`__TS__ObjectDefineProperty`), [ + lua.cloneIdentifier(className), + propertyName, + descriptor, + ]) + : lua.createCallExpression(lua.createIdentifier(`__TS__SetDescriptor`), [ + lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), + propertyName, + descriptor, + ]); + + return lua.createExpressionStatement(call); +} + function* classWithAncestors( context: TransformationContext, classDeclaration: ts.ClassLikeDeclarationBase @@ -71,34 +117,3 @@ export function isGetAccessorOverride( m => ts.isPropertyDeclaration(m) && m.initializer !== undefined && isSamePropertyName(m.name, element.name) ); } - -export function transformAccessorDeclaration( - context: TransformationContext, - node: ts.AccessorDeclaration, - className: lua.Identifier -): lua.Statement | undefined { - if (node.body === undefined) { - return undefined; - } - - const name = transformIdentifier(context, node.name as ts.Identifier); - - const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); - const [body] = transformFunctionBody(context, node.parameters, node.body, restParam); - const accessorFunction = lua.createFunctionExpression( - lua.createBlock(body), - params, - dot, - restParam, - lua.FunctionExpressionFlags.Declaration - ); - - const methodTable = isStaticNode(node) - ? lua.cloneIdentifier(className) - : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); - - const classAccessorsName = ts.isGetAccessorDeclaration(node) ? "____getters" : "____setters"; - const classAccessors = lua.createTableIndexExpression(methodTable, lua.createStringLiteral(classAccessorsName)); - const accessorPath = lua.createTableIndexExpression(classAccessors, lua.createStringLiteral(name.text)); - return lua.createAssignmentStatement(accessorPath, accessorFunction, node); -} diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 87b91e235..9117c1519 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -27,6 +27,8 @@ export function transformClassInstanceFields( statements.push(assignClassField); } + // TODO: Remove when `useDefineForClassFields` would be `true` by default + const getOverrides = classDeclaration.members.filter((m): m is ts.GetAccessorDeclaration => isGetAccessorOverride(context, m, classDeclaration) ); diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts index 2a4a1c8d0..3aec046a3 100644 --- a/src/transformation/visitors/class/setup.ts +++ b/src/transformation/visitors/class/setup.ts @@ -9,9 +9,8 @@ import { hasDefaultExportModifier, } from "../../utils/export"; import { createExportsIdentifier, createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; -import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { hasMemberInClassOrAncestor } from "./members/accessors"; -import { getExtendedTypeNode, isStaticNode } from "./utils"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { getExtendedNode, getExtendsClause } from "./utils"; export function createClassSetup( context: TransformationContext, @@ -62,209 +61,23 @@ export function createClassSetup( ) ); - // localClassName.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && isStaticNode(m))) { - const classGetters = lua.createTableIndexExpression( - lua.cloneIdentifier(localClassName), - lua.createStringLiteral("____getters") - ); - const assignClassGetters = lua.createAssignmentStatement(classGetters, lua.createTableExpression(), statement); - result.push(assignClassGetters); - - importLuaLibFeature(context, LuaLibFeature.ClassIndex); - } - - // localClassName.____setters = {} - if (statement.members.some(m => ts.isSetAccessor(m) && isStaticNode(m))) { - const classSetters = lua.createTableIndexExpression( - lua.cloneIdentifier(localClassName), - lua.createStringLiteral("____setters") - ); - const assignClassSetters = lua.createAssignmentStatement(classSetters, lua.createTableExpression(), statement); - result.push(assignClassSetters); - - importLuaLibFeature(context, LuaLibFeature.ClassNewIndex); - } - - // localClassName.prototype - const createClassPrototype = () => - lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("prototype")); - - // localClassName.prototype.____getters = {} - if (statement.members.some(m => ts.isGetAccessor(m) && !isStaticNode(m))) { - const classPrototypeGetters = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("____getters") - ); - const assignClassPrototypeGetters = lua.createAssignmentStatement( - classPrototypeGetters, - lua.createTableExpression(), - statement - ); - result.push(assignClassPrototypeGetters); - } - - if (hasMemberInClassOrAncestor(context, statement, m => ts.isGetAccessor(m) && !isStaticNode(m))) { - // localClassName.prototype.__index = __TS__Index(localClassName.prototype) - const classPrototypeIndex = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("__index") - ); - const assignClassPrototypeIndex = lua.createAssignmentStatement( - classPrototypeIndex, - transformLuaLibFunction(context, LuaLibFeature.Index, undefined, createClassPrototype()), - statement - ); - result.push(assignClassPrototypeIndex); - } - - if (statement.members.some(m => ts.isSetAccessor(m) && !isStaticNode(m))) { - // localClassName.prototype.____setters = {} - const classPrototypeSetters = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("____setters") - ); - const assignClassPrototypeSetters = lua.createAssignmentStatement( - classPrototypeSetters, - lua.createTableExpression(), - statement - ); - result.push(assignClassPrototypeSetters); - } - - if (hasMemberInClassOrAncestor(context, statement, m => ts.isSetAccessor(m) && !isStaticNode(m))) { - // localClassName.prototype.__newindex = __TS__NewIndex(localClassName.prototype) - const classPrototypeNewIndex = lua.createTableIndexExpression( - createClassPrototype(), - lua.createStringLiteral("__newindex") - ); - const assignClassPrototypeIndex = lua.createAssignmentStatement( - classPrototypeNewIndex, - transformLuaLibFunction(context, LuaLibFeature.NewIndex, undefined, createClassPrototype()), - statement - ); - result.push(assignClassPrototypeIndex); - } - - const hasStaticGetters = hasMemberInClassOrAncestor( - context, - statement, - m => ts.isGetAccessor(m) && isStaticNode(m) - ); - const hasStaticSetters = hasMemberInClassOrAncestor( - context, - statement, - m => ts.isSetAccessor(m) && isStaticNode(m) - ); - if (extendsType) { - const extendedTypeNode = getExtendedTypeNode(context, statement); - if (extendedTypeNode === undefined) { + const extendedNode = getExtendedNode(context, statement); + if (extendedNode === undefined) { throw UndefinedTypeNode(statement); } - // localClassName.____super = extendsExpression - const createClassBase = () => - lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("____super")); - const assignClassBase = lua.createAssignmentStatement( - createClassBase(), - context.transformExpression(extendedTypeNode.expression), - extendedTypeNode.expression - ); - result.push(assignClassBase); - - if (hasStaticGetters || hasStaticSetters) { - const metatableFields: lua.TableFieldExpression[] = []; - if (hasStaticGetters) { - // __index = __TS__ClassIndex - metatableFields.push( - lua.createTableFieldExpression( - lua.createIdentifier("__TS__ClassIndex"), - lua.createStringLiteral("__index"), - extendedTypeNode.expression - ) - ); - } else { - // __index = localClassName.____super - metatableFields.push( - lua.createTableFieldExpression( - createClassBase(), - lua.createStringLiteral("__index"), - extendedTypeNode.expression - ) - ); - } - - if (hasStaticSetters) { - // __newindex = __TS__ClassNewIndex - metatableFields.push( - lua.createTableFieldExpression( - lua.createIdentifier("__TS__ClassNewIndex"), - lua.createStringLiteral("__newindex"), - extendedTypeNode.expression - ) - ); - } - - const setClassMetatable = lua.createExpressionStatement( - lua.createCallExpression( - lua.createIdentifier("setmetatable"), - [lua.cloneIdentifier(localClassName), lua.createTableExpression(metatableFields)], - extendedTypeNode.expression + result.push( + lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.ClassExtends, + getExtendsClause(statement), + lua.cloneIdentifier(localClassName), + context.transformExpression(extendedNode.expression) ) - ); - result.push(setClassMetatable); - } else { - // setmetatable(localClassName, localClassName.____super) - const setClassMetatable = lua.createExpressionStatement( - lua.createCallExpression( - lua.createIdentifier("setmetatable"), - [lua.cloneIdentifier(localClassName), createClassBase()], - extendedTypeNode.expression - ) - ); - result.push(setClassMetatable); - } - - // setmetatable(localClassName.prototype, localClassName.____super.prototype) - const basePrototype = lua.createTableIndexExpression(createClassBase(), lua.createStringLiteral("prototype")); - const setClassPrototypeMetatable = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("setmetatable"), [createClassPrototype(), basePrototype]), - extendedTypeNode.expression - ); - result.push(setClassPrototypeMetatable); - } else if (hasStaticGetters || hasStaticSetters) { - const metatableFields: lua.TableFieldExpression[] = []; - if (hasStaticGetters) { - // __index = __TS__ClassIndex - metatableFields.push( - lua.createTableFieldExpression( - lua.createIdentifier("__TS__ClassIndex"), - lua.createStringLiteral("__index"), - statement - ) - ); - } - - if (hasStaticSetters) { - // __newindex = __TS__ClassNewIndex - metatableFields.push( - lua.createTableFieldExpression( - lua.createIdentifier("__TS__ClassNewIndex"), - lua.createStringLiteral("__newindex"), - statement - ) - ); - } - - const setClassMetatable = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("setmetatable"), [ - lua.cloneIdentifier(localClassName), - lua.createTableExpression(metatableFields), - ]), - statement + ) ); - result.push(setClassMetatable); } return result; diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index a1639e24b..9ba263818 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -6,20 +6,21 @@ export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); } -export function getExtendedTypeNode( +export function getExtendsClause(node: ts.ClassLikeDeclarationBase): ts.HeritageClause | undefined { + return (node.heritageClauses ?? []).find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); +} + +export function getExtendedNode( context: TransformationContext, node: ts.ClassLikeDeclarationBase ): ts.ExpressionWithTypeArguments | undefined { - if (node && node.heritageClauses) { - for (const clause of node.heritageClauses) { - if (clause.token === ts.SyntaxKind.ExtendsKeyword) { - const superType = context.checker.getTypeAtLocation(clause.types[0]); - const annotations = getTypeAnnotations(superType); - if (!annotations.has(AnnotationKind.PureAbstract)) { - return clause.types[0]; - } - } - } + const extendsClause = getExtendsClause(node); + if (!extendsClause) return; + + const superType = context.checker.getTypeAtLocation(extendsClause.types[0]); + const annotations = getTypeAnnotations(superType); + if (!annotations.has(AnnotationKind.PureAbstract)) { + return extendsClause.types[0]; } } @@ -27,6 +28,6 @@ export function getExtendedType( context: TransformationContext, node: ts.ClassLikeDeclarationBase ): ts.Type | undefined { - const extendedTypeNode = getExtendedTypeNode(context, node); - return extendedTypeNode && context.checker.getTypeAtLocation(extendedTypeNode); + const extendedNode = getExtendedNode(context, node); + return extendedNode && context.checker.getTypeAtLocation(extendedNode); } diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 5f647a013..875c196fc 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -453,21 +453,6 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { expect(util.transpileAndExecute(code)).toBe(true); }); - test("variable (rawset)", () => { - const code = ` - const rawset = "foobar"; - class A { - prop = "prop"; - } - class B extends A { - get prop() { return rawset; } - } - const b = new B(); - return b.prop;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); - }); - test("variable (require)", () => { const code = ` const require = "foobar"; diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 918d430d1..c12a89b69 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -86,9 +86,8 @@ test.each([ assertPatterns: [ { luaPattern: "Bar = __TS__Class()", typeScriptPattern: "class Bar" }, { luaPattern: "Bar.name =", typeScriptPattern: "class Bar" }, - { luaPattern: "Bar.____super = Foo", typeScriptPattern: "Foo {" }, - { luaPattern: "setmetatable(Bar,", typeScriptPattern: "Foo {" }, - { luaPattern: "setmetatable(Bar.prototype,", typeScriptPattern: "Foo {" }, + { luaPattern: "__TS__ClassExtends", typeScriptPattern: "extends" }, + { luaPattern: "Foo", typeScriptPattern: "Foo" }, { luaPattern: "function Bar.prototype.____constructor", typeScriptPattern: "constructor" }, ], }, From 9442bf690a2c6989a1ca5c47b8e367dfc328f14a Mon Sep 17 00:00:00 2001 From: Chris Bajorin Date: Fri, 13 Mar 2020 17:55:27 -0400 Subject: [PATCH 237/764] handle non-indexable types for lefthand value of instanceof (#837) * handle non-indexable types for lefthand value of instanceof * cleanup Co-authored-by: Chris Bajorin --- src/lualib/InstanceOf.ts | 2 +- test/unit/classes/instanceof.spec.ts | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index b856ddaa9..b75c040c2 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -8,7 +8,7 @@ function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: LuaClass) return !!classTbl[Symbol.hasInstance](obj); } - if (obj !== undefined) { + if (typeof obj === "object") { let luaClass = obj.constructor; while (luaClass !== undefined) { if (luaClass === classTbl) { diff --git a/test/unit/classes/instanceof.spec.ts b/test/unit/classes/instanceof.spec.ts index fdbb6e36e..4e4000153 100644 --- a/test/unit/classes/instanceof.spec.ts +++ b/test/unit/classes/instanceof.spec.ts @@ -49,6 +49,28 @@ test("null instanceof Class", () => { `.expectToMatchJsResult(); }); +test("function instanceof Class", () => { + util.testFunction` + class myClass {} + const noop = () => {}; + return (noop as any) instanceof myClass; + `.expectToMatchJsResult(); +}); + +test("boolean instanceof Class", () => { + util.testFunction` + class myClass {} + return (false as any) instanceof myClass; + `.expectToMatchJsResult(); +}); + +test("number instanceof Class", () => { + util.testFunction` + class myClass {} + return (5 as any) instanceof myClass; + `.expectToMatchJsResult(); +}); + test("instanceof export", () => { util.testModule` export class myClass {} From 71a2aefe102f17f06685d405b310a17d4c9a6877 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 14 Mar 2020 17:28:13 +0100 Subject: [PATCH 238/764] Bump acorn from 6.4.0 to 6.4.1 (#838) Bumps [acorn](https://github.com/acornjs/acorn) from 6.4.0 to 6.4.1. - [Release notes](https://github.com/acornjs/acorn/releases) - [Commits](https://github.com/acornjs/acorn/compare/6.4.0...6.4.1) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index ded7a98f9..f273f0895 100644 --- a/package-lock.json +++ b/package-lock.json @@ -666,9 +666,9 @@ "dev": true }, "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true }, "acorn-globals": { @@ -682,9 +682,9 @@ }, "dependencies": { "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } From 9f61a8239c0aee3c36b733322cba1e66b65a96a7 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 15 Mar 2020 18:03:51 +0500 Subject: [PATCH 239/764] Return diagnostics instead of throwing errors (#769) * Add diagnostic reporting and convert forbidden for...in array error * Include generated code in diagnostic snapshots * Remove some errors that already have TypeScript diagnostics * Replace unactionable errors with assertions * Replace empty json file diagnostic with runtime error * Refactor `@forRange` annotation tests * Move invalid `@forRange` call error to diagnostics * Make annotation errors diagnostics * Make unsupported `luaIterator` usage error a diagnostic * Make function assignment errors diagnostics * Replace UnsupportedKind errors with diagnostics or better types * Make `UnsupportedForTarget` error a diagnostic * Make `UnsupportedProperty` error a diagnostic * Make loop errors diagnostics * Simplift `isValidLuaIdentifier` usage * Make `InvalidAmbientIdentifierName` error a diagnostic * Remove `UndefinedScope` * Make class transform safer, fixes #771 * Make all other errors diagnostics * Make `bundle` tests check diagnostic snapshots * Remove remaining TranspileError handling code * Fix formatting * Update `loops.spec.ts.snap` * Temporary loosen `for...of` initializer variable declaration check * Refactor SimpleOperator handling * Fix typo * Remove unused missing import * Remove `test.only` from `conditionals.spec.ts` * Use inline snapshots for simple tests * Revert "Use inline snapshots for simple tests" This reverts commit 9312a0c9eea2e38cf3931d3c873d244c678380c4. * Factorize transpilation diagnostics * Improve some diagnostic code spans * Allow to specify expected diagnostic codes in matchers * Add expected diagnostics to snapshot assertions * Add expected diagnostics to function assignability cast tests * Add expected diagnostics to bundle tests * Add changelog entry * Refactor for initializer variable transformation * Update tests * Refactor diagnostc factories * Fix `luaTable` interface declaration tests * Make condition more readable --- CHANGELOG.md | 29 + src/CompilerOptions.ts | 30 +- src/LuaPrinter.ts | 14 +- src/cli/diagnostics.ts | 22 +- src/cli/report.ts | 11 +- src/index.ts | 1 - src/transformation/builtins/array.ts | 6 +- src/transformation/builtins/console.ts | 6 +- src/transformation/builtins/function.ts | 8 +- src/transformation/builtins/index.ts | 26 +- src/transformation/builtins/math.ts | 16 +- src/transformation/builtins/number.ts | 10 +- src/transformation/builtins/object.ts | 6 +- src/transformation/builtins/string.ts | 14 +- src/transformation/builtins/symbol.ts | 7 +- src/transformation/context/context.ts | 3 +- src/transformation/index.ts | 35 +- .../utils/assignment-validation.ts | 31 +- src/transformation/utils/diagnostics.ts | 126 ++ src/transformation/utils/errors.ts | 143 -- src/transformation/utils/lua-ast.ts | 2 +- src/transformation/utils/safe-names.ts | 57 +- src/transformation/utils/scope.ts | 20 +- src/transformation/visitors/access.ts | 4 +- .../visitors/binary-expression/assignments.ts | 13 +- .../visitors/binary-expression/bit.ts | 81 +- .../visitors/binary-expression/compound.ts | 58 +- .../destructuring-assignments.ts | 17 +- .../visitors/binary-expression/index.ts | 234 +-- src/transformation/visitors/break-continue.ts | 18 +- src/transformation/visitors/call.ts | 12 +- .../visitors/class/decorators.ts | 4 +- src/transformation/visitors/class/index.ts | 113 +- src/transformation/visitors/class/new.ts | 27 +- src/transformation/visitors/class/setup.ts | 7 +- src/transformation/visitors/function.ts | 14 +- src/transformation/visitors/identifier.ts | 7 +- src/transformation/visitors/literal.ts | 35 +- src/transformation/visitors/loops/for-in.ts | 39 +- src/transformation/visitors/loops/for-of.ts | 237 +-- src/transformation/visitors/loops/for.ts | 2 +- src/transformation/visitors/loops/utils.ts | 43 +- src/transformation/visitors/lua-table.ts | 163 +- src/transformation/visitors/modules/export.ts | 6 +- src/transformation/visitors/modules/import.ts | 20 +- src/transformation/visitors/sourceFile.ts | 15 +- src/transformation/visitors/switch.ts | 4 +- src/transformation/visitors/typeof.ts | 58 +- .../visitors/unary-expression.ts | 6 +- .../visitors/variable-declaration.ts | 26 +- src/transpilation/bundle.ts | 4 +- src/transpilation/diagnostics.ts | 85 +- src/utils.ts | 33 + test/setup.ts | 57 +- .../__snapshots__/assignments.spec.ts.snap | 47 + test/unit/__snapshots__/bundle.spec.ts.snap | 7 + .../__snapshots__/conditionals.spec.ts.snap | 12 + .../__snapshots__/expressions.spec.ts.snap | 141 ++ .../__snapshots__/identifiers.spec.ts.snap | 241 +++ test/unit/__snapshots__/loops.spec.ts.snap | 72 + .../customConstructor.spec.ts.snap | 16 + .../__snapshots__/extension.spec.ts.snap | 50 + .../__snapshots__/forRange.spec.ts.snap | 92 + .../__snapshots__/luaIterator.spec.ts.snap | 15 + .../__snapshots__/luaTable.spec.ts.snap | 197 ++ .../__snapshots__/metaExtension.spec.ts.snap | 17 + .../annotations/customConstructor.spec.ts | 20 +- test/unit/annotations/extension.spec.ts | 20 +- test/unit/annotations/forRange.spec.ts | 173 +- test/unit/annotations/luaIterator.spec.ts | 91 +- test/unit/annotations/luaTable.spec.ts | 92 +- test/unit/annotations/metaExtension.spec.ts | 33 +- test/unit/assignments.spec.ts | 9 +- .../__snapshots__/loading.spec.ts.snap | 9 + test/unit/builtins/loading.spec.ts | 4 +- test/unit/builtins/set.spec.ts | 4 +- test/unit/bundle.spec.ts | 64 +- .../__snapshots__/classes.spec.ts.snap | 19 + .../__snapshots__/decorators.spec.ts.snap | 18 + test/unit/classes/classes.spec.ts | 26 + test/unit/classes/decorators.spec.ts | 8 +- test/unit/conditionals.spec.ts | 4 +- test/unit/expressions.spec.ts | 13 +- .../__snapshots__/functions.spec.ts.snap | 8 + test/unit/functions/functions.spec.ts | 6 + .../invalidFunctionAssignments.spec.ts.snap | 1723 +++++++++++++++++ .../validation/functionPermutations.ts | 12 +- .../invalidFunctionAssignments.spec.ts | 171 +- .../validFunctionAssignments.spec.ts | 35 +- test/unit/identifiers.spec.ts | 13 +- test/unit/json.spec.ts | 14 +- test/unit/loops.spec.ts | 53 +- .../__snapshots__/resolution.spec.ts.snap | 10 + test/unit/modules/resolution.spec.ts | 3 +- test/util.ts | 55 +- 95 files changed, 4028 insertions(+), 1654 deletions(-) create mode 100644 src/transformation/utils/diagnostics.ts delete mode 100644 src/transformation/utils/errors.ts create mode 100644 test/unit/__snapshots__/assignments.spec.ts.snap create mode 100644 test/unit/__snapshots__/bundle.spec.ts.snap create mode 100644 test/unit/__snapshots__/identifiers.spec.ts.snap create mode 100644 test/unit/__snapshots__/loops.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/extension.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/forRange.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/luaTable.spec.ts.snap create mode 100644 test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap create mode 100644 test/unit/builtins/__snapshots__/loading.spec.ts.snap create mode 100644 test/unit/classes/__snapshots__/classes.spec.ts.snap create mode 100644 test/unit/classes/__snapshots__/decorators.spec.ts.snap create mode 100644 test/unit/functions/__snapshots__/functions.spec.ts.snap create mode 100644 test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap create mode 100644 test/unit/modules/__snapshots__/resolution.spec.ts.snap diff --git a/CHANGELOG.md b/CHANGELOG.md index 6936a691c..ef3c2229d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,35 @@ This change simplifies our codebase and opens a path to object accessors implementation +- Errors reported during transpilation now are created as TypeScript diagnostics, instead of being thrown as JavaScript errors. This makes TypeScriptToLua always try to generate valid code (even in presence of errors) and allows multiple errors to be reported in a single file: + + + ```ts + for (var x in []) {} + ``` + + ```shell + # Before + + $ tstl file.ts + file.ts:1:1 - error TSTL: Iterating over arrays with 'for ... in' is not allowed. + + $ cat file.lua + error("Iterating over arrays with 'for ... in' is not allowed.") + ``` + + ```shell + # Now + + $ tstl file.ts + file.ts:1:1 - error TSTL: Iterating over arrays with 'for ... in' is not allowed. + file.ts:1:6 - error TSTL: `var` declarations are not supported. Use `let` or `const` instead. + + $ cat file.lua + for x in pairs({}) do + end + ``` + ## 0.31.0 - **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 788f15d76..48c8abe82 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import * as diagnosticFactories from "./transpilation/diagnostics"; type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { [_ in keyof T]: infer U; @@ -47,37 +48,12 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { const diagnostics: ts.Diagnostic[] = []; if (options.luaBundle && !options.luaBundleEntry) { - diagnostics.push(configErrorDiagnostic(`'luaBundleEntry' is required when 'luaBundle' is enabled.`)); + diagnostics.push(diagnosticFactories.luaBundleEntryIsRequired()); } if (options.luaBundle && options.luaLibImport === LuaLibImportKind.Inline) { - diagnostics.push( - configWarningDiagnostic( - `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + - `It is recommended to use 'luaLibImport: "require"'` - ) - ); + diagnostics.push(diagnosticFactories.usingLuaBundleWithInlineMightGenerateDuplicateCode()); } return diagnostics; } - -const configErrorDiagnostic = (message: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: message, -}); - -const configWarningDiagnostic = (message: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Warning, - code: 0, - source: "typescript-to-lua", - messageText: message, -}); diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index d37179765..816bb1aea 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -4,7 +4,7 @@ import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; -import { isValidLuaIdentifier, luaKeywords } from "./transformation/utils/safe-names"; +import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; import { trimExtension } from "./utils"; @@ -660,11 +660,7 @@ export class LuaPrinter { const value = this.printExpression(expression.value); if (expression.key) { - if ( - lua.isStringLiteral(expression.key) && - isValidLuaIdentifier(expression.key.value) && - !luaKeywords.has(expression.key.value) - ) { + if (lua.isStringLiteral(expression.key) && isValidLuaIdentifier(expression.key.value)) { chunks.push(expression.key.value, " = ", value); } else { chunks.push("[", this.printExpression(expression.key), "] = ", value); @@ -761,11 +757,7 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printExpressionInParenthesesIfNeeded(expression.table)); - if ( - lua.isStringLiteral(expression.index) && - isValidLuaIdentifier(expression.index.value) && - !luaKeywords.has(expression.index.value) - ) { + if (lua.isStringLiteral(expression.index) && isValidLuaIdentifier(expression.index.value)) { chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); } else { chunks.push("[", this.printExpression(expression.index), "]"); diff --git a/src/cli/diagnostics.ts b/src/cli/diagnostics.ts index 9e950710f..e386fa391 100644 --- a/src/cli/diagnostics.ts +++ b/src/cli/diagnostics.ts @@ -1,16 +1,12 @@ import * as ts from "typescript"; +import { createSerialDiagnosticFactory, createDiagnosticFactoryWithCode } from "../utils"; -export const tstlOptionsAreMovingToTheTstlObject = (tstl: Record): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, +export const tstlOptionsAreMovingToTheTstlObject = createSerialDiagnosticFactory((tstl: Record) => ({ category: ts.DiagnosticCategory.Warning, - code: 0, - source: "typescript-to-lua", messageText: 'TSTL options are moving to the "tstl" object. Adjust your tsconfig to look like\n' + `"tstl": ${JSON.stringify(tstl, undefined, 4)}`, -}); +})); export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ file: undefined, @@ -24,16 +20,8 @@ export const watchErrorSummary = (errorCount: number): ts.Diagnostic => ({ : `Found ${errorCount} errors. Watching for file changes.`, }); -const createCommandLineError = (code: number, getMessage: (...args: Args) => string) => ( - ...args: Args -): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code, - messageText: getMessage(...args), -}); +const createCommandLineError = (code: number, getMessage: (...args: TArgs) => string) => + createDiagnosticFactoryWithCode(code, (...args: TArgs) => ({ messageText: getMessage(...args) })); export const unknownCompilerOption = createCommandLineError( 5023, diff --git a/src/cli/report.ts b/src/cli/report.ts index 039ca069c..19fd02d1e 100644 --- a/src/cli/report.ts +++ b/src/cli/report.ts @@ -1,12 +1,9 @@ import * as ts from "typescript"; +export const prepareDiagnosticForFormatting = (diagnostic: ts.Diagnostic) => + diagnostic.source === "typescript-to-lua" ? { ...diagnostic, code: "TL" as any } : diagnostic; + export function createDiagnosticReporter(pretty: boolean, system = ts.sys): ts.DiagnosticReporter { const reporter = ts.createDiagnosticReporter(system, pretty); - return diagnostic => { - if (diagnostic.source === "typescript-to-lua") { - diagnostic = { ...diagnostic, code: ("TL" + diagnostic.code) as any }; - } - - reporter(diagnostic); - }; + return diagnostic => reporter(prepareDiagnosticForFormatting(diagnostic)); } diff --git a/src/index.ts b/src/index.ts index 8b0159a9c..c828369df 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,5 +6,4 @@ export * from "./LuaAST"; export { LuaLibFeature } from "./LuaLib"; export * from "./LuaPrinter"; export * from "./transformation/context"; -export { TranspileError } from "./transformation/utils/errors"; export * from "./transpilation"; diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index af4f674bd..41859e57c 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -1,14 +1,14 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.CallExpression { +): lua.CallExpression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); @@ -79,7 +79,7 @@ export function transformArrayPrototypeCall( case "flatMap": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); default: - throw UnsupportedProperty("array", expressionName, node); + context.diagnostics.push(unsupportedProperty(expression.name, "array", expressionName)); } } diff --git a/src/transformation/builtins/console.ts b/src/transformation/builtins/console.ts index 988aba1b3..af7ceb87e 100644 --- a/src/transformation/builtins/console.ts +++ b/src/transformation/builtins/console.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; const isStringFormatTemplate = (node: ts.Expression) => ts.isStringLiteral(node) && node.text.includes("%"); @@ -9,7 +9,7 @@ const isStringFormatTemplate = (node: ts.Expression) => ts.isStringLiteral(node) export function transformConsoleCall( context: TransformationContext, expression: PropertyCallExpression -): lua.Expression { +): lua.Expression | undefined { const method = expression.expression; const methodName = method.name.text; const signature = context.checker.getResolvedSignature(expression); @@ -61,6 +61,6 @@ export function transformConsoleCall( ); return lua.createCallExpression(lua.createIdentifier("print"), [debugTracebackCall]); default: - throw UnsupportedProperty("console", methodName, expression); + context.diagnostics.push(unsupportedProperty(method.name, "console", methodName)); } } diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index 2eefae340..3ba8c2aaa 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -1,6 +1,6 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty, UnsupportedSelfFunctionConversion } from "../utils/errors"; +import { unsupportedProperty, unsupportedSelfFunctionConversion } from "../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; @@ -8,11 +8,11 @@ import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformFunctionPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.CallExpression { +): lua.CallExpression | undefined { const expression = node.expression; const callerType = context.checker.getTypeAtLocation(expression.expression); if (getFunctionContextType(context, callerType) === ContextType.Void) { - throw UnsupportedSelfFunctionConversion(node); + context.diagnostics.push(unsupportedSelfFunctionConversion(node)); } const signature = context.checker.getResolvedSignature(node); @@ -27,6 +27,6 @@ export function transformFunctionPrototypeCall( case "call": return transformLuaLibFunction(context, LuaLibFeature.FunctionCall, node, caller, ...params); default: - throw UnsupportedProperty("function", expressionName, node); + context.diagnostics.push(unsupportedProperty(expression.name, "function", expressionName)); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 0958d0145..8a23ed824 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -28,24 +28,22 @@ export function transformBuiltinPropertyAccessExpression( context: TransformationContext, node: ts.PropertyAccessExpression ): lua.Expression | undefined { - const type = context.checker.getTypeAtLocation(node.expression); - if (isStringType(context, type)) { + const ownerType = context.checker.getTypeAtLocation(node.expression); + + if (isStringType(context, ownerType)) { return transformStringProperty(context, node); - } else if (isArrayType(context, type)) { - const arrayPropertyAccess = transformArrayProperty(context, node); - if (arrayPropertyAccess) { - return arrayPropertyAccess; - } } - if (ts.isIdentifier(node.expression)) { - const ownerType = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, ownerType)) { + return transformArrayProperty(context, node); + } - if (isStandardLibraryType(context, ownerType, "Math")) { - return transformMathProperty(node); - } else if (isStandardLibraryType(context, ownerType, "Symbol")) { - // Pull in Symbol lib - importLuaLibFeature(context, LuaLibFeature.Symbol); + if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { + switch (node.expression.text) { + case "Math": + return transformMathProperty(context, node); + case "Symbol": + importLuaLibFeature(context, LuaLibFeature.Symbol); } } } diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 9f5b4a1a3..6ceae16bd 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -2,10 +2,13 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { LuaTarget } from "../../CompilerOptions"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; -export function transformMathProperty(node: ts.PropertyAccessExpression): lua.Expression { +export function transformMathProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { const name = node.name.text; switch (name) { case "PI": @@ -23,11 +26,14 @@ export function transformMathProperty(node: ts.PropertyAccessExpression): lua.Ex return lua.createNumericLiteral(Math[name], node); default: - throw UnsupportedProperty("Math", name, node); + context.diagnostics.push(unsupportedProperty(node.name, "Math", name)); } } -export function transformMathCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { +export function transformMathCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); @@ -93,6 +99,6 @@ export function transformMathCall(context: TransformationContext, node: Property } default: - throw UnsupportedProperty("Math", expressionName, expression); + context.diagnostics.push(unsupportedProperty(expression.name, "Math", expressionName)); } } diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index 9200be74a..227d82b23 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -1,13 +1,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformNumberPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.Expression { +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); @@ -20,14 +20,14 @@ export function transformNumberPrototypeCall( ? lua.createCallExpression(lua.createIdentifier("tostring"), [caller], node) : transformLuaLibFunction(context, LuaLibFeature.NumberToString, node, caller, ...params); default: - throw UnsupportedProperty("number", expressionName, node); + context.diagnostics.push(unsupportedProperty(expression.name, "number", expressionName)); } } export function transformNumberConstructorCall( context: TransformationContext, expression: PropertyCallExpression -): lua.CallExpression { +): lua.CallExpression | undefined { const method = expression.expression; const parameters = transformArguments(context, expression.arguments); const methodName = method.name.text; @@ -37,6 +37,6 @@ export function transformNumberConstructorCall( case "isFinite": return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, expression, ...parameters); default: - throw UnsupportedProperty("Number", methodName, expression); + context.diagnostics.push(unsupportedProperty(method.name, "Number", methodName)); } } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index acd468bd4..358bebbf5 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -1,13 +1,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformObjectConstructorCall( context: TransformationContext, expression: PropertyCallExpression -): lua.Expression { +): lua.Expression | undefined { const method = expression.expression; const parameters = transformArguments(context, expression.arguments); const methodName = method.name.text; @@ -24,7 +24,7 @@ export function transformObjectConstructorCall( case "values": return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...parameters); default: - throw UnsupportedProperty("Object", methodName, expression); + context.diagnostics.push(unsupportedProperty(method.name, "Object", methodName)); } } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index ea755b707..ac2005929 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { createExpressionPlusOne } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; @@ -18,7 +18,7 @@ function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lu export function transformStringPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.Expression { +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); @@ -110,14 +110,14 @@ export function transformStringPrototypeCall( case "padEnd": return transformLuaLibFunction(context, LuaLibFeature.StringPadEnd, node, caller, ...params); default: - throw UnsupportedProperty("string", expressionName, node); + context.diagnostics.push(unsupportedProperty(expression.name, "string", expressionName)); } } export function transformStringConstructorCall( context: TransformationContext, node: PropertyCallExpression -): lua.Expression { +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); @@ -132,19 +132,19 @@ export function transformStringConstructorCall( ); default: - throw UnsupportedProperty("String", expressionName, node); + context.diagnostics.push(unsupportedProperty(expression.name, "String", expressionName)); } } export function transformStringProperty( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.UnaryExpression { +): lua.UnaryExpression | undefined { switch (node.name.text) { case "length": const expression = context.transformExpression(node.expression); return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); default: - throw UnsupportedProperty("string", node.name.text, node); + context.diagnostics.push(unsupportedProperty(node.name, "string", node.name.text)); } } diff --git a/src/transformation/builtins/symbol.ts b/src/transformation/builtins/symbol.ts index 4a6e5e43f..04329e059 100644 --- a/src/transformation/builtins/symbol.ts +++ b/src/transformation/builtins/symbol.ts @@ -1,14 +1,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { UnsupportedProperty } from "../utils/errors"; +import { unsupportedProperty } from "../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; -// Transpile a Symbol._ property export function transformSymbolConstructorCall( context: TransformationContext, expression: PropertyCallExpression -): lua.CallExpression { +): lua.CallExpression | undefined { const method = expression.expression; const signature = context.checker.getResolvedSignature(expression); const parameters = transformArguments(context, expression.arguments, signature); @@ -21,6 +20,6 @@ export function transformSymbolConstructorCall( const functionIdentifier = lua.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); return lua.createCallExpression(functionIdentifier, parameters, expression); default: - throw UnsupportedProperty("Symbol", methodName, expression); + context.diagnostics.push(unsupportedProperty(method.name, "Symbol", methodName)); } } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 0b34da260..ebc8dfea1 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -24,6 +24,7 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { } export class TransformationContext { + public readonly diagnostics: ts.Diagnostic[] = []; public readonly checker: DiagnosticsProducingTypeChecker = (this .program as any).getDiagnosticsProducingTypeChecker(); public readonly resolver: EmitResolver; @@ -52,7 +53,7 @@ export class TransformationContext { const nodeVisitors = this.visitorMap.get(node.kind); if (!nodeVisitors || nodeVisitors.length === 0) { - throw new Error(`${ts.SyntaxKind[node.kind]} is not supported`); + throw new Error(`Unsupported node kind: ${ts.SyntaxKind[node.kind]}.`); } const previousNodeVisitors = this.currentNodeVisitors; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index a720a8ffd..69b098811 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -3,20 +3,9 @@ import * as lua from "../LuaAST"; import { LuaLibFeature } from "../LuaLib"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; -import { TranspileError } from "./utils/errors"; import { getUsedLuaLibFeatures } from "./utils/lualib"; import { standardVisitors } from "./visitors"; -const transpileErrorDiagnostic = (error: TranspileError): ts.Diagnostic => ({ - file: error.node.getSourceFile(), - start: error.node.getStart(), - length: error.node.getWidth(), - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: error.message, -}); - export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { const visitorMap: VisitorMap = new Map(); for (const visitors of [standardVisitors, ...customVisitors]) { @@ -52,23 +41,11 @@ export function transformSourceFile( visitorMap: VisitorMap ): TransformSourceFileResult { const context = new TransformationContext(program, sourceFile, visitorMap); + const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; - try { - const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; - const luaLibFeatures = getUsedLuaLibFeatures(context); - - return { luaAst, luaLibFeatures, diagnostics: [] }; - } catch (error) { - if (!(error instanceof TranspileError)) throw error; - - return { - luaAst: lua.createBlock([ - lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("error"), [lua.createStringLiteral(error.message)]) - ), - ]), - luaLibFeatures: new Set(), - diagnostics: [transpileErrorDiagnostic(error)], - }; - } + return { + luaAst, + luaLibFeatures: getUsedLuaLibFeatures(context), + diagnostics: context.diagnostics, + }; } diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index a9944b260..05cfea467 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -1,30 +1,13 @@ import * as ts from "typescript"; import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "./annotations"; import { - ForbiddenLuaTableUseException, - UnsupportedNoSelfFunctionConversion, - UnsupportedOverloadAssignment, - UnsupportedSelfFunctionConversion, -} from "./errors"; + unsupportedNoSelfFunctionConversion, + unsupportedOverloadAssignment, + unsupportedSelfFunctionConversion, +} from "./diagnostics"; import { ContextType, getFunctionContextType } from "./function-context"; -// TODO: Make validateAssignment check symbols? -// TODO: Move to LuaTable plugin? -export function validatePropertyAssignment( - context: TransformationContext, - node: ts.AssignmentExpression -): void { - if (!ts.isPropertyAccessExpression(node.left)) return; - - const leftType = context.checker.getTypeAtLocation(node.left.expression); - const annotations = getTypeAnnotations(leftType); - if (annotations.has(AnnotationKind.LuaTable) && node.left.name.text === "length") { - throw ForbiddenLuaTableUseException(`A LuaTable object's length cannot be re-assigned.`, node); - } -} - // TODO: Clear if types are reused between compilations const typeValidationCache = new WeakMap>(); @@ -114,12 +97,12 @@ function validateFunctionAssignment( const toContext = getFunctionContextType(context, toType); if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { - throw UnsupportedOverloadAssignment(node, toName); + context.diagnostics.push(unsupportedOverloadAssignment(node, toName)); } else if (fromContext !== toContext && fromContext !== ContextType.None && toContext !== ContextType.None) { if (toContext === ContextType.Void) { - throw UnsupportedNoSelfFunctionConversion(node, toName); + context.diagnostics.push(unsupportedNoSelfFunctionConversion(node, toName)); } else { - throw UnsupportedSelfFunctionConversion(node, toName); + context.diagnostics.push(unsupportedSelfFunctionConversion(node, toName)); } } } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts new file mode 100644 index 000000000..5b7b2de38 --- /dev/null +++ b/src/transformation/utils/diagnostics.ts @@ -0,0 +1,126 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; +import { createSerialDiagnosticFactory } from "../../utils"; +import { AnnotationKind } from "./annotations"; + +const createDiagnosticFactory = (message: string | ((...args: TArgs) => string)) => + createSerialDiagnosticFactory((node: ts.Node, ...args: TArgs) => ({ + file: node.getSourceFile(), + start: node.getStart(), + length: node.getWidth(), + messageText: typeof message === "string" ? message : message(...args), + })); + +export const forbiddenForIn = createDiagnosticFactory(`Iterating over arrays with 'for ... in' is not allowed.`); + +export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { + const nameReference = name ? ` '${name}'` : ""; + return ( + `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: void'.` + ); +}); + +export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: string) => { + const nameReference = name ? ` '${name}'` : ""; + return ( + `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + + `To fix, wrap in an arrow function, or declare with 'this: any'.` + ); +}); + +export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: string) => { + const nameReference = name ? ` to '${name}'` : ""; + return ( + `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + + "Overloads should all have the same type for 'this'." + ); +}); + +export const decoratorInvalidContext = createDiagnosticFactory(`Decorator function cannot have 'this: void'.`); + +export const annotationInvalidArgumentCount = createDiagnosticFactory( + (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` +); + +export const extensionCannotConstruct = createDiagnosticFactory( + "Cannot construct classes with '@extension' or '@metaExtension' annotation." +); + +export const extensionCannotExtend = createDiagnosticFactory( + `Cannot extend classes with '@extension' or '@metaExtension' annotation.` +); + +export const extensionCannotExport = createDiagnosticFactory( + `Cannot export classes with '@extension' or '@metaExtension' annotation.` +); + +export const extensionInvalidInstanceOf = createDiagnosticFactory( + `Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation.` +); + +export const extensionAndMetaExtensionConflict = createDiagnosticFactory( + `Cannot use both '@extension' and '@metaExtension' annotations on the same class.` +); + +export const metaExtensionMissingExtends = createDiagnosticFactory( + `'@metaExtension' annotation requires the extension of the metatable class.` +); + +export const invalidForRangeCall = createDiagnosticFactory((message: string) => `Invalid @forRange call: ${message}.`); + +export const luaTableMustBeAmbient = createDiagnosticFactory( + "Classes with the '@luaTable' annotation must be ambient." +); + +export const luaTableCannotBeExtended = createDiagnosticFactory( + "Cannot extend classes with the '@luaTable' annotation." +); + +export const luaTableInvalidInstanceOf = createDiagnosticFactory( + "The instanceof operator cannot be used with a '@luaTable' class." +); + +export const luaTableCannotBeAccessedDynamically = createDiagnosticFactory("@luaTable cannot be accessed dynamically."); + +export const luaTableForbiddenUsage = createDiagnosticFactory( + (description: string) => `Invalid @luaTable usage: ${description}.` +); + +export const luaIteratorForbiddenUsage = createDiagnosticFactory( + "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + + "You must use a destructuring statement to catch results from a lua iterator with " + + "the '@tupleReturn' annotation." +); + +export const unsupportedAccessorInObjectLiteral = createDiagnosticFactory( + "Accessors in object literal are not supported." +); + +export const unsupportedNullishCoalescing = createDiagnosticFactory("Nullish coalescing is not supported."); + +export const unsupportedRightShiftOperator = createDiagnosticFactory( + "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." +); + +const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); +export const unsupportedForTarget = createDiagnosticFactory( + (functionality: string, version: LuaTarget) => + `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` +); + +export const unsupportedProperty = createDiagnosticFactory( + (parentName: string, property: string) => `${parentName}.${property} is unsupported.` +); + +export const invalidAmbientIdentifierName = createDiagnosticFactory( + (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` +); + +export const unresolvableRequirePath = createDiagnosticFactory( + (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` +); + +export const unsupportedVarDeclaration = createDiagnosticFactory( + "`var` declarations are not supported. Use `let` or `const` instead." +); diff --git a/src/transformation/utils/errors.ts b/src/transformation/utils/errors.ts deleted file mode 100644 index 370e27daa..000000000 --- a/src/transformation/utils/errors.ts +++ /dev/null @@ -1,143 +0,0 @@ -import * as ts from "typescript"; -import { LuaTarget } from "../../CompilerOptions"; - -export class TranspileError extends Error { - public name = "TranspileError"; - constructor(message: string, public node: ts.Node) { - super(message); - } -} - -const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); - -export const ForbiddenForIn = (node: ts.Node) => - new TranspileError(`Iterating over arrays with 'for ... in' is not allowed.`, node); - -export const ForbiddenLuaTableNonDeclaration = (node: ts.Node) => - new TranspileError(`Classes with the '@luaTable' annotation must be declared.`, node); - -export const InvalidExtendsLuaTable = (node: ts.Node) => - new TranspileError(`Cannot extend classes with the '@luaTable' annotation.`, node); - -export const InvalidInstanceOfLuaTable = (node: ts.Node) => - new TranspileError(`The instanceof operator cannot be used with a '@luaTable' class.`, node); - -export const ForbiddenLuaTableUseException = (description: string, node: ts.Node) => - new TranspileError(`Invalid @luaTable usage: ${description}`, node); - -export const InvalidAnnotationArgumentNumber = (name: string, got: number, expected: number, node: ts.Node) => - new TranspileError(`'${name}' expects ${expected} argument(s) but got ${got}.`, node); - -export const InvalidDecoratorContext = (node: ts.Node) => - new TranspileError(`Decorator function cannot have 'this: void'.`, node); - -export const InvalidExtensionMetaExtension = (node: ts.Node) => - new TranspileError(`Cannot use both '@extension' and '@metaExtension' annotations on the same class.`, node); - -export const InvalidNewExpressionOnExtension = (node: ts.Node) => - new TranspileError(`Cannot construct classes with '@extension' or '@metaExtension' annotation.`, node); - -export const InvalidExportDeclaration = (declaration: ts.ExportDeclaration) => - new TranspileError("Encountered invalid export declaration without exports and without module.", declaration); - -export const InvalidExtendsExtension = (node: ts.Node) => - new TranspileError(`Cannot extend classes with '@extension' or '@metaExtension' annotation.`, node); - -export const InvalidExportsExtension = (node: ts.Node) => - new TranspileError(`Cannot export classes with '@extension' or '@metaExtension' annotation.`, node); - -export const InvalidInstanceOfExtension = (node: ts.Node) => - new TranspileError(`Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation.`, node); - -export const InvalidJsonFileContent = (node: ts.Node) => new TranspileError("Invalid JSON file content", node); - -export const MissingClassName = (node: ts.Node) => new TranspileError(`Class declarations must have a name.`, node); - -export const MissingForOfVariables = (node: ts.Node) => - new TranspileError("Transpiled ForOf variable declaration list contains no declarations.", node); - -export const MissingFunctionName = (declaration: ts.FunctionLikeDeclaration) => - new TranspileError("Unsupported function declaration without name.", declaration); - -export const MissingMetaExtension = (node: ts.Node) => - new TranspileError(`'@metaExtension' annotation requires the extension of the metatable class.`, node); - -export const NonFlattenableDestructure = (node: ts.Node) => - new TranspileError(`This node cannot be destructured using a standard Lua assignment statement.`, node); - -export const UndefinedFunctionDefinition = (functionSymbolId: number) => - new Error(`Function definition for function symbol ${functionSymbolId} is undefined.`); - -export const UnsupportedForInVariable = (node: ts.Node) => - new TranspileError(`Unsupported for-in variable kind.`, node); - -export const UndefinedScope = () => new Error("Expected to pop a scope, but found undefined."); - -export const UndefinedTypeNode = (node: ts.Node) => new TranspileError("Failed to resolve required type node.", node); - -export const UnknownSuperType = (node: ts.Node) => - new TranspileError("Unable to resolve type of super expression.", node); - -export const UnsupportedImportType = (node: ts.Node) => new TranspileError(`Unsupported import type.`, node); - -export const UnsupportedKind = (description: string, kind: ts.SyntaxKind, node: ts.Node) => - new TranspileError(`Unsupported ${description} kind: ${ts.SyntaxKind[kind]}`, node); - -export const UnsupportedProperty = (parentName: string, property: string, node: ts.Node) => - new TranspileError(`Unsupported property on ${parentName}: ${property}`, node); - -export const UnsupportedForTarget = (functionality: string, version: LuaTarget, node: ts.Node) => - new TranspileError(`${functionality} is/are not supported for target ${getLuaTargetName(version)}.`, node); - -export const UnsupportedFunctionWithoutBody = (node: ts.FunctionLikeDeclaration) => - new TranspileError("Functions with undefined bodies are not supported.", node); - -export const UnsupportedNoSelfFunctionConversion = (node: ts.Node, name?: string) => { - const nameReference = name ? ` '${name}'` : ""; - return new TranspileError( - `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.`, - node - ); -}; - -export const UnsupportedSelfFunctionConversion = (node: ts.Node, name?: string) => { - const nameReference = name ? ` '${name}'` : ""; - return new TranspileError( - `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + - `To fix, wrap in an arrow function or declare with 'this: any'.`, - node - ); -}; - -export const UnsupportedOverloadAssignment = (node: ts.Node, name?: string) => { - const nameReference = name ? ` to '${name}'` : ""; - return new TranspileError( - `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + - "Overloads should all have the same type for 'this'.", - node - ); -}; - -export const UnsupportedNonDestructuringLuaIterator = (node: ts.Node) => - new TranspileError( - "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + - "You must use a destructuring statement to catch results from a lua iterator with " + - "the '@tupleReturn' annotation.", - node - ); - -export const UnresolvableRequirePath = (node: ts.Node, reason: string, path?: string) => - new TranspileError(`${reason}. TypeScript path: ${path}.`, node); - -export const InvalidAmbientIdentifierName = (node: ts.Identifier) => - new TranspileError( - `Invalid ambient identifier name "${node.text}". Ambient identifiers must be valid lua identifiers.`, - node - ); - -export const InvalidForRangeCall = (node: ts.Node, message: string) => - new TranspileError(`Invalid @forRange call: ${message}`, node); - -export const UnsupportedVarDeclaration = (node: ts.Node) => - new TranspileError("`var` declarations are not supported. Use `let` or `const` instead.", node); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index c72ec2d74..318c4abaf 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -1,7 +1,7 @@ -import * as assert from "assert"; import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; +import { assert } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; import { peekScope, ScopeType } from "./scope"; diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index ed95f0d44..b10ed414f 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -1,9 +1,10 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; -import { InvalidAmbientIdentifierName } from "./errors"; -import { isAmbientNode } from "./typescript"; +import { invalidAmbientIdentifierName } from "./diagnostics"; import { isSymbolExported } from "./export"; +import { isAmbientNode } from "./typescript"; +export const isValidLuaIdentifier = (name: string) => !luaKeywords.has(name) && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name); export const luaKeywords: ReadonlySet = new Set([ "and", "break", @@ -29,7 +30,7 @@ export const luaKeywords: ReadonlySet = new Set([ "while", ]); -export const luaBuiltins: ReadonlySet = new Set([ +const luaBuiltins: ReadonlySet = new Set([ "_G", "assert", "coroutine", @@ -51,42 +52,50 @@ export const luaBuiltins: ReadonlySet = new Set([ "unpack", ]); -export const isValidLuaIdentifier = (str: string) => /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(str); +export const isUnsafeName = (name: string) => !isValidLuaIdentifier(name) || luaBuiltins.has(name); + +function checkName(context: TransformationContext, name: string, node: ts.Node): boolean { + const isInvalid = !isValidLuaIdentifier(name); + + if (isInvalid) { + // Empty identifier is a TypeScript error + if (name !== "") { + context.diagnostics.push(invalidAmbientIdentifierName(node, name)); + } + } -export const isUnsafeName = (name: string) => - luaKeywords.has(name) || luaBuiltins.has(name) || !isValidLuaIdentifier(name); + return isInvalid; +} export function hasUnsafeSymbolName( context: TransformationContext, symbol: ts.Symbol, tsOriginal: ts.Identifier ): boolean { - const isLuaKeyword = luaKeywords.has(symbol.name); - const isInvalidIdentifier = !isValidLuaIdentifier(symbol.name); const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d)); - if ((isLuaKeyword || isInvalidIdentifier) && isAmbient) { - // Catch ambient declarations of identifiers with bad names - throw InvalidAmbientIdentifierName(tsOriginal); - } - if (isUnsafeName(symbol.name)) { - // only unsafe when non-ambient and not exported - return !isAmbient && !isSymbolExported(context, symbol); + // Catch ambient declarations of identifiers with bad names + if (isAmbient && checkName(context, symbol.name, tsOriginal)) { + return true; } - return false; + // only unsafe when non-ambient and not exported + return isUnsafeName(symbol.name) && !isAmbient && !isSymbolExported(context, symbol); } -export function hasUnsafeIdentifierName(context: TransformationContext, identifier: ts.Identifier): boolean { - const symbol = context.checker.getSymbolAtLocation(identifier); - - if (symbol !== undefined) { - return hasUnsafeSymbolName(context, symbol, identifier); - } else if (luaKeywords.has(identifier.text) || !isValidLuaIdentifier(identifier.text)) { - throw InvalidAmbientIdentifierName(identifier); +export function hasUnsafeIdentifierName( + context: TransformationContext, + identifier: ts.Identifier, + checkSymbol = true +): boolean { + if (checkSymbol) { + const symbol = context.checker.getSymbolAtLocation(identifier); + if (symbol) { + return hasUnsafeSymbolName(context, symbol, identifier); + } } - return false; + return checkName(context, identifier.text, identifier); } const fixInvalidLuaIdentifier = (name: string) => diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 44430f763..2c9f267dd 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -1,9 +1,7 @@ -import * as assert from "assert"; import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { getOrUpdate, isNonNull } from "../../utils"; +import { assert, getOrUpdate, isNonNull } from "../../utils"; import { TransformationContext } from "../context"; -import { UndefinedFunctionDefinition, UndefinedScope } from "./errors"; import { getSymbolInfo } from "./symbols"; import { getFirstDeclarationInFile } from "./typescript"; @@ -65,9 +63,7 @@ export function markSymbolAsReferencedInCurrentScopes( export function peekScope(context: TransformationContext): Scope { const scopeStack = getScopeStack(context); const scope = scopeStack[scopeStack.length - 1]; - if (!scope) { - throw UndefinedScope(); - } + assert(scope); return scope; } @@ -90,9 +86,7 @@ export function pushScope(context: TransformationContext, scopeType: ScopeType): export function popScope(context: TransformationContext): Scope { const scopeStack = getScopeStack(context); const scope = scopeStack.pop(); - if (!scope) { - throw UndefinedScope(); - } + assert(scope); return scope; } @@ -123,9 +117,7 @@ function shouldHoistSymbol(context: TransformationContext, symbolId: lua.SymbolI if (scope.functionDefinitions) { for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { - if (functionDefinition.definition === undefined) { - throw UndefinedFunctionDefinition(functionSymbolId); - } + assert(functionDefinition.definition); const { line, column } = lua.getOriginalPos(functionDefinition.definition); if (line !== undefined && column !== undefined) { @@ -196,9 +188,7 @@ function hoistFunctionDefinitions( const result = [...statements]; const hoistedFunctions: Array = []; for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { - if (functionDefinition.definition === undefined) { - throw UndefinedFunctionDefinition(functionSymbolId); - } + assert(functionDefinition.definition); if (shouldHoistSymbol(context, functionSymbolId, scope)) { const index = result.indexOf(functionDefinition.definition); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 4043a56a0..3502e15e4 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -6,7 +6,7 @@ import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { createExpressionPlusOne } from "../utils/lua-ast"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; -import { transformLuaTableElementAccessExpression, transformLuaTablePropertyAccessExpression } from "./lua-table"; +import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; export function transformElementAccessArgument( context: TransformationContext, @@ -24,7 +24,7 @@ export function transformElementAccessArgument( } export const transformElementAccessExpression: FunctionVisitor = (expression, context) => { - transformLuaTableElementAccessExpression(context, expression); + validateLuaTableElementAccessExpression(context, expression); const constEnumValue = tryGetConstEnumValue(context, expression); if (constEnumValue) { diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 6a5417b0f..6a785699a 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -3,12 +3,13 @@ import * as lua from "../../../LuaAST"; import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { isTupleReturnCall } from "../../utils/annotations"; -import { validateAssignment, validatePropertyAssignment } from "../../utils/assignment-validation"; +import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; +import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; export function transformAssignmentLeftHandSideExpression( @@ -16,7 +17,9 @@ export function transformAssignmentLeftHandSideExpression( node: ts.Expression ): lua.AssignmentLeftHandSideExpression { const symbol = context.checker.getSymbolAtLocation(node); - const left = context.transformExpression(node); + const left = ts.isPropertyAccessExpression(node) + ? transformLuaTablePropertyAccessInAssignment(context, node) ?? context.transformExpression(node) + : context.transformExpression(node); return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) ? createExportedIdentifier(context, left) @@ -67,7 +70,7 @@ export function transformAssignment( export function transformAssignmentExpression( context: TransformationContext, expression: ts.AssignmentExpression -): lua.CallExpression | lua.MethodCallExpression { +): lua.Expression { // Validate assignment const rightType = context.checker.getTypeAtLocation(expression.right); const leftType = context.checker.getTypeAtLocation(expression.left); @@ -119,6 +122,9 @@ export function transformAssignmentExpression( const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { + // Called only for validation + transformLuaTablePropertyAccessInAssignment(context, expression.left); + // Property access indexExpression = lua.createStringLiteral(expression.left.name.text); } else { @@ -175,7 +181,6 @@ export function transformAssignmentStatement( const rightType = context.checker.getTypeAtLocation(expression.right); const leftType = context.checker.getTypeAtLocation(expression.left); validateAssignment(context, expression.right, rightType, leftType); - validatePropertyAssignment(context, expression); if (isDestructuringAssignment(expression)) { if (canBeTransformedToLuaAssignmentStatement(context, expression)) { diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index e8369e91d..ffdf410ec 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -1,11 +1,23 @@ import * as ts from "typescript"; import { LuaTarget } from "../../../CompilerOptions"; import * as lua from "../../../LuaAST"; +import { assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { UnsupportedForTarget, UnsupportedKind } from "../../utils/errors"; -import { transformBinaryOperator } from "../binary-expression"; +import { unsupportedForTarget, unsupportedRightShiftOperator } from "../../utils/diagnostics"; + +export type BitOperator = ts.ShiftOperator | ts.BitwiseOperator; +export const isBitOperator = (operator: ts.BinaryOperator): operator is BitOperator => + operator in bitOperatorToLibOperation; + +const bitOperatorToLibOperation: Record = { + [ts.SyntaxKind.AmpersandToken]: "band", + [ts.SyntaxKind.BarToken]: "bor", + [ts.SyntaxKind.CaretToken]: "bxor", + [ts.SyntaxKind.LessThanLessThanToken]: "lshift", + [ts.SyntaxKind.GreaterThanGreaterThanToken]: "arshift", + [ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken]: "rshift", +}; -type BitOperator = ts.ShiftOperator | ts.BitwiseOperator; function transformBinaryBitLibOperation( node: ts.Node, left: lua.Expression, @@ -13,35 +25,33 @@ function transformBinaryBitLibOperation( operator: BitOperator, lib: string ): lua.Expression { - let bitFunction: string; + const functionName = bitOperatorToLibOperation[operator]; + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier(lib), lua.createStringLiteral(functionName)), + [left, right], + node + ); +} + +function transformBitOperatorToLuaOperator( + context: TransformationContext, + node: ts.Node, + operator: BitOperator +): lua.BinaryOperator { switch (operator) { - case ts.SyntaxKind.AmpersandToken: - bitFunction = "band"; - break; case ts.SyntaxKind.BarToken: - bitFunction = "bor"; - break; + return lua.SyntaxKind.BitwiseOrOperator; case ts.SyntaxKind.CaretToken: - bitFunction = "bxor"; - break; + return lua.SyntaxKind.BitwiseExclusiveOrOperator; + case ts.SyntaxKind.AmpersandToken: + return lua.SyntaxKind.BitwiseAndOperator; case ts.SyntaxKind.LessThanLessThanToken: - bitFunction = "lshift"; - break; - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - bitFunction = "rshift"; - break; + return lua.SyntaxKind.BitwiseLeftShiftOperator; case ts.SyntaxKind.GreaterThanGreaterThanToken: - bitFunction = "arshift"; - break; - default: - throw UnsupportedKind("binary bitwise operator", operator, node); + context.diagnostics.push(unsupportedRightShiftOperator(node)); + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + return lua.SyntaxKind.BitwiseRightShiftOperator; } - - return lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier(lib), lua.createStringLiteral(bitFunction)), - [left, right], - node - ); } export function transformBinaryBitOperation( @@ -53,16 +63,15 @@ export function transformBinaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Lua51: - throw UnsupportedForTarget("Bitwise operations", LuaTarget.Lua51, node); - - case LuaTarget.Lua52: - return transformBinaryBitLibOperation(node, left, right, operator, "bit32"); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); case LuaTarget.LuaJIT: return transformBinaryBitLibOperation(node, left, right, operator, "bit"); + case LuaTarget.Lua52: + return transformBinaryBitLibOperation(node, left, right, operator, "bit32"); default: - const luaOperator = transformBinaryOperator(context, node, operator); + const luaOperator = transformBitOperatorToLuaOperator(context, node, operator); return lua.createBinaryExpression(left, right, luaOperator, node); } } @@ -79,7 +88,7 @@ function transformUnaryBitLibOperation( bitFunction = "bnot"; break; default: - throw UnsupportedKind("unary bitwise operator", operator, node); + assertNever(operator); } return lua.createCallExpression( @@ -97,14 +106,14 @@ export function transformUnaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Lua51: - throw UnsupportedForTarget("Bitwise operations", LuaTarget.Lua51, node); - - case LuaTarget.Lua52: - return transformUnaryBitLibOperation(node, expression, operator, "bit32"); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); case LuaTarget.LuaJIT: return transformUnaryBitLibOperation(node, expression, operator, "bit"); + case LuaTarget.Lua52: + return transformUnaryBitLibOperation(node, expression, operator, "bit32"); + default: return lua.createUnaryExpression(expression, operator, node); } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index c7ab11cdc..0eec44875 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -33,7 +33,22 @@ export function parseAccessExpressionWithEvaluationEffects( return []; } -const compoundToAssignmentTokens: Record = { +// TODO: `as const` doesn't work on enum members +type CompoundAssignmentToken = + | ts.SyntaxKind.BarToken + | ts.SyntaxKind.PlusToken + | ts.SyntaxKind.CaretToken + | ts.SyntaxKind.MinusToken + | ts.SyntaxKind.SlashToken + | ts.SyntaxKind.PercentToken + | ts.SyntaxKind.AsteriskToken + | ts.SyntaxKind.AmpersandToken + | ts.SyntaxKind.AsteriskAsteriskToken + | ts.SyntaxKind.LessThanLessThanToken + | ts.SyntaxKind.GreaterThanGreaterThanToken + | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + +const compoundToAssignmentTokens: Record = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, @@ -51,7 +66,7 @@ const compoundToAssignmentTokens: Record token in compoundToAssignmentTokens; -export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator) => +export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; export function transformCompoundAssignmentExpression( @@ -60,7 +75,7 @@ export function transformCompoundAssignmentExpression( // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, rhs: ts.Expression, - replacementOperator: ts.BinaryOperator, + operator: CompoundAssignmentToken, isPostfix: boolean ): lua.CallExpression { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); @@ -85,18 +100,12 @@ export function transformCompoundAssignmentExpression( // local ____tmp = ____obj[____index]; // ____obj[____index] = ____tmp ${replacementOperator} ${right}; tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); - const operatorExpression = transformBinaryOperation(context, tmp, right, replacementOperator, expression); + const operatorExpression = transformBinaryOperation(context, tmp, right, operator, expression); assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); } else { // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; - const operatorExpression = transformBinaryOperation( - context, - accessExpression, - right, - replacementOperator, - expression - ); + const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, expression); tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); assignStatement = lua.createAssignmentStatement(accessExpression, tmp); } @@ -113,13 +122,7 @@ export function transformCompoundAssignmentExpression( // return ____tmp const tmpIdentifier = lua.createIdentifier("____tmp"); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); - const operatorExpression = transformBinaryOperation( - context, - tmpIdentifier, - right, - replacementOperator, - expression - ); + const operatorExpression = transformBinaryOperation(context, tmpIdentifier, right, operator, expression); const assignStatements = transformAssignment(context, lhs, operatorExpression); return createImmediatelyInvokedFunctionExpression( [tmpDeclaration, ...assignStatements], @@ -132,7 +135,7 @@ export function transformCompoundAssignmentExpression( // ${left} = ____tmp; // return ____tmp const tmpIdentifier = lua.createIdentifier("____tmp"); - const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); + const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatements = transformAssignment(context, lhs, tmpIdentifier); return createImmediatelyInvokedFunctionExpression( @@ -143,7 +146,7 @@ export function transformCompoundAssignmentExpression( } else { // Simple expressions // ${left} = ${right}; return ${right} - const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, expression); + const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); const assignStatements = transformAssignment(context, lhs, operatorExpression); return createImmediatelyInvokedFunctionExpression(assignStatements, left, expression); } @@ -154,7 +157,7 @@ export function transformCompoundAssignmentStatement( node: ts.Node, lhs: ts.Expression, rhs: ts.Expression, - replacementOperator: ts.BinaryOperator + operator: CompoundAssignmentToken ): lua.Statement[] { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const right = context.transformExpression(rhs); @@ -171,20 +174,13 @@ export function transformCompoundAssignmentStatement( [context.transformExpression(objExpression), context.transformExpression(indexExpression)] ); const accessExpression = lua.createTableIndexExpression(obj, index); - const operatorExpression = transformBinaryOperation( - context, - accessExpression, - right, - replacementOperator, - node - ); + const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, node); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return [objAndIndexDeclaration, assignStatement]; } else { // Simple statements // ${left} = ${left} ${replacementOperator} ${right} - const operatorExpression = transformBinaryOperation(context, left, right, replacementOperator, node); - const assignmentStatements = transformAssignment(context, lhs, operatorExpression); - return assignmentStatements; + const operatorExpression = transformBinaryOperation(context, left, right, operator, node); + return transformAssignment(context, lhs, operatorExpression); } } diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index e255cbf70..567de4e6f 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; +import { assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { UnsupportedKind } from "../../utils/errors"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isAssignmentPattern } from "../../utils/typescript"; import { transformPropertyName } from "../literal"; @@ -113,7 +113,10 @@ function transformArrayLiteralAssignmentPattern( case ts.SyntaxKind.ElementAccessExpression: return transformAssignment(context, element, indexedRoot); case ts.SyntaxKind.SpreadElement: - if (index !== node.elements.length - 1) return []; + if (index !== node.elements.length - 1) { + // TypeScript error + return []; + } const restElements = transformLuaLibFunction( context, @@ -127,7 +130,8 @@ function transformArrayLiteralAssignmentPattern( case ts.SyntaxKind.OmittedExpression: return []; default: - throw UnsupportedKind("Array Destructure Assignment Element", element.kind, element); + // TypeScript error + return []; } }); } @@ -150,8 +154,13 @@ function transformObjectLiteralAssignmentPattern( case ts.SyntaxKind.SpreadAssignment: result.push(...transformSpreadAssignment(context, property, root, node.properties)); break; + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + // TypeScript error + break; default: - throw UnsupportedKind("Object Destructure Property", property.kind, property); + assertNever(property); } } diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index d810adcf3..bbddf2eff 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,13 +2,17 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { InvalidInstanceOfExtension, InvalidInstanceOfLuaTable, UnsupportedKind } from "../../utils/errors"; +import { + extensionInvalidInstanceOf, + luaTableInvalidInstanceOf, + unsupportedNullishCoalescing, +} from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; import { transformAssignmentExpression, transformAssignmentStatement } from "./assignments"; -import { transformBinaryBitOperation } from "./bit"; +import { BitOperator, isBitOperator, transformBinaryBitOperation } from "./bit"; import { isCompoundAssignmentToken, transformCompoundAssignmentExpression, @@ -16,105 +20,66 @@ import { unwrapCompoundAssignmentToken, } from "./compound"; -export function transformBinaryOperator( - context: TransformationContext, - node: ts.Node, - operator: ts.BinaryOperator -): lua.BinaryOperator { - switch (operator) { - // Bitwise operators - case ts.SyntaxKind.BarToken: - return lua.SyntaxKind.BitwiseOrOperator; - case ts.SyntaxKind.CaretToken: - return lua.SyntaxKind.BitwiseExclusiveOrOperator; - case ts.SyntaxKind.AmpersandToken: - return lua.SyntaxKind.BitwiseAndOperator; - case ts.SyntaxKind.LessThanLessThanToken: - return lua.SyntaxKind.BitwiseLeftShiftOperator; - case ts.SyntaxKind.GreaterThanGreaterThanToken: - throw UnsupportedKind("right shift operator (use >>> instead)", operator, node); - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return lua.SyntaxKind.BitwiseRightShiftOperator; - // Regular operators - case ts.SyntaxKind.AmpersandAmpersandToken: - return lua.SyntaxKind.AndOperator; - case ts.SyntaxKind.BarBarToken: - return lua.SyntaxKind.OrOperator; - case ts.SyntaxKind.MinusToken: - return lua.SyntaxKind.SubtractionOperator; - case ts.SyntaxKind.PlusToken: - if (ts.isBinaryExpression(node)) { - // Check is we need to use string concat operator - const typeLeft = context.checker.getTypeAtLocation(node.left); - const typeRight = context.checker.getTypeAtLocation(node.right); - if (isStringType(context, typeLeft) || isStringType(context, typeRight)) { - return lua.SyntaxKind.ConcatOperator; - } - } - - return lua.SyntaxKind.AdditionOperator; - case ts.SyntaxKind.AsteriskToken: - return lua.SyntaxKind.MultiplicationOperator; - case ts.SyntaxKind.AsteriskAsteriskToken: - return lua.SyntaxKind.PowerOperator; - case ts.SyntaxKind.SlashToken: - return lua.SyntaxKind.DivisionOperator; - case ts.SyntaxKind.PercentToken: - return lua.SyntaxKind.ModuloOperator; - case ts.SyntaxKind.GreaterThanToken: - return lua.SyntaxKind.GreaterThanOperator; - case ts.SyntaxKind.GreaterThanEqualsToken: - return lua.SyntaxKind.GreaterEqualOperator; - case ts.SyntaxKind.LessThanToken: - return lua.SyntaxKind.LessThanOperator; - case ts.SyntaxKind.LessThanEqualsToken: - return lua.SyntaxKind.LessEqualOperator; - case ts.SyntaxKind.EqualsEqualsToken: - case ts.SyntaxKind.EqualsEqualsEqualsToken: - return lua.SyntaxKind.EqualityOperator; - case ts.SyntaxKind.ExclamationEqualsToken: - case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return lua.SyntaxKind.InequalityOperator; - default: - throw UnsupportedKind("binary operator", operator, node); - } -} +type SimpleOperator = + | ts.AdditiveOperatorOrHigher + | Exclude + | ts.EqualityOperator + | ts.LogicalOperator; + +const simpleOperatorsToLua: Record = { + [ts.SyntaxKind.AmpersandAmpersandToken]: lua.SyntaxKind.AndOperator, + [ts.SyntaxKind.BarBarToken]: lua.SyntaxKind.OrOperator, + [ts.SyntaxKind.PlusToken]: lua.SyntaxKind.AdditionOperator, + [ts.SyntaxKind.MinusToken]: lua.SyntaxKind.SubtractionOperator, + [ts.SyntaxKind.AsteriskToken]: lua.SyntaxKind.MultiplicationOperator, + [ts.SyntaxKind.AsteriskAsteriskToken]: lua.SyntaxKind.PowerOperator, + [ts.SyntaxKind.SlashToken]: lua.SyntaxKind.DivisionOperator, + [ts.SyntaxKind.PercentToken]: lua.SyntaxKind.ModuloOperator, + [ts.SyntaxKind.GreaterThanToken]: lua.SyntaxKind.GreaterThanOperator, + [ts.SyntaxKind.GreaterThanEqualsToken]: lua.SyntaxKind.GreaterEqualOperator, + [ts.SyntaxKind.LessThanToken]: lua.SyntaxKind.LessThanOperator, + [ts.SyntaxKind.LessThanEqualsToken]: lua.SyntaxKind.LessEqualOperator, + [ts.SyntaxKind.EqualsEqualsToken]: lua.SyntaxKind.EqualityOperator, + [ts.SyntaxKind.EqualsEqualsEqualsToken]: lua.SyntaxKind.EqualityOperator, + [ts.SyntaxKind.ExclamationEqualsToken]: lua.SyntaxKind.InequalityOperator, + [ts.SyntaxKind.ExclamationEqualsEqualsToken]: lua.SyntaxKind.InequalityOperator, +}; export function transformBinaryOperation( context: TransformationContext, left: lua.Expression, right: lua.Expression, - operator: ts.BinaryOperator, - tsOriginal: ts.Node + operator: BitOperator | SimpleOperator, + node: ts.Node ): lua.Expression { - switch (operator) { - case ts.SyntaxKind.AmpersandToken: - case ts.SyntaxKind.BarToken: - case ts.SyntaxKind.CaretToken: - case ts.SyntaxKind.LessThanLessThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - return transformBinaryBitOperation(context, tsOriginal, left, right, operator); - default: - const luaOperator = transformBinaryOperator(context, tsOriginal, operator); - if (luaOperator === lua.SyntaxKind.ConcatOperator) { - left = wrapInToStringForConcat(left); - right = wrapInToStringForConcat(right); - } + if (isBitOperator(operator)) { + return transformBinaryBitOperation(context, node, left, right, operator); + } - return lua.createBinaryExpression(left, right, luaOperator, tsOriginal); + let luaOperator = simpleOperatorsToLua[operator]; + + // Check if we need to use string concat operator + if (operator === ts.SyntaxKind.PlusToken && ts.isBinaryExpression(node)) { + const typeLeft = context.checker.getTypeAtLocation(node.left); + const typeRight = context.checker.getTypeAtLocation(node.right); + if (isStringType(context, typeLeft) || isStringType(context, typeRight)) { + left = wrapInToStringForConcat(left); + right = wrapInToStringForConcat(right); + luaOperator = lua.SyntaxKind.ConcatOperator; + } } + + return lua.createBinaryExpression(left, right, luaOperator, node); } export const transformBinaryExpression: FunctionVisitor = (node, context) => { + const operator = node.operatorToken.kind; + const typeOfResult = transformTypeOfBinaryExpression(context, node); if (typeOfResult) { return typeOfResult; } - const operator = node.operatorToken.kind; - - // Check if this is an assignment token, then handle accordingly if (isCompoundAssignmentToken(operator)) { return transformCompoundAssignmentExpression( context, @@ -126,39 +91,7 @@ export const transformBinaryExpression: FunctionVisitor = ( ); } - // Transpile operators switch (operator) { - case ts.SyntaxKind.AmpersandToken: - case ts.SyntaxKind.BarToken: - case ts.SyntaxKind.CaretToken: - case ts.SyntaxKind.LessThanLessThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanToken: - case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: - case ts.SyntaxKind.PlusToken: - case ts.SyntaxKind.AmpersandAmpersandToken: - case ts.SyntaxKind.BarBarToken: - case ts.SyntaxKind.MinusToken: - case ts.SyntaxKind.AsteriskToken: - case ts.SyntaxKind.AsteriskAsteriskToken: - case ts.SyntaxKind.SlashToken: - case ts.SyntaxKind.PercentToken: - - case ts.SyntaxKind.GreaterThanToken: - case ts.SyntaxKind.GreaterThanEqualsToken: - case ts.SyntaxKind.LessThanToken: - case ts.SyntaxKind.LessThanEqualsToken: - case ts.SyntaxKind.EqualsEqualsToken: - case ts.SyntaxKind.EqualsEqualsEqualsToken: - case ts.SyntaxKind.ExclamationEqualsToken: - case ts.SyntaxKind.ExclamationEqualsEqualsToken: - return transformBinaryOperation( - context, - context.transformExpression(node.left), - context.transformExpression(node.right), - operator, - node - ); - case ts.SyntaxKind.EqualsToken: return transformAssignmentExpression(context, node as ts.AssignmentExpression); @@ -181,12 +114,11 @@ export const transformBinaryExpression: FunctionVisitor = ( const annotations = getTypeAnnotations(rhsType); if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - // Cannot use instanceof on extension classes - throw InvalidInstanceOfExtension(node); + context.diagnostics.push(extensionInvalidInstanceOf(node)); } if (annotations.has(AnnotationKind.LuaTable)) { - throw InvalidInstanceOfLuaTable(node); + context.diagnostics.push(luaTableInvalidInstanceOf(node)); } if (isStandardLibraryType(context, rhsType, "ObjectConstructor")) { @@ -197,16 +129,31 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.CommaToken: { - const rhs = context.transformExpression(node.right); return createImmediatelyInvokedFunctionExpression( context.transformStatements(ts.createExpressionStatement(node.left)), - rhs, + context.transformExpression(node.right), + node + ); + } + + case ts.SyntaxKind.QuestionQuestionToken: { + context.diagnostics.push(unsupportedNullishCoalescing(node.operatorToken)); + return lua.createBinaryExpression( + context.transformExpression(node.left), + context.transformExpression(node.right), + lua.SyntaxKind.OrOperator, node ); } default: - throw UnsupportedKind("binary operator", operator, node); + return transformBinaryOperation( + context, + context.transformExpression(node.left), + context.transformExpression(node.right), + operator, + node + ); } }; @@ -215,27 +162,26 @@ export function transformBinaryExpressionStatement( node: ts.ExpressionStatement ): lua.Statement[] | lua.Statement | undefined { const { expression } = node; - if (ts.isBinaryExpression(expression)) { - const operator = expression.operatorToken.kind; + if (!ts.isBinaryExpression(expression)) return; + const operator = expression.operatorToken.kind; - if (isCompoundAssignmentToken(operator)) { - // +=, -=, etc... - return transformCompoundAssignmentStatement( - context, - expression, - expression.left, - expression.right, - unwrapCompoundAssignmentToken(operator) - ); - } else if (operator === ts.SyntaxKind.EqualsToken) { - return transformAssignmentStatement(context, expression as ts.AssignmentExpression); - } else if (operator === ts.SyntaxKind.CommaToken) { - const statements = [ - ...context.transformStatements(ts.createExpressionStatement(expression.left)), - ...context.transformStatements(ts.createExpressionStatement(expression.right)), - ]; - - return lua.createDoStatement(statements, expression); - } + if (isCompoundAssignmentToken(operator)) { + // +=, -=, etc... + return transformCompoundAssignmentStatement( + context, + expression, + expression.left, + expression.right, + unwrapCompoundAssignmentToken(operator) + ); + } else if (operator === ts.SyntaxKind.EqualsToken) { + return transformAssignmentStatement(context, expression as ts.AssignmentExpression); + } else if (operator === ts.SyntaxKind.CommaToken) { + const statements = [ + ...context.transformStatements(ts.createExpressionStatement(expression.left)), + ...context.transformStatements(ts.createExpressionStatement(expression.right)), + ]; + + return lua.createDoStatement(statements, expression); } } diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 49ead1ff6..bde4ddd52 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -2,16 +2,12 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { UndefinedScope, UnsupportedForTarget } from "../utils/errors"; +import { unsupportedForTarget } from "../utils/diagnostics"; import { findScope, ScopeType } from "../utils/scope"; export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { const breakableScope = findScope(context, ScopeType.Loop | ScopeType.Switch); - if (breakableScope === undefined) { - throw UndefinedScope(); - } - - if (breakableScope.type === ScopeType.Switch) { + if (breakableScope?.type === ScopeType.Switch) { return lua.createGotoStatement(`____switch${breakableScope.id}_end`); } else { return lua.createBreakStatement(breakStatement); @@ -20,14 +16,14 @@ export const transformBreakStatement: FunctionVisitor = (brea export const transformContinueStatement: FunctionVisitor = (statement, context) => { if (context.luaTarget === LuaTarget.Lua51) { - throw UnsupportedForTarget("Continue statement", LuaTarget.Lua51, statement); + context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", LuaTarget.Lua51)); } const scope = findScope(context, ScopeType.Loop); - if (scope === undefined) { - throw UndefinedScope(); + + if (scope) { + scope.loopContinued = true; } - scope.loopContinued = true; - return lua.createGotoStatement(`__continue${scope.id}`, statement); + return lua.createGotoStatement(`__continue${scope?.id ?? ""}`, statement); }; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 75e2a95b2..d7e339f2b 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -4,11 +4,10 @@ import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isInTupleReturnFunction, isTupleReturnCall, isVarArgType } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; -import { UnsupportedKind } from "../utils/errors"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { isValidLuaIdentifier, luaKeywords } from "../utils/safe-names"; +import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformIdentifier } from "./identifier"; @@ -47,12 +46,7 @@ export function transformContextualCallExpression( transformedArguments: lua.Expression[] ): lua.Expression { const left = ts.isCallExpression(node) ? node.expression : node.tag; - if ( - ts.isPropertyAccessExpression(left) && - ts.isIdentifier(left.name) && - !luaKeywords.has(left.name.text) && - isValidLuaIdentifier(left.name.text) - ) { + if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { // table:name() const table = context.transformExpression(left.expression); @@ -88,7 +82,7 @@ export function transformContextualCallExpression( const expression = context.transformExpression(left); return lua.createCallExpression(expression, transformedArguments, node); } else { - throw UnsupportedKind("Left Hand Side Call Expression", left.kind, left); + throw new Error(`Unsupported LeftHandSideExpression kind: ${ts.SyntaxKind[left.kind]}`); } } diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 5c8406209..5cae0cf17 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import { InvalidDecoratorContext } from "../../utils/errors"; +import { decoratorInvalidContext } from "../../utils/diagnostics"; import { addExportToIdentifier } from "../../utils/export"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; @@ -26,7 +26,7 @@ export function createConstructorDecorationStatement( const type = context.checker.getTypeAtLocation(expression); const callContext = getFunctionContextType(context, type); if (callContext === ContextType.Void) { - throw InvalidDecoratorContext(decorator); + context.diagnostics.push(decoratorInvalidContext(decorator)); } return context.transformExpression(expression); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index bf11c8748..33024923e 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -4,15 +4,13 @@ import { getOrUpdate, isNonNull } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { - ForbiddenLuaTableNonDeclaration, - InvalidExportsExtension, - InvalidExtendsExtension, - InvalidExtendsLuaTable, - InvalidExtensionMetaExtension, - MissingClassName, - MissingMetaExtension, - UnknownSuperType, -} from "../../utils/errors"; + extensionAndMetaExtensionConflict, + extensionCannotExport, + extensionCannotExtend, + metaExtensionMissingExtends, + luaTableMustBeAmbient, + luaTableCannotBeExtended, +} from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, @@ -61,16 +59,17 @@ export function transformClassAsExpression( return createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); } -const classStacks = new WeakMap(); +const classSuperInfos = new WeakMap(); +interface ClassSuperInfo { + className: lua.Identifier; + extendedTypeNode?: ts.ExpressionWithTypeArguments; +} export function transformClassDeclaration( classDeclaration: ts.ClassLikeDeclaration, context: TransformationContext, nameOverride?: lua.Identifier ): OneToManyVisitorResult { - const classStack = getOrUpdate(classStacks, context, () => []); - classStack.push(classDeclaration); - let className: lua.Identifier; let classNameText: string; if (nameOverride !== undefined) { @@ -85,7 +84,9 @@ export function transformClassDeclaration( return lua.createAssignmentStatement(left, right, classDeclaration); } else { - throw MissingClassName(classDeclaration); + // TypeScript error + className = lua.createAnonymousIdentifier(); + classNameText = className.text; } const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); @@ -96,17 +97,21 @@ export function transformClassDeclaration( const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); if (isExtension && isMetaExtension) { - throw InvalidExtensionMetaExtension(classDeclaration); + context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); } if ((isExtension || isMetaExtension) && getIdentifierExportScope(context, className) !== undefined) { // Cannot export extension classes - throw InvalidExportsExtension(classDeclaration); + context.diagnostics.push(extensionCannotExport(classDeclaration)); } // Get type that is extended + const extendedTypeNode = getExtendedNode(context, classDeclaration); const extendedType = getExtendedType(context, classDeclaration); + const superInfo = getOrUpdate(classSuperInfos, context, () => []); + superInfo.push({ className, extendedTypeNode }); + if (extendedType) { checkForLuaLibType(context, extendedType); } @@ -115,7 +120,7 @@ export function transformClassDeclaration( // Non-extensions cannot extend extension classes const extendsAnnotations = getTypeAnnotations(extendedType); if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { - throw InvalidExtendsExtension(classDeclaration); + context.diagnostics.push(extensionCannotExtend(classDeclaration)); } } @@ -123,13 +128,12 @@ export function transformClassDeclaration( if (extendedType) { const annotations = getTypeAnnotations(extendedType); if (annotations.has(AnnotationKind.LuaTable)) { - throw InvalidExtendsLuaTable(classDeclaration); + context.diagnostics.push(luaTableCannotBeExtended(extendedTypeNode!)); } } - // LuaTable classes must be ambient if (annotations.has(AnnotationKind.LuaTable) && !isAmbientNode(classDeclaration)) { - throw ForbiddenLuaTableNonDeclaration(classDeclaration); + context.diagnostics.push(luaTableMustBeAmbient(classDeclaration)); } // Get all properties with value @@ -143,30 +147,30 @@ export function transformClassDeclaration( // Overwrite the original className with the class we are overriding for extensions if (isMetaExtension) { - if (!extendedType) { - throw MissingMetaExtension(classDeclaration); - } - - const extendsName = lua.createStringLiteral(extendedType.symbol.name as string); - className = lua.createIdentifier("__meta__" + extendsName.value); - - // local className = debug.getregistry()["extendsName"] - const assignDebugCallIndex = lua.createVariableDeclarationStatement( - className, - lua.createTableIndexExpression( - lua.createCallExpression( - lua.createTableIndexExpression( - lua.createIdentifier("debug"), - lua.createStringLiteral("getregistry") + if (extendedType) { + const extendsName = lua.createStringLiteral(extendedType.symbol.name); + className = lua.createIdentifier("__meta__" + extendsName.value); + + // local className = debug.getregistry()["extendsName"] + const assignDebugCallIndex = lua.createVariableDeclarationStatement( + className, + lua.createTableIndexExpression( + lua.createCallExpression( + lua.createTableIndexExpression( + lua.createIdentifier("debug"), + lua.createStringLiteral("getregistry") + ), + [] ), - [] + extendsName ), - extendsName - ), - classDeclaration - ); + classDeclaration + ); - result.push(assignDebugCallIndex); + result.push(assignDebugCallIndex); + } else { + context.diagnostics.push(metaExtensionMissingExtends(classDeclaration)); + } } if (extensionDirective !== undefined) { @@ -312,23 +316,22 @@ export function transformClassDeclaration( result.push(decorationStatement); } - classStack.pop(); + superInfo.pop(); return result; } export const transformSuperExpression: FunctionVisitor = (expression, context) => { - const classStack = getOrUpdate(classStacks, context, () => []); - const classDeclaration = classStack[classStack.length - 1]; - const extendedNode = getExtendedNode(context, classDeclaration); - if (extendedNode === undefined) { - throw UnknownSuperType(expression); - } + const superInfos = getOrUpdate(classSuperInfos, context, () => []); + const superInfo = superInfos[superInfos.length - 1]; + if (!superInfo) return lua.createAnonymousIdentifier(expression); + const { className, extendedTypeNode } = superInfo; - const extendsExpression = extendedNode.expression; + // Using `super` without extended type node is a TypeScript error + const extendsExpression = extendedTypeNode?.expression; let baseClassName: lua.AssignmentLeftHandSideExpression | undefined; - if (ts.isIdentifier(extendsExpression)) { + if (extendsExpression && ts.isIdentifier(extendsExpression)) { const symbol = context.checker.getSymbolAtLocation(extendsExpression); if (symbol && !isSymbolExported(context, symbol)) { // Use "baseClassName" if base is a simple identifier @@ -337,16 +340,8 @@ export const transformSuperExpression: FunctionVisitor = (ex } if (!baseClassName) { - if (classDeclaration.name === undefined) { - throw MissingClassName(expression); - } - // Use "className.____super" if the base is not a simple identifier - baseClassName = lua.createTableIndexExpression( - transformIdentifier(context, classDeclaration.name), - lua.createStringLiteral("____super"), - expression - ); + baseClassName = lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression); } return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index d1181a284..da1c2f124 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { InvalidAnnotationArgumentNumber, InvalidNewExpressionOnExtension } from "../../utils/errors"; +import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { transformLuaTableNewExpression } from "../lua-table"; @@ -66,20 +66,27 @@ export const transformNewExpression: FunctionVisitor = (node, const annotations = getTypeAnnotations(type); if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - throw InvalidNewExpressionOnExtension(node); + context.diagnostics.push(extensionCannotConstruct(node)); } const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { - if (customConstructorAnnotation.args[0] === undefined) { - throw InvalidAnnotationArgumentNumber("@customConstructor", 0, 1, node); + if (customConstructorAnnotation.args.length === 1) { + return lua.createCallExpression( + lua.createIdentifier(customConstructorAnnotation.args[0]), + transformArguments(context, node.arguments ?? []), + node + ); + } else { + context.diagnostics.push( + annotationInvalidArgumentCount( + node, + AnnotationKind.CustomConstructor, + customConstructorAnnotation.args.length, + 1 + ) + ); } - - return lua.createCallExpression( - lua.createIdentifier(customConstructorAnnotation.args[0]), - transformArguments(context, node.arguments ?? []), - node - ); } return transformLuaLibFunction(context, LuaLibFeature.New, node, name, ...params); diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts index 3aec046a3..a4ffc5c75 100644 --- a/src/transformation/visitors/class/setup.ts +++ b/src/transformation/visitors/class/setup.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; +import { assert } from "../../../utils"; import { TransformationContext } from "../../context"; -import { UndefinedTypeNode } from "../../utils/errors"; import { createDefaultExportStringLiteral, createExportedIdentifier, @@ -63,10 +63,7 @@ export function createClassSetup( if (extendsType) { const extendedNode = getExtendedNode(context, statement); - if (extendedNode === undefined) { - throw UndefinedTypeNode(statement); - } - + assert(extendedNode); result.push( lua.createExpressionStatement( transformLuaLibFunction( diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 1d81a0e45..005c63a5b 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { isVarArgType } from "../utils/annotations"; -import { MissingFunctionName, UnsupportedFunctionWithoutBody } from "../utils/errors"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { @@ -183,7 +182,8 @@ export function transformFunctionLikeDeclaration( let flags = lua.FunctionExpressionFlags.None; if (node.body === undefined) { - throw UnsupportedFunctionWithoutBody(node); + // This code can be reached only from object methods, which is TypeScript error + return lua.createNilLiteral(); } let body: ts.Block; @@ -257,18 +257,16 @@ export const transformFunctionDeclaration: FunctionVisitor = (statement, context) => { if (isArrayType(context, context.checker.getTypeAtLocation(statement.expression))) { - throw ForbiddenForIn(statement); + context.diagnostics.push(forbiddenForIn(statement)); } // Transpile expression @@ -19,33 +17,6 @@ export const transformForInStatement: FunctionVisitor = (stat const body = lua.createBlock(transformLoopBody(context, statement)); - // Transform iteration variable - // TODO: After the transformation pipeline refactor we should look at refactoring this together with the - // for-of initializer transformation. - let iterationVariable: lua.Identifier; - if (ts.isVariableDeclarationList(statement.initializer)) { - const binding = getVariableDeclarationBinding(statement.initializer); - if (!ts.isIdentifier(binding)) { - throw UnsupportedForInVariable(statement.initializer); - } - - iterationVariable = transformIdentifier(context, binding); - } else if (ts.isIdentifier(statement.initializer)) { - // Iteration variable becomes ____key - iterationVariable = lua.createIdentifier("____key"); - // Push variable = ____key to the start of the loop body to match TS scoping - const assignment = transformAssignment( - context, - statement.initializer, - iterationVariable, - statement.initializer - ); - - body.statements.unshift(...assignment); - } else { - // This should never occur - throw UnsupportedForInVariable(statement.initializer); - } - - return lua.createForInStatement(body, [iterationVariable], [pairsCall], statement); + const valueVariable = transformForInitializer(context, statement.initializer, body); + return lua.createForInStatement(body, [valueVariable], [pairsCall], statement); }; diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 9c0596fb8..c682c042e 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -1,94 +1,65 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { castEach } from "../../../utils"; +import { assert, castEach } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { InvalidForRangeCall, MissingForOfVariables, UnsupportedNonDestructuringLuaIterator } from "../../utils/errors"; +import { invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { isArrayType, isNumberType, isAssignmentPattern } from "../../utils/typescript"; +import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; -import { - transformBindingPattern, - transformArrayBindingElement, - transformVariableDeclaration, -} from "../variable-declaration"; -import { getVariableDeclarationBinding, transformLoopBody } from "./utils"; -import { transformAssignment } from "../binary-expression/assignments"; -import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; - -function transformForOfInitializer( - context: TransformationContext, - initializer: ts.ForInitializer, - expression: lua.Identifier -): lua.Statement[] { - if (ts.isVariableDeclarationList(initializer)) { - const binding = getVariableDeclarationBinding(initializer); - // Declaration of new variable - if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { - return transformBindingPattern(context, binding, expression); - } - - const variableStatements = transformVariableDeclaration(context, initializer.declarations[0]); - if (variableStatements[0]) { - // we can safely assume that for vars are not exported and therefore declarationstatenents - return [ - lua.createVariableDeclarationStatement( - (variableStatements[0] as lua.VariableDeclarationStatement).left, - expression - ), - ]; - } else { - throw MissingForOfVariables(initializer); - } - } else { - // Assignment to existing variable(s) - - if (isAssignmentPattern(initializer)) { - return transformAssignmentPattern(context, initializer, expression); - } - - return transformAssignment(context, initializer, expression); - } -} +import { transformArrayBindingElement } from "../variable-declaration"; +import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; function transformForRangeStatement( context: TransformationContext, statement: ts.ForOfStatement, block: lua.Block ): lua.Statement { - if (!ts.isCallExpression(statement.expression)) { - throw InvalidForRangeCall(statement.expression, "Expression must be a call expression."); - } + assert(ts.isCallExpression(statement.expression)); - if (statement.expression.arguments.length < 2 || statement.expression.arguments.length > 3) { - throw InvalidForRangeCall(statement.expression, "@forRange function must take 2 or 3 arguments."); + const callArguments = statement.expression.arguments; + if (callArguments.length !== 2 && callArguments.length !== 3) { + context.diagnostics.push( + invalidForRangeCall(statement.expression, `Expected 2-3 arguments, but got ${callArguments.length}`) + ); } if (statement.expression.arguments.some(a => !isNumberType(context, context.checker.getTypeAtLocation(a)))) { - throw InvalidForRangeCall(statement.expression, "@forRange arguments must be number types."); + context.diagnostics.push(invalidForRangeCall(statement.expression, "arguments must be numbers")); } - if (!ts.isVariableDeclarationList(statement.initializer)) { - throw InvalidForRangeCall(statement.initializer, "@forRange loop must declare its own control variable."); - } + const controlVariable = getControlVariable() ?? lua.createAnonymousIdentifier(); + function getControlVariable(): lua.Identifier | undefined { + if (!ts.isVariableDeclarationList(statement.initializer)) { + context.diagnostics.push( + invalidForRangeCall(statement.initializer, "loop must declare it's own control variable") + ); + return; + } - const binding = getVariableDeclarationBinding(statement.initializer); - if (!ts.isIdentifier(binding)) { - throw InvalidForRangeCall(statement.initializer, "@forRange loop cannot use destructuring."); - } + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (!ts.isIdentifier(binding)) { + context.diagnostics.push(invalidForRangeCall(statement.initializer, "destructuring cannot be used")); + return; + } - if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { - throw InvalidForRangeCall( - statement.expression, - "@forRange function must return Iterable or Array." - ); + if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { + context.diagnostics.push( + invalidForRangeCall(statement.expression, "function must return Iterable") + ); + } + + return transformIdentifier(context, binding); } - const control = transformIdentifier(context, binding); - const signature = context.checker.getResolvedSignature(statement.expression); - const [start, limit, step] = transformArguments(context, statement.expression.arguments, signature); - return lua.createForStatement(block, control, start, limit, step, statement); + const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( + context, + callArguments, + context.checker.getResolvedSignature(statement.expression) + ); + + return lua.createForStatement(block, controlVariable, start, limit, step, statement); } function transformForOfLuaIteratorStatement( @@ -99,72 +70,51 @@ function transformForOfLuaIteratorStatement( const luaIterator = context.transformExpression(statement.expression); const type = context.checker.getTypeAtLocation(statement.expression); const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); + let identifiers: lua.Identifier[] = []; + if (tupleReturn) { // LuaIterator + TupleReturn if (ts.isVariableDeclarationList(statement.initializer)) { // Variables declared in for loop // for ${initializer} in ${iterable} do - const binding = getVariableDeclarationBinding(statement.initializer); + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (ts.isArrayBindingPattern(binding)) { - const identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); - if (identifiers.length === 0) { - identifiers.push(lua.createAnonymousIdentifier()); - } - return lua.createForInStatement(block, identifiers, [luaIterator]); + identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); } else { - // Single variable is not allowed - throw UnsupportedNonDestructuringLuaIterator(statement.initializer); + context.diagnostics.push(luaIteratorForbiddenUsage(binding)); } } else { // Variables NOT declared in for loop - catch iterator values in temps and assign // for ____value0 in ${iterable} do // ${initializer} = ____value0 if (ts.isArrayLiteralExpression(statement.initializer)) { - const tmps = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); - if (tmps.length > 0) { - const assign = lua.createAssignmentStatement( - castEach( - statement.initializer.elements.map(e => context.transformExpression(e)), - lua.isAssignmentLeftHandSideExpression - ), - tmps + identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + castEach( + statement.initializer.elements.map(e => context.transformExpression(e)), + lua.isAssignmentLeftHandSideExpression + ), + identifiers + ) ); - block.statements.splice(0, 0, assign); - } else { - tmps.push(lua.createAnonymousIdentifier()); } - return lua.createForInStatement(block, tmps, [luaIterator]); } else { - // Single variable is not allowed - throw UnsupportedNonDestructuringLuaIterator(statement.initializer); + context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); } } } else { // LuaIterator (no TupleReturn) - if ( - ts.isVariableDeclarationList(statement.initializer) && - statement.initializer.declarations.length > 0 && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - // Single variable declared in for loop - // for ${initializer} in ${iterator} do - return lua.createForInStatement( - block, - [transformIdentifier(context, statement.initializer.declarations[0].name)], - [luaIterator] - ); - } else { - // Destructuring or variable NOT declared in for loop - // for ____value in ${iterator} do - // local ${initializer} = unpack(____value) - const valueVariable = lua.createIdentifier("____value"); - const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); - if (initializer) { - block.statements.splice(0, 0, ...initializer); - } - return lua.createForInStatement(block, [valueVariable], [luaIterator]); - } + identifiers.push(transformForInitializer(context, statement.initializer, block)); + } + + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); } + + return lua.createForInStatement(block, identifiers, [luaIterator], statement); } function transformForOfArrayStatement( @@ -172,28 +122,7 @@ function transformForOfArrayStatement( statement: ts.ForOfStatement, block: lua.Block ): lua.Statement { - let valueVariable: lua.Identifier; - if (ts.isVariableDeclarationList(statement.initializer)) { - // Declaration of new variable - const binding = getVariableDeclarationBinding(statement.initializer); - if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { - valueVariable = lua.createIdentifier("____values"); - const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); - if (initializer) { - block.statements.unshift(...initializer); - } - } else { - valueVariable = transformIdentifier(context, binding); - } - } else { - // Assignment to existing variable - valueVariable = lua.createIdentifier("____value"); - const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); - if (initializer) { - block.statements.unshift(...initializer); - } - } - + const valueVariable = transformForInitializer(context, statement.initializer, block); const ipairsCall = lua.createCallExpression(lua.createIdentifier("ipairs"), [ context.transformExpression(statement.expression), ]); @@ -206,35 +135,15 @@ function transformForOfIteratorStatement( statement: ts.ForOfStatement, block: lua.Block ): lua.Statement { - const iterable = context.transformExpression(statement.expression); - if ( - ts.isVariableDeclarationList(statement.initializer) && - statement.initializer.declarations.length > 0 && - ts.isIdentifier(statement.initializer.declarations[0].name) - ) { - // Single variable declared in for loop - // for ${initializer} in __TS__iterator(${iterator}) do - return lua.createForInStatement( - block, - [transformIdentifier(context, statement.initializer.declarations[0].name)], - [transformLuaLibFunction(context, LuaLibFeature.Iterator, statement.expression, iterable)] - ); - } else { - // Destructuring or variable NOT declared in for loop - // for ____value in __TS__iterator(${iterator}) do - // local ${initializer} = ____value - const valueVariable = lua.createIdentifier("____value"); - const initializer = transformForOfInitializer(context, statement.initializer, valueVariable); - if (initializer) { - block.statements.unshift(...initializer); - } - - return lua.createForInStatement( - block, - [valueVariable], - [transformLuaLibFunction(context, LuaLibFeature.Iterator, statement.expression, iterable)] - ); - } + const valueVariable = transformForInitializer(context, statement.initializer, block); + const iterable = transformLuaLibFunction( + context, + LuaLibFeature.Iterator, + statement.expression, + context.transformExpression(statement.expression) + ); + + return lua.createForInStatement(block, [valueVariable], [iterable], statement); } export const transformForOfStatement: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 970c2f045..f81a62199 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -9,7 +9,7 @@ export const transformForStatement: FunctionVisitor = (statemen if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { - checkVariableDeclarationList(statement.initializer); + checkVariableDeclarationList(context, statement.initializer); // local initializer = value result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 639c0de95..8ee86f4ea 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -2,8 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { performHoisting, popScope, pushScope, ScopeType } from "../../utils/scope"; +import { isAssignmentPattern } from "../../utils/typescript"; +import { transformAssignment } from "../binary-expression/assignments"; +import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; import { transformBlockOrStatement } from "../block"; -import { checkVariableDeclarationList } from "../variable-declaration"; +import { transformIdentifier } from "../identifier"; +import { checkVariableDeclarationList, transformBindingPattern } from "../variable-declaration"; export function transformLoopBody( context: TransformationContext, @@ -25,8 +29,11 @@ export function transformLoopBody( return baseResult; } -export function getVariableDeclarationBinding(node: ts.VariableDeclarationList): ts.BindingName { - checkVariableDeclarationList(node); +export function getVariableDeclarationBinding( + context: TransformationContext, + node: ts.VariableDeclarationList +): ts.BindingName { + checkVariableDeclarationList(context, node); if (node.declarations.length === 0) { return ts.createIdentifier("____"); @@ -34,3 +41,33 @@ export function getVariableDeclarationBinding(node: ts.VariableDeclarationList): return node.declarations[0].name; } + +export function transformForInitializer( + context: TransformationContext, + initializer: ts.ForInitializer, + block: lua.Block +): lua.Identifier { + const valueVariable = lua.createIdentifier("____value"); + + if (ts.isVariableDeclarationList(initializer)) { + // Declaration of new variable + + const binding = getVariableDeclarationBinding(context, initializer); + if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { + block.statements.unshift(...transformBindingPattern(context, binding, valueVariable)); + } else { + // Single variable declared in for loop + return transformIdentifier(context, binding); + } + } else { + // Assignment to existing variable(s) + + block.statements.unshift( + ...(isAssignmentPattern(initializer) + ? transformAssignmentPattern(context, initializer, valueVariable) + : transformAssignment(context, initializer, valueVariable)) + ); + } + + return valueVariable; +} diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts index 471dba4e3..7647921c3 100644 --- a/src/transformation/visitors/lua-table.ts +++ b/src/transformation/visitors/lua-table.ts @@ -2,46 +2,58 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { ForbiddenLuaTableUseException, UnsupportedKind, UnsupportedProperty } from "../utils/errors"; +import { luaTableCannotBeAccessedDynamically, luaTableForbiddenUsage, unsupportedProperty } from "../utils/diagnostics"; import { transformArguments } from "./call"; -function parseLuaTableExpression( - context: TransformationContext, - node: ts.LeftHandSideExpression -): [lua.Expression, string] { - if (ts.isPropertyAccessExpression(node)) { - return [context.transformExpression(node.expression), node.name.text]; - } else { - throw UnsupportedKind("LuaTable access expression", node.kind, node); - } -} +const parseLuaTableExpression = (context: TransformationContext, node: ts.PropertyAccessExpression) => + [context.transformExpression(node.expression), node.name.text] as const; -function validateLuaTableCall(methodName: string, callArguments: ts.NodeArray, original: ts.Node): void { - if (callArguments.some(argument => ts.isSpreadElement(argument))) { - throw ForbiddenLuaTableUseException("Arguments cannot be spread.", original); +function validateLuaTableCall( + context: TransformationContext, + node: ts.Node, + methodName: string, + callArguments: ts.NodeArray +): void { + for (const argument of callArguments) { + if (ts.isSpreadElement(argument)) { + context.diagnostics.push(luaTableForbiddenUsage(argument, "Arguments cannot be spread")); + return; + } } switch (methodName) { case "get": if (callArguments.length !== 1) { - throw ForbiddenLuaTableUseException("One parameter is required for get().", original); + context.diagnostics.push( + luaTableForbiddenUsage(node, `Expected 1 arguments, but got ${callArguments.length}`) + ); } break; case "set": if (callArguments.length !== 2) { - throw ForbiddenLuaTableUseException("Two parameters are required for set().", original); + context.diagnostics.push( + luaTableForbiddenUsage(node, `Expected 2 arguments, but got ${callArguments.length}`) + ); } break; } } -function transformLuaTableExpressionAsExpressionStatement( +export function transformLuaTableExpressionStatement( context: TransformationContext, - expression: ts.CallExpression -): lua.Statement { + node: ts.ExpressionStatement +): lua.Statement | undefined { + const expression = ts.isExpressionStatement(node) ? node.expression : node; + + if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return; + + const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); + const annotations = getTypeAnnotations(ownerType); + if (!annotations.has(AnnotationKind.LuaTable)) return; + const [luaTable, methodName] = parseLuaTableExpression(context, expression.expression); - validateLuaTableCall(methodName, expression.arguments, expression); + validateLuaTableCall(context, expression, methodName, expression.arguments); const signature = context.checker.getResolvedSignature(expression); const params = transformArguments(context, expression.arguments, signature); @@ -49,83 +61,83 @@ function transformLuaTableExpressionAsExpressionStatement( case "get": return lua.createVariableDeclarationStatement( lua.createAnonymousIdentifier(expression), - lua.createTableIndexExpression(luaTable, params[0], expression), + lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), expression ); case "set": return lua.createAssignmentStatement( - lua.createTableIndexExpression(luaTable, params[0], expression), - params.splice(1), + lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), + [params[1] ?? lua.createNilLiteral()], expression ); default: - throw UnsupportedProperty("LuaTable", methodName, expression); + context.diagnostics.push(unsupportedProperty(expression.expression.name, "LuaTable", methodName)); } } -export function transformLuaTableExpressionStatement( +export function transformLuaTableCallExpression( context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; + node: ts.CallExpression +): lua.Expression | undefined { + if (!ts.isPropertyAccessExpression(node.expression)) return; - if (ts.isCallExpression(expression) && ts.isPropertyAccessExpression(expression.expression)) { - const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (annotations.has(AnnotationKind.LuaTable)) { - return transformLuaTableExpressionAsExpressionStatement(context, expression); - } + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const annotations = getTypeAnnotations(ownerType); + if (!annotations.has(AnnotationKind.LuaTable)) return; + + const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); + validateLuaTableCall(context, node, methodName, node.arguments); + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + switch (methodName) { + case "get": + return lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), node); + default: + context.diagnostics.push(unsupportedProperty(node.expression.name, "LuaTable", methodName)); } } -export function transformLuaTableCallExpression( +export function transformLuaTablePropertyAccessExpression( context: TransformationContext, - node: ts.CallExpression + node: ts.PropertyAccessExpression ): lua.Expression | undefined { - if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); - const annotations = getTypeAnnotations(ownerType); - - if (annotations.has(AnnotationKind.LuaTable)) { - const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); - validateLuaTableCall(methodName, node.arguments, node); - const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - - switch (methodName) { - case "get": - return lua.createTableIndexExpression(luaTable, params[0], node); - default: - throw UnsupportedProperty("LuaTable", methodName, node); - } - } + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); + if (!annotations.has(AnnotationKind.LuaTable)) return; + + const [luaTable, propertyName] = parseLuaTableExpression(context, node); + if (propertyName === "length") { + return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); } + + context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); } -export function transformLuaTablePropertyAccessExpression( +export function transformLuaTablePropertyAccessInAssignment( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.Expression | undefined { - const type = context.checker.getTypeAtLocation(node.expression); - const annotations = getTypeAnnotations(type); - if (annotations.has(AnnotationKind.LuaTable)) { - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - switch (node.name.text) { - case "length": - return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); - default: - throw UnsupportedProperty("LuaTable", propertyName, node); - } +): lua.AssignmentLeftHandSideExpression | undefined { + if (!ts.isPropertyAccessExpression(node)) return; + + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); + if (!annotations.has(AnnotationKind.LuaTable)) return; + + const [luaTable, propertyName] = parseLuaTableExpression(context, node); + if (propertyName === "length") { + context.diagnostics.push(luaTableForbiddenUsage(node, `A LuaTable object's length cannot be re-assigned`)); + return lua.createTableIndexExpression(luaTable, lua.createStringLiteral(propertyName), node); } + + context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); } -export function transformLuaTableElementAccessExpression( +export function validateLuaTableElementAccessExpression( context: TransformationContext, node: ts.ElementAccessExpression ): void { const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); if (annotations.has(AnnotationKind.LuaTable)) { - throw UnsupportedKind("LuaTable access expression", node.kind, node); + context.diagnostics.push(luaTableCannotBeAccessedDynamically(node)); } } @@ -133,13 +145,14 @@ export function transformLuaTableNewExpression( context: TransformationContext, node: ts.NewExpression ): lua.Expression | undefined { - const type = context.checker.getTypeAtLocation(node); - const annotations = getTypeAnnotations(type); - if (annotations.has(AnnotationKind.LuaTable)) { - if (node.arguments && node.arguments.length > 0) { - throw ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", node); - } else { - return lua.createTableExpression(); - } + const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); + if (!annotations.has(AnnotationKind.LuaTable)) return; + + if (node.arguments && node.arguments.length > 0) { + context.diagnostics.push( + luaTableForbiddenUsage(node, "No parameters are allowed when constructing a LuaTable object") + ); } + + return lua.createTableExpression(); } diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index c6b83fcde..5e12c6c5e 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; +import { assert } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { InvalidExportDeclaration } from "../../utils/errors"; import { createDefaultExportIdentifier, createDefaultExportStringLiteral, @@ -37,9 +37,7 @@ export const transformExportAssignment: FunctionVisitor = ( }; function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { - if (node.moduleSpecifier === undefined) { - throw InvalidExportDeclaration(node); - } + assert(node.moduleSpecifier); if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { return undefined; diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 088fac7d2..089f0949f 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -4,20 +4,22 @@ import * as lua from "../../../LuaAST"; import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getSymbolAnnotations, getTypeAnnotations } from "../../utils/annotations"; -import { UnresolvableRequirePath } from "../../utils/errors"; import { createDefaultExportStringLiteral } from "../../utils/export"; import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; +import { unresolvableRequirePath } from "../../utils/diagnostics"; const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => relativePath[0] !== "." && options.baseUrl ? path.resolve(options.baseUrl, relativePath) : path.resolve(directoryPath, relativePath); -function getImportPath(fileName: string, relativePath: string, node: ts.Node, options: ts.CompilerOptions): string { +function getImportPath(context: TransformationContext, relativePath: string, node: ts.Node): string { + const fileName = context.sourceFile.fileName; + const options = context.options; const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); const absoluteImportPath = path.format( @@ -27,11 +29,8 @@ function getImportPath(fileName: string, relativePath: string, node: ts.Node, op if (absoluteImportPath.includes(absoluteRootDirPath)) { return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); } else { - throw UnresolvableRequirePath( - node, - `Cannot create require path. Module does not exist within --rootDir`, - relativePath - ); + context.diagnostics.push(unresolvableRequirePath(node, relativePath)); + return relativePath; } } @@ -51,12 +50,7 @@ export function createModuleRequire( const params: lua.Expression[] = []; if (ts.isStringLiteral(moduleSpecifier)) { const modulePath = shouldResolveModulePath(context, moduleSpecifier) - ? getImportPath( - context.sourceFile.fileName, - moduleSpecifier.text.replace(/"/g, ""), - moduleSpecifier, - context.options - ) + ? getImportPath(context, moduleSpecifier.text.replace(/"/g, ""), moduleSpecifier) : moduleSpecifier.text; params.push(lua.createStringLiteral(modulePath)); diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 064b5200f..539c9f9d7 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; +import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; -import { InvalidJsonFileContent } from "../utils/errors"; import { createExportsIdentifier } from "../utils/lua-ast"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; @@ -10,11 +10,16 @@ export const transformSourceFileNode: FunctionVisitor = (node, co let statements: lua.Statement[] = []; if (node.flags & ts.NodeFlags.JsonFile) { const [statement] = node.statements; - if (!statement || !ts.isExpressionStatement(statement)) { - throw InvalidJsonFileContent(node); - } + if (statement) { + assert(ts.isExpressionStatement(statement)); + statements.push(lua.createReturnStatement([context.transformExpression(statement.expression)])); + } else { + const errorCall = lua.createCallExpression(lua.createIdentifier("error"), [ + lua.createStringLiteral("Unexpected end of JSON input"), + ]); - statements.push(lua.createReturnStatement([context.transformExpression(statement.expression)])); + statements.push(lua.createExpressionStatement(errorCall)); + } } else { pushScope(context, ScopeType.File); statements = performHoisting(context, context.transformStatements(node.statements)); diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 941d8182d..880f449bd 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -2,12 +2,12 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { UnsupportedForTarget } from "../utils/errors"; +import { unsupportedForTarget } from "../utils/diagnostics"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { if (context.luaTarget === LuaTarget.Lua51) { - throw UnsupportedForTarget("Switch statements", LuaTarget.Lua51, statement); + context.diagnostics.push(unsupportedForTarget(statement, "Switch statements", LuaTarget.Lua51)); } const scope = pushScope(context, ScopeType.Switch); diff --git a/src/transformation/visitors/typeof.ts b/src/transformation/visitors/typeof.ts index 585746ca4..60eef310c 100644 --- a/src/transformation/visitors/typeof.ts +++ b/src/transformation/visitors/typeof.ts @@ -15,37 +15,37 @@ export function transformTypeOfBinaryExpression( node: ts.BinaryExpression ): lua.Expression | undefined { const operator = node.operatorToken.kind; - function transformTypeOfLiteralComparison( - typeOfExpression: ts.TypeOfExpression, - comparedExpression: lua.StringLiteral - ): lua.Expression { - if (comparedExpression.value === "object") { - comparedExpression.value = "table"; - } else if (comparedExpression.value === "undefined") { - comparedExpression.value = "nil"; - } + if ( + operator !== ts.SyntaxKind.EqualsEqualsToken && + operator !== ts.SyntaxKind.EqualsEqualsEqualsToken && + operator !== ts.SyntaxKind.ExclamationEqualsToken && + operator !== ts.SyntaxKind.ExclamationEqualsEqualsToken + ) { + return; + } - const innerExpression = context.transformExpression(typeOfExpression.expression); - const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression); - return transformBinaryOperation(context, typeCall, comparedExpression, operator, node); + let literalExpression: ts.Expression; + let typeOfExpression: ts.TypeOfExpression; + if (ts.isTypeOfExpression(node.left)) { + typeOfExpression = node.left; + literalExpression = node.right; + } else if (ts.isTypeOfExpression(node.right)) { + typeOfExpression = node.right; + literalExpression = node.left; + } else { + return; } - if ( - operator === ts.SyntaxKind.EqualsEqualsToken || - operator === ts.SyntaxKind.EqualsEqualsEqualsToken || - operator === ts.SyntaxKind.ExclamationEqualsToken || - operator === ts.SyntaxKind.ExclamationEqualsEqualsToken - ) { - if (ts.isTypeOfExpression(node.left)) { - const right = context.transformExpression(node.right); - if (lua.isStringLiteral(right)) { - return transformTypeOfLiteralComparison(node.left, right); - } - } else if (ts.isTypeOfExpression(node.right)) { - const left = context.transformExpression(node.left); - if (lua.isStringLiteral(left)) { - return transformTypeOfLiteralComparison(node.right, left); - } - } + const comparedExpression = context.transformExpression(literalExpression); + if (!lua.isStringLiteral(comparedExpression)) return; + + if (comparedExpression.value === "object") { + comparedExpression.value = "table"; + } else if (comparedExpression.value === "undefined") { + comparedExpression.value = "nil"; } + + const innerExpression = context.transformExpression(typeOfExpression.expression); + const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression); + return transformBinaryOperation(context, typeCall, comparedExpression, operator, node); } diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index cf0d44312..76b0e4941 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; +import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { UnsupportedKind } from "../utils/errors"; import { transformUnaryBitOperation } from "./binary-expression/bit"; import { transformCompoundAssignmentExpression, @@ -66,7 +66,7 @@ export const transformPostfixUnaryExpression: FunctionVisitor; @@ -229,13 +235,15 @@ export function transformVariableDeclaration( } } -export function checkVariableDeclarationList(node: ts.VariableDeclarationList): void { +export function checkVariableDeclarationList(context: TransformationContext, node: ts.VariableDeclarationList): void { if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) === 0) { - throw UnsupportedVarDeclaration(node); + const token = node.getFirstToken(); + assert(token); + context.diagnostics.push(unsupportedVarDeclaration(token)); } } export const transformVariableStatement: FunctionVisitor = (node, context) => { - checkVariableDeclarationList(node.declarationList); + checkVariableDeclarationList(context, node.declarationList); return node.declarationList.declarations.flatMap(declaration => transformVariableDeclaration(context, declaration)); }; diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 7c587055c..c60a5b7cc 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -5,7 +5,7 @@ import { CompilerOptions } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { escapeString } from "../LuaPrinter"; import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; -import { couldNotFindBundleEntryPoint } from "./diagnostics"; +import * as diagnosticFactories from "./diagnostics"; import { EmitHost, TranspiledFile } from "./transpile"; const createModulePath = (baseDir: string, pathToResolve: string) => @@ -33,7 +33,7 @@ export function bundleTranspiledFiles( // Resolve source files relative to common source directory. const sourceRootDir = program.getCommonSourceDirectory(); if (!transpiledFiles.some(f => path.resolve(sourceRootDir, f.fileName) === resolvedEntryModule)) { - return [[couldNotFindBundleEntryPoint(entryModule)], { fileName: bundleFile }]; + return [[diagnosticFactories.couldNotFindBundleEntryPoint(entryModule)], { fileName: bundleFile }]; } // For each file: [""] = function() end, diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 3383c3cfd..9467bb606 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -1,51 +1,38 @@ import * as ts from "typescript"; +import { createSerialDiagnosticFactory } from "../utils"; -export const toLoadTransformerItShouldBeTranspiled = (transform: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: `To load "${transform}" transformer it should be transpiled or "ts-node" should be installed`, -}); - -export const couldNotResolveTransformerFrom = (transform: string, base: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: `Could not resolve "${transform}" transformer from "${base}".`, -}); - -export const transformerShouldHaveAExport = (transform: string, importName: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: `"${transform}" transformer should have a "${importName}" export`, -}); - -export const transformerShouldBeATsTransformerFactory = (transform: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: `"${transform}" transformer should be a ts.TransformerFactory or an object with ts.TransformerFactory values`, -}); - -export const couldNotFindBundleEntryPoint = (entryPoint: string): ts.Diagnostic => ({ - file: undefined, - start: undefined, - length: undefined, - category: ts.DiagnosticCategory.Error, - code: 0, - source: "typescript-to-lua", - messageText: `Could not find bundle entry point '${entryPoint}'. It should be a file in the project.`, -}); +const createDiagnosticFactory = (getMessage: (...args: TArgs) => string) => + createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args) })); + +export const toLoadTransformerItShouldBeTranspiled = createDiagnosticFactory( + (transform: string) => + `To load "${transform}" transformer it should be transpiled or "ts-node" should be installed.` +); + +export const couldNotResolveTransformerFrom = createDiagnosticFactory( + (transform: string, base: string) => `Could not resolve "${transform}" transformer from "${base}".` +); + +export const transformerShouldHaveAExport = createDiagnosticFactory( + (transform: string, importName: string) => `"${transform}" transformer should have a "${importName}" export.` +); + +export const transformerShouldBeATsTransformerFactory = createDiagnosticFactory( + (transform: string) => + `"${transform}" transformer should be a ts.TransformerFactory or an object with ts.TransformerFactory values.` +); + +export const couldNotFindBundleEntryPoint = createDiagnosticFactory( + (entryPoint: string) => `Could not find bundle entry point '${entryPoint}'. It should be a file in the project.` +); + +export const luaBundleEntryIsRequired = createDiagnosticFactory( + () => "'luaBundleEntry' is required when 'luaBundle' is enabled." +); + +export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDiagnosticFactory(() => ({ + category: ts.DiagnosticCategory.Warning, + messageText: + `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + + `It is recommended to use 'luaLibImport: "require"'.`, +})); diff --git a/src/utils.ts b/src/utils.ts index 6baad413a..822c5df3a 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,5 +1,34 @@ +import * as ts from "typescript"; +import * as nativeAssert from "assert"; import * as path from "path"; +export const createDiagnosticFactoryWithCode = < + T extends (...args: any) => Partial & Pick +>( + code: number, + create: T +) => { + return Object.assign( + (...args: Parameters): ts.Diagnostic => ({ + file: undefined, + start: undefined, + length: undefined, + category: ts.DiagnosticCategory.Error, + code, + source: "typescript-to-lua", + ...create(...(args as any)), + }), + { code } + ); +}; + +let serialDiagnosticCodeCounter = 100000; +export const createSerialDiagnosticFactory = < + T extends (...args: any) => Partial & Pick +>( + create: T +) => createDiagnosticFactoryWithCode(serialDiagnosticCodeCounter++, create); + export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); export const trimExtension = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); @@ -52,6 +81,10 @@ export function castEach( } } +export function assert(value: any, message?: string | Error): asserts value { + nativeAssert(value, message); +} + export function assertNever(_value: never): never { throw new Error("Value is expected to be never"); } diff --git a/test/setup.ts b/test/setup.ts index 8305ec264..ebaa4e2fd 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,54 +1,43 @@ import * as ts from "typescript"; -import * as util from "./util"; +import * as tstl from "../src"; declare global { namespace jest { interface Matchers { - toThrowExactError(error: Error): R; - toHaveDiagnostics(): R; + toHaveDiagnostics(expected?: number[]): R; } } } expect.extend({ - toThrowExactError(callback: () => void, error: Error): jest.CustomMatcherResult { - if (this.isNot) { - return { pass: true, message: () => "Inverted toThrowExactError is not implemented" }; - } - - let executionError: Error | undefined; - try { - callback(); - } catch (err) { - executionError = err; - } - - // TODO: - if (util.expectToBeDefined(executionError)) { - expect(executionError.message).toContain(error.message); - } - - return { pass: true, message: () => "" }; - }, - toHaveDiagnostics(diagnostics: ts.Diagnostic[]): jest.CustomMatcherResult { + toHaveDiagnostics(diagnostics: ts.Diagnostic[], expected?: number[]): jest.CustomMatcherResult { expect(diagnostics).toBeInstanceOf(Array); // @ts-ignore const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", this); - const diagnosticMessages = ts.formatDiagnosticsWithColorAndContext(diagnostics, { - getCurrentDirectory: () => "", - getCanonicalFileName: fileName => fileName, - getNewLine: () => "\n", - }); + const diagnosticMessages = ts.formatDiagnosticsWithColorAndContext( + diagnostics.map(tstl.prepareDiagnosticForFormatting), + { getCurrentDirectory: () => "", getCanonicalFileName: fileName => fileName, getNewLine: () => "\n" } + ); + + if (this.isNot && expected !== undefined) { + throw new Error(`expect(actual).not.toHaveDiagnostics(expected) is not supported`); + } return { - pass: diagnostics.length > 0, + pass: expected + ? diagnostics.length === expected.length && + diagnostics.every((diag, index) => diag.code === expected[index]) + : diagnostics.length > 0, + message: () => { - return ( - matcherHint + - "\n\n" + - (this.isNot ? diagnosticMessages : `Received: ${this.utils.printReceived(diagnostics)}\n`) - ); + const message = this.isNot + ? diagnosticMessages + : expected + ? `Expected:\n${expected.join("\n")}\nReceived:\n${diagnostics.map(diag => diag.code).join("\n")}\n` + : `Received: ${this.utils.printReceived([])}\n`; + + return matcherHint + "\n\n" + message; }, }; }, diff --git a/test/unit/__snapshots__/assignments.spec.ts.snap b/test/unit/__snapshots__/assignments.spec.ts.snap new file mode 100644 index 000000000..6f9f553ff --- /dev/null +++ b/test/unit/__snapshots__/assignments.spec.ts.snap @@ -0,0 +1,47 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`var declaration in for loop is disallowed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + do + local foo = 0 + while true do + end + end +end +return ____exports" +`; + +exports[`var declaration in for loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; + +exports[`var declaration in for...in loop is disallowed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for foo in pairs({}) do + end +end +return ____exports" +`; + +exports[`var declaration in for...in loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; + +exports[`var declaration in for...of loop is disallowed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for ____, foo in ipairs({}) do + end +end +return ____exports" +`; + +exports[`var declaration in for...of loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; + +exports[`var declaration is disallowed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local foo = true +end +return ____exports" +`; + +exports[`var declaration is disallowed: diagnostics 1`] = `"main.ts(2,9): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap new file mode 100644 index 000000000..84c10f3d5 --- /dev/null +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -0,0 +1,7 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; + +exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; + +exports[`no entry point: diagnostics 1`] = `"error TSTL: 'luaBundleEntry' is required when 'luaBundle' is enabled."`; diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/conditionals.spec.ts.snap index e1c59f48f..e7d003fa5 100644 --- a/test/unit/__snapshots__/conditionals.spec.ts.snap +++ b/test/unit/__snapshots__/conditionals.spec.ts.snap @@ -39,3 +39,15 @@ function ____exports.__main(self) end return ____exports" `; + +exports[`switch not allowed in 5.1: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____switch3 = \\"abc\\" + goto ____switch3_end + ::____switch3_end:: +end +return ____exports" +`; + +exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 7095c91a8..fd53ab8ac 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -36,6 +36,128 @@ ____exports.__result = 10 - (4 + 5) return ____exports" `; +exports[`Bitop [5.1] ("~a"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bnot(a) +return ____exports" +`; + +exports[`Bitop [5.1] ("~a"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a&=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.band(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a&=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a&b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.band(a, b) +return ____exports" +`; + +exports[`Bitop [5.1] ("a&b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a<<=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.lshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a<<=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a<>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.arshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a>>>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.rshift(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a>>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a>>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.rshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.1] ("a>>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.arshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.1] ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a^=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.bxor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a^=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a^b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bxor(a, b) +return ____exports" +`; + +exports[`Bitop [5.1] ("a^b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a|=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = bit.bor(a, b) + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.1] ("a|=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`Bitop [5.1] ("a|b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bor(a, b) +return ____exports" +`; + +exports[`Bitop [5.1] ("a|b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.1."`; + exports[`Bitop [5.2] ("~a") 1`] = ` "local ____exports = {} ____exports.__result = bit32.bnot(a) @@ -402,3 +524,22 @@ function ____exports.__main(self) end return ____exports" `; + +exports[`Unsupported bitop 5.3 ("a>>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Unsupported bitop 5.3 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.3 ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap new file mode 100644 index 000000000..6ab8a4433 --- /dev/null +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -0,0 +1,241 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ambient identifier cannot be a lua keyword ("class local {}"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("class local {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("const foo: any, bar: any, local: any;"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("const foo: any, bar: any, local: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("const local: any;"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("const local: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("enum local {}"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("enum local {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("function local() {}"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("function local() {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("let local: any;"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("let local: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("module local { export const bar: any; }"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("module local { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("namespace local { export const bar: any; }"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("namespace local { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier cannot be a lua keyword ("var local: any;"): code 1`] = `"local ____ = ____local"`; + +exports[`ambient identifier cannot be a lua keyword ("var local: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("class $$ {}"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("class $$ {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("const $$: any;"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("const $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("const foo: any, bar: any, $$: any;"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("const foo: any, bar: any, $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("enum $$ {}"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("enum $$ {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("function $$();"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("function $$();"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("let $$: any;"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("let $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("module $$ { export const bar: any; }"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("module $$ { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("namespace $$ { export const bar: any; }"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("namespace $$ { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): code 1`] = `"local ____ = _____24_24_24"`; + +exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; + +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("$$"): code 1`] = `"foo = _____24_24_24"`; + +exports[`undeclared identifier must be a valid lua identifier ("$$"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("_̀ः٠‿"): code 1`] = `"foo = ______300_903_660_203F"`; + +exports[`undeclared identifier must be a valid lua identifier ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("and"): code 1`] = `"foo = ____and"`; + +exports[`undeclared identifier must be a valid lua identifier ("and"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("elseif"): code 1`] = `"foo = ____elseif"`; + +exports[`undeclared identifier must be a valid lua identifier ("elseif"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("end"): code 1`] = `"foo = ____end"`; + +exports[`undeclared identifier must be a valid lua identifier ("end"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("goto"): code 1`] = `"foo = ____goto"`; + +exports[`undeclared identifier must be a valid lua identifier ("goto"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("local"): code 1`] = `"foo = ____local"`; + +exports[`undeclared identifier must be a valid lua identifier ("local"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("nil"): code 1`] = `"foo = ____nil"`; + +exports[`undeclared identifier must be a valid lua identifier ("nil"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("not"): code 1`] = `"foo = ____not"`; + +exports[`undeclared identifier must be a valid lua identifier ("not"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("or"): code 1`] = `"foo = ____or"`; + +exports[`undeclared identifier must be a valid lua identifier ("or"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("repeat"): code 1`] = `"foo = ____repeat"`; + +exports[`undeclared identifier must be a valid lua identifier ("repeat"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("then"): code 1`] = `"foo = ____then"`; + +exports[`undeclared identifier must be a valid lua identifier ("then"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("until"): code 1`] = `"foo = ____until"`; + +exports[`undeclared identifier must be a valid lua identifier ("until"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = _____265_263_24E_24C_37C_19B_CA0"`; + +exports[`undeclared identifier must be a valid lua identifier ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; + +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap new file mode 100644 index 000000000..f1daffe65 --- /dev/null +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -0,0 +1,72 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`forin[Array]: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local array = {} + for key in pairs(array) do + end +end +return ____exports" +`; + +exports[`forin[Array]: diagnostics 1`] = `"main.ts(3,9): error TSTL: Iterating over arrays with 'for ... in' is not allowed."`; + +exports[`loop continue (do { continue; } while (false)) [5.1]: code 1`] = ` +"repeat + do + do + goto __continue2 + end + ::__continue2:: + end +until not false" +`; + +exports[`loop continue (do { continue; } while (false)) [5.1]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + +exports[`loop continue (for (;;) { continue; }) [5.1]: code 1`] = ` +"do + while true do + do + goto __continue2 + end + ::__continue2:: + end +end" +`; + +exports[`loop continue (for (;;) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + +exports[`loop continue (for (const a in {}) { continue; }) [5.1]: code 1`] = ` +"for a in pairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a in {}) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + +exports[`loop continue (for (const a of []) { continue; }) [5.1]: code 1`] = ` +"for ____, a in ipairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a of []) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + +exports[`loop continue (while (false) { continue; }) [5.1]: code 1`] = ` +"while false do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (while (false) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; diff --git a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap new file mode 100644 index 000000000..c283485bf --- /dev/null +++ b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`IncorrectUsage: code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local Point2D = __TS__Class() + Point2D.name = \\"Point2D\\" + function Point2D.prototype.____constructor(self) + end + __TS__New(Point2D) +end +return ____exports" +`; + +exports[`IncorrectUsage: diagnostics 1`] = `"main.ts(5,9): error TSTL: '@customConstructor' expects 1 arguments, but got 0."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap new file mode 100644 index 000000000..f69a1315a --- /dev/null +++ b/test/unit/annotations/__snapshots__/extension.spec.ts.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Class construct extension ("extension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +b = __TS__New(B)" +`; + +exports[`Class construct extension ("extension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; + +exports[`Class construct extension ("metaExtension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local __meta__A = debug.getregistry().A +b = __TS__New(B)" +`; + +exports[`Class construct extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; + +exports[`Class extends extension ("extension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +C = __TS__Class() +C.name = \\"C\\" +__TS__ClassExtends(C, B)" +`; + +exports[`Class extends extension ("extension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; + +exports[`Class extends extension ("metaExtension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local __meta__A = debug.getregistry().A +C = __TS__Class() +C.name = \\"C\\" +__TS__ClassExtends(C, B)" +`; + +exports[`Class extends extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; + +exports[`instanceof extension ("extension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +result = __TS__InstanceOf(foo, B)" +`; + +exports[`instanceof extension ("extension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; + +exports[`instanceof extension ("metaExtension"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local __meta__A = debug.getregistry().A +result = __TS__InstanceOf(foo, B)" +`; + +exports[`instanceof extension ("metaExtension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; diff --git a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap new file mode 100644 index 000000000..325c32be7 --- /dev/null +++ b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap @@ -0,0 +1,92 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid usage argument count ([]): code 1`] = ` +"for i = 0, 0 do +end" +`; + +exports[`invalid usage argument count ([]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 0."`; + +exports[`invalid usage argument count ([1, 2, 3, 4]): code 1`] = ` +"for i = 1, 2, 3 do +end" +`; + +exports[`invalid usage argument count ([1, 2, 3, 4]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 4."`; + +exports[`invalid usage argument count ([1]): code 1`] = ` +"for i = 1, 0 do +end" +`; + +exports[`invalid usage argument count ([1]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 1."`; + +exports[`invalid usage argument types: code 1`] = ` +"for i = \\"foo\\", 2 do +end" +`; + +exports[`invalid usage argument types: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: arguments must be numbers."`; + +exports[`invalid usage non-ambient declaration: code 1`] = ` +"function luaRange(self) +end" +`; + +exports[`invalid usage non-ambient declaration: diagnostics 1`] = `"main.ts(3,22): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage non-declared loop variable: code 1`] = ` +"for ____ = 1, 10, 2 do +end" +`; + +exports[`invalid usage non-declared loop variable: diagnostics 1`] = `"main.ts(7,18): error TSTL: Invalid @forRange call: loop must declare it's own control variable."`; + +exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): code 1`] = ` +"call = nil +call(_G, luaRange)" +`; + +exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): diagnostics 1`] = `"main.ts(6,49): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage reference ("const range = luaRange(1, 10);"): code 1`] = `"range = luaRange(_G, 1, 10)"`; + +exports[`invalid usage reference ("const range = luaRange(1, 10);"): diagnostics 1`] = `"main.ts(6,27): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): code 1`] = ` +"for ____, i in ipairs( + { + table.unpack( + luaRange(_G, 1, 10) + ) + } +) do +end" +`; + +exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): diagnostics 1`] = `"main.ts(6,33): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage reference ("let array = [0, luaRange, 1];"): code 1`] = `"array = {0, luaRange, 1}"`; + +exports[`invalid usage reference ("let array = [0, luaRange, 1];"): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = ` +"require(\\"lualib_bundle\\"); +__TS__FunctionCall(luaRange, nil, 0, 0, 0)" +`; + +exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): diagnostics 1`] = `"main.ts(6,13): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; + +exports[`invalid usage return type: code 1`] = ` +"for i = 1, 10 do +end" +`; + +exports[`invalid usage return type: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: function must return Iterable."`; + +exports[`invalid usage variable destructuring: code 1`] = ` +"for ____ = 1, 10, 2 do +end" +`; + +exports[`invalid usage variable destructuring: diagnostics 1`] = `"main.ts(6,18): error TSTL: Invalid @forRange call: destructuring cannot be used."`; diff --git a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap b/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap new file mode 100644 index 000000000..24761ca3a --- /dev/null +++ b/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`forof lua iterator tuple-return single existing variable: code 1`] = ` +"for ____ in luaIter(_G) do +end" +`; + +exports[`forof lua iterator tuple-return single existing variable: diagnostics 1`] = `"main.ts(9,14): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; + +exports[`forof lua iterator tuple-return single variable: code 1`] = ` +"for ____ in luaIter(_G) do +end" +`; + +exports[`forof lua iterator tuple-return single variable: diagnostics 1`] = `"main.ts(8,18): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; diff --git a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap b/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap new file mode 100644 index 000000000..fae2b1f20 --- /dev/null +++ b/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap @@ -0,0 +1,197 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +Ext = __TS__Class() +Ext.name = \\"Ext\\" +__TS__ClassExtends(Ext, Table)" +`; + +exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,19): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; + +exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +c = (function() + local Ext = __TS__Class() + Ext.name = \\"Ext\\" + __TS__ClassExtends(Ext, Table) + return Ext +end)()" +`; + +exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,29): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; + +exports[`Cannot isolate LuaTable method ("get"): code 1`] = `"property = tbl.get"`; + +exports[`Cannot isolate LuaTable method ("get"): code 2`] = `"property = tbl.get"`; + +exports[`Cannot isolate LuaTable method ("get"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.get is unsupported."`; + +exports[`Cannot isolate LuaTable method ("get"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.get is unsupported."`; + +exports[`Cannot isolate LuaTable method ("set"): code 1`] = `"property = tbl.set"`; + +exports[`Cannot isolate LuaTable method ("set"): code 2`] = `"property = tbl.set"`; + +exports[`Cannot isolate LuaTable method ("set"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.set is unsupported."`; + +exports[`Cannot isolate LuaTable method ("set"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.set is unsupported."`; + +exports[`Cannot set LuaTable length: code 1`] = `"tbl.length = 2"`; + +exports[`Cannot set LuaTable length: code 2`] = `"tbl.length = 2"`; + +exports[`Cannot set LuaTable length: diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; + +exports[`Cannot set LuaTable length: diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 1`] = `"tbl.get(tbl, \\"field\\")"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 2`] = `"tbl.get(tbl, \\"field\\")"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 1`] = `"local ____ = tbl.length"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 2`] = `"local ____ = tbl.length"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 1`] = `"tbl.set(tbl, \\"field\\")"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 2`] = `"tbl.set(tbl, \\"field\\")"`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; + +exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): code 1`] = ` +"require(\\"lualib_bundle\\"); +__TS__InstanceOf(tbl, Table)" +`; + +exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): diagnostics 1`] = `"main.ts(11,1): error TSTL: The instanceof operator cannot be used with a '@luaTable' class."`; + +exports[`Forbidden LuaTable use ("tbl.get()"): code 1`] = `"local ____ = tbl[nil]"`; + +exports[`Forbidden LuaTable use ("tbl.get()"): code 2`] = `"local ____ = tbl[nil]"`; + +exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; + +exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; + +exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 1`] = `"local ____ = tbl.field"`; + +exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 2`] = `"local ____ = tbl.field"`; + +exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; + +exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; + +exports[`Forbidden LuaTable use ("tbl.set()"): code 1`] = `"tbl[nil] = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set()"): code 2`] = `"tbl[nil] = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; + +exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; + +exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 1`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 2`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 1`] = `"main.ts(11,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; + +exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 2`] = `"main.ts(13,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 1`] = `"tbl.field = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 2`] = `"tbl.field = nil"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 1`] = `"tbl.field = table.unpack({0})"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 2`] = `"tbl.field = table.unpack({0})"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 1`] = `"main.ts(11,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 2`] = `"main.ts(13,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 1`] = `"tbl.field = 0"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 2`] = `"tbl.field = 0"`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; + +exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +Table = __TS__Class() +Table.name = \\"Table\\" +function Table.prototype.____constructor(self) +end" +`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +c = (function() + local Table = __TS__Class() + Table.name = \\"Table\\" + function Table.prototype.____constructor(self) + end + return Table +end)()" +`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): diagnostics 1`] = `"main.ts(1,28): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +____exports.Table = __TS__Class() +local Table = ____exports.Table +Table.name = \\"Table\\" +function Table.prototype.____constructor(self) +end +return ____exports" +`; + +exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; + +exports[`LuaTable set() cannot be used in a LuaTable call expression: code 1`] = `"exp = tbl:set(\\"value\\", 5)"`; + +exports[`LuaTable set() cannot be used in a LuaTable call expression: code 2`] = `"exp = tbl:set(\\"value\\", 5)"`; + +exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 1`] = `"main.ts(11,17): error TSTL: LuaTable.set is unsupported."`; + +exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 2`] = `"main.ts(13,17): error TSTL: LuaTable.set is unsupported."`; + +exports[`LuaTables cannot be constructed with arguments: code 1`] = `"____table = {}"`; + +exports[`LuaTables cannot be constructed with arguments: diagnostics 1`] = `"main.ts(11,15): error TSTL: Invalid @luaTable usage: No parameters are allowed when constructing a LuaTable object."`; + +exports[`LuaTables cannot have other members: code 1`] = `"tbl:other()"`; + +exports[`LuaTables cannot have other members: code 2`] = `"tbl:other()"`; + +exports[`LuaTables cannot have other members: code 3`] = `"x = tbl:other()"`; + +exports[`LuaTables cannot have other members: code 4`] = `"x = tbl:other()"`; + +exports[`LuaTables cannot have other members: diagnostics 1`] = `"main.ts(11,5): error TSTL: LuaTable.other is unsupported."`; + +exports[`LuaTables cannot have other members: diagnostics 2`] = `"main.ts(13,5): error TSTL: LuaTable.other is unsupported."`; + +exports[`LuaTables cannot have other members: diagnostics 3`] = `"main.ts(11,13): error TSTL: LuaTable.other is unsupported."`; + +exports[`LuaTables cannot have other members: diagnostics 4`] = `"main.ts(13,13): error TSTL: LuaTable.other is unsupported."`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap new file mode 100644 index 000000000..ba6b5e0a1 --- /dev/null +++ b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DontAllowInstantiation: code 1`] = ` +"require(\\"lualib_bundle\\"); +local __meta___LOADED = debug.getregistry()._LOADED +e = __TS__New(Ext)" +`; + +exports[`DontAllowInstantiation: diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; + +exports[`IncorrectUsage: code 1`] = ` +"function LoadedExt.test(self) + return 5 +end" +`; + +exports[`IncorrectUsage: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class."`; diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index 856a566f0..cd77bcca6 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -1,4 +1,4 @@ -import { InvalidAnnotationArgumentNumber } from "../../../src/transformation/utils/errors"; +import { annotationInvalidArgumentCount } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("CustomCreate", () => { @@ -25,16 +25,10 @@ test("CustomCreate", () => { }); test("IncorrectUsage", () => { - expect(() => { - util.transpileString(` - /** @customConstructor */ - class Point2D { - constructor( - public x: number, - public y: number - ) {} - } - return new Point2D(1, 2).x; - `); - }).toThrowExactError(InvalidAnnotationArgumentNumber("@customConstructor", 0, 1, util.nodeStub)); + util.testFunction` + /** @customConstructor */ + class Point2D {} + + new Point2D(); + `.expectDiagnosticsToMatchSnapshot([annotationInvalidArgumentCount.code]); }); diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts index 18e41719c..c8da1b81b 100644 --- a/test/unit/annotations/extension.spec.ts +++ b/test/unit/annotations/extension.spec.ts @@ -1,28 +1,26 @@ import { - InvalidExtendsExtension, - InvalidInstanceOfExtension, - InvalidNewExpressionOnExtension, -} from "../../../src/transformation/utils/errors"; + extensionCannotConstruct, + extensionCannotExtend, + extensionInvalidInstanceOf, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { - const code = ` + util.testModule` declare class A {} /** @${extensionType} **/ class B extends A {} class C extends B {} - `; - expect(() => util.transpileString(code)).toThrowExactError(InvalidExtendsExtension(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([extensionCannotExtend.code]); }); test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { - const code = ` + util.testModule` declare class A {} /** @${extensionType} **/ class B extends A {} const b = new B(); - `; - expect(() => util.transpileString(code)).toThrowExactError(InvalidNewExpressionOnExtension(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); }); test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { @@ -32,5 +30,5 @@ test.each(["extension", "metaExtension"])("instanceof extension (%p)", extension class B extends A {} declare const foo: any; const result = foo instanceof B; - `.expectToHaveDiagnosticOfError(InvalidInstanceOfExtension(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([extensionInvalidInstanceOf.code]); }); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts index d49fa5c1c..661c45253 100644 --- a/test/unit/annotations/forRange.spec.ts +++ b/test/unit/annotations/forRange.spec.ts @@ -1,108 +1,83 @@ -import * as ts from "typescript"; -import { InvalidForRangeCall } from "../../../src/transformation/utils/errors"; +import { invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; +const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` + /** @forRange */ + declare function luaRange(${args}): ${returns}; +`; + test.each([ - { args: [1, 10], expectResult: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { args: [1, 10, 2], expectResult: [1, 3, 5, 7, 9] }, - { args: [10, 1, -1], expectResult: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, - { args: [10, 1, -2], expectResult: [10, 8, 6, 4, 2] }, -])("@forRange loop", ({ args, expectResult }) => { - const tsHeader = "/** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[];"; - const code = ` - const results: number[] = []; + { args: [1, 10], results: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, + { args: [1, 10, 2], results: [1, 3, 5, 7, 9] }, + { args: [10, 1, -1], results: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, + { args: [10, 1, -2], results: [10, 8, 6, 4, 2] }, +])("usage in for...of loop", ({ args, results }) => { + util.testModule` + ${createForRangeDeclaration()} + export const results: number[] = []; + for (const i of luaRange(${args})) { results.push(i); } - return JSONStringify(results);`; - - const result = util.transpileAndExecute(code, undefined, undefined, tsHeader); - expect(JSON.parse(result)).toEqual(expectResult); -}); - -test("invalid non-ambient @forRange function", () => { - const code = ` - /** @forRange **/ function luaRange(i: number, j: number, k?: number): number[] { return []; } - for (const i of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function can only be used as an iterable in a for...of loop." - ).message - ); -}); - -test.each([[1], [1, 2, 3, 4]])("invalid @forRange argument count", (...args) => { - const code = ` - /** @forRange **/ declare function luaRange(...args: number[]): number[] { return []; } - for (const i of luaRange(${util.formatCode(...args)})) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall(ts.createEmptyStatement(), "@forRange function must take 2 or 3 arguments.").message - ); -}); - -test("invalid @forRange control variable", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; - let i: number; - for (i of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop must declare its own control variable.").message - ); + ` + .setReturnExport("results") + .expectToEqual(results); }); -test("invalid @forRange argument type", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: string, j: number): number[] { return []; } - for (const i of luaRange("foo", 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall(ts.createEmptyStatement(), "@forRange arguments must be number types.").message - ); -}); - -test("invalid @forRange destructuring", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[][]; - for (const [i] of luaRange(1, 10, 2)) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall(ts.createEmptyStatement(), "@forRange loop cannot use destructuring.").message - ); -}); - -test("invalid @forRange return type", () => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): string[]; - for (const i of luaRange(1, 10)) {}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function must return Iterable or Array." - ).message - ); -}); - -test.each([ - "const range = luaRange(1, 10);", - "console.log(luaRange);", - "luaRange.call(null, 0, 0, 0);", - "let array = [0, luaRange, 1];", - "const call: any; call(luaRange);", - "for (const i of [...luaRange(1, 10)]) {}", -])("invalid @forRange reference (%p)", statement => { - const code = ` - /** @forRange **/ declare function luaRange(i: number, j: number, k?: number): number[]; - ${statement}`; - - expect(() => util.transpileString(code)).toThrow( - InvalidForRangeCall( - ts.createEmptyStatement(), - "@forRange function can only be used as an iterable in a for...of loop." - ).message - ); +describe("invalid usage", () => { + test("non-ambient declaration", () => { + util.testModule` + /** @forRange */ + function luaRange() {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { + util.testModule` + ${createForRangeDeclaration("...args: number[]")} + for (const i of luaRange(${args})) {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test("non-declared loop variable", () => { + util.testModule` + ${createForRangeDeclaration()} + let i: number; + for (i of luaRange(1, 10, 2)) {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test("argument types", () => { + util.testModule` + ${createForRangeDeclaration("i: string, j: number")} + for (const i of luaRange("foo", 2)) {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test("variable destructuring", () => { + util.testModule` + ${createForRangeDeclaration(undefined, "number[][]")} + for (const [i] of luaRange(1, 10, 2)) {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test("return type", () => { + util.testModule` + ${createForRangeDeclaration(undefined, "string[]")} + for (const i of luaRange(1, 10)) {} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); + + test.each([ + "const range = luaRange(1, 10);", + "luaRange.call(null, 0, 0, 0);", + "let array = [0, luaRange, 1];", + "const call = undefined as any; call(luaRange);", + "for (const i of [...luaRange(1, 10)]) {}", + ])("reference (%p)", statement => { + util.testModule` + ${createForRangeDeclaration()} + ${statement} + `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + }); }); diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts index 122c6e7fb..46e324bc5 100644 --- a/test/unit/annotations/luaIterator.spec.ts +++ b/test/unit/annotations/luaIterator.spec.ts @@ -1,7 +1,5 @@ -import * as ts from "typescript"; -import * as tstl from "../../../src"; -import { UnsupportedNonDestructuringLuaIterator } from "../../../src/transformation/utils/errors"; import * as util from "../../util"; +import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; test("forof lua iterator", () => { const code = ` @@ -16,12 +14,7 @@ test("forof lua iterator", () => { for (let e of luaIter()) { result += e; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("abc"); }); @@ -38,12 +31,7 @@ test("forof array lua iterator", () => { for (let e of luaIter()) { result += e; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("abc"); }); @@ -61,12 +49,7 @@ test("forof lua iterator with existing variable", () => { for (e of luaIter()) { result += e; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("abc"); }); @@ -83,12 +66,7 @@ test("forof lua iterator destructuring", () => { for (let [a, b] of luaIter()) { result += a + b; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("0a1b2c"); }); @@ -107,12 +85,7 @@ test("forof lua iterator destructuring with existing variables", () => { for ([a, b] of luaIter()) { result += a + b; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("0a1b2c"); }); @@ -134,12 +107,7 @@ test("forof lua iterator tuple-return", () => { for (let [a, b] of luaIter()) { result += a + b; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("0a1b2c"); }); @@ -163,17 +131,12 @@ test("forof lua iterator tuple-return with existing variables", () => { for ([a, b] of luaIter()) { result += a + b; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("0a1b2c"); }); test("forof lua iterator tuple-return single variable", () => { - const code = ` + util.testModule` /** * @luaIterator * @tupleReturn @@ -181,19 +144,11 @@ test("forof lua iterator tuple-return single variable", () => { interface Iter extends Iterable<[string, string]> {} declare function luaIter(): Iter; for (let x of luaIter()) {} - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - UnsupportedNonDestructuringLuaIterator(util.nodeStub) - ); + `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); }); test("forof lua iterator tuple-return single existing variable", () => { - const code = ` + util.testModule` /** * @luaIterator * @tupleReturn @@ -202,15 +157,7 @@ test("forof lua iterator tuple-return single existing variable", () => { declare function luaIter(): Iter; let x: [string, string]; for (x of luaIter()) {} - `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - expect(() => util.transpileString(code, compilerOptions)).toThrowExactError( - UnsupportedNonDestructuringLuaIterator(util.nodeStub) - ); + `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); }); test("forof forwarded lua iterator", () => { @@ -231,12 +178,7 @@ test("forof forwarded lua iterator", () => { for (let a of forward()) { result += a; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("abc"); }); @@ -262,11 +204,6 @@ test("forof forwarded lua iterator with tupleReturn", () => { for (let [a, b] of forward()) { result += a + b; } return result; `; - const compilerOptions = { - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget: tstl.LuaTarget.Lua53, - target: ts.ScriptTarget.ES2015, - }; - const result = util.transpileAndExecute(code, compilerOptions); + const result = util.transpileAndExecute(code); expect(result).toBe("0a1b2c"); }); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts index 95813e5ce..ec7d1af35 100644 --- a/test/unit/annotations/luaTable.spec.ts +++ b/test/unit/annotations/luaTable.spec.ts @@ -1,21 +1,20 @@ -import * as ts from "typescript"; import { - ForbiddenLuaTableNonDeclaration, - ForbiddenLuaTableUseException, - InvalidExtendsLuaTable, - InvalidInstanceOfLuaTable, - UnsupportedKind, - UnsupportedProperty, -} from "../../../src/transformation/utils/errors"; + luaTableCannotBeAccessedDynamically, + luaTableCannotBeExtended, + luaTableForbiddenUsage, + luaTableMustBeAmbient, + unsupportedProperty, + luaTableInvalidInstanceOf, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const tableLibClass = ` /** @luaTable */ declare class Table { length: number; - constructor(notAllowed?: boolean); - set(key?: K, value?: V): void; - get(key?: K): V; + constructor(notAllowed?: any); + set(key?: K, value?: V, notAllowed?: any): void; + get(key?: K, notAllowed?: any): V; other(): void; } declare let tbl: Table; @@ -25,39 +24,37 @@ const tableLibInterface = ` /** @luaTable */ declare interface Table { length: number; - constructor(notAllowed?: boolean); - set(key?: K, value?: V): void; - get(key?: K): V; + set(key?: K, value?: V, notAllowed?: any): void; + get(key?: K, notAllowed?: any): V; other(): void; } + +/** @luaTable */ +declare const Table: new (notAllowed?: any) => Table; declare let tbl: Table; `; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - expect(() => util.transpileString(tableLib + `const table = new Table(true);`)).toThrowExactError( - ForbiddenLuaTableUseException("No parameters are allowed when constructing a LuaTable object.", util.nodeStub) - ); + util.testModule(tableLib + `const table = new Table(true);`).expectDiagnosticsToMatchSnapshot([ + luaTableForbiddenUsage.code, + ]); }); test.each([tableLibClass, tableLibInterface])( "LuaTable set() cannot be used in a LuaTable call expression", tableLib => { - expect(() => util.transpileString(tableLib + `const exp = tbl.set("value", 5)`)).toThrowExactError( - UnsupportedProperty("LuaTable", "set", util.nodeStub) - ); + util.testModule(tableLib + `const exp = tbl.set("value", 5)`).expectDiagnosticsToMatchSnapshot([ + unsupportedProperty.code, + ]); } ); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - expect(() => util.transpileString(tableLib + `tbl.other()`)).toThrowExactError( - UnsupportedProperty("LuaTable", "other", util.nodeStub) - ); + util.testModule(tableLib + `tbl.other()`).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - expect(() => util.transpileString(tableLib + `let x = tbl.other()`)).toThrowExactError( - UnsupportedProperty("LuaTable", "other", util.nodeStub) - ); + util.testModule(tableLib + `let x = tbl.other()`).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass])("LuaTable new", tableLib => { @@ -72,23 +69,20 @@ test.each([tableLibClass])("LuaTable length", tableLib => { }); test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - expect(() => util.transpileString(tableLib + `tbl.length = 2;`)).toThrowExactError( - ForbiddenLuaTableUseException("A LuaTable object's length cannot be re-assigned.", util.nodeStub) - ); + util.testModule(tableLib + `tbl.length = 2;`).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { test.each([ - [`tbl.get()`, "One parameter is required for get()."], - [`tbl.get("field", "field2")`, "One parameter is required for get()."], - [`tbl.set()`, "Two parameters are required for set()."], - [`tbl.set("field")`, "Two parameters are required for set()."], - [`tbl.set("field", 0, 1)`, "Two parameters are required for set()."], - [`tbl.set("field", ...[0, 1])`, "Arguments cannot be spread."], - ])("Forbidden LuaTable use (%p)", (invalidCode, errorDescription) => { - expect(() => util.transpileString(tableLib + invalidCode)).toThrowExactError( - ForbiddenLuaTableUseException(errorDescription, util.nodeStub) - ); + "tbl.get()", + 'tbl.get("field", "field2")', + "tbl.set()", + 'tbl.set("field")', + 'tbl.set("field", 0, 1)', + 'tbl.set(...(["field", 0] as const))', + 'tbl.set("field", ...([0] as const))', + ])("Forbidden LuaTable use (%p)", invalidCode => { + util.testModule(tableLib + invalidCode).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); }); @@ -96,9 +90,7 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each([`class Ext extends Table {}`, `const c = class Ext extends Table {}`])( "Cannot extend LuaTable class (%p)", code => { - expect(() => util.transpileString(tableLib + code)).toThrowExactError( - InvalidExtendsLuaTable(util.nodeStub) - ); + util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); } ); }); @@ -108,12 +100,12 @@ test.each([ `/** @luaTable */ export class Table {}`, `/** @luaTable */ const c = class Table {}`, ])("LuaTable classes must be ambient (%p)", code => { - expect(() => util.transpileString(code)).toThrowExactError(ForbiddenLuaTableNonDeclaration(util.nodeStub)); + util.testModule(code).expectDiagnosticsToMatchSnapshot([luaTableMustBeAmbient.code]); }); test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each([`tbl instanceof Table`])("Cannot use instanceof on a LuaTable class (%p)", code => { - expect(() => util.transpileString(tableLib + code)).toThrowExactError(InvalidInstanceOfLuaTable(util.nodeStub)); + util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); }); }); @@ -121,18 +113,18 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio test.each([`tbl["get"]("field")`, `tbl["set"]("field")`, `tbl["length"]`])( "Cannot use ElementAccessExpression on a LuaTable (%p)", code => { - expect(() => util.transpileString(tableLib + code)).toThrowExactError( - UnsupportedKind("LuaTable access expression", ts.SyntaxKind.ElementAccessExpression, util.nodeStub) - ); + util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([ + luaTableCannotBeAccessedDynamically.code, + ]); } ); }); test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { test.each([`set`, `get`])("Cannot isolate LuaTable method (%p)", propertyName => { - expect(() => util.transpileString(`${tableLib} let property = tbl.${propertyName}`)).toThrowExactError( - UnsupportedProperty("LuaTable", propertyName, util.nodeStub) - ); + util.testModule(`${tableLib} let property = tbl.${propertyName}`).expectDiagnosticsToMatchSnapshot([ + unsupportedProperty.code, + ]); }); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index 76b40c791..da0f1992a 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -1,4 +1,4 @@ -import { InvalidNewExpressionOnExtension, MissingMetaExtension } from "../../../src/transformation/utils/errors"; +import { extensionCannotConstruct, metaExtensionMissingExtends } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("MetaExtension", () => { @@ -26,26 +26,21 @@ test("MetaExtension", () => { }); test("IncorrectUsage", () => { - expect(() => { - util.transpileString(` - /** @metaExtension */ - class LoadedExt { - public static test() { - return 5; - } + util.testModule` + /** @metaExtension */ + class LoadedExt { + public static test() { + return 5; } - `); - }).toThrowExactError(MissingMetaExtension(util.nodeStub)); + } + `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code]); }); test("DontAllowInstantiation", () => { - expect(() => { - util.transpileString(` - declare class _LOADED {} - /** @metaExtension */ - class Ext extends _LOADED { - } - const e = new Ext(); - `); - }).toThrowExactError(InvalidNewExpressionOnExtension(util.nodeStub)); + util.testModule` + declare class _LOADED {} + /** @metaExtension */ + class Ext extends _LOADED {} + const e = new Ext(); + `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); }); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index ce7abd622..1a8665464 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -1,3 +1,4 @@ +import { unsupportedVarDeclaration } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each(["const", "let"])("%s declaration not top-level is not global", declarationKind => { @@ -21,25 +22,25 @@ test.each(["const", "let"])("%s declaration top-level is global", declarationKin test("var declaration is disallowed", () => { util.testFunction` var foo = true; - `.expectToHaveDiagnostics(); + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); }); test("var declaration in for loop is disallowed", () => { util.testFunction` for (var foo = 0;;) {} - `.expectToHaveDiagnostics(); + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); }); test("var declaration in for...in loop is disallowed", () => { util.testFunction` for (var foo in {}) {} - `.expectToHaveDiagnostics(); + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); }); test("var declaration in for...of loop is disallowed", () => { util.testFunction` for (var foo of []) {} - `.expectToHaveDiagnostics(); + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); }); test.each(["let myvar;", "const myvar = null;", "const myvar = undefined;"])("Null assignments (%p)", declaration => { diff --git a/test/unit/builtins/__snapshots__/loading.spec.ts.snap b/test/unit/builtins/__snapshots__/loading.spec.ts.snap new file mode 100644 index 000000000..de7fb50b4 --- /dev/null +++ b/test/unit/builtins/__snapshots__/loading.spec.ts.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Unknown builtin property access: code 1`] = ` +"local ____exports = {} +____exports.__result = Math.unknownProperty +return ____exports" +`; + +exports[`Unknown builtin property access: diagnostics 1`] = `"main.ts(1,30): error TSTL: Math.unknownProperty is unsupported."`; diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index d1e5c204a..9284363be 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -1,5 +1,5 @@ import * as tstl from "../../../src"; -import { UnsupportedProperty } from "../../../src/transformation/utils/errors"; +import { unsupportedProperty } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; describe("luaLibImport", () => { @@ -42,6 +42,6 @@ describe("Unknown builtin property", () => { test("access", () => { util.testExpression`Math.unknownProperty` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(UnsupportedProperty("Math", "unknownProperty", util.nodeStub)); + .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); }); diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index cbd8cb3f4..2c58e5df8 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -109,7 +109,7 @@ test("set keys", () => { util.testFunction` let myset = new Set([5, 6, 7]); let count = 0; - for (var key of myset.keys()) { count += key; } + for (const key of myset.keys()) { count += key; } return count; `.expectToMatchJsResult(); }); @@ -118,7 +118,7 @@ test("set values", () => { util.testFunction` let myset = new Set([5, 6, 7]); let count = 0; - for (var value of myset.values()) { count += value; } + for (const value of myset.values()) { count += value; } return count; `.expectToMatchJsResult(); }); diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index 582b79177..3d9520da4 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -1,20 +1,9 @@ import * as path from "path"; import * as ts from "typescript"; -import { DiagnosticCategory } from "typescript"; import { LuaLibImportKind } from "../../src"; -import { couldNotFindBundleEntryPoint } from "../../src/transpilation/diagnostics"; +import * as diagnosticFactories from "../../src/transpilation/diagnostics"; import * as util from "../util"; -test("no entry point", () => { - util.testBundle`` - .setOptions({ luaBundleEntry: undefined }) - .expectToHaveDiagnostic( - d => - d.messageText === `'luaBundleEntry' is required when 'luaBundle' is enabled.` && - d.category === DiagnosticCategory.Error - ); -}); - test("import module -> main", () => { util.testBundle` export { value } from "./module"; @@ -24,14 +13,14 @@ test("import module -> main", () => { }); test("bundle file name", () => { - const { diagnostics, transpiledFiles } = util.testModule` - export { value } from "./module"; -` + const { transpiledFiles } = util.testModule` + export { value } from "./module"; + ` .addExtraFile("module.ts", "export const value = true") .setOptions({ luaBundle: "mybundle.lua", luaBundleEntry: "main.ts" }) + .expectToHaveNoDiagnostics() .getLuaResult(); - expect(diagnostics.length).toBe(0); expect(transpiledFiles.length).toBe(1); expect(transpiledFiles[0].fileName).toBe( path.join(ts.sys.getCurrentDirectory(), "mybundle.lua").replace(/\\/g, "/") @@ -87,35 +76,26 @@ test("entry point in directory", () => { .expectToEqual({ value: true }); }); -test.each([LuaLibImportKind.Inline, LuaLibImportKind.Require])("LuaLib %p", lualibOption => { - const testBundle = util.testBundle` +test("LuaLibImportKind.Require", () => { + util.testBundle` export const result = [1, 2]; result.push(3); - `.setOptions({ luaLibImport: lualibOption }); - - if (lualibOption === LuaLibImportKind.Inline) { - testBundle.expectToHaveDiagnostic(d => d.category === DiagnosticCategory.Warning); - } else { - expect(testBundle.getLuaResult().diagnostics).toEqual([]); - } - expect(testBundle.getLuaExecutionResult()).toEqual({ result: [1, 2, 3] }); + ` + .setOptions({ luaLibImport: LuaLibImportKind.Require }) + .expectToEqual({ result: [1, 2, 3] }); }); -test("LuaBundle and LuaLibImport.Inline generate warning", () => { - const testBundle = util.testBundle` +test("LuaLibImportKind.Inline generates a warning", () => { + util.testBundle` export const result = [1, 2]; result.push(3); ` .setOptions({ luaLibImport: LuaLibImportKind.Inline }) - .expectToHaveDiagnostic( - d => - d.category === DiagnosticCategory.Warning && - d.messageText === - `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + - `It is recommended to use 'luaLibImport: "require"'` - ); - - expect(testBundle.getLuaExecutionResult()).toEqual({ result: [1, 2, 3] }); // Result should still be the same + .expectDiagnosticsToMatchSnapshot( + [diagnosticFactories.usingLuaBundleWithInlineMightGenerateDuplicateCode.code], + true + ) + .expectToEqual({ result: [1, 2, 3] }); }); test("cyclic imports", () => { @@ -136,6 +116,14 @@ test("cyclic imports", () => { .expectToEqual(new util.ExecutionError("stack overflow")); }); +test("no entry point", () => { + util.testBundle`` + .setOptions({ luaBundleEntry: undefined }) + .expectDiagnosticsToMatchSnapshot([diagnosticFactories.luaBundleEntryIsRequired.code], true); +}); + test("luaEntry doesn't exist", () => { - util.testBundle``.setEntryPoint("entry.ts").expectToHaveExactDiagnostic(couldNotFindBundleEntryPoint("entry.ts")); + util.testBundle`` + .setEntryPoint("entry.ts") + .expectDiagnosticsToMatchSnapshot([diagnosticFactories.couldNotFindBundleEntryPoint.code], true); }); diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap new file mode 100644 index 000000000..0acca51b6 --- /dev/null +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -0,0 +1,19 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`missing declaration name: code 1`] = ` +"require(\\"lualib_bundle\\"); +____ = __TS__Class() +____.name = \\"____\\" +function ____.prototype.____constructor(self) +end" +`; + +exports[`missing declaration name: diagnostics 1`] = `"main.ts(2,9): error TS1211: A class declaration without the 'default' modifier must have a name."`; + +exports[`super without class: code 1`] = ` +"local ____exports = {} +____exports.__result = ____.____constructor(self) +return ____exports" +`; + +exports[`super without class: diagnostics 1`] = `"main.ts(1,25): error TS2337: Super calls are not permitted outside constructors or in nested functions inside constructors."`; diff --git a/test/unit/classes/__snapshots__/decorators.spec.ts.snap b/test/unit/classes/__snapshots__/decorators.spec.ts.snap new file mode 100644 index 000000000..cbc983bd5 --- /dev/null +++ b/test/unit/classes/__snapshots__/decorators.spec.ts.snap @@ -0,0 +1,18 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Throws error if decorator function has void context: code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local function decorator(constructor) + end + local TestClass = __TS__Class() + TestClass.name = \\"TestClass\\" + function TestClass.prototype.____constructor(self) + end + TestClass = __TS__Decorate({decorator}, TestClass) +end +return ____exports" +`; + +exports[`Throws error if decorator function has void context: diagnostics 1`] = `"main.ts(4,9): error TSTL: Decorator function cannot have 'this: void'."`; diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 12751fd40..0e6761fbc 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -236,6 +236,26 @@ test("Subclass constructor across merged namespace", () => { expect(util.transpileAndExecute("return (new NS.Sub()).prop", undefined, undefined, tsHeader)).toBe("foo"); }); +test("super without class", () => { + util.testExpression`super()`.expectDiagnosticsToMatchSnapshot([2337]); +}); + +test("super in unnamed class", () => { + util.testFunction` + class Foo { + public x = true; + } + + const Bar = (class extends (Foo) { + constructor() { + super(); + } + }); + + return new Bar().x; + `.expectToMatchJsResult(); +}); + test("classSuper", () => { const result = util.transpileAndExecute( `class a { @@ -829,3 +849,9 @@ test("Class field override in subclass with constructors", () => { return (new Foo()).field + (new Bar()).field;`; expect(util.transpileAndExecute(code)).toBe("foobar"); }); + +test("missing declaration name", () => { + util.testModule` + class {} + `.expectDiagnosticsToMatchSnapshot([1211]); +}); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index 7d4223ecd..ad77a3a11 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -1,4 +1,4 @@ -import { InvalidDecoratorContext } from "../../../src/transformation/utils/errors"; +import { decoratorInvalidContext } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("Class decorator with no parameters", () => { @@ -105,11 +105,11 @@ test("Class decorators are applied in order and executed in reverse order", () = test("Throws error if decorator function has void context", () => { util.testFunction` - function SetBool(this: void, constructor: new (...args: any[]) => {}) {} + function decorator(this: void, constructor: new (...args: any[]) => {}) {} - @SetBool + @decorator class TestClass {} - `.expectToHaveDiagnosticOfError(InvalidDecoratorContext(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([decoratorInvalidContext.code]); }); test("Exported class decorator", () => { diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index a11fd0595..890c6dc71 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,5 @@ import * as tstl from "../../src"; -import { UnsupportedForTarget } from "../../src/transformation/utils/errors"; +import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each([0, 1])("if (%p)", inp => { @@ -345,7 +345,7 @@ test("switch not allowed in 5.1", () => { switch ("abc") {} ` .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectToHaveDiagnosticOfError(UnsupportedForTarget("Switch statements", tstl.LuaTarget.Lua51, util.nodeStub)); + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); }); test.each([ diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 8f3121c86..90211b78c 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -1,6 +1,5 @@ -import * as ts from "typescript"; import * as tstl from "../../src"; -import { UnsupportedForTarget, UnsupportedKind } from "../../src/transformation/utils/errors"; +import { unsupportedForTarget, unsupportedRightShiftOperator } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; // TODO: @@ -67,7 +66,7 @@ test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua51, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() - .expectToHaveDiagnosticOfError(UnsupportedForTarget("Bitwise operations", tstl.LuaTarget.Lua51, util.nodeStub)); + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); }); test.each(allBinaryOperators)("Bitop [JIT] (%p)", input => { @@ -95,13 +94,7 @@ test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() - .expectToHaveDiagnosticOfError( - UnsupportedKind( - "right shift operator (use >>> instead)", - ts.SyntaxKind.GreaterThanGreaterThanToken, - util.nodeStub - ) - ); + .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( diff --git a/test/unit/functions/__snapshots__/functions.spec.ts.snap b/test/unit/functions/__snapshots__/functions.spec.ts.snap new file mode 100644 index 000000000..e1e5b49d2 --- /dev/null +++ b/test/unit/functions/__snapshots__/functions.spec.ts.snap @@ -0,0 +1,8 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`missing declaration name: code 1`] = ` +"function ____(self) +end" +`; + +exports[`missing declaration name: diagnostics 1`] = `"main.ts(2,18): error TS1003: Identifier expected."`; diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index aab7b151a..d664ab061 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -496,3 +496,9 @@ test("named function expression reference", () => { return y(); `.expectToMatchJsResult(); }); + +test("missing declaration name", () => { + util.testModule` + function () {} + `.expectDiagnosticsToMatchSnapshot([1003]); +}); diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap new file mode 100644 index 000000000..9f112f305 --- /dev/null +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -0,0 +1,1723 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 2`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(11,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 2`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 2`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 2`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 2`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 3`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function argument with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 4`] = ` +"main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,23): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 1`] = `"main.ts(10,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 2`] = `"main.ts(10,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(9,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(11,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 2`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 2`] = `"main.ts(7,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}): diagnostics 1`] = `"main.ts(7,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 1`] = `"main.ts(9,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 2`] = `"main.ts(9,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 1`] = `"main.ts(9,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 2`] = `"main.ts(9,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function assignment ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 2`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 2`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 3`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 4`] = ` +"main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,14): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 2`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(11,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 2`] = `"main.ts(7,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}): diagnostics 1`] = `"main.ts(7,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 2`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 1`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 2`] = `"main.ts(9,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function generic argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function overload assignment ("(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(7,52): error TSTL: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'."`; + +exports[`Invalid function overload assignment ("(this: void, s1: string, s2: string) => string"): diagnostics 1`] = `"main.ts(7,65): error TSTL: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'."`; + +exports[`Invalid function overload assignment ("{(this: any, s1: string, s2: string): string}"): diagnostics 1`] = `"main.ts(7,64): error TSTL: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'."`; + +exports[`Invalid function overload assignment ("{(this: void, s: string): string}"): diagnostics 1`] = `"main.ts(7,52): error TSTL: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 1`] = `"main.ts(10,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 2`] = `"main.ts(10,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(9,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(11,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 2`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 2`] = `"main.ts(7,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}): diagnostics 1`] = `"main.ts(7,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 1`] = `"main.ts(9,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 2`] = `"main.ts(9,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 1`] = `"main.ts(9,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 2`] = `"main.ts(9,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function return ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function return with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 2`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function return with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'. +main.ts(4,24): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." +`; + +exports[`Invalid function return with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 2`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'. +main.ts(4,24): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." +`; + +exports[`Invalid function return with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function return with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function return with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 3`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function return with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 4`] = ` +"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid function tuple assignment: diagnostics 1`] = ` +"main.ts(5,13): error TS2322: Type '[number, Meth]' is not assignable to type '[number, Func]'. + Type 'Meth' is not assignable to type 'Func'. + The 'this' types of each signature are incompatible. + Type 'void' is not assignable to type '{}'. +main.ts(5,38): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." +`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}): diagnostics 1`] = `"main.ts(6,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(4,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(4,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 1`] = `"main.ts(6,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}): diagnostics 2`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 1`] = `"main.ts(6,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}): diagnostics 2`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(6,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 1`] = `"main.ts(9,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}): diagnostics 2`] = `"main.ts(9,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(8,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}): diagnostics 1`] = `"main.ts(10,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}): diagnostics 1`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}): diagnostics 1`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}): diagnostics 1`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}): diagnostics 1`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 1`] = `"main.ts(4,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 1`] = `"main.ts(6,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}): diagnostics 2`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 1`] = `"main.ts(6,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}): diagnostics 2`] = `"main.ts(6,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}): diagnostics 1`] = `"main.ts(6,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 1`] = `"main.ts(8,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}): diagnostics 2`] = `"main.ts(8,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 1`] = `"main.ts(8,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}): diagnostics 2`] = `"main.ts(8,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 1`] = `"main.ts(4,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid function variable declaration ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid interface method assignment: diagnostics 1`] = `"main.ts(5,22): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid lua lib function argument: diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'callbackfn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid method tuple assignment: diagnostics 1`] = `"main.ts(5,38): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index 2602e2ba7..c6c51be91 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -349,9 +349,9 @@ export const selfTestFunctionType = "(this: any, s: string) => string"; export const noSelfTestFunctionType = "(this: void, s: string) => string"; type TestFunctionCast = [ - /*testFunction: */ TestFunction, - /*castedFunction: */ string, - /*isSelfConversion?: */ boolean? + /* testFunction: */ TestFunction, + /* castedFunction: */ string, + /* isSelfConversion?: */ boolean? ]; export const validTestFunctionCasts: TestFunctionCast[] = [ [selfTestFunctions[0], `<${anonTestFunctionType}>(${selfTestFunctions[0].value})`], @@ -377,9 +377,9 @@ export const invalidTestFunctionCasts: TestFunctionCast[] = [ ]; export type TestFunctionAssignment = [ - /*testFunction: */ TestFunction, - /*functionType: */ string, - /*isSelfConversion?: */ boolean? + /* testFunction: */ TestFunction, + /* functionType: */ string, + /* isSelfConversion?: */ boolean? ]; export const validTestFunctionAssignments: TestFunctionAssignment[] = [ ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 4f2e385be..7d678496b 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -1,191 +1,153 @@ import { - UnsupportedNoSelfFunctionConversion, - UnsupportedOverloadAssignment, - UnsupportedSelfFunctionConversion, -} from "../../../../src/transformation/utils/errors"; + unsupportedOverloadAssignment, + unsupportedNoSelfFunctionConversion, + unsupportedSelfFunctionConversion, +} from "../../../../src/transformation/utils/diagnostics"; import * as util from "../../../util"; import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; test.each(invalidTestFunctionAssignments)( "Invalid function variable declaration (%p)", (testFunction, functionType, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} const fn: ${functionType} = ${testFunction.value}; - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub) - : UnsupportedNoSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); } ); test.each(invalidTestFunctionAssignments)( "Invalid function assignment (%p)", (testFunction, functionType, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} let fn: ${functionType}; fn = ${testFunction.value}; - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub) - : UnsupportedNoSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); } ); -test.each(invalidTestFunctionCasts)( - "Invalid function assignment with cast (%p)", - (testFunction, castedFunction, isSelfConversion) => { - const code = ` - ${testFunction.definition || ""} - let fn: typeof ${testFunction.value}; - fn = ${castedFunction}; - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub) - : UnsupportedNoSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - } -); +test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)", (testFunction, castedFunction) => { + util.testModule` + ${testFunction.definition || ""} + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + `.expectDiagnosticsToMatchSnapshot( + [unsupportedNoSelfFunctionConversion.code, unsupportedSelfFunctionConversion.code], + true + ); +}); test.each(invalidTestFunctionAssignments)( "Invalid function argument (%p)", (testFunction, functionType, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} declare function takesFunction(fn: ${functionType}); takesFunction(${testFunction.value}); - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub, "fn") - : UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); } ); test("Invalid lua lib function argument", () => { - const code = ` + util.testModule` declare function foo(this: void, value: string): void; declare const a: string[]; a.forEach(foo); - `; - const err = UnsupportedSelfFunctionConversion(util.nodeStub, "callbackfn"); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot([unsupportedSelfFunctionConversion.code], true); }); -test.each(invalidTestFunctionCasts)( - "Invalid function argument with cast (%p)", - (testFunction, castedFunction, isSelfConversion) => { - const code = ` - ${testFunction.definition || ""} - declare function takesFunction(fn: typeof ${testFunction.value}); - takesFunction(${castedFunction}); - `; - // TODO: Changed in #705 because of order change in `transformArguments`. - // After #412 both errors should be reported. - const err = isSelfConversion - ? UnsupportedNoSelfFunctionConversion(util.nodeStub) - : UnsupportedSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); - } -); +test.each(invalidTestFunctionCasts)("Invalid function argument with cast (%p)", (testFunction, castedFunction) => { + util.testModule` + ${testFunction.definition || ""} + declare function takesFunction(fn: typeof ${testFunction.value}); + takesFunction(${castedFunction}); + `.expectDiagnosticsToMatchSnapshot( + [unsupportedNoSelfFunctionConversion.code, unsupportedSelfFunctionConversion.code], + true + ); +}); test.each(invalidTestFunctionAssignments)( "Invalid function generic argument (%p)", (testFunction, functionType, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} declare function takesFunction(fn: T); takesFunction(${testFunction.value}); - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub, "fn") - : UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn"); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); } ); test.each(invalidTestFunctionAssignments)( "Invalid function return (%p)", (testFunction, functionType, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} function returnsFunction(): ${functionType} { return ${testFunction.value}; } - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub) - : UnsupportedNoSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); } ); test.each(invalidTestFunctionCasts)( "Invalid function return with cast (%p)", (testFunction, castedFunction, isSelfConversion) => { - const code = ` + util.testModule` ${testFunction.definition || ""} function returnsFunction(): typeof ${testFunction.value} { return ${castedFunction}; } - `; - const err = isSelfConversion - ? UnsupportedSelfFunctionConversion(util.nodeStub) - : UnsupportedNoSelfFunctionConversion(util.nodeStub); - expect(() => util.transpileString(code, undefined, false)).toThrowExactError(err); + `.expectDiagnosticsToMatchSnapshot( + isSelfConversion + ? [unsupportedSelfFunctionConversion.code, unsupportedNoSelfFunctionConversion.code] + : [unsupportedNoSelfFunctionConversion.code, unsupportedSelfFunctionConversion.code], + true + ); } ); -test("Interface method assignment", () => { - const code = ` - class Foo { - method(s: string): string { return s + "+method"; } - lambdaProp: (s: string) => string = s => s + "+lambdaProp"; - } - interface IFoo { - method: (s: string) => string; - lambdaProp(s: string): string; - } - const foo: IFoo = new Foo(); - return foo.method("foo") + "|" + foo.lambdaProp("bar"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo+method|bar+lambdaProp"); -}); - test("Invalid function tuple assignment", () => { - const code = ` + util.testModule` interface Func { (this: void, s: string): string; } interface Meth { (this: {}, s: string): string; } declare function getTuple(): [number, Meth]; let [i, f]: [number, Func] = getTuple(); - `; - expect(() => util.transpileString(code)).toThrowExactError(UnsupportedNoSelfFunctionConversion(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([2322, unsupportedNoSelfFunctionConversion.code], true); }); test("Invalid method tuple assignment", () => { - const code = ` + util.testModule` interface Func { (this: void, s: string): string; } interface Meth { (this: {}, s: string): string; } declare function getTuple(): [number, Func]; let [i, f]: [number, Meth] = getTuple(); - `; - expect(() => util.transpileString(code)).toThrowExactError(UnsupportedSelfFunctionConversion(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([unsupportedSelfFunctionConversion.code], true); }); test("Invalid interface method assignment", () => { - const code = ` + util.testModule` interface A { fn(s: string): string; } interface B { fn(this: void, s: string): string; } declare const a: A; const b: B = a; - `; - expect(() => util.transpileString(code)).toThrowExactError( - UnsupportedNoSelfFunctionConversion(util.nodeStub, "fn") - ); + `.expectDiagnosticsToMatchSnapshot([unsupportedNoSelfFunctionConversion.code], true); }); test.each([ @@ -194,13 +156,12 @@ test.each([ "{(this: void, s: string): string}", "{(this: any, s1: string, s2: string): string}", ])("Invalid function overload assignment (%p)", assignType => { - const code = ` + util.testModule` interface O { (this: any, s1: string, s2: string): string; (this: void, s: string): string; } declare const o: O; let f: ${assignType} = o; - `; - expect(() => util.transpileString(code)).toThrowExactError(UnsupportedOverloadAssignment(util.nodeStub)); + `.expectDiagnosticsToMatchSnapshot([unsupportedOverloadAssignment.code], true); }); diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index be1130ba6..4b4721d63 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -144,16 +144,21 @@ test("Valid function tuple assignment", () => { expect(result).toBe("foo"); }); -test("Valid method tuple assignment", () => { - const code = `interface Foo { method(s: string): string; } - interface Meth { (this: Foo, s: string): string; } - let meth: Meth = s => s; - function getTuple(): [number, Meth] { return [1, meth]; } - let [i, f]: [number, Meth] = getTuple(); - let foo: Foo = {method: f}; - return foo.method("foo");`; +test("Interface method assignment", () => { + const code = ` + class Foo { + method(s: string): string { return s + "+method"; } + lambdaProp: (s: string) => string = s => s + "+lambdaProp"; + } + interface IFoo { + method: (s: string) => string; + lambdaProp(s: string): string; + } + const foo: IFoo = new Foo(); + return foo.method("foo") + "|" + foo.lambdaProp("bar"); + `; const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + expect(result).toBe("foo+method|bar+lambdaProp"); }); test("Valid interface method assignment", () => { @@ -166,6 +171,18 @@ test("Valid interface method assignment", () => { expect(result).toBe("foo"); }); +test("Valid method tuple assignment", () => { + const code = `interface Foo { method(s: string): string; } + interface Meth { (this: Foo, s: string): string; } + let meth: Meth = s => s; + function getTuple(): [number, Meth] { return [1, meth]; } + let [i, f]: [number, Meth] = getTuple(); + let foo: Foo = {method: f}; + return foo.method("foo");`; + const result = util.transpileAndExecute(code); + expect(result).toBe("foo"); +}); + test.each([ { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 875c196fc..84583ccd7 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -1,5 +1,4 @@ -import * as ts from "typescript"; -import { InvalidAmbientIdentifierName } from "../../src/transformation/utils/errors"; +import { invalidAmbientIdentifierName } from "../../src/transformation/utils/diagnostics"; import { luaKeywords } from "../../src/transformation/utils/safe-names"; import * as util from "../util"; @@ -83,7 +82,7 @@ test.each([ local; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier("local"))); + .expectDiagnosticsToMatchSnapshot([invalidAmbientIdentifierName.code]); }); test.each([ @@ -100,7 +99,7 @@ test.each([ util.testModule` declare ${statement} $$$; - `.expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier("$$$"))); + `.expectDiagnosticsToMatchSnapshot([invalidAmbientIdentifierName.code]); }); test.each(validTsInvalidLuaNames)( @@ -109,7 +108,7 @@ test.each(validTsInvalidLuaNames)( util.testModule` declare var ${name}: any; const foo = { ${name} }; - `.expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); + `.expectDiagnosticsToMatchSnapshot([invalidAmbientIdentifierName.code]); } ); @@ -118,7 +117,7 @@ test.each(validTsInvalidLuaNames)("undeclared identifier must be a valid lua ide const foo = ${name}; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); + .expectDiagnosticsToMatchSnapshot([invalidAmbientIdentifierName.code]); }); test.each(validTsInvalidLuaNames)( @@ -128,7 +127,7 @@ test.each(validTsInvalidLuaNames)( const foo = { ${name} }; ` .disableSemanticCheck() - .expectToHaveDiagnosticOfError(InvalidAmbientIdentifierName(ts.createIdentifier(name))); + .expectDiagnosticsToMatchSnapshot([invalidAmbientIdentifierName.code]); } ); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index b7b7c27e5..b61e64fd1 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,23 +1,13 @@ -import * as ts from "typescript"; -import { InvalidJsonFileContent } from "../../src/transformation/utils/errors"; import * as util from "../util"; -const jsonOptions = { - resolveJsonModule: true, - noHeader: true, - moduleResolution: ts.ModuleResolutionKind.NodeJs, -}; - test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { util.testModule(JSON.stringify(json)) - .setOptions(jsonOptions) .setMainFileName("main.json") .expectToEqual(json); }); -test("Empty JSON", () => { +test("Empty JSON file error", () => { util.testModule("") - .setOptions(jsonOptions) .setMainFileName("main.json") - .expectToHaveDiagnosticOfError(InvalidJsonFileContent(util.nodeStub)); + .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); }); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index e73f85359..a2bef4c01 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,6 +1,5 @@ -import * as ts from "typescript"; import * as tstl from "../../src"; -import { ForbiddenForIn, UnsupportedForTarget } from "../../src/transformation/utils/errors"; +import { forbiddenForIn, unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test("while", () => { @@ -213,15 +212,11 @@ test.each([ expect(JSON.parse(result)).toEqual(expected); }); -test.each([{ inp: [1, 2, 3] }])("forin[Array] (%p)", ({ inp }) => { - expect(() => - util.transpileString( - `let arrTest = ${JSON.stringify(inp)}; - for (let key in arrTest) { - arrTest[key]++; - }` - ) - ).toThrowExactError(ForbiddenForIn(util.nodeStub)); +test("forin[Array]", () => { + util.testFunction` + const array = []; + for (const key in array) {} + `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( @@ -524,25 +519,23 @@ describe("for...of empty destructuring", () => { describe("assignment", () => declareTests("")); }); -test.each([ - "while (a < b) { i++; continue; }", - "do { i++; continue; } while (a < b)", - "for (let i = 0; i < 3; i++) { continue; }", - "for (let a in b) { continue; }", - "for (let a of b) { continue; }", -])("loop continue in different lua versions (%p)", loop => { - const lua51 = { luaTarget: tstl.LuaTarget.Lua51 }; - const lua52 = { luaTarget: tstl.LuaTarget.Lua52 }; - const lua53 = { luaTarget: tstl.LuaTarget.Lua53 }; - const luajit = { luaTarget: tstl.LuaTarget.LuaJIT }; - - expect(() => util.transpileString(loop, lua51)).toThrowExactError( - UnsupportedForTarget("Continue statement", tstl.LuaTarget.Lua51, ts.createContinue()) - ); - expect(util.transpileString(loop, lua52).indexOf("::__continue2::") !== -1).toBe(true); - expect(util.transpileString(loop, lua53).indexOf("::__continue2::") !== -1).toBe(true); - expect(util.transpileString(loop, luajit).indexOf("::__continue2::") !== -1).toBe(true); -}); +for (const testCase of [ + "while (false) { continue; }", + "do { continue; } while (false)", + "for (;;) { continue; }", + "for (const a in {}) { continue; }", + "for (const a of []) { continue; }", +]) { + const expectContinueGotoLabel: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); + + util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { + [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), + [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, + [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, + [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, + }); +} test("do...while", () => { util.testFunction` diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap new file mode 100644 index 000000000..d4228141d --- /dev/null +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`doesn't resolve paths out of root dir: code 1`] = ` +"local ____exports = {} +local module = require(\\"../module\\") +local ____ = module +return ____exports" +`; + +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"src/main.ts(2,33): error TSTL: Cannot create require path. Module '../module' does not exist within --rootDir."`; diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 6c1dbe105..1b0a6a8f9 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { unresolvableRequirePath } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; @@ -82,7 +83,7 @@ test("doesn't resolve paths out of root dir", () => { .setMainFileName("src/main.ts") .setOptions({ rootDir: "./src" }) .disableSemanticCheck() - .expectToHaveDiagnostics(); + .expectDiagnosticsToMatchSnapshot([unresolvableRequirePath.code]); }); test.each([ diff --git a/test/util.ts b/test/util.ts index a4e84f4b1..6a8909e18 100644 --- a/test/util.ts +++ b/test/util.ts @@ -9,7 +9,7 @@ import * as tstl from "../src"; export * from "./legacy-utils"; -export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown); +export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown, 0, 0); export function parseTypeScript( typescript: string, @@ -50,17 +50,19 @@ export const formatCode = (...values: unknown[]) => values.map(e => stringify(e) export function testEachVersion( name: string | undefined, common: () => T, - special: Record T) | false> + special?: Record void) | boolean> ): void { for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) { - const specialBuilder = special[version]; + const specialBuilder = special?.[version]; if (specialBuilder === false) return; const testName = name === undefined ? version : `${name} [${version}]`; test(testName, () => { const builder = common(); builder.setOptions({ luaTarget: version }); - specialBuilder(builder); + if (typeof specialBuilder === "function") { + specialBuilder(builder); + } }); } } @@ -194,7 +196,6 @@ export class ExecutionError extends Error { export type ExecutableTranspiledFile = tstl.TranspiledFile & { lua: string; sourceMap: string }; export type TapCallback = (builder: TestBuilder) => void; -export type DiagnosticMatcher = (diagnostic: ts.Diagnostic) => boolean; export abstract class TestBuilder { constructor(protected _tsCode: string) {} @@ -242,6 +243,8 @@ export abstract class TestBuilder { skipLibCheck: true, target: ts.ScriptTarget.ES2017, lib: ["lib.esnext.d.ts"], + moduleResolution: ts.ModuleResolutionKind.NodeJs, + resolveJsonModule: true, experimentalDecorators: true, }; public setOptions(options: tstl.CompilerOptions = {}): this { @@ -357,30 +360,20 @@ export abstract class TestBuilder { return this; } - public expectToHaveDiagnostic(matcher: DiagnosticMatcher): this { - expect(this.getLuaDiagnostics().find(matcher)).toBeDefined(); - return this; - } + private diagnosticsChecked = false; - public expectToHaveExactDiagnostic(diagnostic: ts.Diagnostic): this { - expect(this.getLuaDiagnostics()).toContainEqual(diagnostic); - return this; - } - - public expectToHaveDiagnostics(): this { - expect(this.getLuaDiagnostics()).toHaveDiagnostics(); - return this; - } + public expectToHaveDiagnostics(expected?: number[]): this { + if (this.diagnosticsChecked) return this; + this.diagnosticsChecked = true; - public expectToHaveDiagnosticOfError(error: Error): this { - this.expectToHaveDiagnostics(); - expect(this.getLuaDiagnostics()).toHaveLength(1); - const firstDiagnostic = this.getLuaDiagnostics()[0]; - expect(firstDiagnostic).toMatchObject({ messageText: error.message }); + expect(this.getLuaDiagnostics()).toHaveDiagnostics(expected); return this; } public expectToHaveNoDiagnostics(): this { + if (this.diagnosticsChecked) return this; + this.diagnosticsChecked = true; + expect(this.getLuaDiagnostics()).not.toHaveDiagnostics(); return this; } @@ -418,9 +411,19 @@ export abstract class TestBuilder { return this; } - public expectResultToMatchSnapshot(): this { - this.expectToHaveNoDiagnostics(); - expect(this.getLuaExecutionResult()).toMatchSnapshot(); + public expectDiagnosticsToMatchSnapshot(expected?: number[], diagnosticsOnly = false): this { + this.expectToHaveDiagnostics(expected); + + const diagnosticMessages = ts.formatDiagnostics( + this.getLuaDiagnostics().map(tstl.prepareDiagnosticForFormatting), + { getCurrentDirectory: () => "", getCanonicalFileName: fileName => fileName, getNewLine: () => "\n" } + ); + + expect(diagnosticMessages.trim()).toMatchSnapshot("diagnostics"); + if (!diagnosticsOnly) { + expect(this.getMainLuaCodeChunk()).toMatchSnapshot("code"); + } + return this; } From 9783568df3f30bea598ac539aa61cf70cf365eeb Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 16 Mar 2020 06:39:24 +1000 Subject: [PATCH 240/764] Intermediate SpreadElements fix (#832) * Use smarter expression spreading * Fix up test to check that concat doesn't flatten args * flattenExpressions -> flattenSpreadExpressions * Use for-of instead of reduce and rename flattenExpressions * Move test cases up to in function call and in array literal * Update src/transformation/visitors/call.ts Co-Authored-By: ark120202 * Update src/transformation/visitors/call.ts Co-Authored-By: ark120202 * Add test case to check concat * Add in array literal/of tuple return call test * Add test for potential edge case * Add in array literal/of array literal /w OmittedExpression * Refactor unneeded check in call * Allow spreadable expressions in any order * Add of string literal mixed * Update test/unit/spread.spec.ts Co-Authored-By: ark120202 * Update test/unit/spread.spec.ts Co-Authored-By: ark120202 * of string literal mixed -> of string literal * spreadCases -> arrayLiteralCases * Update test/unit/spread.spec.ts Co-Authored-By: ark120202 * Add tuple return tests to in function call * Seperate spread to in function and in array literal * Join spread function call and array literal tests Co-authored-by: ark120202 --- src/transformation/visitors/call.ts | 67 +++++++++++++++++++- src/transformation/visitors/literal.ts | 10 ++- test/unit/spread.spec.ts | 87 +++++++++++++++++++------- 3 files changed, 135 insertions(+), 29 deletions(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index d7e339f2b..90ae8e4b0 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -15,13 +15,78 @@ import { transformLuaTableCallExpression } from "./lua-table"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; +function getExpressionsBeforeAndAfterFirstSpread( + expressions: readonly ts.Expression[] +): [readonly ts.Expression[], readonly ts.Expression[]] { + // [a, b, ...c, d, ...e] --> [a, b] and [...c, d, ...e] + const index = expressions.findIndex(ts.isSpreadElement); + const hasSpreadElement = index !== -1; + const before = hasSpreadElement ? expressions.slice(0, index) : expressions; + const after = hasSpreadElement ? expressions.slice(index) : []; + return [before, after]; +} + +function transformSpreadableExpressionsIntoArrayConcatArguments( + context: TransformationContext, + expressions: readonly ts.Expression[] | ts.NodeArray +): lua.Expression[] { + // [...array, a, b, ...tuple()] --> [ [...array], [a, b], [...tuple()] ] + // chunk non-spread arguments together so they don't concat + const chunks: ts.Expression[][] = []; + for (const [index, expression] of expressions.entries()) { + if (ts.isSpreadElement(expression)) { + chunks.push([expression]); + const next = expressions[index + 1]; + if (next && !ts.isSpreadElement(next)) { + chunks.push([]); + } + } else { + let lastChunk = chunks[chunks.length - 1]; + if (!lastChunk) { + lastChunk = []; + chunks.push(lastChunk); + } + lastChunk.push(expression); + } + } + + return chunks.map(chunk => wrapInTable(...chunk.map(expression => context.transformExpression(expression)))); +} + +export function flattenSpreadExpressions( + context: TransformationContext, + expressions: readonly ts.Expression[] +): lua.Expression[] { + const [preSpreadExpressions, postSpreadExpressions] = getExpressionsBeforeAndAfterFirstSpread(expressions); + const transformedPreSpreadExpressions = preSpreadExpressions.map(a => context.transformExpression(a)); + + // Nothing special required + if (postSpreadExpressions.length === 0) { + return transformedPreSpreadExpressions; + } + + // Only one spread element at the end? Will work as expected + if (postSpreadExpressions.length === 1) { + return [...transformedPreSpreadExpressions, context.transformExpression(postSpreadExpressions[0])]; + } + + // Use Array.concat and unpack the result of that as the last Expression + const concatArguments = transformSpreadableExpressionsIntoArrayConcatArguments(context, postSpreadExpressions); + const lastExpression = createUnpackCall( + context, + transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, undefined, ...concatArguments) + ); + + return [...transformedPreSpreadExpressions, lastExpression]; +} + export function transformArguments( context: TransformationContext, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression ): lua.Expression[] { - const parameters = params.map(param => context.transformExpression(param)); + const parameters = flattenSpreadExpressions(context, params); // Add context as first param if present if (callContext) { diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 85a601bb1..6544367a2 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -9,6 +9,7 @@ import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from ".. import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; +import { flattenSpreadExpressions } from "./call"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -128,13 +129,10 @@ const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { - const values = expression.elements.map(element => - lua.createTableFieldExpression( - ts.isOmittedExpression(element) ? lua.createNilLiteral(element) : context.transformExpression(element), - undefined, - element - ) + const filteredElements = expression.elements.map(e => + ts.isOmittedExpression(e) ? ts.createIdentifier("undefined") : e ); + const values = flattenSpreadExpressions(context, filteredElements).map(e => lua.createTableFieldExpression(e)); return lua.createTableExpression(values, expression); }; diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 9f6f19ae4..0a54e3a41 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -1,10 +1,71 @@ import * as tstl from "../../src"; import * as util from "../util"; +import { formatCode } from "../util"; // TODO: Make some utils for testing other targets const expectUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch(/[^.]unpack\(/); const expectTableUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("table.unpack"); +const arrayLiteralCases = [ + "1, 2, ...[3, 4, 5]", + "...[1, 2], 3, 4, 5", + "1, ...[[2]], 3", + "...[1, 2, 3], 4, ...[5, 6]", + "1, 2, ...[3, 4], ...[5, 6]", +]; + +const tupleReturnDefinition = ` +/** @tupleReturn */ +function tuple(...args: any[]) { + return args; +}`; + +describe.each(["function call", "array literal"] as const)("in %s", kind => { + // prettier-ignore + const factory = (code: string) => kind === "function call" + ? `((...args: any[]) => args)(${code})` + : `[${code}]`; + + test.each(arrayLiteralCases)("of array literal (%p)", expression => { + util.testExpression(factory(expression)).expectToMatchJsResult(); + }); + + test.each(arrayLiteralCases)("of tuple return call (%p)", expression => { + util.testFunction` + ${tupleReturnDefinition} + return ${factory(`...tuple(${expression})`)}; + `.expectToMatchJsResult(); + }); + + test("of multiple string literals", () => { + util.testExpression(factory('..."spread", ..."string"')).expectToMatchJsResult(); + }); + + test.each(["", "string", "string with spaces", "string 1 2 3"])("of string literal (%p)", str => { + util.testExpression(factory(`...${formatCode(str)}`)).expectToMatchJsResult(); + }); + + test("of iterable", () => { + util.testFunction` + const it = { + i: -1, + [Symbol.iterator]() { + return this; + }, + next() { + ++this.i; + return { + value: 2 ** this.i, + done: this.i == 9, + } + } + }; + + return ${factory("...it")}; + `.expectToMatchJsResult(); + }); +}); + describe("in function call", () => { util.testEachVersion( undefined, @@ -12,7 +73,6 @@ describe("in function call", () => { function foo(a: number, b: number, ...rest: number[]) { return { a, b, rest } } - const array = [0, 1, 2, 3] as const; return foo(...array); `, @@ -26,34 +86,17 @@ describe("in function call", () => { }); describe("in array literal", () => { - util.testEachVersion("of array literal", () => util.testExpression`[...[0, 1, 2]]`, { + util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); - test.each(["", "string", "string with spaces", "string 1 2 3"])("of string literal (%p)", str => { - util.testExpressionTemplate`[...${str}]`.expectToMatchJsResult(); - }); - - test("of iterable", () => { + test("of array literal /w OmittedExpression", () => { util.testFunction` - const it = { - i: -1, - [Symbol.iterator]() { - return this; - }, - next() { - ++this.i; - return { - value: 2 ** this.i, - done: this.i == 9, - } - } - }; - - return [...it] + const array = [1, 2, ...[3], , 5]; + return { a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); }); From 9bef35de6544dac67bc60a34e5074149bba57d48 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 16 Mar 2020 01:45:56 +0500 Subject: [PATCH 241/764] Load plugins from `tsconfig.json` (#773) * Load plugins from `tsconfig.json` * Refactor `transformers.spec.ts` test * Add few basic tests * Resolve `ts-node` on behalf of the root application * Merge plugin and transformer diagnostics * Refactor tests * Fix CJS factory loading * Add description to `luaPlugins` option * Add changelog entry * Rename `luaPlugins.plugin` to `luaPlugins.name` --- CHANGELOG.md | 10 +++ src/CompilerOptions.ts | 6 ++ src/cli/parse.ts | 18 ++-- src/transpilation/diagnostics.ts | 15 ++-- src/transpilation/index.ts | 1 + src/transpilation/plugins.ts | 31 +++++-- src/transpilation/transformers.ts | 77 ++++------------ src/transpilation/transpile.ts | 8 +- src/transpilation/utils.ts | 51 +++++++++++ test/transpile/plugins/plugins.spec.ts | 24 +++++ test/transpile/plugins/printer.ts | 12 +++ test/transpile/plugins/visitor-super.ts | 19 ++++ test/transpile/plugins/visitor.ts | 11 +++ test/transpile/resolve-plugin/cjs.js | 1 + test/transpile/resolve-plugin/import.ts | 1 + .../resolve-plugin/resolve-plugin.spec.ts | 27 ++++++ .../resolve-plugin/transpiled-esm.js | 2 + test/transpile/resolve-plugin/ts.ts | 2 + .../transformers/fixtures.ts} | 18 ++-- .../transformers/transformers.spec.ts | 36 ++++++++ .../{unit => transpile}/transformers/utils.ts | 0 test/unit/transformers/import.ts | 9 -- test/unit/transformers/resolve.js | 11 --- test/unit/transformers/resolve.ts | 9 -- test/unit/transformers/transformers.spec.ts | 87 ------------------- 25 files changed, 276 insertions(+), 210 deletions(-) create mode 100644 src/transpilation/utils.ts create mode 100644 test/transpile/plugins/plugins.spec.ts create mode 100644 test/transpile/plugins/printer.ts create mode 100644 test/transpile/plugins/visitor-super.ts create mode 100644 test/transpile/plugins/visitor.ts create mode 100644 test/transpile/resolve-plugin/cjs.js create mode 100644 test/transpile/resolve-plugin/import.ts create mode 100644 test/transpile/resolve-plugin/resolve-plugin.spec.ts create mode 100644 test/transpile/resolve-plugin/transpiled-esm.js create mode 100644 test/transpile/resolve-plugin/ts.ts rename test/{unit/transformers/types.ts => transpile/transformers/fixtures.ts} (73%) create mode 100644 test/transpile/transformers/transformers.spec.ts rename test/{unit => transpile}/transformers/utils.ts (100%) delete mode 100644 test/unit/transformers/import.ts delete mode 100644 test/unit/transformers/resolve.js delete mode 100644 test/unit/transformers/resolve.ts delete mode 100644 test/unit/transformers/transformers.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index ef3c2229d..b7ff3a76b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,16 @@ end ``` +- Added `tstl.luaPlugins` option, allowing to specify plugins in a `tsconfig.json` file: + + ```json + { + "tstl": { + "luaPlugins": [{ "name": "./plugin.ts" }] + } + } + ``` + ## 0.31.0 - **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 48c8abe82..5a6291098 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -18,6 +18,11 @@ export interface TransformerImport { [option: string]: any; } +export interface LuaPluginImport { + name: string; + import?: string; +} + export type CompilerOptions = OmitIndexSignature & { noImplicitSelf?: boolean; noHeader?: boolean; @@ -26,6 +31,7 @@ export type CompilerOptions = OmitIndexSignature & { luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; sourceMapTraceback?: boolean; + luaPlugins?: LuaPluginImport[]; plugins?: Array; [option: string]: any; }; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 9f05f2f9c..ce0985913 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -17,15 +17,11 @@ interface CommandLineOptionOfEnum extends CommandLineOptionBase { choices: string[]; } -interface CommandLineOptionOfBoolean extends CommandLineOptionBase { - type: "boolean"; +interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { + type: "boolean" | "string" | "object"; } -interface CommandLineOptionOfString extends CommandLineOptionBase { - type: "string"; -} - -type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfBoolean | CommandLineOptionOfString; +type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; export const optionDeclarations: CommandLineOption[] = [ { @@ -66,6 +62,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "Applies the source map to show source TS files and lines in error tracebacks.", type: "boolean", }, + { + name: "luaPlugins", + description: "List of TypeScriptToLua plugins.", + type: "object", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { @@ -173,8 +174,9 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { if (value === null) return { value }; switch (option.type) { + case "boolean": case "string": - case "boolean": { + case "object": { if (typeof value !== option.type) { return { value: undefined, diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 9467bb606..80b68088e 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -4,17 +4,18 @@ import { createSerialDiagnosticFactory } from "../utils"; const createDiagnosticFactory = (getMessage: (...args: TArgs) => string) => createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args) })); -export const toLoadTransformerItShouldBeTranspiled = createDiagnosticFactory( - (transform: string) => - `To load "${transform}" transformer it should be transpiled or "ts-node" should be installed.` +export const toLoadItShouldBeTranspiled = createDiagnosticFactory( + (kind: string, transform: string) => + `To load "${transform}" ${kind} it should be transpiled or "ts-node" should be installed.` ); -export const couldNotResolveTransformerFrom = createDiagnosticFactory( - (transform: string, base: string) => `Could not resolve "${transform}" transformer from "${base}".` +export const couldNotResolveFrom = createDiagnosticFactory( + (kind: string, transform: string, base: string) => `Could not resolve "${transform}" ${kind} from "${base}".` ); -export const transformerShouldHaveAExport = createDiagnosticFactory( - (transform: string, importName: string) => `"${transform}" transformer should have a "${importName}" export.` +export const shouldHaveAExport = createDiagnosticFactory( + (kind: string, transform: string, importName: string) => + `"${transform}" ${kind} should have a "${importName}" export.` ); export const transformerShouldBeATsTransformerFactory = createDiagnosticFactory( diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 530fbdd4c..1d15e59c4 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -7,6 +7,7 @@ import { emitTranspiledFiles, OutputFile } from "./emit"; import { transpile, TranspiledFile, TranspileResult } from "./transpile"; export * from "./emit"; +export { Plugin } from "./plugins"; export * from "./transpile"; export interface TranspileFilesResult { diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 8731211d6..0311efbbd 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -1,6 +1,8 @@ import * as ts from "typescript"; +import { CompilerOptions } from "../CompilerOptions"; import { Printer } from "../LuaPrinter"; import { Visitors } from "../transformation/context"; +import { getConfigDirectory, resolvePlugin } from "./utils"; export interface Plugin { /** @@ -18,10 +20,27 @@ export interface Plugin { printer?: Printer; } -export function getPlugins( - _program: ts.Program, - _diagnostics: ts.Diagnostic[], - pluginsFromOptions: Plugin[] -): Plugin[] { - return pluginsFromOptions; +export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], customPlugins: Plugin[]): Plugin[] { + const pluginsFromOptions: Plugin[] = []; + const options = program.getCompilerOptions() as CompilerOptions; + + for (const [index, pluginOption] of (options.luaPlugins ?? []).entries()) { + const optionName = `tstl.luaPlugins[${index}]`; + + const { error: resolveError, result: factory } = resolvePlugin( + "plugin", + `${optionName}.name`, + getConfigDirectory(options), + pluginOption.name, + pluginOption.import + ); + + if (resolveError) diagnostics.push(resolveError); + if (factory === undefined) continue; + + const plugin = typeof factory === "function" ? factory(pluginOption) : factory; + pluginsFromOptions.push(plugin); + } + + return [...customPlugins, ...pluginsFromOptions]; } diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index 71371e208..cefb4dd90 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -1,10 +1,9 @@ -import * as path from "path"; -import * as resolve from "resolve"; import * as ts from "typescript"; // TODO: Don't depend on CLI? import * as cliDiagnostics from "../cli/diagnostics"; import { CompilerOptions, TransformerImport } from "../CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; +import { getConfigDirectory, resolvePlugin } from "./utils"; export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => { const transformSourceFile: ts.Transformer = node => { @@ -18,7 +17,7 @@ export const noImplicitSelfTransformer: ts.TransformerFactory = { before: [], after: [], @@ -64,19 +63,23 @@ function loadTransformersFromOptions(program: ts.Program, allDiagnostics: ts.Dia const options = program.getCompilerOptions() as CompilerOptions; if (!options.plugins) return customTransformers; - const configFileName = options.configFilePath as string | undefined; - const basedir = configFileName ? path.dirname(configFileName) : process.cwd(); - for (const [index, transformerImport] of options.plugins.entries()) { if (!("transform" in transformerImport)) continue; const optionName = `compilerOptions.plugins[${index}]`; - const { error: resolveError, factory } = resolveTransformerFactory(basedir, optionName, transformerImport); - if (resolveError) allDiagnostics.push(resolveError); + const { error: resolveError, result: factory } = resolvePlugin( + "transformer", + `${optionName}.transform`, + getConfigDirectory(options), + transformerImport.transform, + transformerImport.import + ); + + if (resolveError) diagnostics.push(resolveError); if (factory === undefined) continue; const { error: loadError, transformer } = loadTransformer(optionName, program, factory, transformerImport); - if (loadError) allDiagnostics.push(loadError); + if (loadError) diagnostics.push(loadError); if (transformer === undefined) continue; if (transformer.before) { @@ -103,12 +106,6 @@ type CompilerOptionsTransformerFactory = ( ) => Transformer; type TypeCheckerTransformerFactory = (typeChecker: ts.TypeChecker, options: Record) => Transformer; type RawTransformerFactory = Transformer; -type TransformerFactory = - | ProgramTransformerFactory - | ConfigTransformerFactory - | CompilerOptionsTransformerFactory - | TypeCheckerTransformerFactory - | RawTransformerFactory; type Transformer = GroupTransformer | ts.TransformerFactory; interface GroupTransformer { @@ -117,48 +114,10 @@ interface GroupTransformer { afterDeclarations?: ts.TransformerFactory; } -function resolveTransformerFactory( - basedir: string, - transformerOptionPath: string, - { transform, import: importName = "default" }: TransformerImport -): { error?: ts.Diagnostic; factory?: TransformerFactory } { - if (typeof transform !== "string") { - const optionName = `${transformerOptionPath}.transform`; - return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "string") }; - } - - let resolved: string; - try { - resolved = resolve.sync(transform, { basedir, extensions: [".js", ".ts", ".tsx"] }); - } catch (err) { - if (err.code !== "MODULE_NOT_FOUND") throw err; - return { error: diagnosticFactories.couldNotResolveTransformerFrom(transform, basedir) }; - } - - // tslint:disable-next-line: deprecation - const hasNoRequireHook = require.extensions[".ts"] === undefined; - if (hasNoRequireHook && (resolved.endsWith(".ts") || resolved.endsWith(".tsx"))) { - try { - const tsNode: typeof import("ts-node") = require("ts-node"); - tsNode.register({ transpileOnly: true }); - } catch (err) { - if (err.code !== "MODULE_NOT_FOUND") throw err; - return { error: diagnosticFactories.toLoadTransformerItShouldBeTranspiled(transform) }; - } - } - - const factory: TransformerFactory = require(resolved)[importName]; - if (factory === undefined) { - return { error: diagnosticFactories.transformerShouldHaveAExport(transform, importName) }; - } - - return { factory }; -} - function loadTransformer( - transformerOptionPath: string, + optionPath: string, program: ts.Program, - factory: TransformerFactory, + factory: unknown, { transform, after = false, afterDeclarations = false, type = "program", ...extraOptions }: TransformerImport ): { error?: ts.Diagnostic; transformer?: GroupTransformer } { let transformer: Transformer; @@ -179,18 +138,18 @@ function loadTransformer( transformer = (factory as CompilerOptionsTransformerFactory)(program.getCompilerOptions(), extraOptions); break; default: { - const optionName = `--${transformerOptionPath}.type`; + const optionName = `--${optionPath}.type`; return { error: cliDiagnostics.argumentForOptionMustBe(optionName, "program") }; } } if (typeof after !== "boolean") { - const optionName = `${transformerOptionPath}.after`; + const optionName = `${optionPath}.after`; return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "boolean") }; } if (typeof afterDeclarations !== "boolean") { - const optionName = `${transformerOptionPath}.afterDeclarations`; + const optionName = `${optionPath}.afterDeclarations`; return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "boolean") }; } diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index df8214718..9046477e8 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -7,7 +7,7 @@ import { createVisitorMap, transformSourceFile } from "../transformation"; import { isNonNull } from "../utils"; import { bundleTranspiledFiles } from "./bundle"; import { getPlugins, Plugin } from "./plugins"; -import { getCustomTransformers } from "./transformers"; +import { getTransformers } from "./transformers"; export interface TranspiledFile { fileName: string; @@ -42,7 +42,7 @@ export function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, - plugins: pluginsFromOptions = [], + plugins: customPlugins = [], emitHost = ts.sys, }: TranspileOptions): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; @@ -85,7 +85,7 @@ export function transpile({ } } - const plugins = getPlugins(program, diagnostics, pluginsFromOptions); + const plugins = getPlugins(program, diagnostics, customPlugins); const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { @@ -107,7 +107,7 @@ export function transpile({ } }; - const transformers = getCustomTransformers(program, diagnostics, customTransformers, processSourceFile); + const transformers = getTransformers(program, diagnostics, customTransformers, processSourceFile); const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { for (const sourceFile of sourceFiles) { diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts new file mode 100644 index 000000000..e6f975be4 --- /dev/null +++ b/src/transpilation/utils.ts @@ -0,0 +1,51 @@ +import * as path from "path"; +import * as resolve from "resolve"; +import * as ts from "typescript"; +// TODO: Don't depend on CLI? +import * as cliDiagnostics from "../cli/diagnostics"; +import * as diagnosticFactories from "./diagnostics"; + +export const getConfigDirectory = (options: ts.CompilerOptions) => + options.configFilePath ? path.dirname(options.configFilePath) : process.cwd(); + +export function resolvePlugin( + kind: string, + optionName: string, + basedir: string, + query: string, + importName = "default" +): { error?: ts.Diagnostic; result?: unknown } { + if (typeof query !== "string") { + return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "string") }; + } + + let resolved: string; + try { + resolved = resolve.sync(query, { basedir, extensions: [".js", ".ts", ".tsx"] }); + } catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + return { error: diagnosticFactories.couldNotResolveFrom(kind, query, basedir) }; + } + + // tslint:disable-next-line: deprecation + const hasNoRequireHook = require.extensions[".ts"] === undefined; + if (hasNoRequireHook && (resolved.endsWith(".ts") || resolved.endsWith(".tsx"))) { + try { + const tsNodePath = resolve.sync("ts-node", { basedir }); + const tsNode: typeof import("ts-node") = require(tsNodePath); + tsNode.register({ transpileOnly: true }); + } catch (err) { + if (err.code !== "MODULE_NOT_FOUND") throw err; + return { error: diagnosticFactories.toLoadItShouldBeTranspiled(kind, query) }; + } + } + + const commonjsModule = require(resolved); + const factoryModule = commonjsModule.__esModule ? commonjsModule : { default: commonjsModule }; + const result = factoryModule[importName]; + if (result === undefined) { + return { error: diagnosticFactories.shouldHaveAExport(kind, query, importName) }; + } + + return { result }; +} diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts new file mode 100644 index 000000000..ce2ebc7a6 --- /dev/null +++ b/test/transpile/plugins/plugins.spec.ts @@ -0,0 +1,24 @@ +import * as path from "path"; +import * as util from "../../util"; + +test("printer", () => { + util.testModule`` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "printer.ts") }] }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toMatch("Plugin")); +}); + +test("visitor", () => { + util.testFunction` + return false; + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "visitor.ts") }] }) + .expectToEqual(true); +}); + +test("visitor using super", () => { + util.testFunction` + return "foo"; + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "visitor-super.ts") }] }) + .expectToEqual("bar"); +}); diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts new file mode 100644 index 000000000..771f0f4a6 --- /dev/null +++ b/test/transpile/plugins/printer.ts @@ -0,0 +1,12 @@ +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + printer: (program, emitHost, fileName, ...args) => { + const result = new tstl.LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args); + result.code = `-- Plugin\n${result.code}`; + return result; + }, +}; + +// tslint:disable-next-line: no-default-export +export default plugin; diff --git a/test/transpile/plugins/visitor-super.ts b/test/transpile/plugins/visitor-super.ts new file mode 100644 index 000000000..87f665749 --- /dev/null +++ b/test/transpile/plugins/visitor-super.ts @@ -0,0 +1,19 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + visitors: { + [ts.SyntaxKind.StringLiteral]: (node, context) => { + const result = context.superTransformExpression(node); + + if (tstl.isStringLiteral(result)) { + result.value = "bar"; + } + + return result; + }, + }, +}; + +// tslint:disable-next-line: no-default-export +export default plugin; diff --git a/test/transpile/plugins/visitor.ts b/test/transpile/plugins/visitor.ts new file mode 100644 index 000000000..fdbf50782 --- /dev/null +++ b/test/transpile/plugins/visitor.ts @@ -0,0 +1,11 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + visitors: { + [ts.SyntaxKind.ReturnStatement]: () => tstl.createReturnStatement([tstl.createBooleanLiteral(true)]), + }, +}; + +// tslint:disable-next-line: no-default-export +export default plugin; diff --git a/test/transpile/resolve-plugin/cjs.js b/test/transpile/resolve-plugin/cjs.js new file mode 100644 index 000000000..ec01c2c14 --- /dev/null +++ b/test/transpile/resolve-plugin/cjs.js @@ -0,0 +1 @@ +module.exports = true; diff --git a/test/transpile/resolve-plugin/import.ts b/test/transpile/resolve-plugin/import.ts new file mode 100644 index 000000000..3d831e6ad --- /dev/null +++ b/test/transpile/resolve-plugin/import.ts @@ -0,0 +1 @@ +export const named = true; diff --git a/test/transpile/resolve-plugin/resolve-plugin.spec.ts b/test/transpile/resolve-plugin/resolve-plugin.spec.ts new file mode 100644 index 000000000..7b48bad8f --- /dev/null +++ b/test/transpile/resolve-plugin/resolve-plugin.spec.ts @@ -0,0 +1,27 @@ +import * as path from "path"; +import { resolvePlugin } from "../../../src/transpilation/utils"; + +test("resolve relative module paths", () => { + const result = resolvePlugin("test", "test", __dirname, "./ts.ts"); + expect(result).toMatchObject({ result: true }); +}); + +test("load .ts modules", () => { + const result = resolvePlugin("test", "test", __dirname, path.join(__dirname, "ts.ts")); + expect(result).toMatchObject({ result: true }); +}); + +test("load CJS .js modules", () => { + const result = resolvePlugin("test", "test", __dirname, path.join(__dirname, "cjs.js")); + expect(result).toMatchObject({ result: true }); +}); + +test("load transpiled ESM .js modules", () => { + const result = resolvePlugin("test", "test", __dirname, path.join(__dirname, "transpiled-esm.js")); + expect(result).toMatchObject({ result: true }); +}); + +test('"import" option', () => { + const result = resolvePlugin("test", "test", __dirname, path.join(__dirname, "import.ts"), "named"); + expect(result).toMatchObject({ result: true }); +}); diff --git a/test/transpile/resolve-plugin/transpiled-esm.js b/test/transpile/resolve-plugin/transpiled-esm.js new file mode 100644 index 000000000..ebf774058 --- /dev/null +++ b/test/transpile/resolve-plugin/transpiled-esm.js @@ -0,0 +1,2 @@ +module.exports.__esModule = true; +module.exports.default = true; diff --git a/test/transpile/resolve-plugin/ts.ts b/test/transpile/resolve-plugin/ts.ts new file mode 100644 index 000000000..0622167b7 --- /dev/null +++ b/test/transpile/resolve-plugin/ts.ts @@ -0,0 +1,2 @@ +// tslint:disable-next-line: no-default-export +export default true; diff --git a/test/unit/transformers/types.ts b/test/transpile/transformers/fixtures.ts similarity index 73% rename from test/unit/transformers/types.ts rename to test/transpile/transformers/fixtures.ts index dc8ecf71c..c998d6efc 100644 --- a/test/unit/transformers/types.ts +++ b/test/transpile/transformers/fixtures.ts @@ -1,3 +1,4 @@ +import * as assert from "assert"; import * as ts from "typescript"; import * as tstl from "../../../src"; import { visitAndReplace } from "./utils"; @@ -7,7 +8,7 @@ export const program = (program: ts.Program, options: { value: any }): ts.Transf export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || node.expression) return; + if (!ts.isReturnStatement(node)) return; return ts.updateReturn(node, ts.createLiteral(value)); }); @@ -24,19 +25,16 @@ export const checker = ( export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || node.expression) return; + if (!ts.isReturnStatement(node)) return; return ts.updateReturn(node, ts.createLiteral(true)); }); -export const compilerOptions = ({ - luaTarget, -}: tstl.CompilerOptions): ts.TransformerFactory => context => file => { - if (luaTarget !== tstl.LuaTarget.LuaJIT) { - throw new Error("Transformer supports only LuaJIT target"); - } - +export const compilerOptions = ( + options: tstl.CompilerOptions +): ts.TransformerFactory => context => file => { + assert(options.plugins?.length === 1); return visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || node.expression) return; + if (!ts.isReturnStatement(node)) return; return ts.updateReturn(node, ts.createLiteral(true)); }); }; diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts new file mode 100644 index 000000000..e166198bd --- /dev/null +++ b/test/transpile/transformers/transformers.spec.ts @@ -0,0 +1,36 @@ +import * as path from "path"; +import * as util from "../../util"; + +test("ignore language service plugins", () => { + util.testFunction` + return false; + ` + .setOptions({ plugins: [{ name: path.join(__dirname, "types.ts") }] }) + .expectToEqual(false); +}); + +test("default type", () => { + util.testFunction` + return false; + ` + .setOptions({ plugins: [{ transform: path.join(__dirname, "fixtures.ts"), import: "program", value: true }] }) + .expectToEqual(true); +}); + +test("transformer resolution error", () => { + util.testModule`` + .setOptions({ plugins: [{ transform: path.join(__dirname, "error.ts") }] }) + .expectToHaveDiagnostics(); +}); + +describe("factory types", () => { + test.each(["program", "config", "checker", "raw", "compilerOptions"] as const)("%s", type => { + util.testFunction` + return false; + ` + .setOptions({ + plugins: [{ transform: path.join(__dirname, "fixtures.ts"), type, import: type, value: true }], + }) + .expectToEqual(true); + }); +}); diff --git a/test/unit/transformers/utils.ts b/test/transpile/transformers/utils.ts similarity index 100% rename from test/unit/transformers/utils.ts rename to test/transpile/transformers/utils.ts diff --git a/test/unit/transformers/import.ts b/test/unit/transformers/import.ts deleted file mode 100644 index 8dafa5886..000000000 --- a/test/unit/transformers/import.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as ts from "typescript"; -import { visitAndReplace } from "./utils"; - -// tslint:disable-next-line: no-default-export -export const transformer = (): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || node.expression) return; - return ts.updateReturn(node, ts.createLiteral(true)); - }); diff --git a/test/unit/transformers/resolve.js b/test/unit/transformers/resolve.js deleted file mode 100644 index 3ba87c73f..000000000 --- a/test/unit/transformers/resolve.js +++ /dev/null @@ -1,11 +0,0 @@ -const ts = require("typescript"); - -module.exports.default = () => context => file => { - const replaceNode = node => { - if (!ts.isReturnStatement(node) || node.expression) return; - return ts.updateReturn(node, ts.createLiteral(true)); - }; - - const visit = node => replaceNode(node) || ts.visitEachChild(node, visit, context); - return ts.visitNode(file, visit); -}; diff --git a/test/unit/transformers/resolve.ts b/test/unit/transformers/resolve.ts deleted file mode 100644 index 8b0aacff7..000000000 --- a/test/unit/transformers/resolve.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as ts from "typescript"; -import { visitAndReplace } from "./utils"; - -// tslint:disable-next-line: no-default-export -export default (): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || node.expression) return; - return ts.updateReturn(node, ts.createLiteral(true)); - }); diff --git a/test/unit/transformers/transformers.spec.ts b/test/unit/transformers/transformers.spec.ts deleted file mode 100644 index db36c27dc..000000000 --- a/test/unit/transformers/transformers.spec.ts +++ /dev/null @@ -1,87 +0,0 @@ -import * as path from "path"; -import * as tstl from "../../../src"; -import * as util from "../../util"; - -const optionsOfTransformer = (transformer: tstl.TransformerImport): tstl.CompilerOptions => ({ - plugins: [transformer], -}); - -test("should ignore language service plugins", () => { - const options: tstl.CompilerOptions = { - plugins: [{ name: path.join(__dirname, "resolve.ts") }], - }; - - expect(util.transpileAndExecute("return", options)).toBe(undefined); -}); - -describe("resolution", () => { - const testTransform = (transformer: tstl.TransformerImport) => { - const options = optionsOfTransformer(transformer); - expect(util.transpileAndExecute("return", options)).toBe(true); - }; - - test("should resolve relative transformer paths", () => { - jest.spyOn(process, "cwd").mockReturnValue(__dirname); - testTransform({ transform: "./resolve.ts" }); - }); - - test("should load js transformers", () => { - testTransform({ transform: path.join(__dirname, "resolve.js") }); - }); - - test("should load ts transformers", () => { - testTransform({ transform: path.join(__dirname, "resolve.ts") }); - }); - - test('should support "import" option', () => { - testTransform({ - transform: path.join(__dirname, "import.ts"), - import: "transformer", - }); - }); - - test("should error if transformer could not be resolved", () => { - const transform = path.join(__dirname, "error.ts"); - const options = optionsOfTransformer({ transform }); - const { diagnostics } = util.transpileStringResult("", options); - expect(diagnostics).toHaveDiagnostics(); - }); -}); - -describe("factory types", () => { - const value = "foo"; - const getOptions = (options: Partial) => - optionsOfTransformer({ - transform: path.join(__dirname, "types.ts"), - ...options, - }); - - test('should support "program" type', () => { - const options = getOptions({ type: "program", import: "program", value }); - expect(util.transpileAndExecute("return false", options)).toBe(value); - }); - - test('should support "config" type', () => { - const options = getOptions({ type: "config", import: "config", value }); - expect(util.transpileAndExecute("return", options)).toBe(value); - }); - - test('should support "checker" type', () => { - const options = getOptions({ type: "checker", import: "checker", value }); - expect(util.transpileAndExecute("return false", options)).toBe(value); - }); - - test('should support "raw" type', () => { - const options = getOptions({ type: "raw", import: "raw" }); - expect(util.transpileAndExecute("return", options)).toBe(true); - }); - - test('should support "compilerOptions" type', () => { - const options: tstl.CompilerOptions = { - ...getOptions({ type: "compilerOptions", import: "compilerOptions" }), - luaTarget: tstl.LuaTarget.LuaJIT, - }; - - expect(util.transpileAndExecute("return", options)).toBe(true); - }); -}); From 2d938b8e67858794a458ca7d658fbe86e1892019 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 15 Mar 2020 21:59:05 +0100 Subject: [PATCH 242/764] 0.32.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index f273f0895..7806d20d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.31.0", + "version": "0.32.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b19aaf950..cb25b2809 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.31.0", + "version": "0.32.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 3ad73bbf07d062f265918eeb00f41cd9294a4d02 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 15 Mar 2020 22:24:33 +0100 Subject: [PATCH 243/764] Changelog 0.32.0 --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7ff3a76b..44d99e44d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog -## Unreleased +## 0.32.0 + +- **Deprecated:** The `noHoisting` option has been removed, hoisting will always be done. - TypeScript has been updated to 3.8. See [release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html) for details. @@ -52,26 +54,14 @@ This change simplifies our codebase and opens a path to object accessors implementation -- Errors reported during transpilation now are created as TypeScript diagnostics, instead of being thrown as JavaScript errors. This makes TypeScriptToLua always try to generate valid code (even in presence of errors) and allows multiple errors to be reported in a single file: +- Errors reported during transpilation now are created as TypeScript diagnostics instead of being thrown as JavaScript errors. This makes TypeScriptToLua always try to generate valid code (even in presence of errors) and allows multiple errors to be reported in a single file: - ```ts - for (var x in []) {} - ``` - - ```shell - # Before - - $ tstl file.ts - file.ts:1:1 - error TSTL: Iterating over arrays with 'for ... in' is not allowed. - - $ cat file.lua - error("Iterating over arrays with 'for ... in' is not allowed.") + for (var x in []) { + } ``` ```shell - # Now - $ tstl file.ts file.ts:1:1 - error TSTL: Iterating over arrays with 'for ... in' is not allowed. file.ts:1:6 - error TSTL: `var` declarations are not supported. Use `let` or `const` instead. @@ -91,6 +81,28 @@ } ``` +- Added support for all valid TS `for ... of` loop variable patterns. + +- Fixed a bug where spread expressions in array literals were not correctly translated: + + ```diff + - [1, ...[2, 3], 4] // --> { 1, 2, 4 } + + [1, ...[2, 3], 4] // --> { 1, 2, 3, 4 } + + - ((...values) => values)(1, ...[2, 3], 4) // --> { 1, 2, 4 } + + ((...values) => values)(1, ...[2, 3], 4) // --> { 1, 2, 3, 4 } + ``` + +- Fixed Lua error when left hand side of `instanceof` was not a table type. + +- Fixed `sourcemapTraceback` function returning a value different from the standard Lua result in 5.1. + +- Fixed missing LuaLib dependency for Error LuaLib function. + +- Fixed several issues with exported identifiers breaking `for ... in` loops and some default class code. + +- Fixed overflowing numbers transforming to undefined Infinity, instead they are now transformed to `math.huge`. + ## 0.31.0 - **Breaking:** The old annotation syntax (`/* !varArg */`) **no longer works**, the only currently supported syntax is: From cd23caf21f96451ace500b67396cf0002b2763af Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 28 Mar 2020 21:16:03 +0500 Subject: [PATCH 244/764] Small improvements (#842) * Small improvements * Replace `expectToBeDefined` with assertion signature * Refactor some tests * Fix type error * Don't elide empty `do` blocks * Fix semicolons test * Remove npm version bump scripts --- .codecov.yml | 6 +- .gitignore | 8 +- .prettierrc.js | 10 -- .prettierrc.json | 7 ++ package.json | 3 - src/LuaAST.ts | 50 +++------ src/LuaPrinter.ts | 100 ++++-------------- src/cli/information.ts | 2 +- src/transformation/context/context.ts | 11 +- src/transformation/utils/annotations.ts | 6 +- .../utils/assignment-validation.ts | 17 +-- src/transformation/utils/lua-ast.ts | 17 +-- src/transformation/visitors/call.ts | 4 +- src/transformation/visitors/class/index.ts | 1 - .../visitors/class/members/accessors.ts | 8 +- .../visitors/class/members/constructor.ts | 8 +- .../visitors/class/members/method.ts | 1 - src/transformation/visitors/conditional.ts | 1 - src/transformation/visitors/errors.ts | 2 +- src/transformation/visitors/function.ts | 6 +- src/transformation/visitors/loops/for-of.ts | 7 +- src/utils.ts | 35 +++--- test/legacy-utils.ts | 4 +- test/tsconfig.json | 16 +-- .../__snapshots__/assignments.spec.ts.snap | 16 +-- test/unit/annotations/vararg.spec.ts | 10 +- test/unit/assignments.spec.ts | 70 ++++++------ test/unit/functions/functions.spec.ts | 11 ++ .../functions/noImplicitSelfOption.spec.ts | 12 +-- test/unit/modules/resolution.spec.ts | 6 +- test/unit/namespaces.spec.ts | 35 ++++-- .../__snapshots__/semicolons.spec.ts.snap | 63 +++++++++++ test/unit/printer/semicolons.spec.ts | 9 +- test/unit/printer/sourcemaps.spec.ts | 9 +- test/unit/spread.spec.ts | 17 ++- test/util.ts | 43 ++------ tsconfig.json | 21 ++-- 37 files changed, 295 insertions(+), 357 deletions(-) delete mode 100644 .prettierrc.js create mode 100644 .prettierrc.json create mode 100644 test/unit/printer/__snapshots__/semicolons.spec.ts.snap diff --git a/.codecov.yml b/.codecov.yml index d8bafa304..8fcaf7415 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,4 +1,4 @@ -comment: off +comment: false coverage: status: @@ -7,5 +7,5 @@ coverage: target: 90 threshold: null base: auto - changes: off - patch: off + changes: false + patch: false diff --git a/.gitignore b/.gitignore index 0878aa261..09a293fc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,8 @@ -/node_modules +node_modules /dist /coverage yarn.lock .vscode .idea - -# Release -*.tgz - -# OSX .DS_Store -*.lcov diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index e9fb0b291..000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,10 +0,0 @@ -const isCI = require("is-ci"); - -/** @type {import("prettier").Options} */ -module.exports = { - printWidth: 120, - tabWidth: 4, - trailingComma: "es5", - endOfLine: isCI ? "lf" : "auto", - overrides: [{ files: ["**/*.md", "**/*.yml"], options: { tabWidth: 2 } }], -}; diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..f8774a2f2 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "trailingComma": "es5", + "endOfLine": "lf", + "overrides": [{ "files": ["**/*.md", "**/*.yml"], "options": { "tabWidth": 2 } }] +} diff --git a/package.json b/package.json index cb25b2809..be2ebd2d4 100644 --- a/package.json +++ b/package.json @@ -26,9 +26,6 @@ "lint:prettier": "prettier --check \"**/*.{js,ts,yml,json,md}\" || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:tslint": "tslint -p . && tslint -p test && tslint -p src/lualib", "fix:prettier": "prettier --check --write \"**/*.{js,ts,yml,json,md}\"", - "release-major": "npm version major", - "release-minor": "npm version minor", - "release-patch": "npm version patch", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 8ab4f7417..d39639213 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,6 +5,7 @@ // because we don't create the AST from text import * as ts from "typescript"; +import { castArray } from "./utils"; export enum SyntaxKind { Block, @@ -236,14 +237,8 @@ export function createVariableDeclarationStatement( tsOriginal?: ts.Node ): VariableDeclarationStatement { const statement = createNode(SyntaxKind.VariableDeclarationStatement, tsOriginal) as VariableDeclarationStatement; - statement.left = Array.isArray(left) ? left : [left]; - - if (Array.isArray(right)) { - statement.right = right; - } else if (right) { - statement.right = [right]; - } - + statement.left = castArray(left); + if (right) statement.right = castArray(right); return statement; } @@ -264,14 +259,8 @@ export function createAssignmentStatement( tsOriginal?: ts.Node ): AssignmentStatement { const statement = createNode(SyntaxKind.AssignmentStatement, tsOriginal) as AssignmentStatement; - statement.left = Array.isArray(left) ? left : [left]; - - if (Array.isArray(right)) { - statement.right = right; - } else { - statement.right = right ? [right] : []; - } - + statement.left = castArray(left); + statement.right = right ? castArray(right) : []; return statement; } @@ -429,14 +418,14 @@ export function createLabelStatement(name: string, tsOriginal?: ts.Node): LabelS export interface ReturnStatement extends Statement { kind: SyntaxKind.ReturnStatement; - expressions?: Expression[]; + expressions: Expression[]; } export function isReturnStatement(node: Node): node is ReturnStatement { return node.kind === SyntaxKind.ReturnStatement; } -export function createReturnStatement(expressions?: Expression[], tsOriginal?: ts.Node): ReturnStatement { +export function createReturnStatement(expressions: Expression[], tsOriginal?: ts.Node): ReturnStatement { const statement = createNode(SyntaxKind.ReturnStatement, tsOriginal) as ReturnStatement; statement.expressions = expressions; return statement; @@ -496,11 +485,7 @@ export function isBooleanLiteral(node: Node): node is BooleanLiteral { } export function createBooleanLiteral(value: boolean, tsOriginal?: ts.Node): BooleanLiteral { - if (value) { - return createNode(SyntaxKind.TrueKeyword, tsOriginal) as BooleanLiteral; - } else { - return createNode(SyntaxKind.FalseKeyword, tsOriginal) as BooleanLiteral; - } + return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, tsOriginal) as BooleanLiteral; } // TODO Call this DotsLiteral or DotsKeyword? @@ -518,7 +503,7 @@ export function createDotsLiteral(tsOriginal?: ts.Node): DotsLiteral { // StringLiteral / NumberLiteral // TODO TS uses the export interface "LiteralLikeNode" with a "text: string" member -// but since we dont parse from text i think we can simplify by just having a value member +// but since we don't parse from text I think we can simplify by just having a value member // TODO NumericLiteral or NumberLiteral? export interface NumericLiteral extends Expression { @@ -552,16 +537,15 @@ export function createStringLiteral(value: string, tsOriginal?: ts.Node): String } export enum FunctionExpressionFlags { - None = 0x0, - Inline = 0x1, // Keep function on same line - Declaration = 0x2, // Prefer declaration syntax `function foo()` over assignment syntax `foo = function()` + None = 1 << 0, + Inline = 1 << 1, // Keep function body on same line + Declaration = 1 << 2, // Prefer declaration syntax `function foo()` over assignment syntax `foo = function()` } export interface FunctionExpression extends Expression { kind: SyntaxKind.FunctionExpression; params?: Identifier[]; dots?: DotsLiteral; - restParamName?: Identifier; body: Block; flags: FunctionExpressionFlags; } @@ -574,7 +558,6 @@ export function createFunctionExpression( body: Block, params?: Identifier[], dots?: DotsLiteral, - restParamName?: Identifier, flags = FunctionExpressionFlags.None, tsOriginal?: ts.Node ): FunctionExpression { @@ -582,7 +565,6 @@ export function createFunctionExpression( expression.body = body; expression.params = params; expression.dots = dots; - expression.restParamName = restParamName; expression.flags = flags; return expression; } @@ -671,7 +653,7 @@ export function createBinaryExpression( export interface CallExpression extends Expression { kind: SyntaxKind.CallExpression; expression: Expression; - params?: Expression[]; + params: Expression[]; } export function isCallExpression(node: Node): node is CallExpression { @@ -680,7 +662,7 @@ export function isCallExpression(node: Node): node is CallExpression { export function createCallExpression( expression: Expression, - params?: Expression[], + params: Expression[], tsOriginal?: ts.Node ): CallExpression { const callExpression = createNode(SyntaxKind.CallExpression, tsOriginal) as CallExpression; @@ -693,7 +675,7 @@ export interface MethodCallExpression extends Expression { kind: SyntaxKind.MethodCallExpression; prefixExpression: Expression; name: Identifier; - params?: Expression[]; + params: Expression[]; } export function isMethodCallExpression(node: Node): node is MethodCallExpression { @@ -703,7 +685,7 @@ export function isMethodCallExpression(node: Node): node is MethodCallExpression export function createMethodCallExpression( prefixExpression: Expression, name: Identifier, - params?: Expression[], + params: Expression[], tsOriginal?: ts.Node ): MethodCallExpression { const callExpression = createNode(SyntaxKind.MethodCallExpression, tsOriginal) as MethodCallExpression; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 816bb1aea..dc94c6b53 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -6,7 +6,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { trimExtension } from "./utils"; +import { intersperse, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -271,8 +271,6 @@ export class LuaPrinter { protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { const statementNodes: SourceNode[] = []; for (const [index, statement] of statements.entries()) { - if (this.isStatementEmpty(statement)) continue; - const node = this.printStatement(statement); if ( @@ -288,7 +286,7 @@ export class LuaPrinter { if (lua.isReturnStatement(statement)) break; } - return statementNodes.length > 0 ? [...this.joinChunks("\n", statementNodes), "\n"] : []; + return statementNodes.length > 0 ? [...intersperse(statementNodes, "\n"), "\n"] : []; } public printStatement(statement: lua.Statement): SourceNode { @@ -345,21 +343,11 @@ export class LuaPrinter { // Print all local functions as `local function foo()` instead of `local foo = function` to allow recursion chunks.push(this.printFunctionDefinition(statement)); } else { - chunks.push( - ...this.joinChunks( - ", ", - statement.left.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e)))); if (statement.right) { chunks.push(" = "); - chunks.push( - ...this.joinChunks( - ", ", - statement.right.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e)))); } } @@ -383,19 +371,9 @@ export class LuaPrinter { } } - chunks.push( - ...this.joinChunks( - ", ", - statement.left.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(statement.left.map(e => this.printExpression(e)))); chunks.push(" = "); - chunks.push( - ...this.joinChunks( - ", ", - statement.right.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(statement.right.map(e => this.printExpression(e)))); return this.createSourceNode(statement, chunks); } @@ -479,14 +457,8 @@ export class LuaPrinter { } public printForInStatement(statement: lua.ForInStatement): SourceNode { - const names = this.joinChunks( - ", ", - statement.names.map(i => this.printIdentifier(i)) - ); - const expressions = this.joinChunks( - ", ", - statement.expressions.map(e => this.printExpression(e)) - ); + const names = this.joinChunksWithComma(statement.names.map(i => this.printIdentifier(i))); + const expressions = this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e))); const chunks: SourceChunk[] = []; @@ -509,18 +481,13 @@ export class LuaPrinter { } public printReturnStatement(statement: lua.ReturnStatement): SourceNode { - if (!statement.expressions || statement.expressions.length === 0) { + if (statement.expressions.length === 0) { return this.createSourceNode(statement, this.indent("return")); } const chunks: SourceChunk[] = []; - chunks.push( - ...this.joinChunks( - ", ", - statement.expressions.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(statement.expressions.map(e => this.printExpression(e)))); return this.createSourceNode(statement, [this.indent(), "return ", ...chunks]); } @@ -587,23 +554,17 @@ export class LuaPrinter { } public printBooleanLiteral(expression: lua.BooleanLiteral): SourceNode { - if (expression.kind === lua.SyntaxKind.TrueKeyword) { - return this.createSourceNode(expression, "true"); - } else { - return this.createSourceNode(expression, "false"); - } + return this.createSourceNode(expression, expression.kind === lua.SyntaxKind.TrueKeyword ? "true" : "false"); } private printFunctionParameters(expression: lua.FunctionExpression): SourceChunk[] { - const parameterChunks: SourceNode[] = expression.params - ? expression.params.map(i => this.printIdentifier(i)) - : []; + const parameterChunks = (expression.params ?? []).map(i => this.printIdentifier(i)); if (expression.dots) { parameterChunks.push(this.printDotsLiteral(expression.dots)); } - return this.joinChunks(", ", parameterChunks); + return this.joinChunksWithComma(parameterChunks); } public printFunctionExpression(expression: lua.FunctionExpression): SourceNode { @@ -618,10 +579,7 @@ export class LuaPrinter { chunks.push(" "); const returnNode: SourceChunk[] = [ "return ", - ...this.joinChunks( - ", ", - returnStatement.expressions.map(e => this.printExpression(e)) - ), + ...this.joinChunksWithComma(returnStatement.expressions.map(e => this.printExpression(e))), ]; chunks.push(this.createSourceNode(returnStatement, returnNode)); chunks.push(this.createSourceNode(expression, " end")); @@ -770,38 +728,22 @@ export class LuaPrinter { return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } - protected isStatementEmpty(statement: lua.Statement): boolean { - return lua.isDoStatement(statement) && (!statement.statements || statement.statements.length === 0); - } - - protected joinChunks(separator: string, chunks: SourceChunk[]): SourceChunk[] { - const result = []; - for (let i = 0; i < chunks.length; i++) { - result.push(chunks[i]); - if (i < chunks.length - 1) { - result.push(separator); - } - } - return result; + protected joinChunksWithComma(chunks: SourceChunk[]): SourceChunk[] { + return intersperse(chunks, ", "); } protected printExpressionList(expressions: lua.Expression[]): SourceChunk[] { const chunks: SourceChunk[] = []; if (expressions.every(isSimpleExpression)) { - chunks.push( - ...this.joinChunks( - ", ", - expressions.map(e => this.printExpression(e)) - ) - ); + chunks.push(...this.joinChunksWithComma(expressions.map(e => this.printExpression(e)))); } else { chunks.push("\n"); this.pushIndent(); - expressions.forEach((p, i) => { - const tail = i < expressions.length - 1 ? ",\n" : "\n"; - chunks.push(this.indent(), this.printExpression(p), tail); - }); + for (const [index, expression] of expressions.entries()) { + const tail = index < expressions.length - 1 ? ",\n" : "\n"; + chunks.push(this.indent(), this.printExpression(expression), tail); + } this.popIndent(); chunks.push(this.indent()); } diff --git a/src/cli/information.ts b/src/cli/information.ts index 08ffb12f4..4c4b3ce1a 100644 --- a/src/cli/information.ts +++ b/src/cli/information.ts @@ -20,7 +20,7 @@ export function getHelpString(): string { result += "Options:\n"; for (const option of optionDeclarations) { const aliasStrings = (option.aliases ?? []).map(a => "-" + a); - const optionString = aliasStrings.concat(["--" + option.name]).join("|"); + const optionString = [...aliasStrings, "--" + option.name].join("|"); const valuesHint = option.type === "enum" ? option.choices.join("|") : option.type; const spacing = " ".repeat(Math.max(1, 45 - optionString.length - valuesHint.length)); diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index ebc8dfea1..ea375766b 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; +import { castArray } from "../../utils"; import { unwrapVisitorResult } from "../utils/lua-ast"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; @@ -87,16 +88,10 @@ export class TransformationContext { } public transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { - return Array.isArray(node) - ? node.flatMap(n => this.transformStatements(n)) - : // TODO: https://github.com/microsoft/TypeScript/pull/28916 - (this.transformNode(node as StatementLikeNode) as lua.Statement[]); + return castArray(node).flatMap(n => this.transformNode(n) as lua.Statement[]); } public superTransformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { - return Array.isArray(node) - ? node.flatMap(n => this.superTransformStatements(n)) - : // TODO: https://github.com/microsoft/TypeScript/pull/28916 - (this.superTransformNode(node as StatementLikeNode) as lua.Statement[]); + return castArray(node).flatMap(n => this.superTransformNode(n) as lua.Statement[]); } } diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index b3b2c0697..8f5936126 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -15,7 +15,7 @@ export enum AnnotationKind { LuaTable = "luaTable", NoSelf = "noSelf", NoSelfInFile = "noSelfInFile", - VarArg = "varArg", + Vararg = "vararg", ForRange = "forRange", } @@ -170,9 +170,9 @@ export function isLuaIteratorType(context: TransformationContext, node: ts.Node) return getTypeAnnotations(type).has(AnnotationKind.LuaIterator); } -export function isVarArgType(context: TransformationContext, node: ts.Node): boolean { +export function isVarargType(context: TransformationContext, node: ts.Node): boolean { const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(type).has(AnnotationKind.VarArg); + return getTypeAnnotations(type).has(AnnotationKind.Vararg); } export function isForRangeType(context: TransformationContext, node: ts.Node): boolean { diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index 05cfea467..a31a24fdf 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -67,18 +67,19 @@ export function validateAssignment( fromType.symbol.members ) { // Recurse into interfaces - toType.symbol.members.forEach((toMember, memberName) => { + toType.symbol.members.forEach((toMember, escapedMemberName) => { if (fromType.symbol.members) { - const fromMember = fromType.symbol.members.get(memberName); + const fromMember = fromType.symbol.members.get(escapedMemberName); if (fromMember) { const toMemberType = context.checker.getTypeOfSymbolAtLocation(toMember, node); const fromMemberType = context.checker.getTypeOfSymbolAtLocation(fromMember, node); + const memberName = ts.unescapeLeadingUnderscores(escapedMemberName); validateAssignment( context, node, fromMemberType, toMemberType, - toName ? `${toName}.${memberName}` : memberName.toString() + toName ? `${toName}.${memberName}` : memberName ); } } @@ -99,10 +100,10 @@ function validateFunctionAssignment( if (fromContext === ContextType.Mixed || toContext === ContextType.Mixed) { context.diagnostics.push(unsupportedOverloadAssignment(node, toName)); } else if (fromContext !== toContext && fromContext !== ContextType.None && toContext !== ContextType.None) { - if (toContext === ContextType.Void) { - context.diagnostics.push(unsupportedNoSelfFunctionConversion(node, toName)); - } else { - context.diagnostics.push(unsupportedSelfFunctionConversion(node, toName)); - } + context.diagnostics.push( + toContext === ContextType.Void + ? unsupportedNoSelfFunctionConversion(node, toName) + : unsupportedSelfFunctionConversion(node, toName) + ); } } diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 318c4abaf..dfce4b2fc 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; -import { assert } from "../../utils"; +import { assert, castArray } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; import { peekScope, ScopeType } from "./scope"; @@ -9,13 +9,7 @@ import { isFunctionType } from "./typescript"; export type OneToManyVisitorResult = T | T[] | undefined; export function unwrapVisitorResult(result: OneToManyVisitorResult): T[] { - if (result === undefined || result === null) { - return []; - } else if (Array.isArray(result)) { - return result; - } else { - return [result]; - } + return result === undefined ? [] : castArray(result); } export function createSelfIdentifier(tsOriginal?: ts.Node): lua.Identifier { @@ -51,10 +45,9 @@ export function createImmediatelyInvokedFunctionExpression( result: lua.Expression | lua.Expression[], tsOriginal?: ts.Node ): lua.CallExpression { - const body = statements ? statements.slice(0) : []; - body.push(lua.createReturnStatement(Array.isArray(result) ? result : [result])); + const body = [...statements, lua.createReturnStatement(castArray(result))]; const flags = statements.length === 0 ? lua.FunctionExpressionFlags.Inline : lua.FunctionExpressionFlags.None; - const iife = lua.createFunctionExpression(lua.createBlock(body), undefined, undefined, undefined, flags); + const iife = lua.createFunctionExpression(lua.createBlock(body), undefined, undefined, flags); return lua.createCallExpression(iife, [], tsOriginal); } @@ -121,7 +114,7 @@ export function createLocalOrExportedOrGlobalDeclaration( const isFunctionDeclaration = tsOriginal !== undefined && ts.isFunctionDeclaration(tsOriginal); - const identifiers = Array.isArray(lhs) ? lhs : [lhs]; + const identifiers = castArray(lhs); if (identifiers.length === 0) { return []; } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 90ae8e4b0..bd8099afa 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall, isVarArgType } from "../utils/annotations"; +import { isInTupleReturnFunction, isTupleReturnCall, isVarargType } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -255,7 +255,7 @@ export const transformSpreadElement: FunctionVisitor = (node, return innerExpression; } - if (ts.isIdentifier(node.expression) && isVarArgType(context, node.expression)) { + if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { return lua.createDotsLiteral(node); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 33024923e..0736eec25 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -266,7 +266,6 @@ export function transformClassDeclaration( lua.createBlock(constructorBody), [createSelfIdentifier()], lua.createDotsLiteral(), - undefined, lua.FunctionExpressionFlags.Declaration ); result.push( diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 50cc8a10f..9d13deafa 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -10,13 +10,7 @@ import { getExtendedType, isStaticNode } from "../utils"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; - return lua.createFunctionExpression( - lua.createBlock(body), - params, - dot, - restParam, - lua.FunctionExpressionFlags.Declaration - ); + return lua.createFunctionExpression(lua.createBlock(body), params, dot, lua.FunctionExpressionFlags.Declaration); } export function transformAccessorDeclarations( diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 27be76333..d0c611465 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -87,13 +87,7 @@ export function transformConstructorDeclaration( return lua.createAssignmentStatement( createConstructorName(className), - lua.createFunctionExpression( - block, - params, - dotsLiteral, - restParamName, - lua.FunctionExpressionFlags.Declaration - ), + lua.createFunctionExpression(block, params, dotsLiteral, lua.FunctionExpressionFlags.Declaration), constructorWasGenerated ? classDeclaration : statement ); } diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index fe4d15661..4d9610d9b 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -33,7 +33,6 @@ export function transformMethodDeclaration( lua.createBlock(body), paramNames, dots, - restParamName, lua.FunctionExpressionFlags.Declaration, node.body ); diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index d09616abc..2fab7494c 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -34,7 +34,6 @@ function wrapInFunctionCall(expression: lua.Expression): lua.FunctionExpression lua.createBlock([returnStatement]), undefined, undefined, - undefined, lua.FunctionExpressionFlags.Inline ); } diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index ed4cccf9f..6d683c475 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -46,7 +46,7 @@ export const transformTryStatement: FunctionVisitor = (statemen if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { // Wrap catch in function if try or catch has return - const catchCall = lua.createCallExpression(lua.createFunctionExpression(catchBlock)); + const catchCall = lua.createCallExpression(lua.createFunctionExpression(catchBlock), []); const catchAssign = lua.createAssignmentStatement( [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], catchCall diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 005c63a5b..9cee9cc9e 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isVarArgType } from "../utils/annotations"; +import { isVarargType } from "../utils/annotations"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { @@ -48,7 +48,7 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return false; } // Ignore references to @vararg types in spread elements - return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarArgType(context, r)); + return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); } export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] { @@ -205,7 +205,6 @@ export function transformFunctionLikeDeclaration( lua.createBlock(transformedBody), paramNames, dotsLiteral, - spreadIdentifier, flags, node ); @@ -253,7 +252,6 @@ export const transformFunctionDeclaration: FunctionVisitor 0) { block.statements.unshift( lua.createAssignmentStatement( - castEach( - statement.initializer.elements.map(e => context.transformExpression(e)), - lua.isAssignmentLeftHandSideExpression + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) ), identifiers ) diff --git a/src/utils.ts b/src/utils.ts index 822c5df3a..cb0651007 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -2,12 +2,17 @@ import * as ts from "typescript"; import * as nativeAssert from "assert"; import * as path from "path"; -export const createDiagnosticFactoryWithCode = < - T extends (...args: any) => Partial & Pick ->( - code: number, - create: T -) => { +export function castArray(value: T | T[]): T[]; +export function castArray(value: T | readonly T[]): readonly T[]; +export function castArray(value: T | readonly T[]): readonly T[] { + return Array.isArray(value) ? value : [value]; +} + +export const intersperse = (values: T[], separator: T): T[] => + values.flatMap((value, index) => (index === 0 ? [value] : [separator, value])); + +type DiagnosticFactory = (...args: any) => Partial & Pick; +export const createDiagnosticFactoryWithCode = (code: number, create: T) => { return Object.assign( (...args: Parameters): ts.Diagnostic => ({ file: undefined, @@ -23,11 +28,8 @@ export const createDiagnosticFactoryWithCode = < }; let serialDiagnosticCodeCounter = 100000; -export const createSerialDiagnosticFactory = < - T extends (...args: any) => Partial & Pick ->( - create: T -) => createDiagnosticFactoryWithCode(serialDiagnosticCodeCounter++, create); +export const createSerialDiagnosticFactory = (create: T) => + createDiagnosticFactoryWithCode(serialDiagnosticCodeCounter++, create); export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); export const trimExtension = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); @@ -70,17 +72,6 @@ export function cast( } } -export function castEach( - items: TOriginal[], - cast: (item: TOriginal) => item is TCast -): TCast[] { - if (items.every(cast)) { - return items as TCast[]; - } else { - throw new Error(`Failed to cast all elements to expected type using ${cast.name}.`); - } -} - export function assert(value: any, message?: string | Error): asserts value { nativeAssert(value, message); } diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index 35918aabe..d35a2288a 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -19,7 +19,7 @@ export function transpileString( return file.lua!.trim(); } -export function transpileStringsAsProject( +function transpileStringsAsProject( input: Record, options: tstl.CompilerOptions = {} ): tstl.TranspileResult { @@ -36,7 +36,7 @@ export function transpileStringsAsProject( return tstl.transpileVirtualProject(input, optionsWithDefaults); } -export function transpileStringResult( +function transpileStringResult( input: string | Record, options: tstl.CompilerOptions = {} ): Required { diff --git a/test/tsconfig.json b/test/tsconfig.json index 5388f9434..de0b21bdd 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,18 +1,10 @@ { + "extends": "../tsconfig.json", "compilerOptions": { - "baseUrl": ".", - "paths": { "*": ["types/*"] }, - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "newLine": "LF", - "target": "es2019", - "lib": ["es2019"], + "rootDir": "..", "types": ["node", "jest"], - "experimentalDecorators": true, - - "noEmit": true, - "module": "commonjs" + "baseUrl": ".", + "paths": { "*": ["types/*"] } }, "include": [".", "../src"], "exclude": [ diff --git a/test/unit/__snapshots__/assignments.spec.ts.snap b/test/unit/__snapshots__/assignments.spec.ts.snap index 6f9f553ff..f28bc871c 100644 --- a/test/unit/__snapshots__/assignments.spec.ts.snap +++ b/test/unit/__snapshots__/assignments.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`var declaration in for loop is disallowed: code 1`] = ` +exports[`var is disallowed for loop: code 1`] = ` "local ____exports = {} function ____exports.__main(self) do @@ -12,9 +12,9 @@ end return ____exports" `; -exports[`var declaration in for loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; +exports[`var is disallowed for loop: diagnostics 1`] = `"main.ts(2,18): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; -exports[`var declaration in for...in loop is disallowed: code 1`] = ` +exports[`var is disallowed for...in loop: code 1`] = ` "local ____exports = {} function ____exports.__main(self) for foo in pairs({}) do @@ -23,9 +23,9 @@ end return ____exports" `; -exports[`var declaration in for...in loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; +exports[`var is disallowed for...in loop: diagnostics 1`] = `"main.ts(2,18): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; -exports[`var declaration in for...of loop is disallowed: code 1`] = ` +exports[`var is disallowed for...of loop: code 1`] = ` "local ____exports = {} function ____exports.__main(self) for ____, foo in ipairs({}) do @@ -34,9 +34,9 @@ end return ____exports" `; -exports[`var declaration in for...of loop is disallowed: diagnostics 1`] = `"main.ts(2,14): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; +exports[`var is disallowed for...of loop: diagnostics 1`] = `"main.ts(2,18): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; -exports[`var declaration is disallowed: code 1`] = ` +exports[`var is disallowed var declaration: code 1`] = ` "local ____exports = {} function ____exports.__main(self) local foo = true @@ -44,4 +44,4 @@ end return ____exports" `; -exports[`var declaration is disallowed: diagnostics 1`] = `"main.ts(2,9): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; +exports[`var is disallowed var declaration: diagnostics 1`] = `"main.ts(2,13): error TSTL: \`var\` declarations are not supported. Use \`let\` or \`const\` instead."`; diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts index 982109261..1635ef13a 100644 --- a/test/unit/annotations/vararg.spec.ts +++ b/test/unit/annotations/vararg.spec.ts @@ -2,17 +2,17 @@ import * as util from "../../util"; const varargDeclaration = ` /** @vararg */ - type LuaVarArg = A & { __luaVararg?: never }; + type LuaVararg = A & { __luaVararg?: never }; `; test("@vararg", () => { util.testFunction` ${varargDeclaration} - function foo(a: unknown, ...b: LuaVarArg) { + function foo(a: unknown, ...b: LuaVararg) { const c = [...b]; return c.join(""); } - function bar(a: unknown, ...b: LuaVarArg) { + function bar(a: unknown, ...b: LuaVararg) { return foo(a, ...b); } return bar("A", "B", "C", "D"); @@ -25,7 +25,7 @@ test("@vararg", () => { test("@vararg array access", () => { util.testFunction` ${varargDeclaration} - function foo(a: unknown, ...b: LuaVarArg) { + function foo(a: unknown, ...b: LuaVararg) { const c = [...b]; return c.join("") + b[0]; } @@ -36,7 +36,7 @@ test("@vararg array access", () => { test("@vararg global", () => { util.testModule` ${varargDeclaration} - declare const arg: LuaVarArg; + declare const arg: LuaVararg; export const result = [...arg].join(""); ` .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 1a8665464..178d72bab 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -7,46 +7,56 @@ test.each(["const", "let"])("%s declaration not top-level is not global", declar ${declarationKind} foo = true; } // @ts-ignore - return (globalThis as any).foo; - `.expectToEqual(undefined); + return "foo" in globalThis; + `.expectToEqual(false); }); -test.each(["const", "let"])("%s declaration top-level is global", declarationKind => { - util.testModule` - ${declarationKind} foo = true; +test.each(["const", "let"])("top-level %s declaration is global", declarationKind => { + // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports + util.testBundle` // @ts-ignore - return (globalThis as any).foo; - `.expectToEqual(true); + import './a'; + export const result = foo; + ` + .addExtraFile("a.ts", `${declarationKind} foo = true;`) + .expectToEqual({ result: true }); }); -test("var declaration is disallowed", () => { - util.testFunction` - var foo = true; - `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); -}); +describe("var is disallowed", () => { + test("var declaration", () => { + util.testFunction` + var foo = true; + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); + }); -test("var declaration in for loop is disallowed", () => { - util.testFunction` - for (var foo = 0;;) {} - `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); -}); + test("for loop", () => { + util.testFunction` + for (var foo = 0;;) {} + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); + }); -test("var declaration in for...in loop is disallowed", () => { - util.testFunction` - for (var foo in {}) {} - `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); -}); + test("for...in loop", () => { + util.testFunction` + for (var foo in {}) {} + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); + }); -test("var declaration in for...of loop is disallowed", () => { - util.testFunction` - for (var foo of []) {} - `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); + test("for...of loop", () => { + util.testFunction` + for (var foo of []) {} + `.expectDiagnosticsToMatchSnapshot([unsupportedVarDeclaration.code]); + }); }); -test.each(["let myvar;", "const myvar = null;", "const myvar = undefined;"])("Null assignments (%p)", declaration => { - const result = util.transpileAndExecute(declaration + " return myvar;"); - expect(result).toBe(undefined); -}); +test.each(["let result;", "const result = null;", "const result = undefined;"])( + "Null assignments (%p)", + declaration => { + util.testFunction` + ${declaration} + return result; + `.expectToEqual(undefined); + } +); test.each(["x = y", "x += y"])("Assignment expressions (%p)", expression => { util.testFunction` diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index d664ab061..f1235326e 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -502,3 +502,14 @@ test("missing declaration name", () => { function () {} `.expectDiagnosticsToMatchSnapshot([1003]); }); + +test("top-level function declaration is global", () => { + // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports + util.testBundle` + // @ts-ignore + import './a'; + export const result = foo(); + ` + .addExtraFile("a.ts", `function foo() { return "foo" }`) + .expectToEqual({ result: "foo" }); +}); diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index 906d80a65..f61e37cb2 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -1,6 +1,6 @@ import * as util from "../../util"; -test("enables noSelfInFile behaviour for functions", () => { +test("enables noSelfInFile behavior for functions", () => { util.testFunction` function fooBar() {} const test: (this: void) => void = fooBar; @@ -9,7 +9,7 @@ test("enables noSelfInFile behaviour for functions", () => { .expectToHaveNoDiagnostics(); }); -test("enables noSelfInFile behaviour for methods", () => { +test("enables noSelfInFile behavior for methods", () => { util.testFunction` class FooBar { fooBar() {} @@ -22,19 +22,19 @@ test("enables noSelfInFile behaviour for methods", () => { }); test("generates declaration files with @noSelfInFile", () => { - const builder = util.testModule` + const fooBuilder = util.testModule` export function bar() {} ` .setOptions({ declaration: true, noImplicitSelf: true }) .expectToHaveNoDiagnostics(); - const declarationFile = builder.getLuaResult().transpiledFiles.find(f => f.declaration); - if (!util.expectToBeDefined(declarationFile) || !util.expectToBeDefined(declarationFile.declaration)) return; + const fooDeclaration = fooBuilder.getLuaResult().transpiledFiles.find(f => f.declaration)?.declaration; + util.assert(fooDeclaration !== undefined); util.testModule` import { bar } from "./foo.d"; const test: (this: void) => void = bar; ` - .addExtraFile("foo.d.ts", declarationFile.declaration) + .addExtraFile("foo.d.ts", fooDeclaration) .expectToHaveNoDiagnostics(); }); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 1b0a6a8f9..94199e09f 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -4,10 +4,8 @@ import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; const expectToRequire = (expected: string): util.TapCallback => builder => { - const match = requireRegex.exec(builder.getMainLuaCodeChunk()); - if (util.expectToBeDefined(match)) { - expect(match[1]).toBe(expected); - } + const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; + expect(requiredPath).toBe(expected); }; test.each([ diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index fe17f6da4..bb8c8db78 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -54,7 +54,19 @@ test("context in namespace function", () => { `.expectToMatchJsResult(); }); -test("namespace merged with interface", () => { +test("namespace merging", () => { + util.testModule` + export namespace Foo { + export const a = 1; + } + + export namespace Foo { + export const b = 2; + } + `.expectToMatchJsResult(); +}); + +test("namespace merging with interface", () => { util.testModule` interface Foo {} namespace Foo { @@ -65,8 +77,8 @@ test("namespace merged with interface", () => { `.expectToMatchJsResult(); }); -test("namespace merged across files", () => { - const testA = ` +test("namespace merging across files", () => { + const a = ` namespace NS { export namespace Inner { export const foo = "foo"; @@ -74,7 +86,7 @@ test("namespace merged across files", () => { } `; - const testB = ` + const b = ` namespace NS { export namespace Inner { export const bar = "bar"; @@ -82,9 +94,18 @@ test("namespace merged across files", () => { } `; - const { transpiledFiles } = util.transpileStringsAsProject({ "testA.ts": testA, "testB.ts": testB }); - const lua = transpiledFiles.map(f => f.lua).join("\n") + "\nreturn NS.Inner.foo .. NS.Inner.bar"; - expect(util.executeLua(lua)).toBe("foobar"); + // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports + util.testBundle` + // @ts-ignore + import './a'; + // @ts-ignore + import './b'; + + export const result = NS.Inner; + ` + .addExtraFile("a.ts", a) + .addExtraFile("b.ts", b) + .expectToEqual({ result: { foo: "foo", bar: "bar" } }); }); test("declared namespace function call", () => { diff --git a/test/unit/printer/__snapshots__/semicolons.spec.ts.snap b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap new file mode 100644 index 000000000..af1deb303 --- /dev/null +++ b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap @@ -0,0 +1,63 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`semicolon insertion ("{}") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = \\"\\" + local function foo(self) + result = \\"foo\\" + end + do + end + (nil or foo)(nil) + return result +end +return ____exports" +`; + +exports[`semicolon insertion ("const a = 1; const b = a;") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = \\"\\" + local function foo(self) + result = \\"foo\\" + end + local a = 1 + local b = a; + (nil or foo)(nil) + return result +end +return ____exports" +`; + +exports[`semicolon insertion ("const a = 1; let b: number; b = a;") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = \\"\\" + local function foo(self) + result = \\"foo\\" + end + local a = 1 + local b + b = a; + (nil or foo)(nil) + return result +end +return ____exports" +`; + +exports[`semicolon insertion ("function bar() {} bar();") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result = \\"\\" + local function foo(self) + result = \\"foo\\" + end + local function bar(self) + end + bar(nil); + (nil or foo)(nil) + return result +end +return ____exports" +`; diff --git a/test/unit/printer/semicolons.spec.ts b/test/unit/printer/semicolons.spec.ts index ae3a79244..addb66e53 100644 --- a/test/unit/printer/semicolons.spec.ts +++ b/test/unit/printer/semicolons.spec.ts @@ -3,13 +3,14 @@ import * as util from "../../util"; test.each(["const a = 1; const b = a;", "const a = 1; let b: number; b = a;", "{}", "function bar() {} bar();"])( "semicolon insertion (%p)", leadingStatement => { - const code = ` + util.testFunction` let result = ""; function foo() { result = "foo"; } ${leadingStatement} - (foo)(); + (undefined || foo)(); return result; - `; - expect(util.transpileAndExecute(code)).toEqual("foo"); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); } ); diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index c12a89b69..58873690c 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -262,11 +262,10 @@ test("Inline sourcemaps", () => { .expectToMatchJsResult() .getMainLuaFileResult(); - const inlineSourceMapMatch = file.lua.match(/--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/); - if (util.expectToBeDefined(inlineSourceMapMatch)) { - const inlineSourceMap = Buffer.from(inlineSourceMapMatch[1], "base64").toString(); - expect(file.sourceMap).toBe(inlineSourceMap); - } + const [, inlineSourceMapMatch] = + file.lua.match(/--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/) ?? []; + const inlineSourceMap = Buffer.from(inlineSourceMapMatch, "base64").toString(); + expect(file.sourceMap).toBe(inlineSourceMap); }); // Helper functions diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 0a54e3a41..dec923d83 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -14,17 +14,8 @@ const arrayLiteralCases = [ "1, 2, ...[3, 4], ...[5, 6]", ]; -const tupleReturnDefinition = ` -/** @tupleReturn */ -function tuple(...args: any[]) { - return args; -}`; - describe.each(["function call", "array literal"] as const)("in %s", kind => { - // prettier-ignore - const factory = (code: string) => kind === "function call" - ? `((...args: any[]) => args)(${code})` - : `[${code}]`; + const factory = (code: string) => (kind === "function call" ? `((...args: any[]) => args)(${code})` : `[${code}]`); test.each(arrayLiteralCases)("of array literal (%p)", expression => { util.testExpression(factory(expression)).expectToMatchJsResult(); @@ -32,7 +23,11 @@ describe.each(["function call", "array literal"] as const)("in %s", kind => { test.each(arrayLiteralCases)("of tuple return call (%p)", expression => { util.testFunction` - ${tupleReturnDefinition} + /** @tupleReturn */ + function tuple(...args: any[]) { + return args; + } + return ${factory(`...tuple(${expression})`)}; `.expectToMatchJsResult(); }); diff --git a/test/util.ts b/test/util.ts index 6a8909e18..552351de9 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,3 +1,4 @@ +import * as nativeAssert from "assert"; import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; @@ -9,40 +10,8 @@ import * as tstl from "../src"; export * from "./legacy-utils"; -export const nodeStub = ts.createNode(ts.SyntaxKind.Unknown, 0, 0); - -export function parseTypeScript( - typescript: string, - target: tstl.LuaTarget = tstl.LuaTarget.Lua53 -): [ts.SourceFile, ts.TypeChecker] { - const program = tstl.createVirtualProgram({ "main.ts": typescript }, { luaTarget: target }); - const sourceFile = program.getSourceFile("main.ts"); - - if (sourceFile === undefined) { - throw new Error("Could not find source file main.ts in program."); - } - - return [sourceFile, program.getTypeChecker()]; -} - -export function findFirstChild(node: ts.Node, predicate: (node: ts.Node) => boolean): ts.Node | undefined { - for (const child of node.getChildren()) { - if (predicate(child)) { - return child; - } - - const childChild = findFirstChild(child, predicate); - if (childChild !== undefined) { - return childChild; - } - } - return undefined; -} - -export function expectToBeDefined(subject: T | null | undefined): subject is T { - expect(subject).toBeDefined(); - expect(subject).not.toBeNull(); - return true; // If this was false the expect would have thrown an error +export function assert(value: any, message?: string | Error): asserts value { + nativeAssert(value, message); } export const formatCode = (...values: unknown[]) => values.map(e => stringify(e)).join(", "); @@ -330,11 +299,11 @@ export abstract class TestBuilder { @memoize protected getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); - const mainFile = transpiledFiles.find(x => x.fileName === this.mainFileName); - expect(mainFile).toBeDefined(); + const code = transpiledFiles.find(x => x.fileName === this.mainFileName)?.js; + assert(code !== undefined); const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; - return header + mainFile!.js!; + return header + code; } protected abstract getJsCodeWithWrapper(): string; diff --git a/tsconfig.json b/tsconfig.json index d16784b37..bf121bd20 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,21 @@ { "compilerOptions": { - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "rootDir": "./src", - "outDir": "./dist", - "declaration": true, - "sourceMap": true, "target": "es2019", "lib": ["es2019"], + "types": ["node"], "module": "commonjs", - "stripInternal": true + "experimentalDecorators": true, + + "rootDir": "src", + "outDir": "dist", + "declaration": true, + "sourceMap": true, + "newLine": "LF", + "stripInternal": true, + + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true }, "include": ["src"], "exclude": ["src/lualib"] From f366595f69feb265ed6c03de9dc0c3d6db082d28 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 1 Apr 2020 09:25:23 +0200 Subject: [PATCH 245/764] Fixed incorrect escaping of fields (#847) * Fixed incorrect escaping of fields * Removed forgotten debug() and moved comment around * Updated test for invalid syntax identifiers * Reverted test changes --- src/transformation/visitors/call.ts | 3 +- .../visitors/class/members/constructor.ts | 22 +++++++------- test/unit/identifiers.spec.ts | 29 +++++++++++++++++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index bd8099afa..24c4864d1 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -10,7 +10,6 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; -import { transformIdentifier } from "./identifier"; import { transformLuaTableCallExpression } from "./lua-table"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -117,7 +116,7 @@ export function transformContextualCallExpression( return lua.createMethodCallExpression( table, - transformIdentifier(context, left.name), + lua.createIdentifier(left.name.text, left.name), transformedArguments, node ); diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index d0c611465..fe25a21b2 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -1,11 +1,11 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; -import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { transformParameters, transformFunctionBodyStatements, transformFunctionBodyHeader } from "../../function"; import { TransformationContext } from "../../../context"; +import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { popScope, pushScope, ScopeType } from "../../../utils/scope"; +import { transformFunctionBodyHeader, transformFunctionBodyStatements, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; -import { pushScope, ScopeType, popScope } from "../../../utils/scope"; export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { return lua.createTableIndexExpression( @@ -66,13 +66,15 @@ export function transformConstructorDeclaration( // Add in instance field declarations for (const declaration of constructorFieldsDeclarations) { - const declarationName = transformIdentifier(context, declaration.name as ts.Identifier); - // self.declarationName = declarationName - const assignment = lua.createAssignmentStatement( - lua.createTableIndexExpression(createSelfIdentifier(), lua.createStringLiteral(declarationName.text)), - declarationName - ); - bodyWithFieldInitializers.push(assignment); + if (ts.isIdentifier(declaration.name)) { + // self.declarationName = declarationName + const assignment = lua.createAssignmentStatement( + lua.createTableIndexExpression(createSelfIdentifier(), lua.createStringLiteral(declaration.name.text)), + transformIdentifier(context, declaration.name) + ); + bodyWithFieldInitializers.push(assignment); + } + // else { TypeScript error: A parameter property may not be declared using a binding pattern } } bodyWithFieldInitializers.push(...classInstanceFields); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 84583ccd7..27046c81b 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -757,3 +757,32 @@ test("exported variable with lua keyword as name is not renamed", () => { expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/846 +test("lua built-in as class method", () => { + util.testModule` + class MyClass { + error() { return "Error!"; } + } + export const result = new MyClass().error(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/833 +test("lua built-in as object method", () => { + util.testModule` + const obj = { error: () => "Error!" }; + export const result = obj.error(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/789 +test("lua built-in as in constructor assignment", () => { + util.testModule` + class A { + constructor(public error: string){} + } + + export const result = new A("42").error; + `.expectToMatchJsResult(); +}); From 282da2350bf78dfa20064a85b29e6d328a4d2975 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 5 Apr 2020 21:20:19 +0200 Subject: [PATCH 246/764] Bugfix/anonymous class name (#810) * Updated tests to new TestBuilder * Updated classes/classes tests to new TestBuilder * Fixed exported class super call test * Fixed inconsistency between reflection class names of JS and Lua * Reverted unique default class name change * Reverted change and changed tests to use testModule instead of setTsHeader * Fixed some remaining merge issues * Added gitattributes * Refactored class transformation functions * Also fixed #584, moved getReflectionName to setup and some other minor changes * Moved getReflectionClassName to setup completely * Moved tests --- .gitattributes | 1 + src/transformation/visitors/class/index.ts | 56 +- src/transformation/visitors/class/setup.ts | 23 +- .../__snapshots__/classes.spec.ts.snap | 2 +- test/unit/classes/classes.spec.ts | 552 ++++++++---------- test/unit/modules/modules.spec.ts | 18 - 6 files changed, 292 insertions(+), 360 deletions(-) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..fcadb2cf9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 0736eec25..59ecc10b7 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -7,9 +7,9 @@ import { extensionAndMetaExtensionConflict, extensionCannotExport, extensionCannotExtend, - metaExtensionMissingExtends, - luaTableMustBeAmbient, luaTableCannotBeExtended, + luaTableMustBeAmbient, + metaExtensionMissingExtends, } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, @@ -21,7 +21,6 @@ import { import { createImmediatelyInvokedFunctionExpression, createSelfIdentifier, - OneToManyVisitorResult, unwrapVisitorResult, } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; @@ -38,25 +37,29 @@ import { checkForLuaLibType } from "./new"; import { createClassSetup } from "./setup"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; +export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { + // If declaration is a default export, transform to export variable assignment instead + if (hasDefaultExportModifier(declaration)) { + const left = createExportedIdentifier(context, createDefaultExportIdentifier(declaration)); + const right = transformClassAsExpression(declaration, context); + return [lua.createAssignmentStatement(left, right, declaration)]; + } + + const { statements } = transformClassLikeDeclaration(declaration, context); + return statements; +}; + +export const transformThisExpression: FunctionVisitor = node => createSelfIdentifier(node); + export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, - context: TransformationContext, - isDefaultExport = false + context: TransformationContext ): lua.Expression { - let className: lua.Identifier; - if (expression.name) { - className = transformIdentifier(context, expression.name); - } else if (isDefaultExport) { - className = createDefaultExportIdentifier(expression); - } else { - className = lua.createAnonymousIdentifier(); - } - pushScope(context, ScopeType.Function); - const classDeclaration = unwrapVisitorResult(transformClassDeclaration(expression, context, className)); + const { statements, name } = transformClassLikeDeclaration(expression, context); popScope(context); - return createImmediatelyInvokedFunctionExpression(classDeclaration, className, expression); + return createImmediatelyInvokedFunctionExpression(unwrapVisitorResult(statements), name, expression); } const classSuperInfos = new WeakMap(); @@ -65,28 +68,19 @@ interface ClassSuperInfo { extendedTypeNode?: ts.ExpressionWithTypeArguments; } -export function transformClassDeclaration( +function transformClassLikeDeclaration( classDeclaration: ts.ClassLikeDeclaration, context: TransformationContext, nameOverride?: lua.Identifier -): OneToManyVisitorResult { +): { statements: lua.Statement[]; name: lua.Identifier } { let className: lua.Identifier; - let classNameText: string; if (nameOverride !== undefined) { className = nameOverride; - classNameText = nameOverride.text; } else if (classDeclaration.name !== undefined) { className = transformIdentifier(context, classDeclaration.name); - classNameText = classDeclaration.name.text; - } else if (hasDefaultExportModifier(classDeclaration)) { - const left = createExportedIdentifier(context, createDefaultExportIdentifier(classDeclaration)); - const right = transformClassAsExpression(classDeclaration, context, true); - - return lua.createAssignmentStatement(left, right, classDeclaration); } else { // TypeScript error className = lua.createAnonymousIdentifier(); - classNameText = className.text; } const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); @@ -196,9 +190,7 @@ export function transformClassDeclaration( } if (!isExtension && !isMetaExtension) { - result.push( - ...createClassSetup(context, classDeclaration, className, localClassName, classNameText, extendedType) - ); + result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); } else { for (const f of instanceFields) { const fieldName = transformPropertyName(context, f.name); @@ -317,7 +309,7 @@ export function transformClassDeclaration( superInfo.pop(); - return result; + return { statements: result, name: className }; } export const transformSuperExpression: FunctionVisitor = (expression, context) => { @@ -345,5 +337,3 @@ export const transformSuperExpression: FunctionVisitor = (ex return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); }; - -export const transformThisExpression: FunctionVisitor = node => createSelfIdentifier(node); diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts index a4ffc5c75..151e68a77 100644 --- a/src/transformation/visitors/class/setup.ts +++ b/src/transformation/visitors/class/setup.ts @@ -17,7 +17,6 @@ export function createClassSetup( statement: ts.ClassLikeDeclarationBase, className: lua.Identifier, localClassName: lua.Identifier, - classNameText: string, extendsType?: ts.Type ): lua.Statement[] { const result: lua.Statement[] = []; @@ -56,7 +55,7 @@ export function createClassSetup( result.push( lua.createAssignmentStatement( lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("name")), - lua.createStringLiteral(classNameText), + getReflectionClassName(context, statement, className), statement ) ); @@ -79,3 +78,23 @@ export function createClassSetup( return result; } + +export function getReflectionClassName( + context: TransformationContext, + declaration: ts.ClassLikeDeclarationBase, + className: lua.Identifier +): lua.Expression { + if (declaration.name) { + return lua.createStringLiteral(declaration.name.text); + } else if (ts.isVariableDeclaration(declaration.parent) && ts.isIdentifier(declaration.parent.name)) { + return lua.createStringLiteral(declaration.parent.name.text); + } else if (hasDefaultExportModifier(declaration)) { + return lua.createStringLiteral("default"); + } + + if (getExtendedNode(context, declaration)) { + return lua.createTableIndexExpression(className, lua.createStringLiteral("name")); + } + + return lua.createStringLiteral(""); +} diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap index 0acca51b6..a900582b5 100644 --- a/test/unit/classes/__snapshots__/classes.spec.ts.snap +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -3,7 +3,7 @@ exports[`missing declaration name: code 1`] = ` "require(\\"lualib_bundle\\"); ____ = __TS__Class() -____.name = \\"____\\" +____.name = \\"\\" function ____.prototype.____constructor(self) end" `; diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 0e6761fbc..4b58db2cf 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -1,89 +1,73 @@ import * as util from "../../util"; test("ClassFieldInitializer", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { field: number = 4; } - return new a().field;` - ); - - expect(result).toBe(4); + return new a().field; + `.expectToMatchJsResult(); }); test("ClassNumericLiteralFieldInitializer", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { 1: number = 4; } - return new a()[1];` - ); - - expect(result).toBe(4); + return new a()[1]; + `.expectToMatchJsResult(); }); test("ClassStringLiteralFieldInitializer", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { "field": number = 4; } - return new a()["field"];` - ); - - expect(result).toBe(4); + return new a()["field"]; + `.expectToMatchJsResult(); }); test("ClassComputedFieldInitializer", () => { - const result = util.transpileAndExecute( - `const field: "field" = "field"; + util.testFunction` + const field: "field" = "field"; class a { [field]: number = 4; } - return new a()[field];` - ); - - expect(result).toBe(4); + return new a()[field]; + `.expectToMatchJsResult(); }); test("ClassConstructor", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { field: number = 3; constructor(n: number) { this.field = n * 2; } } - return new a(4).field;` - ); - - expect(result).toBe(8); + return new a(4).field; + `.expectToMatchJsResult(); }); test("ClassConstructorAssignment", () => { - const result = util.transpileAndExecute( - `class a { constructor(public field: number) {} } - return new a(4).field;` - ); - - expect(result).toBe(4); + util.testFunction` + class a { constructor(public field: number) {} } + return new a(4).field; + `.expectToMatchJsResult(); }); test("ClassConstructorDefaultParameter", () => { - const result = util.transpileAndExecute( - `class a { public field: number; constructor(f: number = 3) { this.field = f; } } - return new a().field;` - ); - - expect(result).toBe(3); + util.testFunction` + class a { public field: number; constructor(f: number = 3) { this.field = f; } } + return new a().field; + `.expectToMatchJsResult(); }); test("ClassConstructorAssignmentDefault", () => { - const result = util.transpileAndExecute( - `class a { constructor(public field: number = 3) { } } - return new a().field;` - ); - - expect(result).toBe(3); + util.testFunction` + class a { constructor(public field: number = 3) { } } + return new a().field; + `.expectToMatchJsResult(); }); test("ClassConstructorPropertyInitiailizationOrder", () => { @@ -106,83 +90,69 @@ test("ClassConstructorPropertyInitiailizationFalsey", () => { }); test("ClassNewNoBrackets", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public field: number = 4; constructor() {} } let inst = new a; - return inst.field;` - ); - - expect(result).toBe(4); + return inst.field; + `.expectToMatchJsResult(); }); test("ClassStaticFields", () => { - const result = util.transpileAndExecute( - `class a { static field: number = 4; } - return a.field;` - ); - - expect(result).toBe(4); + util.testFunction` + class a { static field: number = 4; } + return a.field; + `.expectToMatchJsResult(); }); test("ClassStaticNumericLiteralFields", () => { - const result = util.transpileAndExecute( - `class a { static 1: number = 4; } - return a[1];` - ); - - expect(result).toBe(4); + util.testFunction` + class a { static 1: number = 4; } + return a[1]; + `.expectToMatchJsResult(); }); test("ClassStaticStringLiteralFields", () => { - const result = util.transpileAndExecute( - `class a { static "field": number = 4; } - return a["field"];` - ); - - expect(result).toBe(4); + util.testFunction` + class a { static "field": number = 4; } + return a["field"]; + `.expectToMatchJsResult(); }); test("ClassStaticComputedFields", () => { - const result = util.transpileAndExecute( - `const field: "field" = "field"; + util.testFunction` + const field: "field" = "field"; class a { static [field]: number = 4; } - return a[field];` - ); - - expect(result).toBe(4); + return a[field]; + `.expectToMatchJsResult(); }); test("classExtends", () => { - const result = util.transpileAndExecute( - `class a { field: number = 4; } + util.testFunction` + class a { field: number = 4; } class b extends a {} - return new b().field;` - ); - - expect(result).toBe(4); + return new b().field; + `.expectToMatchJsResult(); }); test("SubclassDefaultConstructor", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { field: number; constructor(field: number) { this.field = field; } } class b extends a {} - return new b(10).field;` - ); - - expect(result).toBe(10); + return new b(10).field; + `.expectToMatchJsResult(); }); test("SubsubclassDefaultConstructor", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { field: number; constructor(field: number) { this.field = field; @@ -190,15 +160,13 @@ test("SubsubclassDefaultConstructor", () => { } class b extends a {} class c extends b {} - return new c(10).field;` - ); - - expect(result).toBe(10); + return new c(10).field; + `.expectToMatchJsResult(); }); test("SubclassConstructor", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { field: number; constructor(field: number) { this.field = field; @@ -209,14 +177,12 @@ test("SubclassConstructor", () => { super(field + 1); } } - return new b(10).field;` - ); - - expect(result).toBe(11); + return new b(10).field; + `.expectToMatchJsResult(); }); test("Subclass constructor across merged namespace", () => { - const tsHeader = ` + util.testModule` namespace NS { export class Super { prop: string; @@ -231,9 +197,11 @@ test("Subclass constructor across merged namespace", () => { super(); } } - }`; - - expect(util.transpileAndExecute("return (new NS.Sub()).prop", undefined, undefined, tsHeader)).toBe("foo"); + } + export const result = (new NS.Sub()).prop; + ` + .setReturnExport("result") + .expectToMatchJsResult(); }); test("super without class", () => { @@ -257,8 +225,8 @@ test("super in unnamed class", () => { }); test("classSuper", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public field: number = 4; constructor(n: number) { this.field = n; @@ -269,15 +237,13 @@ test("classSuper", () => { super(5); } } - return new b().field;` - ); - - expect(result).toBe(5); + return new b().field; + `.expectToMatchJsResult(); }); test("classSuperSuper", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public field: number = 4; constructor(n: number) { this.field = n; @@ -293,15 +259,13 @@ test("classSuperSuper", () => { super(5); } } - return new c().field;` - ); - - expect(result).toBe(10); + return new c().field; + `.expectToMatchJsResult(); }); test("classSuperSkip", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public field: number = 4; constructor(n: number) { this.field = n; @@ -314,19 +278,13 @@ test("classSuperSkip", () => { super(5); } } - return new c().field;` - ); - - expect(result).toBe(5); + return new c().field; + `.expectToMatchJsResult(); }); test("renamedClassExtends", () => { - const result = util.transpileAndExecute( - `const b = new B(); - return b.value;`, - undefined, - undefined, - `namespace Classes { + util.testModule` + namespace Classes { export class Base { public value: number; constructor(){ this.value = 3; } @@ -336,114 +294,103 @@ test("renamedClassExtends", () => { const A = Classes.Base; class B extends A { constructor(){ super(); } - };` - ); + } - expect(result).toBe(3); + const b = new B(); + export const result = b.value; + ` + .setReturnExport("result") + .expectToMatchJsResult(); }); test("ClassMethodCall", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method(): number { return 4; } } let inst = new a(); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("ClassNumericLiteralMethodCall", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public 1(): number { return 4; } } let inst = new a(); - return inst[1]();` - ); - - expect(result).toBe(4); + return inst[1](); + `.expectToMatchJsResult(); }); test("ClassStringLiteralMethodCall", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public "method"(): number { return 4; } } let inst = new a(); - return inst["method"]();` - ); - - expect(result).toBe(4); + return inst["method"](); + `.expectToMatchJsResult(); }); test("ClassComputedMethodCall", () => { - const result = util.transpileAndExecute( - `const method: "method" = "method"; + util.testFunction` + const method: "method" = "method"; class a { public [method](): number { return 4; } } let inst = new a(); - return inst[method]();` - ); - - expect(result).toBe(4); + return inst[method](); + `.expectToMatchJsResult(); }); test("ClassToString", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public toString(): string { return "instance of a"; } } let inst = new a(); - return inst.toString();` - ); - - expect(result).toBe("instance of a"); + return inst.toString(); + `.expectToMatchJsResult(); }); test("HasOwnProperty true", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public test(): void { } } let inst = new a(); inst["prop"] = 17; - return inst.hasOwnProperty("prop");` - ); - - expect(result).toBe(true); + return inst.hasOwnProperty("prop"); + `.expectToMatchJsResult(); }); test("HasOwnProperty false", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public test(): void { } } let inst = new a(); inst["prop"] = 17; - return inst.hasOwnProperty("test");` - ); - - expect(result).toBe(false); + return inst.hasOwnProperty("test"); + `.expectToMatchJsResult(); }); test("CastClassMethodCall", () => { - const result = util.transpileAndExecute( - `interface result + util.testFunction` + interface result { val : number; } @@ -456,43 +403,37 @@ test("CastClassMethodCall", () => { let result = {val : 0}; (inst as a).method(result); (inst as a).method(result); - return result.val;` - ); - - expect(result).toBe(4); + return result.val; + `.expectToMatchJsResult(); }); test("ClassPropertyFunctionThis", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { constructor(private n: number) {} public method: () => number = () => this.n; } let inst = new a(4); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("ClassInheritedMethodCall", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method(): number { return 4; } } class b extends a {} let inst = new b(); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("ClassDoubleInheritedMethodCall", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method(): number { return 4; } @@ -500,15 +441,13 @@ test("ClassDoubleInheritedMethodCall", () => { class b extends a {} class c extends b {} let inst = new c(); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("ClassInheritedMethodCall2", () => { - const result = util.transpileAndExecute( - `class a {} + util.testFunction` + class a {} class b extends a { public method(): number { return 4; @@ -516,15 +455,13 @@ test("ClassInheritedMethodCall2", () => { } class c extends b {} let inst = new c(); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("ClassMethodOverride", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method(): number { return 2; } @@ -535,29 +472,25 @@ test("ClassMethodOverride", () => { } } let inst = new b(); - return inst.method();` - ); - - expect(result).toBe(4); + return inst.method(); + `.expectToMatchJsResult(); }); test("methodDefaultParameters", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method(b: number, c: number = 5): number { return b + c; } } let inst = new a(); - return inst.method(4);` - ); - - expect(result).toBe(9); + return inst.method(4); + `.expectToMatchJsResult(); }); test("CallSuperMethodNoArgs", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { a: number constructor(n: number) { this.a = n; @@ -575,15 +508,13 @@ test("CallSuperMethodNoArgs", () => { } } let inst = new b(6); - return inst.method();` - ); - - expect(result).toBe(6); + return inst.method(); + `.expectToMatchJsResult(); }); test("CallSuperMethodArgs", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { a: number constructor(n: number) { this.a = n; @@ -601,15 +532,13 @@ test("CallSuperMethodArgs", () => { } } let inst = new b(6); - return inst.method(4);` - ); - - expect(result).toBe(10); + return inst.method(4); + `.expectToMatchJsResult(); }); test("CallSuperExpressionMethod", () => { - const result = util.transpileAndExecute( - `let i = 0; + util.testFunction` + let i = 0; function make() { const j = i++; return class { @@ -625,15 +554,13 @@ test("CallSuperExpressionMethod", () => { inst.method(); inst.method(); inst.method(); - return i;` - ); - - expect(result).toBe(1); + return i; + `.expectToMatchJsResult(); }); test("CallSuperSuperMethod", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { a: number constructor(n: number) { this.a = n; @@ -659,15 +586,13 @@ test("CallSuperSuperMethod", () => { } } let inst = new c(6); - return inst.method();` - ); - - expect(result).toBe(6); + return inst.method(); + `.expectToMatchJsResult(); }); test("classExpression", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method() { return "instance of a"; } @@ -678,29 +603,25 @@ test("classExpression", () => { } } let inst = new b(); - return inst.method();` - ); - - expect(result).toBe("instance of b"); + return inst.method(); + `.expectToMatchJsResult(); }); test("Named Class Expression", () => { - const result = util.transpileAndExecute( - `const a = class MyClass { + util.testFunction` + const a = class MyClass { public method() { return "foo"; } } let inst = new a(); - return inst.method();` - ); - - expect(result).toBe("foo"); + return inst.method(); + `.expectToMatchJsResult(); }); test("classExpressionBaseClassMethod", () => { - const result = util.transpileAndExecute( - `class a { + util.testFunction` + class a { public method() { return 42; } @@ -708,15 +629,13 @@ test("classExpressionBaseClassMethod", () => { const b = class extends a { } let inst = new b(); - return inst.method();` - ); - - expect(result).toBe(42); + return inst.method(); + `.expectToMatchJsResult(); }); test("Class Method Runtime Override", () => { - const result = util.transpileAndExecute( - `class MyClass { + util.testFunction` + class MyClass { method(): number { return 4; } @@ -726,14 +645,12 @@ test("Class Method Runtime Override", () => { inst.method = () => { return 8; } - return inst.method();` - ); - - expect(result).toBe(8); + return inst.method(); + `.expectToMatchJsResult(); }); test("Exported class super call", () => { - const code = ` + util.testModule` export class Foo { prop: string; constructor(prop: string) { this.prop = prop; } @@ -743,101 +660,96 @@ test("Exported class super call", () => { super("bar"); } } - export const baz = (new Bar()).prop; - `; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("bar"); + export const result = (new Bar()).prop; + ` + .setReturnExport("result") + .expectToMatchJsResult(); }); -test.each([ - { input: "(new Foo())", expectResult: "foo" }, - { input: "Foo", expectResult: "bar" }, -])("Class method name collision (%p)", ({ input, expectResult }) => { - const code = ` +test.each(["(new Foo())", "Foo"])("Class method name collision (%p)", input => { + util.testFunction` class Foo { public method() { return "foo"; } public static method() { return "bar"; } } return ${input}.method(); - `; - expect(util.transpileAndExecute(code)).toBe(expectResult); + `.expectToMatchJsResult(); }); test("Class static instance of self", () => { - const code = ` + util.testFunction` class Foo { bar = "foobar"; static instance = new Foo(); } return Foo.instance.bar; - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("Class name", () => { - const code = ` + util.testFunction` class Foo {} return Foo.name; - `; - expect(util.transpileAndExecute(code)).toBe("Foo"); + `.expectToMatchJsResult(); }); test("Class name via constructor", () => { - const code = ` + util.testFunction` class Foo {} const foo = new Foo(); return foo.constructor.name; - `; - expect(util.transpileAndExecute(code)).toBe("Foo"); + `.expectToMatchJsResult(); }); test("Class expression name", () => { - const code = ` + util.testFunction` const foo = class Foo {}; return foo.name; - `; - expect(util.transpileAndExecute(code)).toBe("Foo"); + `.expectToMatchJsResult(); }); test("Class expression name via constructor", () => { - const code = ` + util.testFunction` const foo = class Foo {}; const bar = new foo(); return bar.constructor.name; - `; - expect(util.transpileAndExecute(code)).toBe("Foo"); + `.expectToMatchJsResult(); }); -test("Class annonymous expression name", () => { - const code = ` +test("Anonymous class in variable declaration has name", () => { + util.testFunction` const foo = class {}; - return foo.name; - `; - expect(util.transpileAndExecute(code)).toBe("____"); + const bar = foo; + return { a: foo.name, b: bar.name }; + `.expectToMatchJsResult(); +}); + +test("Anonymous class expression outside variable assignment", () => { + util.testExpression`(class {}).name`.expectToMatchJsResult(); }); -test("Class annonymous expression name via constructor", () => { - const code = ` +test("Class anonymous expression name via constructor", () => { + util.testFunction` const foo = class {}; const bar = new foo(); return bar.constructor.name; - `; - expect(util.transpileAndExecute(code)).toBe("____"); + `.expectToMatchJsResult(); }); test("Class field override in subclass", () => { - const code = ` + util.testFunction` class Foo { field = "foo"; } class Bar extends Foo { field = "bar"; } - return (new Foo()).field + (new Bar()).field;`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (new Foo()).field + (new Bar()).field; + `.expectToMatchJsResult(); }); test("Class field override in subclass with constructors", () => { - const code = ` + util.testFunction` class Foo { field = "foo"; constructor() {} @@ -846,8 +758,8 @@ test("Class field override in subclass with constructors", () => { field = "bar"; constructor() { super(); } } - return (new Foo()).field + (new Bar()).field;`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (new Foo()).field + (new Bar()).field; + `.expectToMatchJsResult(); }); test("missing declaration name", () => { @@ -855,3 +767,31 @@ test("missing declaration name", () => { class {} `.expectDiagnosticsToMatchSnapshot([1211]); }); + +test("default exported name class has correct name property", () => { + util.testModule` + export default class Test { static method() { return true; } } + ` + .setReturnExport("default.name") + .expectToMatchJsResult(); +}); + +test("default exported anonymous class has 'default' name property", () => { + util.testModule` + export default class { static method() { return true; } } + ` + .setReturnExport("default.name") + .expectToEqual("default"); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/584 +test("constructor class name available with constructor", () => { + util.testModule` + const decorator = any>(constructor: T) => class extends constructor {}; + + @decorator + class MyClass {} + + export const className = new MyClass().constructor.name; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 14cea1337..018503687 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -175,24 +175,6 @@ test("Export Default Function", () => { expect(result).toBe(true); }); -test.each([ - ["Test", "export default class Test { static method() { return true; } }"], - ["default", "export default class { static method() { return true; } }"], -])("Export Default Class Name (%p)", (expectedClassName, classDeclarationStatement) => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport.name; - `, - "module.ts": classDeclarationStatement, - }, - "value" - ); - - expect(result).toBe(expectedClassName); -}); - test("Export Equals", () => { const [result] = util.transpileAndExecuteProjectReturningMainExport( { From 7d46a761c7390d93d1314998c2286e3e99e0d821 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 5 Apr 2020 21:36:21 +0200 Subject: [PATCH 247/764] 0.32.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7806d20d1..6bd2b360e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.0", + "version": "0.32.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index be2ebd2d4..b5ec7a009 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.0", + "version": "0.32.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From abeefbfb238864e79b9185191c4f616ea0faf109 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 9 Apr 2020 21:02:59 +0200 Subject: [PATCH 248/764] use checkout v2 in lint job (#851) --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ae6be450f..5ee8ba432 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - uses: actions/setup-node@v1 - run: npm ci - run: npm run lint From 8ac51c340e2ce20daac2fed0f1ba374174e7643d Mon Sep 17 00:00:00 2001 From: chrisd08 Date: Thu, 9 Apr 2020 20:11:38 +0100 Subject: [PATCH 249/764] Fixes class getters inheritance bug (#850) --- src/lualib/Descriptors.ts | 2 +- test/unit/classes/accessors.spec.ts | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lualib/Descriptors.ts b/src/lualib/Descriptors.ts index eb5198408..7b6410ed6 100644 --- a/src/lualib/Descriptors.ts +++ b/src/lualib/Descriptors.ts @@ -50,7 +50,7 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { // It's also used directly in class transform to add descriptors to the prototype function __TS__SetDescriptor(this: void, metatable: Metatable, prop: string, descriptor: PropertyDescriptor): void { - if (!metatable._descriptors) metatable._descriptors = {}; + if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; metatable._descriptors[prop] = descriptor; if (descriptor.get) metatable.__index = ____descriptorIndex; diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 5f9232246..4004a43f2 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -66,6 +66,26 @@ test("get accessor override accessor", () => { `.expectToMatchJsResult(); }); +test("get accessor override accessor (multiple)", () => { + util.testFunction` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + } + class Bar extends Foo { + _bar = "bar"; + get foo() { return this._bar; } + } + class Baz extends Foo { + _baz = "baz"; + get foo() { return this._baz; } + } + const bar = new Bar(); + const baz = new Baz(); + return bar.foo + baz.foo; + `.expectToMatchJsResult(); +}); + test("get accessor from interface", () => { util.testFunction` class Foo { From 3ebc76745f74ce709bf0ba39f830a8f5cf94c473 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 9 Apr 2020 21:17:04 +0200 Subject: [PATCH 250/764] 0.32.2 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6bd2b360e..ad25546ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.1", + "version": "0.32.2", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b5ec7a009..7a3656c5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.1", + "version": "0.32.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 2125b4f2397bf4926db03af5219f6a6ff8e84ccd Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 27 Apr 2020 14:48:25 +0200 Subject: [PATCH 251/764] Update LICENSE (#854) I don't think its required and it doesn't affect the copyright in anyway. But for completeness sake: added `TypeScriptToLua Contributors` to the copyright notice. Closes #852 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 4ae072ee1..5c655aca8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) [fullname] +Copyright (c) TypeScriptToLua Contributors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 918726f1dc912ac161dddba6491814c4f59cf8bd Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 29 Apr 2020 18:27:22 +0500 Subject: [PATCH 252/764] Check Node.js version (#857) --- src/tstl.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tstl.ts b/src/tstl.ts index 3a6446b15..d19f792db 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -204,6 +204,20 @@ function updateWatchCompilationHost( }; } +function checkNodeVersion(): void { + const [major, minor] = process.version + .slice(1) + .split(".") + .map(Number); + const isValid = major > 12 || (major === 12 && minor >= 13); + if (!isValid) { + console.error(`TypeScriptToLua requires Node.js >=12.13.0, the current version is ${process.version}`); + process.exit(1); + } +} + +checkNodeVersion(); + if (ts.sys.setBlocking) { ts.sys.setBlocking(); } From 78780d34464f5bdc61588957c48c0fa5d3e516ac Mon Sep 17 00:00:00 2001 From: ark120202 Date: Thu, 30 Apr 2020 01:14:44 +0500 Subject: [PATCH 253/764] Update readme with website links (#848) * Update readme with website links * Add some tooling references to the description * Add a `Getting Started` section * Apply suggestions from code review Co-Authored-By: Perry van Wesel Co-authored-by: Perry van Wesel --- README.md | 90 +++++++++++++++---------------------------------------- 1 file changed, 24 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index d8c929e23..13198efc1 100644 --- a/README.md +++ b/README.md @@ -1,86 +1,44 @@ -A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua! - -Large projects written in lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good IDE support. This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. - -## Documentation - -More detailed documentation and info on writing declarations can be found [on the wiki](https://github.com/TypeScriptToLua/TypescriptToLua/wiki). - -Changelog can be found in [CHANGELOG.md](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CHANGELOG.md) - -## Usage Guide - -**Install** - -`npm install -g typescript-to-lua` - -**Compile Files** - -`tstl path/to/file.ts path/to/other-file.ts` +--- -**Compile Projects** +A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua! -`tstl -p path/to/tsconfig.json` +Large projects written in Lua can become hard to maintain and make it easy to make mistakes. Writing code in TypeScript instead improves maintainability, readability and robustness, with the added bonus of good [tooling] support (including [ESLint], [Prettier], [Visual Studio Code] and [WebStorm]). This project is useful in any environment where Lua code is accepted, with the powerful option of simply declaring any existing API using TypeScript declaration files. -**Compile project in watch mode** +[tooling]: https://typescripttolua.github.io/docs/editor-support +[eslint]: https://eslint.org/ +[prettier]: https://prettier.io/ +[visual studio code]: https://code.visualstudio.com/ +[webstorm]: https://www.jetbrains.com/webstorm/ -`tstl -p path/to/tsconfig.json --watch` +## Getting Started -**Example tsconfig.json** +To install TypeScriptToLua add the `typescript-to-lua` npm package: -```json -{ - "compilerOptions": { - "target": "esnext", - "lib": ["esnext"], - "strict": true - }, - "tstl": { - "luaTarget": "JIT" - } -} +```bash +$ npm install -D typescript-to-lua ``` -## Contributing - -All contributions are welcome, but please read our [contribution guidelines](https://github.com/TypeScriptToLua/TypescriptToLua/blob/master/CONTRIBUTING.md)! - -## Declarations - -The real power of this transpiler is usage together with good declarations for the Lua API provided. Some examples of Lua interface declarations can be found here: - -- [Dota 2 Modding](https://github.com/ModDota/API/tree/master/declarations/server) -- [Defold Game Engine Scripting](https://github.com/dasannikov/DefoldTypeScript/blob/master/defold.d.ts) -- [LÖVE 2D Game Development](https://github.com/hazzard993/love-typescript-definitions) -- [World of Warcraft - Addon Development](https://github.com/wartoshika/wow-declarations) -- [World of Warcraft Classic - Addon Development](https://github.com/wartoshika/wow-classic-declarations) - -## Sublime Text integration - -This compiler works great in combination with the [Sublime Text Typescript plugin](https://github.com/Microsoft/TypeScript-Sublime-Plugin) (available through the package manager as `TypeScript`). - -You can simply open your typescript project assuming a valid tsconfig.json file is present. The default TypeScript plugin will provide all functionality of a regular TypeScript project. - -### Setting up a custom build system - -To add the option to build with the Lua transpiler instead of the regular typescript compiler, go to `Tools > Build System > New Build System...`. In the new sublime-build file that opens, enter the following (adjust path to tstl if not installed globally): +This package includes the `tstl` command line application, which can be used similarly to `tsc`: ``` -{ - "cmd": ["tstl", "-p", "$file"], - "shell": true -} +$ npx tstl ``` -Save this in your Sublime settings as a `TypeScriptToLua.sublime-build`. You can now select the TypeScriptToLua build system in `Tools > Build System` to build using the normal hotkey (`ctrl+B`), or if you have multiple TypeScript projects open, you can choose your compiler before building by pressing `ctrl+shift+B`. +For more information, check out [Getting Started](https://typescripttolua.github.io/docs/getting-started) in our documentation. From 08aa7784503c6f61f8a48d25dbed93c73d4f3cc2 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 30 Apr 2020 12:40:23 -0600 Subject: [PATCH 254/764] fixed paths in source maps (#859) * fixed paths in source maps - 'sources' now contain full relative paths to original ts file - 'sourceRoot' is only set if specified explicitly from tsconfig.json fixes #855 * updated based on feedback and fixed incorrect test discovered as a result Co-authored-by: Tom --- src/LuaPrinter.ts | 34 ++++++++++++++------ test/transpile/plugins/printer.ts | 2 +- test/unit/printer/sourcemaps.spec.ts | 47 +++++++++++++++++++++++++--- 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index dc94c6b53..5bccfbe30 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -6,7 +6,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, trimExtension } from "./utils"; +import { intersperse, trimExtension, normalizeSlashes } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -87,8 +87,7 @@ export interface PrintResult { export function createPrinter(printers: Printer[]): Printer { if (printers.length === 0) { - return (program, emitHost, fileName, ...args) => - new LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args); + return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args); } else if (printers.length === 1) { return printers[0]; } else { @@ -127,9 +126,26 @@ export class LuaPrinter { private currentIndent = ""; private sourceFile: string; + private options: CompilerOptions; - public constructor(private options: CompilerOptions, private emitHost: EmitHost, fileName: string) { - this.sourceFile = path.basename(fileName); + public constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { + this.options = program.getCompilerOptions(); + + if (this.options.outDir) { + const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName); + if (this.options.sourceRoot) { + // When sourceRoot is specified, just use relative path inside rootDir + this.sourceFile = relativeFileName; + } else { + // Calculate relative path from rootDir to outDir + const outputPath = path.resolve(this.options.outDir, relativeFileName); + this.sourceFile = path.relative(path.dirname(outputPath), fileName); + } + // We want forward slashes, even in windows + this.sourceFile = normalizeSlashes(this.sourceFile); + } else { + this.sourceFile = path.basename(fileName); // File will be in same dir as source + } } public print(block: lua.Block, luaLibFeatures: Set): PrintResult { @@ -138,10 +154,10 @@ export class LuaPrinter { luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); } - const sourceRoot = - this.options.sourceRoot || - (this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : "."); - + const sourceRoot = this.options.sourceRoot + ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included + this.options.sourceRoot.replace(/[\\\/]+$/, "") + "/" + : ""; const rootSourceNode = this.printImplementation(block, luaLibFeatures); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts index 771f0f4a6..6b3999d07 100644 --- a/test/transpile/plugins/printer.ts +++ b/test/transpile/plugins/printer.ts @@ -2,7 +2,7 @@ import * as tstl from "../../../src"; const plugin: tstl.Plugin = { printer: (program, emitHost, fileName, ...args) => { - const result = new tstl.LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args); + const result = new tstl.LuaPrinter(emitHost, program, fileName).print(...args); result.code = `-- Plugin\n${result.code}`; return result; }, diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 58873690c..011ae4e70 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -159,27 +159,64 @@ test.each([ } }); -test("Source map has correct sources", async () => { +test.each([ + { fileName: "/proj/foo.ts", config: {}, mapSource: "foo.ts", fullSource: "foo.ts" }, + { + fileName: "/proj/src/foo.ts", + config: { outDir: "/proj/dst" }, + mapSource: "../src/foo.ts", + fullSource: "../src/foo.ts", + }, + { + fileName: "/proj/src/foo.ts", + config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + mapSource: "../src/foo.ts", + fullSource: "../src/foo.ts", + }, + { + fileName: "/proj/src/sub/foo.ts", + config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + mapSource: "../../src/sub/foo.ts", + fullSource: "../../src/sub/foo.ts", + }, + { + fileName: "/proj/src/sub/main.ts", + config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, + mapSource: "sub/main.ts", + fullSource: "bin/sub/main.ts", + }, +])("Source map has correct sources (%p)", async ({ fileName, config, mapSource, fullSource }) => { const file = util.testModule` const foo = "foo" ` - .expectToHaveNoDiagnostics() + .setOptions(config) + .setMainFileName(fileName) .getMainLuaFileResult(); + const sourceMap = JSON.parse(file.sourceMap); + expect(sourceMap.sources.length).toBe(1); + expect(sourceMap.sources[0]).toBe(mapSource); + const consumer = await new SourceMapConsumer(file.sourceMap); expect(consumer.sources.length).toBe(1); - expect(consumer.sources[0]).toBe("main.ts"); + expect(consumer.sources[0]).toBe(fullSource); }); -test("Source map has correct source root", async () => { +test.each([ + { configSourceRoot: undefined, mapSourceRoot: "" }, + { configSourceRoot: "src", mapSourceRoot: "src/" }, + { configSourceRoot: "src/", mapSourceRoot: "src/" }, + { configSourceRoot: "src\\", mapSourceRoot: "src/" }, +])("Source map has correct source root (%p)", async ({ configSourceRoot, mapSourceRoot }) => { const file = util.testModule` const foo = "foo" ` + .setOptions({ sourceMap: true, sourceRoot: configSourceRoot }) .expectToHaveNoDiagnostics() .getMainLuaFileResult(); const sourceMap = JSON.parse(file.sourceMap); - expect(sourceMap.sourceRoot).toBe("."); + expect(sourceMap.sourceRoot).toBe(mapSourceRoot); }); test.each([ From 8487f7add903eb73d9292747f879cd5da8507cb9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 30 Apr 2020 20:40:40 +0200 Subject: [PATCH 255/764] Allow @noSelf on any function declaration (#858) * Allow @noSelf on any function declaration * PR comments * Fixed snapshots --- src/transformation/utils/function-context.ts | 5 + .../noSelfAnnotation.spec.ts.snap | 15 ++ test/unit/functions/noSelfAnnotation.spec.ts | 53 ++++++ .../invalidFunctionAssignments.spec.ts.snap | 180 ++++++++++++++++++ .../validation/functionPermutations.ts | 24 +++ 5 files changed, 277 insertions(+) create mode 100644 test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap create mode 100644 test/unit/functions/noSelfAnnotation.spec.ts diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 6a2113d6a..8bf05255c 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -46,6 +46,11 @@ export function getDeclarationContextType( : ContextType.NonVoid; } + // noSelf declaration on function signature + if (getNodeAnnotations(signatureDeclaration).has(AnnotationKind.NoSelf)) { + return ContextType.Void; + } + if ( ts.isMethodSignature(signatureDeclaration) || ts.isMethodDeclaration(signatureDeclaration) || diff --git a/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap b/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap new file mode 100644 index 000000000..f4e5fdd6d --- /dev/null +++ b/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`@noSelf on declared function removes context argument 1`] = `"myFunction()"`; + +exports[`@noSelf on method inside class declaration removes context argument 1`] = `"holder.myMethod()"`; + +exports[`@noSelf on method inside interface declaration removes context argument 1`] = `"holder.myMethod()"`; + +exports[`@noSelf on method inside namespace declaration removes context argument 1`] = `"MyNamespace.myMethod()"`; + +exports[`@noSelf on parent class declaration removes context argument 1`] = `"holder.myMethod()"`; + +exports[`@noSelf on parent interface declaration removes context argument 1`] = `"holder.myMethod()"`; + +exports[`@noSelf on parent namespace declaration removes context argument 1`] = `"MyNamespace.myMethod()"`; diff --git a/test/unit/functions/noSelfAnnotation.spec.ts b/test/unit/functions/noSelfAnnotation.spec.ts new file mode 100644 index 000000000..ab77ec03e --- /dev/null +++ b/test/unit/functions/noSelfAnnotation.spec.ts @@ -0,0 +1,53 @@ +import * as util from "../../util"; + +const methodHolders = ["class", "interface"]; + +test("@noSelf on declared function removes context argument", () => { + util.testModule` + /** @noSelf */ + declare function myFunction(): void; + myFunction(); + `.expectLuaToMatchSnapshot(); +}); + +test.each(methodHolders)("@noSelf on method inside %s declaration removes context argument", holderType => { + util.testModule` + declare ${holderType} MethodHolder { + /** @noSelf */ + myMethod(): void; + } + declare const holder: MethodHolder; + holder.myMethod(); + `.expectLuaToMatchSnapshot(); +}); + +test.each(methodHolders)("@noSelf on parent %s declaration removes context argument", holderType => { + util.testModule` + /** @noSelf */ + declare ${holderType} MethodHolder { + myMethod(): void; + } + declare const holder: MethodHolder; + holder.myMethod(); + `.expectLuaToMatchSnapshot(); +}); + +test("@noSelf on method inside namespace declaration removes context argument", () => { + util.testModule` + declare namespace MyNamespace { + /** @noSelf */ + export function myMethod(): void; + } + MyNamespace.myMethod(); + `.expectLuaToMatchSnapshot(); +}); + +test("@noSelf on parent namespace declaration removes context argument", () => { + util.testModule` + /** @noSelf */ + declare namespace MyNamespace { + export function myMethod(): void; + } + MyNamespace.myMethod(); + `.expectLuaToMatchSnapshot(); +}); diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index 9f112f305..55e61f9ae 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -179,6 +179,18 @@ exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMerged exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function argument ({"definition": "class StaticFuncPropClass { static staticFuncProp: (this: any, s: string) => string = s => s; }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -237,6 +249,22 @@ exports[`Invalid function argument ({"definition": "interface FuncPropInterface exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function argument ({"definition": "interface VoidFuncPropInterface { voidFuncProp: (this: void, s: string) => string; } @@ -301,6 +329,14 @@ exports[`Invalid function argument ({"definition": "namespace NoSelfAnonFuncNSMe exports[`Invalid function argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -535,6 +571,18 @@ exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMerg exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function assignment ({"definition": "class StaticFuncPropClass { static staticFuncProp: (this: any, s: string) => string = s => s; }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -593,6 +641,22 @@ exports[`Invalid function assignment ({"definition": "interface FuncPropInterfac exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(10,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function assignment ({"definition": "interface VoidFuncPropInterface { voidFuncProp: (this: void, s: string) => string; } @@ -657,6 +721,14 @@ exports[`Invalid function assignment ({"definition": "namespace NoSelfAnonFuncNS exports[`Invalid function assignment ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function assignment ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(6,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function assignment ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -891,6 +963,18 @@ exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFunc exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function generic argument ({"definition": "class StaticFuncPropClass { static staticFuncProp: (this: any, s: string) => string = s => s; }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -949,6 +1033,22 @@ exports[`Invalid function generic argument ({"definition": "interface FuncPropIn exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function generic argument ({"definition": "interface VoidFuncPropInterface { voidFuncProp: (this: void, s: string) => string; } @@ -1013,6 +1113,14 @@ exports[`Invalid function generic argument ({"definition": "namespace NoSelfAnon exports[`Invalid function generic argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function generic argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(6,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function generic argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -1215,6 +1323,18 @@ exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedCl exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function return ({"definition": "class StaticFuncPropClass { static staticFuncProp: (this: any, s: string) => string = s => s; }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -1273,6 +1393,22 @@ exports[`Invalid function return ({"definition": "interface FuncPropInterface { exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(10,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function return ({"definition": "interface VoidFuncPropInterface { voidFuncProp: (this: void, s: string) => string; } @@ -1337,6 +1473,14 @@ exports[`Invalid function return ({"definition": "namespace NoSelfAnonFuncNSMerg exports[`Invalid function return ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function return ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(6,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function return ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -1579,6 +1723,18 @@ exports[`Invalid function variable declaration ({"definition": "class NoSelfAnon exports[`Invalid function variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function variable declaration ({"definition": "class StaticFuncPropClass { static staticFuncProp: (this: any, s: string) => string = s => s; }", "value": "StaticFuncPropClass.staticFuncProp"}): diagnostics 1`] = `"main.ts(5,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -1637,6 +1793,22 @@ exports[`Invalid function variable declaration ({"definition": "interface FuncPr exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(9,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 2`] = `"main.ts(9,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function variable declaration ({"definition": "interface VoidFuncPropInterface { voidFuncProp: (this: void, s: string) => string; } @@ -1701,6 +1873,14 @@ exports[`Invalid function variable declaration ({"definition": "namespace NoSelf exports[`Invalid function variable declaration ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 1`] = `"main.ts(5,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid function variable declaration ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}): diagnostics 2`] = `"main.ts(5,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + exports[`Invalid function variable declaration ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index c6c51be91..f6b2672f4 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -190,6 +190,12 @@ export const noSelfTestFunctions: TestFunction[] = [ value: "NoSelfFuncNs.noSelfNsFunc", definition: `/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }`, }, + { + value: "NoSelfFuncNs.noSelfNsFunc", + definition: `namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }`, + }, { value: "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc", definition: `/** @noSelf */ namespace NoSelfFuncNestedNs { @@ -213,6 +219,14 @@ export const noSelfTestFunctions: TestFunction[] = [ definition: `/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();`, }, + { + value: "noSelfMethodClass.noSelfMethod", + definition: `class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();`, + }, { value: "NoSelfStaticMethodClass.noSelfStaticMethod", definition: `/** @noSelf */ class NoSelfStaticMethodClass { @@ -255,6 +269,16 @@ export const noSelfTestFunctions: TestFunction[] = [ noSelfMethod: function(s: string): string { return s; } };`, }, + { + value: "noSelfMethodInterface.noSelfMethod", + definition: `interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };`, + }, { value: "noSelfFuncPropInterface.noSelfFuncProp", definition: `/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } From 244633bcbed6b303ce4b6f178be3702646b934a4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 2 May 2020 10:09:42 -0600 Subject: [PATCH 256/764] fixed class name test to work in all versions of node (#862) Co-authored-by: Tom --- test/unit/classes/classes.spec.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 4b58db2cf..6bf2fc85f 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -788,10 +788,12 @@ test("default exported anonymous class has 'default' name property", () => { test("constructor class name available with constructor", () => { util.testModule` const decorator = any>(constructor: T) => class extends constructor {}; - + @decorator class MyClass {} export const className = new MyClass().constructor.name; - `.expectToMatchJsResult(); + ` + .setReturnExport("className") + .expectToEqual("MyClass"); }); From 89f3413c4d8fa4377c3761b33dcf27675690e8da Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 9 May 2020 15:03:14 +0200 Subject: [PATCH 257/764] Feature/nullish coalescing (#866) * Early null-coalescing * Fixed type predicate, added tests for side effects --- src/transformation/utils/diagnostics.ts | 2 - src/transformation/utils/typescript/types.ts | 51 ++++++++++++++--- .../visitors/binary-expression/index.ts | 55 ++++++++++++++----- test/unit/nullishCoalescing.spec.ts | 42 ++++++++++++++ 4 files changed, 127 insertions(+), 23 deletions(-) create mode 100644 test/unit/nullishCoalescing.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 5b7b2de38..656b7baad 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -97,8 +97,6 @@ export const unsupportedAccessorInObjectLiteral = createDiagnosticFactory( "Accessors in object literal are not supported." ); -export const unsupportedNullishCoalescing = createDiagnosticFactory("Nullish coalescing is not supported."); - export const unsupportedRightShiftOperator = createDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index ba7f1b790..2c6e69dcb 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -2,22 +2,57 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; export function isTypeWithFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { - if (type.symbol) { - const baseConstraint = context.checker.getBaseConstraintOfType(type); - if (baseConstraint && baseConstraint !== type) { - return isTypeWithFlags(context, baseConstraint, flags); + const predicate = (type: ts.Type) => { + if (type.symbol) { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint && baseConstraint !== type) { + return isTypeWithFlags(context, baseConstraint, flags); + } } + return (type.flags & flags) !== 0; + }; + + return typeAlwaysSatisfies(context, type, predicate); +} + +export function typeAlwaysSatisfies( + context: TransformationContext, + type: ts.Type, + predicate: (type: ts.Type) => boolean +): boolean { + if (predicate(type)) { + return true; + } + + if (type.isUnion()) { + return type.types.every(t => typeAlwaysSatisfies(context, t, predicate)); + } + + if (type.isIntersection()) { + return type.types.some(t => typeAlwaysSatisfies(context, t, predicate)); + } + + return false; +} + +export function typeCanSatisfy( + context: TransformationContext, + type: ts.Type, + predicate: (type: ts.Type) => boolean +): boolean { + if (predicate(type)) { + return true; } if (type.isUnion()) { - return type.types.every(t => isTypeWithFlags(context, t, flags)); + return type.types.some(t => typeCanSatisfy(context, t, predicate)); } if (type.isIntersection()) { - return type.types.some(t => isTypeWithFlags(context, t, flags)); + return type.types.some(t => typeCanSatisfy(context, t, predicate)); } - return (type.flags & flags) !== 0; + return false; } export function isStringType(context: TransformationContext, type: ts.Type): boolean { @@ -52,7 +87,7 @@ function isExplicitArrayType(context: TransformationContext, type: ts.Type): boo /** * Iterate over a type and its bases until the callback returns true. */ -function forTypeOrAnySupertype( +export function forTypeOrAnySupertype( context: TransformationContext, type: ts.Type, predicate: (type: ts.Type) => boolean diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index bbddf2eff..afc439700 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,14 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { - extensionInvalidInstanceOf, - luaTableInvalidInstanceOf, - unsupportedNullishCoalescing, -} from "../../utils/diagnostics"; +import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { isStandardLibraryType, isStringType } from "../../utils/typescript"; +import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; import { transformAssignmentExpression, transformAssignmentStatement } from "./assignments"; import { BitOperator, isBitOperator, transformBinaryBitOperation } from "./bit"; @@ -137,13 +133,7 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.QuestionQuestionToken: { - context.diagnostics.push(unsupportedNullishCoalescing(node.operatorToken)); - return lua.createBinaryExpression( - context.transformExpression(node.left), - context.transformExpression(node.right), - lua.SyntaxKind.OrOperator, - node - ); + return transformNullishCoalescingExpression(context, node); } default: @@ -185,3 +175,42 @@ export function transformBinaryExpressionStatement( return lua.createDoStatement(statements, expression); } } + +function transformNullishCoalescingExpression( + context: TransformationContext, + node: ts.BinaryExpression +): lua.Expression { + const lhsType = context.checker.getTypeAtLocation(node.left); + + // Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'. + const typeCanBeFalse = (type: ts.Type) => + (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Boolean)) !== 0 || + (type.flags & ts.TypeFlags.BooleanLiteral & ts.TypeFlags.PossiblyFalsy) !== 0; + if (typeCanSatisfy(context, lhsType, typeCanBeFalse)) { + // lhs can be false, transform to IIFE + const lhsIdentifier = lua.createIdentifier("____lhs"); + const nilComparison = lua.createBinaryExpression( + lua.cloneIdentifier(lhsIdentifier), + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + // if ____ == nil then return rhs else return ____ end + const ifStatement = lua.createIfStatement( + nilComparison, + lua.createBlock([lua.createReturnStatement([context.transformExpression(node.right)])]), + lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]) + ); + // (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs) + return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [ + context.transformExpression(node.left), + ]); + } else { + // lhs or rhs + return lua.createBinaryExpression( + context.transformExpression(node.left), + context.transformExpression(node.right), + lua.SyntaxKind.OrOperator, + node + ); + } +} diff --git a/test/unit/nullishCoalescing.spec.ts b/test/unit/nullishCoalescing.spec.ts new file mode 100644 index 000000000..67dbc1cec --- /dev/null +++ b/test/unit/nullishCoalescing.spec.ts @@ -0,0 +1,42 @@ +import * as util from "../util"; + +test.each(["null", "undefined"])("nullish-coalesing operator returns rhs", nullishValue => { + util.testExpression`${nullishValue} ?? "Hello, World!"`.expectToMatchJsResult(); +}); + +test.each([3, "foo", {}, [], true, false])("nullish-coalesing operator returns lhs", value => { + util.testExpression`${util.formatCode(value)} ?? "Hello, World!"`.expectToMatchJsResult(); +}); + +test.each(["any", "unknown"])("nullish-coalesing operator with any/unknown type", type => { + util.testFunction` + const unknownType = false as ${type}; + return unknownType ?? "This should not be returned!"; + `.expectToMatchJsResult(); +}); + +test.each(["boolean | string", "number | false", "undefined | true"])( + "nullish-coalesing operator with union type", + unionType => { + util.testFunction` + const unknownType = false as ${unionType}; + return unknownType ?? "This should not be returned!"; + `.expectToMatchJsResult(); + } +); + +test("nullish-coalescing operator with side effect lhs", () => { + util.testFunction` + let i = 0; + const incI = () => ++i; + return [i, incI() ?? 3, i]; + `.expectToMatchJsResult(); +}); + +test("nullish-coalescing operator with side effect rhs", () => { + util.testFunction` + let i = 0; + const incI = () => ++i; + return [i, undefined ?? incI(), i]; + `.expectToMatchJsResult(); +}); From 7556611cd05e596831ba174a19caccd36838cc83 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 9 May 2020 19:13:09 +0500 Subject: [PATCH 258/764] Switch to ESLint (#839) * Switch to ESLint * Update snapshots * Enable more `@typescript-eslint` rules * Extend typescript part of `@ark120202/eslint-config` * Update code from merge * Remove few tslint disable comments * Remove few unnecessary lines in eslint config * Enable `quotes` rule * Enable more eslint rules * Enable more eslint rules * Add `eslint-plugin-jest` * Disable `prefer-destructuring` rule * Fix `no-lonely-if` instead of suppressing it * Disable no-lonely-if * Make typescript internal module augmentation a declaration file A workaround for typescript-eslint/typescript-eslint#1993. * Upgrade typescript-eslint dependencies --- .eslintignore | 6 + .eslintrc.js | 190 +++ build_lualib.ts => build-lualib.js | 11 +- package-lock.json | 1223 +++++++++++++++-- package.json | 16 +- src/CompilerOptions.ts | 2 +- src/LuaAST.ts | 2 +- src/LuaLib.ts | 2 +- src/LuaPrinter.ts | 24 +- src/cli/parse.ts | 25 +- src/cli/tsconfig.ts | 3 +- src/lualib/ArrayFind.ts | 2 +- src/lualib/ArrayReduce.ts | 3 +- src/lualib/ArrayReduceRight.ts | 5 +- src/lualib/ArrayReverse.ts | 4 +- src/lualib/ArraySetLength.ts | 1 - src/lualib/ArraySplice.ts | 2 +- src/lualib/InstanceOf.ts | 2 +- src/lualib/Iterator.ts | 2 +- src/lualib/Map.ts | 9 +- src/lualib/New.ts | 2 +- src/lualib/NumberToString.ts | 2 - src/lualib/Set.ts | 1 - src/lualib/Spread.ts | 1 + src/lualib/StringConcat.ts | 2 +- src/lualib/StringPadEnd.ts | 3 +- src/lualib/StringPadStart.ts | 3 +- src/lualib/Symbol.ts | 9 +- src/lualib/SymbolRegistry.ts | 1 - src/lualib/WeakMap.ts | 1 + src/lualib/declarations/global.d.ts | 1 + src/lualib/declarations/tstl.d.ts | 2 +- src/transformation/builtins/index.ts | 3 +- src/transformation/context/context.ts | 2 +- src/transformation/context/visitors.ts | 8 +- src/transformation/utils/annotations.ts | 7 +- src/transformation/utils/diagnostics.ts | 18 +- src/transformation/utils/export.ts | 2 +- src/transformation/utils/typescript/index.ts | 3 +- .../visitors/binary-expression/assignments.ts | 35 +- .../visitors/binary-expression/index.ts | 2 +- src/transformation/visitors/call.ts | 8 +- .../visitors/class/members/accessors.ts | 4 +- src/transformation/visitors/enum.ts | 3 +- src/transformation/visitors/function.ts | 2 +- src/transformation/visitors/generator.ts | 9 +- src/transformation/visitors/loops/do-while.ts | 5 +- src/transformation/visitors/loops/for-of.ts | 33 +- src/transformation/visitors/lua-table.ts | 2 +- src/transformation/visitors/modules/import.ts | 6 +- src/transformation/visitors/template.ts | 2 +- .../visitors/variable-declaration.ts | 2 +- src/transpilation/bundle.ts | 9 +- src/transpilation/diagnostics.ts | 4 +- src/transpilation/emit.ts | 2 +- src/transpilation/index.ts | 4 +- src/transpilation/utils.ts | 1 - src/tstl.ts | 7 +- ...t-internal.ts => typescript-internal.d.ts} | 9 +- src/utils.ts | 10 +- test/cli/run.ts | 4 +- test/cli/tsconfig.spec.ts | 4 +- test/cli/watch.spec.ts | 8 +- test/legacy-utils.ts | 6 +- test/setup.ts | 7 +- .../__snapshots__/project.spec.ts.snap | 4 +- test/transpile/bundle.spec.ts | 2 +- test/transpile/directories.spec.ts | 2 +- test/transpile/plugins/printer.ts | 4 +- test/transpile/plugins/visitor-super.ts | 4 +- test/transpile/plugins/visitor.ts | 2 +- test/transpile/project/api.d.ts | 4 +- test/transpile/project/index.ts | 2 +- test/transpile/project/otherFile.ts | 2 +- test/transpile/resolve-plugin/ts.ts | 2 +- test/types/fengari.d.ts | 2 + .../annotations/customConstructor.spec.ts | 2 +- test/unit/annotations/luaTable.spec.ts | 38 +- test/unit/annotations/metaExtension.spec.ts | 2 +- test/unit/builtins/array.spec.ts | 3 - test/unit/builtins/loading.spec.ts | 6 +- test/unit/builtins/map.spec.ts | 54 +- test/unit/builtins/set.spec.ts | 10 +- test/unit/builtins/symbol.spec.ts | 2 +- test/unit/builtins/weakMap.spec.ts | 8 +- test/unit/builtins/weakSet.spec.ts | 2 +- test/unit/bundle.spec.ts | 2 +- test/unit/error.spec.ts | 16 +- test/unit/functions/functions.spec.ts | 2 +- .../validation/functionPermutations.ts | 38 +- .../validFunctionAssignments.spec.ts | 15 - test/unit/loops.spec.ts | 4 +- test/unit/modules/modules.spec.ts | 2 +- test/unit/modules/resolution.spec.ts | 8 +- test/unit/namespaces.spec.ts | 2 +- test/unit/objectLiteral.spec.ts | 8 +- test/unit/printer/deadCodeAfterReturn.spec.ts | 8 +- test/unit/printer/sourcemaps.spec.ts | 28 +- test/unit/typeof.spec.ts | 2 +- test/util.ts | 18 +- tslint.json | 52 - 101 files changed, 1653 insertions(+), 502 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc.js rename build_lualib.ts => build-lualib.js (71%) rename src/{typescript-internal.ts => typescript-internal.d.ts} (50%) delete mode 100644 tslint.json diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..707cb8140 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,6 @@ +/dist +/test/translation/transformation +/test/cli/errors +/test/cli/watch +/test/transpile/directories +/test/transpile/outFile diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 000000000..0ffbec9c9 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,190 @@ +// https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js +const typescriptBase = { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-types": [ + "error", + { + types: { + Function: null, + CallableFunction: { fixWith: "(...args: any[]) => any" }, + NewableFunction: { fixWith: "new (...args: any[]) => any" }, + }, + }, + ], + camelcase: "off", + "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], + "@typescript-eslint/class-name-casing": "error", + "@typescript-eslint/consistent-type-assertions": [ + "error", + { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, + ], + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": ["error", { overrides: { constructors: "no-public" } }], + "@typescript-eslint/generic-type-naming": ["error", "^(T([A-Z][A-Za-z]*)?|U|P|K|V)$"], + "@typescript-eslint/interface-name-prefix": "error", + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "error", + "no-throw-literal": "off", + "@typescript-eslint/no-throw-literal": "error", + "no-constant-condition": "off", + "@typescript-eslint/no-unnecessary-condition": ["error", { ignoreRhs: true, allowConstantLoopConditions: true }], + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-readonly": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + quotes: "off", + "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], + "@typescript-eslint/require-array-sort-compare": "error", + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", +}; + +module.exports = { + extends: ["plugin:jest/recommended", "plugin:jest/style"], + parserOptions: { sourceType: "module", project: ["test/tsconfig.json", "src/lualib/tsconfig.json"] }, + env: { es6: true, node: true }, + plugins: ["import"], + rules: { + "arrow-body-style": "error", + curly: ["error", "multi-line"], + eqeqeq: ["error", "always", { null: "ignore" }], + "no-caller": "error", + "no-cond-assign": "error", + "no-debugger": "error", + "no-duplicate-case": "error", + "no-new-wrappers": "error", + "no-restricted-globals": ["error", "parseInt", "parseFloat"], + "no-unused-labels": "error", + "no-var": "error", + "object-shorthand": "error", + "prefer-const": ["error", { destructuring: "all" }], + radix: "error", + "use-isnan": "error", + "object-shorthand": [ + "error", + "always", + { avoidQuotes: true, ignoreConstructors: false, avoidExplicitReturnArrows: true }, + ], + "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "SequenceExpression"], + "spaced-comment": [ + "error", + "always", + { + line: { exceptions: ["-", "+"], markers: ["=", "!", "/"] }, + block: { exceptions: ["-", "+"], markers: ["=", "!", ":", "::"], balanced: true }, + }, + ], + "no-delete-var": ["error"], + "no-label-var": ["error"], + yoda: ["error"], + "prefer-numeric-literals": ["error"], + "prefer-rest-params": ["error"], + "prefer-spread": ["error"], + "no-useless-computed-key": ["error"], + "for-direction": ["error"], + "no-compare-neg-zero": ["error"], + "no-dupe-else-if": ["error"], + "no-empty": ["error", { allowEmptyCatch: true }], + "no-implicit-coercion": ["error", { boolean: true, number: true, string: true }], + "operator-assignment": ["error"], + "no-path-concat": ["error"], + "no-compare-neg-zero": ["error"], + "no-control-regex": ["error"], + "no-unneeded-ternary": ["error", { defaultAssignment: false }], + "one-var": ["error", "never"], + "prefer-exponentiation-operator": ["error"], + "prefer-object-spread": ["error"], + "no-useless-call": ["off"], + "no-useless-catch": ["error"], + "no-useless-concat": ["error"], + "no-useless-escape": ["error"], + "no-useless-return": ["error"], + + "import/no-default-export": "error", + + "jest/expect-expect": "off", + "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], + "jest/no-expect-resolves": "error", + "jest/no-test-return-statement": "error", + "jest/no-truthy-falsy": "error", + "jest/prefer-spy-on": "error", + "jest/prefer-todo": "error", + "jest/valid-title": "error", + // TODO: + // "jest/lowercase-name": "error", + }, + overrides: [ + { + files: "**/*.ts", + extends: ["plugin:@typescript-eslint/base"], + rules: { + ...typescriptBase, + "@typescript-eslint/array-type": ["error", { default: "array-simple" }], + "@typescript-eslint/ban-types": ["error", { types: { null: null } }], + "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], + "@typescript-eslint/no-require-imports": "off", + "@typescript-eslint/no-unnecessary-condition": "off", + "@typescript-eslint/prefer-for-of": "error", + // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1265 + // "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-readonly": "off", + "@typescript-eslint/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], + "@typescript-eslint/require-array-sort-compare": "off", + "@typescript-eslint/camelcase": "off", + + // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1712 + // "@typescript-eslint/naming-convention": [ + // "error", + // { + // selector: "default", + // format: ["camelCase"], + // leadingUnderscore: "allow", + // }, + // { + // selector: "variable", + // format: ["camelCase", "UPPER_CASE"], + // leadingUnderscore: "allow", + // }, + // { + // selector: "typeLike", + // format: ["PascalCase"], + // }, + // ], + }, + }, + { + files: "src/lualib/**/*.ts", + rules: { + "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], + "@typescript-eslint/no-throw-literal": "off", + "@typescript-eslint/prefer-optional-chain": "off", + }, + }, + ], +}; diff --git a/build_lualib.ts b/build-lualib.js similarity index 71% rename from build_lualib.ts rename to build-lualib.js index 1f6897f0d..c083b854c 100644 --- a/build_lualib.ts +++ b/build-lualib.js @@ -1,8 +1,9 @@ -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import * as tstl from "./src"; -import { loadLuaLibFeatures } from "./src/LuaLib"; +require("ts-node/register/transpile-only"); +const fs = require("fs"); +const path = require("path"); +const ts = require("typescript"); +const tstl = require("./src"); +const { loadLuaLibFeatures } = require("./src/LuaLib"); const configFileName = path.resolve(__dirname, "src/lualib/tsconfig.json"); const { emitResult, diagnostics } = tstl.transpileProject(configFileName); diff --git a/package-lock.json b/package-lock.json index ad25546ec..f3d427049 100644 --- a/package-lock.json +++ b/package-lock.json @@ -556,6 +556,12 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -617,6 +623,12 @@ "pretty-format": "^25.1.0" } }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -659,6 +671,161 @@ "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", + "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.31.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", + "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.23.0", + "eslint-scope": "^5.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.31.0.tgz", + "integrity": "sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + } + }, + "eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", + "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -689,6 +856,12 @@ } } }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, "acorn-walk": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", @@ -789,12 +962,33 @@ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -1030,12 +1224,6 @@ "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", @@ -1090,6 +1278,12 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -1119,6 +1313,21 @@ } } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -1176,12 +1385,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", @@ -1194,6 +1397,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", @@ -1372,6 +1581,15 @@ "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "domexception": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", @@ -1406,6 +1624,15 @@ "once": "^1.4.0" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { "version": "1.17.4", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", @@ -1464,12 +1691,375 @@ } } }, + "eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-jest": { + "version": "23.8.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", + "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^2.5.0" + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true + } + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", @@ -1600,6 +2190,17 @@ } } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1709,6 +2310,24 @@ "tmp": "^0.0.33" } }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -1728,6 +2347,34 @@ "path-exists": "^4.0.0" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1798,6 +2445,12 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", @@ -1848,6 +2501,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -1858,8 +2520,7 @@ "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", - "dev": true, - "optional": true + "dev": true }, "growly": { "version": "1.3.0", @@ -1957,6 +2618,12 @@ } } }, + "hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, "html-encoding-sniffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", @@ -1998,6 +2665,30 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, "import-local": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", @@ -2030,6 +2721,27 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -2056,6 +2768,12 @@ } } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -2128,6 +2846,12 @@ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -2140,6 +2864,15 @@ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2155,6 +2888,12 @@ "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -2170,6 +2909,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -2919,6 +3664,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2991,6 +3742,26 @@ "type-check": "~0.3.2" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3162,6 +3933,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -3228,6 +4005,18 @@ } } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3338,6 +4127,18 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3412,6 +4213,24 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parse5": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", @@ -3447,6 +4266,15 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -3459,6 +4287,12 @@ "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", "dev": true }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, "pirates": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", @@ -3513,6 +4347,12 @@ "react-is": "^16.12.0" } }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "prompts": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", @@ -3557,6 +4397,78 @@ "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", "dev": true }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, "readline-sync": { "version": "1.4.9", "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", @@ -3582,6 +4494,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, "remove-trailing-separator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", @@ -3713,6 +4631,16 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -3734,6 +4662,24 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, + "run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3986,6 +4932,49 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -4156,6 +5145,38 @@ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", "dev": true }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -4306,6 +5327,12 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -4331,6 +5358,58 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -4352,12 +5431,24 @@ "minimatch": "^3.0.4" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "throat": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -4477,83 +5568,10 @@ "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", "dev": true }, - "tslint": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.0.0.tgz", - "integrity": "sha512-9nLya8GBtlFmmFMW7oXXwoXS1NkrccqTqAtwXzdPV9e2mqSEvCki6iHL/Fbzi5oqbugshzgGPk7KBb2qNP1DSA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.10.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -4706,6 +5724,12 @@ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "v8-to-istanbul": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz", @@ -4717,6 +5741,16 @@ "source-map": "^0.7.3" } }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -4827,6 +5861,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", diff --git a/package.json b/package.json index 7a3656c5d..6651b3109 100644 --- a/package.json +++ b/package.json @@ -19,12 +19,12 @@ "types": "dist/index.d.ts", "scripts": { "build": "tsc && npm run build-lualib", - "build-lualib": "ts-node --files ./build_lualib.ts", - "pretest": "npm run lint && ts-node --files --transpile-only ./build_lualib.ts", + "build-lualib": "node build-lualib.js", + "pretest": "npm run lint && npm run build-lualib", "test": "jest", - "lint": "npm run lint:tslint && npm run lint:prettier", + "lint": "npm run lint:eslint && npm run lint:prettier", "lint:prettier": "prettier --check \"**/*.{js,ts,yml,json,md}\" || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", - "lint:tslint": "tslint -p . && tslint -p test && tslint -p src/lualib", + "lint:eslint": "eslint . --ext .js,.ts", "fix:prettier": "prettier --check --write \"**/*.{js,ts,yml,json,md}\"", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" @@ -46,6 +46,11 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", + "@typescript-eslint/eslint-plugin": "^2.31.0", + "@typescript-eslint/parser": "^2.31.0", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jest": "^23.8.2", "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", @@ -53,7 +58,6 @@ "jest-circus": "^25.1.0", "prettier": "^1.19.1", "ts-jest": "^25.2.1", - "ts-node": "^8.6.2", - "tslint": "^6.0.0" + "ts-node": "^8.6.2" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 5a6291098..af9a82d7d 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { - [_ in keyof T]: infer U; + [K in keyof T]: infer U; } ? U : never; diff --git a/src/LuaAST.ts b/src/LuaAST.ts index d39639213..99af02718 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -146,7 +146,7 @@ export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node): Node { } export function cloneNode(node: T): T { - return Object.assign({}, node); + return { ...node }; } export function setNodePosition(node: T, position: TextRange): T { diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 38e978fb3..8c27e5730 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -68,7 +68,7 @@ export enum LuaLibFeature { TypeOf = "TypeOf", } -const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { +const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], Error: [LuaLibFeature.New, LuaLibFeature.Class, LuaLibFeature.FunctionCall], diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 5bccfbe30..63654c595 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -31,7 +31,7 @@ export const escapeString = (value: string) => `"${value.replace(escapeStringReg * `foo.bar` => passes (`function foo.bar()` is valid) * `getFoo().bar` => fails (`function getFoo().bar()` would be illegal) */ -const isValidLuaFunctionDeclarationName = (str: string) => /^[a-zA-Z0-9_\.]+$/.test(str); +const isValidLuaFunctionDeclarationName = (str: string) => /^[a-zA-Z0-9_.]+$/.test(str); /** * Returns true if expression contains no function calls. @@ -128,7 +128,7 @@ export class LuaPrinter { private sourceFile: string; private options: CompilerOptions; - public constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { + constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { this.options = program.getCompilerOptions(); if (this.options.outDir) { @@ -156,7 +156,7 @@ export class LuaPrinter { const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included - this.options.sourceRoot.replace(/[\\\/]+$/, "") + "/" + this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" : ""; const rootSourceNode = this.printImplementation(block, luaLibFeatures); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); @@ -207,7 +207,7 @@ export class LuaPrinter { let header = ""; if (!this.options.noHeader) { - header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`; + header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; } const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; @@ -216,7 +216,7 @@ export class LuaPrinter { (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) ) { // Require lualib bundle - header += `require("lualib_bundle");\n`; + header += 'require("lualib_bundle");\n'; } else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { // Inline lualib features header += "-- Lua Library inline imports\n"; @@ -233,7 +233,7 @@ export class LuaPrinter { } protected pushIndent(): void { - this.currentIndent = this.currentIndent + " "; + this.currentIndent += " "; } protected popIndent(): void { @@ -245,15 +245,14 @@ export class LuaPrinter { } protected createSourceNode(node: lua.Node, chunks: SourceChunk | SourceChunk[], name?: string): SourceNode { - const originalPos = lua.getOriginalPos(node); + const { line, column } = lua.getOriginalPos(node); - return originalPos !== undefined && originalPos.line !== undefined && originalPos.column !== undefined - ? new SourceNode(originalPos.line + 1, originalPos.column, this.sourceFile, chunks, name) - : new SourceNode(null, null, this.sourceFile, chunks, name); // tslint:disable-line:no-null-keyword + return line !== undefined && column !== undefined + ? new SourceNode(line + 1, column, this.sourceFile, chunks, name) + : new SourceNode(null, null, this.sourceFile, chunks, name); } protected concatNodes(...chunks: SourceChunk[]): SourceNode { - // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, this.sourceFile, chunks); } @@ -438,7 +437,7 @@ export class LuaPrinter { public printRepeatStatement(statement: lua.RepeatStatement): SourceNode { const chunks: SourceChunk[] = []; - chunks.push(this.indent(`repeat\n`)); + chunks.push(this.indent("repeat\n")); this.pushIndent(); chunks.push(this.printBlock(statement.body)); @@ -740,7 +739,6 @@ export class LuaPrinter { } public printOperator(kind: lua.Operator): SourceNode { - // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); } diff --git a/src/cli/parse.ts b/src/cli/parse.ts index ce0985913..1ffa50d6a 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -71,12 +71,12 @@ export const optionDeclarations: CommandLineOption[] = [ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { let hasRootLevelOptions = false; - for (const key in parsedConfigFile.raw) { - const option = optionDeclarations.find(option => option.name === key); + for (const [name, rawValue] of Object.entries(parsedConfigFile.raw)) { + const option = optionDeclarations.find(option => option.name === name); if (!option) continue; if (parsedConfigFile.raw.tstl === undefined) parsedConfigFile.raw.tstl = {}; - parsedConfigFile.raw.tstl[key] = parsedConfigFile.raw[key]; + parsedConfigFile.raw.tstl[name] = rawValue; hasRootLevelOptions = true; } @@ -85,16 +85,16 @@ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): parsedConfigFile.errors.push(cliDiagnostics.tstlOptionsAreMovingToTheTstlObject(parsedConfigFile.raw.tstl)); } - for (const key in parsedConfigFile.raw.tstl) { - const option = optionDeclarations.find(option => option.name === key); + for (const [name, rawValue] of Object.entries(parsedConfigFile.raw.tstl)) { + const option = optionDeclarations.find(option => option.name === name); if (!option) { - parsedConfigFile.errors.push(cliDiagnostics.unknownCompilerOption(key)); + parsedConfigFile.errors.push(cliDiagnostics.unknownCompilerOption(name)); continue; } - const { error, value } = readValue(option, parsedConfigFile.raw.tstl[key]); + const { error, value } = readValue(option, rawValue); if (error) parsedConfigFile.errors.push(error); - if (parsedConfigFile.options[key] === undefined) parsedConfigFile.options[key] = value; + if (parsedConfigFile.options[name] === undefined) parsedConfigFile.options[name] = value; } } @@ -123,12 +123,9 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: if (option) { // Ignore errors caused by tstl specific compiler options const tsInvalidCompilerOptionErrorCode = 5023; - parsedCommandLine.errors = parsedCommandLine.errors.filter(error => { - return !( - error.code === tsInvalidCompilerOptionErrorCode && - String(error.messageText).endsWith(`'${args[i]}'.`) - ); - }); + parsedCommandLine.errors = parsedCommandLine.errors.filter( + e => !(e.code === tsInvalidCompilerOptionErrorCode && String(e.messageText).endsWith(`'${args[i]}'.`)) + ); const { error, value, increment } = readCommandLineArgument(option, args[i + 1]); if (error) parsedCommandLine.errors.push(error); diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index 369c14363..bec7c2d31 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -57,8 +57,7 @@ export function createConfigFileUpdater( ): (options: ts.CompilerOptions) => ts.Diagnostic[] { const configFileMap = new WeakMap(); return options => { - const configFile = options.configFile as ts.TsConfigSourceFile | undefined; - const configFilePath = options.configFilePath as string | undefined; + const { configFile, configFilePath } = options; if (!configFile || !configFilePath) return []; if (!configFileMap.has(configFile)) { diff --git a/src/lualib/ArrayFind.ts b/src/lualib/ArrayFind.ts index 370200df1..608bd3ef6 100644 --- a/src/lualib/ArrayFind.ts +++ b/src/lualib/ArrayFind.ts @@ -11,7 +11,7 @@ function __TS__ArrayFind( if (predicate(elem, k, arr)) { return elem; } - k = k + 1; + k += 1; } return undefined; diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index db80f4e62..8dda6ebd5 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduce( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: Vararg ): T { const len = arr.length; @@ -17,7 +17,6 @@ function __TS__ArrayReduce( accumulator = arr[0]; k = 1; } else { - // tslint:disable-next-line: no-string-throw throw "Reduce of empty array with no initial value"; } diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 2ac6d21d3..a57f78697 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduceRight( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: Vararg ): T { const len = arr.length; @@ -15,9 +15,8 @@ function __TS__ArrayReduceRight( accumulator = select(1, ...initial); } else if (len > 0) { accumulator = arr[k]; - k = k - 1; + k -= 1; } else { - // tslint:disable-next-line: no-string-throw throw "Reduce of empty array with no initial value"; } diff --git a/src/lualib/ArrayReverse.ts b/src/lualib/ArrayReverse.ts index ae1fb90dd..b4a97a2c1 100644 --- a/src/lualib/ArrayReverse.ts +++ b/src/lualib/ArrayReverse.ts @@ -5,8 +5,8 @@ function __TS__ArrayReverse(this: void, arr: any[]): any[] { const temp = arr[j]; arr[j] = arr[i]; arr[i] = temp; - i = i + 1; - j = j - 1; + i += 1; + j -= 1; } return arr; } diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 10132ff3e..e1bd8ea03 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -6,7 +6,6 @@ function __TS__ArraySetLength(this: void, arr: T[], length: number): number { Math.floor(length) !== length ) { // non-integer - // tslint:disable-next-line:no-string-throw throw `invalid array length: ${length}`; } for (let i = arr.length - 1; i >= length; --i) { diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 862422e39..5df67938f 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { +function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index b75c040c2..a4d80c881 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -1,10 +1,10 @@ function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: LuaClass): boolean { if (typeof classTbl !== "object") { - // tslint:disable-next-line: no-string-throw throw "Right-hand side of 'instanceof' is not an object"; } if (classTbl[Symbol.hasInstance] !== undefined) { + // eslint-disable-next-line no-implicit-coercion return !!classTbl[Symbol.hasInstance](obj); } diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 8e7afcfe9..ca4618d9f 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -12,7 +12,7 @@ function __TS__Iterator(this: void, iterable: Iterable): (this: void) => T } else { let i = 0; return () => { - i = i + 1; + i += 1; return iterable[i]; }; } diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index aec325664..e442b6132 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -23,6 +23,7 @@ Map = class Map { if (result.done) { break; } + const value: [K, V] = result.value; // Ensures index is offset when tuple is accessed this.set(value[0], value[1]); } @@ -41,7 +42,6 @@ Map = class Map { this.firstKey = undefined; this.lastKey = undefined; this.size = 0; - return; } public delete(key: K): boolean { @@ -78,7 +78,6 @@ Map = class Map { for (const key of this.keys()) { callback(this.items.get(key), key, this); } - return; } public get(key: K): V | undefined { @@ -114,8 +113,7 @@ Map = class Map { } public entries(): IterableIterator<[K, V]> { - const items = this.items; - const nextKey = this.nextKey; + const { items, nextKey } = this; let key = this.firstKey; return { [Symbol.iterator](): IterableIterator<[K, V]> { @@ -145,8 +143,7 @@ Map = class Map { } public values(): IterableIterator { - const items = this.items; - const nextKey = this.nextKey; + const { items, nextKey } = this; let key = this.firstKey; return { [Symbol.iterator](): IterableIterator { diff --git a/src/lualib/New.ts b/src/lualib/New.ts index 47e25694d..507ba120c 100644 --- a/src/lualib/New.ts +++ b/src/lualib/New.ts @@ -1,4 +1,4 @@ -function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { +function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { const instance: any = setmetatable({}, target.prototype); instance.____constructor(...args); return instance; diff --git a/src/lualib/NumberToString.ts b/src/lualib/NumberToString.ts index 3ad9a3d5e..52da58d7c 100644 --- a/src/lualib/NumberToString.ts +++ b/src/lualib/NumberToString.ts @@ -1,4 +1,3 @@ -// tslint:disable-next-line: variable-name const ____radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tostring @@ -9,7 +8,6 @@ function __TS__NumberToString(this: number, radix?: number): string { radix = Math.floor(radix); if (radix < 2 || radix > 36) { - // tslint:disable-next-line: no-string-throw throw "toString() radix argument must be between 2 and 36"; } diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index 6dcbcac8b..71a8265ff 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -56,7 +56,6 @@ Set = class Set { this.firstKey = undefined; this.lastKey = undefined; this.size = 0; - return; } public delete(value: T): boolean { diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 8f88053d2..d9dcf0345 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,6 +1,7 @@ function __TS__Spread(this: void, iterable: string | Iterable): T[] { const arr = []; if (typeof iterable === "string") { + // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < iterable.length; i += 1) { arr[arr.length] = iterable[i]; } diff --git a/src/lualib/StringConcat.ts b/src/lualib/StringConcat.ts index e18a2e890..657ae5c24 100644 --- a/src/lualib/StringConcat.ts +++ b/src/lualib/StringConcat.ts @@ -1,7 +1,7 @@ function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { let out = str1; for (const arg of args) { - out = out + arg; + out += arg; } return out; } diff --git a/src/lualib/StringPadEnd.ts b/src/lualib/StringPadEnd.ts index 6be8b8853..74fb0ffc0 100644 --- a/src/lualib/StringPadEnd.ts +++ b/src/lualib/StringPadEnd.ts @@ -1,7 +1,6 @@ function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): string { if (maxLength !== maxLength) maxLength = 0; if (maxLength === -Infinity || maxLength === Infinity) { - // tslint:disable-next-line: no-string-throw throw "Invalid string length"; } @@ -9,7 +8,7 @@ function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): return this; } - maxLength = maxLength - this.length; + maxLength -= this.length; if (maxLength > fillString.length) { fillString += fillString.repeat(maxLength / fillString.length); } diff --git a/src/lualib/StringPadStart.ts b/src/lualib/StringPadStart.ts index 1fee2e64d..81ba93ad1 100644 --- a/src/lualib/StringPadStart.ts +++ b/src/lualib/StringPadStart.ts @@ -1,7 +1,6 @@ function __TS__StringPadStart(this: string, maxLength: number, fillString = " "): string { if (maxLength !== maxLength) maxLength = 0; if (maxLength === -Infinity || maxLength === Infinity) { - // tslint:disable-next-line: no-string-throw throw "Invalid string length"; } @@ -9,7 +8,7 @@ function __TS__StringPadStart(this: string, maxLength: number, fillString = " ") return this; } - maxLength = maxLength - this.length; + maxLength -= this.length; if (maxLength > fillString.length) { fillString += fillString.repeat(maxLength / fillString.length); } diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index f9e7d5eb5..61a5c0423 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,11 +1,6 @@ -// tslint:disable-next-line: variable-name const ____symbolMetatable = { - __tostring(): string { - if (this.description === undefined) { - return "Symbol()"; - } else { - return "Symbol(" + this.description + ")"; - } + __tostring(this: symbol): string { + return `Symbol(${this.description || ""})`; }, }; diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index 93b19e9b7..460edcc86 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -1,4 +1,3 @@ -// tslint:disable-next-line: variable-name const ____symbolRegistry: Record = {}; function __TS__SymbolRegistryFor(this: void, key: string): symbol { diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 169ad7ded..772f7bb58 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -17,6 +17,7 @@ WeakMap = class WeakMap { if (result.done) { break; } + const value: [K, V] = result.value; // Ensures index is offset when tuple is accessed this.items.set(value[0], value[1]); } diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 4a86d2542..35f2b3b3a 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-var */ /** @noSelfInFile */ declare var __TS__sourcemap: Record | undefined; diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 11c34c809..a983ee66d 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,7 +1,7 @@ /** @noSelfInFile */ /** @vararg */ -interface Vararg extends Array {} +type Vararg = T & { __luaVararg?: never }; /** @forRange */ declare function forRange(start: number, limit: number, step?: number): number[]; diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 8a23ed824..f6be3c0f2 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -73,8 +73,7 @@ export function transformBuiltinCallExpression( if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); - const symbolName = symbol && symbol.name; - switch (symbolName) { + switch (symbol?.name) { case "Console": return transformConsoleCall(context, node); case "Math": diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index ea375766b..27edbeea4 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -37,7 +37,7 @@ export class TransformationContext { (this.options.alwaysStrict ?? this.options.strict) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); - public constructor(public program: ts.Program, public sourceFile: ts.SourceFile, private visitorMap: VisitorMap) { + constructor(public program: ts.Program, public sourceFile: ts.SourceFile, private visitorMap: VisitorMap) { // Use `getParseTreeNode` to get original SourceFile node, before it was substituted by custom transformers. // It's required because otherwise `getEmitResolver` won't use cached diagnostics, produced in `emitWorker` // and would try to re-analyze the file, which would fail because of replaced nodes. diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index 48db4223a..5967c18b4 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { OneToManyVisitorResult } from "../utils/lua-ast"; import { TransformationContext } from "./context"; -type NodesBySyntaxKind = { +interface NodesBySyntaxKind { // Copied from is* type guards, with JSDoc and TypeNodes removed [ts.SyntaxKind.NumericLiteral]: ts.NumericLiteral; [ts.SyntaxKind.BigIntLiteral]: ts.BigIntLiteral; @@ -134,7 +134,7 @@ type NodesBySyntaxKind = { [ts.SyntaxKind.SuperKeyword]: ts.SuperExpression; [ts.SyntaxKind.ThisKeyword]: ts.ThisExpression; [ts.SyntaxKind.NotEmittedStatement]: ts.NotEmittedStatement; -}; +} export type ExpressionLikeNode = ts.Expression | ts.QualifiedName | ts.ExternalModuleReference; export type StatementLikeNode = ts.Statement; @@ -148,7 +148,7 @@ export type VisitorResult = T extends ExpressionLikeNode export type Visitor = FunctionVisitor | ObjectVisitor; export type FunctionVisitor = (node: T, context: TransformationContext) => VisitorResult; -export type ObjectVisitor = { +export interface ObjectVisitor { transform: FunctionVisitor; /** @@ -159,7 +159,7 @@ export type ObjectVisitor = { * Standard visitors have the lowest (`-Infinity`) priority. */ priority?: number; -}; +} export type Visitors = { [P in keyof NodesBySyntaxKind]?: Visitor }; export type VisitorMap = Map>>; diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 8f5936126..bd9d052ab 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -97,7 +97,7 @@ export function getSignatureAnnotations(context: TransformationContext, signatur // Function properties on interfaces have the JSDoc tags on the parent PropertySignature const declaration = signature.getDeclaration(); - if (declaration && declaration.parent && ts.isPropertySignature(declaration.parent)) { + if (declaration?.parent && ts.isPropertySignature(declaration.parent)) { const symbol = context.checker.getSymbolAtLocation(declaration.parent.name); if (symbol) { collectAnnotations(symbol, annotationsMap); @@ -121,8 +121,7 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) // Only check function type for directive if it is declared as an interface or type alias const declaration = signature.getDeclaration(); const isInterfaceOrAlias = - declaration && - declaration.parent && + declaration?.parent && ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || ts.isTypeAliasDeclaration(declaration.parent)); if (!isInterfaceOrAlias) { @@ -158,7 +157,7 @@ export function isInTupleReturnFunction(context: TransformationContext, node: ts // Check all overloads for directive const signatures = functionType.getCallSignatures(); - if (signatures && signatures.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { + if (signatures?.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { return true; } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 656b7baad..0a53898f9 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -11,13 +11,13 @@ const createDiagnosticFactory = (message: string | ((...arg messageText: typeof message === "string" ? message : message(...args), })); -export const forbiddenForIn = createDiagnosticFactory(`Iterating over arrays with 'for ... in' is not allowed.`); +export const forbiddenForIn = createDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: void'.` + "To fix, wrap in an arrow function, or declare with 'this: void'." ); }); @@ -25,7 +25,7 @@ export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + - `To fix, wrap in an arrow function, or declare with 'this: any'.` + "To fix, wrap in an arrow function, or declare with 'this: any'." ); }); @@ -37,7 +37,7 @@ export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: str ); }); -export const decoratorInvalidContext = createDiagnosticFactory(`Decorator function cannot have 'this: void'.`); +export const decoratorInvalidContext = createDiagnosticFactory("Decorator function cannot have 'this: void'."); export const annotationInvalidArgumentCount = createDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` @@ -48,23 +48,23 @@ export const extensionCannotConstruct = createDiagnosticFactory( ); export const extensionCannotExtend = createDiagnosticFactory( - `Cannot extend classes with '@extension' or '@metaExtension' annotation.` + "Cannot extend classes with '@extension' or '@metaExtension' annotation." ); export const extensionCannotExport = createDiagnosticFactory( - `Cannot export classes with '@extension' or '@metaExtension' annotation.` + "Cannot export classes with '@extension' or '@metaExtension' annotation." ); export const extensionInvalidInstanceOf = createDiagnosticFactory( - `Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation.` + "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." ); export const extensionAndMetaExtensionConflict = createDiagnosticFactory( - `Cannot use both '@extension' and '@metaExtension' annotations on the same class.` + "Cannot use both '@extension' and '@metaExtension' annotations on the same class." ); export const metaExtensionMissingExtends = createDiagnosticFactory( - `'@metaExtension' annotation requires the extension of the metatable class.` + "'@metaExtension' annotation requires the extension of the metatable class." ); export const invalidForRangeCall = createDiagnosticFactory((message: string) => `Invalid @forRange call: ${message}.`); diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index 5922a9fc5..d11109427 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -89,7 +89,7 @@ export function getExportedSymbolsFromScope( } // ts.Iterator is not a ES6-compatible iterator, because TypeScript targets ES5 - const it: Iterable = { [Symbol.iterator]: () => scopeSymbol!.exports!.values() }; + const it: Iterable = { [Symbol.iterator]: () => scopeSymbol.exports!.values() }; return [...it]; } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index fa4115614..394d67656 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -64,8 +64,7 @@ export function hasStandardLibrarySignature( callExpression: ts.CallExpression ): boolean { const signature = context.checker.getResolvedSignature(callExpression); - - return signature && signature.declaration ? isStandardLibraryDeclaration(context, signature.declaration) : false; + return signature?.declaration ? isStandardLibraryDeclaration(context, signature.declaration) : false; } export function inferAssignedType(context: TransformationContext, expression: ts.Expression): ts.Type { diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 6a785699a..94e17e9c7 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -150,28 +150,25 @@ export function transformAssignmentExpression( const canBeTransformedToLuaAssignmentStatement = ( context: TransformationContext, node: ts.DestructuringAssignment -): node is ts.ArrayDestructuringAssignment => { - return ( - ts.isArrayLiteralExpression(node.left) && - node.left.elements.every(element => { - if (isArrayLength(context, element)) { - return false; - } +): node is ts.ArrayDestructuringAssignment => + ts.isArrayLiteralExpression(node.left) && + node.left.elements.every(element => { + if (isArrayLength(context, element)) { + return false; + } - if (ts.isPropertyAccessExpression(element) || ts.isElementAccessExpression(element)) { - return true; - } + if (ts.isPropertyAccessExpression(element) || ts.isElementAccessExpression(element)) { + return true; + } - if (ts.isIdentifier(element)) { - const symbol = context.checker.getSymbolAtLocation(element); - if (symbol) { - const aliases = getDependenciesOfSymbol(context, symbol); - return aliases.length === 0; - } + if (ts.isIdentifier(element)) { + const symbol = context.checker.getSymbolAtLocation(element); + if (symbol) { + const aliases = getDependenciesOfSymbol(context, symbol); + return aliases.length === 0; } - }) - ); -}; + } + }); export function transformAssignmentStatement( context: TransformationContext, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index afc439700..356b2bcff 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -151,7 +151,7 @@ export function transformBinaryExpressionStatement( context: TransformationContext, node: ts.ExpressionStatement ): lua.Statement[] | lua.Statement | undefined { - const { expression } = node; + const expression = node.expression; if (!ts.isBinaryExpression(expression)) return; const operator = expression.operatorToken.kind; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 24c4864d1..366ff8041 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -127,7 +127,7 @@ export function transformContextualCallExpression( transformedArguments.unshift(lua.createIdentifier("____self")); // Cache left-side if it has effects - //(function() local ____self = context; return ____self[argument](parameters); end)() + // (function() local ____self = context; return ____self[argument](parameters); end)() const argument = ts.isElementAccessExpression(left) ? transformElementAccessArgument(context, left) : lua.createStringLiteral(left.name.text); @@ -160,7 +160,7 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal } const parameters = transformArguments(context, node.arguments, signature); - const signatureDeclaration = signature && signature.getDeclaration(); + const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // table:name() return transformContextualCallExpression(context, node, parameters); @@ -176,7 +176,7 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { const signature = context.checker.getResolvedSignature(node); - const signatureDeclaration = signature && signature.getDeclaration(); + const signatureDeclaration = signature?.getDeclaration(); const parameters = transformArguments(context, node.arguments, signature); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // A contextual parameter must be given to this call expression @@ -233,7 +233,7 @@ export const transformCallExpression: FunctionVisitor = (node } const callPath = context.transformExpression(node.expression); - const signatureDeclaration = signature && signature.getDeclaration(); + const signatureDeclaration = signature?.getDeclaration(); let parameters: lua.Expression[] = []; if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 9d13deafa..88a7f1545 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -33,12 +33,12 @@ export function transformAccessorDeclarations( importLuaLibFeature(context, LuaLibFeature.Descriptors); const call = isStaticNode(firstAccessor) - ? lua.createCallExpression(lua.createIdentifier(`__TS__ObjectDefineProperty`), [ + ? lua.createCallExpression(lua.createIdentifier("__TS__ObjectDefineProperty"), [ lua.cloneIdentifier(className), propertyName, descriptor, ]) - : lua.createCallExpression(lua.createIdentifier(`__TS__SetDescriptor`), [ + : lua.createCallExpression(lua.createIdentifier("__TS__SetDescriptor"), [ lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), propertyName, descriptor, diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index 89c68e9d6..e915440c7 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -46,8 +46,7 @@ export const transformEnumDeclaration: FunctionVisitor = (no if (ts.isIdentifier(member.initializer)) { const symbol = context.checker.getSymbolAtLocation(member.initializer); if ( - symbol && - symbol.valueDeclaration && + symbol?.valueDeclaration && ts.isEnumMember(symbol.valueDeclaration) && symbol.valueDeclaration.parent === node ) { diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 9cee9cc9e..7c82a89be 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -142,7 +142,7 @@ export function transformParameters( const paramName = ts.isObjectBindingPattern(param.name) || ts.isArrayBindingPattern(param.name) ? lua.createIdentifier(`____bindingPattern${identifierIndex++}`) - : transformIdentifier(context, param.name as ts.Identifier); + : transformIdentifier(context, param.name); // This parameter is a spread parameter (...param) if (!param.dotDotDotToken) { diff --git a/src/transformation/visitors/generator.ts b/src/transformation/visitors/generator.ts index 835cc30fd..60e48e0d9 100644 --- a/src/transformation/visitors/generator.ts +++ b/src/transformation/visitors/generator.ts @@ -89,12 +89,12 @@ export function transformGeneratorFunctionBody( const block = [ coroutine, iterator, - //____it[Symbol.iterator] = {return ____it} + // ____it[Symbol.iterator] = {return ____it} lua.createAssignmentStatement( lua.createTableIndexExpression(itIdentifier, symbolIterator), lua.createFunctionExpression(lua.createBlock([lua.createReturnStatement([itIdentifier])])) ), - //return ____it + // return ____it lua.createReturnStatement([itIdentifier]), ]; @@ -106,10 +106,9 @@ export function transformGeneratorFunctionBody( return [block, functionScope]; } -export const transformYieldExpression: FunctionVisitor = (expression, context) => { - return lua.createCallExpression( +export const transformYieldExpression: FunctionVisitor = (expression, context) => + lua.createCallExpression( lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), expression.expression ? [context.transformExpression(expression.expression)] : [], expression ); -}; diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index 58c37b421..0fafc710a 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -3,13 +3,12 @@ import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; import { transformLoopBody } from "./utils"; -export const transformWhileStatement: FunctionVisitor = (statement, context) => { - return lua.createWhileStatement( +export const transformWhileStatement: FunctionVisitor = (statement, context) => + lua.createWhileStatement( lua.createBlock(transformLoopBody(context, statement)), context.transformExpression(statement.expression), statement ); -}; export const transformDoStatement: FunctionVisitor = (statement, context) => { const body = lua.createDoStatement(transformLoopBody(context, statement)); diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index ccd417de0..44656088a 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -74,38 +74,39 @@ function transformForOfLuaIteratorStatement( if (tupleReturn) { // LuaIterator + TupleReturn + if (ts.isVariableDeclarationList(statement.initializer)) { // Variables declared in for loop // for ${initializer} in ${iterable} do - const binding = getVariableDeclarationBinding(context, statement.initializer); + const binding = getVariableDeclarationBinding(context, statement.initializer); if (ts.isArrayBindingPattern(binding)) { identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); } else { context.diagnostics.push(luaIteratorForbiddenUsage(binding)); } - } else { + } else if (ts.isArrayLiteralExpression(statement.initializer)) { // Variables NOT declared in for loop - catch iterator values in temps and assign // for ____value0 in ${iterable} do // ${initializer} = ____value0 - if (ts.isArrayLiteralExpression(statement.initializer)) { - identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); - if (identifiers.length > 0) { - block.statements.unshift( - lua.createAssignmentStatement( - statement.initializer.elements.map(e => - cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) - ), - identifiers - ) - ); - } - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); + + identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) + ), + identifiers + ) + ); } + } else { + context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); } } else { // LuaIterator (no TupleReturn) + identifiers.push(transformForInitializer(context, statement.initializer, block)); } diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts index 7647921c3..300837c1e 100644 --- a/src/transformation/visitors/lua-table.ts +++ b/src/transformation/visitors/lua-table.ts @@ -124,7 +124,7 @@ export function transformLuaTablePropertyAccessInAssignment( const [luaTable, propertyName] = parseLuaTableExpression(context, node); if (propertyName === "length") { - context.diagnostics.push(luaTableForbiddenUsage(node, `A LuaTable object's length cannot be re-assigned`)); + context.diagnostics.push(luaTableForbiddenUsage(node, "A LuaTable object's length cannot be re-assigned")); return lua.createTableIndexExpression(luaTable, lua.createStringLiteral(propertyName), node); } diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 089f0949f..34fa216d6 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -13,13 +13,13 @@ import { transformPropertyName } from "../literal"; import { unresolvableRequirePath } from "../../utils/diagnostics"; const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => - relativePath[0] !== "." && options.baseUrl + !relativePath.startsWith(".") && options.baseUrl ? path.resolve(options.baseUrl, relativePath) : path.resolve(directoryPath, relativePath); function getImportPath(context: TransformationContext, relativePath: string, node: ts.Node): string { - const fileName = context.sourceFile.fileName; - const options = context.options; + const { options, sourceFile } = context; + const { fileName } = sourceFile; const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); const absoluteImportPath = path.format( diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index e47c3906b..784cf7e4e 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -70,7 +70,7 @@ export const transformTaggedTemplateExpression: FunctionVisitor f.lua?.includes(`require("lualib_bundle")`)); + const lualibRequired = transpiledFiles.some(f => f.lua?.includes('require("lualib_bundle")')); if (lualibRequired) { moduleTableEntries.push(`["lualib_bundle"] = function() ${getLuaLibBundle(emitHost)} end,\n`); } @@ -90,7 +90,7 @@ end\n`; function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): SourceNode { const tableEntryHead = `[${modulePath}] = function() `; - const tableEntryTail = `end,\n`; + const tableEntryTail = "end,\n"; if (transpiledFile.lua && transpiledFile.sourceMapNode) { return joinSourceChunks([tableEntryHead, transpiledFile.sourceMapNode, tableEntryTail]); @@ -100,14 +100,13 @@ function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): S } function createModuleTableNode(fileChunks: SourceChunk[]): SourceNode { - const tableHead = `____modules = {\n`; - const tableEnd = `}\n`; + const tableHead = "____modules = {\n"; + const tableEnd = "}\n"; return joinSourceChunks([tableHead, ...fileChunks, tableEnd]); } type SourceChunk = string | SourceNode; function joinSourceChunks(chunks: SourceChunk[]): SourceNode { - // tslint:disable-next-line:no-null-keyword return new SourceNode(null, null, null, chunks); } diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 80b68088e..d0e609677 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -34,6 +34,6 @@ export const luaBundleEntryIsRequired = createDiagnosticFactory( export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDiagnosticFactory(() => ({ category: ts.DiagnosticCategory.Warning, messageText: - `Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` + - `It is recommended to use 'luaLibImport: "require"'.`, + "Using 'luaBundle' with 'luaLibImport: \"inline\"' might generate duplicate code. " + + "It is recommended to use 'luaLibImport: \"require\"'.", })); diff --git a/src/transpilation/emit.ts b/src/transpilation/emit.ts index 0b6cef269..854f0cc7e 100644 --- a/src/transpilation/emit.ts +++ b/src/transpilation/emit.ts @@ -54,7 +54,7 @@ export function emitTranspiledFiles( luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) ) { - const lualibRequired = files.some(f => f.text?.includes(`require("lualib_bundle")`)); + const lualibRequired = files.some(f => f.text?.includes('require("lualib_bundle")')); if (lualibRequired) { let outPath = path.resolve(rootDir, "lualib_bundle.lua"); if (outDir !== rootDir) { diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 1d15e59c4..76c0e9634 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -49,9 +49,9 @@ export function createVirtualProgram(input: Record, options: Com readFile: () => "", getNewLine: () => "\n", useCaseSensitiveFileNames: () => false, - writeFile: () => {}, + writeFile() {}, - getSourceFile: filename => { + getSourceFile(filename) { if (filename in input) { return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); } diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index e6f975be4..a2270c401 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -27,7 +27,6 @@ export function resolvePlugin( return { error: diagnosticFactories.couldNotResolveFrom(kind, query, basedir) }; } - // tslint:disable-next-line: deprecation const hasNoRequireHook = require.extensions[".ts"] === undefined; if (hasNoRequireHook && (resolved.endsWith(".ts") || resolved.endsWith(".tsx"))) { try { diff --git a/src/tstl.ts b/src/tstl.ts index d19f792db..00b6d7606 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -7,11 +7,8 @@ import { parseCommandLine } from "./cli/parse"; import { createDiagnosticReporter } from "./cli/report"; import { createConfigFileUpdater, locateConfigFile, parseConfigFileWithSystem } from "./cli/tsconfig"; -function shouldBePretty(options?: ts.CompilerOptions): boolean { - return options?.pretty === undefined - ? ts.sys.writeOutputIsTTY !== undefined && ts.sys.writeOutputIsTTY() - : Boolean(options.pretty); -} +const shouldBePretty = ({ pretty }: ts.CompilerOptions = {}) => + pretty !== undefined ? (pretty as boolean) : ts.sys.writeOutputIsTTY?.() ?? false; let reportDiagnostic = createDiagnosticReporter(false); function updateReportDiagnostic(options?: ts.CompilerOptions): void { diff --git a/src/typescript-internal.ts b/src/typescript-internal.d.ts similarity index 50% rename from src/typescript-internal.ts rename to src/typescript-internal.d.ts index 3a8013d61..d3974a168 100644 --- a/src/typescript-internal.ts +++ b/src/typescript-internal.d.ts @@ -1,15 +1,15 @@ -import * as ts from "typescript"; +export {}; declare module "typescript" { - function createDiagnosticReporter(system: ts.System, pretty?: boolean): ts.DiagnosticReporter; - function createWatchStatusReporter(system: ts.System, pretty?: boolean): ts.WatchStatusReporter; + function createDiagnosticReporter(system: System, pretty?: boolean): DiagnosticReporter; + function createWatchStatusReporter(system: System, pretty?: boolean): WatchStatusReporter; interface System { setBlocking?(): void; } interface Statement { - jsDoc?: ts.JSDoc[]; + jsDoc?: JSDoc[]; } interface Program { @@ -17,6 +17,7 @@ declare module "typescript" { } interface CompilerOptions { + configFile?: TsConfigSourceFile; configFilePath?: string; } } diff --git a/src/utils.ts b/src/utils.ts index cb0651007..aad8ce621 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -12,8 +12,8 @@ export const intersperse = (values: T[], separator: T): T[] => values.flatMap((value, index) => (index === 0 ? [value] : [separator, value])); type DiagnosticFactory = (...args: any) => Partial & Pick; -export const createDiagnosticFactoryWithCode = (code: number, create: T) => { - return Object.assign( +export const createDiagnosticFactoryWithCode = (code: number, create: T) => + Object.assign( (...args: Parameters): ts.Diagnostic => ({ file: undefined, start: undefined, @@ -25,7 +25,6 @@ export const createDiagnosticFactoryWithCode = (cod }), { code } ); -}; let serialDiagnosticCodeCounter = 100000; export const createSerialDiagnosticFactory = (create: T) => @@ -57,8 +56,9 @@ export function getOrUpdate( return map.get(key)!; } -export function isNonNull(value: T | undefined | null): value is T { - return value !== undefined && value !== null; +// eslint-disable-next-line @typescript-eslint/ban-types +export function isNonNull(value: T | null | undefined): value is T { + return value != null; } export function cast( diff --git a/test/cli/run.ts b/test/cli/run.ts index 59d2e9263..cee7e19b2 100644 --- a/test/cli/run.ts +++ b/test/cli/run.ts @@ -22,8 +22,8 @@ export async function runCli(args: string[]): Promise { const child = forkCli(args); let output = ""; - child.stdout!.on("data", data => (output += data)); - child.stderr!.on("data", data => (output += data)); + child.stdout!.on("data", (data: Buffer) => (output += data.toString())); + child.stderr!.on("data", (data: Buffer) => (output += data.toString())); return new Promise(resolve => { child.on("close", exitCode => resolve({ exitCode, output })); diff --git a/test/cli/tsconfig.spec.ts b/test/cli/tsconfig.spec.ts index b4fac5cbf..1608ac973 100644 --- a/test/cli/tsconfig.spec.ts +++ b/test/cli/tsconfig.spec.ts @@ -68,12 +68,12 @@ describe("inferred", () => { }); test("not found", () => { - expect(locate(undefined)).toBe(undefined); + expect(locate(undefined)).toBeUndefined(); }); test("does not attempt when has files", async () => { await fs.outputFile("tsconfig.json", ""); - expect(locate(undefined, [""])).toBe(undefined); + expect(locate(undefined, [""])).toBeUndefined(); }); }); diff --git a/test/cli/watch.spec.ts b/test/cli/watch.spec.ts index d1274f865..35d2f2f59 100644 --- a/test/cli/watch.spec.ts +++ b/test/cli/watch.spec.ts @@ -1,4 +1,4 @@ -import * as fs from "fs"; +import * as fs from "fs-extra"; import * as path from "path"; import { forkCli } from "./run"; @@ -8,7 +8,7 @@ afterEach(() => { testsCleanup = []; }); -function waitForFileExists(filePath: string): Promise { +async function waitForFileExists(filePath: string): Promise { return new Promise(resolve => { const intervalTimerId = setInterval(() => { if (fs.existsSync(filePath)) { @@ -29,9 +29,7 @@ function forkWatchProcess(args: string[]): void { const watchedFile = path.join(__dirname, "./watch/watch.ts"); const watchedFileOut = watchedFile.replace(".ts", ".lua"); -afterEach(() => { - if (fs.existsSync(watchedFileOut)) fs.unlinkSync(watchedFileOut); -}); +afterEach(() => fs.removeSync(watchedFileOut)); async function compileChangeAndCompare(filePath: string, content: string): Promise { await waitForFileExists(watchedFileOut); diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index d35a2288a..685b90544 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -93,11 +93,11 @@ export function transpileAndExecute( luaHeader?: string, tsHeader?: string ): any { - const wrappedTsString = `${tsHeader ? tsHeader : ""} + const wrappedTsString = `${tsHeader ?? ""} declare function JSONStringify(this: void, p: any): string; function __runTest(this: void): any {${tsStr}}`; - const lua = `${luaHeader ? luaHeader : ""} + const lua = `${luaHeader ?? ""} ${transpileString(wrappedTsString, compilerOptions, false)} return __runTest();`; @@ -162,7 +162,7 @@ export function transpileExecuteAndReturnExport( ${tsStr}`; const lua = `return (function() - ${luaHeader ? luaHeader : ""} + ${luaHeader ?? ""} ${transpileString(wrappedTsString, compilerOptions, false)} end)().${returnExport}`; diff --git a/test/setup.ts b/test/setup.ts index ebaa4e2fd..6d92e3332 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -1,8 +1,11 @@ +import * as assert from "assert"; import * as ts from "typescript"; import * as tstl from "../src"; declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { + // eslint-disable-next-line @typescript-eslint/generic-type-naming interface Matchers { toHaveDiagnostics(expected?: number[]): R; } @@ -11,7 +14,7 @@ declare global { expect.extend({ toHaveDiagnostics(diagnostics: ts.Diagnostic[], expected?: number[]): jest.CustomMatcherResult { - expect(diagnostics).toBeInstanceOf(Array); + assert(Array.isArray(diagnostics)); // @ts-ignore const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", this); @@ -21,7 +24,7 @@ expect.extend({ ); if (this.isNot && expected !== undefined) { - throw new Error(`expect(actual).not.toHaveDiagnostics(expected) is not supported`); + throw new Error("expect(actual).not.toHaveDiagnostics(expected) is not supported"); } return { diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 387a60fc6..ac0baeb17 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -7,7 +7,7 @@ Array [ "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] local ____exports = {} function ____exports.getNumber(self) - return GetAPIValue() + return getAPIValue() end return ____exports ", @@ -19,7 +19,7 @@ local ____exports = {} local ____otherFile = require(\\"otherFile\\") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) -SetAPIValue(myNumber * 5) +setAPIValue(myNumber * 5) return ____exports ", }, diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index a5afd90b0..166f4e044 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -9,7 +9,7 @@ test("should transpile into one file", () => { const transpileResult = transpileProject(inputProject); expect(transpileResult.diagnostics).not.toHaveDiagnostics(); - expect(transpileResult.emitResult.length).toBe(1); + expect(transpileResult.emitResult).toHaveLength(1); const { name, text } = transpileResult.emitResult[0]; // Verify the name is as specified in tsconfig diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 458c14fec..a2afd5090 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -14,7 +14,7 @@ test.each([ { name: "basic", options: { rootDir: "src" } }, { name: "basic", options: { rootDir: "src", outDir: "out" } }, { name: "baseurl", options: { baseUrl: "./src/lib", rootDir: ".", outDir: "./out" } }, -])("should be able to resolve (%p)", async ({ name, options: compilerOptions }) => { +])("should be able to resolve (%p)", ({ name, options: compilerOptions }) => { const projectPath = path.join(__dirname, "directories", name); jest.spyOn(process, "cwd").mockReturnValue(projectPath); diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts index 6b3999d07..7ae55ca01 100644 --- a/test/transpile/plugins/printer.ts +++ b/test/transpile/plugins/printer.ts @@ -1,12 +1,12 @@ import * as tstl from "../../../src"; const plugin: tstl.Plugin = { - printer: (program, emitHost, fileName, ...args) => { + printer(program, emitHost, fileName, ...args) { const result = new tstl.LuaPrinter(emitHost, program, fileName).print(...args); result.code = `-- Plugin\n${result.code}`; return result; }, }; -// tslint:disable-next-line: no-default-export +// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor-super.ts b/test/transpile/plugins/visitor-super.ts index 87f665749..9a8bee5f1 100644 --- a/test/transpile/plugins/visitor-super.ts +++ b/test/transpile/plugins/visitor-super.ts @@ -3,7 +3,7 @@ import * as tstl from "../../../src"; const plugin: tstl.Plugin = { visitors: { - [ts.SyntaxKind.StringLiteral]: (node, context) => { + [ts.SyntaxKind.StringLiteral](node, context) { const result = context.superTransformExpression(node); if (tstl.isStringLiteral(result)) { @@ -15,5 +15,5 @@ const plugin: tstl.Plugin = { }, }; -// tslint:disable-next-line: no-default-export +// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor.ts b/test/transpile/plugins/visitor.ts index fdbf50782..507b9fa3d 100644 --- a/test/transpile/plugins/visitor.ts +++ b/test/transpile/plugins/visitor.ts @@ -7,5 +7,5 @@ const plugin: tstl.Plugin = { }, }; -// tslint:disable-next-line: no-default-export +// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/project/api.d.ts b/test/transpile/project/api.d.ts index dcac56a84..3375e6830 100644 --- a/test/transpile/project/api.d.ts +++ b/test/transpile/project/api.d.ts @@ -1,3 +1,3 @@ /** @noSelfInFile */ -declare function GetAPIValue(): number; -declare function SetAPIValue(n: number): void; +declare function getAPIValue(): number; +declare function setAPIValue(n: number): void; diff --git a/test/transpile/project/index.ts b/test/transpile/project/index.ts index bd11cd347..a244bdbfb 100644 --- a/test/transpile/project/index.ts +++ b/test/transpile/project/index.ts @@ -1,4 +1,4 @@ import { getNumber } from "./otherFile"; const myNumber = getNumber(); -SetAPIValue(myNumber * 5); +setAPIValue(myNumber * 5); diff --git a/test/transpile/project/otherFile.ts b/test/transpile/project/otherFile.ts index ca4d2aa23..0ee7f628f 100644 --- a/test/transpile/project/otherFile.ts +++ b/test/transpile/project/otherFile.ts @@ -1,3 +1,3 @@ export function getNumber(): number { - return GetAPIValue(); + return getAPIValue(); } diff --git a/test/transpile/resolve-plugin/ts.ts b/test/transpile/resolve-plugin/ts.ts index 0622167b7..60757f0a4 100644 --- a/test/transpile/resolve-plugin/ts.ts +++ b/test/transpile/resolve-plugin/ts.ts @@ -1,2 +1,2 @@ -// tslint:disable-next-line: no-default-export +// eslint-disable-next-line import/no-default-export export default true; diff --git a/test/types/fengari.d.ts b/test/types/fengari.d.ts index 5e76ec549..8b13b169d 100644 --- a/test/types/fengari.d.ts +++ b/test/types/fengari.d.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/class-name-casing */ + export const FENGARI_AUTHORS: string; export const FENGARI_COPYRIGHT: string; export const FENGARI_RELEASE: string; diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index cd77bcca6..007c64c3f 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -19,7 +19,7 @@ test("CustomCreate", () => { } `; - const result = util.transpileAndExecute(`return new Point2D(1, 2).x;`, undefined, luaHeader, tsHeader); + const result = util.transpileAndExecute("return new Point2D(1, 2).x;", undefined, luaHeader, tsHeader); expect(result).toBe(1); }); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts index ec7d1af35..8829938bb 100644 --- a/test/unit/annotations/luaTable.spec.ts +++ b/test/unit/annotations/luaTable.spec.ts @@ -35,7 +35,7 @@ declare let tbl: Table; `; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule(tableLib + `const table = new Table(true);`).expectDiagnosticsToMatchSnapshot([ + util.testModule(tableLib + "const table = new Table(true);").expectDiagnosticsToMatchSnapshot([ luaTableForbiddenUsage.code, ]); }); @@ -43,33 +43,33 @@ test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tab test.each([tableLibClass, tableLibInterface])( "LuaTable set() cannot be used in a LuaTable call expression", tableLib => { - util.testModule(tableLib + `const exp = tbl.set("value", 5)`).expectDiagnosticsToMatchSnapshot([ + util.testModule(tableLib + 'const exp = tbl.set("value", 5)').expectDiagnosticsToMatchSnapshot([ unsupportedProperty.code, ]); } ); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + `tbl.other()`).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule(tableLib + "tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + `let x = tbl.other()`).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule(tableLib + "let x = tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass])("LuaTable new", tableLib => { - const content = tableLib + `tbl = new Table();`; + const content = tableLib + "tbl = new Table();"; expect(util.transpileString(content)).toEqual("tbl = {}"); }); test.each([tableLibClass])("LuaTable length", tableLib => { - const content = tableLib + `tbl = new Table();\nreturn tbl.length;`; + const content = tableLib + "tbl = new Table();\nreturn tbl.length;"; const lua = util.transpileString(content); expect(util.executeLua(lua)).toEqual(0); }); test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule(tableLib + `tbl.length = 2;`).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); + util.testModule(tableLib + "tbl.length = 2;").expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { @@ -87,7 +87,7 @@ test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib }); test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each([`class Ext extends Table {}`, `const c = class Ext extends Table {}`])( + test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( "Cannot extend LuaTable class (%p)", code => { util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); @@ -96,21 +96,21 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { }); test.each([ - `/** @luaTable */ class Table {}`, - `/** @luaTable */ export class Table {}`, - `/** @luaTable */ const c = class Table {}`, + "/** @luaTable */ class Table {}", + "/** @luaTable */ export class Table {}", + "/** @luaTable */ const c = class Table {}", ])("LuaTable classes must be ambient (%p)", code => { util.testModule(code).expectDiagnosticsToMatchSnapshot([luaTableMustBeAmbient.code]); }); test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each([`tbl instanceof Table`])("Cannot use instanceof on a LuaTable class (%p)", code => { + test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); }); }); test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpression on a LuaTable", tableLib => { - test.each([`tbl["get"]("field")`, `tbl["set"]("field")`, `tbl["length"]`])( + test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( "Cannot use ElementAccessExpression on a LuaTable (%p)", code => { util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([ @@ -121,7 +121,7 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio }); test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { - test.each([`set`, `get`])("Cannot isolate LuaTable method (%p)", propertyName => { + test.each(["set", "get"])("Cannot isolate LuaTable method (%p)", propertyName => { util.testModule(`${tableLib} let property = tbl.${propertyName}`).expectDiagnosticsToMatchSnapshot([ unsupportedProperty.code, ]); @@ -130,11 +130,11 @@ test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", test.each([tableLibClass])("LuaTable functional tests", tableLib => { test.each<[string, any]>([ - [`const t = new Table(); t.set("field", "value"); return t.get("field");`, "value"], - [`const t = new Table(); t.set("field", 0); return t.get("field");`, 0], - [`const t = new Table(); t.set(1, true); return t.length`, 1], - [`const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length`, 2], - [`const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);`, 3], + ['const t = new Table(); t.set("field", "value"); return t.get("field");', "value"], + ['const t = new Table(); t.set("field", 0); return t.get("field");', 0], + ["const t = new Table(); t.set(1, true); return t.length", 1], + ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], + ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], ])("LuaTable test (%p)", (code, expectedReturnValue) => { expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index da0f1992a..405eeee5a 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -16,7 +16,7 @@ test("MetaExtension", () => { `; const result = util.transpileAndExecute( - `return debug.getregistry()["_LOADED"].test();`, + 'return debug.getregistry()["_LOADED"].test();', undefined, undefined, tsHeader diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index be3774d54..35294be6d 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -342,7 +342,6 @@ test.each([ { array: [0, 1, 2, 3, 4, 5], start: 3, deleteCount: 2, newElements: [3, 4, 5] }, { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: 9, newElements: [10, 11] }, { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: undefined, newElements: [10, 11] }, - // tslint:disable-next-line:no-null-keyword { array: [0, 1, 2, 3, 4, 5, 6, 7, 8], start: 5, deleteCount: null, newElements: [10, 11] }, // Remove @@ -352,7 +351,6 @@ test.each([ { array: [0, 1, 2, 3, 4, 5], start: 2, deleteCount: 2 }, { array: [0, 1, 2, 3, 4, 5], start: -3, deleteCount: 2 }, { array: [0, 1, 2, 3], start: 1, deleteCount: undefined }, - // tslint:disable-next-line:no-null-keyword { array: [0, 1, 2, 3], start: 1, deleteCount: null }, ])("array.splice (%p)", ({ array, start, deleteCount, newElements = [] }) => { util.testFunction` @@ -456,7 +454,6 @@ test.each([{ args: [1] }, { args: [1, 2, 3] }])("array.push (%p)", ({ args }) => test.each([ { array: [1, 2, 3], expected: [3, 2] }, - // tslint:disable-next-line: no-null-keyword { array: [1, 2, 3, null], expected: [3, 2] }, ])("array.pop (%p)", ({ array, expected }) => { util.testFunction` diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index 9284363be..fa213d03f 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -6,21 +6,21 @@ describe("luaLibImport", () => { test("inline", () => { util.testExpression`[0].push(1)` .setOptions({ luaLibImport: tstl.LuaLibImportKind.Inline }) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain(`require("lualib_bundle")`)) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); test("require", () => { util.testExpression`[0].push(1)` .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) - .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain(`require("lualib_bundle")`)) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); test("always", () => { util.testModule`` .setOptions({ luaLibImport: tstl.LuaLibImportKind.Always }) - .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain(`require("lualib_bundle")`)) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToEqual(undefined); }); }); diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index f12810b3e..e9edd2508 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -1,7 +1,7 @@ import * as util from "../../util"; test("map constructor", () => { - const result = util.transpileAndExecute(`let mymap = new Map(); return mymap.size;`); + const result = util.transpileAndExecute("let mymap = new Map(); return mymap.size;"); expect(result).toBe(0); }); @@ -25,17 +25,17 @@ test("map iterable constructor map", () => { }); test("map clear", () => { - const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();`; - const size = util.transpileAndExecute(mapTS + `return mymap.size;`); + const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();'; + const size = util.transpileAndExecute(mapTS + "return mymap.size;"); expect(size).toBe(0); - const contains = util.transpileAndExecute(mapTS + `return !mymap.has("a") && !mymap.has("b");`); + const contains = util.transpileAndExecute(mapTS + 'return !mymap.has("a") && !mymap.has("b");'); expect(contains).toBe(true); }); test("map delete", () => { - const mapTS = `let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");`; - const contains = util.transpileAndExecute(mapTS + `return mymap.has("b") && !mymap.has("a");`); + const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");'; + const contains = util.transpileAndExecute(mapTS + 'return mymap.has("b") && !mymap.has("a");'); expect(contains).toBe(true); }); @@ -72,31 +72,31 @@ test("map foreach keys", () => { }); test("map get", () => { - const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");`); + const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");'); expect(result).toBe("c"); }); test("map get missing", () => { - const result = util.transpileAndExecute(`let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");`); - expect(result).toBe(undefined); + const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");'); + expect(result).toBeUndefined(); }); test("map has", () => { - const contains = util.transpileAndExecute(`let mymap = new Map([["a", "c"]]); return mymap.has("a");`); + const contains = util.transpileAndExecute('let mymap = new Map([["a", "c"]]); return mymap.has("a");'); expect(contains).toBe(true); }); test("map has false", () => { - const contains = util.transpileAndExecute(`let mymap = new Map(); return mymap.has("a");`); + const contains = util.transpileAndExecute('let mymap = new Map(); return mymap.has("a");'); expect(contains).toBe(false); }); test.each([ - `[["a", null]]`, - `[["b", "c"], ["a", null]]`, - `[["a", null], ["b", "c"]]`, - `[["b", "c"], ["a", null], ["x", "y"]]`, + '[["a", null]]', + '[["b", "c"], ["a", null]]', + '[["a", null], ["b", "c"]]', + '[["b", "c"], ["a", null], ["x", "y"]]', ])("map (%p) has null", entries => { util.testFunction` let mymap = new Map(${entries}); @@ -105,10 +105,10 @@ test.each([ }); test.each([ - `[["a", undefined]]`, - `[["b", "c"], ["a", undefined]]`, - `[["a", undefined], ["b", "c"]]`, - `[["b", "c"], ["a", undefined], ["x", "y"]]`, + '[["a", undefined]]', + '[["b", "c"], ["a", undefined]]', + '[["a", undefined], ["b", "c"]]', + '[["b", "c"], ["a", undefined], ["x", "y"]]', ])("map (%p) has undefined", entries => { util.testFunction` let mymap = new Map(${entries}); @@ -128,11 +128,11 @@ test("map keys", () => { }); test("map set", () => { - const mapTS = `let mymap = new Map(); mymap.set("a", 5);`; - const has = util.transpileAndExecute(mapTS + `return mymap.has("a");`); + const mapTS = 'let mymap = new Map(); mymap.set("a", 5);'; + const has = util.transpileAndExecute(mapTS + 'return mymap.has("a");'); expect(has).toBe(true); - const value = util.transpileAndExecute(mapTS + `return mymap.get("a")`); + const value = util.transpileAndExecute(mapTS + 'return mymap.get("a")'); expect(value).toBe(5); }); @@ -148,11 +148,11 @@ test("map values", () => { }); test("map size", () => { - expect(util.transpileAndExecute(`let m = new Map(); return m.size;`)).toBe(0); - expect(util.transpileAndExecute(`let m = new Map(); m.set(1,3); return m.size;`)).toBe(1); - expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); return m.size;`)).toBe(2); - expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;`)).toBe(0); - expect(util.transpileAndExecute(`let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;`)).toBe(1); + expect(util.transpileAndExecute("let m = new Map(); return m.size;")).toBe(0); + expect(util.transpileAndExecute("let m = new Map(); m.set(1,3); return m.size;")).toBe(1); + expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); return m.size;")).toBe(2); + expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;")).toBe(0); + expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;")).toBe(1); }); const iterationMethods = ["entries", "keys", "values"]; diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index 2c58e5df8..8f81edfe8 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -124,11 +124,11 @@ test("set values", () => { }); test.each([ - `let m = new Set()`, - `let m = new Set(); m.add(1)`, - `let m = new Set([1, 2])`, - `let m = new Set([1, 2]); m.clear()`, - `let m = new Set([1, 2]); m.delete(2)`, + "let m = new Set()", + "let m = new Set(); m.add(1)", + "let m = new Set([1, 2])", + "let m = new Set([1, 2]); m.clear()", + "let m = new Set([1, 2]); m.delete(2)", ])("set size (%p)", code => { util.testFunction`${code}; return m.size`.expectToMatchJsResult(); }); diff --git a/test/unit/builtins/symbol.spec.ts b/test/unit/builtins/symbol.spec.ts index 7faabef84..3d6b35d8a 100644 --- a/test/unit/builtins/symbol.spec.ts +++ b/test/unit/builtins/symbol.spec.ts @@ -15,7 +15,7 @@ test("symbol uniqueness", () => { test("Symbol.for", () => { // TODO: Supported since node 11 - util.testExpression(`Symbol.for("name").description`).expectToEqual("name"); + util.testExpression('Symbol.for("name").description').expectToEqual("name"); }); test("Symbol.for non-uniqueness", () => { diff --git a/test/unit/builtins/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts index 71cabdbe1..ab3ba12fb 100644 --- a/test/unit/builtins/weakMap.spec.ts +++ b/test/unit/builtins/weakMap.spec.ts @@ -63,7 +63,7 @@ test("weakMap get missing", () => { return mymap.get({}); `); - expect(result).toBe(undefined); + expect(result).toBeUndefined(); }); test("weakMap has", () => { @@ -103,15 +103,15 @@ test("weakMap set", () => { mymap.set(ref, 5); `; - const has = util.transpileAndExecute(init + `return mymap.has(ref);`); + const has = util.transpileAndExecute(init + "return mymap.has(ref);"); expect(has).toBe(true); - const value = util.transpileAndExecute(init + `return mymap.get(ref)`); + const value = util.transpileAndExecute(init + "return mymap.get(ref)"); expect(value).toBe(5); }); test("weakMap has no map features (size)", () => { - expect(util.transpileAndExecute(`return (new WeakMap() as any).size`)).toBe(undefined); + expect(util.transpileAndExecute("return (new WeakMap() as any).size")).toBeUndefined(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( diff --git a/test/unit/builtins/weakSet.spec.ts b/test/unit/builtins/weakSet.spec.ts index 1b86e960c..fe6accf45 100644 --- a/test/unit/builtins/weakSet.spec.ts +++ b/test/unit/builtins/weakSet.spec.ts @@ -68,7 +68,7 @@ test("weakSet delete", () => { }); test("weakSet has no set features (size)", () => { - expect(util.transpileAndExecute(`return (new WeakSet() as any).size`)).toBe(undefined); + expect(util.transpileAndExecute("return (new WeakSet() as any).size")).toBeUndefined(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index 3d9520da4..c9956571e 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -21,7 +21,7 @@ test("bundle file name", () => { .expectToHaveNoDiagnostics() .getLuaResult(); - expect(transpiledFiles.length).toBe(1); + expect(transpiledFiles).toHaveLength(1); expect(transpiledFiles[0].fileName).toBe( path.join(ts.sys.getCurrentDirectory(), "mybundle.lua").replace(/\\/g, "/") ); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index b58d488ad..27e0ce839 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -287,14 +287,14 @@ test("return from nested finally", () => { }); test.each([ - `"error string"`, - `42`, - `3.141`, - `true`, - `false`, - `undefined`, - `{ x: "error object" }`, - `() => "error function"`, + '"error string"', + "42", + "3.141", + "true", + "false", + "undefined", + '{ x: "error object" }', + '() => "error function"', ])("throw and catch %s", error => { util.testFunction` try { diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index f1235326e..2f2f3b212 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -510,6 +510,6 @@ test("top-level function declaration is global", () => { import './a'; export const result = foo(); ` - .addExtraFile("a.ts", `function foo() { return "foo" }`) + .addExtraFile("a.ts", 'function foo() { return "foo" }') .expectToEqual({ result: "foo" }); }); diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index f6b2672f4..ebf00dfae 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -6,19 +6,19 @@ export interface TestFunction { export const selfTestFunctions: TestFunction[] = [ { value: "selfFunc", - definition: `let selfFunc: {(this: any, s: string): string} = function(s) { return s; };`, + definition: "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", }, { value: "selfLambda", - definition: `let selfLambda: (this: any, s: string) => string = s => s;`, + definition: "let selfLambda: (this: any, s: string) => string = s => s;", }, { value: "anonFunc", - definition: `let anonFunc: {(s: string): string} = function(s) { return s; };`, + definition: "let anonFunc: {(s: string): string} = function(s) { return s; };", }, { value: "anonLambda", - definition: `let anonLambda: (s: string) => string = s => s;`, + definition: "let anonLambda: (s: string) => string = s => s;", }, { value: "methodClass.method", @@ -48,7 +48,7 @@ export const selfTestFunctions: TestFunction[] = [ }, { value: "AnonStaticMethodClass.anonStaticMethod", - definition: `class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }`, + definition: "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", }, { value: "StaticFuncPropClass.staticFuncProp", @@ -64,7 +64,7 @@ export const selfTestFunctions: TestFunction[] = [ }, { value: "FuncNs.nsFunc", - definition: `namespace FuncNs { export function nsFunc(s: string) { return s; } }`, + definition: "namespace FuncNs { export function nsFunc(s: string) { return s; } }", }, { value: "FuncNestedNs.NestedNs.nestedNsFunc", @@ -154,11 +154,11 @@ export const selfTestFunctions: TestFunction[] = [ export const noSelfTestFunctions: TestFunction[] = [ { value: "voidFunc", - definition: `let voidFunc: {(this: void, s: string): string} = function(s) { return s; };`, + definition: "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", }, { value: "voidLambda", - definition: `let voidLambda: (this: void, s: string) => string = s => s;`, + definition: "let voidLambda: (this: void, s: string) => string = s => s;", }, { value: "voidMethodClass.voidMethod", @@ -188,7 +188,7 @@ export const noSelfTestFunctions: TestFunction[] = [ }, { value: "NoSelfFuncNs.noSelfNsFunc", - definition: `/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }`, + definition: "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", }, { value: "NoSelfFuncNs.noSelfNsFunc", @@ -324,11 +324,11 @@ export const noSelfTestFunctions: TestFunction[] = [ const noSelfInFileTestFunctions: TestFunction[] = [ { value: "noSelfInFileFunc", - definition: `/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };`, + definition: "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", }, { value: "noSelfInFileLambda", - definition: `/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;`, + definition: "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", }, { value: "NoSelfInFileFuncNs.noSelfInFileNsFunc", @@ -352,20 +352,20 @@ const noSelfInFileTestFunctions: TestFunction[] = [ ]; export const anonTestFunctionExpressions: TestFunction[] = [ - { value: `s => s` }, - { value: `(s => s)` }, - { value: `function(s) { return s; }` }, - { value: `(function(s) { return s; })` }, + { value: "s => s" }, + { value: "(s => s)" }, + { value: "function(s) { return s; }" }, + { value: "(function(s) { return s; })" }, ]; export const selfTestFunctionExpressions: TestFunction[] = [ - { value: `function(this: any, s) { return s; }` }, - { value: `(function(this: any, s) { return s; })` }, + { value: "function(this: any, s) { return s; }" }, + { value: "(function(this: any, s) { return s; })" }, ]; export const noSelfTestFunctionExpressions: TestFunction[] = [ - { value: `function(this: void, s) { return s; }` }, - { value: `(function(this: void, s) { return s; })` }, + { value: "function(this: void, s) { return s; }" }, + { value: "(function(this: void, s) { return s; })" }, ]; export const anonTestFunctionType = "(s: string) => string"; diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 4b4721d63..a491ccd7b 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -120,21 +120,6 @@ test.each(validTestFunctionCasts)("Valid function return with cast (%p)", (testF expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); }); -test("Interface method assignment", () => { - const code = `class Foo { - method(s: string): string { return s + "+method"; } - lambdaProp: (s: string) => string = s => s + "+lambdaProp"; - } - interface IFoo { - method: (s: string) => string; - lambdaProp(s: string): string; - } - const foo: IFoo = new Foo(); - return foo.method("foo") + "|" + foo.lambdaProp("bar");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo+method|bar+lambdaProp"); -}); - test("Valid function tuple assignment", () => { const code = `interface Func { (this: void, s: string): string; } function getTuple(): [number, Func] { return [1, s => s]; } diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index a2bef4c01..172150c47 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -197,8 +197,8 @@ test("for scope", () => { test.each([ { - inp: { ["test1"]: 0, ["test2"]: 1, ["test3"]: 2 }, - expected: { ["test1"]: 1, ["test2"]: 2, ["test3"]: 3 }, + inp: { test1: 0, test2: 1, test3: 2 }, + expected: { test1: 1, test2: 2, test3: 3 }, }, ])("forin[Object] (%p)", ({ inp, expected }) => { const result = util.transpileAndExecute( diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 018503687..885f24541 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -59,7 +59,7 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ export { foo }; ` .disableSemanticCheck() - .setLuaHeader(`setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })`) + .setLuaHeader('setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })') .setReturnExport("foo") .expectToEqual("bar"); } diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 94199e09f..541c28c56 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -90,7 +90,7 @@ test.each([ /** @noResolution */ declare module "fake" {} `, - mainCode: `import "fake";`, + mainCode: 'import "fake";', expectedPath: "fake", }, { @@ -98,7 +98,7 @@ test.each([ /** @noResolution */ declare module "fake" {} `, - mainCode: `import * as fake from "fake"; fake;`, + mainCode: 'import * as fake from "fake"; fake;', expectedPath: "fake", }, { @@ -108,7 +108,7 @@ test.each([ export const x: number; } `, - mainCode: `import { x } from "fake"; x;`, + mainCode: 'import { x } from "fake"; x;', expectedPath: "fake", }, { @@ -122,7 +122,7 @@ test.each([ export const y: number; } `, - mainCode: `import { y } from "fake"; y;`, + mainCode: 'import { y } from "fake"; y;', expectedPath: "fake", }, ])("noResolution prevents any module path resolution behavior", ({ declarationStatement, mainCode, expectedPath }) => { diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index bb8c8db78..a745e1383 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -15,7 +15,7 @@ test("global scoping", () => { "return a.foo();", undefined, undefined, - `namespace a { export function foo() { return "bar"; } }` + 'namespace a { export function foo() { return "bar"; } }' ); expect(result).toBe("bar"); diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 2dfdfa1d0..819143e1f 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -1,6 +1,6 @@ import * as util from "../util"; -test.each([`{ a: 3, b: "4" }`, `{ "a": 3, b: "4" }`, `{ ["a"]: 3, b: "4" }`, `{ ["a" + 123]: 3, b: "4" }`])( +test.each(['{ a: 3, b: "4" }', '{ "a": 3, b: "4" }', '{ ["a"]: 3, b: "4" }', '{ ["a" + 123]: 3, b: "4" }'])( "Object Literal (%p)", inp => { util.testExpression(inp).expectToMatchJsResult(); @@ -36,8 +36,8 @@ describe("property shorthand", () => { test("should support _G shorthand", () => { util.testExpression`({ _G })._G.foobar` - .setTsHeader(`declare const _G: any;`) - .setLuaHeader(`foobar = "foobar"`) + .setTsHeader("declare const _G: any;") + .setLuaHeader('foobar = "foobar"') .expectToEqual("foobar"); }); @@ -57,7 +57,7 @@ test("undefined as object key", () => { `.expectToMatchJsResult(); }); -test.each([`{x: "foobar"}.x`, `{x: "foobar"}["x"]`, `{x: () => "foobar"}.x()`, `{x: () => "foobar"}["x"]()`])( +test.each(['{x: "foobar"}.x', '{x: "foobar"}["x"]', '{x: () => "foobar"}.x()', '{x: () => "foobar"}["x"]()'])( "object literal property access (%p)", expression => { util.testExpression(expression).expectToMatchJsResult(); diff --git a/test/unit/printer/deadCodeAfterReturn.spec.ts b/test/unit/printer/deadCodeAfterReturn.spec.ts index 08c88658d..0ccead50e 100644 --- a/test/unit/printer/deadCodeAfterReturn.spec.ts +++ b/test/unit/printer/deadCodeAfterReturn.spec.ts @@ -37,25 +37,25 @@ test("Method dead code after return", () => { }); test("for dead code after return", () => { - const result = util.transpileAndExecute(`for (let i = 0; i < 10; i++) { return 3; const b = 8; }`); + const result = util.transpileAndExecute("for (let i = 0; i < 10; i++) { return 3; const b = 8; }"); expect(result).toBe(3); }); test("for..in dead code after return", () => { - const result = util.transpileAndExecute(`for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }`); + const result = util.transpileAndExecute('for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }'); expect(result).toBe(3); }); test("for..of dead code after return", () => { - const result = util.transpileAndExecute(`for (let a of [1,2,4]) { return 3; const b = 8; }`); + const result = util.transpileAndExecute("for (let a of [1,2,4]) { return 3; const b = 8; }"); expect(result).toBe(3); }); test("while dead code after return", () => { - const result = util.transpileAndExecute(`while (true) { return 3; const b = 8; }`); + const result = util.transpileAndExecute("while (true) { return 3; const b = 8; }"); expect(result).toBe(3); }); diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 011ae4e70..6b4487ac9 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -15,9 +15,9 @@ test.each([ { luaPattern: "abc", typeScriptPattern: "abc" }, { luaPattern: "def", typeScriptPattern: "def" }, { luaPattern: "xyz", typeScriptPattern: "xyz" }, - { luaPattern: `"foo"`, typeScriptPattern: `"foo"` }, - { luaPattern: `"bar"`, typeScriptPattern: `"bar"` }, - { luaPattern: `"baz"`, typeScriptPattern: `"baz"` }, + { luaPattern: '"foo"', typeScriptPattern: '"foo"' }, + { luaPattern: '"bar"', typeScriptPattern: '"bar"' }, + { luaPattern: '"baz"', typeScriptPattern: '"baz"' }, ], }, { @@ -194,11 +194,11 @@ test.each([ .getMainLuaFileResult(); const sourceMap = JSON.parse(file.sourceMap); - expect(sourceMap.sources.length).toBe(1); + expect(sourceMap.sources).toHaveLength(1); expect(sourceMap.sources[0]).toBe(mapSource); const consumer = await new SourceMapConsumer(file.sourceMap); - expect(consumer.sources.length).toBe(1); + expect(consumer.sources).toHaveLength(1); expect(consumer.sources[0]).toBe(fullSource); }); @@ -207,7 +207,7 @@ test.each([ { configSourceRoot: "src", mapSourceRoot: "src/" }, { configSourceRoot: "src/", mapSourceRoot: "src/" }, { configSourceRoot: "src\\", mapSourceRoot: "src/" }, -])("Source map has correct source root (%p)", async ({ configSourceRoot, mapSourceRoot }) => { +])("Source map has correct source root (%p)", ({ configSourceRoot, mapSourceRoot }) => { const file = util.testModule` const foo = "foo" ` @@ -220,13 +220,13 @@ test.each([ }); test.each([ - { code: `const type = "foobar";`, name: "type" }, - { code: `const and = "foobar";`, name: "and" }, - { code: `const $$$ = "foobar";`, name: "$$$" }, - { code: `const foo = { bar() { this; } };`, name: "this" }, - { code: `function foo($$$: unknown) {}`, name: "$$$" }, - { code: `class $$$ {}`, name: "$$$" }, - { code: `namespace $$$ { const foo = "bar"; }`, name: "$$$" }, + { code: 'const type = "foobar";', name: "type" }, + { code: 'const and = "foobar";', name: "and" }, + { code: 'const $$$ = "foobar";', name: "$$$" }, + { code: "const foo = { bar() { this; } };", name: "this" }, + { code: "function foo($$$: unknown) {}", name: "$$$" }, + { code: "class $$$ {}", name: "$$$" }, + { code: 'namespace $$$ { const foo = "bar"; }', name: "$$$" }, ])("Source map has correct name mappings (%p)", async ({ code, name }) => { const file = util .testModule(code) @@ -268,7 +268,7 @@ test("sourceMapTraceback saves sourcemap in _G", () => { const assertPatterns = [ { luaPattern: "function abc(", typeScriptPattern: "function abc() {" }, - { luaPattern: `return "foo"`, typeScriptPattern: `return "foo"` }, + { luaPattern: 'return "foo"', typeScriptPattern: 'return "foo"' }, ]; for (const { luaPattern, typeScriptPattern } of assertPatterns) { diff --git a/test/unit/typeof.spec.ts b/test/unit/typeof.spec.ts index d85e8f8c1..f8a063c1c 100644 --- a/test/unit/typeof.spec.ts +++ b/test/unit/typeof.spec.ts @@ -53,7 +53,7 @@ const equalityComparisonCases: ComparisonCase[] = [ { expression: "() => {}", operator: "===", compareTo: "function" }, { expression: "1", operator: "===", compareTo: "number" }, { expression: "true", operator: "===", compareTo: "boolean" }, - { expression: `"foo"`, operator: "===", compareTo: "string" }, + { expression: '"foo"', operator: "===", compareTo: "string" }, ]; const relationalComparisonCases: ComparisonCase[] = [ diff --git a/test/util.ts b/test/util.ts index 552351de9..1b30c5105 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,3 +1,4 @@ +/* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; import * as fs from "fs"; @@ -10,6 +11,9 @@ import * as tstl from "../src"; export * from "./legacy-utils"; +// Using `test` directly makes eslint-plugin-jest consider this file as a test +const defineTest = test; + export function assert(value: any, message?: string | Error): asserts value { nativeAssert(value, message); } @@ -26,7 +30,7 @@ export function testEachVersion( if (specialBuilder === false) return; const testName = name === undefined ? version : `${name} [${version}]`; - test(testName, () => { + defineTest(testName, () => { const builder = common(); builder.setOptions({ luaTarget: version }); if (typeof specialBuilder === "function") { @@ -62,7 +66,7 @@ function transpileJs(program: ts.Program): TranspileJsResult { for (const sourceFile of sourceFiles) { const isJs = fileName.endsWith(".js"); const isSourceMap = fileName.endsWith(".js.map"); - if (isJs || isSourceMap) { + if (isJs) { updateTranspiledFile(sourceFile.fileName, { js: data }); } else if (isSourceMap) { updateTranspiledFile(sourceFile.fileName, { sourceMap: data }); @@ -145,7 +149,7 @@ function executeJsModule(code: string): any { const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; - const memoized = new WeakMap(); + const memoized = new WeakMap(); descriptor.value = function(this: any, ...args: any[]): any { if (!memoized.has(this)) { memoized.set(this, originalFunction.apply(this, args)); @@ -158,6 +162,8 @@ const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { export class ExecutionError extends Error { public name = "ExecutionError"; + // https://github.com/typescript-eslint/typescript-eslint/issues/1131 + // eslint-disable-next-line @typescript-eslint/no-useless-constructor constructor(message: string) { super(message); } @@ -414,7 +420,7 @@ class AccessorTestBuilder extends TestBuilder { } class BundleTestBuilder extends AccessorTestBuilder { - public constructor(_tsCode: string) { + constructor(_tsCode: string) { super(_tsCode); this.setOptions({ luaBundle: "main.lua", luaBundleEntry: this.mainFileName }); } @@ -455,12 +461,12 @@ const createTestBuilderFactory = ( expect(serializeSubstitutions).toBe(false); tsCode = args[0]; } else { - let [template, ...substitutions] = args; + let [raw, ...substitutions] = args; if (serializeSubstitutions) { substitutions = substitutions.map(s => formatCode(s)); } - tsCode = template.map((chunk, index) => (substitutions[index - 1] ?? "") + chunk).join(""); + tsCode = String.raw(Object.assign([], { raw }), ...substitutions); } return new builder(tsCode); diff --git a/tslint.json b/tslint.json deleted file mode 100644 index be6ae2b58..000000000 --- a/tslint.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "rules": { - "array-type": [true, "array-simple"], - "arrow-return-shorthand": true, - "ban": [ - true, - { "name": "parseInt", "message": "tsstyle#type-coercion" }, - { "name": "parseFloat", "message": "tsstyle#type-coercion" }, - { "name": "Array", "message": "tsstyle#array-constructor" } - ], - "ban-types": [ - true, - ["Object", "Use {} instead."], - ["String", "Use 'string' instead."], - ["Number", "Use 'number' instead."], - ["Boolean", "Use 'boolean' instead."] - ], - "class-name": true, - "curly": [true, "ignore-same-line"], - "deprecation": true, - "forin": false, - "interface-name": [true, "never-prefix"], - "jsdoc-format": true, - "label-position": true, - "member-access": true, - "no-angle-bracket-type-assertion": true, - "no-any": false, - "no-arg": true, - "no-conditional-assignment": true, - "no-construct": true, - "no-debugger": true, - "no-default-export": true, - "no-duplicate-switch-case": true, - "no-duplicate-variable": true, - "no-inferrable-types": true, - "no-namespace": [true, "allow-declarations"], - "no-null-keyword": true, - "no-reference": true, - "no-string-throw": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-shorthand": true, - "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], - "prefer-const": [true, { "destructuring": "all" }], - "radix": true, - "switch-default": false, - "triple-equals": [true, "allow-null-check"], - "typedef": [true, "call-signature", "property-declaration"], - "use-isnan": true, - "variable-name": [true, "check-format", "ban-keywords", "allow-leading-underscore", "allow-pascal-case"] - } -} From 375e009eb8a5062c0cec1a41148b154aa9f36ab9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 9 May 2020 17:15:37 +0200 Subject: [PATCH 259/764] Replaced error throw with diagnostic (#861) * Replaced error throw with diagnostic * Return nil if node is not a statement * Handle expression case in transformExpression * Throw error when expression visitor returns nothing * Moved tests around * Added error incase superTransform expression visitor returns nothing --- src/transformation/context/context.ts | 23 ++++++++++++++++--- src/transformation/utils/diagnostics.ts | 4 ++++ .../__snapshots__/statements.spec.ts.snap | 8 +++++++ test/unit/expressions.spec.ts | 9 -------- test/unit/statements.spec.ts | 19 +++++++++++++++ 5 files changed, 51 insertions(+), 12 deletions(-) create mode 100644 test/unit/__snapshots__/statements.spec.ts.snap create mode 100644 test/unit/statements.spec.ts diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 27edbeea4..e310a9e19 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { castArray } from "../../utils"; +import { unsupportedNodeKind } from "../utils/diagnostics"; import { unwrapVisitorResult } from "../utils/lua-ast"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; @@ -46,7 +47,12 @@ export class TransformationContext { } private currentNodeVisitors: Array> = []; - public transformNode(node: ts.Node): lua.Node[] { + + public transformNode(node: ts.Node): lua.Node[]; + /** @internal */ + // eslint-disable-next-line @typescript-eslint/unified-signatures + public transformNode(node: ts.Node, isExpression?: boolean): lua.Node[]; + public transformNode(node: ts.Node, isExpression?: boolean): lua.Node[] { // TODO: Move to visitors? if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { return []; @@ -54,7 +60,8 @@ export class TransformationContext { const nodeVisitors = this.visitorMap.get(node.kind); if (!nodeVisitors || nodeVisitors.length === 0) { - throw new Error(`Unsupported node kind: ${ts.SyntaxKind[node.kind]}.`); + this.diagnostics.push(unsupportedNodeKind(node, node.kind)); + return isExpression ? [lua.createNilLiteral()] : []; } const previousNodeVisitors = this.currentNodeVisitors; @@ -78,12 +85,22 @@ export class TransformationContext { } public transformExpression(node: ExpressionLikeNode): lua.Expression { - const [result] = this.transformNode(node); + const [result] = this.transformNode(node, true); + + if (result === undefined) { + throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`); + } + return result as lua.Expression; } public superTransformExpression(node: ExpressionLikeNode): lua.Expression { const [result] = this.superTransformNode(node); + + if (result === undefined) { + throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`); + } + return result as lua.Expression; } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 0a53898f9..a87de4c74 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -11,6 +11,10 @@ const createDiagnosticFactory = (message: string | ((...arg messageText: typeof message === "string" ? message : message(...args), })); +export const unsupportedNodeKind = createDiagnosticFactory( + (kind: ts.SyntaxKind) => `Unsupported node kind ${ts.SyntaxKind[kind]}` +); + export const forbiddenForIn = createDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { diff --git a/test/unit/__snapshots__/statements.spec.ts.snap b/test/unit/__snapshots__/statements.spec.ts.snap new file mode 100644 index 000000000..d16dde3a7 --- /dev/null +++ b/test/unit/__snapshots__/statements.spec.ts.snap @@ -0,0 +1,8 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Unsupported node adds diagnostic: code 1`] = ` +"a = function() +end" +`; + +exports[`Unsupported node adds diagnostic: diagnostics 1`] = `"main.ts(3,13): error TSTL: Unsupported node kind LabeledStatement"`; diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 90211b78c..25f4c20ed 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -2,15 +2,6 @@ import * as tstl from "../../src"; import { unsupportedForTarget, unsupportedRightShiftOperator } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; -// TODO: -test("Block statement", () => { - util.testFunction` - let a = 4; - { let a = 42; } - return a; - `.expectToMatchJsResult(); -}); - test.each([ "i++", "++i", diff --git a/test/unit/statements.spec.ts b/test/unit/statements.spec.ts new file mode 100644 index 000000000..d653a8885 --- /dev/null +++ b/test/unit/statements.spec.ts @@ -0,0 +1,19 @@ +import * as util from "../util"; +import { unsupportedNodeKind } from "../../src/transformation/utils/diagnostics"; + +test("Block statement", () => { + util.testFunction` + let a = 4; + { let a = 42; } + return a; + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/860 +test("Unsupported node adds diagnostic", () => { + util.testModule` + const a = () => { + foo: "bar" + }; + `.expectDiagnosticsToMatchSnapshot([unsupportedNodeKind.code]); +}); From 00735b7488fa3079c7a1d125d12aaf40c0a8e831 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 11 May 2020 18:41:27 +0200 Subject: [PATCH 260/764] Fix side effects in string index causing issues (#868) * Fix side effects in string index causing issues * Removed unnecessary variable --- src/transformation/visitors/access.ts | 46 +++++++++++++++++++++------ test/unit/builtins/string.spec.ts | 8 +++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 3502e15e4..619a31fb2 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -4,7 +4,7 @@ import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { createExpressionPlusOne } from "../utils/lua-ast"; -import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; +import { isArrayType, isNumberType, isStringType, isExpressionWithEvaluationEffect } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; @@ -31,20 +31,17 @@ export const transformElementAccessExpression: FunctionVisitor = ( @@ -94,3 +91,32 @@ export const transformQualifiedName: FunctionVisitor = (node, return lua.createTableIndexExpression(left, right, node); }; + +function transformStringIndex(context: TransformationContext, expression: ts.ElementAccessExpression): lua.Expression { + const string = context.transformExpression(expression.expression); + // Translate to string.sub(str, index, index), cache index in case it has side effects. + if (isExpressionWithEvaluationEffect(expression.argumentExpression)) { + const indexIdentifier = lua.createIdentifier("____index"); + // string.sub(stringExpression, ____index, ____index) + const subCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("sub")), + [string, lua.cloneIdentifier(indexIdentifier), lua.cloneIdentifier(indexIdentifier)], + expression + ); + // function(____index) string.sub(stringExpression, ____index, ____index) + const functionExpression = lua.createFunctionExpression( + lua.createBlock([lua.createReturnStatement([subCall])]), + [lua.cloneIdentifier(indexIdentifier)] + ); + // (function(____index) string.sub(stringExpression, ____index, ____index) end)(index + 1) + const indexPlusOne = createExpressionPlusOne(context.transformExpression(expression.argumentExpression)); + return lua.createCallExpression(functionExpression, [indexPlusOne]); + } else { + const index = context.transformExpression(expression.argumentExpression); + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("sub")), + [string, createExpressionPlusOne(index), createExpressionPlusOne(index)], + expression + ); + } +} diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index a9b6afba4..b0139e1a0 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -41,6 +41,14 @@ test.each([ util.testExpressionTemplate`${input}[${index}]`.expectToMatchJsResult(); }); +test("string index with side effect", () => { + util.testFunction` + let i = 0; + const mystring = "abc"; + return mystring[i++]; + `.expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", searchValue: "", replaceValue: "" }, { inp: "hello test", searchValue: " ", replaceValue: "" }, From 0da1b35d3fb5e252ea10143a938246f5ccf09ee2 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 11 May 2020 19:04:36 +0200 Subject: [PATCH 261/764] Added memory benchmarks to CI (#864) * Added memory benchmarks to CI * Fixed linting issues * Fixed benchmark working directory * Load benchmarks from directory * Run benchmarks on master and commit Run benchmarks on master and commit Run benchmarks on master and commit * Changed find -d parameter to be unix compliant * Strip leading './' in readDir find command * Improved local development workflow and performed additional cleanup * Changed unit from kb to mb Some more cleanup * Addressed Review Fixed popen behaviour Improved error handling Fixed tslint issues * Fixed readFile returning incorrect result Reverted lua-types dev version back to jit * Consistent variable names * Reduced error handling boilerplate & Added some becnhmarks * Track amount of garbage collected * Typos * Addressed final review Changed error handling to use throw instead of monads Added eslint and fixed linting issues * Added missing function to readme * Removed tslint comments * Updated readme regarding non garbage results * Improved readabilty * Fixed typos --- .eslintrc.js | 11 +- .github/workflows/ci.yml | 91 ++++ .gitignore | 4 + benchmark/README.md | 43 ++ benchmark/dist/json.lua | 388 ++++++++++++++++++ benchmark/src/benchmark_types.ts | 27 ++ benchmark/src/memory_benchmark.ts | 114 +++++ .../src/memory_benchmarks/array_concat.ts | 9 + .../src/memory_benchmarks/array_every.ts | 9 + benchmark/src/memory_benchmarks/array_push.ts | 8 + .../src/memory_benchmarks/class_creation.ts | 18 + .../src/memory_benchmarks/graph_cylce.ts | 52 +++ benchmark/src/run.ts | 61 +++ benchmark/src/util.ts | 71 ++++ benchmark/tsconfig.53.json | 9 + benchmark/tsconfig.jit.json | 9 + benchmark/tsconfig.json | 15 + package-lock.json | 6 + package.json | 1 + 19 files changed, 945 insertions(+), 1 deletion(-) create mode 100644 benchmark/README.md create mode 100644 benchmark/dist/json.lua create mode 100644 benchmark/src/benchmark_types.ts create mode 100644 benchmark/src/memory_benchmark.ts create mode 100644 benchmark/src/memory_benchmarks/array_concat.ts create mode 100644 benchmark/src/memory_benchmarks/array_every.ts create mode 100644 benchmark/src/memory_benchmarks/array_push.ts create mode 100644 benchmark/src/memory_benchmarks/class_creation.ts create mode 100644 benchmark/src/memory_benchmarks/graph_cylce.ts create mode 100644 benchmark/src/run.ts create mode 100644 benchmark/src/util.ts create mode 100644 benchmark/tsconfig.53.json create mode 100644 benchmark/tsconfig.jit.json create mode 100644 benchmark/tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 0ffbec9c9..fb8ec7488 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -67,7 +67,10 @@ const typescriptBase = { module.exports = { extends: ["plugin:jest/recommended", "plugin:jest/style"], - parserOptions: { sourceType: "module", project: ["test/tsconfig.json", "src/lualib/tsconfig.json"] }, + parserOptions: { + sourceType: "module", + project: ["test/tsconfig.json", "src/lualib/tsconfig.json", "benchmark/tsconfig.json"], + }, env: { es6: true, node: true }, plugins: ["import"], rules: { @@ -186,5 +189,11 @@ module.exports = { "@typescript-eslint/prefer-optional-chain": "off", }, }, + { + files: "benchmark/src/memory_benchmarks/**/*.ts", + rules: { + "import/no-default-export": "off", + }, + }, ], }; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5ee8ba432..6ba373041 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,3 +38,94 @@ jobs: CI: true - if: matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v1 + + benchmark: + name: Benchmark + runs-on: ubuntu-latest + steps: + - name: Lua Install + run: sudo apt-get install lua5.3 luajit + # Checkout master & commit + - name: Checkout master + uses: actions/checkout@v2 + with: + ref: master + path: master + - name: Checkout commit + uses: actions/checkout@v2 + with: + path: commit + - name: Use Node.js 12.13.1 + uses: actions/setup-node@v1 + with: + node-version: 12.13.1 + # NPM + - name: NPM master + # TODO Lua types is only added manually to test the benchmark PR this can be removed again once the PR is merged + run: npm ci && npm run build && npm install -D lua-types + working-directory: master + - name: NPM commit + run: npm ci && npm run build + working-directory: commit + # Benchmark directory setup + - name: Ensure benchmark data dir exists + run: mkdir -p ./benchmark/data + working-directory: commit + - name: Copy commit benchmark to master + run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark + # Run master benchmark first and output to commit benchmark data + - name: Build benchmark Lua 5.3 master + run: node ../dist/tstl.js -p tsconfig.53.json + working-directory: master/benchmark + - name: Run benchmark Lua 5.3 master + id: benchmark-lua-master + run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json + working-directory: master/benchmark/dist + - name: Build benchmark LuaJIT master + run: node ../dist/tstl.js -p tsconfig.jit.json + working-directory: master/benchmark + - name: Run benchmark LuaJIT master + id: benchmark-jit-master + run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json + working-directory: master/benchmark/dist + # Run commit benchmark and compare with master + - name: Build benchmark Lua 5.3 commit + run: node ../dist/tstl.js -p tsconfig.53.json + working-directory: commit/benchmark + - name: Run benchmark Lua 5.3 commit + id: benchmark-lua-commit + run: echo ::set-output name=info::`lua5.3 -- run.lua ../data/benchmark_commit_53.json ../data/benchmark_master_53.json` + working-directory: commit/benchmark/dist + - name: Build benchmark LuaJIT commit + run: node ../dist/tstl.js -p tsconfig.jit.json + working-directory: commit/benchmark + - name: Run benchmark LuaJIT commit + id: benchmark-jit-commit + run: echo ::set-output name=info::`luajit -- run.lua ../data/benchmark_commit_jit.json ../data/benchmark_master_jit.json` + working-directory: commit/benchmark/dist + - name: Create benchmark check + uses: actions/github-script@0.9.0 + with: + benchmark-info-lua: ${{steps.benchmark-lua-commit.outputs.info}} + benchmark-info-jit: ${{steps.benchmark-jit-commit.outputs.info}} + script: | + const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); + const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); + + const summary = `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; + + const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; + + github.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: "Benchmark results", + head_sha: context.sha, + status: "completed", + conclusion: "neutral", + output: { + title: "Benchmark results", + summary: summary, + text: text + } + }); diff --git a/.gitignore b/.gitignore index 09a293fc7..5546914da 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ yarn.lock .vscode .idea .DS_Store + +benchmark/data/* +benchmark/dist/* +!benchmark/dist/json.lua diff --git a/benchmark/README.md b/benchmark/README.md new file mode 100644 index 000000000..c7b7d39c2 --- /dev/null +++ b/benchmark/README.md @@ -0,0 +1,43 @@ +## TSTL Benchmarks + +These benchmarks are written in typescript and transpiled to lua by using tstl. + +### Currently only memory benchmarks are supported + +To add a new benchmark add a new file to `memory_benchmarks` +and **default** export a function with the following type: `() => void`. +To prevent the benchmark from reporting "useful" results of your benchmark function as garbage, simply return the result. +The memory used by the returned result wont count towards the total garbage amount. + +For example (memory_benchmarks/my_benchmark.ts): + +```ts +export default function myBenchmark() { + const n = 123; + const result = []; + for (let i = 0; i < n; i++) { + // Do something memory instensive + } + return result; // Return results so they wont be counted as garbage +} +``` + +**Goal** + +The goal of memory benchmarks is to track how much (memory) `"garbage"` is created by tstl. +For that reason garabage collection is disabled in the benchmarks. + +You can force the creation of `"garbage"` by creating a lot of anonymous functions or temporary tables (see [lua-users.org](http://lua-users.org/wiki/OptimisingGarbageCollection) for more information). + +To avoid crashes in the CI your benchmark should not use more than 500MB of memory. + +**Running locally** + +1. Create a benchmark baseline called "benchmark_baseline.json": + `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_baseline.json` +2. Make some changes to tstl. +3. Create an updated benchmark and compare with the baseline: + `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_updated.json benchmark_baseline.json` +4. The above command will output comparison data as json to stdout. + If you provide a path as third argument the comparison data will be written to that path instead. + `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_updated.json benchmark_baseline.json result.md` diff --git a/benchmark/dist/json.lua b/benchmark/dist/json.lua new file mode 100644 index 000000000..54d444840 --- /dev/null +++ b/benchmark/dist/json.lua @@ -0,0 +1,388 @@ +-- +-- json.lua +-- +-- Copyright (c) 2020 rxi +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. +-- + +local json = { _version = "0.1.2" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\", + [ "\"" ] = "\"", + [ "\b" ] = "b", + [ "\f" ] = "f", + [ "\n" ] = "n", + [ "\r" ] = "r", + [ "\t" ] = "t", +} + +local escape_char_map_inv = { [ "/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return "\\" .. (escape_char_map[c] or string.format("u%04x", c:byte())) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if rawget(val, 1) ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + if n ~= #val then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. val:gsub('[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + -- Check for NaN, -inf and inf + if val ~= val or val <= -math.huge or val >= math.huge then + error("unexpected number value '" .. tostring(val) .. "'") + end + return string.format("%.14g", val) +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + + +function json.encode(val) + return ( encode(val) ) +end + + +------------------------------------------------------------------------------- +-- Decode +------------------------------------------------------------------------------- + +local parse + +local function create_set(...) + local res = {} + for i = 1, select("#", ...) do + res[ select(i, ...) ] = true + end + return res +end + +local space_chars = create_set(" ", "\t", "\r", "\n") +local delim_chars = create_set(" ", "\t", "\r", "\n", "]", "}", ",") +local escape_chars = create_set("\\", "/", '"', "b", "f", "n", "r", "t", "u") +local literals = create_set("true", "false", "null") + +local literal_map = { + [ "true" ] = true, + [ "false" ] = false, + [ "null" ] = nil, +} + + +local function next_char(str, idx, set, negate) + for i = idx, #str do + if set[str:sub(i, i)] ~= negate then + return i + end + end + return #str + 1 +end + + +local function decode_error(str, idx, msg) + local line_count = 1 + local col_count = 1 + for i = 1, idx - 1 do + col_count = col_count + 1 + if str:sub(i, i) == "\n" then + line_count = line_count + 1 + col_count = 1 + end + end + error( string.format("%s at line %d col %d", msg, line_count, col_count) ) +end + + +local function codepoint_to_utf8(n) + -- http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=iws-appendixa + local f = math.floor + if n <= 0x7f then + return string.char(n) + elseif n <= 0x7ff then + return string.char(f(n / 64) + 192, n % 64 + 128) + elseif n <= 0xffff then + return string.char(f(n / 4096) + 224, f(n % 4096 / 64) + 128, n % 64 + 128) + elseif n <= 0x10ffff then + return string.char(f(n / 262144) + 240, f(n % 262144 / 4096) + 128, + f(n % 4096 / 64) + 128, n % 64 + 128) + end + error( string.format("invalid unicode codepoint '%x'", n) ) +end + + +local function parse_unicode_escape(s) + local n1 = tonumber( s:sub(1, 4), 16 ) + local n2 = tonumber( s:sub(7, 10), 16 ) + -- Surrogate pair? + if n2 then + return codepoint_to_utf8((n1 - 0xd800) * 0x400 + (n2 - 0xdc00) + 0x10000) + else + return codepoint_to_utf8(n1) + end +end + + +local function parse_string(str, i) + local res = "" + local j = i + 1 + local k = j + + while j <= #str do + local x = str:byte(j) + + if x < 32 then + decode_error(str, j, "control character in string") + + elseif x == 92 then -- `\`: Escape + res = res .. str:sub(k, j - 1) + j = j + 1 + local c = str:sub(j, j) + if c == "u" then + local hex = str:match("^[dD][89aAbB]%x%x\\u%x%x%x%x", j + 1) + or str:match("^%x%x%x%x", j + 1) + or decode_error(str, j - 1, "invalid unicode escape in string") + res = res .. parse_unicode_escape(hex) + j = j + #hex + else + if not escape_chars[c] then + decode_error(str, j - 1, "invalid escape char '" .. c .. "' in string") + end + res = res .. escape_char_map_inv[c] + end + k = j + 1 + + elseif x == 34 then -- `"`: End of string + res = res .. str:sub(k, j - 1) + return res, j + 1 + end + + j = j + 1 + end + + decode_error(str, i, "expected closing quote for string") +end + + +local function parse_number(str, i) + local x = next_char(str, i, delim_chars) + local s = str:sub(i, x - 1) + local n = tonumber(s) + if not n then + decode_error(str, i, "invalid number '" .. s .. "'") + end + return n, x +end + + +local function parse_literal(str, i) + local x = next_char(str, i, delim_chars) + local word = str:sub(i, x - 1) + if not literals[word] then + decode_error(str, i, "invalid literal '" .. word .. "'") + end + return literal_map[word], x +end + + +local function parse_array(str, i) + local res = {} + local n = 1 + i = i + 1 + while 1 do + local x + i = next_char(str, i, space_chars, true) + -- Empty / end of array? + if str:sub(i, i) == "]" then + i = i + 1 + break + end + -- Read token + x, i = parse(str, i) + res[n] = x + n = n + 1 + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "]" then break end + if chr ~= "," then decode_error(str, i, "expected ']' or ','") end + end + return res, i +end + + +local function parse_object(str, i) + local res = {} + i = i + 1 + while 1 do + local key, val + i = next_char(str, i, space_chars, true) + -- Empty / end of object? + if str:sub(i, i) == "}" then + i = i + 1 + break + end + -- Read key + if str:sub(i, i) ~= '"' then + decode_error(str, i, "expected string for key") + end + key, i = parse(str, i) + -- Read ':' delimiter + i = next_char(str, i, space_chars, true) + if str:sub(i, i) ~= ":" then + decode_error(str, i, "expected ':' after key") + end + i = next_char(str, i + 1, space_chars, true) + -- Read value + val, i = parse(str, i) + -- Set + res[key] = val + -- Next token + i = next_char(str, i, space_chars, true) + local chr = str:sub(i, i) + i = i + 1 + if chr == "}" then break end + if chr ~= "," then decode_error(str, i, "expected '}' or ','") end + end + return res, i +end + + +local char_func_map = { + [ '"' ] = parse_string, + [ "0" ] = parse_number, + [ "1" ] = parse_number, + [ "2" ] = parse_number, + [ "3" ] = parse_number, + [ "4" ] = parse_number, + [ "5" ] = parse_number, + [ "6" ] = parse_number, + [ "7" ] = parse_number, + [ "8" ] = parse_number, + [ "9" ] = parse_number, + [ "-" ] = parse_number, + [ "t" ] = parse_literal, + [ "f" ] = parse_literal, + [ "n" ] = parse_literal, + [ "[" ] = parse_array, + [ "{" ] = parse_object, +} + + +parse = function(str, idx) + local chr = str:sub(idx, idx) + local f = char_func_map[chr] + if f then + return f(str, idx) + end + decode_error(str, idx, "unexpected character '" .. chr .. "'") +end + + +function json.decode(str) + if type(str) ~= "string" then + error("expected argument of type string, got " .. type(str)) + end + local res, idx = parse(str, next_char(str, 1, space_chars, true)) + idx = next_char(str, idx, space_chars, true) + if idx <= #str then + decode_error(str, idx, "trailing garbage") + end + return res +end + + +return json \ No newline at end of file diff --git a/benchmark/src/benchmark_types.ts b/benchmark/src/benchmark_types.ts new file mode 100644 index 000000000..6ec80efe6 --- /dev/null +++ b/benchmark/src/benchmark_types.ts @@ -0,0 +1,27 @@ +export enum BenchmarkKind { + Memory = "memory", +} + +export type BenchmarkFunction = () => void; + +export type BenchmarkResult = MemoryBenchmarkResult; + +export enum MemoryBenchmarkCategory { + TotalMemory = "totalMemory", + Garbage = "garbage", +} + +export interface MemoryBenchmarkResult { + kind: BenchmarkKind.Memory; + categories: Record; + benchmarkName: string; +} + +export function isMemoryBenchmarkResult(result: BenchmarkResult): result is MemoryBenchmarkResult { + return result.kind === BenchmarkKind.Memory; +} + +export interface ComparisonInfo { + summary: string; + text: string; +} diff --git a/benchmark/src/memory_benchmark.ts b/benchmark/src/memory_benchmark.ts new file mode 100644 index 000000000..10934757a --- /dev/null +++ b/benchmark/src/memory_benchmark.ts @@ -0,0 +1,114 @@ +import { BenchmarkKind, MemoryBenchmarkResult, ComparisonInfo, MemoryBenchmarkCategory } from "./benchmark_types"; +import { toFixed, json, calculatePercentageChange } from "./util"; + +export function runMemoryBenchmark(benchmarkFunction: Function): MemoryBenchmarkResult { + const result: MemoryBenchmarkResult = { + kind: BenchmarkKind.Memory, + benchmarkName: "NO_NAME", + categories: { + [MemoryBenchmarkCategory.Garbage]: 0, + [MemoryBenchmarkCategory.TotalMemory]: 0, + }, + }; + + // collect before running benchmark + collectgarbage("collect"); + + // stop automatic gc + collectgarbage("stop"); + + const preExecMemoryUsage = collectgarbage("count"); + + // store return value this allows benchmark functions + // to prevent "useful" result data from being garbage collected + let temp = benchmarkFunction(); + + const postExecMemoryUsage = collectgarbage("count"); + + collectgarbage("restart"); + collectgarbage("collect"); + + // get the amount of garbage collected + result.categories[MemoryBenchmarkCategory.Garbage] = postExecMemoryUsage - collectgarbage("count"); + + // make sure result isn't garbage collected until now and supress unused var warning + temp = temp; + + result.benchmarkName = debug.getinfo(benchmarkFunction).short_src; + + result.categories[MemoryBenchmarkCategory.TotalMemory] = postExecMemoryUsage - preExecMemoryUsage; + + return result; +} + +const formatMemory = (memInKB: number) => toFixed(memInKB / 1024, 3); +const makeMarkdownTableRow = (cells: string[]) => `| ${cells.join(" | ")} |\n`; +const makeBold = (input: string) => `**${input}**`; + +export function compareMemoryBenchmarks( + oldResults: MemoryBenchmarkResult[], + newResults: MemoryBenchmarkResult[] +): ComparisonInfo { + // Can not use Object.values because we want a fixed order. + const categories = [MemoryBenchmarkCategory.TotalMemory, MemoryBenchmarkCategory.Garbage]; + + const summary = categories + .map(category => `${makeBold(category)}\n${compareCategory(newResults, oldResults, category)}`) + .join("\n"); + + const text = `**master:**\n\`\`\`json\n${json.encode(oldResults)}\n\`\`\`\n**commit:**\n\`\`\`json\n${json.encode( + newResults + )}\n\`\`\``; + + return { summary, text }; +} + +function compareCategory( + newResults: MemoryBenchmarkResult[], + oldResults: MemoryBenchmarkResult[], + category: MemoryBenchmarkCategory +): string { + let comparisonTable = makeMarkdownTableRow(["name", "master (mb)", "commit (mb)", "change (mb)", "change (%)"]); + comparisonTable += makeMarkdownTableRow(["-", "-", "-", "-", "-"]); + + let oldValueSum = 0; + let newValueSum = 0; + + newResults.forEach(newResult => { + const oldResult = oldResults.find(r => r.benchmarkName === newResult.benchmarkName); + if (oldResult) { + const oldValue = oldResult.categories[category]; + const newValue = newResult.categories[category]; + const percentageChange = calculatePercentageChange( + newResult.categories[category], + oldResult.categories[category] + ); + const change = newResult.categories[category] - oldResult.categories[category]; + const row = [ + newResult.benchmarkName, + formatMemory(oldValue), + formatMemory(newValue), + formatMemory(change), + toFixed(percentageChange, 2), + ]; + comparisonTable += makeMarkdownTableRow(row); + oldValueSum += oldValue; + newValueSum += newValue; + } else { + // No master found => new benchmark + const row = [newResult.benchmarkName, formatMemory(newResult.categories[category]), "/", "/", "/"]; + comparisonTable += makeMarkdownTableRow(row); + } + }); + + const sumPercentageChange = calculatePercentageChange(oldValueSum, newValueSum); + comparisonTable += makeMarkdownTableRow([ + makeBold("sum"), + makeBold(formatMemory(oldValueSum)), + makeBold(formatMemory(newValueSum)), + makeBold(formatMemory(newValueSum - oldValueSum)), + makeBold(toFixed(sumPercentageChange, 2)), + ]); + + return comparisonTable; +} diff --git a/benchmark/src/memory_benchmarks/array_concat.ts b/benchmark/src/memory_benchmarks/array_concat.ts new file mode 100644 index 000000000..fbe149703 --- /dev/null +++ b/benchmark/src/memory_benchmarks/array_concat.ts @@ -0,0 +1,9 @@ +export default function arrayConcat(): number[] { + let arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const n = 1000; + for (let i = 0; i < n; i++) { + arr1 = arr1.concat(arr2); + } + return arr1; +} diff --git a/benchmark/src/memory_benchmarks/array_every.ts b/benchmark/src/memory_benchmarks/array_every.ts new file mode 100644 index 000000000..0ba21334f --- /dev/null +++ b/benchmark/src/memory_benchmarks/array_every.ts @@ -0,0 +1,9 @@ +export default function arrayEvery(): boolean { + const arr = []; + const n = 10000; + for (let i = 0; i < n; i++) { + arr[i] = i; + } + const isSmallerN = arr.every(e => e < n); + return isSmallerN; +} diff --git a/benchmark/src/memory_benchmarks/array_push.ts b/benchmark/src/memory_benchmarks/array_push.ts new file mode 100644 index 000000000..15c0a7dd1 --- /dev/null +++ b/benchmark/src/memory_benchmarks/array_push.ts @@ -0,0 +1,8 @@ +export default function arrayPush(): number[] { + const n = 10000; + const numberList: number[] = []; + for (let i = 0; i < n; i++) { + numberList.push(i * i); + } + return numberList; +} diff --git a/benchmark/src/memory_benchmarks/class_creation.ts b/benchmark/src/memory_benchmarks/class_creation.ts new file mode 100644 index 000000000..aaa57742f --- /dev/null +++ b/benchmark/src/memory_benchmarks/class_creation.ts @@ -0,0 +1,18 @@ +class A { + constructor(x: number) { + this.z = x * x; + } + + public z: number; +} + +class B extends A {} + +export default function classCreation(): B[] { + const arr1 = []; + const n = 10000; + for (let i = 0; i < n; i++) { + arr1.push(new B(i)); + } + return arr1; +} diff --git a/benchmark/src/memory_benchmarks/graph_cylce.ts b/benchmark/src/memory_benchmarks/graph_cylce.ts new file mode 100644 index 000000000..c78812dc5 --- /dev/null +++ b/benchmark/src/memory_benchmarks/graph_cylce.ts @@ -0,0 +1,52 @@ +type Graph = Map; + +function range(start: number, end: number): number[] { + if (start > end) return []; + return [start, ...range(start + 1, end)]; +} + +export default function detectCyleBenchmark(): boolean { + const n = 500; + const benchmarkGraph = new Map(); + // build a graph with n nodes and no cycle + for (let i = 0; i < n; i++) { + benchmarkGraph.set(i, range(i, n - 1)); + } + return detectCycle(benchmarkGraph); +} + +/** + * Detects cycles in an undirected graph + */ +function detectCycle(graph: Graph): boolean { + const visited: Map = new Map(); + + return [...graph.keys()].some(current => { + if (!visited.get(current)) { + return _detectCycle(graph, current, visited, undefined); + } + }); +} + +function _detectCycle(graph: Graph, current: T, visited: Map, parent: T | undefined): boolean { + visited.set(current, true); + + const neighbours = graph.get(current); + + if (!neighbours) { + throw Error("Err invalid graph format"); + } + + return neighbours.some(neighbour => { + if (!visited.get(neighbour)) { + // If an adjacent is not visited, then recur for that adjacent + return _detectCycle(graph, neighbour, visited, current); + } else if (neighbour !== parent) { + /* + * If an adjacent node is visited and not a parent of current vertex, + * then there is a cycle. + */ + return true; + } + }); +} diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts new file mode 100644 index 000000000..c632efe39 --- /dev/null +++ b/benchmark/src/run.ts @@ -0,0 +1,61 @@ +import { runMemoryBenchmark, compareMemoryBenchmarks } from "./memory_benchmark"; +import { isMemoryBenchmarkResult, BenchmarkResult, MemoryBenchmarkResult, ComparisonInfo } from "./benchmark_types"; +import { json, loadBenchmarksFromDirectory, readFile } from "./util"; + +// CLI arguments +// arg[0]: output path for benchmark data +// arg[1]: path to baseline benchmark data (required to generate comparison) +// arg[2]: path to result markdown file (optional) +declare const arg: [string | undefined, string | undefined, string | undefined]; + +function benchmark(): void { + // Memory tests + let memoryBenchmarkNewResults: MemoryBenchmarkResult[] = []; + + const memoryBenchmarks = loadBenchmarksFromDirectory("memory_benchmarks"); + + memoryBenchmarkNewResults = memoryBenchmarks.map(runMemoryBenchmark); + + // run future benchmarks types here + + const newBenchmarkResults = [...memoryBenchmarkNewResults]; + + // Try to read the baseline benchmark result + let oldBenchmarkResults: BenchmarkResult[] = []; + if (arg[1]) { + const oldBenchmarkData = readFile(arg[1]); + oldBenchmarkResults = json.decode(oldBenchmarkData) as BenchmarkResult[]; + } + + // Compare results + const comparisonInfo = compareBenchmarks(oldBenchmarkResults, newBenchmarkResults); + + // Output comparison info + outputBenchmarkData(comparisonInfo, newBenchmarkResults); +} +benchmark(); + +function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): ComparisonInfo { + const oldResultsMemory = oldResults.filter(isMemoryBenchmarkResult); + const newResultsMemory = newResults.filter(isMemoryBenchmarkResult); + + const memoryComparisonInfo = compareMemoryBenchmarks(oldResultsMemory, newResultsMemory); + + return { summary: memoryComparisonInfo.summary, text: memoryComparisonInfo.text }; +} + +function outputBenchmarkData(comparisonInfo: { summary: string; text: string }, newResults: BenchmarkResult[]): void { + if (!arg[2]) { + // Output to stdout as json by default, this is used by the CI to retrieve the info + print(json.encode(comparisonInfo)); + } else { + // Output to file as markdown if arg[2] is set, this is useful for local development + const markdownDataFile = io.open(arg[2], "w+")[0]!; + markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); + } + // Output benchmark results to json + if (arg[0]) { + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode(newResults)); + } +} diff --git a/benchmark/src/util.ts b/benchmark/src/util.ts new file mode 100644 index 000000000..d1c9fcc1d --- /dev/null +++ b/benchmark/src/util.ts @@ -0,0 +1,71 @@ +import { BenchmarkFunction } from "./benchmark_types"; + +export function toFixed(num: number, decimalPlaces = 0): string { + return string.format(`%.${decimalPlaces}f`, num); +} + +export function calculatePercentageChange(oldValue: number, newValue: number): number { + return (newValue / oldValue) * 100 - 100; +} + +// @ts-ignore +export const isWindows = package.config.startsWith("\\"); + +export const json: { + decode: (this: void, str: string) => {}; + encode: (this: void, val: any) => string; +} = require("json"); + +export function readFile(path: string): string { + const [fileHandle] = io.open(path, "rb"); + + if (!fileHandle) { + throw Error(`Can't open file ${path}`); + } + + const fileContent = readAll(fileHandle); + fileHandle.close(); + + return fileContent; +} + +export function readAll(file: LuaFile): string { + const content = file.read(_VERSION === "Lua 5.3" ? "a" : ("*a" as any)) as [string | undefined]; + + if (content[0]) { + return content[0]; + } + throw Error(`Can't readAll for file ${file}`); +} + +export function readDir(dir: string): string[] { + const findHandle = io.popen(isWindows ? `dir /A-D /B ${dir}` : `find '${dir}' -maxdepth 1 -type f`); + const findResult = readAll(findHandle); + + if (!findHandle.close()) { + throw Error(`readDir popen failed for dir ${dir} see stdout for more information.`); + } + + let files = findResult.split("\n"); + if (isWindows) { + // on windows we need to append the directory path + // on unix this is done by find automatically + files = files.map(f => `${dir}/${f}`); + } else { + // strip leading "./" on unix + files = files.map(f => (f.startsWith(".") && f[1] === "/" ? f.substr(2) : f)); + } + return files.filter(p => p !== ""); +} + +export function loadBenchmarksFromDirectory(benchmarkDir: string): BenchmarkFunction[] { + const benchmarkFiles = readDir(benchmarkDir); + + return benchmarkFiles.map(f => { + // replace slashes with dots + let dotPath = string.gsub(f, "%/", ".")[0]; + // remove extension + dotPath = string.gsub(dotPath, ".lua", "")[0]; + return require(dotPath).default as BenchmarkFunction; + }); +} diff --git a/benchmark/tsconfig.53.json b/benchmark/tsconfig.53.json new file mode 100644 index 000000000..0a7096234 --- /dev/null +++ b/benchmark/tsconfig.53.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": ["lua-types/5.3"] + }, + "tstl": { + "luaTarget": "5.3" + } +} diff --git a/benchmark/tsconfig.jit.json b/benchmark/tsconfig.jit.json new file mode 100644 index 000000000..1fe18fa2c --- /dev/null +++ b/benchmark/tsconfig.jit.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": ["lua-types/jit"] + }, + "tstl": { + "luaTarget": "JIT" + } +} diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json new file mode 100644 index 000000000..aefc13ae9 --- /dev/null +++ b/benchmark/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["esnext"], + // Dev types are JIT + "types": ["lua-types/jit"], + "moduleResolution": "node", + "outDir": "dist", + "rootDir": "src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "include": ["src"] +} diff --git a/package-lock.json b/package-lock.json index f3d427049..e17d11a90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3798,6 +3798,12 @@ "@sinonjs/commons": "^1.7.0" } }, + "lua-types": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", + "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", + "dev": true + }, "make-dir": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", diff --git a/package.json b/package.json index 6651b3109..3008b5b67 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "javascript-stringify": "^2.0.1", "jest": "^25.1.0", "jest-circus": "^25.1.0", + "lua-types": "^2.8.0", "prettier": "^1.19.1", "ts-jest": "^25.2.1", "ts-node": "^8.6.2" From cfbbb28599128e3968df7a198a71785b69f1d6ae Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 11 May 2020 19:08:31 +0200 Subject: [PATCH 262/764] 0.33.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index e17d11a90..a55b48f1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.2", + "version": "0.33.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 3008b5b67..6d41b4235 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.32.2", + "version": "0.33.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 249a365f2145de126a1fa370312ed973db22e028 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 11 May 2020 23:05:03 +0200 Subject: [PATCH 263/764] CHANGELOG 0.33.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44d99e44d..831cdc183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.33.0 + +- Added support for nullish coalescing `A ?? B`. +- Annotation `/** @noSelf */` now also works directly on function declarations, not only on classes/interfaces. +- Fixed incorrect file paths in source maps. +- Fixed unknown node kind throwing an error instead of diagnostic. +- Fixed string index with side-effects being evaluated twice. +- Added check for node.js version when running tstl. +- Fixed some issues with reflection class names. + +- Fixed incorrectly escaped variable names. + +Under the hood: + +- Switched from TSLint to ESLint. +- Added benchmarking capability for garbage collection. + ## 0.32.0 - **Deprecated:** The `noHoisting` option has been removed, hoisting will always be done. From 7260012df8cf43d15ce8eca5946565a84a8ace3f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 16 May 2020 21:06:32 +0200 Subject: [PATCH 264/764] Prevent benchmark action failing check run for fork PRs (#876) * Try something * Try checking by owner * Print full context * Printing some other stuff * Try creating a gist for forks * Wait why is this broken * I'm dumb * Forget about the gist idea --- .github/workflows/ci.yml | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ba373041..4ed53ce8c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -116,16 +116,23 @@ jobs: const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; - github.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: "Benchmark results", - head_sha: context.sha, - status: "completed", - conclusion: "neutral", - output: { - title: "Benchmark results", - summary: summary, - text: text - } - }); + const pull_request = context.payload.pull_request; + if (pull_request.head.repo.url === pull_request.base.repo.url) { + // This only works if not in a fork. + github.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: "Benchmark results", + head_sha: context.sha, + status: "completed", + conclusion: "neutral", + output: { + title: "Benchmark results", + summary: summary, + text: text + } + }); + } else { + console.log(summary); + console.log(text); + } From 6131fa663c32e6aae24287f8519775c2c44959e1 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 17 May 2020 00:09:52 +0500 Subject: [PATCH 265/764] Upgrade TypeScript to v3.9 (#874) --- CHANGELOG.md | 18 ++++++++++++++++++ package-lock.json | 6 +++--- package.json | 2 +- test/unit/assignments.spec.ts | 2 -- test/unit/builtins/array.spec.ts | 1 - test/unit/classes/classes.spec.ts | 4 ++-- test/unit/classes/decorators.spec.ts | 9 +++++---- test/unit/functions/functions.spec.ts | 2 -- test/unit/identifiers.spec.ts | 26 ++++++++++++++------------ test/unit/namespaces.spec.ts | 3 --- test/util.ts | 4 ++-- 11 files changed, 45 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 831cdc183..4e2cc02ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## Unreleased + + + +- TypeScript has been updated to 3.9. See [release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/) for details. This update includes some fixes specific to our API usage: + - Importing a non-module using `import "./file"` produced a TS2307 error [#35973](https://github.com/microsoft/TypeScript/issues/35973) + - TypeScript now tries to find a call signature even in presence of type errors (#36665)(https://github.com/microsoft/TypeScript/pull/36665): + ```ts + function foo(this: void, x: string) {} + foo(1); + ``` + ```lua + -- 3.8 + foo(nil, 1) + -- 3.9 + foo(1) + ``` + ## 0.33.0 - Added support for nullish coalescing `A ?? B`. diff --git a/package-lock.json b/package-lock.json index a55b48f1d..a8e0102ed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5629,9 +5629,9 @@ } }, "typescript": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", - "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==" + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", + "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==" }, "union-value": { "version": "1.0.1", diff --git a/package.json b/package.json index 6d41b4235..4992ba80a 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "^3.8.3" + "typescript": "^3.9.2" }, "devDependencies": { "@types/fs-extra": "^8.1.0", diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 178d72bab..02e1a3b9b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -12,9 +12,7 @@ test.each(["const", "let"])("%s declaration not top-level is not global", declar }); test.each(["const", "let"])("top-level %s declaration is global", declarationKind => { - // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports util.testBundle` - // @ts-ignore import './a'; export const result = foo; ` diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 35294be6d..7525513a7 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -570,7 +570,6 @@ describe.each(["reduce", "reduceRight"])("array.%s", reduce => { const genericChecks = [ "function generic(array: T)", "function generic(array: T)", - "function generic(array: T[])", "type ArrayType = number[]; function generic(array: T)", "function generic(array: T & {})", "function generic(array: T)", diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 6bf2fc85f..52bcdd0fc 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -772,7 +772,7 @@ test("default exported name class has correct name property", () => { util.testModule` export default class Test { static method() { return true; } } ` - .setReturnExport("default.name") + .setReturnExport("default", "name") .expectToMatchJsResult(); }); @@ -780,7 +780,7 @@ test("default exported anonymous class has 'default' name property", () => { util.testModule` export default class { static method() { return true; } } ` - .setReturnExport("default.name") + .setReturnExport("default", "name") .expectToEqual("default"); }); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index ad77a3a11..cba245c1f 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -114,14 +114,15 @@ test("Throws error if decorator function has void context", () => { test("Exported class decorator", () => { util.testModule` - function decorator(c: T): T { - c.bar = "foobar"; - return c; + function decorator any>(Class: T): T { + return class extends Class { + public bar = "foobar"; + }; } @decorator export class Foo {} ` - .setReturnExport("Foo.bar") + .setReturnExport("Foo", "bar") .expectToMatchJsResult(); }); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 2f2f3b212..73549d918 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -504,9 +504,7 @@ test("missing declaration name", () => { }); test("top-level function declaration is global", () => { - // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports util.testBundle` - // @ts-ignore import './a'; export const result = foo(); ` diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 27046c81b..ba2bcd8a0 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -194,9 +194,10 @@ test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name => { util.testFunction` - function decorator(c: T): T { - c.bar = "foobar"; - return c; + function decorator any>(Class: T): T { + return class extends Class { + public bar = "foobar"; + }; } @decorator @@ -206,17 +207,18 @@ test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name }); test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua name", name => { - const code = ` - function decorator(c: T): T { - c.bar = "foobar"; - return c; + util.testModule` + function decorator any>(Class: T): T { + return class extends Class { + public bar = "foobar"; + }; } @decorator - export class ${name} {}`; - - const lua = util.transpileString(code); - expect(util.executeLua(`return (function() ${lua} end)()["${name}"].bar`)).toBe("foobar"); + export class ${name} {} + ` + .setReturnExport(name, "bar") + .expectToMatchJsResult(); }); describe("lua keyword as identifier doesn't interfere with lua's value", () => { @@ -782,7 +784,7 @@ test("lua built-in as in constructor assignment", () => { class A { constructor(public error: string){} } - + export const result = new A("42").error; `.expectToMatchJsResult(); }); diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index a745e1383..159fb8534 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -94,11 +94,8 @@ test("namespace merging across files", () => { } `; - // TODO [typescript@>=3.9]: Remove `@ts-ignore` comments before module imports util.testBundle` - // @ts-ignore import './a'; - // @ts-ignore import './b'; export const result = NS.Inner; diff --git a/test/util.ts b/test/util.ts index 1b30c5105..a24ce29a1 100644 --- a/test/util.ts +++ b/test/util.ts @@ -431,9 +431,9 @@ class BundleTestBuilder extends AccessorTestBuilder { } class ModuleTestBuilder extends AccessorTestBuilder { - public setReturnExport(name: string): this { + public setReturnExport(...names: string[]): this { expect(this.hasProgram).toBe(false); - this.accessor = `.${name}`; + this.accessor = names.map(n => `[${tstl.escapeString(n)}]`).join(""); return this; } } From b2988fd1cc154f52c887f2347c0bcdaec5f06baa Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 16 May 2020 21:21:00 +0200 Subject: [PATCH 266/764] Fix benchmark failing outside of pull requests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4ed53ce8c..3cff50e60 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -117,7 +117,7 @@ jobs: const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; const pull_request = context.payload.pull_request; - if (pull_request.head.repo.url === pull_request.base.repo.url) { + if (!pull_request || pull_request.head.repo.url === pull_request.base.repo.url) { // This only works if not in a fork. github.checks.create({ owner: context.repo.owner, From d1efec14ee4862d8cbe5f55dc22b3ec3de5f21be Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 23 May 2020 15:38:05 +0500 Subject: [PATCH 267/764] Generator and iteration improvements (#872) * Generator and iteration improvements * Pass input vararg count to unpack * Fix .next() parameter not being passed * Methods are missing `FunctionExpressionFlags.Declaration` * Add changelog --- CHANGELOG.md | 7 ++ src/LuaLib.ts | 2 + src/lualib/Generator.ts | 31 +++++ src/lualib/Iterator.ts | 43 ++++--- src/lualib/declarations/coroutine.d.ts | 19 +++ src/lualib/declarations/global.d.ts | 6 + .../visitors/class/members/method.ts | 28 ++--- src/transformation/visitors/function.ts | 84 +++++++------ src/transformation/visitors/generator.ts | 114 ------------------ src/transformation/visitors/index.ts | 3 +- src/transformation/visitors/loops/for-of.ts | 2 +- test/unit/functions/functions.spec.ts | 65 +--------- test/unit/functions/generators.spec.ts | 96 +++++++++++++++ 13 files changed, 248 insertions(+), 252 deletions(-) create mode 100644 src/lualib/Generator.ts create mode 100644 src/lualib/declarations/coroutine.d.ts delete mode 100644 src/transformation/visitors/generator.ts create mode 100644 test/unit/functions/generators.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e2cc02ee..eceb69bb4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - TypeScript has been updated to 3.9. See [release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/) for details. This update includes some fixes specific to our API usage: + - Importing a non-module using `import "./file"` produced a TS2307 error [#35973](https://github.com/microsoft/TypeScript/issues/35973) - TypeScript now tries to find a call signature even in presence of type errors (#36665)(https://github.com/microsoft/TypeScript/pull/36665): ```ts @@ -18,6 +19,12 @@ foo(1) ``` +- Reduced memory consumption and optimized performance of generators and iterators + +- Fixed generator syntax being ignored on methods (`*foo() {}`) and function expressions (`function*() {}`) + +- Fixed iteration over generators stopping at first yielded `nil` value + ## 0.33.0 - Added support for nullish coalescing `A ?? B`. diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 8c27e5730..33437a7b8 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -33,6 +33,7 @@ export enum LuaLibFeature { FunctionApply = "FunctionApply", FunctionBind = "FunctionBind", FunctionCall = "FunctionCall", + Generator = "Generator", InstanceOf = "InstanceOf", InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", @@ -72,6 +73,7 @@ const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], Error: [LuaLibFeature.New, LuaLibFeature.Class, LuaLibFeature.FunctionCall], + Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts new file mode 100644 index 000000000..37b639776 --- /dev/null +++ b/src/lualib/Generator.ts @@ -0,0 +1,31 @@ +interface GeneratorIterator { + ____coroutine: LuaThread; + [Symbol.iterator](): GeneratorIterator; + next: typeof __TS__GeneratorNext; +} + +function __TS__GeneratorIterator(this: GeneratorIterator) { + return this; +} + +function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { + const co = this.____coroutine; + if (coroutine.status(co) === "dead") return { done: true }; + + const [status, value] = coroutine.resume(co, ...args); + if (!status) throw value; + + return { value, done: coroutine.status(co) === "dead" }; +} + +function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { + return function(this: void, ...args: Vararg): GeneratorIterator { + const argsLength = select("#", ...args); + return { + // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil + ____coroutine: coroutine.create(() => fn((unpack || table.unpack)(args, 1, argsLength))), + [Symbol.iterator]: __TS__GeneratorIterator, + next: __TS__GeneratorNext, + }; + }; +} diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index ca4618d9f..ac1effadb 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,19 +1,32 @@ -function __TS__Iterator(this: void, iterable: Iterable): (this: void) => T { - if (iterable[Symbol.iterator]) { +/** @tupleReturn */ +function __TS__IteratorGeneratorStep(this: GeneratorIterator): [true, any] | [] { + const co = this.____coroutine; + + const [status, value] = coroutine.resume(co); + if (!status) throw value; + + if (coroutine.status(co) === "dead") return []; + return [true, value]; +} + +/** @tupleReturn */ +function __TS__IteratorIteratorStep(this: Iterator): [true, T] | [] { + const result = this.next(); + if (result.done) return []; + return [true, result.value]; +} + +/** @tupleReturn */ +function __TS__Iterator( + this: void, + iterable: Iterable | GeneratorIterator | readonly T[] +): [(...args: any[]) => [any, T] | [], ...any[]] { + if ("____coroutine" in iterable) { + return [__TS__IteratorGeneratorStep, iterable]; + } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); - return () => { - const result = iterator.next(); - if (!result.done) { - return result.value; - } else { - return undefined; - } - }; + return [__TS__IteratorIteratorStep, iterator]; } else { - let i = 0; - return () => { - i += 1; - return iterable[i]; - }; + return ipairs(iterable as readonly T[]); } } diff --git a/src/lualib/declarations/coroutine.d.ts b/src/lualib/declarations/coroutine.d.ts new file mode 100644 index 000000000..1e648d6c8 --- /dev/null +++ b/src/lualib/declarations/coroutine.d.ts @@ -0,0 +1,19 @@ +/** @noSelfInFile */ + +interface LuaThread { + readonly __internal__: unique symbol; +} + +declare namespace coroutine { + function create(f: (...args: any[]) => any): LuaThread; + + /** @tupleReturn */ + function resume(co: LuaThread, ...val: any[]): [true, ...any[]] | [false, string]; + + function status(co: LuaThread): "running" | "suspended" | "normal" | "dead"; + + function wrap(f: (...args: any[]) => any): /** @tupleReturn */ (...args: any[]) => any[]; + + /** @tupleReturn */ + function yield(...args: any[]): any[]; +} diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 35f2b3b3a..2e13fbdb9 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -24,3 +24,9 @@ declare function unpack(list: T[], i?: number, j?: number): T[]; declare function select(index: number, ...args: T[]): T; declare function select(index: "#", ...args: T[]): number; + +/** + * @luaIterator + * @tupleReturn + */ +declare function ipairs(t: Record): LuaTupleIterable<[number, T]>; diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 4d9610d9b..6f6df45b0 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -1,9 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; -import { ContextType, getFunctionContextType } from "../../../utils/function-context"; -import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { transformFunctionBody, transformParameters } from "../../function"; +import { transformFunctionToExpression } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; @@ -18,29 +16,17 @@ export function transformMethodDeclaration( return undefined; } + const methodTable = + isStaticNode(node) || noPrototype + ? lua.cloneIdentifier(className) + : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); + let methodName = transformPropertyName(context, node.name); if (lua.isStringLiteral(methodName) && methodName.value === "toString") { methodName = lua.createStringLiteral("__tostring", node.name); } - const type = context.checker.getTypeAtLocation(node); - const functionContext = - getFunctionContextType(context, type) !== ContextType.Void ? createSelfIdentifier() : undefined; - const [paramNames, dots, restParamName] = transformParameters(context, node.parameters, functionContext); - - const [body] = transformFunctionBody(context, node.parameters, node.body, restParamName); - const functionExpression = lua.createFunctionExpression( - lua.createBlock(body), - paramNames, - dots, - lua.FunctionExpressionFlags.Declaration, - node.body - ); - - const methodTable = - isStaticNode(node) || noPrototype - ? lua.cloneIdentifier(className) - : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); + const [functionExpression] = transformFunctionToExpression(context, node); return lua.createAssignmentStatement( lua.createTableIndexExpression(methodTable, methodName), diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 7c82a89be..cfbd8622d 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; +import { assert } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; import { isVarargType } from "../utils/annotations"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; @@ -11,8 +12,8 @@ import { createSelfIdentifier, wrapInTable, } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; -import { transformGeneratorFunctionBody } from "./generator"; import { transformIdentifier } from "./identifier"; import { transformBindingPattern } from "./variable-declaration"; @@ -157,12 +158,13 @@ export function transformParameters( return [paramNames, dotsLiteral, restParamName]; } -export function transformFunctionLikeDeclaration( - node: ts.FunctionLikeDeclaration, - context: TransformationContext -): lua.Expression { - const type = context.checker.getTypeAtLocation(node); +export function transformFunctionToExpression( + context: TransformationContext, + node: ts.FunctionLikeDeclaration +): [lua.Expression, Scope] { + assert(node.body); + const type = context.checker.getTypeAtLocation(node); let functionContext: lua.Identifier | undefined; if (getFunctionContextType(context, type) !== ContextType.Void) { if (ts.isArrowFunction(node)) { @@ -176,14 +178,10 @@ export function transformFunctionLikeDeclaration( } } - // Build parameter string - const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); - let flags = lua.FunctionExpressionFlags.None; - - if (node.body === undefined) { - // This code can be reached only from object methods, which is TypeScript error - return lua.createNilLiteral(); + if (!ts.isBlock(node.body)) flags |= lua.FunctionExpressionFlags.Inline; + if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) { + flags |= lua.FunctionExpressionFlags.Declaration; } let body: ts.Block; @@ -193,14 +191,11 @@ export function transformFunctionLikeDeclaration( const returnExpression = ts.createReturn(node.body); body = ts.createBlock([returnExpression]); returnExpression.parent = body; - if (node.body) { - body.parent = node.body.parent; - } - flags |= lua.FunctionExpressionFlags.Inline; + if (node.body) body.parent = node.body.parent; } - const [transformedBody, scope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); - + const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); + const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), paramNames, @@ -209,12 +204,31 @@ export function transformFunctionLikeDeclaration( node ); + return [ + node.asteriskToken + ? transformLuaLibFunction(context, LuaLibFeature.Generator, undefined, functionExpression) + : functionExpression, + functionScope, + ]; +} + +export function transformFunctionLikeDeclaration( + node: ts.FunctionLikeDeclaration, + context: TransformationContext +): lua.Expression { + if (node.body === undefined) { + // This code can be reached only from object methods, which is TypeScript error + return lua.createNilLiteral(); + } + + const [functionExpression, functionScope] = transformFunctionToExpression(context, node); + // Handle named function expressions which reference themselves - if (ts.isFunctionExpression(node) && node.name && scope.referencedSymbols) { + if (ts.isFunctionExpression(node) && node.name && functionScope.referencedSymbols) { const symbol = context.checker.getSymbolAtLocation(node.name); if (symbol) { // TODO: Not using symbol ids because of https://github.com/microsoft/TypeScript/issues/37131 - const isReferenced = [...scope.referencedSymbols].some(([, nodes]) => + const isReferenced = [...functionScope.referencedSymbols].some(([, nodes]) => nodes.some(n => context.checker.getSymbolAtLocation(n)?.valueDeclaration === symbol.valueDeclaration) ); @@ -234,27 +248,10 @@ export function transformFunctionLikeDeclaration( export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { // Don't transform functions without body (overload declarations) - if (!node.body) { + if (node.body === undefined) { return undefined; } - const type = context.checker.getTypeAtLocation(node); - const functionContext = - getFunctionContextType(context, type) !== ContextType.Void ? createSelfIdentifier() : undefined; - const [params, dotsLiteral, restParamName] = transformParameters(context, node.parameters, functionContext); - - const [body, functionScope] = node.asteriskToken - ? transformGeneratorFunctionBody(context, node.parameters, node.body, restParamName) - : transformFunctionBody(context, node.parameters, node.body, restParamName); - - const block = lua.createBlock(body); - const functionExpression = lua.createFunctionExpression( - block, - params, - dotsLiteral, - lua.FunctionExpressionFlags.Declaration - ); - if (hasDefaultExportModifier(node)) { return lua.createAssignmentStatement( lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(node)), @@ -262,6 +259,8 @@ export const transformFunctionDeclaration: FunctionVisitor = (expression, context) => + lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), + expression.expression ? [context.transformExpression(expression.expression)] : [], + expression + ); diff --git a/src/transformation/visitors/generator.ts b/src/transformation/visitors/generator.ts deleted file mode 100644 index 60e48e0d9..000000000 --- a/src/transformation/visitors/generator.ts +++ /dev/null @@ -1,114 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../LuaAST"; -import { FunctionVisitor, TransformationContext } from "../context"; -import { wrapInTable } from "../utils/lua-ast"; -import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; -import { Scope } from "../utils/scope"; -import { transformFunctionBody } from "./function"; - -export function transformGeneratorFunctionBody( - context: TransformationContext, - parameters: ts.NodeArray, - body: ts.Block, - spreadIdentifier?: lua.Identifier -): [lua.Statement[], Scope] { - importLuaLibFeature(context, LuaLibFeature.Symbol); - const [functionBody, functionScope] = transformFunctionBody(context, parameters, body); - - const coroutineIdentifier = lua.createIdentifier("____co"); - const valueIdentifier = lua.createIdentifier("____value"); - const errIdentifier = lua.createIdentifier("____err"); - const itIdentifier = lua.createIdentifier("____it"); - - // local ____co = coroutine.create(originalFunction) - const coroutine = lua.createVariableDeclarationStatement( - coroutineIdentifier, - lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("create")), - [lua.createFunctionExpression(lua.createBlock(functionBody))] - ) - ); - - const nextBody = []; - // coroutine.resume(__co, ...) - const resumeCall = lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("resume")), - [coroutineIdentifier, lua.createDotsLiteral()] - ); - - // ____err, ____value = coroutine.resume(____co, ...) - nextBody.push(lua.createVariableDeclarationStatement([errIdentifier, valueIdentifier], resumeCall)); - - // if(not ____err){error(____value)} - const errorCheck = lua.createIfStatement( - lua.createUnaryExpression(errIdentifier, lua.SyntaxKind.NotOperator), - lua.createBlock([ - lua.createExpressionStatement(lua.createCallExpression(lua.createIdentifier("error"), [valueIdentifier])), - ]) - ); - nextBody.push(errorCheck); - - // coroutine.status(____co) == "dead"; - const coStatus = lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("status")), - [coroutineIdentifier] - ); - const status = lua.createBinaryExpression( - coStatus, - lua.createStringLiteral("dead"), - lua.SyntaxKind.EqualityOperator - ); - - // {done = coroutine.status(____co) == "dead"; value = ____value} - const iteratorResult = lua.createTableExpression([ - lua.createTableFieldExpression(status, lua.createStringLiteral("done")), - lua.createTableFieldExpression(valueIdentifier, lua.createStringLiteral("value")), - ]); - nextBody.push(lua.createReturnStatement([iteratorResult])); - - // function(____, ...) - const nextFunctionDeclaration = lua.createFunctionExpression( - lua.createBlock(nextBody), - [lua.createAnonymousIdentifier()], - lua.createDotsLiteral() - ); - - // ____it = {next = function(____, ...)} - const iterator = lua.createVariableDeclarationStatement( - itIdentifier, - lua.createTableExpression([ - lua.createTableFieldExpression(nextFunctionDeclaration, lua.createStringLiteral("next")), - ]) - ); - - const symbolIterator = lua.createTableIndexExpression( - lua.createIdentifier("Symbol"), - lua.createStringLiteral("iterator") - ); - - const block = [ - coroutine, - iterator, - // ____it[Symbol.iterator] = {return ____it} - lua.createAssignmentStatement( - lua.createTableIndexExpression(itIdentifier, symbolIterator), - lua.createFunctionExpression(lua.createBlock([lua.createReturnStatement([itIdentifier])])) - ), - // return ____it - lua.createReturnStatement([itIdentifier]), - ]; - - if (spreadIdentifier) { - const spreadTable = wrapInTable(lua.createDotsLiteral()); - block.unshift(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); - } - - return [block, functionScope]; -} - -export const transformYieldExpression: FunctionVisitor = (expression, context) => - lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), - expression.expression ? [context.transformExpression(expression.expression)] : [], - expression - ); diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 17b25ffd7..48469a84b 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -17,8 +17,7 @@ import { transformDeleteExpression } from "./delete"; import { transformEnumDeclaration } from "./enum"; import { transformThrowStatement, transformTryStatement } from "./errors"; import { transformExpressionStatement } from "./expression-statement"; -import { transformFunctionDeclaration, transformFunctionLikeDeclaration } from "./function"; -import { transformYieldExpression } from "./generator"; +import { transformFunctionDeclaration, transformFunctionLikeDeclaration, transformYieldExpression } from "./function"; import { transformIdentifierExpression } from "./identifier"; import { literalVisitors } from "./literal"; import { transformDoStatement, transformWhileStatement } from "./loops/do-while"; diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 44656088a..67adb2ca2 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -143,7 +143,7 @@ function transformForOfIteratorStatement( context.transformExpression(statement.expression) ); - return lua.createForInStatement(block, [valueVariable], [iterable], statement); + return lua.createForInStatement(block, [lua.createAnonymousIdentifier(), valueVariable], [iterable], statement); } export const transformForOfStatement: FunctionVisitor = (node, context) => { diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 73549d918..7e4aa6a08 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -34,20 +34,11 @@ test.each(["b => a = b", "b => a += b", "b => a -= b", "b => a *= b", "b => a /= } ); -test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Arrow Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - - const callArgs = inp.join(","); - - const result = util.transpileAndExecute( - `let add = (a: number = 3, b: number = 4) => a+b; - return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); +test.each([{ args: [] }, { args: [1] }, { args: [1, 2] }])("Arrow default values (%p)", ({ args }) => { + util.testFunction` + const add = (a = 3, b = 4) => a + b; + return add(${util.formatCode(...args)}); + `.expectToMatchJsResult(); }); test("Function Expression", () => { @@ -351,52 +342,6 @@ test("Complex element access call statement", () => { `.expectToMatchJsResult(); }); -test.each([1, 2])("Generator functions value (%p)", iterations => { - util.testFunction` - function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: number; - for(let i = 0; i < ${iterations}; ++i) { - ret = gen.next(i).value; - } - return ret; - `.expectToMatchJsResult(); -}); - -test.each([1, 2])("Generator functions done (%p)", iterations => { - util.testFunction` - function* seq(value: number) { - let a = yield value + 1; - return 42; - } - const gen = seq(0); - let ret: boolean; - for(let i = 0; i < ${iterations}; ++i) { - ret = gen.next(i).done; - } - return ret; - `.expectToMatchJsResult(); -}); - -test("Generator for..of", () => { - util.testFunction` - function* seq() { - yield(1); - yield(2); - yield(3); - return 4; - } - let result = 0; - for(let i of seq()) { - result = result * 10 + i; - } - return result - `.expectToMatchJsResult(); -}); - test("Function local overriding export", () => { util.testModule` export const foo = 5; diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts new file mode 100644 index 000000000..90fb67aa4 --- /dev/null +++ b/test/unit/functions/generators.spec.ts @@ -0,0 +1,96 @@ +import * as util from "../../util"; + +test("generator parameters", () => { + util.testFunction` + function* generator(value: number) { + yield value; + } + + return generator(5).next(); + `.expectToMatchJsResult(); +}); + +test(".next()", () => { + util.testFunction` + function* generator() { + yield 1; + yield 2; + return 3; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); +}); + +test(".next() with parameters", () => { + util.testFunction` + function* generator() { + return yield 0; + } + + const it = generator(); + return [it.next(1), it.next(2), it.next(3)]; + `.expectToMatchJsResult(); +}); + +test("for..of", () => { + util.testFunction` + function* generator() { + yield 1; + yield 2; + yield undefined; + return 3; + } + + const results = []; + for (const value of generator()) { + results.push({ value }); + } + return results; + `.expectToMatchJsResult(); +}); + +test("function expression", () => { + util.testFunction` + const generator = function*() { + return true; + } + + return generator().next(); + `.expectToMatchJsResult(); +}); + +test("class method", () => { + util.testFunction` + class A { + *generator() { + return true; + } + } + + return new A().generator().next(); + `.expectToMatchJsResult(); +}); + +test("object member", () => { + util.testFunction` + const a = { + *generator() { + return true; + } + } + + return a.generator().next(); + `.expectToMatchJsResult(); +}); + +test("hoisting", () => { + util.testFunction` + return generator().next(); + + function* generator() { + return true; + } + `.expectToMatchJsResult(); +}); From 1e4a8bb92a673eff1c97225e4db5ae49a266cb7e Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 23 May 2020 21:56:21 +0500 Subject: [PATCH 268/764] Cli fixes (#883) * Don't parse values of custom options as files * Remove `did you mean` CLI parsing diagnostic * Add ignored diagnostic code messages as comments --- src/cli/parse.ts | 21 +++++++++++++-------- test/cli/parse.spec.ts | 3 ++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 1ffa50d6a..fff0ef0d0 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -122,15 +122,20 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: if (option) { // Ignore errors caused by tstl specific compiler options - const tsInvalidCompilerOptionErrorCode = 5023; parsedCommandLine.errors = parsedCommandLine.errors.filter( - e => !(e.code === tsInvalidCompilerOptionErrorCode && String(e.messageText).endsWith(`'${args[i]}'.`)) + // TS5023: Unknown compiler option '{0}'. + // TS5025: Unknown compiler option '{0}'. Did you mean '{1}'? + e => !((e.code === 5023 || e.code === 5025) && String(e.messageText).includes(`'${args[i]}'.`)) ); - const { error, value, increment } = readCommandLineArgument(option, args[i + 1]); + const { error, value, consumed } = readCommandLineArgument(option, args[i + 1]); if (error) parsedCommandLine.errors.push(error); parsedCommandLine.options[option.name] = value; - i += increment; + if (consumed) { + i += 1; + // Values of custom options are parsed as a file name, exclude them + parsedCommandLine.fileNames = parsedCommandLine.fileNames.filter(f => f !== value); + } } } @@ -138,7 +143,7 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: } interface CommandLineArgument extends ReadValueResult { - increment: number; + consumed: boolean; } function readCommandLineArgument(option: CommandLineOption, value: any): CommandLineArgument { @@ -147,7 +152,7 @@ function readCommandLineArgument(option: CommandLineOption, value: any): Command value = value === "true"; } else { // Set boolean arguments without supplied value to true - return { value: true, increment: 0 }; + return { value: true, consumed: false }; } } @@ -155,11 +160,11 @@ function readCommandLineArgument(option: CommandLineOption, value: any): Command return { error: cliDiagnostics.compilerOptionExpectsAnArgument(option.name), value: undefined, - increment: 0, + consumed: false, }; } - return { ...readValue(option, value), increment: 1 }; + return { ...readValue(option, value), consumed: true }; } interface ReadValueResult { diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 3ce9b35ba..1053aae67 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -9,10 +9,11 @@ describe("command line", () => { }); test("should support standard typescript options", () => { - const commandLine = "--project tsconfig.json --noHeader -t es3 -lt 5.3"; + const commandLine = "main.ts --project tsconfig.json --noHeader -t es3 -lt 5.3"; const result = tstl.parseCommandLine(commandLine.split(" ")); expect(result.errors).not.toHaveDiagnostics(); + expect(result.fileNames).toEqual(["main.ts"]); expect(result.options).toEqual({ project: "tsconfig.json", noHeader: true, From 42b356868c43a588928771df1a352494ece775a6 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 24 May 2020 18:22:05 +0500 Subject: [PATCH 269/764] Fix class .toString inheritance (#882) * Fix class .toString inheritance * Move tests to builtins/object and add few more toString tests --- CHANGELOG.md | 2 + src/lualib/ClassExtends.ts | 1 + src/lualib/declarations/tstl.d.ts | 1 + test/unit/builtins/object.spec.ts | 93 +++++++++++++++++++++++++++++++ test/unit/classes/classes.spec.ts | 36 ------------ 5 files changed, 97 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eceb69bb4..1311e01d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ - Fixed iteration over generators stopping at first yielded `nil` value +- Fixed extending a class not keeping `toString` implementation from a super class + ## 0.33.0 - Added support for nullish coalescing `A ?? B`. diff --git a/src/lualib/ClassExtends.ts b/src/lualib/ClassExtends.ts index e297cba93..0df851629 100644 --- a/src/lualib/ClassExtends.ts +++ b/src/lualib/ClassExtends.ts @@ -16,4 +16,5 @@ function __TS__ClassExtends(this: void, target: LuaClass, base: LuaClass): void // Re-add metatable events defined by accessors with `__TS__SetDescriptor` if (typeof base.prototype.__index === "function") target.prototype.__index = base.prototype.__index; if (typeof base.prototype.__newindex === "function") target.prototype.__newindex = base.prototype.__newindex; + if (typeof base.prototype.__tostring === "function") target.prototype.__tostring = base.prototype.__tostring; } diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index a983ee66d..57e436ae3 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -10,6 +10,7 @@ interface Metatable { _descriptors?: Record; __index?: any; __newindex?: any; + __tostring?: any; } interface LuaClass extends Metatable { diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 067da81f6..b4866d2e7 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -28,3 +28,96 @@ test.each(["[]", '[["a", 1], ["b", 2]]', '[["a", 1], ["a", 2]]', 'new Map([["foo util.testExpression`Object.fromEntries(${entries})`.expectToMatchJsResult(); } ); + +describe(".toString()", () => { + const toStringDeclaration = ` + function toString(value: object) { + const result = value.toString(); + return result === "[object Object]" || result.startsWith("table: ") ? "table" : result; + } + `; + + test("class override", () => { + util.testFunction` + ${toStringDeclaration} + class A { + public toString() { + return "A"; + } + } + + return toString(new A()); + `.expectToMatchJsResult(); + }); + + test("inherited class override", () => { + util.testFunction` + ${toStringDeclaration} + class A { + public toString() { + return "A"; + } + } + + class B extends A {} + + return { A: toString(new A()), B: toString(new B()) }; + `.expectToMatchJsResult(); + }); + + test("don't affect inherited class", () => { + util.testFunction` + ${toStringDeclaration} + class A {} + + class B extends A { + public toString() { + return "B"; + } + } + + return { A: toString(new A()), B: toString(new B()) }; + `.expectToMatchJsResult(); + }); + + test("override inherited class override", () => { + util.testFunction` + ${toStringDeclaration} + class A { + public toString() { + return "A"; + } + } + + class B extends A { + public toString() { + return "B"; + } + } + + return { A: toString(new A()), B: toString(new B()) }; + `.expectToMatchJsResult(); + }); +}); + +describe(".hasOwnProperty()", () => { + test("class field", () => { + util.testFunction` + class A { + public field = true; + } + + return new A().hasOwnProperty("field"); + `.expectToMatchJsResult(); + }); + + test("class method", () => { + util.testFunction` + class A { + public method() {} + } + + return new A().hasOwnProperty("method"); + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 52bcdd0fc..f4c14df34 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -352,42 +352,6 @@ test("ClassComputedMethodCall", () => { `.expectToMatchJsResult(); }); -test("ClassToString", () => { - util.testFunction` - class a { - public toString(): string { - return "instance of a"; - } - } - let inst = new a(); - return inst.toString(); - `.expectToMatchJsResult(); -}); - -test("HasOwnProperty true", () => { - util.testFunction` - class a { - public test(): void { - } - } - let inst = new a(); - inst["prop"] = 17; - return inst.hasOwnProperty("prop"); - `.expectToMatchJsResult(); -}); - -test("HasOwnProperty false", () => { - util.testFunction` - class a { - public test(): void { - } - } - let inst = new a(); - inst["prop"] = 17; - return inst.hasOwnProperty("test"); - `.expectToMatchJsResult(); -}); - test("CastClassMethodCall", () => { util.testFunction` interface result From b3b4a21f6d5f2c9f9997a01b189f2ad3eadd95be Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 24 May 2020 18:56:22 +0500 Subject: [PATCH 270/764] Fix `array.join` accepting only string and number elements (#887) --- CHANGELOG.md | 2 ++ src/LuaLib.ts | 1 + src/lualib/ArrayJoin.ts | 8 +++++++ src/lualib/Iterator.ts | 2 +- src/lualib/declarations/global.d.ts | 4 +++- src/transformation/builtins/array.ts | 31 +++++++++++++++++----------- src/typescript-internal.d.ts | 4 ++++ test/unit/builtins/array.spec.ts | 9 ++++++++ 8 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 src/lualib/ArrayJoin.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 1311e01d4..98a3c32fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ - Fixed iteration over generators stopping at first yielded `nil` value +- Fixed `Array.prototype.join` throwing an error when array contains anything other than strings and numbers + - Fixed extending a class not keeping `toString` implementation from a super class ## 0.33.0 diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 33437a7b8..ca81866f1 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -10,6 +10,7 @@ export enum LuaLibFeature { ArrayFindIndex = "ArrayFindIndex", ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", + ArrayJoin = "ArrayJoin", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", ArrayReduce = "ArrayReduce", diff --git a/src/lualib/ArrayJoin.ts b/src/lualib/ArrayJoin.ts new file mode 100644 index 000000000..33e220181 --- /dev/null +++ b/src/lualib/ArrayJoin.ts @@ -0,0 +1,8 @@ +function __TS__ArrayJoin(this: unknown[], separator = ",") { + let result = ""; + for (const [index, value] of ipairs(this)) { + if (index > 1) result += separator; + result += value.toString(); + } + return result; +} diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index ac1effadb..897d4a7a2 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -27,6 +27,6 @@ function __TS__Iterator( const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; } else { - return ipairs(iterable as readonly T[]); + return ipairs(iterable as readonly T[]) as any; } } diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 2e13fbdb9..450fba8dc 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -29,4 +29,6 @@ declare function select(index: "#", ...args: T[]): number; * @luaIterator * @tupleReturn */ -declare function ipairs(t: Record): LuaTupleIterable<[number, T]>; +type LuaTupleIterator = Iterable & { " LuaTupleIterator": never }; + +declare function ipairs(t: Record): LuaTupleIterator<[number, T]>; diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 41859e57c..35be01a00 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -4,6 +4,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { isStringType, isNumberType } from "../utils/typescript"; export function transformArrayPrototypeCall( context: TransformationContext, @@ -61,19 +62,25 @@ export function transformArrayPrototypeCall( case "splice": return transformLuaLibFunction(context, LuaLibFeature.ArraySplice, node, caller, ...params); case "join": - const defaultSeparatorLiteral = lua.createStringLiteral(","); - const parameters = [ - caller, - node.arguments.length === 0 - ? defaultSeparatorLiteral - : lua.createBinaryExpression(params[0], defaultSeparatorLiteral, lua.SyntaxKind.OrOperator), - ]; + const callerType = context.checker.getTypeAtLocation(expression.expression); + const elementType = context.checker.getElementTypeOfArrayType(callerType); + if (elementType && (isStringType(context, elementType) || isNumberType(context, elementType))) { + const defaultSeparatorLiteral = lua.createStringLiteral(","); + const parameters = [ + caller, + node.arguments.length === 0 + ? defaultSeparatorLiteral + : lua.createBinaryExpression(params[0], defaultSeparatorLiteral, lua.SyntaxKind.OrOperator), + ]; - return lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("concat")), - parameters, - node - ); + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("concat")), + parameters, + node + ); + } + + return transformLuaLibFunction(context, LuaLibFeature.ArrayJoin, node, caller, ...params); case "flat": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlat, node, caller, ...params); case "flatMap": diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index d3974a168..7444d89d7 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -20,4 +20,8 @@ declare module "typescript" { configFile?: TsConfigSourceFile; configFilePath?: string; } + + interface TypeChecker { + getElementTypeOfArrayType(type: Type): Type | undefined; + } } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 7525513a7..075de32e9 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -424,10 +424,19 @@ test.each([ { array: ["test1", "test2"] }, { array: ["test1", "test2"], separator: ";" }, { array: ["test1", "test2"], separator: "" }, + { array: [1, "2"] }, ])("array.join (%p)", ({ array, separator }) => { util.testExpression`${util.formatCode(array)}.join(${util.formatCode(separator)})`.expectToMatchJsResult(); }); +test('array.join (1, "2", {})', () => { + util.testExpression`[1, "2", {}].join()`.expectToEqual("1,2,table: 0x168"); +}); + +test('array.join (1, "2", Symbol("foo"))', () => { + util.testExpression`[1, "2", Symbol("foo")].join()`.expectToEqual("1,2,Symbol(foo)"); +}); + test("array.join without separator argument", () => { util.testExpression`["test1", "test2"].join()`.expectToMatchJsResult(); }); From 912a23029375cefee5c4817ad851f66131ec0ea8 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 24 May 2020 19:02:13 +0500 Subject: [PATCH 271/764] Add `luaTarget: "universal"` (#873) * Add `luaTarget: "universal"` * Add changelog * Add missing dependencies on LuaLibFeature.Unpack * Feedback * `expectTsUnpack` -> `expectLualibUnpack` --- CHANGELOG.md | 3 + src/CompilerOptions.ts | 1 + src/LuaLib.ts | 7 ++- src/lualib/FunctionApply.ts | 2 +- src/lualib/FunctionBind.ts | 2 +- src/lualib/FunctionCall.ts | 2 +- src/lualib/MathAtan2.ts | 1 + src/lualib/Spread.ts | 2 +- src/lualib/Unpack.ts | 1 + src/lualib/declarations/math.d.ts | 6 ++ src/lualib/tsconfig.json | 1 - src/transformation/builtins/math.ts | 16 ++--- src/transformation/context/context.ts | 2 +- src/transformation/utils/diagnostics.ts | 2 +- src/transformation/utils/lua-ast.ts | 6 ++ .../visitors/binary-expression/bit.ts | 2 + src/transformation/visitors/break-continue.ts | 2 +- src/transformation/visitors/switch.ts | 2 +- test/cli/parse.spec.ts | 2 + test/unit/__snapshots__/loops.spec.ts.snap | 59 +++++++++++++++++++ test/unit/builtins/math.spec.ts | 3 + test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 3 + 23 files changed, 110 insertions(+), 18 deletions(-) create mode 100644 src/lualib/MathAtan2.ts create mode 100644 src/lualib/Unpack.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 98a3c32fb..1b4a14b1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ ## Unreleased +- Added new `"luaTarget"` option value - `"universal"`. Choosing this target would make TypeScriptToLua generate code compatible with all supported Lua targets. + - **BREAKING CHANGE:** This is a new default target. If you have been depending on LuaJIT being chosen implicitly, now you have to enable it explicitly with `"luaTarget": "JIT"` in the `tsconfig.json` file. + - TypeScript has been updated to 3.9. See [release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/) for details. This update includes some fixes specific to our API usage: diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index af9a82d7d..45786a555 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -44,6 +44,7 @@ export enum LuaLibImportKind { } export enum LuaTarget { + Universal = "universal", Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", diff --git a/src/LuaLib.ts b/src/LuaLib.ts index ca81866f1..52ecf550b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -39,6 +39,7 @@ export enum LuaLibFeature { InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", Map = "Map", + MathAtan2 = "MathAtan2", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", @@ -68,12 +69,16 @@ export enum LuaLibFeature { Symbol = "Symbol", SymbolRegistry = "SymbolRegistry", TypeOf = "TypeOf", + Unpack = "Unpack", } const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], Error: [LuaLibFeature.New, LuaLibFeature.Class, LuaLibFeature.FunctionCall], + FunctionApply: [LuaLibFeature.Unpack], + FunctionBind: [LuaLibFeature.Unpack], + FunctionCall: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], @@ -82,7 +87,7 @@ const luaLibDependencies: Partial> = { Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], - Spread: [LuaLibFeature.Iterator], + Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], SymbolRegistry: [LuaLibFeature.Symbol], }; diff --git a/src/lualib/FunctionApply.ts b/src/lualib/FunctionApply.ts index 294efdda9..2638a43a8 100644 --- a/src/lualib/FunctionApply.ts +++ b/src/lualib/FunctionApply.ts @@ -1,6 +1,6 @@ function __TS__FunctionApply(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, args?: any[]): any { if (args) { - return fn(thisArg, (unpack || table.unpack)(args)); + return fn(thisArg, ...args); } else { return fn(thisArg); } diff --git a/src/lualib/FunctionBind.ts b/src/lualib/FunctionBind.ts index 671570ab9..e12fbe37c 100644 --- a/src/lualib/FunctionBind.ts +++ b/src/lualib/FunctionBind.ts @@ -8,6 +8,6 @@ function __TS__FunctionBind( for (let i = 0; i < boundArgs.length; ++i) { table.insert(args, i + 1, boundArgs[i]); } - return fn(thisArg, (unpack || table.unpack)(args)); + return fn(thisArg, ...args); }; } diff --git a/src/lualib/FunctionCall.ts b/src/lualib/FunctionCall.ts index e9b50fbbe..8435e7239 100644 --- a/src/lualib/FunctionCall.ts +++ b/src/lualib/FunctionCall.ts @@ -1,3 +1,3 @@ function __TS__FunctionCall(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, ...args: any[]): any { - return fn(thisArg, (unpack || table.unpack)(args)); + return fn(thisArg, ...args); } diff --git a/src/lualib/MathAtan2.ts b/src/lualib/MathAtan2.ts new file mode 100644 index 000000000..fdf322664 --- /dev/null +++ b/src/lualib/MathAtan2.ts @@ -0,0 +1 @@ +const __TS__MathAtan2 = math.atan2 || math.atan; diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index d9dcf0345..2bc96395b 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -10,5 +10,5 @@ function __TS__Spread(this: void, iterable: string | Iterable): T[] { arr[arr.length] = item; } } - return (table.unpack || unpack)(arr); + return __TS__Unpack(arr); } diff --git a/src/lualib/Unpack.ts b/src/lualib/Unpack.ts new file mode 100644 index 000000000..99aedf253 --- /dev/null +++ b/src/lualib/Unpack.ts @@ -0,0 +1 @@ +const __TS__Unpack = table.unpack || unpack; diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts index a0fb6c0e6..837f717f9 100644 --- a/src/lualib/declarations/math.d.ts +++ b/src/lualib/declarations/math.d.ts @@ -2,4 +2,10 @@ declare namespace math { /** @tupleReturn */ function modf(x: number): [number, number]; + + function atan(x: number): number; + // eslint-disable-next-line @typescript-eslint/unified-signatures + function atan(y: number, x?: number): number; + + function atan2(y: number, x: number): number; } diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index a9ca1cb4d..b9d6de8ce 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -11,7 +11,6 @@ }, "tstl": { "luaLibImport": "none", - "luaTarget": "5.1", "noHeader": true } } diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 6ceae16bd..af742214f 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -1,8 +1,9 @@ import * as ts from "typescript"; -import * as lua from "../../LuaAST"; import { LuaTarget } from "../../CompilerOptions"; +import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; export function transformMathProperty( @@ -37,22 +38,24 @@ export function transformMathCall( const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); + const math = lua.createIdentifier("math"); const expressionName = expression.name.text; switch (expressionName) { // Lua 5.3: math.atan(y, x) // Otherwise: math.atan2(y, x) case "atan2": { - const math = lua.createIdentifier("math"); - const methodName = context.options.luaTarget === LuaTarget.Lua53 ? "atan" : expressionName; - const method = lua.createStringLiteral(methodName); + if (context.luaTarget === LuaTarget.Universal) { + return transformLuaLibFunction(context, LuaLibFeature.MathAtan2, node, ...params); + } + + const method = lua.createStringLiteral(context.luaTarget === LuaTarget.Lua53 ? "atan" : "atan2"); return lua.createCallExpression(lua.createTableIndexExpression(math, method), params, node); } // (math.log(x) / Math.LNe) case "log10": case "log2": { - const math = lua.createIdentifier("math"); const log1 = lua.createTableIndexExpression(math, lua.createStringLiteral("log")); const logCall1 = lua.createCallExpression(log1, params); const e = lua.createNumericLiteral(expressionName === "log10" ? Math.LN10 : Math.LN2); @@ -61,7 +64,6 @@ export function transformMathCall( // math.log(1 + x) case "log1p": { - const math = lua.createIdentifier("math"); const log = lua.createStringLiteral("log"); const one = lua.createNumericLiteral(1); const add = lua.createBinaryExpression(one, params[0], lua.SyntaxKind.AdditionOperator); @@ -70,7 +72,6 @@ export function transformMathCall( // math.floor(x + 0.5) case "round": { - const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); const half = lua.createNumericLiteral(0.5); const add = lua.createBinaryExpression(params[0], half, lua.SyntaxKind.AdditionOperator); @@ -93,7 +94,6 @@ export function transformMathCall( case "sin": case "sqrt": case "tan": { - const math = lua.createIdentifier("math"); const method = lua.createStringLiteral(expressionName); return lua.createCallExpression(lua.createTableIndexExpression(math, method), params, node); } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index e310a9e19..4ee4515c4 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -32,7 +32,7 @@ export class TransformationContext { public readonly resolver: EmitResolver; public readonly options: CompilerOptions = this.program.getCompilerOptions(); - public readonly luaTarget = this.options.luaTarget ?? LuaTarget.LuaJIT; + public readonly luaTarget = this.options.luaTarget ?? LuaTarget.Universal; public readonly isModule = ts.isExternalModule(this.sourceFile); public readonly isStrict = (this.options.alwaysStrict ?? this.options.strict) || diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index a87de4c74..a5bdb35db 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -107,7 +107,7 @@ export const unsupportedRightShiftOperator = createDiagnosticFactory( const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export const unsupportedForTarget = createDiagnosticFactory( - (functionality: string, version: LuaTarget) => + (functionality: string, version: Exclude) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index dfce4b2fc..e0c7682d5 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -6,6 +6,8 @@ import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; import { peekScope, ScopeType } from "./scope"; import { isFunctionType } from "./typescript"; +import { transformLuaLibFunction } from "./lualib"; +import { LuaLibFeature } from "../../LuaLib"; export type OneToManyVisitorResult = T | T[] | undefined; export function unwrapVisitorResult(result: OneToManyVisitorResult): T[] { @@ -56,6 +58,10 @@ export function createUnpackCall( expression: lua.Expression, tsOriginal?: ts.Node ): lua.Expression { + if (context.luaTarget === LuaTarget.Universal) { + return transformLuaLibFunction(context, LuaLibFeature.Unpack, tsOriginal, expression); + } + const unpack = context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.LuaJIT ? lua.createIdentifier("unpack") diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index ffdf410ec..e284b2ea0 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -62,6 +62,7 @@ export function transformBinaryBitOperation( operator: BitOperator ): lua.Expression { switch (context.luaTarget) { + case LuaTarget.Universal: case LuaTarget.Lua51: context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); @@ -105,6 +106,7 @@ export function transformUnaryBitOperation( operator: lua.UnaryBitwiseOperator ): lua.Expression { switch (context.luaTarget) { + case LuaTarget.Universal: case LuaTarget.Lua51: context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index bde4ddd52..9211d4165 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -15,7 +15,7 @@ export const transformBreakStatement: FunctionVisitor = (brea }; export const transformContinueStatement: FunctionVisitor = (statement, context) => { - if (context.luaTarget === LuaTarget.Lua51) { + if (context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua51) { context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", LuaTarget.Lua51)); } diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 880f449bd..99ff3df7d 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -6,7 +6,7 @@ import { unsupportedForTarget } from "../utils/diagnostics"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { - if (context.luaTarget === LuaTarget.Lua51) { + if (context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua51) { context.diagnostics.push(unsupportedForTarget(statement, "Switch statements", LuaTarget.Lua51)); } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 1053aae67..6b6349f9b 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -110,6 +110,7 @@ describe("command line", () => { ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], + ["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }], ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], @@ -216,6 +217,7 @@ describe("tsconfig", () => { ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], + ["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }], ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap index f1daffe65..e9b6be991 100644 --- a/test/unit/__snapshots__/loops.spec.ts.snap +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -25,6 +25,19 @@ until not false" exports[`loop continue (do { continue; } while (false)) [5.1]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (do { continue; } while (false)) [universal]: code 1`] = ` +"repeat + do + do + goto __continue2 + end + ::__continue2:: + end +until not false" +`; + +exports[`loop continue (do { continue; } while (false)) [universal]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + exports[`loop continue (for (;;) { continue; }) [5.1]: code 1`] = ` "do while true do @@ -38,6 +51,19 @@ end" exports[`loop continue (for (;;) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (;;) { continue; }) [universal]: code 1`] = ` +"do + while true do + do + goto __continue2 + end + ::__continue2:: + end +end" +`; + +exports[`loop continue (for (;;) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + exports[`loop continue (for (const a in {}) { continue; }) [5.1]: code 1`] = ` "for a in pairs({}) do do @@ -49,6 +75,17 @@ end" exports[`loop continue (for (const a in {}) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (const a in {}) { continue; }) [universal]: code 1`] = ` +"for a in pairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a in {}) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + exports[`loop continue (for (const a of []) { continue; }) [5.1]: code 1`] = ` "for ____, a in ipairs({}) do do @@ -60,6 +97,17 @@ end" exports[`loop continue (for (const a of []) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (const a of []) { continue; }) [universal]: code 1`] = ` +"for ____, a in ipairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a of []) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + exports[`loop continue (while (false) { continue; }) [5.1]: code 1`] = ` "while false do do @@ -70,3 +118,14 @@ end" `; exports[`loop continue (while (false) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; + +exports[`loop continue (while (false) { continue; }) [universal]: code 1`] = ` +"while false do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (while (false) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 163095d9d..4d95e4afb 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -27,8 +27,11 @@ test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s" const expectMathAtan2: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan2("); const expectMathAtan: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan("); +const expectLualibMathAtan2: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toContain("__TS__MathAtan2("); util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, { + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibMathAtan2), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 172150c47..0959d31b8 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -530,6 +530,7 @@ for (const testCase of [ expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { + [tstl.LuaTarget.Universal]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index dec923d83..b3b7c95a0 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -5,6 +5,7 @@ import { formatCode } from "../util"; // TODO: Make some utils for testing other targets const expectUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch(/[^.]unpack\(/); const expectTableUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("table.unpack"); +const expectLualibUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("__TS__Unpack"); const arrayLiteralCases = [ "1, 2, ...[3, 4, 5]", @@ -72,6 +73,7 @@ describe("in function call", () => { return foo(...array); `, { + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), @@ -82,6 +84,7 @@ describe("in function call", () => { describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), From 6d200323eafe904aca6d9c39a35f4e64eb95af47 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 25 May 2020 23:37:06 +0500 Subject: [PATCH 272/764] Don't use lualib for .call and .apply (#884) * Don't use lualib for .call and .apply * Fix flaky array.join test --- src/LuaLib.ts | 6 +----- src/lualib/FunctionApply.ts | 7 ------- src/lualib/FunctionCall.ts | 3 --- src/transformation/builtins/function.ts | 9 +++++++-- .../unit/annotations/__snapshots__/forRange.spec.ts.snap | 5 +---- test/unit/builtins/array.spec.ts | 5 +++-- 6 files changed, 12 insertions(+), 23 deletions(-) delete mode 100644 src/lualib/FunctionApply.ts delete mode 100644 src/lualib/FunctionCall.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 52ecf550b..2c09e3c8e 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -31,9 +31,7 @@ export enum LuaLibFeature { Decorate = "Decorate", Descriptors = "Descriptors", Error = "Error", - FunctionApply = "FunctionApply", FunctionBind = "FunctionBind", - FunctionCall = "FunctionCall", Generator = "Generator", InstanceOf = "InstanceOf", InstanceOfObject = "InstanceOfObject", @@ -75,10 +73,8 @@ export enum LuaLibFeature { const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], - Error: [LuaLibFeature.New, LuaLibFeature.Class, LuaLibFeature.FunctionCall], - FunctionApply: [LuaLibFeature.Unpack], + Error: [LuaLibFeature.New, LuaLibFeature.Class], FunctionBind: [LuaLibFeature.Unpack], - FunctionCall: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], diff --git a/src/lualib/FunctionApply.ts b/src/lualib/FunctionApply.ts deleted file mode 100644 index 2638a43a8..000000000 --- a/src/lualib/FunctionApply.ts +++ /dev/null @@ -1,7 +0,0 @@ -function __TS__FunctionApply(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, args?: any[]): any { - if (args) { - return fn(thisArg, ...args); - } else { - return fn(thisArg); - } -} diff --git a/src/lualib/FunctionCall.ts b/src/lualib/FunctionCall.ts deleted file mode 100644 index 8435e7239..000000000 --- a/src/lualib/FunctionCall.ts +++ /dev/null @@ -1,3 +0,0 @@ -function __TS__FunctionCall(this: void, fn: (this: void, ...args: any[]) => any, thisArg: any, ...args: any[]): any { - return fn(thisArg, ...args); -} diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index 3ba8c2aaa..0d84e48a8 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -2,6 +2,7 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty, unsupportedSelfFunctionConversion } from "../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../utils/function-context"; +import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; @@ -21,11 +22,15 @@ export function transformFunctionPrototypeCall( const expressionName = expression.name.text; switch (expressionName) { case "apply": - return transformLuaLibFunction(context, LuaLibFeature.FunctionApply, node, caller, ...params); + return lua.createCallExpression( + caller, + [params[0], createUnpackCall(context, params[1], node.arguments[1])], + node + ); case "bind": return transformLuaLibFunction(context, LuaLibFeature.FunctionBind, node, caller, ...params); case "call": - return transformLuaLibFunction(context, LuaLibFeature.FunctionCall, node, caller, ...params); + return lua.createCallExpression(caller, params, node); default: context.diagnostics.push(unsupportedProperty(expression.name, "function", expressionName)); } diff --git a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap index 325c32be7..e752d0782 100644 --- a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap @@ -70,10 +70,7 @@ exports[`invalid usage reference ("let array = [0, luaRange, 1];"): code 1`] = ` exports[`invalid usage reference ("let array = [0, luaRange, 1];"): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = ` -"require(\\"lualib_bundle\\"); -__TS__FunctionCall(luaRange, nil, 0, 0, 0)" -`; +exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = `"luaRange(nil, 0, 0, 0)"`; exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): diagnostics 1`] = `"main.ts(6,13): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 075de32e9..44fe1fa0e 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -430,11 +430,12 @@ test.each([ }); test('array.join (1, "2", {})', () => { - util.testExpression`[1, "2", {}].join()`.expectToEqual("1,2,table: 0x168"); + const result = util.testExpression`[1, "2", {}].join()`.getLuaExecutionResult(); + expect(result).toMatch(/^1,2,table: 0x\d+$/); }); test('array.join (1, "2", Symbol("foo"))', () => { - util.testExpression`[1, "2", Symbol("foo")].join()`.expectToEqual("1,2,Symbol(foo)"); + util.testExpression`[1, "2", Symbol("foo")].join(", ")`.expectToEqual("1, 2, Symbol(foo)"); }); test("array.join without separator argument", () => { From a709c7d1f8ed168a7bc3cec2c84371f9215713c8 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 25 May 2020 23:38:42 +0500 Subject: [PATCH 273/764] Upgrade Prettier to v2 (#869) * Set "arrowParens" option to "always" * Upgrade Prettier to v2 * Revert "Set "arrowParens" option to "always"" This reverts commit 1f3a98123e63454efd4a7ca9bed2f57f2276631b. --- .prettierrc.json | 3 +-- package-lock.json | 6 +++--- package.json | 6 +++--- src/lualib/Error.ts | 2 +- src/lualib/Generator.ts | 2 +- src/transformation/utils/safe-names.ts | 9 +-------- src/transpilation/transpile.ts | 5 +---- src/tstl.ts | 5 +---- test/unit/builtins/console.spec.ts | 24 ++++++------------------ test/unit/builtins/math.spec.ts | 4 +--- test/unit/expressions.spec.ts | 4 +--- test/unit/json.spec.ts | 4 +--- test/unit/printer/sourcemaps.spec.ts | 10 ++-------- test/util.ts | 2 +- 14 files changed, 24 insertions(+), 62 deletions(-) diff --git a/.prettierrc.json b/.prettierrc.json index f8774a2f2..9dd6427dc 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -1,7 +1,6 @@ { "printWidth": 120, "tabWidth": 4, - "trailingComma": "es5", - "endOfLine": "lf", + "arrowParens": "avoid", "overrides": [{ "files": ["**/*.md", "**/*.yml"], "options": { "tabWidth": 2 } }] } diff --git a/package-lock.json b/package-lock.json index a8e0102ed..7d07d2f17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4336,9 +4336,9 @@ "dev": true }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index 4992ba80a..af51eb999 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,9 @@ "pretest": "npm run lint && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", - "lint:prettier": "prettier --check \"**/*.{js,ts,yml,json,md}\" || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", + "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint . --ext .js,.ts", - "fix:prettier": "prettier --check --write \"**/*.{js,ts,yml,json,md}\"", + "fix:prettier": "prettier --write .", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, @@ -57,7 +57,7 @@ "jest": "^25.1.0", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "prettier": "^1.19.1", + "prettier": "^2.0.5", "ts-jest": "^25.2.1", "ts-node": "^8.6.2" } diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index c91223f65..d44a3b9eb 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -21,7 +21,7 @@ function __TS__GetErrorStack(constructor: Function): string { } function __TS__WrapErrorToString(getDescription: (this: T) => string): (this: T) => string { - return function(this: Error): string { + return function (this: Error): string { const description = getDescription.call(this); const caller = debug.getinfo(3, "f"); if (_VERSION === "Lua 5.1" || (caller && caller.func !== error)) { diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index 37b639776..a71740761 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -19,7 +19,7 @@ function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { } function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { - return function(this: void, ...args: Vararg): GeneratorIterator { + return function (this: void, ...args: Vararg): GeneratorIterator { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index b10ed414f..c072135f4 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -99,13 +99,6 @@ export function hasUnsafeIdentifierName( } const fixInvalidLuaIdentifier = (name: string) => - name.replace( - /[^a-zA-Z0-9_]/g, - c => - `_${c - .charCodeAt(0) - .toString(16) - .toUpperCase()}` - ); + name.replace(/[^a-zA-Z0-9_]/g, c => `_${c.charCodeAt(0).toString(16).toUpperCase()}`); export const createSafeName = (name: string) => "____" + fixInvalidLuaIdentifier(name); diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 9046477e8..d024e8a09 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -142,10 +142,7 @@ export function transpile({ diagnostics.push(...program.emit(undefined, writeFile, undefined, false, transformers).diagnostics); // JSON files don't get through transformers and aren't written when outDir is the same as rootDir - program - .getSourceFiles() - .filter(isEmittableJsonFile) - .forEach(processSourceFile); + program.getSourceFiles().filter(isEmittableJsonFile).forEach(processSourceFile); } options.noEmit = oldNoEmit; diff --git a/src/tstl.ts b/src/tstl.ts index 00b6d7606..aab3feff2 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -202,10 +202,7 @@ function updateWatchCompilationHost( } function checkNodeVersion(): void { - const [major, minor] = process.version - .slice(1) - .split(".") - .map(Number); + const [major, minor] = process.version.slice(1).split(".").map(Number); const isValid = major > 12 || (major === 12 && minor >= 13); if (!isValid) { console.error(`TypeScriptToLua requires Node.js >=12.13.0, the current version is ${process.version}`); diff --git a/test/unit/builtins/console.spec.ts b/test/unit/builtins/console.spec.ts index 6cf4e6139..a68c1be5c 100644 --- a/test/unit/builtins/console.spec.ts +++ b/test/unit/builtins/console.spec.ts @@ -9,9 +9,7 @@ test.each([ 'console.log("Hello %%s", "there")', 'console.log("Hello", "There")', ])("console.log (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test.each([ @@ -21,9 +19,7 @@ test.each([ 'console.info("Hello %%s", "there")', 'console.info("Hello", "There")', ])("console.info (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test.each([ @@ -33,9 +29,7 @@ test.each([ 'console.error("Hello %%s", "there")', 'console.error("Hello", "There")', ])("console.error (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test.each([ @@ -45,9 +39,7 @@ test.each([ 'console.warn("Hello %%s", "there")', 'console.warn("Hello", "There")', ])("console.warn (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test.each([ @@ -57,9 +49,7 @@ test.each([ 'console.trace("Hello %%s", "there")', 'console.trace("Hello", "there")', ])("console.trace (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test.each([ @@ -69,9 +59,7 @@ test.each([ 'console.assert(false, "message %%s", "info")', 'console.assert(false, "message", "more")', ])("console.assert (%p)", code => { - util.testFunction(code) - .setOptions(compilerOptions) - .expectLuaToMatchSnapshot(); + util.testFunction(code).setOptions(compilerOptions).expectLuaToMatchSnapshot(); }); test("console.differentiation", () => { diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 4d95e4afb..faaeacbcd 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -14,9 +14,7 @@ test.each([ "Math.PI", ])("%s", code => { // TODO: Remove? - util.testFunction(code) - .disableSemanticCheck() - .expectLuaToMatchSnapshot(); + util.testFunction(code).disableSemanticCheck().expectLuaToMatchSnapshot(); }); test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s", constant => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 25f4c20ed..6720fe8fb 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -15,9 +15,7 @@ test.each([ "let a = delete tbl.test", "delete tbl.test", ])("Unary expressions basic (%p)", input => { - util.testFunction(input) - .disableSemanticCheck() - .expectLuaToMatchSnapshot(); + util.testFunction(input).disableSemanticCheck().expectLuaToMatchSnapshot(); }); test.each(["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"])("Binary expressions basic numeric (%p)", input => { diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts index b61e64fd1..2f4b0d6a5 100644 --- a/test/unit/json.spec.ts +++ b/test/unit/json.spec.ts @@ -1,9 +1,7 @@ import * as util from "../util"; test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { - util.testModule(JSON.stringify(json)) - .setMainFileName("main.json") - .expectToEqual(json); + util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); }); test("Empty JSON file error", () => { diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 6b4487ac9..96ffec05f 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -144,10 +144,7 @@ test.each([ ], }, ])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { - const file = util - .testModule(code) - .expectToHaveNoDiagnostics() - .getMainLuaFileResult(); + const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.sourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { @@ -228,10 +225,7 @@ test.each([ { code: "class $$$ {}", name: "$$$" }, { code: 'namespace $$$ { const foo = "bar"; }', name: "$$$" }, ])("Source map has correct name mappings (%p)", async ({ code, name }) => { - const file = util - .testModule(code) - .expectToHaveNoDiagnostics() - .getMainLuaFileResult(); + const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.sourceMap); const typescriptPosition = lineAndColumnOf(code, name); diff --git a/test/util.ts b/test/util.ts index a24ce29a1..ee8b8e892 100644 --- a/test/util.ts +++ b/test/util.ts @@ -150,7 +150,7 @@ function executeJsModule(code: string): any { const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); - descriptor.value = function(this: any, ...args: any[]): any { + descriptor.value = function (this: any, ...args: any[]): any { if (!memoized.has(this)) { memoized.set(this, originalFunction.apply(this, args)); } From d82cf8d400e8bb288be44c6bb4187338fea2da21 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 25 May 2020 20:53:04 +0200 Subject: [PATCH 274/764] Dependencies upgrade --- package-lock.json | 4724 ++++++++++++++++++++++++++++++++++++++------- package.json | 4 +- 2 files changed, 4024 insertions(+), 704 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7d07d2f17..8ce991867 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,28 +14,97 @@ } }, "@babel/core": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", - "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.4", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", + "json5": "^2.1.2", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "dependencies": { + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -84,12 +153,171 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, "@babel/helper-plugin-utils": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, + "@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + }, + "dependencies": { + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", @@ -99,15 +327,86 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", "dev": true, "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + }, + "dependencies": { + "@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true + }, + "@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, "@babel/highlight": { @@ -179,6 +478,15 @@ "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", "dev": true }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, "@babel/plugin-syntax-bigint": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", @@ -188,6 +496,51 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", + "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", + "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", @@ -197,6 +550,24 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, "@babel/template": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", @@ -250,24 +621,17 @@ "requires": { "exec-sh": "^0.3.2", "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } } }, "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "requires": { "camelcase": "^5.3.1", "find-up": "^4.1.0", + "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" } @@ -279,142 +643,796 @@ "dev": true }, "@jest/console": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", - "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@jest/source-map": "^25.1.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-util": "^25.1.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "@jest/core": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz", - "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", + "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", "dev": true, "requires": { - "@jest/console": "^25.1.0", - "@jest/reporters": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", + "@jest/console": "^26.0.1", + "@jest/reporters": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", + "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-changed-files": "^25.1.0", - "jest-config": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-resolve-dependencies": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "jest-watcher": "^25.1.0", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.0.1", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-resolve-dependencies": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "jest-watcher": "^26.0.1", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", - "realpath-native": "^1.1.0", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + } + }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true - } - } - }, - "@jest/environment": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz", - "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==", - "dev": true, - "requires": { - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0" - } - }, - "@jest/fake-timers": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz", - "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==", - "dev": true, - "requires": { - "@jest/types": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0", - "lolex": "^5.0.0" - } - }, - "@jest/reporters": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", - "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } + } + }, + "@jest/globals": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", + "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "dev": true, + "requires": { + "@jest/environment": "^26.0.1", + "@jest/types": "^26.0.1", + "expect": "^26.0.1" + }, + "dependencies": { + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "@jest/reporters": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", + "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", + "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^4.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "jest-haste-map": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", - "node-notifier": "^6.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", - "string-length": "^3.1.0", + "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.0.1" + "v8-to-istanbul": "^4.1.3" }, "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } } } }, "@jest/source-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", - "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", + "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", "dev": true, "requires": { "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", + "graceful-fs": "^4.2.4", "source-map": "^0.6.0" }, "dependencies": { "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "source-map": { @@ -426,60 +1444,213 @@ } }, "@jest/test-result": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", - "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/console": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "@jest/test-sequencer": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", - "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", - "dev": true, - "requires": { - "@jest/test-result": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0" - } - }, - "@jest/transform": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", - "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", + "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.1.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", + "@jest/test-result": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1" + }, + "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "@jest/transform": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", + "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.0.1", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-util": "^25.1.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.0.1", "micromatch": "^4.0.2", "pirates": "^4.0.1", - "realpath-native": "^1.1.0", "slash": "^3.0.0", "source-map": "^0.6.1", "write-file-atomic": "^3.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -501,18 +1672,27 @@ } }, "@sinonjs/commons": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.1.tgz", - "integrity": "sha512-Debi3Baff1Qu1Unc3mjJ96MgpbwTn43S1+9yJ0llWygPwDNu2aaWBD6yc9y/Z8XDRNhx7U+u2UDg2OGQXkclUQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", "dev": true, "requires": { "type-detect": "4.0.8" } }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@types/babel__core": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.6.tgz", - "integrity": "sha512-tTnhWszAqvXnhW7m5jQU9PomXSiKXk2sFxpahXvI20SZKu9ylPi8WtIxueZ6ehDWikPT0jeFujMj3X4ZHuf3Tg==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", + "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -542,9 +1722,9 @@ } }, "@types/babel__traverse": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", - "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", + "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -588,6 +1768,15 @@ "@types/node": "*" } }, + "@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", @@ -641,6 +1830,18 @@ "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, "@types/resolve": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", @@ -833,27 +2034,19 @@ "dev": true }, "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", "dev": true }, "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", - "dev": true - } + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, "acorn-jsx": { @@ -863,9 +2056,9 @@ "dev": true }, "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", "dev": true }, "ajv": { @@ -956,12 +2149,6 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, "array-includes": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", @@ -1035,24 +2222,55 @@ "dev": true }, "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "dev": true }, "babel-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", - "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", + "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", "dev": true, "requires": { - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/babel__core": "^7.1.0", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.1.0", - "chalk": "^3.0.0", + "babel-preset-jest": "^26.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } } }, "babel-plugin-istanbul": { @@ -1069,23 +2287,42 @@ } }, "babel-plugin-jest-hoist": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", - "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", + "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", "dev": true, "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", "@types/babel__traverse": "^7.0.6" } }, + "babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, "babel-preset-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", - "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", + "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", "dev": true, "requires": { - "@babel/plugin-syntax-bigint": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^25.1.0" + "babel-plugin-jest-hoist": "^26.0.0", + "babel-preset-current-node-syntax": "^0.1.2" } }, "balanced-match": { @@ -1178,9 +2415,9 @@ } }, "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, "browser-resolve": { @@ -1278,6 +2515,12 @@ "supports-color": "^7.1.0" } }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", @@ -1346,9 +2589,9 @@ "dev": true }, "collect-v8-coverage": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz", - "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, "collection-visit": { @@ -1444,9 +2687,9 @@ "dev": true }, "cssstyle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", - "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, "requires": { "cssom": "~0.3.6" @@ -1470,14 +2713,14 @@ } }, "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" } }, "debug": { @@ -1495,6 +2738,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, "decode-uri-component": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", @@ -1507,6 +2756,12 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -1591,12 +2846,20 @@ } }, "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, "requires": { - "webidl-conversions": "^4.0.2" + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } } }, "ecc-jsbn": { @@ -2150,17 +3413,79 @@ } }, "expect": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.1.0.tgz", - "integrity": "sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-styles": "^4.0.0", - "jest-get-type": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-regex-util": "^25.1.0" + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } } }, "extend": { @@ -2433,9 +3758,9 @@ "dev": true }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, @@ -2463,6 +3788,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", @@ -2625,18 +3956,18 @@ "dev": true }, "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "requires": { - "whatwg-encoding": "^1.0.1" + "whatwg-encoding": "^1.0.5" } }, "html-escaper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, "http-signature": { @@ -2840,6 +4171,13 @@ } } }, + "is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true + }, "is-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -2888,6 +4226,12 @@ "isobject": "^3.0.1" } }, + "is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", @@ -2937,11 +4281,14 @@ "dev": true }, "is-wsl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", - "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, - "optional": true + "optional": true, + "requires": { + "is-docker": "^2.0.0" + } }, "isarray": { "version": "1.0.0", @@ -2974,15 +4321,12 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", - "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.0.0", "semver": "^6.3.0" @@ -3027,9 +4371,9 @@ } }, "istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", "dev": true, "requires": { "html-escaper": "^2.0.0", @@ -3043,54 +4387,173 @@ "dev": true }, "jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", - "integrity": "sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", + "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", "dev": true, "requires": { - "@jest/core": "^25.1.0", + "@jest/core": "^26.0.1", "import-local": "^3.0.2", - "jest-cli": "^25.1.0" + "jest-cli": "^26.0.1" }, "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "jest-cli": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.1.0.tgz", - "integrity": "sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", + "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", "dev": true, "requires": { - "@jest/core": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", + "@jest/core": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", "exit": "^0.1.2", + "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", + "jest-config": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^15.0.0" + "yargs": "^15.3.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" } } } }, "jest-changed-files": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.1.0.tgz", - "integrity": "sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", + "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", "dev": true, "requires": { - "@jest/types": "^25.1.0", - "execa": "^3.2.0", + "@jest/types": "^26.0.1", + "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { "path-key": "^3.1.0", @@ -3099,9 +4562,9 @@ } }, "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", + "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -3111,7 +4574,6 @@ "merge-stream": "^2.0.0", "npm-run-path": "^4.0.0", "onetime": "^5.1.0", - "p-finally": "^2.0.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" } @@ -3140,12 +4602,6 @@ "path-key": "^3.0.0" } }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", - "dev": true - }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -3203,28 +4659,164 @@ } }, "jest-config": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.1.0.tgz", - "integrity": "sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", + "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.1.0", - "@jest/types": "^25.1.0", - "babel-jest": "^25.1.0", - "chalk": "^3.0.0", + "@jest/test-sequencer": "^26.0.1", + "@jest/types": "^26.0.1", + "babel-jest": "^26.0.1", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", "glob": "^7.1.1", - "jest-environment-jsdom": "^25.1.0", - "jest-environment-node": "^25.1.0", - "jest-get-type": "^25.1.0", - "jest-jasmine2": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.0.1", + "jest-environment-node": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", "micromatch": "^4.0.2", - "pretty-format": "^25.1.0", - "realpath-native": "^1.1.0" + "pretty-format": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "jest-diff": { @@ -3240,52 +4832,298 @@ } }, "jest-docblock": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.1.0.tgz", - "integrity": "sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", - "integrity": "sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-get-type": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } } }, "jest-environment-jsdom": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz", - "integrity": "sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", + "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", "dev": true, "requires": { - "@jest/environment": "^25.1.0", - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0", - "jsdom": "^15.1.1" + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1", + "jsdom": "^16.2.2" + }, + "dependencies": { + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } } }, "jest-environment-node": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.1.0.tgz", - "integrity": "sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", + "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", "dev": true, "requires": { - "@jest/environment": "^25.1.0", - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0" + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "dependencies": { + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } } }, "jest-get-type": { @@ -3295,102 +5133,540 @@ "dev": true }, "jest-haste-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", - "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", + "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^26.0.1", + "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.0.0", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7" + "walker": "^1.0.7", + "which": "^2.0.2" }, "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, "jest-jasmine2": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz", - "integrity": "sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", + "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.1.0", - "@jest/source-map": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", + "@jest/environment": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^25.1.0", + "expect": "^26.0.1", "is-generator-fn": "^2.0.0", - "jest-each": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0", + "jest-each": "^26.0.1", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1", "throat": "^5.0.0" - } - }, - "jest-leak-detector": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz", - "integrity": "sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w==", - "dev": true, - "requires": { - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-message-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", - "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz", - "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==", + }, + "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-each": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", + "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "jest-leak-detector": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", + "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", "dev": true, "requires": { - "@jest/types": "^25.1.0" + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } + } + }, + "jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + } } }, "jest-pnp-resolver": { @@ -3400,190 +5676,1246 @@ "dev": true }, "jest-regex-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", - "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true }, "jest-resolve": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", - "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "browser-resolve": "^1.11.3", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "jest-resolve-dependencies": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz", - "integrity": "sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", + "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", "dev": true, "requires": { - "@jest/types": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-snapshot": "^25.1.0" + "@jest/types": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } } }, "jest-runner": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.1.0.tgz", - "integrity": "sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", + "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", "dev": true, "requires": { - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-config": "^25.1.0", - "jest-docblock": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-jasmine2": "^25.1.0", - "jest-leak-detector": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.0.1", + "jest-jasmine2": "^26.0.1", + "jest-leak-detector": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } } } }, "jest-runtime": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.1.0.tgz", - "integrity": "sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA==", - "dev": true, - "requires": { - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/source-map": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", + "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/globals": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", + "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.3", - "jest-config": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "realpath-native": "^1.1.0", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", "slash": "^3.0.0", "strip-bom": "^4.0.0", - "yargs": "^15.0.0" + "yargs": "^15.3.1" + }, + "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + } + }, + "@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + } + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1" + } + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + } + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "jest-serializer": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", + "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" }, "dependencies": { "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true } } }, - "jest-serializer": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", - "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==", - "dev": true - }, "jest-snapshot": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz", - "integrity": "sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A==", + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", "chalk": "^3.0.0", - "expect": "^25.1.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "mkdirp": "^0.5.1", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", "natural-compare": "^1.4.0", - "pretty-format": "^25.1.0", - "semver": "^7.1.1" + "pretty-format": "^25.5.0", + "semver": "^6.3.0" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, "semver": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.3.tgz", - "integrity": "sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "jest-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", - "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "mkdirp": "^0.5.1" + "make-dir": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } } }, "jest-validate": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.1.0.tgz", - "integrity": "sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", "dev": true, "requires": { - "@jest/types": "^25.1.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.1.0", + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", "leven": "^3.1.0", - "pretty-format": "^25.1.0" + "pretty-format": "^26.0.1" + }, + "dependencies": { + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true + }, + "pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + } } }, "jest-watcher": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", - "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==", + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", + "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", "dev": true, "requires": { - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "string-length": "^3.1.0" + "chalk": "^4.0.0", + "jest-util": "^26.0.1", + "string-length": "^4.0.1" + }, + "dependencies": { + "@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + } + }, + "@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "requires": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + } + }, + "jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "requires": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } } }, "jest-worker": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", - "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", "dev": true, "requires": { "merge-stream": "^2.0.0", @@ -3613,36 +6945,36 @@ "dev": true }, "jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", + "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.0.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", "xml-name-validator": "^3.0.0" } }, @@ -3652,6 +6984,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", @@ -3677,20 +7015,12 @@ "dev": true }, "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "minimist": "^1.2.5" } }, "jsonfile": { @@ -3742,6 +7072,12 @@ "type-check": "~0.3.2" } }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", @@ -3805,9 +7141,9 @@ "dev": true }, "make-dir": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", - "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "requires": { "semver": "^6.0.0" @@ -3868,18 +7204,18 @@ } }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", "dev": true }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "mimic-fn": { @@ -3898,9 +7234,9 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "mixin-deep": { @@ -3925,12 +7261,12 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -3989,25 +7325,36 @@ "dev": true }, "node-notifier": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", - "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", "dev": true, "optional": true, "requires": { "growly": "^1.3.0", "is-wsl": "^2.1.1", - "semver": "^6.3.0", + "semver": "^7.2.1", "shellwords": "^0.1.1", - "which": "^1.3.1" + "uuid": "^7.0.3", + "which": "^2.0.2" }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true, "optional": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -4114,16 +7461,6 @@ "object-keys": "^1.0.11" } }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, "object.pick": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", @@ -4238,9 +7575,9 @@ } }, "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", "dev": true }, "pascalcase": { @@ -4288,9 +7625,9 @@ "dev": true }, "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, "pify": { @@ -4317,12 +7654,6 @@ "find-up": "^4.0.0" } }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -4360,9 +7691,9 @@ "dev": true }, "prompts": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.1.tgz", - "integrity": "sha512-qIP2lQyCwYbdzcqHIUi2HAxiWixhoM9OdLCWf8txXsapC/X9YdsCoeyRIXE/GP+Q0J37Q7+XN/MFqbUa7IzXNA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", "dev": true, "requires": { "kleur": "^3.0.3", @@ -4370,9 +7701,9 @@ } }, "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "pump": { @@ -4482,13 +7813,10 @@ "dev": true }, "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "dev": true, - "requires": { - "util.promisify": "^1.0.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true }, "regex-not": { "version": "1.0.2", @@ -4561,6 +7889,12 @@ "psl": "^1.1.28", "punycode": "^2.1.1" } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true } } }, @@ -4827,12 +8161,6 @@ "to-regex": "^3.0.2" } }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, "normalize-path": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", @@ -4855,12 +8183,12 @@ } }, "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "requires": { - "xmlchars": "^2.1.1" + "xmlchars": "^2.2.0" } }, "semver": { @@ -4927,9 +8255,9 @@ "dev": true }, "sisteransi": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", - "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true }, "slash": { @@ -5249,30 +8577,13 @@ "dev": true }, "string-length": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", - "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", "dev": true, "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" } }, "string-width": { @@ -5529,18 +8840,18 @@ } }, "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", "dev": true, "requires": { - "punycode": "^2.1.0" + "punycode": "^2.1.1" } }, "ts-jest": { - "version": "25.2.1", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-25.2.1.tgz", - "integrity": "sha512-TnntkEEjuXq/Gxpw7xToarmHbAafgCaAzOpnajnFC6jI7oo1trMzAHA04eWpc3MhV6+yvhE8uUBAmN+teRJh0A==", + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz", + "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==", "dev": true, "requires": { "bs-logger": "0.x", @@ -5549,10 +8860,24 @@ "json5": "2.x", "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "0.x", - "resolve": "1.x", - "semver": "^5.5", - "yargs-parser": "^16.1.0" + "micromatch": "4.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "18.x" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + } } }, "ts-node": { @@ -5712,23 +9037,12 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "dev": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "optional": true }, "v8-compile-cache": { "version": "2.1.0", @@ -5737,9 +9051,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.2.tgz", - "integrity": "sha512-G9R+Hpw0ITAmPSr47lSlc5A1uekSYzXxTMlFxso2xoffwo4jQnzbv1p9yXIinO8UMZKfAFewaCHwWvnH4Jb4Ug==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -5769,22 +9083,20 @@ } }, "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, "requires": { - "browser-process-hrtime": "^0.1.2" + "browser-process-hrtime": "^1.0.0" } }, "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "dev": true, "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", "xml-name-validator": "^3.0.0" } }, @@ -5798,9 +9110,9 @@ } }, "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", "dev": true }, "whatwg-encoding": { @@ -5819,14 +9131,22 @@ "dev": true }, "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } } }, "which": { @@ -5889,9 +9209,9 @@ } }, "ws": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", - "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", "dev": true }, "xml-name-validator": { @@ -5913,9 +9233,9 @@ "dev": true }, "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", - "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -5928,13 +9248,13 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" + "yargs-parser": "^18.1.1" } }, "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index af51eb999..624bac351 100644 --- a/package.json +++ b/package.json @@ -54,11 +54,11 @@ "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^25.1.0", + "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "prettier": "^2.0.5", - "ts-jest": "^25.2.1", + "ts-jest": "^26.0.0", "ts-node": "^8.6.2" } } From d2c187cc5074b8f5994bba0fdc65bd2c61554e54 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 25 May 2020 21:13:56 +0200 Subject: [PATCH 275/764] 0.34.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ce991867..006e8b177 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.33.0", + "version": "0.34.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 624bac351..57044a644 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.33.0", + "version": "0.34.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 9ee609113bd8cb0096ea26e0a9f334bfea389b8e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 25 May 2020 21:46:38 +0200 Subject: [PATCH 276/764] Changelog 0.34.0 --- CHANGELOG.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b4a14b1d..0a5842b0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,37 +1,39 @@ # Changelog -## Unreleased +## 0.34.0 -- Added new `"luaTarget"` option value - `"universal"`. Choosing this target would make TypeScriptToLua generate code compatible with all supported Lua targets. - - **BREAKING CHANGE:** This is a new default target. If you have been depending on LuaJIT being chosen implicitly, now you have to enable it explicitly with `"luaTarget": "JIT"` in the `tsconfig.json` file. +- Added new `"luaTarget"` option value - `"universal"`. Choosing this target makes TypeScriptToLua generate code compatible with all supported Lua targets. - + - **BREAKING CHANGE:** This is a new default target. If you have been depending on LuaJIT being chosen implicitly, you now have to enable it explicitly with `"luaTarget": "JIT"` in the `tsconfig.json` file. -- TypeScript has been updated to 3.9. See [release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/) for details. This update includes some fixes specific to our API usage: +- TypeScript has been updated to **3.9**. See [release notes](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html) for details. This update includes some fixes specific to our API usage: - Importing a non-module using `import "./file"` produced a TS2307 error [#35973](https://github.com/microsoft/TypeScript/issues/35973) - - TypeScript now tries to find a call signature even in presence of type errors (#36665)(https://github.com/microsoft/TypeScript/pull/36665): + - TypeScript now tries to find a call signature even in presence of type errors [#36665](https://github.com/microsoft/TypeScript/pull/36665): ```ts function foo(this: void, x: string) {} foo(1); ``` ```lua - -- 3.8 + -- Before: with 3.8 (this: void ignored due to signature mismatch) foo(nil, 1) - -- 3.9 + -- Now: with 3.9 foo(1) ``` - Reduced memory consumption and optimized performance of generators and iterators - - Fixed generator syntax being ignored on methods (`*foo() {}`) and function expressions (`function*() {}`) - - Fixed iteration over generators stopping at first yielded `nil` value - - Fixed `Array.prototype.join` throwing an error when array contains anything other than strings and numbers - - Fixed extending a class not keeping `toString` implementation from a super class +- Fixed issue where CLI arguments were incorrectly removed. +- Fixed issue where class accessors threw an error due to a missing dependency. + +Under the hood: + +- Upgraded to Prettier 2.0 + ## 0.33.0 - Added support for nullish coalescing `A ?? B`. From 45aaac635160b63156614af3b98e80005bfe867f Mon Sep 17 00:00:00 2001 From: Chris Bajorin Date: Mon, 1 Jun 2020 07:43:54 -0400 Subject: [PATCH 277/764] added top level export parseConfigFileWithSystem (#888) Co-authored-by: Chris Bajorin --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index c828369df..3d060a994 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ export { version } from "./cli/information"; export { parseCommandLine, ParsedCommandLine, updateParsedConfigFile } from "./cli/parse"; export * from "./cli/report"; +export { parseConfigFileWithSystem } from "./cli/tsconfig"; export * from "./CompilerOptions"; export * from "./LuaAST"; export { LuaLibFeature } from "./LuaLib"; From 03fae3506ecf49b913c80df56ac349c423e5f209 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 1 Jun 2020 16:45:38 +0500 Subject: [PATCH 278/764] Implement `function.length` (#889) * Implement `function.length` * Add diagnostic on Lua 5.1 target * Add changelog * Remove outdated snapshots --- CHANGELOG.md | 4 +++ src/transformation/builtins/function.ts | 32 ++++++++++++++++++- src/transformation/builtins/index.ts | 6 +++- .../__snapshots__/functions.spec.ts.snap | 24 ++++++++++++++ test/unit/functions/functions.spec.ts | 27 ++++++++++++++++ 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a5842b0a..5ebfb096c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- `Function.length` is supported now + ## 0.34.0 - Added new `"luaTarget"` option value - `"universal"`. Choosing this target makes TypeScriptToLua generate code compatible with all supported Lua targets. diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index 0d84e48a8..f6cb8a6a0 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -1,6 +1,8 @@ +import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { unsupportedProperty, unsupportedSelfFunctionConversion } from "../utils/diagnostics"; +import { unsupportedForTarget, unsupportedProperty, unsupportedSelfFunctionConversion } from "../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; @@ -35,3 +37,31 @@ export function transformFunctionPrototypeCall( context.diagnostics.push(unsupportedProperty(expression.name, "function", expressionName)); } } + +export function transformFunctionProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { + switch (node.name.text) { + case "length": + if (context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Universal) { + context.diagnostics.push(unsupportedForTarget(node, "function.length", LuaTarget.Lua51)); + } + + // debug.getinfo(fn) + const getInfoCall = lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("debug"), lua.createStringLiteral("getinfo")), + [context.transformExpression(node.expression)] + ); + + const nparams = lua.createTableIndexExpression(getInfoCall, lua.createStringLiteral("nparams")); + + const contextType = getFunctionContextType(context, context.checker.getTypeAtLocation(node.expression)); + return contextType === ContextType.NonVoid + ? lua.createBinaryExpression(nparams, lua.createNumericLiteral(1), lua.SyntaxKind.SubtractionOperator) + : nparams; + + default: + context.diagnostics.push(unsupportedProperty(node.name, "function", node.name.text)); + } +} diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index f6be3c0f2..352ac9c2f 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -16,7 +16,7 @@ import { PropertyCallExpression } from "../visitors/call"; import { checkForLuaLibType } from "../visitors/class/new"; import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; -import { transformFunctionPrototypeCall } from "./function"; +import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { transformGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; @@ -38,6 +38,10 @@ export function transformBuiltinPropertyAccessExpression( return transformArrayProperty(context, node); } + if (isFunctionType(context, ownerType)) { + return transformFunctionProperty(context, node); + } + if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { switch (node.expression.text) { case "Math": diff --git a/test/unit/functions/__snapshots__/functions.spec.ts.snap b/test/unit/functions/__snapshots__/functions.spec.ts.snap index e1e5b49d2..345e31731 100644 --- a/test/unit/functions/__snapshots__/functions.spec.ts.snap +++ b/test/unit/functions/__snapshots__/functions.spec.ts.snap @@ -1,5 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`function.length unsupported ("5.1"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function fn(self) + end + return debug.getinfo(fn).nparams - 1 +end +return ____exports" +`; + +exports[`function.length unsupported ("5.1"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; + +exports[`function.length unsupported ("universal"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function fn(self) + end + return debug.getinfo(fn).nparams - 1 +end +return ____exports" +`; + +exports[`function.length unsupported ("universal"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; + exports[`missing declaration name: code 1`] = ` "function ____(self) end" diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 7e4aa6a08..20f76e273 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -1,4 +1,6 @@ +import * as tstl from "../../../src"; import * as util from "../../util"; +import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; test("Arrow Function Expression", () => { util.testFunction` @@ -185,6 +187,31 @@ test("Function call", () => { `.expectToMatchJsResult(); }); +test.each([ + "function fn() {}", + "function fn(x, y, z) {}", + "function fn(x, y, z, ...args) {}", + "function fn(...args) {}", + "function fn(this: void) {}", + "function fn(this: void, x, y, z) {}", + "function fnReference(x, y, z) {} const fn = fnReference;", + "const wrap = (fn: (...args: any[]) => any) => (...args: any[]) => fn(...args); const fn = wrap((x, y, z) => {});", +])("function.length (%p)", declaration => { + util.testFunction` + ${declaration} + return fn.length; + `.expectToMatchJsResult(); +}); + +test.each([tstl.LuaTarget.Lua51, tstl.LuaTarget.Universal])("function.length unsupported (%p)", luaTarget => { + util.testFunction` + function fn() {} + return fn.length; + ` + .setOptions({ luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + test("Recursive function definition", () => { util.testFunction` function f() { return typeof f; }; From fddc544d69b5efad7779e2e7249c6964d55e4408 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 9 Jun 2020 21:57:17 +0500 Subject: [PATCH 279/764] Make strings iterable (#891) * Make strings iterable * Add changelog --- src/lualib/Iterator.ts | 11 ++++++++++- test/unit/loops.spec.ts | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 897d4a7a2..e55de6404 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -16,16 +16,25 @@ function __TS__IteratorIteratorStep(this: Iterator): [true, T] | [] { return [true, result.value]; } +/** @tupleReturn */ +function __TS__IteratorStringStep(this: string, index: number): [number, string] | [] { + index += 1; + if (index > this.length) return []; + return [index, string.sub(this, index, index)]; +} + /** @tupleReturn */ function __TS__Iterator( this: void, iterable: Iterable | GeneratorIterator | readonly T[] -): [(...args: any[]) => [any, T] | [], ...any[]] { +): [(...args: any[]) => [any, any] | [], ...any[]] { if ("____coroutine" in iterable) { return [__TS__IteratorGeneratorStep, iterable]; } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; + } else if (typeof iterable === "string") { + return [__TS__IteratorStringStep, iterable, 0]; } else { return ipairs(iterable as readonly T[]) as any; } diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 0959d31b8..b35bbd767 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -442,6 +442,16 @@ test("forof with array typed as iterable", () => { `.expectToMatchJsResult(); }); +test.each(["", "abc", "a\0c"])("forof string (%p)", string => { + util.testFunctionTemplate` + const results: string[] = []; + for (const x of ${string}) { + results.push(x); + } + return results; + `.expectToMatchJsResult(); +}); + describe("for...of empty destructuring", () => { const declareTests = (destructuringPrefix: string) => { test("array", () => { From f0410e0419a6078747006168cfa94268354a2713 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 10 Jun 2020 21:13:41 +0500 Subject: [PATCH 280/764] Fix incorrectly escaped `string.replace` replace value (#892) * Fix incorrectly escaped `string.replace` replace value * Add test with escaped char in search value and re-add removed test --- CHANGELOG.md | 2 ++ src/lualib/StringReplace.ts | 2 +- test/unit/builtins/string.spec.ts | 6 ++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ebfb096c..044cba2e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ - `Function.length` is supported now +- Fixed `string.replace` incorrectly escaping some `replaceValue` characters (`().+-*?[^$`) + ## 0.34.0 - Added new `"luaTarget"` option value - `"universal"`. Choosing this target makes TypeScriptToLua generate code compatible with all supported Lua targets. diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index 7a22992ed..51a093bef 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -7,7 +7,7 @@ function __TS__StringReplace( [searchValue] = string.gsub(searchValue, "[%%%(%)%.%+%-%*%?%[%^%$]", "%%%1"); if (typeof replaceValue === "string") { - [replaceValue] = string.gsub(replaceValue, "[%%%(%)%.%+%-%*%?%[%^%$]", "%%%1"); + [replaceValue] = string.gsub(replaceValue, "%%", "%%%%"); const [result] = string.gsub(source, searchValue, replaceValue, 1); return result; } else { diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index b0139e1a0..ddc61130e 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -56,10 +56,12 @@ test.each([ { inp: "hello test", searchValue: "test", replaceValue: "" }, { inp: "hello test", searchValue: "test", replaceValue: "world" }, { inp: "hello test", searchValue: "test", replaceValue: "%world" }, + { inp: "hello test", searchValue: "test", replaceValue: "." }, { inp: "hello %test", searchValue: "test", replaceValue: "world" }, { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, - { inp: "hello test", searchValue: "test", replaceValue: (): string => "a" }, - { inp: "hello test", searchValue: "test", replaceValue: (): string => "%a" }, + { inp: "hello test.", searchValue: ".", replaceValue: "$" }, + { inp: "hello test", searchValue: "test", replaceValue: () => "a" }, + { inp: "hello test", searchValue: "test", replaceValue: () => "%a" }, { inp: "aaa", searchValue: "a", replaceValue: "b" }, ])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { util.testExpression`"${inp}".replace(${util.formatCode(searchValue, replaceValue)})`.expectToMatchJsResult(); From cd2932e2aa9325e4bd4e088a1962c9217869478a Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 2 Jul 2020 18:15:50 +0200 Subject: [PATCH 281/764] Added __TS__Class as dependecy of (Weak)Map/Set (#901) --- src/LuaLib.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 2c09e3c8e..fd70ed5ec 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -79,10 +79,10 @@ const luaLibDependencies: Partial> = { InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], - Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], - Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], - WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], - WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol], + Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], + Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], + WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], + WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], SymbolRegistry: [LuaLibFeature.Symbol], }; From 0d7c5cd7bf4651feb3b5cee11942b4de174d50c1 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Mon, 13 Jul 2020 23:04:29 +0500 Subject: [PATCH 282/764] Fix some string operations (#895) * Fix string.slice, string.substring, string.substr * Fix string.charAt and string.charCodeAt * Fix string.indexOf with negative indexes * Fix out-of-bounds string access being "" instead of undefined * Fix array.join flacky test * Feedback * Replace createExpressionPlusOne with more general addToNumericExpression --- src/LuaLib.ts | 6 ++ src/lualib/StringAccess.ts | 5 ++ src/lualib/StringCharAt.ts | 5 ++ src/lualib/StringCharCodeAt.ts | 5 ++ src/lualib/StringPadEnd.ts | 2 +- src/lualib/StringPadStart.ts | 2 +- src/lualib/StringSlice.ts | 9 +++ src/lualib/StringSubstr.ts | 12 ++++ src/lualib/StringSubstring.ts | 17 +++++ src/lualib/declarations/string.d.ts | 4 ++ src/transformation/builtins/index.ts | 8 +-- src/transformation/builtins/string.ts | 97 +++++++++++++++++---------- src/transformation/utils/lua-ast.ts | 43 ++++++++++-- src/transformation/visitors/access.ts | 61 +++++------------ test/unit/builtins/array.spec.ts | 2 +- test/unit/builtins/string.spec.ts | 78 +++++++++++++-------- 16 files changed, 233 insertions(+), 123 deletions(-) create mode 100644 src/lualib/StringAccess.ts create mode 100644 src/lualib/StringCharAt.ts create mode 100644 src/lualib/StringCharCodeAt.ts create mode 100644 src/lualib/StringSlice.ts create mode 100644 src/lualib/StringSubstr.ts create mode 100644 src/lualib/StringSubstring.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index fd70ed5ec..c476882c7 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -54,13 +54,19 @@ export enum LuaLibFeature { WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", Spread = "Spread", + StringAccess = "StringAccess", + StringCharAt = "StringCharAt", + StringCharCodeAt = "StringCharCodeAt", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", StringPadEnd = "StringPadEnd", StringPadStart = "StringPadStart", StringReplace = "StringReplace", + StringSlice = "StringSlice", StringSplit = "StringSplit", StringStartsWith = "StringStartsWith", + StringSubstr = "StringSubstr", + StringSubstring = "StringSubstring", StringTrim = "StringTrim", StringTrimEnd = "StringTrimEnd", StringTrimStart = "StringTrimStart", diff --git a/src/lualib/StringAccess.ts b/src/lualib/StringAccess.ts new file mode 100644 index 000000000..8695fd4e7 --- /dev/null +++ b/src/lualib/StringAccess.ts @@ -0,0 +1,5 @@ +function __TS__StringAccess(this: string, index: number) { + if (index >= 0 && index < this.length) { + return string.sub(this, index + 1, index + 1); + } +} diff --git a/src/lualib/StringCharAt.ts b/src/lualib/StringCharAt.ts new file mode 100644 index 000000000..3c0e5161f --- /dev/null +++ b/src/lualib/StringCharAt.ts @@ -0,0 +1,5 @@ +function __TS__StringCharAt(this: string, pos: number): string { + if (pos !== pos) pos = 0; + if (pos < 0) return ""; + return string.sub(this, pos + 1, pos + 1); +} diff --git a/src/lualib/StringCharCodeAt.ts b/src/lualib/StringCharCodeAt.ts new file mode 100644 index 000000000..0044cc6cf --- /dev/null +++ b/src/lualib/StringCharCodeAt.ts @@ -0,0 +1,5 @@ +function __TS__StringCharCodeAt(this: string, index: number): number { + if (index !== index) index = 0; + if (index < 0) return NaN; + return string.byte(this, index + 1) ?? NaN; +} diff --git a/src/lualib/StringPadEnd.ts b/src/lualib/StringPadEnd.ts index 74fb0ffc0..24c8d48da 100644 --- a/src/lualib/StringPadEnd.ts +++ b/src/lualib/StringPadEnd.ts @@ -13,5 +13,5 @@ function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): fillString += fillString.repeat(maxLength / fillString.length); } - return this + fillString.slice(0, Math.floor(maxLength)); + return this + string.sub(fillString, 1, Math.floor(maxLength)); } diff --git a/src/lualib/StringPadStart.ts b/src/lualib/StringPadStart.ts index 81ba93ad1..0e73f06fc 100644 --- a/src/lualib/StringPadStart.ts +++ b/src/lualib/StringPadStart.ts @@ -13,5 +13,5 @@ function __TS__StringPadStart(this: string, maxLength: number, fillString = " ") fillString += fillString.repeat(maxLength / fillString.length); } - return fillString.slice(0, Math.floor(maxLength)) + this; + return string.sub(fillString, 1, Math.floor(maxLength)) + this; } diff --git a/src/lualib/StringSlice.ts b/src/lualib/StringSlice.ts new file mode 100644 index 000000000..42355d9e1 --- /dev/null +++ b/src/lualib/StringSlice.ts @@ -0,0 +1,9 @@ +function __TS__StringSlice(this: string, start?: number, end?: number): string { + if (start === undefined || start !== start) start = 0; + if (end !== end) end = 0; + + if (start >= 0) start += 1; + if (end !== undefined && end < 0) end -= 1; + + return string.sub(this, start, end); +} diff --git a/src/lualib/StringSubstr.ts b/src/lualib/StringSubstr.ts new file mode 100644 index 000000000..e14c3c4a5 --- /dev/null +++ b/src/lualib/StringSubstr.ts @@ -0,0 +1,12 @@ +function __TS__StringSubstr(this: string, from: number, length?: number): string { + if (from !== from) from = 0; + + if (length !== undefined) { + if (length !== length || length <= 0) return ""; + length += from; + } + + if (from >= 0) from += 1; + + return string.sub(this, from, length); +} diff --git a/src/lualib/StringSubstring.ts b/src/lualib/StringSubstring.ts new file mode 100644 index 000000000..df8210555 --- /dev/null +++ b/src/lualib/StringSubstring.ts @@ -0,0 +1,17 @@ +function __TS__StringSubstring(this: string, start: number, end?: number): string { + if (end !== end) end = 0; + + if (end !== undefined && start > end) { + [start, end] = [end, start]; + } + + if (start >= 0) { + start += 1; + } else { + start = 1; + } + + if (end !== undefined && end < 0) end = 0; + + return string.sub(this, start, end); +} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index a21500d28..e8d657da6 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -1,5 +1,9 @@ /** @noSelf */ declare namespace string { + function byte(s: string, i?: number): number | undefined; + /** @tupleReturn */ + function byte(s: string, i?: number, j?: number): number[]; + /** @tupleReturn */ function gsub( source: string, diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 352ac9c2f..1125e96b2 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assume } from "../../utils"; import { TransformationContext } from "../context"; +import { createNaN } from "../utils/lua-ast"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { getIdentifierSymbolId } from "../utils/symbols"; import { @@ -121,12 +122,7 @@ export function transformBuiltinIdentifierExpression( ): lua.Expression | undefined { switch (node.text) { case "NaN": - return lua.createBinaryExpression( - lua.createNumericLiteral(0), - lua.createNumericLiteral(0), - lua.SyntaxKind.DivisionOperator, - node - ); + return createNaN(node); case "Infinity": const math = lua.createIdentifier("math"); diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index ac2005929..65a76d28b 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; -import { createExpressionPlusOne } from "../utils/lua-ast"; +import { addToNumericExpression, createNaN, getNumberLiteralValue } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; @@ -30,13 +30,20 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringReplace, node, caller, ...params); case "concat": return transformLuaLibFunction(context, LuaLibFeature.StringConcat, node, caller, ...params); - case "indexOf": + + case "indexOf": { const stringExpression = createStringCall( "find", node, caller, params[0], - params[1] ? createExpressionPlusOne(params[1]) : lua.createNilLiteral(), + params[1] + ? // string.find handles negative indexes by making it relative to string end, but for indexOf it's the same as 0 + lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("math"), lua.createStringLiteral("max")), + [addToNumericExpression(params[1], 1), lua.createNumericLiteral(1)] + ) + : lua.createNilLiteral(), lua.createBooleanLiteral(true) ); @@ -46,35 +53,38 @@ export function transformStringPrototypeCall( lua.SyntaxKind.SubtractionOperator, node ); + } + case "substr": - if (node.arguments.length === 1) { - const argument = context.transformExpression(node.arguments[0]); - const arg1 = createExpressionPlusOne(argument); - return createStringCall("sub", node, caller, arg1); - } else { - const sumArg = lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.AdditionOperator); - return createStringCall("sub", node, caller, createExpressionPlusOne(params[0]), sumArg); - } + return transformLuaLibFunction(context, LuaLibFeature.StringSubstr, node, caller, ...params); case "substring": - if (node.arguments.length === 1) { - const arg1 = createExpressionPlusOne(params[0]); - return createStringCall("sub", node, caller, arg1); - } else { - const arg1 = createExpressionPlusOne(params[0]); - const arg2 = params[1]; - return createStringCall("sub", node, caller, arg1, arg2); - } - case "slice": - if (node.arguments.length === 0) { - return caller; - } else if (node.arguments.length === 1) { - const arg1 = createExpressionPlusOne(params[0]); - return createStringCall("sub", node, caller, arg1); - } else { - const arg1 = createExpressionPlusOne(params[0]); - const arg2 = params[1]; - return createStringCall("sub", node, caller, arg1, arg2); + return transformLuaLibFunction(context, LuaLibFeature.StringSubstring, node, caller, ...params); + + case "slice": { + const literalArg1 = getNumberLiteralValue(params[0]); + if (params[0] && literalArg1 !== undefined) { + let stringSubArgs: lua.Expression[] | undefined = [ + addToNumericExpression(params[0], literalArg1 < 0 ? 0 : 1), + ]; + + if (params[1]) { + const literalArg2 = getNumberLiteralValue(params[1]); + if (literalArg2 !== undefined) { + stringSubArgs.push(addToNumericExpression(params[1], literalArg2 < 0 ? -1 : 0)); + } else { + stringSubArgs = undefined; + } + } + + // Inline string.sub call if we know that both parameters are pure and aren't negative + if (stringSubArgs) { + return createStringCall("sub", node, caller, ...stringSubArgs); + } } + + return transformLuaLibFunction(context, LuaLibFeature.StringSlice, node, caller, ...params); + } + case "toLowerCase": return createStringCall("lower", node, caller); case "toUpperCase": @@ -89,13 +99,32 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringTrimStart, node, caller); case "split": return transformLuaLibFunction(context, LuaLibFeature.StringSplit, node, caller, ...params); - case "charAt": - const firstParamPlusOne = createExpressionPlusOne(params[0]); - return createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); + + case "charAt": { + const literalValue = getNumberLiteralValue(params[0]); + // Inline string.sub call if we know that parameter is pure and isn't negative + if (literalValue !== undefined && literalValue >= 0) { + const firstParamPlusOne = addToNumericExpression(params[0], 1); + return createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); + } + + return transformLuaLibFunction(context, LuaLibFeature.StringCharAt, node, caller, ...params); + } + case "charCodeAt": { - const firstParamPlusOne = createExpressionPlusOne(params[0]); - return createStringCall("byte", node, caller, firstParamPlusOne); + const literalValue = getNumberLiteralValue(params[0]); + // Inline string.sub call if we know that parameter is pure and isn't negative + if (literalValue !== undefined && literalValue >= 0) { + return lua.createBinaryExpression( + createStringCall("byte", node, caller, addToNumericExpression(params[0], 1)), + createNaN(), + lua.SyntaxKind.OrOperator + ); + } + + return transformLuaLibFunction(context, LuaLibFeature.StringCharCodeAt, node, caller, ...params); } + case "startsWith": return transformLuaLibFunction(context, LuaLibFeature.StringStartsWith, node, caller, ...params); case "endsWith": diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index e0c7682d5..236e32437 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -22,24 +22,45 @@ export function createExportsIdentifier(): lua.Identifier { return lua.createIdentifier("____exports"); } -export function createExpressionPlusOne(expression: lua.Expression): lua.Expression { - if (lua.isNumericLiteral(expression)) { - const newNode = lua.cloneNode(expression); - newNode.value += 1; +export function addToNumericExpression(expression: lua.Expression, change: number): lua.Expression { + if (change === 0) return expression; + + const literalValue = getNumberLiteralValue(expression); + if (literalValue !== undefined) { + const newNode = lua.createNumericLiteral(literalValue + change); + lua.setNodePosition(newNode, expression); return newNode; } if (lua.isBinaryExpression(expression)) { if ( - expression.operator === lua.SyntaxKind.SubtractionOperator && lua.isNumericLiteral(expression.right) && - expression.right.value === 1 + ((expression.operator === lua.SyntaxKind.SubtractionOperator && expression.right.value === change) || + (expression.operator === lua.SyntaxKind.AdditionOperator && expression.right.value === -change)) ) { return expression.left; } } - return lua.createBinaryExpression(expression, lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator); + return change > 0 + ? lua.createBinaryExpression(expression, lua.createNumericLiteral(change), lua.SyntaxKind.AdditionOperator) + : lua.createBinaryExpression(expression, lua.createNumericLiteral(-change), lua.SyntaxKind.SubtractionOperator); +} + +export function getNumberLiteralValue(expression?: lua.Expression) { + if (!expression) return undefined; + + if (lua.isNumericLiteral(expression)) return expression.value; + + if ( + lua.isUnaryExpression(expression) && + expression.operator === lua.SyntaxKind.NegationOperator && + lua.isNumericLiteral(expression.operand) + ) { + return -expression.operand.value; + } + + return undefined; } export function createImmediatelyInvokedFunctionExpression( @@ -197,3 +218,11 @@ export function createLocalOrExportedOrGlobalDeclaration( return []; } } + +export const createNaN = (tsOriginal?: ts.Node) => + lua.createBinaryExpression( + lua.createNumericLiteral(0), + lua.createNumericLiteral(0), + lua.SyntaxKind.DivisionOperator, + tsOriginal + ); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 619a31fb2..eaa5591b7 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,8 +3,9 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { createExpressionPlusOne } from "../utils/lua-ast"; -import { isArrayType, isNumberType, isStringType, isExpressionWithEvaluationEffect } from "../utils/typescript"; +import { addToNumericExpression } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; @@ -16,32 +17,31 @@ export function transformElementAccessArgument( const type = context.checker.getTypeAtLocation(node.expression); const argumentType = context.checker.getTypeAtLocation(node.argumentExpression); - if (isNumberType(context, argumentType) && isArrayType(context, type)) { - return createExpressionPlusOne(index); + if (isArrayType(context, type) && isNumberType(context, argumentType)) { + return addToNumericExpression(index, 1); } return index; } -export const transformElementAccessExpression: FunctionVisitor = (expression, context) => { - validateLuaTableElementAccessExpression(context, expression); +export const transformElementAccessExpression: FunctionVisitor = (node, context) => { + validateLuaTableElementAccessExpression(context, node); - const constEnumValue = tryGetConstEnumValue(context, expression); + const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return constEnumValue; } - const argumentType = context.checker.getTypeAtLocation(expression.argumentExpression); - const type = context.checker.getTypeAtLocation(expression.expression); - if (isNumberType(context, argumentType) && isStringType(context, type)) { - return transformStringIndex(context, expression); + const table = context.transformExpression(node.expression); + + const type = context.checker.getTypeAtLocation(node.expression); + const argumentType = context.checker.getTypeAtLocation(node.argumentExpression); + if (isStringType(context, type) && isNumberType(context, argumentType)) { + const index = context.transformExpression(node.argumentExpression); + return transformLuaLibFunction(context, LuaLibFeature.StringAccess, node, table, index); } - return lua.createTableIndexExpression( - context.transformExpression(expression.expression), - transformElementAccessArgument(context, expression), - expression - ); + return lua.createTableIndexExpression(table, transformElementAccessArgument(context, node), node); }; export const transformPropertyAccessExpression: FunctionVisitor = ( @@ -91,32 +91,3 @@ export const transformQualifiedName: FunctionVisitor = (node, return lua.createTableIndexExpression(left, right, node); }; - -function transformStringIndex(context: TransformationContext, expression: ts.ElementAccessExpression): lua.Expression { - const string = context.transformExpression(expression.expression); - // Translate to string.sub(str, index, index), cache index in case it has side effects. - if (isExpressionWithEvaluationEffect(expression.argumentExpression)) { - const indexIdentifier = lua.createIdentifier("____index"); - // string.sub(stringExpression, ____index, ____index) - const subCall = lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("sub")), - [string, lua.cloneIdentifier(indexIdentifier), lua.cloneIdentifier(indexIdentifier)], - expression - ); - // function(____index) string.sub(stringExpression, ____index, ____index) - const functionExpression = lua.createFunctionExpression( - lua.createBlock([lua.createReturnStatement([subCall])]), - [lua.cloneIdentifier(indexIdentifier)] - ); - // (function(____index) string.sub(stringExpression, ____index, ____index) end)(index + 1) - const indexPlusOne = createExpressionPlusOne(context.transformExpression(expression.argumentExpression)); - return lua.createCallExpression(functionExpression, [indexPlusOne]); - } else { - const index = context.transformExpression(expression.argumentExpression); - return lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("sub")), - [string, createExpressionPlusOne(index), createExpressionPlusOne(index)], - expression - ); - } -} diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 44fe1fa0e..57c162f94 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -431,7 +431,7 @@ test.each([ test('array.join (1, "2", {})', () => { const result = util.testExpression`[1, "2", {}].join()`.getLuaExecutionResult(); - expect(result).toMatch(/^1,2,table: 0x\d+$/); + expect(result).toMatch(/^1,2,table: 0x[\da-f]+$/); }); test('array.join (1, "2", Symbol("foo"))', () => { diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index ddc61130e..00f5c878d 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -33,15 +33,19 @@ test.each([ }); test.each([ - { input: "abcd", index: 3 }, - { input: "abcde", index: 3 }, - { input: "abcde", index: 0 }, - { input: "a", index: 0 }, + { input: "01234", index: 0 }, + { input: "01234", index: 1 }, + { input: "01234", index: 4 }, + { input: "01234", index: 5 }, + { input: "01234", index: -1 }, + { input: "01234", index: 100 }, + { input: "01234", index: NaN }, + { input: "", index: 0 }, ])("string index (%p)", ({ input, index }) => { util.testExpressionTemplate`${input}[${index}]`.expectToMatchJsResult(); }); -test("string index with side effect", () => { +test("string index (side effect)", () => { util.testFunction` let i = 0; const mystring = "abc"; @@ -73,7 +77,7 @@ test.each([ ["hello", "test", "bye"], ["hello", 42], [42, "hello"], -])("string.concat[+] (%p)", (...elements: any[]) => { +])("string + (%p)", (...elements: any[]) => { util.testExpression(elements.map(e => util.formatCode(e)).join(" + ")).expectToMatchJsResult(); }); @@ -82,7 +86,7 @@ test.each([ { str: "hello", args: ["test"] }, { str: "hello", args: [] }, { str: "hello", args: ["test", "bye"] }, -])("string.concatFct (%p)", ({ str, args }) => { +])("string.concat (%p)", ({ str, args }) => { util.testExpression`"${str}".concat(${util.formatCode(...args)})`.expectToMatchJsResult(); }); @@ -101,6 +105,9 @@ test.each([ { inp: "hello test", searchValue: "t", offset: 6 }, { inp: "hello test", searchValue: "t", offset: 7 }, { inp: "hello test", searchValue: "h", offset: 4 }, + { inp: "00100", searchValue: "1", offset: -1 }, + { inp: "00100", searchValue: "1", offset: -2 }, + { inp: "01010", searchValue: "1", offset: -3 }, ])("string.indexOf with offset (%p)", ({ inp, searchValue, offset }) => { util.testExpressionTemplate`${inp}.indexOf(${searchValue}, ${offset})`.expectToMatchJsResult(); }); @@ -112,22 +119,31 @@ test.each([ util.testExpressionTemplate`${inp}.indexOf(${searchValue}, 2 > 1 && ${x} || ${y})`.expectToMatchJsResult(); }); -test.each([ - { inp: "hello test", args: [] }, - { inp: "hello test", args: [0] }, - { inp: "hello test", args: [1] }, - { inp: "hello test", args: [1, 2] }, - { inp: "hello test", args: [1, 5] }, -])("string.slice (%p)", ({ inp, args }) => { - util.testExpression`"${inp}".slice(${util.formatCode(...args)})`.expectToMatchJsResult(); -}); +const stringPartCases = [ + { inp: "0123456789", args: [0] }, + { inp: "0123456789", args: [0, 0] }, + { inp: "0123456789", args: [1] }, + { inp: "0123456789", args: [1, 1] }, + { inp: "0123456789", args: [1, 5] }, + { inp: "0123456789", args: [5, 1] }, + { inp: "0123456789", args: [1, 100] }, + { inp: "0123456789", args: [100, 1] }, + { inp: "0123456789", args: [100, 101] }, + { inp: "0123456789", args: [-3] }, + { inp: "0123456789", args: [1, -1] }, + { inp: "0123456789", args: [-5, -2] }, + { inp: "0123456789", args: [NaN, 3] }, + { inp: "0123456789", args: [3, NaN] }, +]; -test.each([ - { inp: "hello test", args: [0] }, - { inp: "hello test", args: [1] }, - { inp: "hello test", args: [1, 2] }, - { inp: "hello test", args: [1, 5] }, -])("string.substring (%p)", ({ inp, args }) => { +test.each([{ inp: "0123456789", args: [] }, { inp: "0123456789", args: [undefined, 5] }, ...stringPartCases])( + "string.slice (%p)", + ({ inp, args }) => { + util.testExpression`"${inp}".slice(${util.formatCode(...args)})`.expectToMatchJsResult(); + } +); + +test.each(stringPartCases)("string.substring (%p)", ({ inp, args }) => { util.testExpression`"${inp}".substring(${util.formatCode(...args)})`.expectToMatchJsResult(); }); @@ -139,12 +155,7 @@ test.each([ util.testExpression`"${inp}".substring(${paramStr})`.expectToMatchJsResult(); }); -test.each([ - { inp: "hello test", args: [0] }, - { inp: "hello test", args: [1] }, - { inp: "hello test", args: [1, 2] }, - { inp: "hello test", args: [1, 5] }, -])("string.substr (%p)", ({ inp, args }) => { +test.each(stringPartCases)("string.substr (%p)", ({ inp, args }) => { util.testExpression`"${inp}".substr(${util.formatCode(...args)})`.expectToMatchJsResult(); }); @@ -183,18 +194,29 @@ test.each([ }); test.each([ + { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }, { inp: "hello test", index: 99 }, + { inp: "hello test", index: -1 }, + { inp: "hello test", index: -5 }, + { inp: "hello test", index: -99 }, + { inp: "hello test", index: NaN }, ])("string.charAt (%p)", ({ inp, index }) => { util.testExpressionTemplate`${inp}.charAt(${index})`.expectToMatchJsResult(); }); test.each([ + { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, { inp: "hello test", index: 2 }, { inp: "hello test", index: 3 }, + { inp: "hello test", index: 99 }, + { inp: "hello test", index: -1 }, + { inp: "hello test", index: -5 }, + { inp: "hello test", index: -99 }, + { inp: "hello test", index: NaN }, ])("string.charCodeAt (%p)", ({ inp, index }) => { util.testExpressionTemplate`${inp}.charCodeAt(${index})`.expectToMatchJsResult(); }); From 404ab4ec122c93234862e86a821999d1a975f19e Mon Sep 17 00:00:00 2001 From: ark120202 Date: Tue, 14 Jul 2020 00:38:21 +0500 Subject: [PATCH 283/764] Refactor transpilation pipeline (#885) * Refactor transpilation pipeline * Fix bundle main file finding * Fix transpile tests * Fix source map tests * Add comment to inline source maps test * Rename `transpile` to `getProgramTranspileResult` and export it * Move emit output collector to it's own file * Add missing TranspiledFile reexport --- build-lualib.js | 7 +- src/CompilerOptions.ts | 3 + src/transpilation/bundle.ts | 99 +++++++++---------- src/transpilation/emit.ts | 69 ------------- src/transpilation/index.ts | 78 +++++++++------ src/transpilation/output-collector.ts | 43 ++++++++ src/transpilation/transformers.ts | 24 ++--- src/transpilation/transpile.ts | 96 +++++------------- src/transpilation/transpiler.ts | 80 +++++++++++++++ src/transpilation/utils.ts | 25 +++++ src/tstl.ts | 21 ++-- src/utils.ts | 7 +- test/legacy-utils.ts | 13 +-- .../__snapshots__/project.spec.ts.snap | 6 +- test/transpile/bundle.spec.ts | 12 +-- test/transpile/directories.spec.ts | 6 +- test/transpile/project.spec.ts | 18 +--- test/transpile/run.ts | 30 +++--- test/unit/bundle.spec.ts | 17 ---- test/unit/printer/sourcemaps.spec.ts | 15 +-- test/util.ts | 69 +++++-------- 21 files changed, 364 insertions(+), 374 deletions(-) delete mode 100644 src/transpilation/emit.ts create mode 100644 src/transpilation/output-collector.ts create mode 100644 src/transpilation/transpiler.ts diff --git a/build-lualib.js b/build-lualib.js index c083b854c..41ece7e32 100644 --- a/build-lualib.js +++ b/build-lualib.js @@ -6,11 +6,8 @@ const tstl = require("./src"); const { loadLuaLibFeatures } = require("./src/LuaLib"); const configFileName = path.resolve(__dirname, "src/lualib/tsconfig.json"); -const { emitResult, diagnostics } = tstl.transpileProject(configFileName); -emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); - -const reportDiagnostic = tstl.createDiagnosticReporter(true); -diagnostics.forEach(reportDiagnostic); +const { diagnostics } = tstl.transpileProject(configFileName); +diagnostics.forEach(tstl.createDiagnosticReporter(true)); const bundlePath = path.join(__dirname, "dist/lualib/lualib_bundle.lua"); if (fs.existsSync(bundlePath)) { diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 45786a555..2e78b2b87 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -51,6 +51,9 @@ export enum LuaTarget { LuaJIT = "JIT", } +export const isBundleEnabled = (options: CompilerOptions) => + options.luaBundle !== undefined && options.luaBundleEntry !== undefined; + export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { const diagnostics: ts.Diagnostic[] = []; diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 2acda7399..c696c6900 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -2,77 +2,70 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; -import { getLuaLibBundle } from "../LuaLib"; import { escapeString } from "../LuaPrinter"; -import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; -import * as diagnosticFactories from "./diagnostics"; -import { EmitHost, TranspiledFile } from "./transpile"; +import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; +import { couldNotFindBundleEntryPoint } from "./diagnostics"; +import { EmitFile, EmitHost, ProcessedFile } from "./utils"; const createModulePath = (baseDir: string, pathToResolve: string) => escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); -export function bundleTranspiledFiles( - bundleFile: string, - entryModule: string, - transpiledFiles: TranspiledFile[], +// Override `require` to read from ____modules table. +const requireOverride = ` +local ____modules = {} +local ____moduleCache = {} +local ____originalRequire = require +local function require(file) + if ____moduleCache[file] then + return ____moduleCache[file] + end + if ____modules[file] then + ____moduleCache[file] = ____modules[file]() + return ____moduleCache[file] + else + if ____originalRequire then + return ____originalRequire(file) + else + error("module '" .. file .. "' not found") + end + end +end +`; + +export function getBundleResult( program: ts.Program, - emitHost: EmitHost -): [ts.Diagnostic[], TranspiledFile] { + emitHost: EmitHost, + files: ProcessedFile[] +): [ts.Diagnostic[], EmitFile] { const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; + const bundleFile = cast(options.luaBundle, isNonNull); + const entryModule = cast(options.luaBundleEntry, isNonNull); + const rootDir = program.getCommonSourceDirectory(); + const outDir = options.outDir ?? rootDir; const projectRootDir = options.configFilePath ? path.dirname(options.configFilePath) : emitHost.getCurrentDirectory(); // Resolve project settings relative to project file. const resolvedEntryModule = path.resolve(projectRootDir, entryModule); - const resolvedBundleFile = path.resolve(projectRootDir, bundleFile); + const outputPath = normalizeSlashes(path.resolve(projectRootDir, bundleFile)); - // Resolve source files relative to common source directory. - const sourceRootDir = program.getCommonSourceDirectory(); - if (!transpiledFiles.some(f => path.resolve(sourceRootDir, f.fileName) === resolvedEntryModule)) { - return [[diagnosticFactories.couldNotFindBundleEntryPoint(entryModule)], { fileName: bundleFile }]; + if (!files.some(f => f.fileName === resolvedEntryModule)) { + diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); + return [diagnostics, { outputPath, code: "" }]; } // For each file: [""] = function() end, - const moduleTableEntries: SourceChunk[] = transpiledFiles.map(f => - moduleSourceNode(f, createModulePath(sourceRootDir, f.fileName)) - ); - - // If any of the modules contains a require for lualib_bundle, add it to the module table. - const lualibRequired = transpiledFiles.some(f => f.lua?.includes('require("lualib_bundle")')); - if (lualibRequired) { - moduleTableEntries.push(`["lualib_bundle"] = function() ${getLuaLibBundle(emitHost)} end,\n`); - } + const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(outDir, f.fileName))); // Create ____modules table containing all entries from moduleTableEntries const moduleTable = createModuleTableNode(moduleTableEntries); - // Override `require` to read from ____modules table. - const requireOverride = ` -local ____modules = {} -local ____moduleCache = {} -local ____originalRequire = require -local function require(file) - if ____moduleCache[file] then - return ____moduleCache[file] - end - if ____modules[file] then - ____moduleCache[file] = ____modules[file]() - return ____moduleCache[file] - else - if ____originalRequire then - return ____originalRequire(file) - else - error("module '" .. file .. "' not found") - end - end -end\n`; - // return require("") - const entryPoint = `return require(${createModulePath(sourceRootDir, resolvedEntryModule)})\n`; + const entryPoint = `return require(${createModulePath(outDir, resolvedEntryModule)})\n`; const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); const { code, map } = bundleNode.toStringWithSourceMap(); @@ -80,23 +73,19 @@ end\n`; return [ diagnostics, { - fileName: normalizeSlashes(resolvedBundleFile), - lua: code, + outputPath, + code, sourceMap: map.toString(), - sourceMapNode: moduleTable, + sourceFiles: files.flatMap(x => x.sourceFiles ?? []), }, ]; } -function moduleSourceNode(transpiledFile: TranspiledFile, modulePath: string): SourceNode { +function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { const tableEntryHead = `[${modulePath}] = function() `; const tableEntryTail = "end,\n"; - if (transpiledFile.lua && transpiledFile.sourceMapNode) { - return joinSourceChunks([tableEntryHead, transpiledFile.sourceMapNode, tableEntryTail]); - } else { - return joinSourceChunks([tableEntryHead, tableEntryTail]); - } + return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); } function createModuleTableNode(fileChunks: SourceChunk[]): SourceNode { diff --git a/src/transpilation/emit.ts b/src/transpilation/emit.ts deleted file mode 100644 index 854f0cc7e..000000000 --- a/src/transpilation/emit.ts +++ /dev/null @@ -1,69 +0,0 @@ -import * as path from "path"; -import * as ts from "typescript"; -import { LuaLibImportKind } from "../CompilerOptions"; -import { getLuaLibBundle } from "../LuaLib"; -import { normalizeSlashes, trimExtension } from "../utils"; -import { EmitHost, TranspiledFile } from "./transpile"; - -export interface OutputFile { - name: string; - text: string; -} - -export function emitTranspiledFiles( - program: ts.Program, - transpiledFiles: TranspiledFile[], - emitHost: EmitHost = ts.sys -): OutputFile[] { - const options = program.getCompilerOptions(); - let { outDir, luaLibImport, luaBundle } = options; - - const rootDir = program.getCommonSourceDirectory(); - outDir = outDir ?? rootDir; - - const files: OutputFile[] = []; - for (const { fileName, lua, sourceMap, declaration, declarationMap } of transpiledFiles) { - let outPath = fileName; - if (outDir !== rootDir) { - outPath = path.resolve(outDir, path.relative(rootDir, fileName)); - } - - // change extension - outPath = normalizeSlashes(trimExtension(outPath) + ".lua"); - - if (lua !== undefined) { - files.push({ name: outPath, text: lua }); - } - - if (sourceMap !== undefined && options.sourceMap) { - files.push({ name: outPath + ".map", text: sourceMap }); - } - - if (declaration !== undefined) { - files.push({ name: trimExtension(outPath) + ".d.ts", text: declaration }); - } - - if (declarationMap !== undefined) { - files.push({ name: trimExtension(outPath) + ".d.ts.map", text: declarationMap }); - } - } - - if ( - !luaBundle && - (luaLibImport === undefined || - luaLibImport === LuaLibImportKind.Require || - luaLibImport === LuaLibImportKind.Always) - ) { - const lualibRequired = files.some(f => f.text?.includes('require("lualib_bundle")')); - if (lualibRequired) { - let outPath = path.resolve(rootDir, "lualib_bundle.lua"); - if (outDir !== rootDir) { - outPath = path.join(outDir, path.relative(rootDir, outPath)); - } - - files.push({ name: normalizeSlashes(outPath), text: getLuaLibBundle(emitHost) }); - } - } - - return files; -} diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 76c0e9634..628246ec9 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -3,38 +3,41 @@ import * as path from "path"; import * as ts from "typescript"; import { parseConfigFileWithSystem } from "../cli/tsconfig"; import { CompilerOptions } from "../CompilerOptions"; -import { emitTranspiledFiles, OutputFile } from "./emit"; -import { transpile, TranspiledFile, TranspileResult } from "./transpile"; +import { createEmitOutputCollector, TranspiledFile } from "./output-collector"; +import { EmitResult, Transpiler } from "./transpiler"; -export * from "./emit"; export { Plugin } from "./plugins"; export * from "./transpile"; - -export interface TranspileFilesResult { - diagnostics: ts.Diagnostic[]; - emitResult: OutputFile[]; -} - -export function transpileFiles(rootNames: string[], options: CompilerOptions = {}): TranspileFilesResult { +export * from "./transpiler"; +export { EmitHost } from "./utils"; +export { TranspiledFile }; + +export function transpileFiles( + rootNames: string[], + options: CompilerOptions = {}, + writeFile?: ts.WriteFileCallback +): EmitResult { const program = ts.createProgram(rootNames, options); - const { transpiledFiles, diagnostics: transpileDiagnostics } = transpile({ program }); - const emitResult = emitTranspiledFiles(program, transpiledFiles); - + const { diagnostics: transpileDiagnostics, emitSkipped } = new Transpiler().emit({ program, writeFile }); const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...ts.getPreEmitDiagnostics(program), ...transpileDiagnostics, ]); - return { diagnostics: [...diagnostics], emitResult }; + return { diagnostics: [...diagnostics], emitSkipped }; } -export function transpileProject(configFileName: string, optionsToExtend?: CompilerOptions): TranspileFilesResult { +export function transpileProject( + configFileName: string, + optionsToExtend?: CompilerOptions, + writeFile?: ts.WriteFileCallback +): EmitResult { const parseResult = parseConfigFileWithSystem(configFileName, optionsToExtend); if (parseResult.errors.length > 0) { - return { diagnostics: parseResult.errors, emitResult: [] }; + return { diagnostics: parseResult.errors, emitSkipped: true }; } - return transpileFiles(parseResult.fileNames, parseResult.options); + return transpileFiles(parseResult.fileNames, parseResult.options, writeFile); } const libCache: { [key: string]: ts.SourceFile } = {}; @@ -51,20 +54,20 @@ export function createVirtualProgram(input: Record, options: Com useCaseSensitiveFileNames: () => false, writeFile() {}, - getSourceFile(filename) { - if (filename in input) { - return ts.createSourceFile(filename, input[filename], ts.ScriptTarget.Latest, false); + getSourceFile(fileName) { + if (fileName in input) { + return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false); } - if (filename.startsWith("lib.")) { - if (libCache[filename]) return libCache[filename]; + if (fileName.startsWith("lib.")) { + if (libCache[fileName]) return libCache[fileName]; const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, filename); + const filePath = path.join(typeScriptDir, fileName); const content = fs.readFileSync(filePath, "utf8"); - libCache[filename] = ts.createSourceFile(filename, content, ts.ScriptTarget.Latest, false); + libCache[fileName] = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false); - return libCache[filename]; + return libCache[fileName]; } }, }; @@ -72,12 +75,24 @@ export function createVirtualProgram(input: Record, options: Com return ts.createProgram(Object.keys(input), options, compilerHost); } -export function transpileVirtualProject(files: Record, options: CompilerOptions = {}): TranspileResult { +export interface TranspileVirtualProjectResult { + diagnostics: ts.Diagnostic[]; + transpiledFiles: TranspiledFile[]; +} + +export function transpileVirtualProject( + files: Record, + options: CompilerOptions = {} +): TranspileVirtualProjectResult { const program = createVirtualProgram(files, options); - const result = transpile({ program }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([...ts.getPreEmitDiagnostics(program), ...result.diagnostics]); + const collector = createEmitOutputCollector(); + const { diagnostics: transpileDiagnostics } = new Transpiler().emit({ program, writeFile: collector.writeFile }); + const diagnostics = ts.sortAndDeduplicateDiagnostics([ + ...ts.getPreEmitDiagnostics(program), + ...transpileDiagnostics, + ]); - return { ...result, diagnostics: [...diagnostics] }; + return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; } export interface TranspileStringResult { @@ -87,5 +102,8 @@ export interface TranspileStringResult { export function transpileString(main: string, options: CompilerOptions = {}): TranspileStringResult { const { diagnostics, transpiledFiles } = transpileVirtualProject({ "main.ts": main }, options); - return { diagnostics, file: transpiledFiles.find(({ fileName }) => fileName === "main.ts") }; + return { + diagnostics, + file: transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === "main.ts")), + }; } diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts new file mode 100644 index 000000000..d18137c5a --- /dev/null +++ b/src/transpilation/output-collector.ts @@ -0,0 +1,43 @@ +import * as ts from "typescript"; +import { intersection, union } from "../utils"; + +export interface TranspiledFile { + sourceFiles: ts.SourceFile[]; + lua?: string; + luaSourceMap?: string; + declaration?: string; + declarationMap?: string; + /** @internal */ + js?: string; + /** @internal */ + jsSourceMap?: string; +} + +export function createEmitOutputCollector() { + const files: TranspiledFile[] = []; + const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { + let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); + if (!file) { + file = { sourceFiles: [...sourceFiles] }; + files.push(file); + } else { + file.sourceFiles = union(file.sourceFiles, sourceFiles); + } + + if (fileName.endsWith(".lua")) { + file.lua = data; + } else if (fileName.endsWith(".lua.map")) { + file.luaSourceMap = data; + } else if (fileName.endsWith(".js")) { + file.js = data; + } else if (fileName.endsWith(".js.map")) { + file.jsSourceMap = data; + } else if (fileName.endsWith(".d.ts")) { + file.declaration = data; + } else if (fileName.endsWith(".d.ts.map")) { + file.declarationMap = data; + } + }; + + return { writeFile, files }; +} diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index cefb4dd90..470e7ad13 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -5,18 +5,6 @@ import { CompilerOptions, TransformerImport } from "../CompilerOptions"; import * as diagnosticFactories from "./diagnostics"; import { getConfigDirectory, resolvePlugin } from "./utils"; -export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => { - const transformSourceFile: ts.Transformer = node => { - const empty = ts.createNotEmittedStatement(undefined!); - ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); - return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); - }; - - return ts.isBundle(node) - ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) - : transformSourceFile(node); -}; - export function getTransformers( program: ts.Program, diagnostics: ts.Diagnostic[], @@ -53,6 +41,18 @@ export function getTransformers( }; } +export const noImplicitSelfTransformer: ts.TransformerFactory = () => node => { + const transformSourceFile: ts.Transformer = node => { + const empty = ts.createNotEmittedStatement(undefined!); + ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); + return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); + }; + + return ts.isBundle(node) + ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) + : transformSourceFile(node); +}; + function loadTransformersFromOptions(program: ts.Program, diagnostics: ts.Diagnostic[]): ts.CustomTransformers { const customTransformers: Required = { before: [], diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index d024e8a09..01d9278c5 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -1,63 +1,34 @@ -import { SourceNode } from "source-map"; +import * as path from "path"; import * as ts from "typescript"; import { CompilerOptions, validateOptions } from "../CompilerOptions"; -import { Block } from "../LuaAST"; import { createPrinter } from "../LuaPrinter"; import { createVisitorMap, transformSourceFile } from "../transformation"; import { isNonNull } from "../utils"; -import { bundleTranspiledFiles } from "./bundle"; import { getPlugins, Plugin } from "./plugins"; import { getTransformers } from "./transformers"; - -export interface TranspiledFile { - fileName: string; - luaAst?: Block; - lua?: string; - sourceMap?: string; - declaration?: string; - declarationMap?: string; - /** @internal */ - sourceMapNode?: SourceNode; -} - -export interface TranspileResult { - diagnostics: ts.Diagnostic[]; - transpiledFiles: TranspiledFile[]; -} +import { EmitHost, ProcessedFile } from "./utils"; export interface TranspileOptions { program: ts.Program; sourceFiles?: ts.SourceFile[]; customTransformers?: ts.CustomTransformers; plugins?: Plugin[]; - emitHost?: EmitHost; } -export interface EmitHost { - getCurrentDirectory(): string; - readFile(path: string): string | undefined; +export interface TranspileResult { + diagnostics: ts.Diagnostic[]; + transpiledFiles: ProcessedFile[]; } -export function transpile({ - program, - sourceFiles: targetSourceFiles, - customTransformers = {}, - plugins: customPlugins = [], - emitHost = ts.sys, -}: TranspileOptions): TranspileResult { +export function getProgramTranspileResult( + emitHost: EmitHost, + writeFileResult: ts.WriteFileCallback, + { program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins: customPlugins = [] }: TranspileOptions +): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; const diagnostics = validateOptions(options); - let transpiledFiles: TranspiledFile[] = []; - - const updateTranspiledFile = (fileName: string, update: Omit) => { - const file = transpiledFiles.find(f => f.fileName === fileName); - if (file) { - Object.assign(file, update); - } else { - transpiledFiles.push({ fileName, ...update }); - } - }; + let transpiledFiles: ProcessedFile[] = []; if (options.noEmitOnError) { const preEmitDiagnostics = [ @@ -94,42 +65,33 @@ export function transpile({ sourceFile, visitorMap ); + diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { - const { code, sourceMap, sourceMapNode } = printer( - program, - emitHost, - sourceFile.fileName, - luaAst, - luaLibFeatures - ); - updateTranspiledFile(sourceFile.fileName, { luaAst, lua: code, sourceMap, sourceMapNode }); + const printResult = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures); + const sourceRootDir = program.getCommonSourceDirectory(); + const fileName = path.resolve(sourceRootDir, sourceFile.fileName); + transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst, ...printResult }); } }; const transformers = getTransformers(program, diagnostics, customTransformers, processSourceFile); - const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { - for (const sourceFile of sourceFiles) { - const isDeclaration = fileName.endsWith(".d.ts"); - const isDeclarationMap = fileName.endsWith(".d.ts.map"); - if (isDeclaration) { - updateTranspiledFile(sourceFile.fileName, { declaration: data }); - } else if (isDeclarationMap) { - updateTranspiledFile(sourceFile.fileName, { declarationMap: data }); - } - } - }; - const isEmittableJsonFile = (sourceFile: ts.SourceFile) => sourceFile.flags & ts.NodeFlags.JsonFile && !options.emitDeclarationOnly && !program.isSourceFileFromExternalLibrary(sourceFile); - // We always have to emit to get transformer diagnostics + // We always have to run transformers to get diagnostics const oldNoEmit = options.noEmit; options.noEmit = false; + const writeFile: ts.WriteFileCallback = (fileName, ...rest) => { + if (!fileName.endsWith(".js") && !fileName.endsWith(".js.map")) { + writeFileResult(fileName, ...rest); + } + }; + if (targetSourceFiles) { for (const file of targetSourceFiles) { if (isEmittableJsonFile(file)) { @@ -151,17 +113,5 @@ export function transpile({ transpiledFiles = []; } - if (options.luaBundle && options.luaBundleEntry) { - const [bundleDiagnostics, bundle] = bundleTranspiledFiles( - options.luaBundle, - options.luaBundleEntry, - transpiledFiles, - program, - emitHost - ); - diagnostics.push(...bundleDiagnostics); - transpiledFiles = [bundle]; - } - return { diagnostics, transpiledFiles }; } diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts new file mode 100644 index 000000000..205b6b2db --- /dev/null +++ b/src/transpilation/transpiler.ts @@ -0,0 +1,80 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { isBundleEnabled } from "../CompilerOptions"; +import { getLuaLibBundle } from "../LuaLib"; +import { normalizeSlashes, trimExtension } from "../utils"; +import { getBundleResult } from "./bundle"; +import { getProgramTranspileResult, TranspileOptions } from "./transpile"; +import { EmitFile, EmitHost, ProcessedFile } from "./utils"; + +export interface TranspilerOptions { + emitHost?: EmitHost; +} + +export interface EmitOptions extends TranspileOptions { + writeFile?: ts.WriteFileCallback; +} + +export interface EmitResult { + emitSkipped: boolean; + diagnostics: readonly ts.Diagnostic[]; +} + +export class Transpiler { + protected emitHost: EmitHost; + constructor({ emitHost = ts.sys }: TranspilerOptions = {}) { + this.emitHost = emitHost; + } + + public emit(emitOptions: EmitOptions): EmitResult { + const { program, writeFile = this.emitHost.writeFile } = emitOptions; + const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( + this.emitHost, + writeFile, + emitOptions + ); + const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); + + const options = program.getCompilerOptions(); + const emitBOM = options.emitBOM ?? false; + for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) { + writeFile(outputPath, code, emitBOM, undefined, sourceFiles); + if (options.sourceMap && sourceMap !== undefined) { + writeFile(outputPath + ".map", sourceMap, emitBOM, undefined, sourceFiles); + } + } + + return { diagnostics, emitSkipped: emitPlan.length === 0 }; + } + + protected getEmitPlan( + program: ts.Program, + diagnostics: ts.Diagnostic[], + files: ProcessedFile[] + ): { emitPlan: EmitFile[] } { + const options = program.getCompilerOptions(); + const rootDir = program.getCommonSourceDirectory(); + const outDir = options.outDir ?? rootDir; + + const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); + if (lualibRequired) { + const fileName = normalizeSlashes(path.resolve(rootDir, "lualib_bundle.lua")); + files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); + } + + let emitPlan: EmitFile[]; + if (isBundleEnabled(options)) { + const [bundleDiagnostics, bundleFile] = getBundleResult(program, this.emitHost, files); + diagnostics.push(...bundleDiagnostics); + emitPlan = [bundleFile]; + } else { + emitPlan = files.map(file => { + const pathInOutDir = path.resolve(outDir, path.relative(rootDir, file.fileName)); + const outputPath = normalizeSlashes(trimExtension(pathInOutDir) + ".lua"); + return { ...file, outputPath }; + }); + } + + return { emitPlan }; + } +} diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index a2270c401..98c3f5cc6 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -1,10 +1,35 @@ import * as path from "path"; import * as resolve from "resolve"; +import { SourceNode } from "source-map"; import * as ts from "typescript"; // TODO: Don't depend on CLI? import * as cliDiagnostics from "../cli/diagnostics"; +import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; +export interface EmitHost { + getCurrentDirectory(): string; + readFile(path: string): string | undefined; + writeFile: ts.WriteFileCallback; +} + +interface BaseFile { + code: string; + sourceMap?: string; + sourceFiles?: ts.SourceFile[]; +} + +export interface ProcessedFile extends BaseFile { + fileName: string; + luaAst?: lua.Block; + /** @internal */ + sourceMapNode?: SourceNode; +} + +export interface EmitFile extends BaseFile { + outputPath: string; +} + export const getConfigDirectory = (options: ts.CompilerOptions) => options.configFilePath ? path.dirname(options.configFilePath) : process.cwd(); diff --git a/src/tstl.ts b/src/tstl.ts index aab3feff2..fb011be3c 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -6,6 +6,7 @@ import { getHelpString, versionString } from "./cli/information"; import { parseCommandLine } from "./cli/parse"; import { createDiagnosticReporter } from "./cli/report"; import { createConfigFileUpdater, locateConfigFile, parseConfigFileWithSystem } from "./cli/tsconfig"; +import { isBundleEnabled } from "./CompilerOptions"; const shouldBePretty = ({ pretty }: ts.CompilerOptions = {}) => pretty !== undefined ? (pretty as boolean) : ts.sys.writeOutputIsTTY?.() ?? false; @@ -101,21 +102,18 @@ function performCompilation( configFileParsingDiagnostics, }); - const { transpiledFiles, diagnostics: transpileDiagnostics } = tstl.transpile({ program }); + const { diagnostics: transpileDiagnostics, emitSkipped } = new tstl.Transpiler().emit({ program }); const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...ts.getPreEmitDiagnostics(program), ...transpileDiagnostics, ]); - const emitResult = tstl.emitTranspiledFiles(program, transpiledFiles); - emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); - diagnostics.forEach(reportDiagnostic); const exitCode = diagnostics.length === 0 ? ts.ExitStatus.Success - : transpiledFiles.length === 0 + : emitSkipped ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped : ts.ExitStatus.DiagnosticsPresent_OutputsGenerated; @@ -154,16 +152,17 @@ function updateWatchCompilationHost( host: ts.WatchCompilerHost, optionsToExtend: tstl.CompilerOptions ): void { - let fullRecompile = true; + let hadErrorLastTime = true; const updateConfigFile = createConfigFileUpdater(optionsToExtend); + const transpiler = new tstl.Transpiler(); host.afterProgramCreate = builderProgram => { const program = builderProgram.getProgram(); const options = builderProgram.getCompilerOptions() as tstl.CompilerOptions; const configFileParsingDiagnostics: ts.Diagnostic[] = updateConfigFile(options); let sourceFiles: ts.SourceFile[] | undefined; - if (!fullRecompile) { + if (!isBundleEnabled(options) && !hadErrorLastTime) { sourceFiles = []; while (true) { const currentFile = builderProgram.getSemanticDiagnosticsOfNextAffectedFile(); @@ -177,10 +176,7 @@ function updateWatchCompilationHost( } } - const { diagnostics: emitDiagnostics, transpiledFiles } = tstl.transpile({ program, sourceFiles }); - - const emitResult = tstl.emitTranspiledFiles(program, transpiledFiles); - emitResult.forEach(({ name, text }) => ts.sys.writeFile(name, text)); + const { diagnostics: emitDiagnostics } = transpiler.emit({ program, sourceFiles }); const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...configFileParsingDiagnostics, @@ -194,8 +190,7 @@ function updateWatchCompilationHost( diagnostics.forEach(reportDiagnostic); const errors = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error); - // do a full recompile after an error - fullRecompile = errors.length > 0; + hadErrorLastTime = errors.length > 0; host.onWatchStatusChange!(cliDiagnostics.watchErrorSummary(errors.length), host.getNewLine(), options); }; diff --git a/src/utils.ts b/src/utils.ts index aad8ce621..1244068a4 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -8,9 +8,14 @@ export function castArray(value: T | readonly T[]): readonly T[] { return Array.isArray(value) ? value : [value]; } -export const intersperse = (values: T[], separator: T): T[] => +export const intersperse = (values: readonly T[], separator: T): T[] => values.flatMap((value, index) => (index === 0 ? [value] : [separator, value])); +export const union = (...values: Array>): T[] => [...new Set(...values)]; + +export const intersection = (first: readonly T[], ...rest: Array): T[] => + union(first).filter(x => rest.every(r => r.includes(x))); + type DiagnosticFactory = (...args: any) => Partial & Pick; export const createDiagnosticFactoryWithCode = (code: number, create: T) => Object.assign( diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index 685b90544..de781d954 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -19,11 +19,8 @@ export function transpileString( return file.lua!.trim(); } -function transpileStringsAsProject( - input: Record, - options: tstl.CompilerOptions = {} -): tstl.TranspileResult { - const optionsWithDefaults: tstl.CompilerOptions = { +function transpileStringsAsProject(input: Record, options: tstl.CompilerOptions = {}) { + return tstl.transpileVirtualProject(input, { luaTarget: tstl.LuaTarget.Lua53, noHeader: true, skipLibCheck: true, @@ -31,9 +28,7 @@ function transpileStringsAsProject( lib: ["lib.esnext.d.ts"], experimentalDecorators: true, ...options, - }; - - return tstl.transpileVirtualProject(input, optionsWithDefaults); + }); } function transpileStringResult( @@ -45,7 +40,7 @@ function transpileStringResult( options ); - const file = transpiledFiles.find(({ fileName }) => /\bmain\.[a-z]+$/.test(fileName)); + const file = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => /\bmain\.[a-z]+$/.test(f.fileName))); if (file === undefined) { throw new Error('Program should have a file named "main"'); } diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index ac0baeb17..4db30085f 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -3,7 +3,7 @@ exports[`should transpile 1`] = ` Array [ Object { - "name": "otherFile.lua", + "name": "project/otherFile.lua", "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] local ____exports = {} function ____exports.getNumber(self) @@ -11,9 +11,10 @@ function ____exports.getNumber(self) end return ____exports ", + "writeByteOrderMark": false, }, Object { - "name": "index.lua", + "name": "project/index.lua", "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] local ____exports = {} local ____otherFile = require(\\"otherFile\\") @@ -22,6 +23,7 @@ local myNumber = getNumber(nil) setAPIValue(myNumber * 5) return ____exports ", + "writeByteOrderMark": false, }, ] `; diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 166f4e044..21e9f153a 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -1,19 +1,19 @@ import * as path from "path"; import * as util from "../util"; -import { transpileProject } from "../../src"; +import { transpileProjectResult } from "./run"; const projectDir = path.join(__dirname, "bundle"); const inputProject = path.join(projectDir, "tsconfig.json"); test("should transpile into one file", () => { - const transpileResult = transpileProject(inputProject); + const { diagnostics, emittedFiles } = transpileProjectResult(inputProject); - expect(transpileResult.diagnostics).not.toHaveDiagnostics(); - expect(transpileResult.emitResult).toHaveLength(1); + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toHaveLength(1); - const { name, text } = transpileResult.emitResult[0]; + const { name, text } = emittedFiles[0]; // Verify the name is as specified in tsconfig - expect(name).toBe(path.join(projectDir, "bundle.lua").replace(/\\/g, "/")); + expect(name).toBe("bundle/bundle.lua"); // Verify exported module by executing expect(util.executeLuaModule(text)).toEqual({ myNumber: 3 }); }); diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index a2afd5090..9141199e5 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../../src"; -import { buildVirtualProject } from "./run"; +import { transpileFilesResult } from "./run"; interface DirectoryTestCase { name: string; @@ -27,7 +27,7 @@ test.each([ ts.parseJsonConfigFileContent(config, ts.sys, projectPath) ); - const { diagnostics, emittedFiles } = buildVirtualProject(fileNames, options); + const { diagnostics, emittedFiles } = transpileFilesResult(fileNames, options); expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toMatchSnapshot(); + expect(emittedFiles.map(f => f.name).sort()).toMatchSnapshot(); }); diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index a8afc4229..6f262dada 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,18 +1,8 @@ import * as path from "path"; -import { transpileProject } from "../../src"; - -const projectDir = path.join(__dirname, "project"); -const inputProject = path.join(projectDir, "tsconfig.json"); +import { transpileProjectResult } from "./run"; test("should transpile", () => { - const transpileResult = transpileProject(inputProject); - - expect(transpileResult.diagnostics).not.toHaveDiagnostics(); - - // Check output paths relative to projectDir - const relativeResult = transpileResult.emitResult.map(({ name, text }) => ({ - name: path.relative(projectDir, name), - text, - })); - expect(relativeResult).toMatchSnapshot(); + const { diagnostics, emittedFiles } = transpileProjectResult(path.join(__dirname, "project", "tsconfig.json")); + expect(diagnostics).not.toHaveDiagnostics(); + expect(emittedFiles).toMatchSnapshot(); }); diff --git a/test/transpile/run.ts b/test/transpile/run.ts index 72afa7ca2..8890d7a18 100644 --- a/test/transpile/run.ts +++ b/test/transpile/run.ts @@ -1,19 +1,27 @@ +import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../../src"; -import * as path from "path"; - -interface BuildVirtualProjectResult { - diagnostics: ts.Diagnostic[]; - emitResult: tstl.OutputFile[]; - emittedFiles: string[]; -} +import { parseConfigFileWithSystem } from "../../src/cli/tsconfig"; +import { normalizeSlashes } from "../../src/utils"; -export function buildVirtualProject(rootNames: string[], options: tstl.CompilerOptions): BuildVirtualProjectResult { +export function transpileFilesResult(rootNames: string[], options: tstl.CompilerOptions) { options.skipLibCheck = true; options.types = []; - const { diagnostics, emitResult } = tstl.transpileFiles(rootNames, options); - const emittedFiles = emitResult.map(result => path.relative(__dirname, result.name).replace(/\\/g, "/")).sort(); + const emittedFiles: ts.OutputFile[] = []; + const { diagnostics } = tstl.transpileFiles(rootNames, options, (fileName, text, writeByteOrderMark) => { + const name = normalizeSlashes(path.relative(__dirname, fileName)); + emittedFiles.push({ name, text, writeByteOrderMark }); + }); + + return { diagnostics, emittedFiles }; +} + +export function transpileProjectResult(configFileName: string) { + const parseResult = parseConfigFileWithSystem(configFileName); + if (parseResult.errors.length > 0) { + return { diagnostics: parseResult.errors, emittedFiles: [] }; + } - return { diagnostics, emitResult, emittedFiles }; + return transpileFilesResult(parseResult.fileNames, parseResult.options); } diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index c9956571e..d28f4bf25 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -1,5 +1,3 @@ -import * as path from "path"; -import * as ts from "typescript"; import { LuaLibImportKind } from "../../src"; import * as diagnosticFactories from "../../src/transpilation/diagnostics"; import * as util from "../util"; @@ -12,21 +10,6 @@ test("import module -> main", () => { .expectToEqual({ value: true }); }); -test("bundle file name", () => { - const { transpiledFiles } = util.testModule` - export { value } from "./module"; - ` - .addExtraFile("module.ts", "export const value = true") - .setOptions({ luaBundle: "mybundle.lua", luaBundleEntry: "main.ts" }) - .expectToHaveNoDiagnostics() - .getLuaResult(); - - expect(transpiledFiles).toHaveLength(1); - expect(transpiledFiles[0].fileName).toBe( - path.join(ts.sys.getCurrentDirectory(), "mybundle.lua").replace(/\\/g, "/") - ); -}); - test("import chain export -> reexport -> main", () => { util.testBundle` export { value } from "./reexport"; diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 96ffec05f..84a6596a6 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -146,7 +146,7 @@ test.each([ ])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); - const consumer = await new SourceMapConsumer(file.sourceMap); + const consumer = await new SourceMapConsumer(file.luaSourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { const luaPosition = lineAndColumnOf(file.lua, luaPattern); const mappedPosition = consumer.originalPositionFor(luaPosition); @@ -190,11 +190,11 @@ test.each([ .setMainFileName(fileName) .getMainLuaFileResult(); - const sourceMap = JSON.parse(file.sourceMap); + const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); expect(sourceMap.sources[0]).toBe(mapSource); - const consumer = await new SourceMapConsumer(file.sourceMap); + const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); expect(consumer.sources[0]).toBe(fullSource); }); @@ -212,7 +212,7 @@ test.each([ .expectToHaveNoDiagnostics() .getMainLuaFileResult(); - const sourceMap = JSON.parse(file.sourceMap); + const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sourceRoot).toBe(mapSourceRoot); }); @@ -227,7 +227,7 @@ test.each([ ])("Source map has correct name mappings (%p)", async ({ code, name }) => { const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); - const consumer = await new SourceMapConsumer(file.sourceMap); + const consumer = await new SourceMapConsumer(file.luaSourceMap); const typescriptPosition = lineAndColumnOf(code, name); let mappedName: string | undefined; consumer.eachMapping(mapping => { @@ -289,14 +289,15 @@ test("Inline sourcemaps", () => { const file = util .testFunction(code) - .setOptions({ inlineSourceMap: true }) + .setOptions({ inlineSourceMap: true }) // We can't disable 'sourceMap' option because it's used for comparison + .disableSemanticCheck() // TS5053: Option 'sourceMap' cannot be specified with option 'inlineSourceMap'. .expectToMatchJsResult() .getMainLuaFileResult(); const [, inlineSourceMapMatch] = file.lua.match(/--# sourceMappingURL=data:application\/json;base64,([A-Za-z0-9+/=]+)/) ?? []; const inlineSourceMap = Buffer.from(inlineSourceMapMatch, "base64").toString(); - expect(file.sourceMap).toBe(inlineSourceMap); + expect(inlineSourceMap).toBe(file.luaSourceMap); }); // Helper functions diff --git a/test/util.ts b/test/util.ts index ee8b8e892..560b0102f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -8,6 +8,7 @@ import * as prettyFormat from "pretty-format"; import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; +import { createEmitOutputCollector } from "../src/transpilation/output-collector"; export * from "./legacy-utils"; @@ -40,43 +41,6 @@ export function testEachVersion( } } -interface TranspiledJsFile { - fileName: string; - js?: string; - sourceMap?: string; -} - -interface TranspileJsResult { - diagnostics: ts.Diagnostic[]; - transpiledFiles: TranspiledJsFile[]; -} - -function transpileJs(program: ts.Program): TranspileJsResult { - const transpiledFiles: TranspiledJsFile[] = []; - const updateTranspiledFile = (fileName: string, update: Omit) => { - const file = transpiledFiles.find(f => f.fileName === fileName); - if (file) { - Object.assign(file, update); - } else { - transpiledFiles.push({ fileName, ...update }); - } - }; - - const { diagnostics } = program.emit(undefined, (fileName, data, _bom, _onError, sourceFiles = []) => { - for (const sourceFile of sourceFiles) { - const isJs = fileName.endsWith(".js"); - const isSourceMap = fileName.endsWith(".js.map"); - if (isJs) { - updateTranspiledFile(sourceFile.fileName, { js: data }); - } else if (isSourceMap) { - updateTranspiledFile(sourceFile.fileName, { sourceMap: data }); - } - } - }); - - return { transpiledFiles, diagnostics: [...diagnostics] }; -} - function executeLua(code: string): any { const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); @@ -169,7 +133,7 @@ export class ExecutionError extends Error { } } -export type ExecutableTranspiledFile = tstl.TranspiledFile & { lua: string; sourceMap: string }; +export type ExecutableTranspiledFile = tstl.TranspiledFile & { lua: string; luaSourceMap: string }; export type TapCallback = (builder: TestBuilder) => void; export abstract class TestBuilder { constructor(protected _tsCode: string) {} @@ -221,6 +185,7 @@ export abstract class TestBuilder { moduleResolution: ts.ModuleResolutionKind.NodeJs, resolveJsonModule: true, experimentalDecorators: true, + sourceMap: true, }; public setOptions(options: tstl.CompilerOptions = {}): this { expect(this.hasProgram).toBe(false); @@ -263,15 +228,21 @@ export abstract class TestBuilder { } @memoize - public getLuaResult(): tstl.TranspileResult { + public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); - const result = tstl.transpile({ program, customTransformers: this.customTransformers }); + const collector = createEmitOutputCollector(); + const { diagnostics: transpileDiagnostics } = new tstl.Transpiler().emit({ + program, + customTransformers: this.customTransformers, + writeFile: collector.writeFile, + }); + const diagnostics = ts.sortAndDeduplicateDiagnostics([ ...ts.getPreEmitDiagnostics(program), - ...result.diagnostics, + ...transpileDiagnostics, ]); - return { ...result, diagnostics: [...diagnostics] }; + return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; } @memoize @@ -279,8 +250,8 @@ export abstract class TestBuilder { const { transpiledFiles } = this.getLuaResult(); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(x => x.fileName === this.mainFileName); - expect(mainFile).toMatchObject({ lua: expect.any(String), sourceMap: expect.any(String) }); + : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)); + expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; } @@ -296,16 +267,20 @@ export abstract class TestBuilder { } @memoize - public getJsResult(): TranspileJsResult { + public getJsResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); program.getCompilerOptions().module = ts.ModuleKind.CommonJS; - return transpileJs(program); + + const collector = createEmitOutputCollector(); + const { diagnostics } = program.emit(undefined, collector.writeFile); + return { transpiledFiles: collector.files, diagnostics: [...diagnostics] }; } @memoize protected getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); - const code = transpiledFiles.find(x => x.fileName === this.mainFileName)?.js; + const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) + ?.js; assert(code !== undefined); const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; From 5a292c2459b52c9181e9e52ea8b44360a613550f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 13 Jul 2020 21:47:07 +0200 Subject: [PATCH 284/764] 0.35.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 006e8b177..2a7114663 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.34.0", + "version": "0.35.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 57044a644..744d4571b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.34.0", + "version": "0.35.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 110b56f57045cd7cae2088f31e15ffac84036c84 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 13 Jul 2020 22:16:28 +0200 Subject: [PATCH 285/764] Changelog 0.35.0 --- CHANGELOG.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 044cba2e3..25033b16f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,18 @@ # Changelog -## Unreleased - -- `Function.length` is supported now - +## 0.35.0 + +- In preparation for some new features, some public APIs have been changed: + - High-level APIs that read input files from the file system (`transpileFiles` and `transpileProject`) now write transpiled files by default. This behavior can be changed by providing a `writeFile` callback, similarly to TypeScript's `program.emit`. + - `transpile` and `emitTranspiledFiles` functions have been replaced with the `Transpiler` class. See [documentation](https://typescripttolua.github.io/docs/api/overview#low-level-api) for usage examples. +- Fixed `declarationDir` option not being respected. +- `Function.length` is supported now. +- String iteration is now supported. +- Exposed `parseConfigFileWithSystem` to parse _tsconfig.json_ files as part of the tstl API. - Fixed `string.replace` incorrectly escaping some `replaceValue` characters (`().+-*?[^$`) +- Fixed several other string operations behaving differently from JS (mostly regarding indices out of bounds and NaN arguments). +- Fixed a bug where the length argument of `String.prototype.substr` was evaluated twice. +- Fixed some missing dependencies in LuaLib classes (Map, Set, WeakMap, WeakSet) ## 0.34.0 From 8dd12a93778fb2465cbcf393ad72a68915a75e23 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 1 Aug 2020 07:20:39 -0600 Subject: [PATCH 286/764] fixed declarations that reference their own identifiers (#910) * fixed variable declarations that reference their own identifiers in the initializer * Update src/transformation/utils/lua-ast.ts Co-authored-by: ark120202 * compiler error fix * moved tests to assignments Co-authored-by: Tom Co-authored-by: ark120202 --- src/transformation/utils/lua-ast.ts | 25 +++++++++++--------- test/unit/assignments.spec.ts | 36 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 236e32437..b9b600c90 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -4,8 +4,7 @@ import * as lua from "../../LuaAST"; import { assert, castArray } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; -import { peekScope, ScopeType } from "./scope"; -import { isFunctionType } from "./typescript"; +import { peekScope, ScopeType, Scope } from "./scope"; import { transformLuaLibFunction } from "./lualib"; import { LuaLibFeature } from "../../LuaLib"; @@ -129,6 +128,17 @@ export function createHoistableVariableDeclarationStatement( return declaration; } +function hasMultipleReferences(scope: Scope, identifiers: lua.Identifier | lua.Identifier[]) { + const scopeSymbols = scope.referencedSymbols; + if (!scopeSymbols) { + return false; + } + + const referenceLists = castArray(identifiers).map(i => i.symbolId && scopeSymbols.get(i.symbolId)); + + return referenceLists.some(symbolRefs => symbolRefs && symbolRefs.length > 1); +} + export function createLocalOrExportedOrGlobalDeclaration( context: TransformationContext, lhs: lua.Identifier | lua.Identifier[], @@ -163,15 +173,8 @@ export function createLocalOrExportedOrGlobalDeclaration( const isTopLevelVariable = scope.type === ScopeType.File; if (context.isModule || !isTopLevelVariable) { - const isPossibleWrappedFunction = - !isFunctionDeclaration && - tsOriginal && - ts.isVariableDeclaration(tsOriginal) && - tsOriginal.initializer && - isFunctionType(context, context.checker.getTypeAtLocation(tsOriginal.initializer)); - - if (isPossibleWrappedFunction || scope.type === ScopeType.Switch) { - // Split declaration and assignment for wrapped function types to allow recursion + if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { + // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } else { diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 02e1a3b9b..7ae3e1bb0 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -323,3 +323,39 @@ test.each([ return { r, o, a }; `.expectToMatchJsResult(); }); + +test("local variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return "foo"; + } + + let bar = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); + +test("local multiple variable declaration referencing self indirectly", () => { + util.testFunction` + let cb: () => void; + + function foo(newCb: () => void) { + cb = newCb; + return ["a", "foo", "c"]; + } + + let [a, bar, c] = foo(() => { + bar = "bar"; + }); + + cb(); + return bar; + `.expectToMatchJsResult(); +}); From 1093e8f084155bcf1a0b57c0405808b8da4dc30c Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 14 Sep 2020 17:44:25 +1000 Subject: [PATCH 287/764] Update to TypeScript 4 (#914) * Print numbers overflowing the float limit as math.huge * Update TypeScript * Equalize Object.assign change * Use ts-ignore instead of Object.assign * Update dependencies, fix minor issues * Add package-lock.json changes * Update package.json Co-authored-by: ark120202 * Remove some skipped accessors tests, TypeScript no longer accepts that code * Rename transformFunctionBodyStatements -> transformFunctionBodyContent * Slight refactor for return.ts Co-authored-by: ark120202 --- package-lock.json | 333 +++++++++++++++--- package.json | 6 +- .../utils/assignment-validation.ts | 4 +- .../visitors/binary-expression/compound.ts | 7 +- .../visitors/binary-expression/index.ts | 31 +- .../visitors/class/members/constructor.ts | 4 +- src/transformation/visitors/function.ts | 29 +- src/transformation/visitors/return.ts | 63 ++-- test/unit/classes/accessors.spec.ts | 72 ---- 9 files changed, 365 insertions(+), 184 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2a7114663..fa1a4185c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1671,6 +1671,32 @@ "chalk": "^3.0.0" } }, + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@sinonjs/commons": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", @@ -1736,12 +1762,6 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "@types/eslint-visitor-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", - "dev": true - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -1940,61 +1960,57 @@ } }, "@typescript-eslint/parser": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.31.0.tgz", - "integrity": "sha512-uph+w6xUOlyV2DLSC6o+fBDzZ5i7+3/TxAsH4h3eC64tlga57oMb96vVlXoMwjR/nN+xyWlsnxtbDkB46M2EPQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", + "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", "dev": true, "requires": { - "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.31.0", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-visitor-keys": "^1.1.0" + "@typescript-eslint/scope-manager": "4.1.0", + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/typescript-estree": "4.1.0", + "debug": "^4.1.1" }, "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", + "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", "dev": true, "requires": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0", "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", + "globby": "^11.0.1", "is-glob": "^4.0.1", "lodash": "^4.17.15", - "semver": "^6.3.0", + "semver": "^7.3.2", "tsutils": "^3.17.1" } }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", "dev": true } } }, + "@typescript-eslint/scope-manager": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", + "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0" + } + }, + "@typescript-eslint/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", + "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "dev": true + }, "@typescript-eslint/typescript-estree": { "version": "2.23.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", @@ -2027,6 +2043,24 @@ } } }, + "@typescript-eslint/visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", + "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.1.0", + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + } + } + }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", @@ -2160,6 +2194,12 @@ "is-string": "^1.0.5" } }, + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, "array-unique": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", @@ -2836,6 +2876,23 @@ "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", "dev": true }, + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "requires": { + "path-type": "^4.0.0" + }, + "dependencies": { + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -3603,6 +3660,20 @@ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, + "fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + } + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -3615,6 +3686,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -3847,6 +3927,28 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", @@ -7193,6 +7295,12 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -7987,6 +8095,12 @@ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -8011,6 +8125,12 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "rxjs": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", @@ -8849,29 +8969,142 @@ } }, "ts-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.0.0.tgz", - "integrity": "sha512-eBpWH65mGgzobuw7UZy+uPP9lwu+tPp60o324ASRX4Ijg8UC5dl2zcge4kkmqr2Zeuk9FwIjvCTOPuNMEyGWWw==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", + "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", "dev": true, "requires": { + "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", + "jest-util": "26.x", "json5": "2.x", "lodash.memoize": "4.x", "make-error": "1.x", - "micromatch": "4.x", "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "18.x" }, "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/jest": { + "version": "26.0.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", + "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "dev": true, + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + } + }, + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-util": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "dev": true, + "requires": { + "@jest/types": "^26.3.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, + "pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + } + }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -8954,9 +9187,9 @@ } }, "typescript": { - "version": "3.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", - "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==" + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==" }, "union-value": { "version": "1.0.1", diff --git a/package.json b/package.json index 744d4571b..a149df59c 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "^3.9.2" + "typescript": ">=4.0.2" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -47,7 +47,7 @@ "@types/node": "^13.7.7", "@types/resolve": "1.14.0", "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^2.31.0", + "@typescript-eslint/parser": "^4.1.0", "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", @@ -58,7 +58,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "prettier": "^2.0.5", - "ts-jest": "^26.0.0", + "ts-jest": "^26.3.0", "ts-node": "^8.6.2" } } diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index a31a24fdf..e62045248 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -34,8 +34,8 @@ export function validateAssignment( validateFunctionAssignment(context, node, fromType, toType, toName); - const fromTypeNode = context.checker.typeToTypeNode(fromType); - const toTypeNode = context.checker.typeToTypeNode(toType); + const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined); + const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined); if (!fromTypeNode || !toTypeNode) { return; } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 0eec44875..c82fe6862 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -48,7 +48,7 @@ type CompoundAssignmentToken = | ts.SyntaxKind.GreaterThanGreaterThanToken | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; -const compoundToAssignmentTokens: Record = { +const compoundToAssignmentTokens: Partial> = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, @@ -66,8 +66,9 @@ const compoundToAssignmentTokens: Record token in compoundToAssignmentTokens; -export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => - compoundToAssignmentTokens[token]; +export const unwrapCompoundAssignmentToken = ( + token: ts.CompoundAssignmentOperator +): CompoundAssignmentToken | undefined => compoundToAssignmentTokens[token]; export function transformCompoundAssignmentExpression( context: TransformationContext, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 356b2bcff..f150d848e 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; +import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf, unsupportedNodeKind } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -77,14 +77,13 @@ export const transformBinaryExpression: FunctionVisitor = ( } if (isCompoundAssignmentToken(operator)) { - return transformCompoundAssignmentExpression( - context, - node, - node.left, - node.right, - unwrapCompoundAssignmentToken(operator), - false - ); + const token = unwrapCompoundAssignmentToken(operator); + if (!token) { + context.diagnostics.push(unsupportedNodeKind(node, operator)); + return lua.createNilLiteral(node); + } + + return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false); } switch (operator) { @@ -157,13 +156,13 @@ export function transformBinaryExpressionStatement( if (isCompoundAssignmentToken(operator)) { // +=, -=, etc... - return transformCompoundAssignmentStatement( - context, - expression, - expression.left, - expression.right, - unwrapCompoundAssignmentToken(operator) - ); + const token = unwrapCompoundAssignmentToken(operator); + if (!token) { + context.diagnostics.push(unsupportedNodeKind(node, operator)); + return; + } + + return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token); } else if (operator === ts.SyntaxKind.EqualsToken) { return transformAssignmentStatement(context, expression as ts.AssignmentExpression); } else if (operator === ts.SyntaxKind.CommaToken) { diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index fe25a21b2..571c1022c 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -3,7 +3,7 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; -import { transformFunctionBodyHeader, transformFunctionBodyStatements, transformParameters } from "../../function"; +import { transformFunctionBodyHeader, transformFunctionBodyContent, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; @@ -28,7 +28,7 @@ export function transformConstructorDeclaration( // Transform body const scope = pushScope(context, ScopeType.Function); - const body = transformFunctionBodyStatements(context, statement.body); + const body = transformFunctionBodyContent(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( context, diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index cfbd8622d..b62a115be 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,6 +15,7 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; +import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; function transformParameterDefaultValueDeclaration( @@ -52,7 +53,12 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); } -export function transformFunctionBodyStatements(context: TransformationContext, body: ts.Block): lua.Statement[] { +export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { + if (!ts.isBlock(body)) { + const returnStatement = transformExpressionBodyToReturnStatement(context, body); + return [returnStatement]; + } + const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); return bodyStatements; } @@ -107,11 +113,11 @@ export function transformFunctionBodyHeader( export function transformFunctionBody( context: TransformationContext, parameters: ts.NodeArray, - body: ts.Block, + body: ts.ConciseBody, spreadIdentifier?: lua.Identifier ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); - const bodyStatements = transformFunctionBodyStatements(context, body); + const bodyStatements = transformFunctionBodyContent(context, body); const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); return [[...headerStatements, ...bodyStatements], scope]; @@ -184,18 +190,13 @@ export function transformFunctionToExpression( flags |= lua.FunctionExpressionFlags.Declaration; } - let body: ts.Block; - if (ts.isBlock(node.body)) { - body = node.body; - } else { - const returnExpression = ts.createReturn(node.body); - body = ts.createBlock([returnExpression]); - returnExpression.parent = body; - if (node.body) body.parent = node.body.parent; - } - const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); - const [transformedBody, functionScope] = transformFunctionBody(context, node.parameters, body, spreadIdentifier); + const [transformedBody, functionScope] = transformFunctionBody( + context, + node.parameters, + node.body, + spreadIdentifier + ); const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), paramNames, diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 970db6be0..c5ec3c740 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -1,12 +1,51 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; +import { FunctionVisitor, TransformationContext } from "../context"; import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; +function transformExpressionsInReturn( + context: TransformationContext, + node: ts.Expression, + insideTryCatch: boolean +): lua.Expression[] { + if (!isInTupleReturnFunction(context, node)) { + return [context.transformExpression(node)]; + } + + let results: lua.Expression[]; + const expressionType = context.checker.getTypeAtLocation(node); + + // Parent function is a TupleReturn function + if (ts.isArrayLiteralExpression(node)) { + // If return expression is an array literal, leave out brackets. + results = node.elements.map(e => context.transformExpression(e)); + } else if (!isTupleReturnCall(context, node) && isArrayType(context, expressionType)) { + // If return expression is an array-type and not another TupleReturn call, unpack it + results = [createUnpackCall(context, context.transformExpression(node), node)]; + } else { + results = [context.transformExpression(node)]; + } + + // Wrap tupleReturn results when returning inside try/catch + if (insideTryCatch) { + results = [wrapInTable(...results)]; + } + + return results; +} + +export function transformExpressionBodyToReturnStatement( + context: TransformationContext, + node: ts.Expression +): lua.Statement { + const expressions = transformExpressionsInReturn(context, node, false); + return lua.createReturnStatement(expressions, node); +} + export const transformReturnStatement: FunctionVisitor = (statement, context) => { // Bubble up explicit return flag and check if we're inside a try/catch block let insideTryCatch = false; @@ -29,27 +68,7 @@ export const transformReturnStatement: FunctionVisitor = (st validateAssignment(context, statement, expressionType, returnType); } - if (isInTupleReturnFunction(context, statement)) { - // Parent function is a TupleReturn function - if (ts.isArrayLiteralExpression(statement.expression)) { - // If return expression is an array literal, leave out brackets. - results = statement.expression.elements.map(e => context.transformExpression(e)); - } else if (!isTupleReturnCall(context, statement.expression) && isArrayType(context, expressionType)) { - // If return expression is an array-type and not another TupleReturn call, unpack it - results = [ - createUnpackCall(context, context.transformExpression(statement.expression), statement.expression), - ]; - } else { - results = [context.transformExpression(statement.expression)]; - } - - // Wrap tupleReturn results when returning inside try/catch - if (insideTryCatch) { - results = [wrapInTable(...results)]; - } - } else { - results = [context.transformExpression(statement.expression)]; - } + results = transformExpressionsInReturn(context, statement.expression, insideTryCatch); } else { // Empty return results = []; diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 4004a43f2..8a39fb21b 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -23,34 +23,6 @@ test("get accessor in base class", () => { `.expectToMatchJsResult(); }); -test.skip("get accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - get foo() { return this._foo + "bar"; } - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - -test.skip("get accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "foo"; - get foo() { return this._foo; } - } - class Bar extends Foo { - foo = "bar"; - } - const b = new Bar(); - return b.foo; - `.expectToMatchJsResult(); -}); - test("get accessor override accessor", () => { util.testFunction` class Foo { @@ -125,37 +97,6 @@ test("set accessor in base class", () => { `.expectToMatchJsResult(); }); -test("set accessor override", () => { - util.testFunction` - class Foo { - _foo = "foo"; - foo = "foo"; - } - class Bar extends Foo { - set foo(val: string) { this._foo = val; } - } - const b = new Bar(); - b.foo = "bar" - return b._foo; - `.expectToMatchJsResult(); -}); - -test("set accessor overridden", () => { - util.testFunction` - class Foo { - _foo = "baz"; - set foo(val: string) { this._foo = val; } - } - class Bar extends Foo { - foo = "foo"; // triggers base class setter - } - const b = new Bar(); - const fooOriginal = b._foo; - b.foo = "bar" - return fooOriginal + b._foo; - `.expectToMatchJsResult(); -}); - test("set accessor override accessor", () => { util.testFunction` class Foo { @@ -250,19 +191,6 @@ test("static get accessor override", () => { `.expectToMatchJsResult(); }); -test.skip("static get accessor overridden", () => { - util.testFunction` - class Foo { - static _foo = "foo"; - static get foo() { return this._foo; } - } - class Bar extends Foo { - static foo = "bar"; - } - return Bar.foo; - `.expectToMatchJsResult(); -}); - test("static get accessor override accessor", () => { util.testFunction` class Foo { From 849f630d8199edc8b5742c98f9756b7d60aa66f9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 3 Oct 2020 18:42:06 +0200 Subject: [PATCH 288/764] Add in missing 4.0 compound assignments (#919) * Add in missing 4.0 compound assignments * Compound assignments 4.0 take 2 * Addressed PR comments * Removed obsolete exception case in transformBinaryExpression --- .../visitors/binary-expression/compound.ts | 87 +++++++++++- .../visitors/binary-expression/index.ts | 24 ++-- test/unit/assignments.spec.ts | 134 ++++++++++++++++++ 3 files changed, 223 insertions(+), 22 deletions(-) diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index c82fe6862..3b92ade58 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; +import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; @@ -46,9 +46,12 @@ type CompoundAssignmentToken = | ts.SyntaxKind.AsteriskAsteriskToken | ts.SyntaxKind.LessThanLessThanToken | ts.SyntaxKind.GreaterThanGreaterThanToken - | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken; + | ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken + | ts.SyntaxKind.BarBarToken + | ts.SyntaxKind.AmpersandAmpersandToken + | ts.SyntaxKind.QuestionQuestionToken; -const compoundToAssignmentTokens: Partial> = { +const compoundToAssignmentTokens: Record = { [ts.SyntaxKind.BarEqualsToken]: ts.SyntaxKind.BarToken, [ts.SyntaxKind.PlusEqualsToken]: ts.SyntaxKind.PlusToken, [ts.SyntaxKind.CaretEqualsToken]: ts.SyntaxKind.CaretToken, @@ -61,14 +64,16 @@ const compoundToAssignmentTokens: Partial token in compoundToAssignmentTokens; -export const unwrapCompoundAssignmentToken = ( - token: ts.CompoundAssignmentOperator -): CompoundAssignmentToken | undefined => compoundToAssignmentTokens[token]; +export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => + compoundToAssignmentTokens[token]; export function transformCompoundAssignmentExpression( context: TransformationContext, @@ -139,6 +144,15 @@ export function transformCompoundAssignmentExpression( const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); const assignStatements = transformAssignment(context, lhs, tmpIdentifier); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return createImmediatelyInvokedFunctionExpression( + [tmpDeclaration, ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs)], + tmpIdentifier, + expression + ); + } + return createImmediatelyInvokedFunctionExpression( [tmpDeclaration, ...assignStatements], tmpIdentifier, @@ -175,13 +189,74 @@ export function transformCompoundAssignmentStatement( [context.transformExpression(objExpression), context.transformExpression(indexExpression)] ); const accessExpression = lua.createTableIndexExpression(obj, index); + + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return [ + objAndIndexDeclaration, + ...transformSetterSkippingCompoundAssignment(context, accessExpression, operator, rhs, node), + ]; + } + const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, node); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return [objAndIndexDeclaration, assignStatement]; } else { + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + const luaLhs = context.transformExpression(lhs) as lua.AssignmentLeftHandSideExpression; + return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node); + } + // Simple statements // ${left} = ${left} ${replacementOperator} ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, node); return transformAssignment(context, lhs, operatorExpression); } } + +/* These setter-skipping operators will not execute the setter if result does not change. + * x.y ||= z does NOT call the x.y setter if x.y is already true. + * x.y &&= z does NOT call the x.y setter if x.y is already false. + * x.y ??= z does NOT call the x.y setter if x.y is already not nullish. + */ +type SetterSkippingCompoundAssignmentOperator = ts.LogicalOperator | ts.SyntaxKind.QuestionQuestionToken; + +function isSetterSkippingCompoundAssignmentOperator( + operator: ts.BinaryOperator +): operator is SetterSkippingCompoundAssignmentOperator { + return ( + operator === ts.SyntaxKind.AmpersandAmpersandToken || + operator === ts.SyntaxKind.BarBarToken || + operator === ts.SyntaxKind.QuestionQuestionToken + ); +} + +function transformSetterSkippingCompoundAssignment( + context: TransformationContext, + lhs: lua.AssignmentLeftHandSideExpression, + operator: SetterSkippingCompoundAssignmentOperator, + rhs: ts.Expression, + node?: ts.Node +): lua.Statement[] { + // These assignments have the form 'if x then y = z', figure out what condition x is first. + let condition: lua.Expression; + + if (operator === ts.SyntaxKind.AmpersandAmpersandToken) { + condition = lhs; + } else if (operator === ts.SyntaxKind.BarBarToken) { + condition = lua.createUnaryExpression(lhs, lua.SyntaxKind.NotOperator); + } else if (operator === ts.SyntaxKind.QuestionQuestionToken) { + condition = lua.createBinaryExpression(lhs, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator); + } else { + assertNever(operator); + } + + // if condition then lhs = rhs end + return [ + lua.createIfStatement( + condition, + lua.createBlock([lua.createAssignmentStatement(lhs, context.transformExpression(rhs))]), + undefined, + node + ), + ]; +} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index f150d848e..001591c01 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf, unsupportedNodeKind } from "../../utils/diagnostics"; +import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -15,6 +15,7 @@ import { transformCompoundAssignmentStatement, unwrapCompoundAssignmentToken, } from "./compound"; +import { assert } from "../../../utils"; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -45,13 +46,18 @@ export function transformBinaryOperation( context: TransformationContext, left: lua.Expression, right: lua.Expression, - operator: BitOperator | SimpleOperator, + operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node ): lua.Expression { if (isBitOperator(operator)) { return transformBinaryBitOperation(context, node, left, right, operator); } + if (operator === ts.SyntaxKind.QuestionQuestionToken) { + assert(ts.isBinaryExpression(node)); + return transformNullishCoalescingExpression(context, node); + } + let luaOperator = simpleOperatorsToLua[operator]; // Check if we need to use string concat operator @@ -78,11 +84,6 @@ export const transformBinaryExpression: FunctionVisitor = ( if (isCompoundAssignmentToken(operator)) { const token = unwrapCompoundAssignmentToken(operator); - if (!token) { - context.diagnostics.push(unsupportedNodeKind(node, operator)); - return lua.createNilLiteral(node); - } - return transformCompoundAssignmentExpression(context, node, node.left, node.right, token, false); } @@ -131,10 +132,6 @@ export const transformBinaryExpression: FunctionVisitor = ( ); } - case ts.SyntaxKind.QuestionQuestionToken: { - return transformNullishCoalescingExpression(context, node); - } - default: return transformBinaryOperation( context, @@ -157,11 +154,6 @@ export function transformBinaryExpressionStatement( if (isCompoundAssignmentToken(operator)) { // +=, -=, etc... const token = unwrapCompoundAssignmentToken(operator); - if (!token) { - context.diagnostics.push(unsupportedNodeKind(node, operator)); - return; - } - return transformCompoundAssignmentStatement(context, expression, expression.left, expression.right, token); } else if (operator === ts.SyntaxKind.EqualsToken) { return transformAssignmentStatement(context, expression as ts.AssignmentExpression); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 7ae3e1bb0..d2d80f08b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -121,6 +121,9 @@ test.each([ "x ^= y", "x <<= y", "x >>>= y", + "x &&= y", + "x ||= y", + "x ??= y", ])("Operator assignment statements (%p)", statement => { util.testFunction` let x = 3; @@ -359,3 +362,134 @@ test("local multiple variable declaration referencing self indirectly", () => { return bar; `.expectToMatchJsResult(); }); + +describe.each(["x &&= y", "x ||= y"])("boolean compound assignment (%p)", assignment => { + const booleanCases = [ + [false, false], + [false, true], + [true, false], + [true, true], + ]; + test.each(booleanCases)("matches JS", (x, y) => { + util.testFunction` + let x = ${x}; + let y = ${y}; + ${assignment}; + return x; + `.expectToMatchJsResult(); + }); +}); + +test.each([undefined, 3])("nullish coalescing compound assignment", initialValue => { + util.testFunction` + let x: number = ${util.formatCode(initialValue)}; + x ??= 5; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment lhs false", () => { + util.testFunction` + let x = false; + x ??= true; + return x; + `.expectToMatchJsResult(); +}); + +test("nullish coalescing compound assignment side effect not evaluated", () => { + util.testFunction` + let x = 3; + let y = 10; + x ??= (y += 5); + return [x, y]; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + inst.prop ${operator} 8; + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "||=", initialValue: true }, + { operator: "&&=", initialValue: false }, + { operator: "??=", initialValue: false }, +])("compound assignment short-circuits and does not call setter as expression", ({ operator, initialValue }) => { + /* + In JS if the rhs does not affect the resulting value, the setter is NOT called: + * x.y ||= z is translated to x.y || (x.y = z). + * x.y &&= z is translated to x.y && (x.y = z). + * x.y ||= z is translated to x.y !== undefined && (x.y = z). + + Test if setter in Lua is called same nr of times as in JS. + */ + util.testModule` + export let setterCalled = 0; + + class MyClass { + + get prop(): any { + return ${initialValue}; + } + + set prop(value: any) { + setterCalled++; + } + } + + const inst = new MyClass(); + export const result = (inst.prop ${operator} 8); + `.expectToMatchJsResult(); +}); + +test.each([ + { operator: "+=", initialValue: 3 }, + { operator: "-=", initialValue: 10 }, + { operator: "*=", initialValue: 4 }, + { operator: "/=", initialValue: 20 }, + { operator: "||=", initialValue: false }, + { operator: "&&=", initialValue: true }, + { operator: "??=", initialValue: undefined }, +])("compound assignment side effects", ({ operator, initialValue }) => { + // Test if when assigning to something with potential side effects, they are only evaluated once. + util.testFunction` + const obj: { prop: any} = { prop: ${initialValue} }; + + let objGot = 0; + function getObj() { + objGot++; + return obj; + } + + getObj().prop ${operator} 4; + + return [obj, objGot]; + `.expectToMatchJsResult(); +}); From 7b6580b640368d7198dc27551dc2a558e0b0a036 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 8 Oct 2020 18:34:35 +0200 Subject: [PATCH 289/764] Implement parseInt and parseFloat (#920) * Alias parseInt parseFloat to tonumber * Implemented ParseFloat and ParseInt as lualib functions * PR comments --- src/LuaLib.ts | 2 + src/lualib/ParseFloat.ts | 11 ++++++ src/lualib/ParseInt.ts | 41 ++++++++++++++++++++ src/lualib/declarations/math.d.ts | 3 ++ src/lualib/declarations/string.d.ts | 1 + src/transformation/builtins/global.ts | 4 ++ test/unit/builtins/numbers.spec.ts | 54 +++++++++++++++++++++++++++ 7 files changed, 116 insertions(+) create mode 100644 src/lualib/ParseFloat.ts create mode 100644 src/lualib/ParseInt.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index c476882c7..1898be2cf 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -49,6 +49,8 @@ export enum LuaLibFeature { ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", + ParseFloat = "ParseFloat", + ParseInt = "ParseInt", Set = "Set", WeakMap = "WeakMap", WeakSet = "WeakSet", diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts new file mode 100644 index 000000000..1cd069111 --- /dev/null +++ b/src/lualib/ParseFloat.ts @@ -0,0 +1,11 @@ +function __TS__ParseFloat(this: void, numberString: string): number { + // Check if string is infinity + const infinityMatch = string.match(numberString, "^%s*(-?Infinity)"); + if (infinityMatch) { + // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with + return infinityMatch[0] === "-" ? -Infinity : Infinity; + } + + const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")); + return number ?? NaN; +} diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts new file mode 100644 index 000000000..b1d5710a0 --- /dev/null +++ b/src/lualib/ParseInt.ts @@ -0,0 +1,41 @@ +const __TS__parseInt_base_pattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; + +function __TS__ParseInt(this: void, numberString: string, base?: number): number { + // Check which base to use if none specified + if (base === undefined) { + base = 10; + const hexMatch = string.match(numberString, "^%s*-?0[xX]"); + if (hexMatch) { + base = 16; + numberString = string.match(hexMatch, "-") + ? "-" + numberString.substr(hexMatch.length) + : numberString.substr(hexMatch.length); + } + } + + // Check if base is in bounds + if (base < 2 || base > 36) { + return NaN; + } + + // Calculate string match pattern to use + const allowedDigits = + base <= 10 + ? __TS__parseInt_base_pattern.substring(0, base) + : __TS__parseInt_base_pattern.substr(0, 10 + 2 * (base - 10)); + const pattern = `^%s*(-?[${allowedDigits}]*)`; + + // Try to parse with Lua tonumber + const number = tonumber(string.match(numberString, pattern), base); + + if (number === undefined) { + return NaN; + } + + // Lua uses a different floor convention for negative numbers than JS + if (number >= 0) { + return math.floor(number); + } else { + return math.ceil(number); + } +} diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts index 837f717f9..54568c031 100644 --- a/src/lualib/declarations/math.d.ts +++ b/src/lualib/declarations/math.d.ts @@ -8,4 +8,7 @@ declare namespace math { function atan(y: number, x?: number): number; function atan2(y: number, x: number): number; + + function ceil(x: number): number; + function floor(x: number): number; } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index e8d657da6..2857690cb 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -13,4 +13,5 @@ declare namespace string { ): [string, number]; function sub(s: string, i: number, j?: number): string; function format(formatstring: string, ...args: any[]): string; + function match(string: string, pattern: string): string; } diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 2021951a5..79f359bbd 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -30,5 +30,9 @@ export function transformGlobalCall( node, ...numberParameters ); + case "parseFloat": + return transformLuaLibFunction(context, LuaLibFeature.ParseFloat, node, ...parameters); + case "parseInt": + return transformLuaLibFunction(context, LuaLibFeature.ParseInt, node, ...parameters); } } diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 2f52c1d7d..0ae65efb3 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -78,3 +78,57 @@ test("number intersected method", () => { test("numbers overflowing the float limit become math.huge", () => { util.testExpression`1e309`.expectToMatchJsResult(); }); + +describe.each(["parseInt", "parseFloat"])("parse numbers with %s", parseFunction => { + const numberStrings = ["3", "3.0", "9", "42", "239810241", "-20391", "3.1415", "2.7182", "-34910.3"]; + + test.each(numberStrings)("parses (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test("empty string", () => { + util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); + }); + + test("invalid string", () => { + util.testExpression`${parseFunction}("bla")`.expectToMatchJsResult(); + }); + + test.each(["1px", "2300m", "3,4", "452adkfl"])("trailing text (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + + test.each([" 3", " 4", " -231", " 1px"])("leading whitespace (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); +}); + +test.each(["Infinity", "-Infinity", " -Infinity"])("parseFloat handles Infinity", numberString => { + util.testExpression`parseFloat("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36", base: 8 }, + { numberString: "-36", base: 8 }, + { numberString: "100010101101", base: 2 }, + { numberString: "-100010101101", base: 2 }, + { numberString: "3F", base: 16 }, +])("parseInt with base (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + +test.each(["0x4A", "-0x42", "0X42", " 0x391", " -0x8F"])("parseInt detects hexadecimal", numberString => { + util.testExpression`parseInt("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([1, 37, -100])("parseInt with invalid base (%p)", base => { + util.testExpression`parseInt("11111", ${base})`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36px", base: 8 }, + { numberString: "10001010110231", base: 2 }, + { numberString: "3Fcolor", base: 16 }, +])("parseInt with base and trailing text (%p)", ({ numberString, base }) => { + util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); From c76813f91ae505089b5bef7f16543e7fe2f5c159 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 17 Oct 2020 15:26:32 +0500 Subject: [PATCH 290/764] `yield*` support (#923) * `yield*` support * Remove `.debug()` call --- src/LuaLib.ts | 1 + src/lualib/DelegatedYield.ts | 32 +++++++++++++++ src/lualib/Iterator.ts | 8 ++-- src/transformation/visitors/function.ts | 16 +++++--- test/unit/functions/generators.spec.ts | 53 +++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 src/lualib/DelegatedYield.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 1898be2cf..1b4c2aa2b 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -29,6 +29,7 @@ export enum LuaLibFeature { Class = "Class", ClassExtends = "ClassExtends", Decorate = "Decorate", + DelegatedYield = "DelegatedYield", Descriptors = "Descriptors", Error = "Error", FunctionBind = "FunctionBind", diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts new file mode 100644 index 000000000..6b524365a --- /dev/null +++ b/src/lualib/DelegatedYield.ts @@ -0,0 +1,32 @@ +function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { + if (typeof iterable === "string") { + for (const index of forRange(0, iterable.length - 1)) { + coroutine.yield(iterable[index]); + } + } else if ("____coroutine" in iterable) { + const co = iterable.____coroutine; + while (true) { + const [status, value] = coroutine.resume(co); + if (!status) throw value; + if (coroutine.status(co) === "dead") { + return value; + } else { + coroutine.yield(value); + } + } + } else if (iterable[Symbol.iterator]) { + const iterator = iterable[Symbol.iterator](); + while (true) { + const result = iterator.next(); + if (result.done) { + return result.value; + } else { + coroutine.yield(result.value); + } + } + } else { + for (const value of iterable as readonly T[]) { + coroutine.yield(value); + } + } +} diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index e55de6404..809ca69ee 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -26,15 +26,15 @@ function __TS__IteratorStringStep(this: string, index: number): [number, string] /** @tupleReturn */ function __TS__Iterator( this: void, - iterable: Iterable | GeneratorIterator | readonly T[] + iterable: string | GeneratorIterator | Iterable | readonly T[] ): [(...args: any[]) => [any, any] | [], ...any[]] { - if ("____coroutine" in iterable) { + if (typeof iterable === "string") { + return [__TS__IteratorStringStep, iterable, 0]; + } else if ("____coroutine" in iterable) { return [__TS__IteratorGeneratorStep, iterable]; } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; - } else if (typeof iterable === "string") { - return [__TS__IteratorStringStep, iterable, 0]; } else { return ipairs(iterable as readonly T[]) as any; } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index b62a115be..d3fb88a5a 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -279,9 +279,13 @@ export const transformFunctionDeclaration: FunctionVisitor = (expression, context) => - lua.createCallExpression( - lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), - expression.expression ? [context.transformExpression(expression.expression)] : [], - expression - ); +export const transformYieldExpression: FunctionVisitor = (expression, context) => { + const parameters = expression.expression ? [context.transformExpression(expression.expression)] : []; + return expression.asteriskToken + ? transformLuaLibFunction(context, LuaLibFeature.DelegatedYield, expression, ...parameters) + : lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("coroutine"), lua.createStringLiteral("yield")), + parameters, + expression + ); +}; diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 90fb67aa4..7065aecf6 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -51,6 +51,59 @@ test("for..of", () => { `.expectToMatchJsResult(); }); +describe("yield*", () => { + test("generator", () => { + util.testFunction` + function* subGenerator() { + yield 1; + yield 2; + yield 3; + } + + function* generator() { + yield 0; + return yield* subGenerator(); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("array", () => { + util.testFunction` + function* generator() { + return yield* [1, 2, 3]; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("string", () => { + util.testFunction` + function* generator() { + return yield* "abc"; + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); + + test("iterable", () => { + util.testFunction` + function* generator() { + return yield* new Set([1, 2, 3]); + } + + const it = generator(); + return [it.next(), it.next(), it.next(), it.next()]; + `.expectToMatchJsResult(); + }); +}); + test("function expression", () => { util.testFunction` const generator = function*() { From 70f3e392a71f8ed7deec6930a51bf2c97f499ec9 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sat, 17 Oct 2020 15:26:50 +0500 Subject: [PATCH 291/764] Add devcontainer.json configuration (#922) --- .devcontainer/devcontainer.json | 14 ++++++++++++++ .gitattributes | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..311827173 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,14 @@ +{ + "name": "TypeScriptToLua", + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "extensions": [ + "ark120202.vscode-typescript-to-lua", + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode" + ], + "postCreateCommand": "npm ci" +} diff --git a/.gitattributes b/.gitattributes index fcadb2cf9..6313b56c5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -* text eol=lf +* text=auto eol=lf From 5a6ba5667b7242afb42b3f1169d0d144a3f0125f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sun, 18 Oct 2020 23:57:12 +1000 Subject: [PATCH 292/764] Method and Method Property decorators (#905) * Improve decorator use cases * Implementing descriptors * Refactoring * Revert tsconfig change * Single pass over class members * Add and fix more tests * Move decorator descriptor tests to descriptors * Refactoring and more consistent naming * Inline object.ts lines * Remove unnecessary descriptor clone * Use assignment instead for simple descriptors * Stop throwing an error when deletion attempt was disallowed * Use expectToMatchJsResult again for descriptor test * Use expectToMatchJsResult for existing array test case * Update test/unit/classes/decorators.spec.ts Co-authored-by: ark120202 * Update test/unit/builtins/array.spec.ts Co-authored-by: ark120202 * Update src/lualib/ObjectGetOwnPropertyDescriptors.ts Co-authored-by: ark120202 * Fix tests for DeleteExpressions * Remove unnecessary question tokens from method * Fix array tests * Capture error in a variable * Move Decorators with descriptors tests to decorator tests * Move descriptors tests to object * Add more getOwnPropertyDescriptor tests * Refactor ObjectDefineProperty slightly * Remove Descriptors LuaLib feature * Remove bar property * Improve targetKind statement * Merge class member decorating tests Co-authored-by: ark120202 --- src/LuaLib.ts | 11 ++- src/lualib/CloneDescriptor.ts | 26 ++++++ src/lualib/Decorate.ts | 20 ++++- src/lualib/DecorateParam.ts | 3 + src/lualib/Delete.ts | 19 ++++ src/lualib/ObjectDefineProperty.ts | 29 ++++++ src/lualib/ObjectGetOwnPropertyDescriptor.ts | 6 ++ src/lualib/ObjectGetOwnPropertyDescriptors.ts | 5 ++ .../{Descriptors.ts => SetDescriptor.ts} | 39 ++++---- src/transformation/builtins/object.ts | 18 ++-- .../visitors/class/decorators.ts | 56 ++++++------ src/transformation/visitors/class/index.ts | 66 ++++++++------ .../visitors/class/members/accessors.ts | 22 ++--- .../visitors/class/members/constructor.ts | 9 +- .../visitors/class/members/fields.ts | 32 +++++++ .../visitors/class/members/method.ts | 73 ++++++++++++--- src/transformation/visitors/delete.ts | 48 ++++++---- .../visitors/expression-statement.ts | 6 -- .../__snapshots__/expressions.spec.ts.snap | 26 +++--- test/unit/builtins/array.spec.ts | 20 +++-- test/unit/builtins/object.spec.ts | 90 +++++++++++++++++++ test/unit/classes/decorators.spec.ts | 58 ++++++++++++ 22 files changed, 520 insertions(+), 162 deletions(-) create mode 100644 src/lualib/CloneDescriptor.ts create mode 100644 src/lualib/DecorateParam.ts create mode 100644 src/lualib/Delete.ts create mode 100644 src/lualib/ObjectDefineProperty.ts create mode 100644 src/lualib/ObjectGetOwnPropertyDescriptor.ts create mode 100644 src/lualib/ObjectGetOwnPropertyDescriptors.ts rename src/lualib/{Descriptors.ts => SetDescriptor.ts} (65%) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 1b4c2aa2b..fde43c604 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -28,9 +28,11 @@ export enum LuaLibFeature { ArraySetLength = "ArraySetLength", Class = "Class", ClassExtends = "ClassExtends", + CloneDescriptor = "CloneDescriptor", Decorate = "Decorate", + DecorateParam = "DecorateParam", + Delete = "Delete", DelegatedYield = "DelegatedYield", - Descriptors = "Descriptors", Error = "Error", FunctionBind = "FunctionBind", Generator = "Generator", @@ -45,14 +47,18 @@ export enum LuaLibFeature { NumberIsNaN = "NumberIsNaN", NumberToString = "NumberToString", ObjectAssign = "ObjectAssign", + ObjectDefineProperty = "ObjectDefineProperty", ObjectEntries = "ObjectEntries", ObjectFromEntries = "ObjectFromEntries", + ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor", + ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors", ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", ParseFloat = "ParseFloat", ParseInt = "ParseInt", Set = "Set", + SetDescriptor = "SetDescriptor", WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", @@ -82,11 +88,14 @@ export enum LuaLibFeature { const luaLibDependencies: Partial> = { ArrayFlat: [LuaLibFeature.ArrayConcat], ArrayFlatMap: [LuaLibFeature.ArrayConcat], + Decorate: [LuaLibFeature.CloneDescriptor], + Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], Error: [LuaLibFeature.New, LuaLibFeature.Class], FunctionBind: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], + ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], diff --git a/src/lualib/CloneDescriptor.ts b/src/lualib/CloneDescriptor.ts new file mode 100644 index 000000000..d74292bab --- /dev/null +++ b/src/lualib/CloneDescriptor.ts @@ -0,0 +1,26 @@ +function __TS__CloneDescriptor( + this: void, + { enumerable, configurable, get, set, writable, value }: PropertyDescriptor +): PropertyDescriptor { + const descriptor: PropertyDescriptor = { + enumerable: enumerable === true, + configurable: configurable === true, + }; + + const hasGetterOrSetter = get !== undefined || set !== undefined; + const hasValueOrWritableAttribute = writable !== undefined || value !== undefined; + + if (hasGetterOrSetter && hasValueOrWritableAttribute) { + throw "Invalid property descriptor. Cannot both specify accessors and a value or writable attribute."; + } + + if (get || set) { + descriptor.get = get; + descriptor.set = set; + } else { + descriptor.value = value; + descriptor.writable = writable === true; + } + + return descriptor; +} diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 15dbee15d..e5cad0218 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,7 +1,7 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: string, desc?: any): {} { +function __TS__Decorate(this: void, decorators: Function[], target: any, key?: any, desc?: any): {} { let result = target; for (let i = decorators.length; i >= 0; i--) { @@ -11,8 +11,22 @@ function __TS__Decorate(this: void, decorators: Function[], target: {}, key?: st if (key === undefined) { result = decorator(result); - } else if (desc !== undefined) { - result = decorator(target, key, result); + } else if (desc === true) { + const value = rawget(target, key); + const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) || { + configurable: true, + writable: true, + value, + }; + const desc = decorator(target, key, descriptor) || descriptor; + const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set; + if (isSimpleValue) { + rawset(target, key, desc.value); + } else { + __TS__SetDescriptor(target, key, { ...descriptor, ...desc }); + } + } else if (desc === false) { + result = decorator(target, key, desc); } else { result = decorator(target, key); } diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts new file mode 100644 index 000000000..ed0c28309 --- /dev/null +++ b/src/lualib/DecorateParam.ts @@ -0,0 +1,3 @@ +function __TS__DecorateParam(this: void, paramIndex: number, decorator: Function): {} { + return (target: Function, key?: string) => decorator(target, key, paramIndex); +} diff --git a/src/lualib/Delete.ts b/src/lualib/Delete.ts new file mode 100644 index 000000000..079dcb93d --- /dev/null +++ b/src/lualib/Delete.ts @@ -0,0 +1,19 @@ +function __TS__Delete(this: void, target: any, key: any): boolean { + const descriptors = __TS__ObjectGetOwnPropertyDescriptors(target); + const descriptor = descriptors[key]; + if (descriptor) { + if (!descriptor.configurable) { + throw `Cannot delete property ${key} of ${target}.`; + } + + descriptors[key] = undefined; + return true; + } + + if (target[key] !== undefined) { + target[key] = undefined; + return true; + } + + return false; +} diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts new file mode 100644 index 000000000..68297c420 --- /dev/null +++ b/src/lualib/ObjectDefineProperty.ts @@ -0,0 +1,29 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty +function __TS__ObjectDefineProperty(this: void, target: any, key: any, desc: PropertyDescriptor): object { + const luaKey = typeof key === "number" ? key + 1 : key; + const value = rawget(target, luaKey); + + const hasGetterOrSetter = desc.get !== undefined || desc.set !== undefined; + + let descriptor: PropertyDescriptor; + if (hasGetterOrSetter) { + if (value !== undefined) { + throw `Cannot redefine property: ${key}`; + } + + descriptor = desc; + } else { + const valueExists = value !== undefined; + descriptor = { + set: desc.set, + get: desc.get, + configurable: desc.configurable !== undefined ? desc.configurable : valueExists, + enumerable: desc.enumerable !== undefined ? desc.enumerable : valueExists, + writable: desc.writable !== undefined ? desc.writable : valueExists, + value: desc.value !== undefined ? desc.value : value, + }; + } + + __TS__SetDescriptor(target, luaKey, descriptor); + return target; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts new file mode 100644 index 000000000..84dab33df --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -0,0 +1,6 @@ +function __TS__ObjectGetOwnPropertyDescriptor(this: void, object: any, key: any): PropertyDescriptor | undefined { + const metatable = getmetatable(object); + if (!metatable) return; + if (!rawget(metatable, "_descriptors")) return; + return rawget(metatable, "_descriptors")[key]; +} diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts new file mode 100644 index 000000000..9adc0071e --- /dev/null +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -0,0 +1,5 @@ +function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { + const metatable = getmetatable(object); + if (!metatable) return {}; + return rawget(metatable, "_descriptors"); +} diff --git a/src/lualib/Descriptors.ts b/src/lualib/SetDescriptor.ts similarity index 65% rename from src/lualib/Descriptors.ts rename to src/lualib/SetDescriptor.ts index 7b6410ed6..49c7a0bf2 100644 --- a/src/lualib/Descriptors.ts +++ b/src/lualib/SetDescriptor.ts @@ -19,7 +19,7 @@ function ____descriptorIndex(this: any, key: string): void { return descriptor.get.call(this); } - return; + return descriptor.value; } } @@ -36,8 +36,13 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { if (descriptor) { if (descriptor.set) { descriptor.set.call(this, value); - } + } else { + if (descriptor.writable === false) { + throw `Cannot assign to read only property '${key}' of object '${this}'`; + } + descriptor.value = value; + } return; } } @@ -49,27 +54,19 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { } // It's also used directly in class transform to add descriptors to the prototype -function __TS__SetDescriptor(this: void, metatable: Metatable, prop: string, descriptor: PropertyDescriptor): void { - if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; - metatable._descriptors[prop] = descriptor; - - if (descriptor.get) metatable.__index = ____descriptorIndex; - if (descriptor.set) metatable.__newindex = ____descriptorNewindex; -} - -// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty( - this: void, - object: T, - prop: string, - descriptor: PropertyDescriptor -): T { - let metatable = getmetatable(object); +function __TS__SetDescriptor(this: void, target: any, key: any, desc: PropertyDescriptor, isPrototype = false): void { + let metatable = isPrototype ? target : getmetatable(target); if (!metatable) { metatable = {}; - setmetatable(object, metatable); + setmetatable(target, metatable); } - __TS__SetDescriptor(metatable, prop, descriptor); - return object; + const value = rawget(target, key); + if (value !== undefined) rawset(target, key, undefined); + + if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; + const descriptor = __TS__CloneDescriptor(desc); + metatable._descriptors[key] = descriptor; + metatable.__index = ____descriptorIndex; + metatable.__newindex = ____descriptorNewindex; } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 358bebbf5..2db793f91 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -9,20 +9,26 @@ export function transformObjectConstructorCall( expression: PropertyCallExpression ): lua.Expression | undefined { const method = expression.expression; - const parameters = transformArguments(context, expression.arguments); + const args = transformArguments(context, expression.arguments); const methodName = method.name.text; switch (methodName) { case "assign": - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...args); + case "defineProperty": + return transformLuaLibFunction(context, LuaLibFeature.ObjectDefineProperty, expression, ...args); case "entries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...args); case "fromEntries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...args); + case "getOwnPropertyDescriptor": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, expression, ...args); + case "getOwnPropertyDescriptors": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, expression, ...args); case "keys": - return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...args); case "values": - return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...args); default: context.diagnostics.push(unsupportedProperty(method.name, "Object", methodName)); } diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 5cae0cf17..4b913485c 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -2,42 +2,38 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { decoratorInvalidContext } from "../../utils/diagnostics"; -import { addExportToIdentifier } from "../../utils/export"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { transformIdentifier } from "../identifier"; -export function createConstructorDecorationStatement( - context: TransformationContext, - declaration: ts.ClassLikeDeclaration -): lua.AssignmentStatement | undefined { - const className = - declaration.name !== undefined - ? addExportToIdentifier(context, transformIdentifier(context, declaration.name)) - : lua.createAnonymousIdentifier(); - - const decorators = declaration.decorators; - if (!decorators) { - return undefined; +export function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression { + const expression = decorator.expression; + const type = context.checker.getTypeAtLocation(expression); + const callContext = getFunctionContextType(context, type); + if (callContext === ContextType.Void) { + context.diagnostics.push(decoratorInvalidContext(decorator)); } - const decoratorExpressions = decorators.map(decorator => { - const expression = decorator.expression; - const type = context.checker.getTypeAtLocation(expression); - const callContext = getFunctionContextType(context, type); - if (callContext === ContextType.Void) { - context.diagnostics.push(decoratorInvalidContext(decorator)); - } + return context.transformExpression(expression); +} - return context.transformExpression(expression); - }); +export function createDecoratingExpression( + context: TransformationContext, + kind: ts.SyntaxKind, + decorators: lua.Expression[], + targetTableName: lua.Expression, + targetFieldExpression?: lua.Expression +): lua.Expression { + const decoratorTable = lua.createTableExpression(decorators.map(e => lua.createTableFieldExpression(e))); + const trailingExpressions = [decoratorTable, targetTableName]; - const decoratorTable = lua.createTableExpression( - decoratorExpressions.map(expression => lua.createTableFieldExpression(expression)) - ); + if (targetFieldExpression) { + trailingExpressions.push(targetFieldExpression); + const isMethodOrAccessor = + kind === ts.SyntaxKind.MethodDeclaration || + kind === ts.SyntaxKind.GetAccessor || + kind === ts.SyntaxKind.SetAccessor; + trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral()); + } - return lua.createAssignmentStatement( - className, - transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, decoratorTable, className) - ); + return transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, ...trailingExpressions); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 59ecc10b7..d70095bff 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { getOrUpdate, isNonNull } from "../../../utils"; +import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { @@ -28,11 +28,15 @@ import { popScope, pushScope, ScopeType } from "../../utils/scope"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { createConstructorDecorationStatement } from "./decorators"; +import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; -import { transformClassInstanceFields } from "./members/fields"; -import { transformMethodDeclaration } from "./members/method"; +import { + createPropertyDecoratingExpression, + transformClassInstanceFields, + transformStaticPropertyDeclaration, +} from "./members/fields"; +import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; import { checkForLuaLibType } from "./new"; import { createClassSetup } from "./setup"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; @@ -134,7 +138,6 @@ function transformClassLikeDeclaration( const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); // Divide properties into static and non-static - const staticFields = properties.filter(isStaticNode); const instanceFields = properties.filter(prop => !isStaticNode(prop)); const result: lua.Statement[] = []; @@ -282,29 +285,42 @@ function transformClassLikeDeclaration( } } - // Transform methods - result.push( - ...classDeclaration.members - .filter(ts.isMethodDeclaration) - .map(m => transformMethodDeclaration(context, m, localClassName, isExtension || isMetaExtension)) - .filter(isNonNull) - ); - - // Add static declarations - for (const field of staticFields) { - const fieldName = transformPropertyName(context, field.name); - const value = field.initializer ? context.transformExpression(field.initializer) : undefined; - - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), fieldName); - - const fieldAssign = lua.createAssignmentStatement(classField, value); + const noPrototype = isExtension || isMetaExtension; + const decorationStatements: lua.Statement[] = []; - result.push(fieldAssign); + for (const member of classDeclaration.members) { + if (ts.isAccessor(member)) { + const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } else if (ts.isMethodDeclaration(member)) { + const statement = transformMethodDeclaration(context, member, localClassName, noPrototype); + if (statement) result.push(statement); + if (member.body) { + const statement = createMethodDecoratingExpression(context, member, localClassName, noPrototype); + if (statement) decorationStatements.push(statement); + } + } else if (ts.isPropertyDeclaration(member)) { + if (isStaticNode(member)) { + const statement = transformStaticPropertyDeclaration(context, member, localClassName); + if (statement) decorationStatements.push(statement); + } + const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + } } - const decorationStatement = createConstructorDecorationStatement(context, classDeclaration); - if (decorationStatement) { - result.push(decorationStatement); + result.push(...decorationStatements); + + // Decorate the class + if (classDeclaration.decorators) { + const decoratingExpression = createDecoratingExpression( + context, + classDeclaration.kind, + classDeclaration.decorators.map(d => transformDecoratorExpression(context, d)), + localClassName + ); + const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); + result.push(decoratingStatement); } superInfo.pop(); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 88a7f1545..6a2709c74 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -2,10 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { importLuaLibFeature, LuaLibFeature } from "../../../utils/lualib"; +import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; import { getExtendedType, isStaticNode } from "../utils"; +import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); @@ -31,19 +32,12 @@ export function transformAccessorDeclarations( descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); } - importLuaLibFeature(context, LuaLibFeature.Descriptors); - const call = isStaticNode(firstAccessor) - ? lua.createCallExpression(lua.createIdentifier("__TS__ObjectDefineProperty"), [ - lua.cloneIdentifier(className), - propertyName, - descriptor, - ]) - : lua.createCallExpression(lua.createIdentifier("__TS__SetDescriptor"), [ - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - propertyName, - descriptor, - ]); - + const isStatic = isStaticNode(firstAccessor); + const target = isStatic ? lua.cloneIdentifier(className) : createPrototypeName(className); + const feature = isStatic ? LuaLibFeature.ObjectDefineProperty : LuaLibFeature.SetDescriptor; + const parameters: lua.Expression[] = [target, propertyName, descriptor]; + if (!isStatic) parameters.push(lua.createBooleanLiteral(true)); + const call = transformLuaLibFunction(context, feature, undefined, ...parameters); return lua.createExpressionStatement(call); } diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 571c1022c..49329ed12 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -7,11 +7,12 @@ import { transformFunctionBodyHeader, transformFunctionBodyContent, transformPar import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; +export function createPrototypeName(className: lua.Identifier): lua.TableIndexExpression { + return lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); +} + export function createConstructorName(className: lua.Identifier): lua.TableIndexExpression { - return lua.createTableIndexExpression( - lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")), - lua.createStringLiteral("____constructor") - ); + return lua.createTableIndexExpression(createPrototypeName(className), lua.createStringLiteral("____constructor")); } export function transformConstructorDeclaration( diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 9117c1519..0237a9f4d 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -4,6 +4,26 @@ import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformPropertyName } from "../../literal"; import { isGetAccessorOverride } from "./accessors"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { transformMemberExpressionOwnerName } from "./method"; + +export function createPropertyDecoratingExpression( + context: TransformationContext, + node: ts.PropertyDeclaration | ts.AccessorDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Expression | undefined { + if (!node.decorators) return; + const propertyName = transformPropertyName(context, node.name); + const propertyOwnerTable = transformMemberExpressionOwnerName(node, className, noPrototype); + return createDecoratingExpression( + context, + node.kind, + node.decorators.map(d => transformDecoratorExpression(context, d)), + propertyOwnerTable, + propertyName + ); +} export function transformClassInstanceFields( context: TransformationContext, @@ -49,3 +69,15 @@ export function transformClassInstanceFields( return statements; } + +export function transformStaticPropertyDeclaration( + context: TransformationContext, + field: ts.PropertyDeclaration, + className: lua.Identifier +): lua.AssignmentStatement | undefined { + if (!field.initializer) return; + const fieldName = transformPropertyName(context, field.name); + const value = context.transformExpression(field.initializer); + const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); + return lua.createAssignmentStatement(classField, value); +} diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 6f6df45b0..24cd77f44 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -4,6 +4,26 @@ import { TransformationContext } from "../../../context"; import { transformFunctionToExpression } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; +import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; +import { createPrototypeName } from "./constructor"; +import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; +import { isNonNull } from "../../../../utils"; + +export function transformMemberExpressionOwnerName( + node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Expression { + return isStaticNode(node) || noPrototype ? lua.cloneIdentifier(className) : createPrototypeName(className); +} + +export function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression { + const methodName = transformPropertyName(context, node.name); + if (lua.isStringLiteral(methodName) && methodName.value === "toString") { + return lua.createStringLiteral("__tostring", node.name); + } + return methodName; +} export function transformMethodDeclaration( context: TransformationContext, @@ -12,20 +32,10 @@ export function transformMethodDeclaration( noPrototype: boolean ): lua.Statement | undefined { // Don't transform methods without body (overload declarations) - if (!node.body) { - return undefined; - } - - const methodTable = - isStaticNode(node) || noPrototype - ? lua.cloneIdentifier(className) - : lua.createTableIndexExpression(lua.cloneIdentifier(className), lua.createStringLiteral("prototype")); - - let methodName = transformPropertyName(context, node.name); - if (lua.isStringLiteral(methodName) && methodName.value === "toString") { - methodName = lua.createStringLiteral("__tostring", node.name); - } + if (!node.body) return; + const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); return lua.createAssignmentStatement( @@ -34,3 +44,40 @@ export function transformMethodDeclaration( node ); } + +export function createMethodDecoratingExpression( + context: TransformationContext, + node: ts.MethodDeclaration, + className: lua.Identifier, + noPrototype: boolean +): lua.Statement | undefined { + const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodName = transformMethodName(context, node); + + const parameterDecorators = node.parameters + .flatMap((parameter, index) => + parameter.decorators?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) + ) + ) + .filter(isNonNull); + + const methodDecorators = node.decorators?.map(d => transformDecoratorExpression(context, d)) ?? []; + + if (methodDecorators.length > 0 || parameterDecorators.length > 0) { + const decorateMethod = createDecoratingExpression( + context, + node.kind, + [...methodDecorators, ...parameterDecorators], + methodTable, + methodName + ); + return lua.createExpressionStatement(decorateMethod); + } +} diff --git a/src/transformation/visitors/delete.ts b/src/transformation/visitors/delete.ts index 34e378be8..39bbf1d57 100644 --- a/src/transformation/visitors/delete.ts +++ b/src/transformation/visitors/delete.ts @@ -1,25 +1,35 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { cast } from "../../utils"; -import { FunctionVisitor, TransformationContext } from "../context"; -import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; +import { FunctionVisitor } from "../context"; +import { transformLuaLibFunction, LuaLibFeature } from "../utils/lualib"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { isArrayType, isNumberType } from "../utils/typescript"; +import { addToNumericExpression } from "../utils/lua-ast"; export const transformDeleteExpression: FunctionVisitor = (node, context) => { - const lhs = cast(context.transformExpression(node.expression), lua.isAssignmentLeftHandSideExpression); - const assignment = lua.createAssignmentStatement(lhs, lua.createNilLiteral(), node); - return createImmediatelyInvokedFunctionExpression([assignment], [lua.createBooleanLiteral(true)], node); -}; + let ownerExpression: lua.Expression | undefined; + let propertyExpression: lua.Expression | undefined; + + if (ts.isPropertyAccessExpression(node.expression)) { + if (ts.isPrivateIdentifier(node.expression.name)) throw new Error("PrivateIdentifier is not supported"); + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = lua.createStringLiteral(node.expression.name.text); + } else if (ts.isElementAccessExpression(node.expression)) { + ownerExpression = context.transformExpression(node.expression.expression); + propertyExpression = context.transformExpression(node.expression.argumentExpression); -export function transformDeleteExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - if (ts.isDeleteExpression(expression)) { - return lua.createAssignmentStatement( - cast(context.transformExpression(expression.expression), lua.isAssignmentLeftHandSideExpression), - lua.createNilLiteral(), - expression - ); + const type = context.checker.getTypeAtLocation(node.expression.expression); + const argumentType = context.checker.getTypeAtLocation(node.expression.argumentExpression); + + if (isArrayType(context, type) && isNumberType(context, argumentType)) { + propertyExpression = addToNumericExpression(propertyExpression, 1); + } } -} + + if (!ownerExpression || !propertyExpression) { + context.diagnostics.push(unsupportedProperty(node, "delete", ts.SyntaxKind[node.kind])); + return lua.createNilLiteral(); + } + + return transformLuaLibFunction(context, LuaLibFeature.Delete, node, ownerExpression, propertyExpression); +}; diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 0b338be6f..890695be0 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { transformDeleteExpressionStatement } from "./delete"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -22,11 +21,6 @@ export const transformExpressionStatement: FunctionVisitor { `.expectToMatchJsResult(); }); - test("returns true when element exists", () => { + test("returns true when deletion attempt was allowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[2]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + const success = delete array[2]; + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); - test("returns false when element not exists", () => { + test("returns false when deletion attempt was disallowed", () => { util.testFunction` const array = [1, 2, 3, 4]; - const exists = delete array[4]; - return { exists, a: array[0], b: array[1], c: array[2], d: array[3] }; + Object.defineProperty(array, 2, { configurable: false }); + + let success; + try { + success = delete array[2]; + } catch { + success = "error"; + } + + return { success, a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); }); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index b4866d2e7..cc7e380d6 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -121,3 +121,93 @@ describe(".hasOwnProperty()", () => { `.expectToMatchJsResult(); }); }); + +const trueFalseTests = [[true], [false]] as const; + +describe("Object.defineProperty", () => { + test.each(trueFalseTests)("writable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { writable: ${value} }); + let error = false; + try { + foo.bar = false; + } catch { + error = true; + } + return { foobar: foo.bar, error }; + `.expectToMatchJsResult(); + }); + + test.each(trueFalseTests)("configurable (%p)", value => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", { configurable: ${value} }); + try { delete foo.bar } catch {}; + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("defines a new property", () => { + util.testFunction` + const foo: any = {}; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("overwrites an existing property", () => { + util.testFunction` + const foo = { bar: false }; + Object.defineProperty(foo, "bar", { value: true }); + return foo.bar; + `.expectToMatchJsResult(); + }); + + test("default descriptor", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); + + test.each([ + ["{ value: true, get: () => true }"], + ["{ value: true, set: value => {} }"], + ["{ writable: true, get: () => true }"], + ])("invalid descriptor (%p)", props => { + util.testFunction` + const foo: any = {}; + let err = false; + + try { + Object.defineProperty(foo, "bar", ${props}); + } catch { + err = true; + } + + return { prop: foo.bar, err }; + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptor", () => { + test("descriptor is exactly the same as the last one set", () => { + util.testFunction` + const foo = {}; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptor(foo, "bar"); + `.expectToMatchJsResult(); + }); +}); + +describe("Object.getOwnPropertyDescriptors", () => { + test("all descriptors match", () => { + util.testFunction` + const foo = { bar: true }; + Object.defineProperty(foo, "bar", {}); + return Object.getOwnPropertyDescriptors(foo); + `.expectToMatchJsResult(); + }); +}); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index cba245c1f..dadb73655 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -126,3 +126,61 @@ test("Exported class decorator", () => { .setReturnExport("Foo", "bar") .expectToMatchJsResult(); }); + +test.each([ + ["@decorator method() {}"], + ["@decorator property;"], + ["@decorator propertyWithInitializer = () => {};"], + ["@decorator ['evaluated property'];"], + ["@decorator get getter() { return 5 }"], + ["@decorator set setter(value) {}"], + ["@decorator static method() {}"], + ["@decorator static property;"], + ["@decorator static propertyWithInitializer = () => {}"], + ["@decorator static get getter() { return 5 }"], + ["@decorator static set setter(value) {}"], + ["@decorator static ['evaluated property'];"], + ["method(@decorator a) {}"], + ["static method(@decorator a) {}"], +])("Decorate class member (%p)", classMember => { + util.testFunction` + let decoratorParameters: any; + + const decorator = (target, key, index?) => { + const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; + decoratorParameters = { targetKind, key, index: typeof index }; + }; + + class Foo { + ${classMember} + } + + return decoratorParameters; + `.expectToMatchJsResult(); +}); + +describe("Decorators /w descriptors", () => { + test.each([ + ["return { writable: true }", "return { configurable: true }"], + ["desc.writable = true", "return { configurable: true }"], + ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { + util.testFunction` + const A = (target, key, desc): any => { ${decorateA} }; + const B = (target, key, desc): any => { ${decorateB} }; + class Foo { @A @B static method() {} } + const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); + return rest; + `.expectToMatchJsResult(); + }); + + test.each(["return { value: true }", "desc.value = true"])( + "Use decorator to override method value", + overrideStatement => { + util.testFunction` + const decorator = (target, key, desc): any => { ${overrideStatement} }; + class Foo { @decorator static method() {} } + return Foo.method; + `.expectToMatchJsResult(); + } + ); +}); From b1eb04141da93263d80a8bb762f4dfc1b6d2b207 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Sun, 18 Oct 2020 18:57:33 +0500 Subject: [PATCH 293/764] Shebang support (#924) --- src/LuaAST.ts | 26 ++++++++++++++++++ src/LuaPrinter.ts | 32 +++++++++-------------- src/transformation/context/visitors.ts | 2 +- src/transformation/index.ts | 22 +++------------- src/transformation/visitors/sourceFile.ts | 4 ++- src/transpilation/transpile.ts | 10 +++---- src/transpilation/utils.ts | 2 +- test/unit/__snapshots__/file.spec.ts.snap | 11 ++++++++ test/unit/file.spec.ts | 27 +++++++++++++++++++ test/unit/json.spec.ts | 11 -------- 10 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 test/unit/__snapshots__/file.spec.ts.snap create mode 100644 test/unit/file.spec.ts delete mode 100644 test/unit/json.spec.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 99af02718..8efb23817 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,9 +5,11 @@ // because we don't create the AST from text import * as ts from "typescript"; +import { LuaLibFeature } from "./transformation/utils/lualib"; import { castArray } from "./utils"; export enum SyntaxKind { + File, Block, // Statements @@ -186,6 +188,30 @@ export function getOriginalPos(node: Node): TextRange { return { line: node.line, column: node.column }; } +export interface File extends Node { + kind: SyntaxKind.File; + statements: Statement[]; + luaLibFeatures: Set; + trivia: string; +} + +export function isFile(node: Node): node is File { + return node.kind === SyntaxKind.File; +} + +export function createFile( + statements: Statement[], + luaLibFeatures: Set, + trivia: string, + tsOriginal?: ts.Node +): File { + const file = createNode(SyntaxKind.File, tsOriginal) as File; + file.statements = statements; + file.luaLibFeatures = luaLibFeatures; + file.trivia = trivia; + return file; +} + export interface Block extends Node { kind: SyntaxKind.Block; statements: Statement[]; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 63654c595..a021ae7d5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -6,7 +6,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, trimExtension, normalizeSlashes } from "./utils"; +import { intersperse, normalizeSlashes, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -71,13 +71,7 @@ function isSimpleExpression(expression: lua.Expression): boolean { type SourceChunk = string | SourceNode; -export type Printer = ( - program: ts.Program, - emitHost: EmitHost, - fileName: string, - block: lua.Block, - luaLibFeatures: Set -) => PrintResult; +export type Printer = (program: ts.Program, emitHost: EmitHost, fileName: string, file: lua.File) => PrintResult; export interface PrintResult { code: string; @@ -87,7 +81,7 @@ export interface PrintResult { export function createPrinter(printers: Printer[]): Printer { if (printers.length === 0) { - return (program, emitHost, fileName, ...args) => new LuaPrinter(emitHost, program, fileName).print(...args); + return (program, emitHost, fileName, file) => new LuaPrinter(emitHost, program, fileName).print(file); } else if (printers.length === 1) { return printers[0]; } else { @@ -148,17 +142,17 @@ export class LuaPrinter { } } - public print(block: lua.Block, luaLibFeatures: Set): PrintResult { + public print(file: lua.File): PrintResult { // Add traceback lualib if sourcemap traceback option is enabled if (this.options.sourceMapTraceback) { - luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); + file.luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack); } const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" : ""; - const rootSourceNode = this.printImplementation(block, luaLibFeatures); + const rootSourceNode = this.printFile(file); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); let code = rootSourceNode.toString(); @@ -203,8 +197,8 @@ export class LuaPrinter { return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printImplementation(block: lua.Block, luaLibFeatures: Set): SourceNode { - let header = ""; + private printFile(file: lua.File): SourceNode { + let header = file.trivia; if (!this.options.noHeader) { header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; @@ -213,23 +207,21 @@ export class LuaPrinter { const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if ( luaLibImport === LuaLibImportKind.Always || - (luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0) + (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) ) { // Require lualib bundle header += 'require("lualib_bundle");\n'; - } else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { + } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features header += "-- Lua Library inline imports\n"; - header += loadLuaLibFeatures(luaLibFeatures, this.emitHost); + header += loadLuaLibFeatures(file.luaLibFeatures, this.emitHost); } if (this.options.sourceMapTraceback) { header += "{#SourceMapTraceback}\n"; } - const fileBlockNode = this.printBlock(block); - - return this.concatNodes(header, fileBlockNode); + return this.concatNodes(header, ...this.printStatementArray(file.statements)); } protected pushIndent(): void { diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index 5967c18b4..df7cd7acb 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -143,7 +143,7 @@ export type VisitorResult = T extends ExpressionLikeNode : T extends StatementLikeNode ? OneToManyVisitorResult : T extends ts.SourceFile - ? lua.Block + ? lua.File : OneToManyVisitorResult; export type Visitor = FunctionVisitor | ObjectVisitor; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 69b098811..5b6fca647 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -1,9 +1,7 @@ import * as ts from "typescript"; import * as lua from "../LuaAST"; -import { LuaLibFeature } from "../LuaLib"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; -import { getUsedLuaLibFeatures } from "./utils/lualib"; import { standardVisitors } from "./visitors"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { @@ -29,23 +27,9 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { return visitorMap; } -export interface TransformSourceFileResult { - luaAst: lua.Block; - luaLibFeatures: Set; - diagnostics: ts.Diagnostic[]; -} - -export function transformSourceFile( - program: ts.Program, - sourceFile: ts.SourceFile, - visitorMap: VisitorMap -): TransformSourceFileResult { +export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { const context = new TransformationContext(program, sourceFile, visitorMap); - const [luaAst] = context.transformNode(sourceFile) as [lua.Block]; + const [file] = context.transformNode(sourceFile) as [lua.File]; - return { - luaAst, - luaLibFeatures: getUsedLuaLibFeatures(context), - diagnostics: context.diagnostics, - }; + return { file, diagnostics: context.diagnostics }; } diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 539c9f9d7..604aa0c7e 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; import { createExportsIdentifier } from "../utils/lua-ast"; +import { getUsedLuaLibFeatures } from "../utils/lualib"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; @@ -39,5 +40,6 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } } - return lua.createBlock(statements, node); + const trivia = node.getFullText().match(/^#!.*\r?\n/)?.[0] ?? ""; + return lua.createFile(statements, getUsedLuaLibFeatures(context), trivia, node); }; diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 01d9278c5..cbc77c13c 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -60,18 +60,14 @@ export function getProgramTranspileResult( const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { - const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformSourceFile( - program, - sourceFile, - visitorMap - ); + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { - const printResult = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures); + const printResult = printer(program, emitHost, sourceFile.fileName, file); const sourceRootDir = program.getCommonSourceDirectory(); const fileName = path.resolve(sourceRootDir, sourceFile.fileName); - transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst, ...printResult }); + transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst: file, ...printResult }); } }; diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 98c3f5cc6..099dfd400 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -21,7 +21,7 @@ interface BaseFile { export interface ProcessedFile extends BaseFile { fileName: string; - luaAst?: lua.Block; + luaAst?: lua.File; /** @internal */ sourceMapNode?: SourceNode; } diff --git a/test/unit/__snapshots__/file.spec.ts.snap b/test/unit/__snapshots__/file.spec.ts.snap new file mode 100644 index 000000000..12a004c6c --- /dev/null +++ b/test/unit/__snapshots__/file.spec.ts.snap @@ -0,0 +1,11 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`shebang CRLF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; + +exports[`shebang LF 1`] = ` +"#!/usr/bin/env lua +foo = true" +`; diff --git a/test/unit/file.spec.ts b/test/unit/file.spec.ts new file mode 100644 index 000000000..3a810dc60 --- /dev/null +++ b/test/unit/file.spec.ts @@ -0,0 +1,27 @@ +import * as util from "../util"; + +describe("JSON", () => { + test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { + util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); + }); + + test("empty file throws runtime error", () => { + util.testModule("") + .setMainFileName("main.json") + .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); + }); +}); + +describe("shebang", () => { + test("LF", () => { + util.testModule`#!/usr/bin/env lua\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); + + test("CRLF", () => { + util.testModule`#!/usr/bin/env lua\r\n + const foo = true; + `.expectLuaToMatchSnapshot(); + }); +}); diff --git a/test/unit/json.spec.ts b/test/unit/json.spec.ts deleted file mode 100644 index 2f4b0d6a5..000000000 --- a/test/unit/json.spec.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as util from "../util"; - -test.each([0, "", [], [1, "2", []], { a: "b" }, { a: { b: "c" } }])("JSON (%p)", json => { - util.testModule(JSON.stringify(json)).setMainFileName("main.json").expectToEqual(json); -}); - -test("Empty JSON file error", () => { - util.testModule("") - .setMainFileName("main.json") - .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); -}); From ccf95d75b1ee4baa83af77cc717d9ef98c356e2b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 18 Oct 2020 16:21:59 +0200 Subject: [PATCH 294/764] 0.36.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fa1a4185c..dbe13db2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.35.0", + "version": "0.36.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index a149df59c..a2623d785 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.35.0", + "version": "0.36.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From d9878951320358b50942f9266d4b5b3c3a4e169c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 18 Oct 2020 16:47:15 +0200 Subject: [PATCH 295/764] CHANGELOG.md 0.36.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 25033b16f..64ef0e7c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.36.0 + +- Upgraded to TypeScript 4.0. +- Added support for `parseInt` and `parseFloat`. +- Added support for `yield*` [for generator functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield*). +- Added support for [method, property and accessor decorators](https://www.typescriptlang.org/docs/handbook/decorators.html). +- Shebangs at the top of a .ts file will now be preserved. +- Fixed an issue causing declarations referencing their own identifier to cause a nil reference error. + ## 0.35.0 - In preparation for some new features, some public APIs have been changed: From ea748a3eceb5fb86ebd87d911045a08a6546f935 Mon Sep 17 00:00:00 2001 From: Justin Walsh Date: Wed, 21 Oct 2020 11:00:58 -0700 Subject: [PATCH 296/764] Add test for argument passing in plugin config (#931) --- src/CompilerOptions.ts | 1 + test/transpile/plugins/arguments.ts | 28 ++++++++++++++++++++++++++ test/transpile/plugins/plugins.spec.ts | 8 ++++++++ 3 files changed, 37 insertions(+) create mode 100644 test/transpile/plugins/arguments.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 2e78b2b87..889a5837a 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -21,6 +21,7 @@ export interface TransformerImport { export interface LuaPluginImport { name: string; import?: string; + [option: string]: any; } export type CompilerOptions = OmitIndexSignature & { diff --git a/test/transpile/plugins/arguments.ts b/test/transpile/plugins/arguments.ts new file mode 100644 index 000000000..f6aa2ba6e --- /dev/null +++ b/test/transpile/plugins/arguments.ts @@ -0,0 +1,28 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +interface Options { + name: string; + option: boolean; +} + +// eslint-disable-next-line import/no-default-export +export default function plugin(options: Options): tstl.Plugin { + return { + visitors: { + [ts.SyntaxKind.ReturnStatement]: () => + tstl.createReturnStatement([ + tstl.createTableExpression([ + tstl.createTableFieldExpression( + tstl.createStringLiteral(options.name), + tstl.createStringLiteral("name") + ), + tstl.createTableFieldExpression( + tstl.createBooleanLiteral(options.option), + tstl.createStringLiteral("option") + ), + ]), + ]), + }, + }; +} diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index ce2ebc7a6..e78cc4201 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -22,3 +22,11 @@ test("visitor using super", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "visitor-super.ts") }] }) .expectToEqual("bar"); }); + +test("passing arguments", () => { + util.testFunction` + return {}; + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "arguments.ts"), option: true }] }) + .expectToEqual({ name: path.join(__dirname, "arguments.ts"), option: true }); +}); From dae7abab3f9f3225a4c504492cf961fbc760436f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 21 Oct 2020 20:01:36 +0200 Subject: [PATCH 297/764] Get benchmark data to visualizer (#878) * Try zlibbing output data * Try with lz-string * Explicitly install lz-string * Another try with regular zlib * Use deflateSync now * Try without extra dependencies * Once more, with dollarsign * Output raw results instead of processed table * Fix run script * reverted package-lock * Add link to visualizer to benchmark result * prettier fix * Removed forgotten comment from benchmarking CI --- .github/workflows/ci.yml | 10 +++++++--- benchmark/src/run.ts | 11 +++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3cff50e60..d8ac390a1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -61,8 +61,7 @@ jobs: node-version: 12.13.1 # NPM - name: NPM master - # TODO Lua types is only added manually to test the benchmark PR this can be removed again once the PR is merged - run: npm ci && npm run build && npm install -D lua-types + run: npm ci && npm run build working-directory: master - name: NPM commit run: npm ci && npm run build @@ -112,7 +111,12 @@ jobs: const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); - const summary = `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; + const zlib = require('zlib'); + const buffer = Buffer.from(core.getInput('benchmark-info-lua', { required: true })); + const compressed = zlib.deflateSync(buffer); + + const summary = `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString('base64')})\n` + + `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index c632efe39..22e4ec70c 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -27,11 +27,8 @@ function benchmark(): void { oldBenchmarkResults = json.decode(oldBenchmarkData) as BenchmarkResult[]; } - // Compare results - const comparisonInfo = compareBenchmarks(oldBenchmarkResults, newBenchmarkResults); - // Output comparison info - outputBenchmarkData(comparisonInfo, newBenchmarkResults); + outputBenchmarkData(oldBenchmarkResults, newBenchmarkResults); } benchmark(); @@ -44,12 +41,14 @@ function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkR return { summary: memoryComparisonInfo.summary, text: memoryComparisonInfo.text }; } -function outputBenchmarkData(comparisonInfo: { summary: string; text: string }, newResults: BenchmarkResult[]): void { +function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { if (!arg[2]) { // Output to stdout as json by default, this is used by the CI to retrieve the info - print(json.encode(comparisonInfo)); + print(json.encode({ old: oldResults, new: newResults })); } else { // Output to file as markdown if arg[2] is set, this is useful for local development + // Compare results + const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); } From 86cc1b965971f2a967364866656ce7e7ae633418 Mon Sep 17 00:00:00 2001 From: ark120202 Date: Wed, 21 Oct 2020 23:09:58 +0500 Subject: [PATCH 298/764] Remove class field/accessor compatibility code (#929) --- src/transformation/visitors/class/index.ts | 9 +-- .../visitors/class/members/accessors.ts | 69 +------------------ .../visitors/class/members/constructor.ts | 4 +- .../visitors/class/members/fields.ts | 22 ------ 4 files changed, 7 insertions(+), 97 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index d70095bff..9142775f7 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -29,7 +29,7 @@ import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; -import { isGetAccessorOverride, transformAccessorDeclarations } from "./members/accessors"; +import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; import { createPropertyDecoratingExpression, @@ -238,15 +238,12 @@ function transformClassLikeDeclaration( ); if (constructorResult) result.push(constructorResult); - } else if ( - instanceFields.length > 0 || - classDeclaration.members.some(m => isGetAccessorOverride(context, m, classDeclaration)) - ) { + } else if (instanceFields.length > 0) { // Generate a constructor if none was defined in a class with instance fields that need initialization // localClassName.prototype.____constructor = function(self, ...) // baseClassName.prototype.____constructor(self, ...) // ... - const constructorBody = transformClassInstanceFields(context, classDeclaration, instanceFields); + const constructorBody = transformClassInstanceFields(context, instanceFields); const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 6a2709c74..f774b9645 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -2,10 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { AllAccessorDeclarations, TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; +import { LuaLibFeature, transformLuaLibFunction } from "../../../utils/lualib"; import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; -import { getExtendedType, isStaticNode } from "../utils"; +import { isStaticNode } from "../utils"; import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { @@ -40,68 +40,3 @@ export function transformAccessorDeclarations( const call = transformLuaLibFunction(context, feature, undefined, ...parameters); return lua.createExpressionStatement(call); } - -function* classWithAncestors( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase -): Generator { - yield classDeclaration; - - const extendsType = getExtendedType(context, classDeclaration); - if (!extendsType) { - return false; - } - - const symbol = extendsType.getSymbol(); - if (symbol === undefined) { - return false; - } - - const symbolDeclarations = symbol.getDeclarations(); - if (symbolDeclarations === undefined) { - return false; - } - - const declaration = symbolDeclarations.find(ts.isClassLike); - if (!declaration) { - return false; - } - - yield* classWithAncestors(context, declaration); -} - -export const hasMemberInClassOrAncestor = ( - context: TransformationContext, - classDeclaration: ts.ClassLikeDeclarationBase, - callback: (m: ts.ClassElement) => boolean -) => [...classWithAncestors(context, classDeclaration)].some(c => c.members.some(callback)); - -function getPropertyName(propertyName: ts.PropertyName): string | number | undefined { - if (ts.isIdentifier(propertyName) || ts.isStringLiteral(propertyName) || ts.isNumericLiteral(propertyName)) { - return propertyName.text; - } else { - return undefined; // TODO: how to handle computed property names? - } -} - -function isSamePropertyName(a: ts.PropertyName, b: ts.PropertyName): boolean { - const aName = getPropertyName(a); - const bName = getPropertyName(b); - return aName !== undefined && aName === bName; -} - -export function isGetAccessorOverride( - context: TransformationContext, - element: ts.ClassElement, - classDeclaration: ts.ClassLikeDeclarationBase -): element is ts.GetAccessorDeclaration { - if (!ts.isGetAccessor(element) || isStaticNode(element)) { - return false; - } - - return hasMemberInClassOrAncestor( - context, - classDeclaration, - m => ts.isPropertyDeclaration(m) && m.initializer !== undefined && isSamePropertyName(m.name, element.name) - ); -} diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 49329ed12..11766d2a8 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -3,7 +3,7 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; -import { transformFunctionBodyHeader, transformFunctionBodyContent, transformParameters } from "../../function"; +import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; @@ -43,7 +43,7 @@ export function transformConstructorDeclaration( // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - const classInstanceFields = transformClassInstanceFields(context, classDeclaration, instanceFields); + const classInstanceFields = transformClassInstanceFields(context, instanceFields); // If there are field initializers and the first statement is a super call, // move super call between default assignments and initializers diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 0237a9f4d..5d07033dd 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -3,7 +3,6 @@ import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformPropertyName } from "../../literal"; -import { isGetAccessorOverride } from "./accessors"; import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; import { transformMemberExpressionOwnerName } from "./method"; @@ -27,7 +26,6 @@ export function createPropertyDecoratingExpression( export function transformClassInstanceFields( context: TransformationContext, - classDeclaration: ts.ClassLikeDeclaration, instanceFields: ts.PropertyDeclaration[] ): lua.Statement[] { const statements: lua.Statement[] = []; @@ -47,26 +45,6 @@ export function transformClassInstanceFields( statements.push(assignClassField); } - // TODO: Remove when `useDefineForClassFields` would be `true` by default - - const getOverrides = classDeclaration.members.filter((m): m is ts.GetAccessorDeclaration => - isGetAccessorOverride(context, m, classDeclaration) - ); - - for (const getter of getOverrides) { - const getterName = transformPropertyName(context, getter.name); - - const resetGetter = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("rawset"), [ - createSelfIdentifier(), - getterName, - lua.createNilLiteral(), - ]), - classDeclaration.members.find(ts.isConstructorDeclaration) ?? classDeclaration - ); - statements.push(resetGetter); - } - return statements; } From 54569aac73c553e86a03b47a0fc755e9c83d3927 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 23 Nov 2020 20:59:52 +0100 Subject: [PATCH 299/764] Fixed various benchmark issues (#935) * Fixed various benchmark issues Benchmarks now hopefully work for pull requests from a fork Fixed comparison info not beeing emmitted correctly after #878 Bump actions/github-script from 0.9.0 to v3 Moved create benchmark check script to standalone js file * Formatting & Adjusted script path * Pass core to the js file * Output markdown directly to CLI instead of creating an actions check * Fixed github-script usage * Fixed visualizer data passing * Linting :) * Return benchmark info from github-script * Fixed glow flags * Update name of final step * Update .github/workflows/ci.yml Co-authored-by: ark120202 Co-authored-by: ark120202 --- .github/scripts/create_benchmark_check.js | 22 + .github/workflows/ci.yml | 52 +- benchmark/src/run.ts | 22 +- package-lock.json | 11616 +++++++++++++++++++- package.json | 2 +- 5 files changed, 11665 insertions(+), 49 deletions(-) create mode 100644 .github/scripts/create_benchmark_check.js diff --git a/.github/scripts/create_benchmark_check.js b/.github/scripts/create_benchmark_check.js new file mode 100644 index 000000000..e1d303e06 --- /dev/null +++ b/.github/scripts/create_benchmark_check.js @@ -0,0 +1,22 @@ +module.exports = ({ github, context, core }) => { + const fs = require("fs"); + + const benchmarkResultPathLua = core.getInput("benchmark-result-path-lua", { required: true }); + const benchmarkInfoLua = JSON.parse(fs.readFileSync(benchmarkResultPathLua)); + + const benchmarkResultPathJIT = core.getInput("benchmark-result-path-jit", { required: true }); + const benchmarkInfoJIT = JSON.parse(fs.readFileSync(benchmarkResultPathJIT)); + + // Remove Comparison info to save some bytes + const benchmarkInfoForVizLua = { old: benchmarkInfoLua.old, new: benchmarkInfoLua.new }; + const buffer = Buffer.from(JSON.stringify(benchmarkInfoForVizLua)); + + const zlib = require("zlib"); + const compressed = zlib.deflateSync(buffer); + + const summary = + `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString("base64")})\n` + + `### Lua5.3\n${benchmarkInfoLua.comparison.summary}\n### LuaJIT\n${benchmarkInfoJIT.comparison.summary}`; + + return summary; +}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8ac390a1..13df095ec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,8 @@ jobs: steps: - name: Lua Install run: sudo apt-get install lua5.3 luajit + - name: Glow Install + run: brew install glow # Checkout master & commit - name: Checkout master uses: actions/checkout@v2 @@ -93,50 +95,24 @@ jobs: working-directory: commit/benchmark - name: Run benchmark Lua 5.3 commit id: benchmark-lua-commit - run: echo ::set-output name=info::`lua5.3 -- run.lua ../data/benchmark_commit_53.json ../data/benchmark_master_53.json` + run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json working-directory: commit/benchmark/dist - name: Build benchmark LuaJIT commit run: node ../dist/tstl.js -p tsconfig.jit.json working-directory: commit/benchmark - name: Run benchmark LuaJIT commit id: benchmark-jit-commit - run: echo ::set-output name=info::`luajit -- run.lua ../data/benchmark_commit_jit.json ../data/benchmark_master_jit.json` + run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json working-directory: commit/benchmark/dist - - name: Create benchmark check - uses: actions/github-script@0.9.0 + - name: Combine benchmark results + id: script-combine-results + uses: actions/github-script@v3 with: - benchmark-info-lua: ${{steps.benchmark-lua-commit.outputs.info}} - benchmark-info-jit: ${{steps.benchmark-jit-commit.outputs.info}} + benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json + benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json + result-encoding: string script: | - const benchmarkInfoLua = JSON.parse(core.getInput('benchmark-info-lua', { required: true })); - const benchmarkInfoJIT = JSON.parse(core.getInput('benchmark-info-jit', { required: true })); - - const zlib = require('zlib'); - const buffer = Buffer.from(core.getInput('benchmark-info-lua', { required: true })); - const compressed = zlib.deflateSync(buffer); - - const summary = `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString('base64')})\n` - + `### Lua5.3\n${benchmarkInfoLua.summary}\n### LuaJIT\n${benchmarkInfoJIT.summary}`; - - const text = `### Lua5.3\n${benchmarkInfoLua.text}\n### LuaJIT\n${benchmarkInfoJIT.text}`; - - const pull_request = context.payload.pull_request; - if (!pull_request || pull_request.head.repo.url === pull_request.base.repo.url) { - // This only works if not in a fork. - github.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: "Benchmark results", - head_sha: context.sha, - status: "completed", - conclusion: "neutral", - output: { - title: "Benchmark results", - summary: summary, - text: text - } - }); - } else { - console.log(summary); - console.log(text); - } + const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); + return createBenchmarkCheck({ github, context, core }); + - name: Benchmark results + run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index 22e4ec70c..b880537e5 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -42,19 +42,23 @@ function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkR } function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { - if (!arg[2]) { - // Output to stdout as json by default, this is used by the CI to retrieve the info - print(json.encode({ old: oldResults, new: newResults })); - } else { + // Output benchmark results to json + if (arg[0]) { + if (arg[1]) { + // if baseline is provide output full comparison info + const comparisonInfo = compareBenchmarks(oldResults, newResults); + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode({ old: oldResults, new: newResults, comparison: comparisonInfo })); + } else { + const jsonDataFile = io.open(arg[0], "w+")[0]!; + jsonDataFile.write(json.encode(newResults)); + } + } + if (arg[2]) { // Output to file as markdown if arg[2] is set, this is useful for local development // Compare results const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); } - // Output benchmark results to json - if (arg[0]) { - const jsonDataFile = io.open(arg[0], "w+")[0]!; - jsonDataFile.write(json.encode(newResults)); - } } diff --git a/package-lock.json b/package-lock.json index dbe13db2e..73ebb5214 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,8 +1,11622 @@ { "name": "typescript-to-lua", "version": "0.36.0", - "lockfileVersion": 1, + "lockfileVersion": 2, "requires": true, + "packages": { + "": { + "name": "typescript-to-lua", + "version": "0.36.0", + "license": "MIT", + "dependencies": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": ">=4.0.2" + }, + "bin": { + "tstl": "dist/tstl.js" + }, + "devDependencies": { + "@types/fs-extra": "^8.1.0", + "@types/glob": "^7.1.1", + "@types/jest": "^25.1.3", + "@types/node": "^13.7.7", + "@types/resolve": "1.14.0", + "@typescript-eslint/eslint-plugin": "^2.31.0", + "@typescript-eslint/parser": "^4.1.0", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.1", + "eslint-plugin-jest": "^23.8.2", + "fengari": "^0.1.4", + "fs-extra": "^8.1.0", + "javascript-stringify": "^2.0.1", + "jest": "^26.0.1", + "jest-circus": "^25.1.0", + "lua-types": "^2.8.0", + "prettier": "^2.0.5", + "ts-jest": "^26.3.0", + "ts-node": "^8.6.2" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.8.3" + } + }, + "node_modules/@babel/core": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", + "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.6", + "@babel/parser": "^7.9.6", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/core/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/core/node_modules/@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "node_modules/@babel/core/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/core/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/core/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/generator": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", + "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/generator/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "dependencies": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "dev": true + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", + "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "dev": true, + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helper-replace-supers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "dev": true + }, + "node_modules/@babel/helpers": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", + "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.9.6", + "@babel/types": "^7.9.6" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/generator": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", + "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.9.6", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { + "version": "7.9.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", + "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", + "dev": true, + "dependencies": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.9.5" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/parser": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", + "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/traverse": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", + "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.9.6", + "@babel/helper-function-name": "^7.9.5", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.9.6", + "@babel/types": "^7.9.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/helpers/node_modules/@babel/types": { + "version": "7.9.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", + "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.9.5", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@babel/helpers/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", + "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", + "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", + "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", + "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "node_modules/@babel/template": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "node_modules/@babel/traverse": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", + "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.4", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.4", + "@babel/types": "^7.8.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "node_modules/@babel/types": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "dependencies": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + }, + "bin": { + "watch": "cli.js" + }, + "engines": { + "node": ">=0.1.95" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/console/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/core": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", + "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/reporters": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.0.1", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-resolve-dependencies": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "jest-watcher": "^26.0.1", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/core/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/core/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@jest/core/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/core/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/globals": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", + "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/types": "^26.0.1", + "expect": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/globals/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/globals/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", + "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^4.1.3" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "node-notifier": "^7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/reporters/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/reporters/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/reporters/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/source-map": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", + "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/source-map/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/test-result/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", + "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-runner": "^26.0.1", + "jest-runtime": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/test-sequencer/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/test-sequencer/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/test-sequencer/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/transform": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", + "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.0.1", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.0.1", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@jest/transform/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", + "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", + "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", + "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.1", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", + "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", + "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", + "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "node_modules/@types/events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", + "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", + "dev": true + }, + "node_modules/@types/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "dependencies": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", + "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", + "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", + "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "25.1.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", + "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "dev": true, + "dependencies": { + "jest-diff": "^25.1.0", + "pretty-format": "^25.1.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", + "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", + "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", + "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", + "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "2.31.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", + "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", + "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.23.0", + "eslint-scope": "^5.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", + "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.1.0", + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/typescript-estree": "4.1.0", + "debug": "^4.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", + "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", + "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/visitor-keys": "4.1.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", + "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", + "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", + "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.1.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/abab": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", + "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", + "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, + "node_modules/acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", + "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/argparse/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", + "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "dev": true, + "dependencies": { + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-jest/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/babel-jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", + "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", + "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" + } + }, + "node_modules/babel-preset-jest": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", + "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^26.0.0", + "babel-preset-current-node-syntax": "^0.1.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" + } + }, + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "dev": true, + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", + "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "dev": true + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", + "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dir-glob/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", + "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "dependencies": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-jest": { + "version": "23.8.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", + "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/eslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/eslint/node_modules/globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/exec-sh": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", + "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "dev": true + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/expect/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.0" + ] + }, + "node_modules/fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fengari": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", + "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", + "dev": true, + "dependencies": { + "readline-sync": "^1.4.9", + "sprintf-js": "^1.1.1", + "tmp": "^0.0.33" + } + }, + "node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flat-cache/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-extra/node_modules/graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/globby": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "dependencies": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-fresh/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", + "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", + "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "dev": true + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "optional": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/javascript-stringify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", + "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", + "dev": true + }, + "node_modules/jest": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", + "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "dev": true, + "dependencies": { + "@jest/core": "^26.0.1", + "import-local": "^3.0.2", + "jest-cli": "^26.0.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", + "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "execa": "^4.0.0", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-changed-files/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-changed-files/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", + "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-changed-files/node_modules/get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-circus": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", + "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.1.0", + "@jest/test-result": "^25.1.0", + "@jest/types": "^25.1.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.1.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.1.0", + "jest-matcher-utils": "^25.1.0", + "jest-message-util": "^25.1.0", + "jest-snapshot": "^25.1.0", + "jest-util": "^25.1.0", + "pretty-format": "^25.1.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-config": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", + "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.0.1", + "@jest/types": "^26.0.1", + "babel-jest": "^26.0.1", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.0.1", + "jest-environment-node": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-jasmine2": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "micromatch": "^4.0.2", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-config/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-config/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-diff": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", + "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-each/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", + "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1", + "jsdom": "^16.2.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-jsdom/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-jsdom/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-node": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", + "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-environment-node/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-environment-node/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-environment-node/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-get-type": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", + "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-haste-map": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", + "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^26.0.0", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" + } + }, + "node_modules/jest-haste-map/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-haste-map/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-haste-map/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-haste-map/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-haste-map/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/jest-jasmine2": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", + "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", + "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.0.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.0.1", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-jasmine2/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-each": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", + "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-util": "^26.0.1", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-jasmine2/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-jasmine2/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-jasmine2/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-leak-detector": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", + "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", + "dev": true, + "dependencies": { + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-matcher-utils": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", + "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.1.0", + "jest-get-type": "^25.1.0", + "pretty-format": "^25.1.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-message-util/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", + "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", + "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve-dependencies/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-resolve/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-resolve/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runner": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", + "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.0.1", + "jest-jasmine2": "^26.0.1", + "jest-leak-detector": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "jest-runtime": "^26.0.1", + "jest-util": "^26.0.1", + "jest-worker": "^26.0.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runner/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-runner/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runner/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runner/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", + "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/environment": "^26.0.1", + "@jest/fake-timers": "^26.0.1", + "@jest/globals": "^26.0.1", + "@jest/source-map": "^26.0.0", + "@jest/test-result": "^26.0.1", + "@jest/transform": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.0.1", + "jest-haste-map": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.0.1", + "jest-snapshot": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/environment": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", + "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^26.0.1", + "@jest/types": "^26.0.1", + "jest-mock": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/fake-timers": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", + "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "@sinonjs/fake-timers": "^6.0.1", + "jest-message-util": "^26.0.1", + "jest-mock": "^26.0.1", + "jest-util": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/@types/prettier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", + "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/diff-sequences": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", + "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/expect": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", + "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-regex-util": "^26.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/jest-diff": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", + "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^26.0.0", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-matcher-utils": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", + "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", + "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-resolve": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", + "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "jest-util": "^26.0.1", + "read-pkg-up": "^7.0.1", + "resolve": "^1.17.0", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-snapshot": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", + "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.0.1", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.0.1", + "jest-get-type": "^26.0.0", + "jest-matcher-utils": "^26.0.1", + "jest-message-util": "^26.0.1", + "jest-resolve": "^26.0.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^26.0.1", + "semver": "^7.3.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/jest-runtime/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-runtime/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-serializer": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", + "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-serializer/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-util/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-util/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-validate": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", + "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.0.0", + "leven": "^3.1.0", + "pretty-format": "^26.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", + "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", + "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.0.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-watcher/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-watcher/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-worker": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", + "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "dev": true, + "dependencies": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/console": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", + "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "jest-message-util": "^26.0.1", + "jest-util": "^26.0.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/test-result": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", + "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "dev": true, + "dependencies": { + "@jest/console": "^26.0.1", + "@jest/types": "^26.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/@jest/types": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", + "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/jest/node_modules/jest-cli": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", + "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "dev": true, + "dependencies": { + "@jest/core": "^26.0.1", + "@jest/test-result": "^26.0.1", + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.0.1", + "jest-util": "^26.0.1", + "jest-validate": "^26.0.1", + "prompts": "^2.0.1", + "yargs": "^15.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/jest-message-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", + "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.0.1", + "@types/stack-utils": "^1.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/jest-util": { + "version": "26.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", + "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "dev": true, + "dependencies": { + "@jest/types": "^26.0.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest/node_modules/stack-utils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", + "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", + "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "acorn": "^7.1.1", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.2.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.0", + "domexception": "^2.0.1", + "escodegen": "^1.14.1", + "html-encoding-sniffer": "^2.0.1", + "is-potential-custom-element-name": "^1.0.0", + "nwsapi": "^2.2.0", + "parse5": "5.1.1", + "request": "^2.88.2", + "request-promise-native": "^1.0.8", + "saxes": "^5.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.0.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0", + "ws": "^7.2.3", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/lua-types": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", + "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "dependencies": { + "tmpl": "1.0.x" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-notifier": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", + "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "dev": true, + "optional": true, + "dependencies": { + "growly": "^1.3.0", + "is-wsl": "^2.1.1", + "semver": "^7.2.1", + "shellwords": "^0.1.1", + "uuid": "^7.0.3", + "which": "^2.0.2" + } + }, + "node_modules/node-notifier/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-notifier/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "optional": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-each-series": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", + "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "dev": true, + "dependencies": { + "node-modules-regexp": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/pretty-format": { + "version": "25.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", + "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.1.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", + "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/react-is": { + "version": "16.12.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", + "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/readline-sync": { + "version": "1.4.9", + "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", + "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-promise-core": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", + "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/request-promise-native": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", + "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "dev": true, + "dependencies": { + "request-promise-core": "1.1.3", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dependencies": { + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "node_modules/run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, + "node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "dev": true, + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/sane/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "node_modules/signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/slice-ansi/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/slice-ansi/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", + "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stack-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", + "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-length": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", + "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", + "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", + "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "dev": true, + "dependencies": { + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", + "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ts-jest": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", + "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", + "dev": true, + "dependencies": { + "@types/jest": "26.x", + "bs-logger": "0.x", + "buffer-from": "1.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "26.x", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "mkdirp": "1.x", + "semver": "7.x", + "yargs-parser": "18.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/ts-jest/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/@types/jest": { + "version": "26.0.13", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", + "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "dev": true, + "dependencies": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "node_modules/ts-jest/node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "node_modules/ts-jest/node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/jest-util": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", + "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "dev": true, + "dependencies": { + "@jest/types": "^26.3.0", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/@jest/types": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", + "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/ts-jest/node_modules/jest-util/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-node": { + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", + "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "dev": true, + "dependencies": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-script": "dist/script.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/tslib": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", + "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", + "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uuid": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", + "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "dev": true, + "optional": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", + "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": "8.x.x || >=10.10.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "dependencies": { + "makeerror": "1.0.x" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", + "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "dev": true, + "dependencies": { + "lodash.sortby": "^4.7.0", + "tr46": "^2.0.2", + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/whatwg-url/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", + "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "dev": true, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "node_modules/yargs": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "dev": true, + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, "dependencies": { "@babel/code-frame": { "version": "7.8.3", diff --git a/package.json b/package.json index a2623d785..c56a3dc05 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "postversion": "git push && git push --tags" }, "bin": { - "tstl": "./dist/tstl.js" + "tstl": "dist/tstl.js" }, "engines": { "node": ">=12.13.0" From 0d61965aa8a0f166c56eb5cba9e2962f3e5c9f27 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sun, 13 Dec 2020 21:28:59 +1000 Subject: [PATCH 300/764] Fix spread bug #898 (#936) --- .../visitors/variable-declaration.ts | 40 ++++++++++++------- test/unit/destructuring.spec.ts | 2 + 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 12ffeb763..bec7548e5 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -36,14 +36,13 @@ export function transformBindingPattern( propertyAccessStack: ts.PropertyName[] = [] ): lua.Statement[] { const result: lua.Statement[] = []; - const isObjectBindingPattern = ts.isObjectBindingPattern(pattern); for (const [index, element] of pattern.elements.entries()) { if (ts.isOmittedExpression(element)) continue; if (ts.isArrayBindingPattern(element.name) || ts.isObjectBindingPattern(element.name)) { // nested binding pattern - const propertyName = isObjectBindingPattern + const propertyName = ts.isObjectBindingPattern(pattern) ? element.propertyName : ts.createNumericLiteral(String(index + 1)); @@ -73,16 +72,29 @@ export function transformBindingPattern( continue; } - if (isObjectBindingPattern) { - const elements = pattern.elements as ts.NodeArray; - const usedProperties = elements.map(e => - lua.createTableFieldExpression( - lua.createBooleanLiteral(true), - lua.createStringLiteral( - ((e.propertyName ?? e.name) as ts.Identifier).text, - e.propertyName ?? e.name - ) - ) + if (ts.isObjectBindingPattern(pattern)) { + const excludedProperties: ts.Identifier[] = []; + + for (const element of pattern.elements) { + // const { ...x } = ...; + // ~~~~ + if (element.dotDotDotToken) continue; + + // const { x } = ...; + // ~ + if (ts.isIdentifier(element.name) && !element.propertyName) { + excludedProperties.push(element.name); + } + + // const { x: ... } = ...; + // ~~~~~~ + if (element.propertyName && element.name && ts.isIdentifier(element.propertyName)) { + excludedProperties.push(element.propertyName); + } + } + + const excludedPropertiesTable = excludedProperties.map(e => + lua.createTableFieldExpression(lua.createBooleanLiteral(true), lua.createStringLiteral(e.text, e)) ); expression = transformLuaLibFunction( @@ -90,7 +102,7 @@ export function transformBindingPattern( LuaLibFeature.ObjectRest, undefined, tableExpression, - lua.createTableExpression(usedProperties) + lua.createTableExpression(excludedPropertiesTable) ); } else { expression = transformLuaLibFunction( @@ -104,7 +116,7 @@ export function transformBindingPattern( } else { expression = lua.createTableIndexExpression( tableExpression, - isObjectBindingPattern ? propertyName : lua.createNumericLiteral(index + 1) + ts.isObjectBindingPattern(pattern) ? propertyName : lua.createNumericLiteral(index + 1) ); } diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 761930ec2..2ec12c7d1 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -12,6 +12,8 @@ const testCases = [ { binding: "{ ...rest }", value: {} }, { binding: "{ x, ...rest }", value: { x: "x" } }, { binding: "{ x, ...rest }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x, ...y }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x: y, ...z }", value: { x: "x", y: "y", z: "z" } }, { binding: "[]", value: [] }, { binding: "[x, y]", value: ["x", "y"] }, From a3bfc2dfce5782cb3bdb01bda1ac3831cc263942 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Tue, 15 Dec 2020 05:45:42 +1000 Subject: [PATCH 301/764] Fix export all bug and add NamespaceExport support (#937) * Fix export all bug #927 * Support NamespaceExport #928 * Update snapshots * Add unsafe Lua name NamespaceExport test * Add comments to transformExportAll and add export default if NamespaceExport --- src/transformation/visitors/modules/export.ts | 56 ++++++++++++++++--- .../__snapshots__/transformation.spec.ts.snap | 4 +- test/unit/modules/modules.spec.ts | 29 ++++++++++ 3 files changed, 79 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 5e12c6c5e..0fa5d9ee4 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -36,7 +36,7 @@ export const transformExportAssignment: FunctionVisitor = ( } }; -function transformExportAllFrom(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { +function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { assert(node.moduleSpecifier); if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { @@ -44,26 +44,64 @@ function transformExportAllFrom(context: TransformationContext, node: ts.ExportD } const moduleRequire = createModuleRequire(context, node.moduleSpecifier); - const tempModuleIdentifier = lua.createIdentifier("____export"); + // export * as ns from "..."; + // exports.ns = require(...) + if (node.exportClause && ts.isNamespaceExport(node.exportClause)) { + const assignToExports = lua.createAssignmentStatement( + lua.createTableIndexExpression( + createExportsIdentifier(), + lua.createStringLiteral(node.exportClause.name.text) + ), + moduleRequire + ); + return assignToExports; + } + + // export * from "..."; + // exports all values EXCEPT "default" from "..." + const result: lua.Statement[] = []; + + // local ____export = require(...) + const tempModuleIdentifier = lua.createIdentifier("____export"); const declaration = lua.createVariableDeclarationStatement(tempModuleIdentifier, moduleRequire); + result.push(declaration); + // ____exports[____exportKey] = ____exportValue const forKey = lua.createIdentifier("____exportKey"); const forValue = lua.createIdentifier("____exportValue"); + const leftAssignment = lua.createAssignmentStatement( + lua.createTableIndexExpression(createExportsIdentifier(), forKey), + forValue + ); - const body = lua.createBlock([ - lua.createAssignmentStatement(lua.createTableIndexExpression(createExportsIdentifier(), forKey), forValue), - ]); + // if key ~= "default" then + // -- export the value, do not export "default" values + // end + const ifBody = lua.createBlock([leftAssignment]); + const ifStatement = lua.createIfStatement( + lua.createBinaryExpression( + lua.cloneIdentifier(forKey), + lua.createStringLiteral("default"), + lua.SyntaxKind.InequalityOperator + ), + ifBody + ); + // for ____exportKey, ____exportValue in ____export do + // -- export ____exportValue, unless ____exportKey is "default" + // end const pairsIdentifier = lua.createIdentifier("pairs"); const forIn = lua.createForInStatement( - body, + lua.createBlock([ifStatement]), [lua.cloneIdentifier(forKey), lua.cloneIdentifier(forValue)], [lua.createCallExpression(pairsIdentifier, [lua.cloneIdentifier(tempModuleIdentifier)])] ); + result.push(forIn); + // Wrap this in a DoStatement to prevent polluting the scope. - return lua.createDoStatement([declaration, forIn], node); + return lua.createDoStatement(result, node); } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => @@ -127,7 +165,7 @@ export const getExported = (context: TransformationContext, exportSpecifiers: ts export const transformExportDeclaration: FunctionVisitor = (node, context) => { if (!node.exportClause) { // export * from "..."; - return transformExportAllFrom(context, node); + return transformExportAll(context, node); } if (!context.resolver.isValueAliasDeclaration(node)) { @@ -136,7 +174,7 @@ export const transformExportDeclaration: FunctionVisitor = if (ts.isNamespaceExport(node.exportClause)) { // export * as ns from "..."; - throw new Error("NamespaceExport is not supported"); + return transformExportAll(context, node); } const exportSpecifiers = getExported(context, node.exportClause); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 942f17aa2..a299f2640 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -64,7 +64,9 @@ ____exports.uwv = xyz do local ____export = require(\\"xyz\\") for ____exportKey, ____exportValue in pairs(____export) do - ____exports[____exportKey] = ____exportValue + if ____exportKey ~= \\"default\\" then + ____exports[____exportKey] = ____exportValue + end end end do diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 885f24541..b6aefdc0c 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -275,3 +275,32 @@ test("export default function with future reference", () => { .setReturnExport("result") .expectToMatchJsResult(); }); + +const moduleFile = ` +export default true; +export const foo = "bar"; +`; + +test("export all does not include default", () => { + util.testBundle` + export * from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ foo: "bar" }); +}); + +test("namespace export does not include default", () => { + util.testBundle` + export * as result from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ result: { default: true, foo: "bar" } }); +}); + +test("namespace export with unsafe Lua name", () => { + util.testBundle` + export * as $$$ from "./module"; + ` + .addExtraFile("module.ts", moduleFile) + .expectToEqual({ $$$: { default: true, foo: "bar" } }); +}); From befc0c745b3886ba290a8f24ddc748fc9531f09e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Dec 2020 20:49:27 +0100 Subject: [PATCH 302/764] 0.36.1 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 73ebb5214..85e431644 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "lockfileVersion": 2, "requires": true, "packages": { diff --git a/package.json b/package.json index c56a3dc05..16e3e20a1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "license": "MIT", From 5ced4c74ff5fada401a7a6f5e3672e2d6c19d40a Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Mon, 21 Dec 2020 21:51:27 +1000 Subject: [PATCH 303/764] Omit tostring from template literal spans if they are strings (#948) * Omit tostring from template literal spans if they are a definite string type * Add negative tests * Simplify and split templateLiteral tests --- src/transformation/visitors/template.ts | 8 +++++++- test/unit/templateLiterals.spec.ts | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 784cf7e4e..1b714d765 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -3,6 +3,7 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; +import { isStringType } from "../utils/typescript/types"; import { transformArguments, transformContextualCallExpression } from "./call"; // TODO: Source positions @@ -25,7 +26,12 @@ export const transformTemplateExpression: FunctionVisitor for (const span of node.templateSpans) { const expression = context.transformExpression(span.expression); - parts.push(wrapInToStringForConcat(expression)); + const spanType = context.checker.getTypeAtLocation(span.expression); + if (isStringType(context, spanType)) { + parts.push(expression); + } else { + parts.push(wrapInToStringForConcat(expression)); + } const text = span.literal.text; if (text.length > 0) { diff --git a/test/unit/templateLiterals.spec.ts b/test/unit/templateLiterals.spec.ts index 7db192a88..d5dc519a5 100644 --- a/test/unit/templateLiterals.spec.ts +++ b/test/unit/templateLiterals.spec.ts @@ -60,3 +60,26 @@ test.each(["func`noSelfParameter`", "obj.func`noSelfParameter`", "obj[`func`]`no `.expectToMatchJsResult(); } ); + +test.each(["number", "string | any"])("template span expect tostring for non string type (%p)", type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain("tostring")) + .expectToMatchJsResult(); +}); + +test.each(["string", "'string literal type'", "string & unknown"])( + "template span expect no tostring for string-like type (%p)", + type => { + util.testFunction` + // @ts-ignore + const msg = "" as ${type}; + return \`\${msg}\`; + ` + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("tostring")) + .expectToMatchJsResult(); + } +); From 237a788354640a3f9e7141b067e22bcb1b0b8e23 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Dec 2020 15:32:15 +0100 Subject: [PATCH 304/764] Fixed incorrect variable declarations in some cases when there is no initializer (#952) --- src/transformation/utils/lua-ast.ts | 4 +++- test/unit/hoisting.spec.ts | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index b9b600c90..91e81bc9a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -176,7 +176,9 @@ export function createLocalOrExportedOrGlobalDeclaration( if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); - assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + if (rhs) { + assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); + } } else { declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 997c53f73..16172b410 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -254,3 +254,14 @@ test("Hoisting Shorthand Property", () => { return foo();`; expect(util.transpileAndExecute(code)).toBe("foobar"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944 +test("Hoisting variable without initializer", () => { + util.testFunction` + function foo() { + return x; + } + let x: number; + return foo(); + `.expectToMatchJsResult(); +}); From 3546f59d39555c539be6b1ff4281a5e89918c0c6 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Tue, 22 Dec 2020 13:23:57 -0800 Subject: [PATCH 305/764] Deprecate phantom, metaExtension, extension, pureAbstract (#949) * Deprecate phantom, metaExtension, extension, pureAbstract I tried to keep the deprecation warnings seperate from existing code/tests, so they can be easily removed once we delete the the deprecated annotations. Fixes #652 * Add URL to annotationDeprecated diangostic * LowerCase deprecated links Ignore all warnings in legacyutils transpileString --- package-lock.json | 2 +- src/transformation/utils/diagnostics.ts | 77 ++++++++++++------- src/transformation/visitors/class/index.ts | 8 ++ src/transformation/visitors/class/utils.ts | 5 ++ src/transformation/visitors/namespace.ts | 2 + test/legacy-utils.ts | 9 ++- test/translation/transformation.spec.ts | 2 + .../__snapshots__/deprecated.spec.ts.snap | 26 +++++++ .../__snapshots__/extension.spec.ts.snap | 30 ++++++-- .../__snapshots__/metaExtension.spec.ts.snap | 10 ++- test/unit/annotations/deprecated.spec.ts | 27 +++++++ test/unit/annotations/extension.spec.ts | 7 +- test/unit/annotations/metaExtension.spec.ts | 13 +++- test/util.ts | 10 ++- 14 files changed, 180 insertions(+), 48 deletions(-) create mode 100644 test/unit/annotations/__snapshots__/deprecated.spec.ts.snap create mode 100644 test/unit/annotations/deprecated.spec.ts diff --git a/package-lock.json b/package-lock.json index 85e431644..f775485f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "typescript-to-lua", - "version": "0.36.0", + "version": "0.36.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index a5bdb35db..0197d90c2 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -3,21 +3,32 @@ import { LuaTarget } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; -const createDiagnosticFactory = (message: string | ((...args: TArgs) => string)) => +type MessageProvider = string | ((...args: TArgs) => string); + +const createDiagnosticFactory = ( + category: ts.DiagnosticCategory, + message: MessageProvider +) => createSerialDiagnosticFactory((node: ts.Node, ...args: TArgs) => ({ file: node.getSourceFile(), start: node.getStart(), length: node.getWidth(), messageText: typeof message === "string" ? message : message(...args), + category, })); -export const unsupportedNodeKind = createDiagnosticFactory( +const createErrorDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Error, message); +const createWarningDiagnosticFactory = (message: MessageProvider) => + createDiagnosticFactory(ts.DiagnosticCategory.Warning, message); + +export const unsupportedNodeKind = createErrorDiagnosticFactory( (kind: ts.SyntaxKind) => `Unsupported node kind ${ts.SyntaxKind[kind]}` ); -export const forbiddenForIn = createDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); +export const forbiddenForIn = createErrorDiagnosticFactory("Iterating over arrays with 'for ... in' is not allowed."); -export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedNoSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with a 'this' parameter to function${nameReference} with no 'this'. ` + @@ -25,7 +36,7 @@ export const unsupportedNoSelfFunctionConversion = createDiagnosticFactory((name ); }); -export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: string) => { +export const unsupportedSelfFunctionConversion = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` '${name}'` : ""; return ( `Unable to convert function with no 'this' parameter to function${nameReference} with 'this'. ` + @@ -33,7 +44,7 @@ export const unsupportedSelfFunctionConversion = createDiagnosticFactory((name?: ); }); -export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: string) => { +export const unsupportedOverloadAssignment = createErrorDiagnosticFactory((name?: string) => { const nameReference = name ? ` to '${name}'` : ""; return ( `Unsupported assignment of function with different overloaded types for 'this'${nameReference}. ` + @@ -41,88 +52,98 @@ export const unsupportedOverloadAssignment = createDiagnosticFactory((name?: str ); }); -export const decoratorInvalidContext = createDiagnosticFactory("Decorator function cannot have 'this: void'."); +export const decoratorInvalidContext = createErrorDiagnosticFactory("Decorator function cannot have 'this: void'."); -export const annotationInvalidArgumentCount = createDiagnosticFactory( +export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const extensionCannotConstruct = createDiagnosticFactory( +export const extensionCannotConstruct = createErrorDiagnosticFactory( "Cannot construct classes with '@extension' or '@metaExtension' annotation." ); -export const extensionCannotExtend = createDiagnosticFactory( +export const extensionCannotExtend = createErrorDiagnosticFactory( "Cannot extend classes with '@extension' or '@metaExtension' annotation." ); -export const extensionCannotExport = createDiagnosticFactory( +export const extensionCannotExport = createErrorDiagnosticFactory( "Cannot export classes with '@extension' or '@metaExtension' annotation." ); -export const extensionInvalidInstanceOf = createDiagnosticFactory( +export const extensionInvalidInstanceOf = createErrorDiagnosticFactory( "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." ); -export const extensionAndMetaExtensionConflict = createDiagnosticFactory( +export const extensionAndMetaExtensionConflict = createErrorDiagnosticFactory( "Cannot use both '@extension' and '@metaExtension' annotations on the same class." ); -export const metaExtensionMissingExtends = createDiagnosticFactory( +export const metaExtensionMissingExtends = createErrorDiagnosticFactory( "'@metaExtension' annotation requires the extension of the metatable class." ); -export const invalidForRangeCall = createDiagnosticFactory((message: string) => `Invalid @forRange call: ${message}.`); +export const invalidForRangeCall = createErrorDiagnosticFactory( + (message: string) => `Invalid @forRange call: ${message}.` +); -export const luaTableMustBeAmbient = createDiagnosticFactory( +export const luaTableMustBeAmbient = createErrorDiagnosticFactory( "Classes with the '@luaTable' annotation must be ambient." ); -export const luaTableCannotBeExtended = createDiagnosticFactory( +export const luaTableCannotBeExtended = createErrorDiagnosticFactory( "Cannot extend classes with the '@luaTable' annotation." ); -export const luaTableInvalidInstanceOf = createDiagnosticFactory( +export const luaTableInvalidInstanceOf = createErrorDiagnosticFactory( "The instanceof operator cannot be used with a '@luaTable' class." ); -export const luaTableCannotBeAccessedDynamically = createDiagnosticFactory("@luaTable cannot be accessed dynamically."); +export const luaTableCannotBeAccessedDynamically = createErrorDiagnosticFactory( + "@luaTable cannot be accessed dynamically." +); -export const luaTableForbiddenUsage = createDiagnosticFactory( +export const luaTableForbiddenUsage = createErrorDiagnosticFactory( (description: string) => `Invalid @luaTable usage: ${description}.` ); -export const luaIteratorForbiddenUsage = createDiagnosticFactory( +export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + "You must use a destructuring statement to catch results from a lua iterator with " + "the '@tupleReturn' annotation." ); -export const unsupportedAccessorInObjectLiteral = createDiagnosticFactory( +export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( "Accessors in object literal are not supported." ); -export const unsupportedRightShiftOperator = createDiagnosticFactory( +export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); -export const unsupportedForTarget = createDiagnosticFactory( +export const unsupportedForTarget = createErrorDiagnosticFactory( (functionality: string, version: Exclude) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); -export const unsupportedProperty = createDiagnosticFactory( +export const unsupportedProperty = createErrorDiagnosticFactory( (parentName: string, property: string) => `${parentName}.${property} is unsupported.` ); -export const invalidAmbientIdentifierName = createDiagnosticFactory( +export const invalidAmbientIdentifierName = createErrorDiagnosticFactory( (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` ); -export const unresolvableRequirePath = createDiagnosticFactory( +export const unresolvableRequirePath = createErrorDiagnosticFactory( (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` ); -export const unsupportedVarDeclaration = createDiagnosticFactory( +export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); + +export const annotationDeprecated = createWarningDiagnosticFactory( + (kind: AnnotationKind) => + `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` +); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 9142775f7..d9da80cf7 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -4,6 +4,7 @@ import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { + annotationDeprecated, extensionAndMetaExtensionConflict, extensionCannotExport, extensionCannotExtend, @@ -94,6 +95,13 @@ function transformClassLikeDeclaration( const isExtension = extensionDirective !== undefined; const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); + if (isExtension) { + context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.Extension)); + } + if (isMetaExtension) { + context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.MetaExtension)); + } + if (isExtension && isMetaExtension) { context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); } diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 9ba263818..88388adf8 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; +import { annotationDeprecated } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -22,6 +23,10 @@ export function getExtendedNode( if (!annotations.has(AnnotationKind.PureAbstract)) { return extendsClause.types[0]; } + + if (annotations.has(AnnotationKind.PureAbstract)) { + context.diagnostics.push(annotationDeprecated(extendsClause, AnnotationKind.PureAbstract)); + } } export function getExtendedType( diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 35190705f..3316ace4b 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { annotationDeprecated } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, @@ -53,6 +54,7 @@ export const transformModuleDeclaration: FunctionVisitor = const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Phantom)); return context.transformStatements(node.body.statements); } diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts index de781d954..534c5849a 100644 --- a/test/legacy-utils.ts +++ b/test/legacy-utils.ts @@ -13,7 +13,9 @@ export function transpileString( const { diagnostics, file } = transpileStringResult(str, options); expect(file.lua).toBeDefined(); - const errors = diagnostics.filter(d => !ignoreDiagnostics || d.source === "typescript-to-lua"); + const errors = diagnostics.filter( + d => (!ignoreDiagnostics || d.source === "typescript-to-lua") && d.category === ts.DiagnosticCategory.Error + ); expect(errors).not.toHaveDiagnostics(); return file.lua!.trim(); @@ -86,14 +88,15 @@ export function transpileAndExecute( tsStr: string, compilerOptions?: tstl.CompilerOptions, luaHeader?: string, - tsHeader?: string + tsHeader?: string, + ignoreDiagnostics = false ): any { const wrappedTsString = `${tsHeader ?? ""} declare function JSONStringify(this: void, p: any): string; function __runTest(this: void): any {${tsStr}}`; const lua = `${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} + ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnostics)} return __runTest();`; return executeLua(lua); diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 7a5088fcb..4e0d7dd9d 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -1,6 +1,7 @@ import * as fs from "fs"; import * as path from "path"; import * as tstl from "../../src"; +import { annotationDeprecated } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; const fixturesPath = path.join(__dirname, "./transformation"); @@ -13,6 +14,7 @@ const fixtures = fs test.each(fixtures)("Transformation (%s)", (_name, content) => { util.testModule(content) .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .ignoreDiagnostics([annotationDeprecated.code]) .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap new file mode 100644 index 000000000..956143495 --- /dev/null +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`extension deprecation: code 1`] = `""`; + +exports[`extension deprecation: code 2`] = `"local __meta__A = debug.getregistry().A"`; + +exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; + +exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; + +exports[`phantom deprecation: code 1`] = ` +"function nsMember(self) +end" +`; + +exports[`phantom deprecation: diagnostics 1`] = `"main.ts(3,9): warning TSTL: '@phantom' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; + +exports[`pureAbstract deprecation: code 1`] = ` +"require(\\"lualib_bundle\\"); +ClassB = __TS__Class() +ClassB.name = \\"ClassB\\" +function ClassB.prototype.____constructor(self) +end" +`; + +exports[`pureAbstract deprecation: diagnostics 1`] = `"main.ts(4,22): warning TSTL: '@pureAbstract' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap index f69a1315a..606d21635 100644 --- a/test/unit/annotations/__snapshots__/extension.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/extension.spec.ts.snap @@ -5,7 +5,10 @@ exports[`Class construct extension ("extension"): code 1`] = ` b = __TS__New(B)" `; -exports[`Class construct extension ("extension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class construct extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class construct extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -13,7 +16,10 @@ local __meta__A = debug.getregistry().A b = __TS__New(B)" `; -exports[`Class construct extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class construct extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class extends extension ("extension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -22,7 +28,10 @@ C.name = \\"C\\" __TS__ClassExtends(C, B)" `; -exports[`Class extends extension ("extension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class extends extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." +`; exports[`Class extends extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -32,14 +41,20 @@ C.name = \\"C\\" __TS__ClassExtends(C, B)" `; -exports[`Class extends extension ("metaExtension"): diagnostics 1`] = `"main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation."`; +exports[`Class extends extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." +`; exports[`instanceof extension ("extension"): code 1`] = ` "require(\\"lualib_bundle\\"); result = __TS__InstanceOf(foo, B)" `; -exports[`instanceof extension ("extension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; +exports[`instanceof extension ("extension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. +main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." +`; exports[`instanceof extension ("metaExtension"): code 1`] = ` "require(\\"lualib_bundle\\"); @@ -47,4 +62,7 @@ local __meta__A = debug.getregistry().A result = __TS__InstanceOf(foo, B)" `; -exports[`instanceof extension ("metaExtension"): diagnostics 1`] = `"main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation."`; +exports[`instanceof extension ("metaExtension"): diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." +`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap index ba6b5e0a1..ad3f2ac51 100644 --- a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap @@ -6,7 +6,10 @@ local __meta___LOADED = debug.getregistry()._LOADED e = __TS__New(Ext)" `; -exports[`DontAllowInstantiation: diagnostics 1`] = `"main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation."`; +exports[`DontAllowInstantiation: diagnostics 1`] = ` +"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. +main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." +`; exports[`IncorrectUsage: code 1`] = ` "function LoadedExt.test(self) @@ -14,4 +17,7 @@ exports[`IncorrectUsage: code 1`] = ` end" `; -exports[`IncorrectUsage: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class."`; +exports[`IncorrectUsage: diagnostics 1`] = ` +"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class. +main.ts(3,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information." +`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts new file mode 100644 index 000000000..488b66a28 --- /dev/null +++ b/test/unit/annotations/deprecated.spec.ts @@ -0,0 +1,27 @@ +import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; +import * as util from "../../util"; + +test.each(["extension", "metaExtension"])("extension deprecation", extensionType => { + util.testModule` + declare class A {} + /** @${extensionType} **/ + class B extends A {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("phantom deprecation", () => { + util.testModule` + /** @phantom **/ + namespace A { + function nsMember() {} + } + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("pureAbstract deprecation", () => { + util.testModule` + /** @pureAbstract */ + declare class ClassA {} + class ClassB extends ClassA {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts index c8da1b81b..27093801b 100644 --- a/test/unit/annotations/extension.spec.ts +++ b/test/unit/annotations/extension.spec.ts @@ -1,4 +1,5 @@ import { + annotationDeprecated, extensionCannotConstruct, extensionCannotExtend, extensionInvalidInstanceOf, @@ -11,7 +12,7 @@ test.each(["extension", "metaExtension"])("Class extends extension (%p)", extens /** @${extensionType} **/ class B extends A {} class C extends B {} - `.expectDiagnosticsToMatchSnapshot([extensionCannotExtend.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotExtend.code]); }); test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { @@ -20,7 +21,7 @@ test.each(["extension", "metaExtension"])("Class construct extension (%p)", exte /** @${extensionType} **/ class B extends A {} const b = new B(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); }); test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { @@ -30,5 +31,5 @@ test.each(["extension", "metaExtension"])("instanceof extension (%p)", extension class B extends A {} declare const foo: any; const result = foo instanceof B; - `.expectDiagnosticsToMatchSnapshot([extensionInvalidInstanceOf.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionInvalidInstanceOf.code]); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index 405eeee5a..aec48f4cf 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -1,4 +1,8 @@ -import { extensionCannotConstruct, metaExtensionMissingExtends } from "../../../src/transformation/utils/diagnostics"; +import { + annotationDeprecated, + extensionCannotConstruct, + metaExtensionMissingExtends, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("MetaExtension", () => { @@ -19,7 +23,8 @@ test("MetaExtension", () => { 'return debug.getregistry()["_LOADED"].test();', undefined, undefined, - tsHeader + tsHeader, + true ); expect(result).toBe(5); @@ -33,7 +38,7 @@ test("IncorrectUsage", () => { return 5; } } - `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code]); + `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code, annotationDeprecated.code]); }); test("DontAllowInstantiation", () => { @@ -42,5 +47,5 @@ test("DontAllowInstantiation", () => { /** @metaExtension */ class Ext extends _LOADED {} const e = new Ext(); - `.expectDiagnosticsToMatchSnapshot([extensionCannotConstruct.code]); + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); }); diff --git a/test/util.ts b/test/util.ts index 560b0102f..7be98e727 100644 --- a/test/util.ts +++ b/test/util.ts @@ -298,7 +298,9 @@ export abstract class TestBuilder { private getLuaDiagnostics(): ts.Diagnostic[] { const { diagnostics } = this.getLuaResult(); - return diagnostics.filter(d => this.semanticCheck || d.source === "typescript-to-lua"); + return diagnostics.filter( + d => (this.semanticCheck || d.source === "typescript-to-lua") && !this.ignoredDiagnostics.includes(d.code) + ); } // Actions @@ -311,6 +313,12 @@ export abstract class TestBuilder { } private diagnosticsChecked = false; + private ignoredDiagnostics: number[] = []; + + public ignoreDiagnostics(ignored: number[]): this { + this.ignoredDiagnostics.push(...ignored); + return this; + } public expectToHaveDiagnostics(expected?: number[]): this { if (this.diagnosticsChecked) return this; From 0cb8f5f000759cdff2da81bbf5ba2385177447c1 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Wed, 23 Dec 2020 23:34:58 +1000 Subject: [PATCH 306/764] Multi Helper (#821) * Add tuple helper * Elide helper import declarations * tuple validation progress * Use Visitors * Fix VariableDeclaration * Implement tuple helper * Use nil if no arguments were provided to tuple * Add destructuring assignment support * Support side effects and add more validation * Add unit tests * Add test for tuple within multiple VariableDeclarations * Can be used inside for loops * Fix syntax error in test case * Remove unnecessary boilerplate from tuple helper * Use some instead of every * Use flatMap in tuple instead of map * Use Boolean instead of ternary in tuple * Import helpers from /helpers * Do not use ts-ignore in tuple test cases * Use more specific test case names for tuple * Remove unsafe cast in for-of * Remove tuple visitors * Rename to multi and MultiReturn * Revert FunctionVisitor conversion * Rename tupleResult to multiResult * Update tsconfig.json Co-Authored-By: ark120202 * Update test/unit/helpers/multi.spec.ts Co-Authored-By: ark120202 * Refactor for new createVirtualProgram code * Move helper transformer to transformation * Use nullish operator instead of Boolean constructor * Attempt a CommonJS implementation of multi * Add MultiReturn alias MR * Add export in front of multi function * Simplify multi js implementation * Remove MR alias * Make multi helper global * Revert multi helper import changes * Apply suggestions from code review Co-Authored-By: ark120202 * Inline and join multi conditions * Rename to $multi * Use declare for top level $multi * Add empty tuple to MultiReturn * Add declare to MultiReturn to top level declaration * Reduce number of diagnostics for multi error * Improve multi diagnostics * Apply suggestions from code review Co-Authored-By: ark120202 * Rename utils to helpers * Include helpers inside lualib's tsconfig * Fix esnext target error * Drop support for VariableDeclarations, support only ReturnStatements * Simplify multi tests a bit * Remove multi.js * Revert "Drop support for VariableDeclarations, support only ReturnStatements" This reverts commit b7d1ec0c6b29ccbcf5b904974f76ce20108fe1aa. * State that multi can only be used in return statements * Throw an error if a helper is unknown * Improve multi nomenclature * Disallow multi function use in non-return statements * Merge helpers together into index.d.ts * Prefer for loop to filter/map/foreach * Add test to return spreaded multi type from multi type function * Rename to language extensions / extensions * Remove remaining helper references * Allow multi call as ConciseBody * Remove ts-ignore * Add check first to all multi transforms * Add multi example use case Co-authored-by: ark120202 --- language-extensions/index.d.ts | 2 + package.json | 3 +- src/lualib/tsconfig.json | 2 +- src/transformation/utils/diagnostics.ts | 26 +++ .../utils/language-extensions.ts | 28 +++ src/transformation/visitors/call.ts | 6 +- .../visitors/expression-statement.ts | 10 + src/transformation/visitors/function.ts | 5 + src/transformation/visitors/identifier.ts | 8 +- .../visitors/language-extensions/multi.ts | 188 ++++++++++++++++++ src/transformation/visitors/literal.ts | 9 +- src/transformation/visitors/return.ts | 9 + .../visitors/variable-declaration.ts | 9 + src/transpilation/index.ts | 16 +- test/tsconfig.json | 3 +- .../__snapshots__/multi.spec.ts.snap | 135 +++++++++++++ test/unit/language-extensions/multi.spec.ts | 128 ++++++++++++ 17 files changed, 575 insertions(+), 12 deletions(-) create mode 100644 language-extensions/index.d.ts create mode 100644 src/transformation/utils/language-extensions.ts create mode 100644 src/transformation/visitors/language-extensions/multi.ts create mode 100644 test/unit/language-extensions/__snapshots__/multi.spec.ts.snap create mode 100644 test/unit/language-extensions/multi.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts new file mode 100644 index 000000000..d7270be32 --- /dev/null +++ b/language-extensions/index.d.ts @@ -0,0 +1,2 @@ +declare function $multi(...values: T): MultiReturn; +declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; diff --git a/package.json b/package.json index 16e3e20a1..017169255 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "files": [ "dist/**/*.js", "dist/**/*.lua", - "dist/**/*.ts" + "dist/**/*.ts", + "language-extensions/**/*.ts" ], "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index b9d6de8ce..f16968dc1 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "../../dist/lualib", "target": "esnext", "lib": ["esnext"], - "types": [], + "types": ["../../language-extensions"], "skipLibCheck": true, "noUnusedLocals": true, diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 0197d90c2..8f69eadd9 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -142,6 +142,32 @@ export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); +export const invalidMultiFunctionUse = createErrorDiagnosticFactory( + "The $multi function must be called in an expression that is returned." +); + +export const invalidMultiTypeToNonArrayBindingPattern = createErrorDiagnosticFactory( + "Expected an array destructuring pattern." +); + +export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); + +export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosticFactory( + "There must be one or more elements specified here." +); + +export const invalidMultiTypeArrayBindingPatternElementInitializer = createErrorDiagnosticFactory( + "This array binding pattern cannot have initializers." +); + +export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnosticFactory( + "This array literal pattern cannot have initializers." +); + +export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( + "Omitted expressions and BindingElements are expected here." +); + export const annotationDeprecated = createWarningDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts new file mode 100644 index 000000000..8f3b07672 --- /dev/null +++ b/src/transformation/utils/language-extensions.ts @@ -0,0 +1,28 @@ +import * as ts from "typescript"; +import * as path from "path"; + +export enum ExtensionKind { + MultiFunction = "MultiFunction", + MultiType = "MultiType", +} + +function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { + const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); + const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); + return extensionDirectory === sourceFileDirectory; +} + +export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { + const sourceFile = declaration.getSourceFile(); + if (isSourceFileFromLanguageExtensions(sourceFile)) { + if (ts.isFunctionDeclaration(declaration) && declaration?.name?.text === "$multi") { + return ExtensionKind.MultiFunction; + } + + if (ts.isTypeAliasDeclaration(declaration) && declaration.name.text === "MultiReturn") { + return ExtensionKind.MultiType; + } + + throw new Error("Unknown extension kind"); + } +} diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 366ff8041..90959a580 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -11,6 +11,7 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; +import { returnsMultiType } from "./language-extensions/multi"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -250,9 +251,8 @@ export const transformCallExpression: FunctionVisitor = (node // TODO: Currently it's also used as an array member export const transformSpreadElement: FunctionVisitor = (node, context) => { const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) { - return innerExpression; - } + if (isTupleReturnCall(context, node.expression)) return innerExpression; + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { return lua.createDotsLiteral(node); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 890695be0..4901a3210 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -4,8 +4,18 @@ import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; +import { returnsMultiType, transformMultiDestructuringAssignmentStatement } from "./language-extensions/multi"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { + if ( + ts.isBinaryExpression(node.expression) && + node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isCallExpression(node.expression.right) && + returnsMultiType(context, node.expression.right) + ) { + return transformMultiDestructuringAssignmentStatement(context, node); + } + const luaTableResult = transformLuaTableExpressionStatement(context, node); if (luaTableResult) { return luaTableResult; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index d3fb88a5a..424e75efe 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,6 +15,7 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; +import { isMultiFunction, transformMultiCallExpressionToReturnStatement } from "./language-extensions/multi"; import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; @@ -55,6 +56,10 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { + if (ts.isCallExpression(body) && isMultiFunction(context, body)) { + return [transformMultiCallExpressionToReturnStatement(context, body)]; + } + const returnStatement = transformExpressionBodyToReturnStatement(context, body); return [returnStatement]; } diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 54ed2a2f0..6e95411a5 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,13 +3,19 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall } from "../utils/diagnostics"; +import { invalidForRangeCall, invalidMultiFunctionUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; +import { isMultiFunctionNode } from "./language-extensions/multi"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { + if (isMultiFunctionNode(context, identifier)) { + context.diagnostics.push(invalidMultiFunctionUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts new file mode 100644 index 000000000..a6cb2a755 --- /dev/null +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -0,0 +1,188 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { transformAssignmentLeftHandSideExpression } from "../binary-expression/assignments"; +import { transformIdentifier } from "../identifier"; +import { transformArguments } from "../call"; +import { getDependenciesOfSymbol, createExportedIdentifier } from "../../utils/export"; +import { createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; +import { + invalidMultiTypeArrayBindingPatternElementInitializer, + invalidMultiTypeArrayLiteralElementInitializer, + invalidMultiTypeToEmptyPatternOrArrayLiteral, + invalidMultiTypeToNonArrayBindingPattern, + invalidMultiTypeToNonArrayLiteral, + unsupportedMultiFunctionAssignment, + invalidMultiFunctionUse, +} from "../../utils/diagnostics"; +import { assert } from "../../../utils"; + +const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; + +const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; + +export function isMultiFunction(context: TransformationContext, expression: ts.CallExpression): boolean { + const type = context.checker.getTypeAtLocation(expression.expression); + return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; +} + +export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + return signature?.getReturnType().aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; +} + +export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const type = context.checker.getTypeAtLocation(node); + return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; +} + +export function transformMultiCallExpressionToReturnStatement( + context: TransformationContext, + expression: ts.Expression +): lua.Statement { + assert(ts.isCallExpression(expression)); + + const expressions = transformArguments(context, expression.arguments); + return lua.createReturnStatement(expressions, expression); +} + +export function transformMultiReturnStatement( + context: TransformationContext, + statement: ts.ReturnStatement +): lua.Statement { + assert(statement.expression); + + return transformMultiCallExpressionToReturnStatement(context, statement.expression); +} + +function transformMultiFunctionArguments( + context: TransformationContext, + expression: ts.CallExpression +): lua.Expression[] | lua.Expression { + if (!isMultiFunction(context, expression)) { + return context.transformExpression(expression); + } + + if (expression.arguments.length === 0) { + return lua.createNilLiteral(expression); + } + + return expression.arguments.map(e => context.transformExpression(e)); +} + +export function transformMultiVariableDeclaration( + context: TransformationContext, + declaration: ts.VariableDeclaration +): lua.Statement[] { + assert(declaration.initializer); + assert(ts.isCallExpression(declaration.initializer)); + + if (!ts.isArrayBindingPattern(declaration.name)) { + context.diagnostics.push(invalidMultiTypeToNonArrayBindingPattern(declaration.name)); + return []; + } + + if (declaration.name.elements.length < 1) { + context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(declaration.name)); + return []; + } + + if (declaration.name.elements.some(e => ts.isBindingElement(e) && e.initializer)) { + context.diagnostics.push(invalidMultiTypeArrayBindingPatternElementInitializer(declaration.name)); + return []; + } + + if (isMultiFunction(context, declaration.initializer)) { + context.diagnostics.push(invalidMultiFunctionUse(declaration.initializer)); + return []; + } + + const leftIdentifiers: lua.Identifier[] = []; + + for (const element of declaration.name.elements) { + if (ts.isBindingElement(element)) { + if (ts.isIdentifier(element.name)) { + leftIdentifiers.push(transformIdentifier(context, element.name)); + } else { + context.diagnostics.push(unsupportedMultiFunctionAssignment(element)); + } + } else if (ts.isOmittedExpression(element)) { + leftIdentifiers.push(lua.createAnonymousIdentifier(element)); + } + } + + const rightExpressions = transformMultiFunctionArguments(context, declaration.initializer); + return createLocalOrExportedOrGlobalDeclaration(context, leftIdentifiers, rightExpressions, declaration); +} + +export function transformMultiDestructuringAssignmentStatement( + context: TransformationContext, + statement: ts.ExpressionStatement +): lua.Statement[] | undefined { + assert(ts.isBinaryExpression(statement.expression)); + assert(ts.isCallExpression(statement.expression.right)); + + if (!ts.isArrayLiteralExpression(statement.expression.left)) { + context.diagnostics.push(invalidMultiTypeToNonArrayLiteral(statement.expression.left)); + return []; + } + + if (statement.expression.left.elements.some(ts.isBinaryExpression)) { + context.diagnostics.push(invalidMultiTypeArrayLiteralElementInitializer(statement.expression.left)); + return []; + } + + if (statement.expression.left.elements.length < 1) { + context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(statement.expression.left)); + return []; + } + + if (isMultiFunction(context, statement.expression.right)) { + context.diagnostics.push(invalidMultiFunctionUse(statement.expression.right)); + return []; + } + + const transformLeft = (expression: ts.Expression): lua.AssignmentLeftHandSideExpression => + ts.isOmittedExpression(expression) + ? lua.createAnonymousIdentifier(expression) + : transformAssignmentLeftHandSideExpression(context, expression); + + const leftIdentifiers = statement.expression.left.elements.map(transformLeft); + + const rightExpressions = transformMultiFunctionArguments(context, statement.expression.right); + + const trailingStatements = statement.expression.left.elements.flatMap(expression => { + const symbol = context.checker.getSymbolAtLocation(expression); + const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; + return dependentSymbols.map(symbol => { + const identifierToAssign = createExportedIdentifier(context, lua.createIdentifier(symbol.name)); + return lua.createAssignmentStatement(identifierToAssign, transformLeft(expression)); + }); + }); + + return [lua.createAssignmentStatement(leftIdentifiers, rightExpressions, statement), ...trailingStatements]; +} + +export function findMultiAssignmentViolations( + context: TransformationContext, + node: ts.ObjectLiteralExpression +): ts.Node[] { + const result: ts.Node[] = []; + + for (const element of node.properties) { + if (!ts.isShorthandPropertyAssignment(element)) continue; + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + const declaration = valueSymbol.valueDeclaration; + if (declaration && isMultiFunctionDeclaration(declaration)) { + context.diagnostics.push(invalidMultiFunctionUse(element)); + result.push(element); + } + } + } + + return result; +} diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 6544367a2..36c7e48c6 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; +import { unsupportedAccessorInObjectLiteral, invalidMultiFunctionUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -10,6 +10,7 @@ import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; +import { findMultiAssignmentViolations } from "./language-extensions/multi"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -62,6 +63,12 @@ const transformNumericLiteralExpression: FunctionVisitor = ex }; const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } + let properties: lua.TableFieldExpression[] = []; const tableExpressions: lua.Expression[] = []; diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index c5ec3c740..c13d571ff 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -6,6 +6,7 @@ import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; +import { isMultiFunction, transformMultiReturnStatement } from "./language-extensions/multi"; function transformExpressionsInReturn( context: TransformationContext, @@ -59,6 +60,14 @@ export const transformReturnStatement: FunctionVisitor = (st insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; } + if ( + statement.expression && + ts.isCallExpression(statement.expression) && + isMultiFunction(context, statement.expression) + ) { + return transformMultiReturnStatement(context, statement); + } + let results: lua.Expression[]; if (statement.expression) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index bec7548e5..6ddd4acdc 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -10,6 +10,7 @@ import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../u import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; import { transformPropertyName } from "./literal"; +import { returnsMultiType, transformMultiVariableDeclaration } from "./language-extensions/multi"; export function transformArrayBindingElement( context: TransformationContext, @@ -229,6 +230,14 @@ export function transformVariableDeclaration( context: TransformationContext, statement: ts.VariableDeclaration ): lua.Statement[] { + if ( + statement.initializer && + ts.isCallExpression(statement.initializer) && + returnsMultiType(context, statement.initializer) + ) { + return transformMultiVariableDeclaration(context, statement); + } + if (statement.initializer && statement.type) { const initializerType = context.checker.getTypeAtLocation(statement.initializer); const varType = context.checker.getTypeFromTypeNode(statement.type); diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 628246ec9..608b42818 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -59,14 +59,22 @@ export function createVirtualProgram(input: Record, options: Com return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false); } + let filePath: string | undefined; + if (fileName.startsWith("lib.")) { - if (libCache[fileName]) return libCache[fileName]; const typeScriptDir = path.dirname(require.resolve("typescript")); - const filePath = path.join(typeScriptDir, fileName); - const content = fs.readFileSync(filePath, "utf8"); + filePath = path.join(typeScriptDir, fileName); + } - libCache[fileName] = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, false); + if (fileName.includes("language-extensions")) { + const dtsName = fileName.replace(/(\.d)?(\.ts)$/, ".d.ts"); + filePath = path.resolve(dtsName); + } + if (filePath !== undefined) { + if (libCache[fileName]) return libCache[fileName]; + const content = fs.readFileSync(filePath, "utf8"); + libCache[fileName] = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, false); return libCache[fileName]; } }, diff --git a/test/tsconfig.json b/test/tsconfig.json index de0b21bdd..2c06244c7 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -13,6 +13,7 @@ "cli/watch", "transpile/directories", "transpile/outFile", - "../src/lualib" + "../src/lualib", + "../language-extensions" ] } diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap new file mode 100644 index 000000000..587cdfd90 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -0,0 +1,135 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`; + +exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`; + +exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` +"local function ____(____, ____bindingPattern0) + if ____bindingPattern0 == nil then + ____bindingPattern0 = ____(_G, 1) + end + local a = ____bindingPattern0[1] +end" +`; + +exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; + +exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = `""`; + +exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,15): error TSTL: This array binding pattern cannot have initializers."`; + +exports[`invalid $multi call (const {} = $multi();): code 1`] = `""`; + +exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; + +exports[`invalid $multi call (const a = $multi();): code 1`] = `""`; + +exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; + +exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local _ = nil +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local ar = {1} +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +do + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in an expression that is returned."`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +do + while false do + local ____ = 1 + end +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in an expression that is returned."`; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts new file mode 100644 index 000000000..ed5353bbc --- /dev/null +++ b/test/unit/language-extensions/multi.spec.ts @@ -0,0 +1,128 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { + invalidMultiFunctionUse, + invalidMultiTypeToNonArrayBindingPattern, + invalidMultiTypeArrayBindingPatternElementInitializer, +} from "../../../src/transformation/utils/diagnostics"; + +const multiProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test("multi example use case", () => { + util.testModule` + function multiReturn(): MultiReturn<[string, number]> { + return $multi("foo", 5); + } + + const [a, b] = multiReturn(); + export { a, b }; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: "foo", b: 5 }); +}); + +test.each<[string, any]>([ + ["$multi()", undefined], + ["$multi(true)", true], + ["$multi(1, 2)", 1], +])("$multi call on return statement (%s)", (expression, result) => { + util.testFunction` + return ${expression}; + ` + .setOptions(multiProjectOptions) + .expectToEqual(result); +}); + +const multiFunction = ` +function multi(...args) { + return $multi(...args); +} +`; + +const createCasesThatCall = (name: string): Array<[string, any]> => [ + [`let a; [a] = ${name}()`, undefined], + [`const [a] = ${name}()`, undefined], + [`const [a] = ${name}(1)`, 1], + [`const ar = [1]; const [a] = ${name}(...ar)`, 1], + [`const _ = null, [a] = ${name}(1)`, 1], + [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], + [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], +]; + +test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionUse.code]); +}); + +test.each<[string, any]>(createCasesThatCall("multi"))( + "valid indirect $multi function use (%s)", + (statement, result) => { + util.testModule` + ${multiFunction} + ${statement} + export { a }; + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectToEqual(result); + } +); + +test.each<[string, number[]]>([ + ["$multi", [invalidMultiFunctionUse.code]], + ["$multi()", [invalidMultiFunctionUse.code]], + ["({ $multi });", [invalidMultiFunctionUse.code]], + ["const a = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["const {} = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]], + ["const [a = 0] = $multi()", [invalidMultiTypeArrayBindingPatternElementInitializer.code]], +])("invalid $multi call (%s)", (statement, diagnostics) => { + util.testModule` + ${statement} + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot(diagnostics); +}); + +test("function to spread multi type result from multi type function", () => { + util.testFunction` + ${multiFunction} + function m() { + return $multi(...multi(true)); + } + return m(); + ` + .setOptions(multiProjectOptions) + .expectToEqual(true); +}); + +test("$multi call with destructuring assignment side effects", () => { + util.testModule` + ${multiFunction} + let a; + export { a }; + [a] = multi(1); + ` + .setOptions(multiProjectOptions) + .setReturnExport("a") + .expectToEqual(1); +}); + +test("allow $multi call in ArrowFunction body", () => { + util.testFunction` + const call = () => $multi(1); + const [result] = call(); + return result; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); From e58da3fbe9363967def2cb65311bfa0e4e435b6d Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 27 Dec 2020 02:53:29 -0800 Subject: [PATCH 307/764] Add homepage and bugs to package.json (#956) --- package.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/package.json b/package.json index 017169255..464daf98f 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,10 @@ "version": "0.36.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "homepage": "https://typescripttolua.github.io/", + "bugs": { + "url": "https://github.com/TypeScriptToLua/TypeScriptToLua/issues" + }, "license": "MIT", "keywords": [ "typescript", From 7d1696a11f516459312adc5bc1aa841f2f65ba51 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 30 Dec 2020 20:03:32 +0100 Subject: [PATCH 308/764] 0.37.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f775485f5..7cc4c921f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 464daf98f..c10a7aecd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.36.1", + "version": "0.37.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f90f6af8bd49908fcfde4667649ddbfc1d9f7691 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 30 Dec 2020 22:40:13 +0100 Subject: [PATCH 309/764] Changelog 0.37.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64ef0e7c3..5f277e056 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.37.0 + +- **[Important]** Deprecated the @phantom, @extension, @metaExtension and @pureAbstract annotations. This is done because there are good alternatives in regular TypeScript, and this helps us simplify the transpiler. For now, using these annotations will result in a warning but they will still continue to function. A few months from now these annotations will no longer be supported, so upgrade if possible. See [Compiler Annotations](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for more info. +- Added the `MultiReturn<>` type and `$multi()` helper function as the first language extensions. This is to provide a type-safe alternative to the `@tupleReturn` annotation. For more information see [the new Language Extensions page](https://typescripttolua.github.io/docs/advanced/language-extensions) on the docs website. +- Removed some class transformation code from the transpiler that was no longer used. +- Fixed a bug causing object spread to malfunction in some cases ([#898](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/898)). +- Omitted `tostring` for parameters of template literals (`` `${}` ``) that are already known strings. +- Fixed a bug causing incorrect Lua syntax to be generated in some cases ([#944](https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944)). + ## 0.36.0 - Upgraded to TypeScript 4.0. From 3c9e369fcc80f91f2c4c38b1c13de2b6d305f604 Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Fri, 8 Jan 2021 05:29:10 +1000 Subject: [PATCH 310/764] Allow numeric access to MultiReturn (#962) --- src/transformation/utils/diagnostics.ts | 4 +++ src/transformation/visitors/access.ts | 21 ++++++++++++- .../__snapshots__/multi.spec.ts.snap | 31 +++++++++++++++++++ test/unit/language-extensions/multi.spec.ts | 20 ++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8f69eadd9..d7b7b6467 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -164,6 +164,10 @@ export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnos "This array literal pattern cannot have initializers." ); +export const invalidMultiReturnAccess = createErrorDiagnosticFactory( + "The MultiReturn type can only be accessed via an element access expression of a numeric type." +); + export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( "Omitted expressions and BindingElements are expected here." ); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index eaa5591b7..6cf61a62c 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,10 +3,12 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { invalidMultiReturnAccess } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; +import { returnsMultiType } from "./language-extensions/multi"; import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; export function transformElementAccessArgument( @@ -41,7 +43,20 @@ export const transformElementAccessExpression: FunctionVisitor = ( @@ -63,6 +78,10 @@ export const transformPropertyAccessExpression: FunctionVisitor { .setOptions(multiProjectOptions) .expectToEqual(1); }); + +test.each(["0", "i"])("allow MultiReturn numeric access", expression => { + util.testFunction` + ${multiFunction} + const i = 0; + return multi(1)[${expression}]; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); + +test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-numeric access", expression => { + util.testFunction` + ${multiFunction} + return ${expression}; + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); +}); From 6ac1980195e71264e1e4bfa97110556fb98ebcb4 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 7 Jan 2021 21:13:06 +0100 Subject: [PATCH 311/764] 0.37.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7cc4c921f..d98d38972 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index c10a7aecd..d4d39ce59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.37.0", + "version": "0.37.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 948f71bff43932aa22d8a8217db6d7c35d0262af Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Wed, 13 Jan 2021 11:29:37 -0800 Subject: [PATCH 312/764] Added optional chaining unsupported diagnostic (#966) --- src/transformation/utils/diagnostics.ts | 2 ++ src/transformation/visitors/access.ts | 6 +++++- test/unit/optionalChaining.spec.ts | 9 +++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/unit/optionalChaining.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index d7b7b6467..2c1a6793d 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -177,3 +177,5 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); + +export const optionalChainingNotSupported = createErrorDiagnosticFactory("Optional chaining is not supported yet."); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 6cf61a62c..d33c5c5c6 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { invalidMultiReturnAccess } from "../utils/diagnostics"; +import { invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; @@ -63,6 +63,10 @@ export const transformPropertyAccessExpression: FunctionVisitor { + if (ts.isOptionalChain(expression)) { + context.diagnostics.push(optionalChainingNotSupported(expression)); + } + const constEnumValue = tryGetConstEnumValue(context, expression); if (constEnumValue) { return constEnumValue; diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts new file mode 100644 index 000000000..33d0802db --- /dev/null +++ b/test/unit/optionalChaining.spec.ts @@ -0,0 +1,9 @@ +import { optionalChainingNotSupported } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test("Diagnostic optional chaining is not supported yet", () => { + util.testFunction` + let func = (value: number) => value != 0 ? {value} : undefined; + return func(1)?.value; + `.expectToHaveDiagnostics([optionalChainingNotSupported.code]); +}); From 0158732bdb597132b7b4a22cd40e7ce61ef37877 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Tue, 26 Jan 2021 13:06:02 -0700 Subject: [PATCH 313/764] Operator Mapping Library Extensions (#969) * initial setup of add operator mapping * basic add operator mappings working, including tests and invalid use checks * overload tests for operator mapping * added unary operator map for len and updated tests * added missing operator extensions * added checks for unsupported operators in pre-53 lua versions * reverting package-lock.json to correct version * tabs to spaces * fixed snapshot * addressed feedback * Update src/transformation/utils/diagnostics.ts Co-authored-by: Perry van Wesel * snapshot update Co-authored-by: Tom Co-authored-by: Perry van Wesel --- language-extensions/index.d.ts | 402 ++++++++++++++++++ src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 83 +++- src/transformation/visitors/call.ts | 5 + src/transformation/visitors/identifier.ts | 7 +- .../visitors/language-extensions/operators.ts | 177 ++++++++ .../__snapshots__/operators.spec.ts.snap | 133 ++++++ .../language-extensions/operators.spec.ts | 392 +++++++++++++++++ 8 files changed, 1200 insertions(+), 3 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/operators.ts create mode 100644 test/unit/language-extensions/__snapshots__/operators.spec.ts.snap create mode 100644 test/unit/language-extensions/operators.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index d7270be32..87a7f1395 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,2 +1,404 @@ declare function $multi(...values: T): MultiReturn; declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; + +/** + * Calls to functions with this type are translated to `left + right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaAdditionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & { + readonly __luaAdditionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left - right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaSubtractionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & { + readonly __luaSubtractionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left * right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaMultiplicationBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & { + readonly __luaMultiplicationMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left / right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaDivisionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & { + readonly __luaDivisionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left % right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaModuloBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaModuloMethod = ((right: TRight) => TReturn) & { + readonly __luaModuloMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left ^ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaPowerBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaPowerMethod = ((right: TRight) => TReturn) & { + readonly __luaPowerMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left // right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaFloorDivisionBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & { + readonly __luaFloorDivisionMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left & right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseAndBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseAndMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left | right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseOrBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseOrMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left ~ right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseExclusiveOrBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseExclusiveOrMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left << right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseLeftShiftBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseLeftShiftMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left >> right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaBitwiseRightShiftBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & { + readonly __luaBitwiseRightShiftMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left .. right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaConcatBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaConcatMethod = ((right: TRight) => TReturn) & { + readonly __luaConcatMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left < right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaLessThanBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & { + readonly __luaLessThanMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `left > right`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TLeft The type of the left-hand-side of the operation. + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & { + readonly __luaGreaterThanBrand: unique symbol; +}; + +/** + * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TRight The type of the right-hand-side of the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & { + readonly __luaGreaterThanMethodBrand: unique symbol; +}; + +/** + * Calls to functions with this type are translated to `-operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegation = ((operand: TOperand) => TReturn) & { + readonly __luaNegationBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNegationMethodBrand: unique symbol }; + +/** + * Calls to functions with this type are translated to `~operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & { + readonly __luaBitwiseNotBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBitwiseNotMethodBrand: unique symbol }; + +/** + * Calls to functions with this type are translated to `#operand`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TOperand The type of the value in the operation. + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLength = ((operand: TOperand) => TReturn) & { + readonly __luaLengthBrand: unique symbol; +}; + +/** + * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TReturn The resulting (return) type of the operation. + */ +declare type LuaLengthMethod = (() => TReturn) & { readonly __luaLengthMethodBrand: unique symbol }; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 2c1a6793d..8cd721421 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -172,6 +172,10 @@ export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( "Omitted expressions and BindingElements are expected here." ); +export const invalidOperatorMappingUse = createErrorDiagnosticFactory( + "This function must always be directly called and cannot be referred to." +); + export const annotationDeprecated = createWarningDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 8f3b07672..6838d6b55 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -4,8 +4,84 @@ import * as path from "path"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", + AdditionOperatorType = "AdditionOperatorType", + AdditionOperatorMethodType = "AdditionOperatorMethodType", + SubtractionOperatorType = "SubtractionOperatorType", + SubtractionOperatorMethodType = "SubtractionOperatorMethodType", + MultiplicationOperatorType = "MultiplicationOperatorType", + MultiplicationOperatorMethodType = "MultiplicationOperatorMethodType", + DivisionOperatorType = "DivisionOperatorType", + DivisionOperatorMethodType = "DivisionOperatorMethodType", + ModuloOperatorType = "ModuloOperatorType", + ModuloOperatorMethodType = "ModuloOperatorMethodType", + PowerOperatorType = "PowerOperatorType", + PowerOperatorMethodType = "PowerOperatorMethodType", + FloorDivisionOperatorType = "FloorDivisionOperatorType", + FloorDivisionOperatorMethodType = "FloorDivisionOperatorMethodType", + BitwiseAndOperatorType = "BitwiseAndOperatorType", + BitwiseAndOperatorMethodType = "BitwiseAndOperatorMethodType", + BitwiseOrOperatorType = "BitwiseOrOperatorType", + BitwiseOrOperatorMethodType = "BitwiseOrOperatorMethodType", + BitwiseExclusiveOrOperatorType = "BitwiseExclusiveOrOperatorType", + BitwiseExclusiveOrOperatorMethodType = "BitwiseExclusiveOrOperatorMethodType", + BitwiseLeftShiftOperatorType = "BitwiseLeftShiftOperatorType", + BitwiseLeftShiftOperatorMethodType = "BitwiseLeftShiftOperatorMethodType", + BitwiseRightShiftOperatorType = "BitwiseRightShiftOperatorType", + BitwiseRightShiftOperatorMethodType = "BitwiseRightShiftOperatorMethodType", + ConcatOperatorType = "ConcatOperatorType", + ConcatOperatorMethodType = "ConcatOperatorMethodType", + LessThanOperatorType = "LessThanOperatorType", + LessThanOperatorMethodType = "LessThanOperatorMethodType", + GreaterThanOperatorType = "GreaterThanOperatorType", + GreaterThanOperatorMethodType = "GreaterThanOperatorMethodType", + NegationOperatorType = "NegationOperatorType", + NegationOperatorMethodType = "NegationOperatorMethodType", + BitwiseNotOperatorType = "BitwiseNotOperatorType", + BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", + LengthOperatorType = "LengthOperatorType", + LengthOperatorMethodType = "LengthOperatorMethodType", } +const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { + MultiReturn: ExtensionKind.MultiType, + LuaAddition: ExtensionKind.AdditionOperatorType, + LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, + LuaSubtraction: ExtensionKind.SubtractionOperatorType, + LuaSubtractionMethod: ExtensionKind.SubtractionOperatorMethodType, + LuaMultiplication: ExtensionKind.MultiplicationOperatorType, + LuaMultiplicationMethod: ExtensionKind.MultiplicationOperatorMethodType, + LuaDivision: ExtensionKind.DivisionOperatorType, + LuaDivisionMethod: ExtensionKind.DivisionOperatorMethodType, + LuaModulo: ExtensionKind.ModuloOperatorType, + LuaModuloMethod: ExtensionKind.ModuloOperatorMethodType, + LuaPower: ExtensionKind.PowerOperatorType, + LuaPowerMethod: ExtensionKind.PowerOperatorMethodType, + LuaFloorDivision: ExtensionKind.FloorDivisionOperatorType, + LuaFloorDivisionMethod: ExtensionKind.FloorDivisionOperatorMethodType, + LuaBitwiseAnd: ExtensionKind.BitwiseAndOperatorType, + LuaBitwiseAndMethod: ExtensionKind.BitwiseAndOperatorMethodType, + LuaBitwiseOr: ExtensionKind.BitwiseOrOperatorType, + LuaBitwiseOrMethod: ExtensionKind.BitwiseOrOperatorMethodType, + LuaBitwiseExclusiveOr: ExtensionKind.BitwiseExclusiveOrOperatorType, + LuaBitwiseExclusiveOrMethod: ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + LuaBitwiseLeftShift: ExtensionKind.BitwiseLeftShiftOperatorType, + LuaBitwiseLeftShiftMethod: ExtensionKind.BitwiseLeftShiftOperatorMethodType, + LuaBitwiseRightShift: ExtensionKind.BitwiseRightShiftOperatorType, + LuaBitwiseRightShiftMethod: ExtensionKind.BitwiseRightShiftOperatorMethodType, + LuaConcat: ExtensionKind.ConcatOperatorType, + LuaConcatMethod: ExtensionKind.ConcatOperatorMethodType, + LuaLessThan: ExtensionKind.LessThanOperatorType, + LuaLessThanMethod: ExtensionKind.LessThanOperatorMethodType, + LuaGreaterThan: ExtensionKind.GreaterThanOperatorType, + LuaGreaterThanMethod: ExtensionKind.GreaterThanOperatorMethodType, + LuaNegation: ExtensionKind.NegationOperatorType, + LuaNegationMethod: ExtensionKind.NegationOperatorMethodType, + LuaBitwiseNot: ExtensionKind.BitwiseNotOperatorType, + LuaBitwiseNotMethod: ExtensionKind.BitwiseNotOperatorMethodType, + LuaLength: ExtensionKind.LengthOperatorType, + LuaLengthMethod: ExtensionKind.LengthOperatorMethodType, +}; + function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); @@ -19,8 +95,11 @@ export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | u return ExtensionKind.MultiFunction; } - if (ts.isTypeAliasDeclaration(declaration) && declaration.name.text === "MultiReturn") { - return ExtensionKind.MultiType; + if (ts.isTypeAliasDeclaration(declaration)) { + const extensionKind = typeNameToExtensionKind[declaration.name.text]; + if (extensionKind) { + return extensionKind; + } } throw new Error("Unknown extension kind"); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 90959a580..20583d007 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -12,6 +12,7 @@ import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignmen import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; import { returnsMultiType } from "./language-extensions/multi"; +import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -208,6 +209,10 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResult ? wrapInTable(builtinResult) : builtinResult; } + if (isOperatorMapping(context, node)) { + return transformOperatorMappingExpression(context, node); + } + if (ts.isPropertyAccessExpression(node.expression)) { const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 6e95411a5..dd69699b3 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,12 +3,13 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall, invalidMultiFunctionUse } from "../utils/diagnostics"; +import { invalidForRangeCall, invalidMultiFunctionUse, invalidOperatorMappingUse } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; import { isMultiFunctionNode } from "./language-extensions/multi"; +import { isOperatorMapping } from "./language-extensions/operators"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -16,6 +17,10 @@ export function transformIdentifier(context: TransformationContext, identifier: return lua.createAnonymousIdentifier(identifier); } + if (isOperatorMapping(context, identifier)) { + context.diagnostics.push(invalidOperatorMappingUse(identifier)); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts new file mode 100644 index 000000000..b217a26e8 --- /dev/null +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -0,0 +1,177 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { assert } from "../../../utils"; +import { findFirstNodeAbove } from "../../utils/typescript"; +import { LuaTarget } from "../../../CompilerOptions"; +import { unsupportedForTarget } from "../../utils/diagnostics"; + +const binaryOperatorMappings = new Map([ + [extensions.ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.AdditionOperatorMethodType, lua.SyntaxKind.AdditionOperator], + [extensions.ExtensionKind.SubtractionOperatorType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.SubtractionOperatorMethodType, lua.SyntaxKind.SubtractionOperator], + [extensions.ExtensionKind.MultiplicationOperatorType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.MultiplicationOperatorMethodType, lua.SyntaxKind.MultiplicationOperator], + [extensions.ExtensionKind.DivisionOperatorType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.DivisionOperatorMethodType, lua.SyntaxKind.DivisionOperator], + [extensions.ExtensionKind.ModuloOperatorType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.ModuloOperatorMethodType, lua.SyntaxKind.ModuloOperator], + [extensions.ExtensionKind.PowerOperatorType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.PowerOperatorMethodType, lua.SyntaxKind.PowerOperator], + [extensions.ExtensionKind.FloorDivisionOperatorType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.FloorDivisionOperatorMethodType, lua.SyntaxKind.FloorDivisionOperator], + [extensions.ExtensionKind.BitwiseAndOperatorType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseAndOperatorMethodType, lua.SyntaxKind.BitwiseAndOperator], + [extensions.ExtensionKind.BitwiseOrOperatorType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseOrOperatorMethodType, lua.SyntaxKind.BitwiseOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, lua.SyntaxKind.BitwiseRightShiftOperator], + [extensions.ExtensionKind.ConcatOperatorType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.ConcatOperatorMethodType, lua.SyntaxKind.ConcatOperator], + [extensions.ExtensionKind.LessThanOperatorType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.LessThanOperatorMethodType, lua.SyntaxKind.LessThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorType, lua.SyntaxKind.GreaterThanOperator], + [extensions.ExtensionKind.GreaterThanOperatorMethodType, lua.SyntaxKind.GreaterThanOperator], +]); + +const unaryOperatorMappings = new Map([ + [extensions.ExtensionKind.NegationOperatorType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.NegationOperatorMethodType, lua.SyntaxKind.NegationOperator], + [extensions.ExtensionKind.BitwiseNotOperatorType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.BitwiseNotOperatorMethodType, lua.SyntaxKind.BitwiseNotOperator], + [extensions.ExtensionKind.LengthOperatorType, lua.SyntaxKind.LengthOperator], + [extensions.ExtensionKind.LengthOperatorMethodType, lua.SyntaxKind.LengthOperator], +]); + +const operatorMapExtensions = new Set([ + ...binaryOperatorMappings.keys(), + ...unaryOperatorMappings.keys(), +]); + +const bitwiseOperatorMapExtensions = new Set([ + extensions.ExtensionKind.BitwiseAndOperatorType, + extensions.ExtensionKind.BitwiseAndOperatorMethodType, + extensions.ExtensionKind.BitwiseOrOperatorType, + extensions.ExtensionKind.BitwiseOrOperatorMethodType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, + extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorType, + extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseRightShiftOperatorType, + extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, + extensions.ExtensionKind.BitwiseNotOperatorType, + extensions.ExtensionKind.BitwiseNotOperatorMethodType, +]); + +function getTypeDeclaration(declaration: ts.Declaration) { + return ts.isTypeAliasDeclaration(declaration) + ? declaration + : findFirstNodeAbove(declaration, ts.isTypeAliasDeclaration); +} + +function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { + const signature = context.checker.getResolvedSignature(node); + if (!signature || !signature.declaration) { + return; + } + const typeDeclaration = getTypeDeclaration(signature.declaration); + if (!typeDeclaration) { + return; + } + const mapping = extensions.getExtensionKind(typeDeclaration); + if (mapping !== undefined && operatorMapExtensions.has(mapping)) { + return mapping; + } +} + +function isOperatorMapDeclaration(declaration: ts.Declaration) { + const typeDeclaration = getTypeDeclaration(declaration); + if (typeDeclaration) { + const extensionKind = extensions.getExtensionKind(typeDeclaration); + return extensionKind !== undefined ? operatorMapExtensions.has(extensionKind) : false; + } +} + +function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { + if (type.isUnionOrIntersection()) { + return type.types.some(t => isOperatorMapType(context, t)); + } else { + return type.symbol?.declarations?.some(isOperatorMapDeclaration); + } +} + +function isOperatorMapIdentifier(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return isOperatorMapType(context, type); +} + +export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { + if (ts.isCallExpression(node)) { + return getOperatorMapExtensionKindForCall(context, node) !== undefined; + } else { + return isOperatorMapIdentifier(context, node); + } +} + +export function transformOperatorMappingExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression { + const extensionKind = getOperatorMapExtensionKindForCall(context, node); + assert(extensionKind); + + const isBefore53 = + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Lua52 || + context.luaTarget === LuaTarget.LuaJIT || + context.luaTarget === LuaTarget.Universal; + if (isBefore53) { + const luaTarget = context.luaTarget === LuaTarget.Universal ? LuaTarget.Lua51 : context.luaTarget; + if (bitwiseOperatorMapExtensions.has(extensionKind)) { + context.diagnostics.push(unsupportedForTarget(node, "Native bitwise operations", luaTarget)); + } else if ( + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorType || + extensionKind === extensions.ExtensionKind.FloorDivisionOperatorMethodType + ) { + context.diagnostics.push(unsupportedForTarget(node, "Floor division operator", luaTarget)); + } + } + + const args = node.arguments.slice(); + if (binaryOperatorMappings.has(extensionKind)) { + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + const luaOperator = binaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createBinaryExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + luaOperator + ); + } else { + let arg: ts.Expression; + if ( + args.length === 0 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + arg = node.expression.expression; + } else { + arg = args[0]; + } + + const luaOperator = unaryOperatorMappings.get(extensionKind); + assert(luaOperator); + return lua.createUnaryExpression(context.transformExpression(arg), luaOperator); + } +} diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap new file mode 100644 index 000000000..cfeef91c8 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -0,0 +1,133 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): code 1`] = `"foo = op(_G, 1, 2)"`; + +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = [op];): code 1`] = `"foo = {op}"`; + +exports[`operator mapping - invalid use (const foo = [op];): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): code 1`] = `"foo = tostring(op)"`; + +exports[`operator mapping - invalid use (const foo = \`\${op}\`): diagnostics 1`] = `"main.ts(3,24): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): code 1`] = `"foo = op"`; + +exports[`operator mapping - invalid use (const foo: unknown = op;): diagnostics 1`] = `"main.ts(3,30): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): code 1`] = `"foo(_G, op)"`; + +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must always be directly called and cannot be referred to."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.1 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.1 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.2 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.2 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.2."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (JIT LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (JIT LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target LuaJIT."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (universal LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (universal LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.2 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.2."`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (JIT LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target LuaJIT."`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (universal LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts new file mode 100644 index 000000000..4559ff7e6 --- /dev/null +++ b/test/unit/language-extensions/operators.spec.ts @@ -0,0 +1,392 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidOperatorMappingUse } from "../../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../../src"; +import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; + +const operatorsProjectOptions: tstl.CompilerOptions = { + luaTarget: LuaTarget.Lua53, + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +const operatorMapTestObject = ` + class OpTest { + public value: number; + public constructor(value: number) { this.value = value; } + + public __add(other: OpTest): OpTest; + public __add(other: number): number; + public __add(other: OpTest | number) { + if (typeof other === "number") { + return this.value + other; + } else { + return new OpTest(this.value + other.value); + } + } + public __sub(other: OpTest) { return new OpTest(this.value - other.value); } + public __mul(other: OpTest) { return new OpTest(this.value * other.value); } + public __div(other: OpTest) { return new OpTest(this.value / other.value); } + public __mod(other: OpTest) { return new OpTest(this.value % other.value); } + public __pow(other: OpTest) { return new OpTest(this.value ** other.value); } + public __idiv(other: OpTest) { return new OpTest(Math.floor(this.value / other.value)); } + public __band(other: OpTest) { return new OpTest(this.value & other.value); } + public __bor(other: OpTest) { return new OpTest(this.value | other.value); } + public __bxor(other: OpTest) { return new OpTest(this.value ^ other.value); } + public __shl(other: OpTest) { return new OpTest(this.value << other.value); } + public __shr(other: OpTest) { return new OpTest(this.value >>> other.value); } + + public __lt(other: OpTest) { return this.value < other.value; } + public __gt(other: OpTest) { return this.value > other.value; } + + public __concat(other: OpTest) { return this.value.toString() + other.value.toString(); } + + public __unm() { return -this.value; } + public __bnot() { return ~this.value; } + public __len() { return this.value; } + } +`; + +const binaryMathOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: number }> = [ + { opType: "LuaAddition", left: 7, right: 4, expectResult: 11 }, + { opType: "LuaSubtraction", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaMultiplication", left: 7, right: 4, expectResult: 28 }, + { opType: "LuaDivision", left: 7, right: 4, expectResult: 1.75 }, + { opType: "LuaModulo", left: 7, right: 4, expectResult: 3 }, + { opType: "LuaPower", left: 7, right: 4, expectResult: 2401 }, + { opType: "LuaFloorDivision", left: 7, right: 4, expectResult: 1 }, + { opType: "LuaBitwiseAnd", left: 6, right: 5, expectResult: 4 }, + { opType: "LuaBitwiseOr", left: 6, right: 5, expectResult: 7 }, + { opType: "LuaBitwiseExclusiveOr", left: 6, right: 5, expectResult: 3 }, + { opType: "LuaBitwiseLeftShift", left: 7, right: 2, expectResult: 28 }, + { opType: "LuaBitwiseRightShift", left: 7, right: 2, expectResult: 1 }, +]; + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(binaryMathOperatorTests)( + "binary math operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right).value; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +const luaTargetsPre53 = [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; + +const operatorTypesPost53 = [ + "LuaFloorDivision", + "LuaBitwiseAnd", + "LuaBitwiseOr", + "LuaBitwiseExclusiveOr", + "LuaBitwiseLeftShift", + "LuaBitwiseRightShift", +]; + +test.each(luaTargetsPre53.flatMap(target => operatorTypesPost53.map(opType => [target, opType] as const)))( + "unsupported binary operator mapping (%s %s)", + (luaTarget, opType) => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: ${opType}; + declare const left: OpTest; + declare const right: OpTest; + op(left, right); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + } +); + +const comparisonOperatorTests: Array<{ opType: string; left: number; right: number; expectResult: boolean }> = [ + { opType: "LuaLessThan", left: 7, right: 4, expectResult: false }, + { opType: "LuaLessThan", left: 4, right: 7, expectResult: true }, + { opType: "LuaGreaterThan", left: 7, right: 4, expectResult: true }, + { opType: "LuaGreaterThan", left: 4, right: 7, expectResult: false }, +]; + +test.each(comparisonOperatorTests)( + "comparison operator mapping - global function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - static function (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test.each(comparisonOperatorTests)( + "comparison operator mapping - method (%s)", + ({ opType, left, right, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const left = new OpTest(${left}); + const right = new OpTest(${right}); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); + } +); + +test("concat operator mapping - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaConcat; + const left = new OpTest(7); + const right = new OpTest(4); + export const result = op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaConcat; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = OpTest.op(left, right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +test("concat operator mapping - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaConcatMethod; + } + const left = new OpTest(7); + const right = new OpTest(4); + export const result = left.op(right); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual("74"); +}); + +const unaryOperatorTests: Array<{ opType: string; operand: number; expectResult: number }> = [ + { opType: "LuaNegation", operand: 13, expectResult: -13 }, + { opType: "LuaBitwiseNot", operand: 13, expectResult: -14 }, + { opType: "LuaLength", operand: 13, expectResult: 13 }, +]; + +test.each(unaryOperatorTests)("unary operator mapping - global function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare const op: ${opType}; + const operand = new OpTest(${operand}); + export const result = op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - static function (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: ${opType}; + } + const operand = new OpTest(${operand}); + export const result = OpTest.op(operand); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(unaryOperatorTests)("unary operator mapping - method (%s)", ({ opType, operand, expectResult }) => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: ${opType}Method; + } + const operand = new OpTest(${operand}); + export const result = operand.op(); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(expectResult); +}); + +test.each(luaTargetsPre53)("unsupported unary operator mapping (%s LuaBitwiseNot)", luaTarget => { + util.testModule` + declare interface OpTest { value: number; } + declare const op: LuaBitwiseNot; + declare const operand: OpTest; + op(operand); + ` + .setOptions({ ...operatorsProjectOptions, luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +test("operator mapping overload - global function", () => { + util.testModule` + ${operatorMapTestObject} + declare const op: LuaAddition & LuaAddition; + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = op(left, right).value; + const resultB = op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - static function", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const op: LuaAddition & LuaAddition; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = OpTest.op(left, right).value; + const resultB = OpTest.op(left, 13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping overload - method", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + op: LuaAdditionMethod & LuaAdditionMethod; + } + const left = new OpTest(4); + const right = new OpTest(7); + const resultA = left.op(right).value; + const resultB = left.op(13); + export const result = {resultA, resultB}; + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual({ resultA: 11, resultB: 17 }); +}); + +test("operator mapping - method element call", () => { + util.testModule` + ${operatorMapTestObject} + declare interface OpTest { + add: LuaAdditionMethod; + } + const left = new OpTest(7); + export const result = left["add"](4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test("operator mapping - function element call", () => { + util.testModule` + ${operatorMapTestObject} + declare namespace OpTest { + export const add: LuaAddition; + } + const left = new OpTest(7); + export const result = OpTest["add"](left, 4); + ` + .setOptions(operatorsProjectOptions) + .setReturnExport("result") + .expectToEqual(11); +}); + +test.each([ + "const foo: unknown = op;", + "const foo = `${op}`", + "declare function foo(op: LuaAddition): void; foo(op);", + "const foo = (op as any)(1, 2);", + "const foo = [op];", +])("operator mapping - invalid use (%s)", invalidCode => { + util.testModule` + declare const op: LuaAddition; + ${invalidCode} + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidOperatorMappingUse.code]); +}); From 39c7420a28d4c5fbb527d2c526656d16c37a9d69 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Jan 2021 21:13:15 +0100 Subject: [PATCH 314/764] Feature/arrayisarray (#970) * Added Array.IsArray to lualib * Fix bug in string.split lualib dependencies * Fix isArray test for empty object actually testing an object * Used Array.isArray in array.prototype.concat --- src/LuaLib.ts | 7 +++++-- src/lualib/ArrayConcat.ts | 5 ++--- src/lualib/ArrayFlat.ts | 8 +------- src/lualib/ArrayFlatMap.ts | 7 +------ src/lualib/ArrayIsArray.ts | 5 +++++ src/transformation/builtins/array.ts | 17 +++++++++++++++++ src/transformation/builtins/index.ts | 4 +++- test/unit/builtins/array.spec.ts | 20 ++++++++++++++++++++ test/unit/builtins/string.spec.ts | 7 +++++++ test/unit/spread.spec.ts | 2 +- 10 files changed, 62 insertions(+), 20 deletions(-) create mode 100644 src/lualib/ArrayIsArray.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index fde43c604..8a3fee340 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -10,6 +10,7 @@ export enum LuaLibFeature { ArrayFindIndex = "ArrayFindIndex", ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", + ArrayIsArray = "ArrayIsArray", ArrayJoin = "ArrayJoin", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", @@ -86,8 +87,9 @@ export enum LuaLibFeature { } const luaLibDependencies: Partial> = { - ArrayFlat: [LuaLibFeature.ArrayConcat], - ArrayFlatMap: [LuaLibFeature.ArrayConcat], + ArrayConcat: [LuaLibFeature.ArrayIsArray], + ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], + ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], Decorate: [LuaLibFeature.CloneDescriptor], Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], Error: [LuaLibFeature.New, LuaLibFeature.Class], @@ -102,6 +104,7 @@ const luaLibDependencies: Partial> = { WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], + StringSplit: [LuaLibFeature.StringSubstring], SymbolRegistry: [LuaLibFeature.Symbol], }; diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index a133bb97a..30da83514 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -4,9 +4,8 @@ function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { out[out.length] = val; } for (const arg of args) { - // Hack because we don't have an isArray function - if (pcall(() => (arg as any[]).length) && type(arg) !== "string") { - const argAsArray = arg as any[]; + if (Array.isArray(arg)) { + const argAsArray = arg; for (const val of argAsArray) { out[out.length] = val; } diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index 54120e69a..2bed314cb 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,13 +1,7 @@ function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { let result: any[] = []; for (const value of array) { - if ( - depth > 0 && - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined) - ) { + if (depth > 0 && Array.isArray(value)) { result = result.concat(__TS__ArrayFlat(value, depth - 1)); } else { result[result.length] = value; diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 02d58329b..c31af9046 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -6,12 +6,7 @@ function __TS__ArrayFlatMap( let result: U[] = []; for (let i = 0; i < array.length; i++) { const value = callback(array[i], i, array); - if ( - type(value) === "table" && - // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - (1 in value || (next as NextEmptyCheck)(value as any, undefined) === undefined) - ) { + if (type(value) === "table" && Array.isArray(value)) { result = result.concat(value); } else { result[result.length] = value as U; diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts new file mode 100644 index 000000000..38a4525ef --- /dev/null +++ b/src/lualib/ArrayIsArray.ts @@ -0,0 +1,5 @@ +function __TS__ArrayIsArray(this: void, value: any): value is any[] { + // Workaround to determine if value is an array or not (fails in case of objects without keys) + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/7 + return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 35be01a00..a04e0e98b 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -6,6 +6,23 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments } from "../visitors/call"; import { isStringType, isNumberType } from "../utils/typescript"; +export function transformArrayConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "isArray": + return transformLuaLibFunction(context, LuaLibFeature.ArrayIsArray, node, ...params); + default: + context.diagnostics.push(unsupportedProperty(expression.name, "Array", expressionName)); + } +} + export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 1125e96b2..6d7f0bd8b 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -15,7 +15,7 @@ import { } from "../utils/typescript"; import { PropertyCallExpression } from "../visitors/call"; import { checkForLuaLibType } from "../visitors/class/new"; -import { transformArrayProperty, transformArrayPrototypeCall } from "./array"; +import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { transformGlobalCall } from "./global"; @@ -79,6 +79,8 @@ export function transformBuiltinCallExpression( if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); switch (symbol?.name) { + case "ArrayConstructor": + return transformArrayConstructorCall(context, node); case "Console": return transformConsoleCall(context, node); case "Math": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index ecaaaca53..2cabbac29 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -618,3 +618,23 @@ test.each(genericChecks)("array constrained generic length (%p)", signature => { `; expect(util.transpileAndExecute(code)).toBe(3); }); + +test.each(["[]", '"hello"', "42", "[1, 2, 3]", '{ a: "foo", b: "bar" }'])( + "Array.isArray matches JavaScript (%p)", + valueString => { + util.testExpression`Array.isArray(${valueString})`.expectToMatchJsResult(); + } +); + +test("Array.isArray returns true for empty objects", () => { + // Important edge case we cannot handle correctly due to [] and {} + // being identical in Lua. We assume [] is more common than Array.isArray({}), + // so it is more important to handle [] right, sacrificing the result for {}. + // See discussion: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 + util.testExpression`Array.isArray({})`.expectToEqual(true); +}); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/738 +test("array.prototype.concat issue #738", () => { + util.testExpression`([] as any[]).concat(13, 323, {x: 3}, [2, 3])`.expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 00f5c878d..37dadeedc 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -1,3 +1,4 @@ +import { LuaLibImportKind } from "../../../src"; import * as util from "../../util"; test("Supported lua string function", () => { @@ -193,6 +194,12 @@ test.each([ util.testExpressionTemplate`${inp}.split(${separator})`.expectToMatchJsResult(); }); +test("string.split inline", () => { + util.testExpression`"a, b, c".split(",")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index b3b7c95a0..3384b60fb 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -93,7 +93,7 @@ describe("in array literal", () => { test("of array literal /w OmittedExpression", () => { util.testFunction` - const array = [1, 2, ...[3], , 5]; + const array = [1, 2, ...[3], 5, , 6]; return { a: array[0], b: array[1], c: array[2], d: array[3] }; `.expectToMatchJsResult(); }); From a67b61a30a46b1e94528a8af4c34a85d00cc99b4 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 28 Jan 2021 12:21:45 -0800 Subject: [PATCH 315/764] Added string.includes (#971) --- src/LuaLib.ts | 1 + src/lualib/StringIncludes.ts | 9 +++++++++ src/lualib/declarations/string.d.ts | 6 ++++++ src/transformation/builtins/string.ts | 2 ++ test/unit/builtins/string.spec.ts | 14 ++++++++++++++ 5 files changed, 32 insertions(+) create mode 100644 src/lualib/StringIncludes.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 8a3fee340..7168d0067 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -69,6 +69,7 @@ export enum LuaLibFeature { StringCharCodeAt = "StringCharCodeAt", StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", + StringIncludes = "StringIncludes", StringPadEnd = "StringPadEnd", StringPadStart = "StringPadStart", StringReplace = "StringReplace", diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts new file mode 100644 index 000000000..cba5bf15f --- /dev/null +++ b/src/lualib/StringIncludes.ts @@ -0,0 +1,9 @@ +function __TS__StringIncludes(this: string, searchString: string, position?: number): boolean { + // http://lua-users.org/wiki/StringLibraryTutorial + if (!position) { + position = 1; + } else { + position += 1; + } + return string.find(this, searchString, position, true) !== undefined; +} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 2857690cb..778257d7f 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -14,4 +14,10 @@ declare namespace string { function sub(s: string, i: number, j?: number): string; function format(formatstring: string, ...args: any[]): string; function match(string: string, pattern: string): string; + function find( + string: string, + pattern: string, + start?: number, + plainflag?: boolean + ): MultiReturn<[number, number]> | undefined; } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 65a76d28b..4cb21ea93 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -129,6 +129,8 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringStartsWith, node, caller, ...params); case "endsWith": return transformLuaLibFunction(context, LuaLibFeature.StringEndsWith, node, caller, ...params); + case "includes": + return transformLuaLibFunction(context, LuaLibFeature.StringIncludes, node, caller, ...params); case "repeat": const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 37dadeedc..3a1cbe772 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -240,6 +240,7 @@ test.each([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["hello"] }, + { inp: "HELLO test", args: ["hello"] }, { inp: "hello test", args: ["test"] }, { inp: "hello test", args: ["test", 6] }, ])("string.startsWith (%p)", ({ inp, args }) => { @@ -249,12 +250,25 @@ test.each<{ inp: string; args: Parameters }>([ test.each<{ inp: string; args: Parameters }>([ { inp: "hello test", args: [""] }, { inp: "hello test", args: ["test"] }, + { inp: "hello TEST", args: ["test"] }, { inp: "hello test", args: ["hello"] }, { inp: "hello test", args: ["hello", 5] }, ])("string.endsWith (%p)", ({ inp, args }) => { util.testExpression`"${inp}".endsWith(${util.formatCode(...args)})`.expectToMatchJsResult(); }); +test.each<{ inp: string; args: Parameters }>([ + { inp: "hello test", args: [""] }, + { inp: "hello test", args: ["test"] }, + { inp: "HELLO TEST", args: ["test"] }, + { inp: "hello test", args: ["hello"] }, + { inp: "HELLO TEST", args: ["hello"] }, + { inp: "hello test", args: ["hello", 5] }, + { inp: "hello test", args: ["test", 6] }, +])("string.includes (%p)", ({ inp, args }) => { + util.testExpression`"${inp}".includes(${util.formatCode(...args)})`.expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", count: 0 }, { inp: "hello test", count: 1 }, From 8578376ce2c48a90c3ca01d4079f1acdd7b3dd67 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sat, 6 Feb 2021 07:24:47 -0800 Subject: [PATCH 316/764] Remove legacy test utils (#957) * Delete legacy-utils.ts * Updated some test suites to use new testbuilder * Added module capabilities to testbuilder * Fixed more test cases * Updated remaining test cases that used legacy utils * Fixed unused variable * Fix prettier * Fixed remaining tests Fixed function assignment test according to discord discussion (https://discord.com/channels/515854149821267971/600291243523702805/800403280512417792) Fixed hoisting by hardcoding the expected value, because the current TestBuilder.executeJS() setup does not handle module hoisting * Addressed review comments * Addressed 2nd review --- test/json.lua | 6 +- test/legacy-utils.ts | 168 ------- test/transpile/bundle.spec.ts | 3 +- .../__snapshots__/expressions.spec.ts.snap | 12 + .../__snapshots__/identifiers.spec.ts.snap | 8 + .../annotations/customConstructor.spec.ts | 9 +- test/unit/annotations/luaIterator.spec.ts | 54 +-- test/unit/annotations/luaTable.spec.ts | 52 +- test/unit/annotations/metaExtension.spec.ts | 17 +- test/unit/annotations/tupleReturn.spec.ts | 24 +- test/unit/assignments.spec.ts | 3 +- test/unit/builtins/array.spec.ts | 38 +- test/unit/builtins/map.spec.ts | 123 +++-- test/unit/builtins/string.spec.ts | 19 +- test/unit/builtins/weakMap.spec.ts | 66 +-- test/unit/builtins/weakSet.spec.ts | 41 +- test/unit/error.spec.ts | 70 ++- test/unit/expressions.spec.ts | 14 +- test/unit/functions/functions.spec.ts | 14 +- .../invalidFunctionAssignments.spec.ts.snap | 10 +- .../functionExpressionTypeInference.spec.ts | 82 ++-- .../validation/functionPermutations.ts | 2 +- .../validFunctionAssignments.spec.ts | 196 ++++---- test/unit/hoisting.spec.ts | 157 +++--- test/unit/identifiers.spec.ts | 456 ++++++++---------- test/unit/loops.spec.ts | 66 ++- test/unit/modules/modules.spec.ts | 171 +++---- test/unit/namespaces.spec.ts | 15 +- test/unit/overloads.spec.ts | 60 +-- test/unit/printer/deadCodeAfterReturn.spec.ts | 24 +- test/unit/printer/parenthesis.spec.ts | 13 +- test/util.ts | 232 ++++++--- 32 files changed, 991 insertions(+), 1234 deletions(-) delete mode 100644 test/legacy-utils.ts diff --git a/test/json.lua b/test/json.lua index e41c3798a..cd345c9b4 100644 --- a/test/json.lua +++ b/test/json.lua @@ -142,8 +142,4 @@ encode = function(val, stack) error("unexpected type '" .. t .. "'") end - --- TODO: Since it supports NaN and Infinity it is considered a superset of JSON, so it probably should be renamed -function JSONStringify(val) - return ( encode(val) ) -end +return {stringify = function(val) return ( encode(val) ) end} \ No newline at end of file diff --git a/test/legacy-utils.ts b/test/legacy-utils.ts deleted file mode 100644 index 534c5849a..000000000 --- a/test/legacy-utils.ts +++ /dev/null @@ -1,168 +0,0 @@ -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; -import * as fs from "fs"; -import * as path from "path"; -import * as ts from "typescript"; -import * as tstl from "../src"; -import { formatPathToLuaPath } from "../src/utils"; - -export function transpileString( - str: string | { [filename: string]: string }, - options: tstl.CompilerOptions = {}, - ignoreDiagnostics = true -): string { - const { diagnostics, file } = transpileStringResult(str, options); - expect(file.lua).toBeDefined(); - - const errors = diagnostics.filter( - d => (!ignoreDiagnostics || d.source === "typescript-to-lua") && d.category === ts.DiagnosticCategory.Error - ); - expect(errors).not.toHaveDiagnostics(); - - return file.lua!.trim(); -} - -function transpileStringsAsProject(input: Record, options: tstl.CompilerOptions = {}) { - return tstl.transpileVirtualProject(input, { - luaTarget: tstl.LuaTarget.Lua53, - noHeader: true, - skipLibCheck: true, - target: ts.ScriptTarget.ESNext, - lib: ["lib.esnext.d.ts"], - experimentalDecorators: true, - ...options, - }); -} - -function transpileStringResult( - input: string | Record, - options: tstl.CompilerOptions = {} -): Required { - const { diagnostics, transpiledFiles } = transpileStringsAsProject( - typeof input === "string" ? { "main.ts": input } : input, - options - ); - - const file = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => /\bmain\.[a-z]+$/.test(f.fileName))); - if (file === undefined) { - throw new Error('Program should have a file named "main"'); - } - - return { diagnostics, file }; -} - -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8") + "\n"; -export function executeLua(luaStr: string, withLib = true): any { - luaStr = luaStr.replace(/require\("lualib_bundle"\)/g, lualibContent); - if (withLib) { - luaStr = minimalTestLib + luaStr; - } - - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(luaStr)); - - if (status === lua.LUA_OK) { - // Read the return value from stack depending on its type. - if (lua.lua_isboolean(L, -1)) { - return lua.lua_toboolean(L, -1); - } else if (lua.lua_isnil(L, -1)) { - return undefined; - } else if (lua.lua_isnumber(L, -1)) { - return lua.lua_tonumber(L, -1); - } else if (lua.lua_isstring(L, -1)) { - return lua.lua_tojsstring(L, -1); - } else { - throw new Error("Unsupported lua return type: " + to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1)))); - } - } else { - // If the lua VM did not terminate with status code LUA_OK an error occurred. - // Throw a JS error with the message, retrieved by reading a string from the stack. - - // Filter control characters out of string which are in there because ???? - throw new Error("LUA ERROR: " + to_jsstring(lua.lua_tostring(L, -1).filter(c => c >= 20))); - } -} - -export function transpileAndExecute( - tsStr: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string, - tsHeader?: string, - ignoreDiagnostics = false -): any { - const wrappedTsString = `${tsHeader ?? ""} - declare function JSONStringify(this: void, p: any): string; - function __runTest(this: void): any {${tsStr}}`; - - const lua = `${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, ignoreDiagnostics)} - return __runTest();`; - - return executeLua(lua); -} - -function getExportPath(fileName: string, options: ts.CompilerOptions): string { - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absolutePath = path.resolve(fileName.replace(/.ts$/, "")); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - return formatPathToLuaPath(absolutePath.replace(absoluteRootDirPath, "").slice(1)); -} - -export function transpileAndExecuteProjectReturningMainExport( - typeScriptFiles: Record, - exportName: string, - options: tstl.CompilerOptions = {} -): [any, string] { - const mainFile = Object.keys(typeScriptFiles).find(typeScriptFileName => typeScriptFileName === "main.ts"); - if (!mainFile) { - throw new Error("An entry point file needs to be specified. This should be called main.ts"); - } - - const joinedTranspiledFiles = Object.keys(typeScriptFiles) - .filter(typeScriptFileName => typeScriptFileName !== "main.ts") - .map(typeScriptFileName => { - const modulePath = getExportPath(typeScriptFileName, options); - const tsCode = typeScriptFiles[typeScriptFileName]; - const luaCode = transpileString(tsCode, options); - return `package.preload["${modulePath}"] = function() - ${luaCode} - end`; - }) - .join("\n"); - - const luaCode = `return (function() - ${joinedTranspiledFiles} - ${transpileString(typeScriptFiles[mainFile])} - end)().${exportName}`; - - try { - return [executeLua(luaCode), luaCode]; - } catch (err) { - throw new Error(` - Encountered an error when executing the following Lua code: - - ${luaCode} - - ${err} - `); - } -} - -export function transpileExecuteAndReturnExport( - tsStr: string, - returnExport: string, - compilerOptions?: tstl.CompilerOptions, - luaHeader?: string -): any { - const wrappedTsString = `declare function JSONStringify(this: void, p: any): string; - ${tsStr}`; - - const lua = `return (function() - ${luaHeader ?? ""} - ${transpileString(wrappedTsString, compilerOptions, false)} - end)().${returnExport}`; - - return executeLua(lua); -} diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 21e9f153a..0ccab7c70 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -15,5 +15,6 @@ test("should transpile into one file", () => { // Verify the name is as specified in tsconfig expect(name).toBe("bundle/bundle.lua"); // Verify exported module by executing - expect(util.executeLuaModule(text)).toEqual({ myNumber: 3 }); + // Use an empty TS string because we already transpiled the TS project + util.testModule("").setLuaHeader(text).expectToEqual({ myNumber: 3 }); }); diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index d3ff509a2..b743ed0c8 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -431,6 +431,12 @@ ____exports.__result = bit.bor(a, b) return ____exports" `; +exports[`Null Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unary expressions basic ("!a") 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -523,6 +529,12 @@ end return ____exports" `; +exports[`Undefined Expression 1`] = ` +"local ____exports = {} +____exports.__result = nil +return ____exports" +`; + exports[`Unsupported bitop 5.3 ("a>>=b"): code 1`] = ` "local ____exports = {} ____exports.__result = (function() diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 6ab8a4433..d955068e5 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -128,6 +128,14 @@ exports[`ambient identifier must be a valid lua identifier (object literal short exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; +exports[`declaration-only variable with lua keyword as name is not renamed 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + type(7) +end +return ____exports" +`; + exports[`undeclared identifier must be a valid lua identifier ("$$"): code 1`] = `"foo = _____24_24_24"`; exports[`undeclared identifier must be a valid lua identifier ("$$"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index 007c64c3f..86858f700 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -19,9 +19,12 @@ test("CustomCreate", () => { } `; - const result = util.transpileAndExecute("return new Point2D(1, 2).x;", undefined, luaHeader, tsHeader); - - expect(result).toBe(1); + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule`export default new Point2D(1, 2).x;` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setReturnExport("default") + .expectToEqual(1); }); test("IncorrectUsage", () => { diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts index 46e324bc5..b1efc62ca 100644 --- a/test/unit/annotations/luaIterator.spec.ts +++ b/test/unit/annotations/luaIterator.spec.ts @@ -2,7 +2,7 @@ import * as util from "../../util"; import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; test("forof lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -13,13 +13,11 @@ test("forof lua iterator", () => { let result = ""; for (let e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof array lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Array {} @@ -30,13 +28,11 @@ test("forof array lua iterator", () => { let result = ""; for (let e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof lua iterator with existing variable", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -48,13 +44,11 @@ test("forof lua iterator with existing variable", () => { let e: string; for (e of luaIter()) { result += e; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof lua iterator destructuring", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable<[string, string]> {} @@ -65,13 +59,11 @@ test("forof lua iterator destructuring", () => { let result = ""; for (let [a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator destructuring with existing variables", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable<[string, string]> {} @@ -84,13 +76,11 @@ test("forof lua iterator destructuring with existing variables", () => { let b: string; for ([a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -106,13 +96,11 @@ test("forof lua iterator tuple-return", () => { let result = ""; for (let [a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return with existing variables", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -130,9 +118,7 @@ test("forof lua iterator tuple-return with existing variables", () => { let b: string; for ([a, b] of luaIter()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); test("forof lua iterator tuple-return single variable", () => { @@ -161,7 +147,7 @@ test("forof lua iterator tuple-return single existing variable", () => { }); test("forof forwarded lua iterator", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** @luaIterator */ interface Iter extends Iterable {} @@ -177,13 +163,11 @@ test("forof forwarded lua iterator", () => { let result = ""; for (let a of forward()) { result += a; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("abc"); + `.expectToEqual("abc"); }); test("forof forwarded lua iterator with tupleReturn", () => { - const code = ` + util.testFunction` const arr = ["a", "b", "c"]; /** * @luaIterator @@ -203,7 +187,5 @@ test("forof forwarded lua iterator with tupleReturn", () => { let result = ""; for (let [a, b] of forward()) { result += a + b; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("0a1b2c"); + `.expectToEqual("0a1b2c"); }); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts index 8829938bb..0f9cbbf36 100644 --- a/test/unit/annotations/luaTable.spec.ts +++ b/test/unit/annotations/luaTable.spec.ts @@ -35,41 +35,47 @@ declare let tbl: Table; `; test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule(tableLib + "const table = new Table(true);").expectDiagnosticsToMatchSnapshot([ - luaTableForbiddenUsage.code, - ]); + util.testModule("const table = new Table(true);") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])( "LuaTable set() cannot be used in a LuaTable call expression", tableLib => { - util.testModule(tableLib + 'const exp = tbl.set("value", 5)').expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); + util.testModule('const exp = tbl.set("value", 5)') + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); } ); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule("tbl.other()").setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule(tableLib + "let x = tbl.other()").expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); + util.testModule("let x = tbl.other()") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); }); test.each([tableLibClass])("LuaTable new", tableLib => { - const content = tableLib + "tbl = new Table();"; - expect(util.transpileString(content)).toEqual("tbl = {}"); + expect(util.testFunction("tbl = new Table();").setTsHeader(tableLib).getMainLuaCodeChunk()).toContain("tbl = {}"); }); test.each([tableLibClass])("LuaTable length", tableLib => { - const content = tableLib + "tbl = new Table();\nreturn tbl.length;"; - const lua = util.transpileString(content); - expect(util.executeLua(lua)).toEqual(0); + util.testFunction` + tbl = new Table(); + return tbl.length; + ` + .setTsHeader(tableLib) + .expectToEqual(0); }); test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule(tableLib + "tbl.length = 2;").expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); + util.testModule("tbl.length = 2;") + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { @@ -82,7 +88,9 @@ test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib 'tbl.set(...(["field", 0] as const))', 'tbl.set("field", ...([0] as const))', ])("Forbidden LuaTable use (%p)", invalidCode => { - util.testModule(tableLib + invalidCode).expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); + util.testModule(invalidCode) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); }); }); @@ -90,7 +98,9 @@ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( "Cannot extend LuaTable class (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); + util.testModule(code) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); } ); }); @@ -105,7 +115,7 @@ test.each([ test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); + util.testModule(code).setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); }); }); @@ -113,9 +123,9 @@ test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpressio test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( "Cannot use ElementAccessExpression on a LuaTable (%p)", code => { - util.testModule(tableLib + code).expectDiagnosticsToMatchSnapshot([ - luaTableCannotBeAccessedDynamically.code, - ]); + util.testModule(code) + .setTsHeader(tableLib) + .expectDiagnosticsToMatchSnapshot([luaTableCannotBeAccessedDynamically.code]); } ); }); @@ -136,6 +146,6 @@ test.each([tableLibClass])("LuaTable functional tests", tableLib => { ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], ])("LuaTable test (%p)", (code, expectedReturnValue) => { - expect(util.transpileAndExecute(code, undefined, undefined, tableLib)).toBe(expectedReturnValue); + util.testFunction(code).setTsHeader(tableLib).expectToEqual(expectedReturnValue); }); }); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts index aec48f4cf..b0fa56578 100644 --- a/test/unit/annotations/metaExtension.spec.ts +++ b/test/unit/annotations/metaExtension.spec.ts @@ -19,15 +19,14 @@ test("MetaExtension", () => { } `; - const result = util.transpileAndExecute( - 'return debug.getregistry()["_LOADED"].test();', - undefined, - undefined, - tsHeader, - true - ); - - expect(result).toBe(5); + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule` + export default debug.getregistry()["_LOADED"].test(); + ` + .setTsHeader(tsHeader) + .ignoreDiagnostics([annotationDeprecated.code]) + .setReturnExport("default") + .expectToEqual(5); }); test("IncorrectUsage", () => { diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts index 7c7c7ae9b..337e52c37 100644 --- a/test/unit/annotations/tupleReturn.spec.ts +++ b/test/unit/annotations/tupleReturn.spec.ts @@ -405,39 +405,27 @@ test("TupleReturn method assignment", () => { }); test("TupleReturn functional", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } const [a, b] = abc(); return b + a; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); + `.expectToMatchJsResult(); }); test("TupleReturn single", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } const res = abc(); return res.length - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe(2); + `.expectToMatchJsResult(); }); test("TupleReturn in expression", () => { - const code = ` + util.testFunction` /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } return abc()[1] + abc()[0]; - `; - - const result = util.transpileAndExecute(code); - - expect(result).toBe("a3"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index d2d80f08b..5f9209c41 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -12,7 +12,8 @@ test.each(["const", "let"])("%s declaration not top-level is not global", declar }); test.each(["const", "let"])("top-level %s declaration is global", declarationKind => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo; ` diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 2cabbac29..584f686bb 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -594,29 +594,27 @@ const genericChecks = [ ]; test.each(genericChecks)("array constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - let sum = 0; - array.forEach(item => { - if (typeof item === "number") { - sum += item; - } - }); - return sum; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + let sum = 0; + array.forEach(item => { + if (typeof item === "number") { + sum += item; + } + }); + return sum; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); }); test.each(genericChecks)("array constrained generic length (%p)", signature => { - const code = ` - ${signature}: number { - return array.length; - } - return generic([1, 2, 3]); - `; - expect(util.transpileAndExecute(code)).toBe(3); + util.testFunction` + ${signature}: number { + return array.length; + } + return generic([1, 2, 3]); + `.expectToMatchJsResult(); }); test.each(["[]", '"hello"', "42", "[1, 2, 3]", '{ a: "foo", b: "bar" }'])( diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index e9edd2508..7eec8844d 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -1,95 +1,94 @@ import * as util from "../../util"; test("map constructor", () => { - const result = util.transpileAndExecute("let mymap = new Map(); return mymap.size;"); - - expect(result).toBe(0); + util.testFunction` + let mymap = new Map(); + return mymap.size; + `.expectToMatchJsResult(); }); test("map iterable constructor", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([["a", "c"],["b", "d"]]); - return mymap.has("a") && mymap.has("b");` - ); - - expect(result).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.has("a") && mymap.has("b"); + `.expectToMatchJsResult(); }); test("map iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` let mymap = new Map(new Map([["a", "c"],["b", "d"]])); return mymap.has("a") && mymap.has("b"); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("map clear", () => { const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.clear();'; - const size = util.transpileAndExecute(mapTS + "return mymap.size;"); - expect(size).toBe(0); + util.testExpression("mymap.size").setTsHeader(mapTS).expectToMatchJsResult(); - const contains = util.transpileAndExecute(mapTS + 'return !mymap.has("a") && !mymap.has("b");'); - expect(contains).toBe(true); + util.testExpression('!mymap.has("a") && !mymap.has("b")').setTsHeader(mapTS).expectToMatchJsResult(); }); test("map delete", () => { - const mapTS = 'let mymap = new Map([["a", "c"],["b", "d"]]); mymap.delete("a");'; - const contains = util.transpileAndExecute(mapTS + 'return mymap.has("b") && !mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + mymap.delete("a"); + return mymap.has("b") && !mymap.has("a"); + `.expectToMatchJsResult(); }); test("map entries", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const [key, value] of mymap.entries()) { count += key + value; } - return count;` - ); - expect(result).toBe(27); + return count; + `.expectToMatchJsResult(); }); test("map foreach", () => { - const result = util.transpileAndExecute( + util.testFunction( `let mymap = new Map([["a", 2],["b", 3],["c", 4]]); let count = 0; mymap.forEach(i => count += i); return count;` - ); - - expect(result).toBe(9); + ).expectToMatchJsResult(); }); test("map foreach keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; mymap.forEach((value, key) => { count += key; }); - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map get", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("a");'); - - expect(result).toBe("c"); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("a"); + `.expectToMatchJsResult(); }); test("map get missing", () => { - const result = util.transpileAndExecute('let mymap = new Map([["a", "c"],["b", "d"]]); return mymap.get("c");'); - expect(result).toBeUndefined(); + util.testFunction` + let mymap = new Map([["a", "c"],["b", "d"]]); + return mymap.get("c"); + `.expectToMatchJsResult(); }); test("map has", () => { - const contains = util.transpileAndExecute('let mymap = new Map([["a", "c"]]); return mymap.has("a");'); - expect(contains).toBe(true); + util.testFunction` + let mymap = new Map([["a", "c"]]); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test("map has false", () => { - const contains = util.transpileAndExecute('let mymap = new Map(); return mymap.has("a");'); - expect(contains).toBe(false); + util.testFunction` + let mymap = new Map(); + return mymap.has("a"); + `.expectToMatchJsResult(); }); test.each([ @@ -117,42 +116,36 @@ test.each([ }); test("map keys", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const key of mymap.keys()) { count += key; } - return count;` - ); - - expect(result).toBe(18); + return count; + `.expectToMatchJsResult(); }); test("map set", () => { const mapTS = 'let mymap = new Map(); mymap.set("a", 5);'; - const has = util.transpileAndExecute(mapTS + 'return mymap.has("a");'); - expect(has).toBe(true); + util.testFunction(mapTS + 'return mymap.has("a");').expectToMatchJsResult(); - const value = util.transpileAndExecute(mapTS + 'return mymap.get("a")'); - expect(value).toBe(5); + util.testFunction(mapTS + 'return mymap.get("a")').expectToMatchJsResult(); }); test("map values", () => { - const result = util.transpileAndExecute( - `let mymap = new Map([[5, 2],[6, 3],[7, 4]]); + util.testFunction` + let mymap = new Map([[5, 2],[6, 3],[7, 4]]); let count = 0; for (const value of mymap.values()) { count += value; } - return count;` - ); - - expect(result).toBe(9); + return count; + `.expectToMatchJsResult(); }); test("map size", () => { - expect(util.transpileAndExecute("let m = new Map(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map(); m.set(1,3); return m.size;")).toBe(1); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); return m.size;")).toBe(2); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;")).toBe(0); - expect(util.transpileAndExecute("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;")).toBe(1); + util.testFunction("let m = new Map(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map(); m.set(1,3); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.clear(); return m.size;").expectToMatchJsResult(); + util.testFunction("let m = new Map([[1,2],[3,4]]); m.delete(3); return m.size;").expectToMatchJsResult(); }); const iterationMethods = ["entries", "keys", "values"]; diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 3a1cbe772..5e1790573 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -165,9 +165,9 @@ test.each([ { inp: "hello test", start: 3, ignored: 0, end: 2 }, ])("string.substr with expression (%p)", ({ inp, start, ignored, end }) => { const paramStr = `2 > 1 && ${start} || ${ignored}` + (end ? `, ${end}` : ""); - const result = util.transpileAndExecute(`return "${inp}".substr(${paramStr})`); - - expect(result).toBe(inp.substr(start, end)); + util.testExpression` + "${inp}".substr(${paramStr}) + `.expectToMatchJsResult(); }); test.each(["", "h", "hello"])("string.length (%p)", input => { @@ -303,13 +303,12 @@ test.each([ "function generic(string: T)", "type StringType = string; function generic(string: T)", ])("string constrained generic foreach (%p)", signature => { - const code = ` - ${signature}: number { - return string.length; - } - return generic("string"); - `; - expect(util.transpileAndExecute(code)).toBe(6); + util.testFunction` + ${signature}: number { + return string.length; + } + return generic("string"); + `.expectToMatchJsResult(); }); const trimTestCases = [ diff --git a/test/unit/builtins/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts index ab3ba12fb..812e43622 100644 --- a/test/unit/builtins/weakMap.spec.ts +++ b/test/unit/builtins/weakMap.spec.ts @@ -6,94 +6,76 @@ const initRefsTs = ` `; test("weakMap constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [ref2, 2]]); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap iterable constructor map", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap(new Map([[ref, 1], [ref2, 2]])); return mymap.has(ref) && mymap.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true], [ref2, true]]); mymap.delete(ref2); return mymap.has(ref) && !mymap.has(ref2); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap get", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, 1], [{}, 2]]); return mymap.get(ref); - `); - - expect(result).toBe(1); + `.expectToMatchJsResult(); }); test("weakMap get missing", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.get({}); - `); - - expect(result).toBeUndefined(); + `.expectToMatchJsResult(); }); test("weakMap has", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref); - `); - - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakMap has false", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[ref, true]]); return mymap.has(ref2); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap has null", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); return mymap.has(null); - `); - - expect(contains).toBe(false); + `.expectToMatchJsResult(); }); test("weakMap set", () => { @@ -103,20 +85,20 @@ test("weakMap set", () => { mymap.set(ref, 5); `; - const has = util.transpileAndExecute(init + "return mymap.has(ref);"); - expect(has).toBe(true); + util.testFunction(init + "return mymap.has(ref);").expectToMatchJsResult(); - const value = util.transpileAndExecute(init + "return mymap.get(ref)"); - expect(value).toBe(5); + util.testFunction(init + "return mymap.get(ref)").expectToMatchJsResult(); }); test("weakMap has no map features (size)", () => { - expect(util.transpileAndExecute("return (new WeakMap() as any).size")).toBeUndefined(); + util.testExpression("(new WeakMap() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakMap has no map features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakMap() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakMap() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/builtins/weakSet.spec.ts b/test/unit/builtins/weakSet.spec.ts index fe6accf45..33c5e80c3 100644 --- a/test/unit/builtins/weakSet.spec.ts +++ b/test/unit/builtins/weakSet.spec.ts @@ -6,74 +6,65 @@ const initRefsTs = ` `; test("weakSet constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref]); return myset.has(ref) - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet iterable constructor set", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(new Set([ref, ref2])); return myset.has(ref) && myset.has(ref2); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add(ref); return myset.has(ref); - `); - - expect(result).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet add different references", () => { - const result = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet(); myset.add({}); return myset.has({}); - `); - - expect(result).toBe(false); + `.expectToMatchJsResult(); }); test("weakSet delete", () => { - const contains = util.transpileAndExecute(` + util.testFunction` ${initRefsTs} let myset = new WeakSet([ref, ref2]); myset.delete(ref); return myset.has(ref2) && !myset.has(ref); - `); - expect(contains).toBe(true); + `.expectToMatchJsResult(); }); test("weakSet has no set features (size)", () => { - expect(util.transpileAndExecute("return (new WeakSet() as any).size")).toBeUndefined(); + util.testExpression("(new WeakSet() as any).size").expectToMatchJsResult(); }); test.each(["clear()", "keys()", "values()", "entries()", "forEach(() => {})"])( "weakSet has no set features (%p)", call => { - expect(() => util.transpileAndExecute(`(new WeakSet() as any).${call}`)).toThrow(); + const testBuilder = util.testFunction(`(new WeakSet() as any).${call}`); + const luaResult = testBuilder.getLuaExecutionResult(); + expect(luaResult.message).toContain("attempt to call a nil value"); } ); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 27e0ce839..9174f941c 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -51,7 +51,7 @@ test("re-throw (no catch var)", () => { }); test("return from try", () => { - const code = ` + util.testFunction` function foobar() { try { return "foobar"; @@ -59,12 +59,11 @@ test("return from try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return nil from try", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -75,12 +74,11 @@ test("return nil from try", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); test("tuple return from try", () => { - const code = ` + const testBuilder = util.testFunction` /** @tupleReturn */ function foobar() { try { @@ -91,12 +89,12 @@ test("tuple return from try", () => { const [foo, bar] = foobar(); return foo + bar; `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toBe("foobar"); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -105,12 +103,11 @@ test("return from catch", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + `.expectToMatchJsResult(); }); test("return nil from catch", () => { - const code = ` + util.testFunction` let x = "unset"; function foobar() { try { @@ -122,12 +119,11 @@ test("return nil from catch", () => { } foobar(); return x; - `; - expect(util.transpileAndExecute(code)).toBe("unset"); + `.expectToMatchJsResult(); }); test("tuple return from catch", () => { - const code = ` + const testBuilder = util.testFunction` /** @tupleReturn */ function foobar(): [string, string] { try { @@ -139,12 +135,12 @@ test("tuple return from catch", () => { const [foo, bar] = foobar(); return foo + bar; `; - expect(util.transpileString(code)).not.toMatch("unpack(foobar"); - expect(util.transpileAndExecute(code)).toMatch(/foobar catch$/); + expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); + testBuilder.expectToMatchJsResult(); }); test("return from nested try", () => { - const code = ` + util.testFunction` function foobar() { try { try { @@ -155,12 +151,11 @@ test("return from nested try", () => { } } return foobar(); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("return from nested catch", () => { - const code = ` + util.testFunction` function foobar() { try { throw "foobar"; @@ -173,15 +168,11 @@ test("return from nested catch", () => { } } return foobar(); - `; - const result = util.transpileAndExecute(code); - expect(result).toMatch("catch1"); - expect(result).toMatch("catch2"); - expect(result).toMatch("foobar"); + `.expectToMatchJsResult(); }); test("return from try->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -196,12 +187,11 @@ test("return from try->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("return from catch->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: unknown) { x = "evaluated"; @@ -217,12 +207,11 @@ test("return from catch->finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("tuple return from try->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; @@ -239,12 +228,11 @@ test("tuple return from try->finally", () => { } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("tuple return from catch->finally", () => { - const code = ` + util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; @@ -262,12 +250,11 @@ test("tuple return from catch->finally", () => { } const [foo, bar] = foobar(); return foo + bar + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally evaluated"); + `.expectToMatchJsResult(); }); test("return from nested finally", () => { - const code = ` + util.testFunction` let x = ""; function foobar() { try { @@ -282,8 +269,7 @@ test("return from nested finally", () => { } } return foobar() + " " + x; - `; - expect(util.transpileAndExecute(code)).toBe("finally AB"); + `.expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 6720fe8fb..fd6c8ab0d 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -30,12 +30,10 @@ test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1 ); test.each(["'key' in obj", "'existingKey' in obj", "0 in obj", "9 in obj"])("Binary expression in (%p)", input => { - const tsHeader = "declare var obj: any;"; - const tsSource = `return ${input}`; - const luaHeader = "obj = { existingKey = 1 }"; - const result = util.transpileAndExecute(tsSource, undefined, luaHeader, tsHeader); - - expect(result).toBe(eval(`let obj = { existingKey: 1 }; ${input}`)); + util.testFunction` + let obj = { existingKey: 1 }; + return ${input}; + `.expectToMatchJsResult(); }); test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions overridden operators (%p)", input => { @@ -119,11 +117,11 @@ test("Binary Comma Statement in For Loop", () => { }); test("Null Expression", () => { - expect(util.transpileString("null")).toBe("local ____ = nil"); + util.testExpression("null").expectLuaToMatchSnapshot(); }); test("Undefined Expression", () => { - expect(util.transpileString("undefined")).toBe("local ____ = nil"); + util.testExpression("undefined").expectLuaToMatchSnapshot(); }); test.each(["i++", "i--", "++i", "--i"])("Incrementor value (%p)", expression => { diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 20f76e273..2d9d8f1e3 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -66,19 +66,12 @@ test("Function default parameter", () => { }); test.each([{ inp: [] }, { inp: [5] }, { inp: [1, 2] }])("Function Default Values (%p)", ({ inp }) => { - // Default value is 3 for v1 - const v1 = inp.length > 0 ? inp[0] : 3; - // Default value is 4 for v2 - const v2 = inp.length > 1 ? inp[1] : 4; - const callArgs = inp.join(","); - const result = util.transpileAndExecute( + util.testFunction( `let add = function(a: number = 3, b: number = 4) { return a+b; }; return add(${callArgs});` - ); - - expect(result).toBe(v1 + v2); + ).expectToMatchJsResult(); }); test("Function default array binding parameter", () => { @@ -476,7 +469,8 @@ test("missing declaration name", () => { }); test("top-level function declaration is global", () => { - util.testBundle` + // Can't be tested with expectToMatchJsResult because in JS that would not be global + util.testModule` import './a'; export const result = foo(); ` diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index 55e61f9ae..7ed8e7560 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -247,7 +247,7 @@ exports[`Invalid function argument ({"definition": "interface FuncPropInterface const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -639,7 +639,7 @@ exports[`Invalid function assignment ({"definition": "interface FuncPropInterfac const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1031,7 +1031,7 @@ exports[`Invalid function generic argument ({"definition": "interface FuncPropIn const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1391,7 +1391,7 @@ exports[`Invalid function return ({"definition": "interface FuncPropInterface { const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ @@ -1791,7 +1791,7 @@ exports[`Invalid function variable declaration ({"definition": "interface FuncPr const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { /** @noSelf */ diff --git a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts index e475f2216..abac4e483 100644 --- a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -13,7 +13,7 @@ test.each(["noSelf", "noSelfInFile"])("noSelf function method argument (%p)", no const c = new NS.C(); return c.method(foo); `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + util.testFunction(code).setTsHeader(header).expectToMatchJsResult(); }); test("noSelfInFile works when first statement has other annotations", () => { @@ -30,20 +30,21 @@ test("noSelfInFile works when first statement has other annotations", () => { test.each(["(this: void, s: string) => string", "(this: any, s: string) => string", "(s: string) => string"])( "Function expression type inference in binary operator (%p)", funcType => { - const header = `declare const undefinedFunc: ${funcType};`; - const code = ` - let func: ${funcType} = s => s; - func = undefinedFunc || (s => s); - return func("foo"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, header)).toBe("foo"); + const header = `let undefinedFunc: (${funcType}) | undefined;`; + util.testFunction` + let func: ${funcType} = s => s; + func = undefinedFunc || (s => s); + return func("foo"); + ` + .setTsHeader(header) + .expectToMatchJsResult(); } ); test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { return s; })"])( "Function expression type inference in class (%p)", funcExp => { - const code = ` + util.testFunction` class Foo { func: (this: void, s: string) => string = ${funcExp}; method: (s: string) => string = ${funcExp}; @@ -52,8 +53,7 @@ test.each(["s => s", "(s => s)", "function(s) { return s; }", "(function(s) { re } const foo = new Foo(); return foo.func("a") + foo.method("b") + Foo.staticFunc("c") + Foo.staticMethod("d"); - `; - expect(util.transpileAndExecute(code)).toBe("abcd"); + `.expectToMatchJsResult(); } ); @@ -67,23 +67,21 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (%p)", ({ assignTo, funcExp }) => { - const code = ` + util.testFunction` interface Foo { func(this: void, s: string): string; method(this: this, s: string): string; } ${assignTo} = {func: ${funcExp}, method: ${funcExp}}; return foo.method("foo") + foo.func("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("Function expression type inference in object literal assigned to narrower type", () => { - const code = ` + util.testFunction` let foo: {} = {bar: s => s}; return (foo as {bar: (a: any) => any}).bar("foobar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -96,14 +94,13 @@ test.each([ { assignTo: "let foo: Foo; foo", funcExp: "function(s) { return s; }" }, { assignTo: "let foo: Foo; foo", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in object literal (generic key) (%p)", ({ assignTo, funcExp }) => { - const code = ` - interface Foo { - [f: string]: (this: void, s: string) => string; - } - ${assignTo} = {func: ${funcExp}}; - return foo.func("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + util.testFunction` + interface Foo { + [f: string]: (this: void, s: string) => string; + } + ${assignTo} = {func: ${funcExp}}; + return foo.func("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -204,7 +201,7 @@ test.each([ funcExp: "(function(s) { return s; })", }, ])("Function expression type inference in tuple (%p)", ({ assignTo, func, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -217,8 +214,7 @@ test.each([ ${assignTo} = [${funcExp}, ${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo") + ${func}("bar"); - `; - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test.each([ @@ -239,7 +235,7 @@ test.each([ { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "function(s) { return s; }" }, { assignTo: "let meth: Method; [meth]", method: "meth", funcExp: "(function(s) { return s; })" }, ])("Function expression type inference in array (%p)", ({ assignTo, method, funcExp }) => { - const code = ` + util.testFunction` interface Foo { method(s: string): string; } @@ -249,8 +245,7 @@ test.each([ ${assignTo} = [${funcExp}]; const foo: Foo = {method: ${method}}; return foo.method("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -261,12 +256,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` type U = string | number | (${funcType}); const u: U = ${funcExp}; return (u as ${funcType})("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -277,12 +271,11 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in union tuple (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` interface I { callback: ${funcType}; } let a: I[] | number = [{ callback: ${funcExp} }]; return a[0].callback("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -293,11 +286,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in as cast (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = (${funcExp}) as (${funcType}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -308,11 +300,10 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in type assertion (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` const fn: ${funcType} = <${funcType}>(${funcExp}); return fn("foo"); - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); test.each([ @@ -323,13 +314,12 @@ test.each([ { funcType: "(this: any, s: string) => string", funcExp: "function(s) { return s; }" }, { funcType: "(s: string) => string", funcExp: "function(s) { return s; }" }, ])("Function expression type inference in constructor (%p)", ({ funcType, funcExp }) => { - const code = ` + util.testFunction` class C { result: string; constructor(fn: ${funcType}) { this.result = fn("foo"); } } const c = new C(${funcExp}); return c.result; - `; - expect(util.transpileAndExecute(code)).toBe("foo"); + `.expectToMatchJsResult(); }); diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index ebf00dfae..f95af8ab3 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -87,7 +87,7 @@ export const selfTestFunctions: TestFunction[] = [ { value: "methodInterface.method", definition: `interface MethodInterface { method(this: any, s: string): string; } - const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } }`, + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };`, }, { value: "anonMethodInterface.anonMethod", diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index a491ccd7b..d9613692d 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -15,54 +15,64 @@ import { } from "./functionPermutations"; test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { - const code = `const fn: ${functionType} = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + const fn: ${functionType} = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function assignment (%p)", (testFunction, functionType) => { - const code = `let fn: ${functionType}; - fn = ${testFunction.value}; - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: ${functionType}; + fn = ${testFunction.value}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function assignment with cast (%p)", (testFunction, castedFunction) => { - const code = ` - let fn: typeof ${testFunction.value}; - fn = ${castedFunction}; - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + let fn: typeof ${testFunction.value}; + fn = ${castedFunction}; + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFunction, functionType) => { - const code = ` - function takesFunction(fn: ${functionType}) { - return fn("foobar"); - } - return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: ${functionType}) { + return fn("foobar"); + } + return takesFunction(${testFunction.value}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid lua lib function argument", () => { - const code = `let result = ""; + util.testFunction` + let result = ""; function foo(this: any, value: string) { result += value; } const a = ['foo', 'bar']; a.forEach(foo); - return result;`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function argument with cast (%p)", (testFunction, castedFunction) => { - const code = ` - function takesFunction(fn: typeof ${testFunction.value}) { - return fn("foobar"); - } - return takesFunction(${castedFunction}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function takesFunction(fn: typeof ${testFunction.value}) { + return fn("foobar"); + } + return takesFunction(${castedFunction}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ @@ -77,60 +87,66 @@ test.each([ ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ])("Valid function generic argument (%p)", (testFunction, functionType) => { - const code = ` + util.testFunction` function takesFunction(fn: T) { return fn("foobar"); } return takesFunction(${testFunction.value}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each([ ...anonTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...selfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["0", "'foobar'"]]), ...noSelfTestFunctionExpressions.map((f): [TestFunction, string[]] => [f, ["'foobar'"]]), -])("Valid function expression argument with no signature (%p)", (testFunction, args) => { - const code = ` +])("Valid function expression argument with no signature (%p, %p)", (testFunction, args) => { + util.testFunction` const takesFunction: any = (fn: (this: void, ...args: any[]) => any, ...args: any[]) => { return fn(...args); } return takesFunction(${testFunction.value}, ${args.join(", ")}); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToEqual("foobar"); }); test.each(validTestFunctionAssignments)("Valid function return (%p)", (testFunction, functionType) => { - const code = ` - function returnsFunction(): ${functionType} { - return ${testFunction.value}; - } - const fn = returnsFunction(); - return fn("foobar"); - `; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): ${functionType} { + return ${testFunction.value}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test.each(validTestFunctionCasts)("Valid function return with cast (%p)", (testFunction, castedFunction) => { - const code = `function returnsFunction(): typeof ${testFunction.value} { - return ${castedFunction}; - } - const fn = returnsFunction(); - return fn("foobar");`; - expect(util.transpileAndExecute(code, undefined, undefined, testFunction.definition)).toBe("foobar"); + util.testFunction` + function returnsFunction(): typeof ${testFunction.value} { + return ${castedFunction}; + } + const fn = returnsFunction(); + return fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); }); test("Valid function tuple assignment", () => { - const code = `interface Func { (this: void, s: string): string; } - function getTuple(): [number, Func] { return [1, s => s]; } - let [i, f]: [number, Func] = getTuple(); - return f("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Func { (this: void, s: string): string; } + function getTuple(): [number, Func] { return [1, s => s]; } + let [i, f]: [number, Func] = getTuple(); + return f("foo"); + `.expectToMatchJsResult(); }); test("Interface method assignment", () => { - const code = ` + util.testFunction` class Foo { method(s: string): string { return s + "+method"; } lambdaProp: (s: string) => string = s => s + "+lambdaProp"; @@ -141,46 +157,44 @@ test("Interface method assignment", () => { } const foo: IFoo = new Foo(); return foo.method("foo") + "|" + foo.lambdaProp("bar"); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo+method|bar+lambdaProp"); + `.expectToMatchJsResult(); }); test("Valid interface method assignment", () => { - const code = `interface A { fn(this: void, s: string): string; } - interface B { fn(this: void, s: string): string; } - const a: A = { fn(this: void, s) { return s; } }; - const b: B = a; - return b.fn("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface A { fn(this: void, s: string): string; } + interface B { fn(this: void, s: string): string; } + const a: A = { fn(this: void, s) { return s; } }; + const b: B = a; + return b.fn("foo"); + `.expectToMatchJsResult(); }); test("Valid method tuple assignment", () => { - const code = `interface Foo { method(s: string): string; } - interface Meth { (this: Foo, s: string): string; } - let meth: Meth = s => s; - function getTuple(): [number, Meth] { return [1, meth]; } - let [i, f]: [number, Meth] = getTuple(); - let foo: Foo = {method: f}; - return foo.method("foo");`; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + util.testFunction` + interface Foo { method(s: string): string; } + interface Meth { (this: Foo, s: string): string; } + let meth: Meth = s => s; + function getTuple(): [number, Meth] { return [1, meth]; } + let [i, f]: [number, Meth] = getTuple(); + let foo: Foo = {method: f}; + return foo.method("foo"); + `.expectToMatchJsResult(); }); test.each([ - { assignType: "(this: any, s: string) => string", args: ["foo"], expectResult: "foobar" }, - { assignType: "{(this: any, s: string): string}", args: ["foo"], expectResult: "foobar" }, - { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"], expectResult: "foobaz" }, - { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"], expectResult: "foobaz" }, -])("Valid function overload assignment (%p)", ({ assignType, args, expectResult }) => { - const code = `interface O { - (s1: string, s2: string): string; - (s: string): string; - } - const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); - let f: ${assignType} = o; - return f(${args.map(a => '"' + a + '"').join(", ")});`; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + { assignType: "(this: any, s: string) => string", args: ["foo"] }, + { assignType: "{(this: any, s: string): string}", args: ["foo"] }, + { assignType: "(this: any, s1: string, s2: string) => string", args: ["foo", "baz"] }, + { assignType: "{(this: any, s1: string, s2: string): string}", args: ["foo", "baz"] }, +])("Valid function overload assignment (%p)", ({ assignType, args }) => { + util.testFunction` + interface O { + (s1: string, s2: string): string; + (s: string): string; + } + const o: O = (s1: string, s2?: string) => s1 + (s2 || "bar"); + let f: ${assignType} = o; + return f(${args.map(a => '"' + a + '"').join(", ")}); + `.expectToMatchJsResult(); }); diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 16172b410..9caefb300 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -2,110 +2,101 @@ import * as ts from "typescript"; import * as util from "../util"; test.each(["let", "const"])("Let/Const Hoisting (%p)", varType => { - const code = ` + util.testFunction` let bar: string; function setBar() { bar = foo; } ${varType} foo = "foo"; setBar(); return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test.each(["let", "const"])("Exported Let/Const Hoisting (%p)", varType => { - const code = ` + util.testModule` let bar: string; function setBar() { bar = foo; } export ${varType} foo = "foo"; setBar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Global Function Hoisting", () => { - const code = ` + util.testFunction` const foo = bar(); function bar() { return "bar"; } return foo; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Local Function Hoisting", () => { - const code = ` + util.testModule` export const foo = bar(); function bar() { return "bar"; } - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("bar"); + `.expectToMatchJsResult(); }); test("Exported Function Hoisting", () => { - const code = ` + util.testModule` const foo = bar(); export function bar() { return "bar"; } export const baz = foo; - `; - const result = util.transpileExecuteAndReturnExport(code, "baz"); - expect(result).toBe("bar"); + ` + .setReturnExport("baz") + .expectToMatchJsResult(); }); test("Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction` + return foo; + ` + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); test("Exported Namespace Function Hoisting", () => { - const code = ` - let foo: string; - namespace NS { - foo = bar(); - export function bar() { return "bar"; } - } - `; - const result = util.transpileAndExecute("return foo;", undefined, undefined, code); - expect(result).toBe("bar"); + util.testFunction("return foo;") + .setTsHeader( + ` + let foo: string; + namespace NS { + foo = bar(); + export function bar() { return "bar"; } + } + ` + ) + .expectToMatchJsResult(); }); -test.each([ - { varType: "let", expectResult: "bar" }, - { varType: "const", expectResult: "bar" }, -])("Hoisting in Non-Function Scope (%p)", ({ varType, expectResult }) => { - const code = ` - function foo() { - ${varType} bar = "bar"; - for (let i = 0; i < 1; ++i) { - ${varType} bar = "foo"; - } - return bar; +test.each(["let", "const"])("Hoisting in Non-Function Scope (%p)", varType => { + util.testFunction` + function foo() { + ${varType} bar = "bar"; + for (let i = 0; i < 1; ++i) { + ${varType} bar = "foo"; } - return foo(); - `; - const result = util.transpileAndExecute(code); - expect(result).toBe(expectResult); + return bar; + } + return foo(); + `.expectToMatchJsResult(); }); test("Hoisting due to reference from hoisted function", () => { - const code = ` + util.testFunction` const foo = "foo"; const result = bar(); function bar() { return foo; } return result; - `; - const result = util.transpileAndExecute(code); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Hoisting with synthetic source file node", () => { @@ -131,7 +122,7 @@ test("Hoisting with synthetic source file node", () => { }); test("Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -139,13 +130,11 @@ test("Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Exported Namespace Hoisting", () => { - const code = ` + util.testModule` function bar() { return NS.foo; } @@ -153,9 +142,7 @@ test("Exported Namespace Hoisting", () => { export let foo = "foo"; } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Nested Namespace Hoisting", () => { @@ -176,7 +163,7 @@ test("Nested Namespace Hoisting", () => { }); test("Class Hoisting", () => { - const code = ` + util.testModule` function makeFoo() { return new Foo(); } @@ -184,13 +171,11 @@ test("Class Hoisting", () => { public bar = "foo"; } export const foo = makeFoo().bar; - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToMatchJsResult(); }); test("Enum Hoisting", () => { - const code = ` + util.testModule` function bar() { return E.A; } @@ -198,13 +183,14 @@ test("Enum Hoisting", () => { A = "foo" } export const foo = bar(); - `; - const result = util.transpileExecuteAndReturnExport(code, "foo"); - expect(result).toBe("foo"); + `.expectToHaveNoDiagnostics(); }); test("Import hoisting (named)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = foo; import { foo } from "./module"; ` @@ -213,16 +199,22 @@ test("Import hoisting (named)", () => { }); test("Import hoisting (namespace)", () => { - util.testBundle` - export const result = module.foo; - import * as module from "./module"; + // TODO cant be tested with expectToEqualJSresult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` + export const result = m.foo; + import * as m from "./module"; ` .addExtraFile("module.ts", "export const foo = true;") .expectToEqual({ result: true }); }); test("Import hoisting (side-effect)", () => { - util.testBundle` + // TODO cant be tested with expectToEqualJSResult because of + // the scuffed module setup in TestBuilder.executeJs (module hoisting is not possible) + // should be updated once vm.module becomes stable + util.testModule` export const result = (globalThis as any).result; import "./module"; ` @@ -231,7 +223,8 @@ test("Import hoisting (side-effect)", () => { }); test("Import hoisted before function", () => { - util.testBundle` + // Can't use expectToMatchJsResult because above is not valid TS/JS + util.testModule` export let result: any; baz(); @@ -246,13 +239,13 @@ test("Import hoisted before function", () => { }); test("Hoisting Shorthand Property", () => { - const code = ` + util.testFunction` function foo() { return { bar }.bar; } let bar = "foobar"; - return foo();`; - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo(); + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/944 diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index ba2bcd8a0..9f72ad671 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -132,20 +132,21 @@ test.each(validTsInvalidLuaNames)( ); test.each(validTsInvalidLuaNames)("exported values with invalid lua identifier names (%p)", name => { - const code = `export const ${name} = "foobar";`; - const lua = util.transpileString(code); + const testBuilder = util.testModule(`export const ${name} = "foobar";`); + const lua = testBuilder.getMainLuaCodeChunk(); + const luaResult = testBuilder.getLuaExecutionResult(); expect(lua.indexOf(`"${name}"`)).toBeGreaterThanOrEqual(0); - expect(util.executeLua(`return (function() ${lua} end)()["${name}"]`)).toBe("foobar"); + expect(luaResult[name]).toBe("foobar"); }); test("exported identifiers referenced in namespace (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace NS { export const bar = foo; } - export const baz = NS.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = NS.bar; + `.expectToMatchJsResult(); }); test("exported namespace identifiers referenced in different namespace (%p)", () => { @@ -157,31 +158,31 @@ test("exported namespace identifiers referenced in different namespace (%p)", () } export const baz = B.bar; }`; - expect(util.transpileAndExecute("return A.baz", undefined, undefined, tsHeader)).toBe("foobar"); + util.testFunction("return A.baz").setTsHeader(tsHeader).expectToMatchJsResult(); }); test("exported identifiers referenced in nested scope (%p)", () => { - const code = ` + util.testModule` export const foo = "foobar"; namespace A { export namespace B { export const bar = foo; } } - export const baz = A.B.bar;`; - expect(util.transpileExecuteAndReturnExport(code, "baz")).toBe("foobar"); + export const baz = A.B.bar; + `.expectToMatchJsResult(); }); test.each(validTsInvalidLuaNames)( "exported values with invalid lua identifier names referenced in different scope (%p)", name => { - const code = ` - export const ${name} = "foobar"; - namespace NS { - export const foo = ${name}; - } - export const bar = NS.foo;`; - expect(util.transpileExecuteAndReturnExport(code, "bar")).toBe("foobar"); + util.testModule` + export const ${name} = "foobar"; + namespace NS { + export const foo = ${name}; + } + export const bar = NS.foo; + `.expectToMatchJsResult(); } ); @@ -223,103 +224,92 @@ test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua nam describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { - const code = ` + util.testFunction` const nil = "foobar"; - return \`\${undefined}|\${nil}\``; - - expect(util.transpileAndExecute(code)).toBe("nil|foobar"); + return \`\${undefined}|\${nil}\` + `.expectToEqual("nil|foobar"); }); test("variable (and)", () => { - const code = ` + util.testFunction` const and = "foobar"; - return true && and;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return true && and; + `.expectToMatchJsResult(); }); test("variable (elseif)", () => { - const code = ` + util.testFunction` const elseif = "foobar"; if (false) { } else if (elseif) { return elseif; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (end)", () => { - const code = ` + util.testFunction` const end = "foobar"; { return end; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (local)", () => { - const code = ` + util.testFunction` const local = "foobar"; - return local;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return local; + `.expectToMatchJsResult(); }); test("variable (not)", () => { - const code = ` + util.testFunction` const not = "foobar"; - return (!false) && not;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return (!false) && not; + `.expectToMatchJsResult(); }); test("variable (or)", () => { - const code = ` + util.testFunction` const or = "foobar"; - return false || or;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return false || or; + `.expectToMatchJsResult(); }); test("variable (repeat)", () => { - const code = ` + util.testFunction` const repeat = "foobar"; do {} while (false); - return repeat;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return repeat; + `.expectToMatchJsResult(); }); test("variable (then)", () => { - const code = ` + util.testFunction` const then = "foobar"; if (then) { return then; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (until)", () => { - const code = ` + util.testFunction` const until = "foobar"; do {} while (false); - return until;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return until; + `.expectToMatchJsResult(); }); test("variable (goto)", () => { - const code = ` + util.testFunction` const goto = "foobar"; switch (goto) { case goto: return goto; - }`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + } + `.expectToMatchJsResult(); }); test("variable (print)", () => { @@ -332,42 +322,48 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` - const print = "foobar"; - console.log(print); - return result;`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toBe("foobar"); + util.testFunction` + const print = "foobar"; + console.log(print); + return result; + ` + .setLuaHeader(luaHeader) + .setTsHeader(tsHeader) + .setOptions(compilerOptions) + .expectToEqual("foobar"); }); test("variable (type)", () => { - const code = ` + util.testFunction` function type(this: void, a: unknown) { return (typeof a) + "|foobar"; } - return type(7);`; - - expect(util.transpileAndExecute(code)).toBe("number|foobar"); + return type(7); + `.expectToMatchJsResult(); }); test("variable (error)", () => { - const code = ` + const executionResult = util.testFunction` const error = "foobar"; - throw error;`; + throw error; + `.getLuaExecutionResult(); - expect(() => util.transpileAndExecute(code)).toThrow(/^LUA ERROR: foobar$/); + expect(executionResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (assert)", () => { - const code = ` - const assert = false; - console.assert(assert, "foobar");`; - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; - expect(() => util.transpileAndExecute(code, compilerOptions)).toThrow(/^LUA ERROR: .+ foobar$/); + const luaResult = util.testFunction` + const assert = false; + console.assert(assert, "foobar"); + ` + .setOptions(compilerOptions) + .getLuaExecutionResult(); + + expect(luaResult).toEqual(new util.ExecutionError("foobar")); }); test("variable (debug)", () => { @@ -380,297 +376,272 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const tsHeader = ` declare let result: string;`; - const code = ` + const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + + const luaResult = util.testFunction` const debug = "foobar"; console.trace(debug); - return result;`; - - const compilerOptions = { lib: ["lib.es2015.d.ts", "lib.dom.d.ts"] }; + return result; + ` + .setTsHeader(tsHeader) + .setLuaHeader(luaHeader) + .setOptions(compilerOptions) + .getLuaExecutionResult(); - expect(util.transpileAndExecute(code, compilerOptions, luaHeader, tsHeader)).toMatch( - /^foobar\nstack traceback.+/ - ); + expect(luaResult).toMatch(/^foobar\nstack traceback.+/); }); test("variable (string)", () => { - const code = ` + util.testFunction` const string = "foobar"; - return string[0];`; - - expect(util.transpileAndExecute(code)).toBe("f"); + return string[0]; + `.expectToMatchJsResult(); }); test("variable (math)", () => { - const code = ` + util.testFunction` const math = -17; - return Math.abs(math);`; - - expect(util.transpileAndExecute(code)).toBe(17); + return Math.abs(math); + `.expectToMatchJsResult(); }); test("variable (table)", () => { - const code = ` + util.testFunction` const table = ["foobar"]; - return table.pop();`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return table.pop(); + `.expectToMatchJsResult(); }); test("variable (coroutine)", () => { - const code = ` + util.testFunction` const coroutine = "foobar"; function *foo() { yield coroutine; } - return foo().next().value;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return foo().next().value; + `.expectToMatchJsResult(); }); test("variable (pairs)", () => { - const code = ` + util.testFunction` const pairs = {foobar: "foobar"}; let result = ""; for (const key in pairs) { result += key; } - return result;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return result; + `.expectToMatchJsResult(); }); test("variable (pcall)", () => { - const code = ` + util.testFunction` const pcall = "foobar"; try {} finally {} - return pcall;`; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + return pcall; + `.expectToMatchJsResult(); }); test("variable (rawget)", () => { - const code = ` + util.testFunction` const rawget = {foobar: "foobar"}; - return rawget.hasOwnProperty("foobar");`; - - expect(util.transpileAndExecute(code)).toBe(true); + return rawget.hasOwnProperty("foobar"); + `.expectToMatchJsResult(); }); test("variable (require)", () => { - const code = ` + const luaHeader = 'package.loaded.someModule = {foo = "bar"}'; + + const luaResult = util.testModule` const require = "foobar"; export { foo } from "someModule"; - export const result = require;`; - - const lua = ` - package.loaded.someModule = {foo = "bar"} - return (function() - ${util.transpileString(code, undefined, true)} - end)().result`; + export const result = require; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult.result).toBe("foobar"); }); test("variable (tostring)", () => { - const code = ` + util.testFunction` const tostring = 17; - return tostring.toString();`; - - expect(util.transpileAndExecute(code)).toBe(17); + return tostring.toString(); + `.expectToMatchJsResult(); }); test("variable (unpack)", () => { - const code = ` - const unpack = ["foo", "bar"]; - const [foo, bar] = unpack;`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = "unpack = table.unpack"; - const lua = ` - unpack = table.unpack - ${util.transpileString(code, undefined, false)} - return foo .. bar`; + const luaResult = util.testFunction` + const unpack = ["foo", "bar"]; + const [foo, bar] = unpack; + return foo + bar; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(util.executeLua(lua)).toBe("foobar"); + expect(luaResult).toBe("foobar"); }); test("variable (_G)", () => { - const code = ` + util.testFunction` const _G = "bar"; (globalThis as any).foo = "foo"; return (globalThis as any).foo + _G; - `; - - expect(util.transpileAndExecute(code)).toBe("foobar"); + `.expectToMatchJsResult(); }); test("function parameter", () => { - const code = ` + util.testFunction` function foo(type: unknown) { return \`\${typeof type}|\${type}\`; } - return foo("foobar");`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo("foobar"); + `.expectToMatchJsResult(); }); test("destructured property function parameter", () => { - const code = ` + util.testFunction` function foo({type}: any) { return \`\${typeof type}|\${type}\`; } - return foo({type: "foobar"});`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo({type: "foobar"}); + `.expectToMatchJsResult(); }); test("destructured array element function parameter", () => { - const code = ` + util.testFunction` function foo([type]: any) { return \`\${typeof type}|\${type}\`; } - return foo(["foobar"]);`; - - expect(util.transpileAndExecute(code)).toBe("string|foobar"); + return foo(["foobar"]); + `.expectToMatchJsResult(); }); test("property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type: type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("shorthand property", () => { - const code = ` + util.testFunction` const type = "foobar"; const foo = { type }; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type: type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured shorthand property", () => { - const code = ` + util.testFunction` const foo = { type: "foobar" }; const { type } = foo; - return type + "|" + foo.type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|foobar|string"); + return type + "|" + foo.type + "|" + typeof type; + `.expectToMatchJsResult(); }); test("destructured array element", () => { - const code = ` + util.testFunction` const foo = ["foobar"]; const [type] = foo; - return type + "|" + typeof type;`; - - expect(util.transpileAndExecute(code)).toBe("foobar|string"); + return type + "|" + typeof type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("imported variable (%p)", importName => { - const luaHeader = ` - package.loaded.someModule = {type = "foobar"}`; + // Can't use expectToMatchJsResult because above is not valid TS/JS + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - const code = ` + const luaResult = util.testModule` import {${importName}} from "someModule"; export const result = typeof 7 + "|" + type; - `; - - const lua = util.transpileString(code); - const result = util.executeLua(`${luaHeader} return (function() ${lua} end)().result`); + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); - expect(result).toBe("number|foobar"); + expect(luaResult.result).toBe("number|foobar"); }); - test.each([ - { returnExport: "type", expectResult: "foobar" }, - { returnExport: "mytype", expectResult: "foobar" }, - { returnExport: "result", expectResult: "string|foobar" }, - ])("separately exported variable (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("separately exported variable (%p)", () => { + util.testModule` const type = "foobar"; export { type } export { type as mytype } - export const result = typeof type + "|" + type;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type + "|" + type; + `.expectToMatchJsResult(); }); test.each(["type", "type as type"])("re-exported variable with lua keyword as name (%p)", importName => { - const code = ` - export { ${importName} } from "someModule"`; + // Can't use expectToMatchJsResult because above is not valid TS/JS - const lua = ` - package.loaded.someModule = {type = "foobar"} - return (function() - ${util.transpileString(code)} - end)().type`; + const luaHeader = 'package.loaded.someModule = {type = "foobar"}'; - expect(util.executeLua(lua)).toBe("foobar"); + const luaResult = util.testModule` + export { ${importName} } from "someModule"; + ` + .setLuaHeader(luaHeader) + .getLuaExecutionResult(); + + expect(luaResult.type).toBe("foobar"); }); test("class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - return t.method() + "|" + type.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return t.method() + "|" + type.staticMethod(); + `.expectToMatchJsResult(); }); test("subclass of class", () => { - const code = ` + util.testFunction` class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - return foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileAndExecute(code)).toBe("number|string"); + return foo.method() + "|" + Foo.staticMethod(); + `.expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } const t = new type(); - export const result = t.method() + "|" + type.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = t.method() + "|" + type.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|string" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("subclass of exported class (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("subclass of exported class (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof "foo"; } } class Foo extends type {} const foo = new Foo(); - export const result = foo.method() + "|" + Foo.staticMethod();`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = foo.method() + "|" + Foo.staticMethod(); + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); test("namespace", () => { @@ -682,20 +653,16 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const code = ` return typeof type.foo + "|" + type.foo`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("string|foobar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "string|foobar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test("exported namespace (%p)", () => { + util.testModule` export namespace type { export const foo = "foobar"; } - export const result = typeof type.foo + "|" + type.foo;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = typeof type.foo + "|" + type.foo; + `.expectToMatchJsResult(); }); test("merged namespace", () => { @@ -717,14 +684,11 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { const t = new type(); return \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - expect(util.transpileAndExecute(code, undefined, undefined, tsHeader)).toBe("number|boolean|string|foo|bar"); + util.testFunction(code).setTsHeader(tsHeader).expectToMatchJsResult(); }); - test.each([ - { returnExport: "result", expectResult: "number|boolean|string|foo|bar" }, - { returnExport: "type ~= nil", expectResult: true }, - ])("exported merged namespace (%p)", ({ returnExport, expectResult }) => { - const code = ` + test.each(["result", "type ~= nil"])("exported merged namespace (%p)", returnExport => { + util.testModule` export class type { method() { return typeof 0; } static staticMethod() { return typeof true; } @@ -739,25 +703,23 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { } const t = new type(); - export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`;`; - - expect(util.transpileExecuteAndReturnExport(code, returnExport)).toBe(expectResult); + export const result = \`\${t.method()}|\${type.staticMethod()}|\${typeof type.foo}|\${type.foo}|\${type.bar}\`; + ` + .setReturnExport(returnExport) + .expectToMatchJsResult(); }); }); test("declaration-only variable with lua keyword as name is not renamed", () => { - const code = ` - declare function type(this: void, a: unknown): string; - type(7);`; - - expect(util.transpileString(code, undefined, false)).toBe("type(7)"); + util.testFunction("type(7)") + .setTsHeader("declare function type(this: void, a: unknown): string;") + .expectLuaToMatchSnapshot(); }); test("exported variable with lua keyword as name is not renamed", () => { - const code = ` - export const print = "foobar";`; - - expect(util.transpileExecuteAndReturnExport(code, "print")).toBe("foobar"); + util.testModule` + export const print = "foobar"; + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/846 diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index b35bbd767..c644776e5 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -198,18 +198,15 @@ test("for scope", () => { test.each([ { inp: { test1: 0, test2: 1, test3: 2 }, - expected: { test1: 1, test2: 2, test3: 3 }, }, -])("forin[Object] (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +])("forin[Object] (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; for (let key in objTest) { objTest[key] = objTest[key] + 1; } - return JSONStringify(objTest);` - ); - - expect(JSON.parse(result)).toEqual(expected); + return objTest; + `.expectToMatchJsResult(); }); test("forin[Array]", () => { @@ -219,11 +216,9 @@ test("forin[Array]", () => { `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); -test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2, d: 0, e: 4 } }])( - "forin with continue (%p)", - ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let obj = ${JSON.stringify(inp)}; +test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p)", ({ inp }) => { + util.testFunctionTemplate` + let obj = ${inp}; for (let i in obj) { if (obj[i] % 2 == 0) { continue; @@ -231,24 +226,19 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 }, expected: { a: 0, b: 0, c: 2 obj[i] = 0; } - return JSONStringify(obj);` - ); - - expect(result).toBe(JSON.stringify(expected)); - } -); + return obj; + `.expectToMatchJsResult(); +}); -test.each([{ inp: [0, 1, 2], expected: [1, 2, 3] }])("forof (%p)", ({ inp, expected }) => { - const result = util.transpileAndExecute( - `let objTest = ${JSON.stringify(inp)}; +test.each([{ inp: [0, 1, 2] }])("forof (%p)", ({ inp }) => { + util.testFunctionTemplate` + let objTest = ${inp}; let arrResultTest = []; for (let value of objTest) { arrResultTest.push(value + 1) } - return JSONStringify(arrResultTest);` - ); - - expect(result).toBe(JSON.stringify(expected)); + return arrResultTest; + `.expectToMatchJsResult(); }); test("Tuple loop", () => { @@ -455,31 +445,29 @@ test.each(["", "abc", "a\0c"])("forof string (%p)", string => { describe("for...of empty destructuring", () => { const declareTests = (destructuringPrefix: string) => { test("array", () => { - const code = ` + util.testFunction` const arr = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of arr) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); test("iterable", () => { - const code = ` + util.testFunction` const iter: Iterable = [["a"], ["b"], ["c"]]; let i = 0; for (${destructuringPrefix}[] of iter) { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.expectToMatchJsResult(); }); test("luaIterator", () => { - const code = ` + const luaResult = util.testFunction` const arr = [["a"], ["b"], ["c"]]; /** @luaIterator */ interface Iter extends Iterable {} @@ -492,12 +480,13 @@ describe("for...of empty destructuring", () => { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.getLuaExecutionResult(); + // Can't use expectToMatchJsResult because above is not valid TS/JS + expect(luaResult).toBe(3); }); test("luaIterator+tupleReturn", () => { - const code = ` + const luaResult = util.testFunction` const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; /** * @luaIterator @@ -520,8 +509,9 @@ describe("for...of empty destructuring", () => { ++i; } return i; - `; - expect(util.transpileAndExecute(code)).toBe(3); + `.getLuaExecutionResult(); + // Can't use expectToMatchJsResult because above is not valid TS/JS + expect(luaResult).toBe(3); }); }; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index b6aefdc0c..dd3d1dd7a 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -66,130 +66,106 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ ); test.each(["export default value;", "export { value as default };"])("Export Default From (%p)", exportStatement => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - export { default } from "./module"; - `, - "module.ts": ` + util.testModule` + export { default } from "./module"; + ` + .addExtraFile( + "module.ts", + ` export const value = true; ${exportStatement}; - `, - }, - "default" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Default Import and Export Expression", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport; - `, - "module.ts": ` + util.testModule` + import defaultExport from "./module"; + export const value = defaultExport; + ` + .addExtraFile( + "module.ts", + ` export default 1 + 2 + 3; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Import and Export Assignment", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as m from "./module"; - export const value = m; - `, - "module.ts": ` + util.testModule` + // @ts-ignore + import * as m from "./module"; + export const value = m; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .addExtraFile( + "module.ts", + ` export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Named Imports", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, { a, b, c } from "./module"; - export const value = defaultExport + b + c; - `, - "module.ts": ` + util.testModule` + import defaultExport, { a, b, c } from "./module"; + export const value = defaultExport + b + c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Mixed Exports, Default and Namespace Import", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport, * as ns from "./module"; - export const value = defaultExport + ns.b + ns.c; - `, - "module.ts": ` + util.testModule` + import defaultExport, * as ns from "./module"; + export const value = defaultExport + ns.b + ns.c; + ` + .addExtraFile( + "module.ts", + ` export const a = 1; export const b = 2; export const c = 3; export default a; - `, - }, - "value" - ); - - expect(result).toBe(6); + ` + ) + .expectToMatchJsResult(); }); test("Export Default Function", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import defaultExport from "./module"; - export const value = defaultExport(); - `, - "module.ts": ` + const mainCode = ` + import defaultExport from "./module"; + export const value = defaultExport(); + `; + util.testModule(mainCode) + .addExtraFile( + "module.ts", + ` export default function() { return true; } - `, - }, - "value" - ); - - expect(result).toBe(true); + ` + ) + .expectToMatchJsResult(); }); test("Export Equals", () => { - const [result] = util.transpileAndExecuteProjectReturningMainExport( - { - "main.ts": ` - import * as module from "./module"; - export const value = module; - `, - "module.ts": ` - export = true; - `, - }, - "value" - ); - - expect(result).toBe(true); + util.testModule` + export = true; + ` + .setOptions({ module: ts.ModuleKind.CommonJS }) + .expectToMatchJsResult(); }); const reassignmentTestCases = [ @@ -282,25 +258,26 @@ export const foo = "bar"; `; test("export all does not include default", () => { - util.testBundle` + util.testModule` export * from "./module"; ` + .setOptions({ module: ts.ModuleKind.CommonJS }) .addExtraFile("module.ts", moduleFile) - .expectToEqual({ foo: "bar" }); + .expectToMatchJsResult(); }); test("namespace export does not include default", () => { - util.testBundle` + util.testModule` export * as result from "./module"; ` .addExtraFile("module.ts", moduleFile) - .expectToEqual({ result: { default: true, foo: "bar" } }); + .expectToMatchJsResult(); }); test("namespace export with unsafe Lua name", () => { - util.testBundle` + util.testModule` export * as $$$ from "./module"; ` .addExtraFile("module.ts", moduleFile) - .expectToEqual({ $$$: { default: true, foo: "bar" } }); + .expectToMatchJsResult(); }); diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 159fb8534..762152d67 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -11,14 +11,9 @@ test("legacy internal module syntax", () => { }); test("global scoping", () => { - const result = util.transpileAndExecute( - "return a.foo();", - undefined, - undefined, - 'namespace a { export function foo() { return "bar"; } }' - ); - - expect(result).toBe("bar"); + util.testFunction("return a.foo();") + .setTsHeader('namespace a { export function foo() { return "bar"; } }') + .expectToMatchJsResult(); }); test("nested namespace", () => { @@ -94,7 +89,7 @@ test("namespace merging across files", () => { } `; - util.testBundle` + util.testModule` import './a'; import './b'; @@ -102,7 +97,7 @@ test("namespace merging across files", () => { ` .addExtraFile("a.ts", a) .addExtraFile("b.ts", b) - .expectToEqual({ result: { foo: "foo", bar: "bar" } }); + .expectToMatchJsResult(); }); test("declared namespace function call", () => { diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index f911eeb2f..d18daa000 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -1,8 +1,8 @@ import * as util from "../util"; test("overload function1", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -11,15 +11,13 @@ test("overload function1", () => { return def; } } - return abc(3);` - ); - - expect(result).toBe("jkl9"); + return abc(3); + `.expectToMatchJsResult(); }); test("overload function2", () => { - const result = util.transpileAndExecute( - `function abc(def: number): string; + util.testFunction` + function abc(def: number): string; function abc(def: string): string; function abc(def: number | string): string { if (typeof def == "number") { @@ -28,15 +26,13 @@ test("overload function2", () => { return def; } } - return abc("ghj");` - ); - - expect(result).toBe("ghj"); + return abc("ghj"); + `.expectToMatchJsResult(); }); test("overload method1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -47,15 +43,13 @@ test("overload method1", () => { } } } - return myclass.abc(3);` - ); - - expect(result).toBe("jkl9"); + return myclass.abc(3); + `.expectToMatchJsResult(); }); test("overload method2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { static abc(def: number): string; static abc(def: string): string; static abc(def: number | string): string { @@ -66,15 +60,13 @@ test("overload method2", () => { } } } - return myclass.abc("ghj");` - ); - - expect(result).toBe("ghj"); + return myclass.abc("ghj"); + `.expectToMatchJsResult(); }); test("constructor1", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -89,15 +81,13 @@ test("constructor1", () => { } } const inst = new myclass(3); - return inst.num` - ); - - expect(result).toBe(3); + return inst.num; + `.expectToMatchJsResult(); }); test("constructor2", () => { - const result = util.transpileAndExecute( - `class myclass { + util.testFunction` + class myclass { num: number; str: string; @@ -112,8 +102,6 @@ test("constructor2", () => { } } const inst = new myclass("ghj"); - return inst.str` - ); - - expect(result).toBe("ghj"); + return inst.str + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/deadCodeAfterReturn.spec.ts b/test/unit/printer/deadCodeAfterReturn.spec.ts index 0ccead50e..fba16387a 100644 --- a/test/unit/printer/deadCodeAfterReturn.spec.ts +++ b/test/unit/printer/deadCodeAfterReturn.spec.ts @@ -37,25 +37,25 @@ test("Method dead code after return", () => { }); test("for dead code after return", () => { - const result = util.transpileAndExecute("for (let i = 0; i < 10; i++) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let i = 0; i < 10; i++) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..in dead code after return", () => { - const result = util.transpileAndExecute('for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; }'); - - expect(result).toBe(3); + util.testFunction` + for (let a in {"a": 5, "b": 8}) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("for..of dead code after return", () => { - const result = util.transpileAndExecute("for (let a of [1,2,4]) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + for (let a of [1,2,4]) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); test("while dead code after return", () => { - const result = util.transpileAndExecute("while (true) { return 3; const b = 8; }"); - - expect(result).toBe(3); + util.testFunction` + while (true) { return 3; const b = 8; } + `.expectToMatchJsResult(); }); diff --git a/test/unit/printer/parenthesis.spec.ts b/test/unit/printer/parenthesis.spec.ts index ef08a6e3d..6c8e58156 100644 --- a/test/unit/printer/parenthesis.spec.ts +++ b/test/unit/printer/parenthesis.spec.ts @@ -1,7 +1,7 @@ import * as util from "../../util"; test("binary expression with 'as' type assertion wrapped in parenthesis", () => { - expect(util.transpileAndExecute("return 2 * (3 - 2 as number);")).toBe(2); + util.testFunction("return 2 * (3 - 2 as number);").expectToMatchJsResult(); }); test.each([ @@ -26,7 +26,7 @@ test.each([ declare function z(this: void): unknown; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).not.toMatch(/\(.+\)/); }); @@ -50,15 +50,14 @@ test.each([ declare let y: {}; ${expression}`; - const lua = util.transpileString(code, undefined, false); + const lua = util.testExpression(code).getMainLuaCodeChunk(); expect(lua).toMatch(/\(.+\)/); }); test("not operator precedence (%p)", () => { - const code = ` + util.testFunction` const a = true; const b = false; - return !a && b;`; - - expect(util.transpileAndExecute(code)).toBe(false); + return !a && b; + `.expectToMatchJsResult(); }); diff --git a/test/util.ts b/test/util.ts index 7be98e727..8cc36f6ca 100644 --- a/test/util.ts +++ b/test/util.ts @@ -10,7 +10,8 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -export * from "./legacy-utils"; +const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -41,76 +42,6 @@ export function testEachVersion( } } -function executeLua(code: string): any { - const L = lauxlib.luaL_newstate(); - lualib.luaL_openlibs(L); - const status = lauxlib.luaL_dostring(L, to_luastring(code)); - - if (status === lua.LUA_OK) { - if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); - return result === null ? undefined : result; - } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); - throw new Error(`Unsupported Lua return type: ${returnType}`); - } - } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "--\.\.\."\]:\d+: /, ""); - return new ExecutionError(message); - } -} - -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -export function executeLuaModule(code: string): any { - const lualibImport = code.includes('require("lualib_bundle")') - ? `package.preload.lualib_bundle = function()\n${lualibContent}\nend` - : ""; - - return executeLua(`${minimalTestLib}\n${lualibImport}\nreturn JSONStringify((function()\n${code}\nend)())`); -} - -function executeJsModule(code: string): any { - const exports = {}; - const context = vm.createContext({ exports, module: { exports } }); - context.global = context; - let result: unknown; - try { - result = vm.runInContext(code, context); - } catch (error) { - return new ExecutionError(error.message); - } - - function transform(currentValue: any): any { - if (currentValue === null) { - return undefined; - } - - if (Array.isArray(currentValue)) { - return currentValue.map(transform); - } - - if (typeof currentValue === "object") { - for (const [key, value] of Object.entries(currentValue)) { - currentValue[key] = transform(value); - if (currentValue[key] === undefined) { - delete currentValue[key]; - } - } - - if (Object.keys(currentValue).length === 0) { - return []; - } - } - - return currentValue; - } - - return transform(result); -} - const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); @@ -162,7 +93,7 @@ export abstract class TestBuilder { return this; } - protected abstract getLuaCodeWithWrapper: (code: string) => string; + protected abstract getLuaCodeWithWrapper(code: string): string; public setLuaFactory(luaFactory: (code: string) => string): this { expect(this.hasProgram).toBe(false); this.getLuaCodeWithWrapper = luaFactory; @@ -200,7 +131,7 @@ export abstract class TestBuilder { return this; } - private extraFiles: Record = {}; + protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { expect(this.hasProgram).toBe(false); this.extraFiles[fileName] = code; @@ -263,7 +194,7 @@ export abstract class TestBuilder { @memoize public getLuaExecutionResult(): any { - return executeLuaModule(this.getLuaCodeWithWrapper(this.getMainLuaCodeChunk())); + return this.executeLua(); } @memoize @@ -277,7 +208,7 @@ export abstract class TestBuilder { } @memoize - protected getMainJsCodeChunk(): string { + public getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) ?.js; @@ -291,7 +222,7 @@ export abstract class TestBuilder { @memoize public getJsExecutionResult(): any { - return executeJsModule(this.getJsCodeWithWrapper()); + return this.executeJs(); } // Utilities @@ -345,9 +276,19 @@ export abstract class TestBuilder { return this; } + private expectNoJsExecutionError(): this { + const jsResult = this.getJsExecutionResult(); + if (jsResult instanceof ExecutionError) { + throw jsResult; + } + + return this; + } + public expectToMatchJsResult(allowErrors = false): this { this.expectToHaveNoDiagnostics(); if (!allowErrors) this.expectNoExecutionError(); + if (!allowErrors) this.expectNoJsExecutionError(); const luaResult = this.getLuaExecutionResult(); const jsResult = this.getJsExecutionResult(); @@ -389,12 +330,148 @@ export abstract class TestBuilder { callback(this); return this; } + + private executeLua(): any { + // Main file + const mainFile = this.getMainLuaCodeChunk(); + + const L = lauxlib.luaL_newstate(); + lualib.luaL_openlibs(L); + + // Load modules + // Json + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(minimalTestLib)); + lua.lua_setfield(L, -2, "json"); + // Lua lib + if ( + this.options.luaLibImport === tstl.LuaLibImportKind.Require || + mainFile.includes('require("lualib_bundle")') + ) { + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(lualibContent)); + lua.lua_setfield(L, -2, "lualib_bundle"); + } + + // Extra files + const { transpiledFiles } = this.getLuaResult(); + + Object.keys(this.extraFiles).forEach(fileName => { + const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === fileName) + ); + if (transpiledExtraFile?.lua) { + lua.lua_getglobal(L, "package"); + lua.lua_getfield(L, -1, "preload"); + lauxlib.luaL_loadstring(L, to_luastring(transpiledExtraFile.lua)); + lua.lua_setfield(L, -2, fileName.replace(".ts", "")); + } + }); + + // Execute Main + const wrappedMainCode = ` +local JSON = require("json"); +return JSON.stringify((function() + ${this.getLuaCodeWithWrapper(mainFile)} +end)());`; + + const status = lauxlib.luaL_dostring(L, to_luastring(wrappedMainCode)); + + if (status === lua.LUA_OK) { + if (lua.lua_isstring(L, -1)) { + const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + return result === null ? undefined : result; + } else { + const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + throw new Error(`Unsupported Lua return type: ${returnType}`); + } + } else { + // Filter out control characters appearing on some systems + const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); + const message = to_jsstring(luaStackString).replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + return new ExecutionError(message); + } + } + + private executeJs(): any { + const { transpiledFiles } = this.getJsResult(); + // Custom require for extra files. Really basic. Global support is hacky + // TODO Should be replaced with vm.Module https://nodejs.org/api/vm.html#vm_class_vm_module + // once stable + const globalContext: any = {}; + const mainExports = {}; + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + globalContext.require = (fileName: string) => { + // create clean export object for "module" + const moduleExports = {}; + globalContext.exports = moduleExports; + globalContext.module = { exports: moduleExports }; + const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === fileName.replace("./", "") + ".ts") + ); + + if (transpiledExtraFile?.js) { + vm.runInContext(transpiledExtraFile.js, globalContext); + } + + // Have to return globalContext.module.exports + // becuase module.exports might no longer be equal to moduleExports (export assignment) + const result = globalContext.module.exports; + // Reset module/export + globalContext.exports = mainExports; + globalContext.module = { exports: mainExports }; + return result; + }; + + vm.createContext(globalContext); + + let result: unknown; + try { + result = vm.runInContext(this.getJsCodeWithWrapper(), globalContext); + } catch (error) { + return new ExecutionError(error.message); + } + + function removeUndefinedFields(obj: any): any { + if (obj === null) { + return undefined; + } + + if (Array.isArray(obj)) { + return obj.map(removeUndefinedFields); + } + + if (typeof obj === "object") { + const copy: any = {}; + for (const [key, value] of Object.entries(obj)) { + if (obj[key] !== undefined) { + copy[key] = removeUndefinedFields(value); + } + } + + if (Object.keys(copy).length === 0) { + return []; + } + + return copy; + } + + return obj; + } + + return removeUndefinedFields(result); + } } class AccessorTestBuilder extends TestBuilder { protected accessor = ""; - protected getLuaCodeWithWrapper = (code: string) => `return (function()\n${code}\nend)()${this.accessor}`; + protected getLuaCodeWithWrapper(code: string) { + return `return (function()\n${code}\nend)()${this.accessor}`; + } @memoize protected getJsCodeWithWrapper(): string { @@ -420,7 +497,6 @@ class ModuleTestBuilder extends AccessorTestBuilder { return this; } } - class FunctionTestBuilder extends AccessorTestBuilder { protected accessor = ".__main()"; public getTsCode(): string { From 2766de134c526916380f31a55043e8487cd67bfc Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:05:27 +0000 Subject: [PATCH 317/764] $range language extension (#979) * added $range language extension * addressing feedback * fixed mis-named range spec and test which were actually broken * checking for $range function based on symbol instead of type to reduce redundant diagnostics * deprecated @forRange annotation and fixed some tabs Co-authored-by: Tom --- language-extensions/index.d.ts | 10 +++ src/lualib/ArrayIncludes.ts | 2 +- src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/DelegatedYield.ts | 2 +- src/lualib/declarations/tstl.d.ts | 3 - src/transformation/utils/diagnostics.ts | 6 ++ .../utils/language-extensions.ts | 13 ++- src/transformation/visitors/identifier.ts | 13 ++- .../visitors/language-extensions/range.ts | 53 +++++++++++ src/transformation/visitors/loops/for-of.ts | 9 +- .../__snapshots__/deprecated.spec.ts.snap | 7 ++ test/unit/annotations/deprecated.spec.ts | 10 ++- test/unit/annotations/forRange.spec.ts | 31 +++++-- .../__snapshots__/range.spec.ts.snap | 88 +++++++++++++++++++ test/unit/language-extensions/range.spec.ts | 68 ++++++++++++++ 17 files changed, 299 insertions(+), 22 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/range.ts create mode 100644 test/unit/language-extensions/__snapshots__/range.spec.ts.snap create mode 100644 test/unit/language-extensions/range.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 87a7f1395..437db5a85 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,6 +1,16 @@ declare function $multi(...values: T): MultiReturn; declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; +/** + * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param start The first number in the sequence to iterate over. + * @param limit The last number in the sequence to iterate over. + * @param step The amount to increment each iteration. + */ +declare function $range(start: number, limit: number, step?: number): Iterable; + /** * Calls to functions with this type are translated to `left + right`. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts index a9ff19ba4..b012f87bf 100644 --- a/src/lualib/ArrayIncludes.ts +++ b/src/lualib/ArrayIncludes.ts @@ -11,7 +11,7 @@ function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boo k = 0; } - for (const i of forRange(k, len)) { + for (const i of $range(k, len)) { if (this[i] === searchElement) { return true; } diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 8dda6ebd5..edb6825e6 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -20,7 +20,7 @@ function __TS__ArrayReduce( throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, len - 1)) { + for (const i of $range(k, len - 1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index a57f78697..8e5336f61 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -20,7 +20,7 @@ function __TS__ArrayReduceRight( throw "Reduce of empty array with no initial value"; } - for (const i of forRange(k, 0, -1)) { + for (const i of $range(k, 0, -1)) { accumulator = callbackFn(accumulator, arr[i], i, arr); } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 5df67938f..1b0bf9cff 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -66,7 +66,7 @@ function __TS__ArraySplice(this: void, list: T[], ...args: Vararg) } let j = actualStart; - for (const i of forRange(3, actualArgumentCount)) { + for (const i of $range(3, actualArgumentCount)) { list[j] = select(i, ...args) as T; j++; } diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts index 6b524365a..ab47d02d8 100644 --- a/src/lualib/DelegatedYield.ts +++ b/src/lualib/DelegatedYield.ts @@ -1,6 +1,6 @@ function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { if (typeof iterable === "string") { - for (const index of forRange(0, iterable.length - 1)) { + for (const index of $range(0, iterable.length - 1)) { coroutine.yield(iterable[index]); } } else if ("____coroutine" in iterable) { diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 57e436ae3..4a718a31a 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -3,9 +3,6 @@ /** @vararg */ type Vararg = T & { __luaVararg?: never }; -/** @forRange */ -declare function forRange(start: number, limit: number, step?: number): number[]; - interface Metatable { _descriptors?: Record; __index?: any; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8cd721421..79f21528e 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -86,6 +86,12 @@ export const invalidForRangeCall = createErrorDiagnosticFactory( (message: string) => `Invalid @forRange call: ${message}.` ); +export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); + +export const invalidRangeControlVariable = createErrorDiagnosticFactory( + "For loop using $range must declare a single control variable." +); + export const luaTableMustBeAmbient = createErrorDiagnosticFactory( "Classes with the '@luaTable' annotation must be ambient." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 6838d6b55..b260d9fae 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -4,6 +4,7 @@ import * as path from "path"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", + RangeFunction = "RangeFunction", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -42,6 +43,11 @@ export enum ExtensionKind { LengthOperatorMethodType = "LengthOperatorMethodType", } +const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { + $multi: ExtensionKind.MultiFunction, + $range: ExtensionKind.RangeFunction, +}; + const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { MultiReturn: ExtensionKind.MultiType, LuaAddition: ExtensionKind.AdditionOperatorType, @@ -91,8 +97,11 @@ function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { const sourceFile = declaration.getSourceFile(); if (isSourceFileFromLanguageExtensions(sourceFile)) { - if (ts.isFunctionDeclaration(declaration) && declaration?.name?.text === "$multi") { - return ExtensionKind.MultiFunction; + if (ts.isFunctionDeclaration(declaration) && declaration.name?.text) { + const extensionKind = functionNameToExtensionKind[declaration.name.text]; + if (extensionKind) { + return extensionKind; + } } if (ts.isTypeAliasDeclaration(declaration)) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index dd69699b3..e872e841e 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -3,13 +3,19 @@ import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { isForRangeType } from "../utils/annotations"; -import { invalidForRangeCall, invalidMultiFunctionUse, invalidOperatorMappingUse } from "../utils/diagnostics"; +import { + invalidForRangeCall, + invalidMultiFunctionUse, + invalidOperatorMappingUse, + invalidRangeUse, +} from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { findFirstNodeAbove } from "../utils/typescript"; import { isMultiFunctionNode } from "./language-extensions/multi"; import { isOperatorMapping } from "./language-extensions/operators"; +import { isRangeFunctionNode } from "./language-extensions/range"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -21,6 +27,11 @@ export function transformIdentifier(context: TransformationContext, identifier: context.diagnostics.push(invalidOperatorMappingUse(identifier)); } + if (isRangeFunctionNode(context, identifier)) { + context.diagnostics.push(invalidRangeUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts new file mode 100644 index 000000000..d68729c3c --- /dev/null +++ b/src/transformation/visitors/language-extensions/range.ts @@ -0,0 +1,53 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding } from "../loops/utils"; +import { transformIdentifier } from "../identifier"; +import { transformArguments } from "../call"; +import { assert } from "../../../utils"; +import { invalidRangeControlVariable } from "../../utils/diagnostics"; + +const isRangeFunctionDeclaration = (declaration: ts.Declaration): boolean => + extensions.getExtensionKind(declaration) === extensions.ExtensionKind.RangeFunction; + +export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { + const type = context.checker.getTypeAtLocation(expression.expression); + return type.symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; +} + +export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; +} + +function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { + if (!ts.isVariableDeclarationList(statement.initializer)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (!ts.isIdentifier(binding)) { + context.diagnostics.push(invalidRangeControlVariable(statement.initializer)); + return; + } + + return transformIdentifier(context, binding); +} + +export function transformRangeStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + assert(ts.isCallExpression(statement.expression)); + const controlVariable = + getControlVariable(context, statement) ?? lua.createAnonymousIdentifier(statement.initializer); + const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( + context, + statement.expression.arguments, + context.checker.getResolvedSignature(statement.expression) + ); + return lua.createForStatement(block, controlVariable, start, limit, step, statement); +} diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 67adb2ca2..047ed3535 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -3,11 +3,12 @@ import * as lua from "../../../LuaAST"; import { assert, cast } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; +import { annotationDeprecated, invalidForRangeCall, luaIteratorForbiddenUsage } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; +import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformArrayBindingElement } from "../variable-declaration"; import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; @@ -18,6 +19,8 @@ function transformForRangeStatement( ): lua.Statement { assert(ts.isCallExpression(statement.expression)); + context.diagnostics.push(annotationDeprecated(statement.expression, AnnotationKind.ForRange)); + const callArguments = statement.expression.arguments; if (callArguments.length !== 2 && callArguments.length !== 3) { context.diagnostics.push( @@ -149,7 +152,9 @@ function transformForOfIteratorStatement( export const transformForOfStatement: FunctionVisitor = (node, context) => { const body = lua.createBlock(transformLoopBody(context, node)); - if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { + if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { + return transformRangeStatement(context, node, body); + } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { return transformForRangeStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { return transformForOfLuaIteratorStatement(context, node, body); diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 956143495..5be0a22b4 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -8,6 +8,13 @@ exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; +exports[`forRange deprecation: code 1`] = ` +"for i = 1, 10 do +end" +`; + +exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; + exports[`phantom deprecation: code 1`] = ` "function nsMember(self) end" diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 488b66a28..4fe836014 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -22,6 +22,14 @@ test("pureAbstract deprecation", () => { util.testModule` /** @pureAbstract */ declare class ClassA {} - class ClassB extends ClassA {} + class ClassB extends ClassA {} + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); + +test("forRange deprecation", () => { + util.testModule` + /** @forRange */ + declare function forRange(start: number, limit: number, step?: number): number[]; + for (const i of forRange(1, 10)) {} `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); }); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts index 661c45253..35dc285b1 100644 --- a/test/unit/annotations/forRange.spec.ts +++ b/test/unit/annotations/forRange.spec.ts @@ -1,4 +1,4 @@ -import { invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; +import { annotationDeprecated, invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` @@ -21,6 +21,7 @@ test.each([ } ` .setReturnExport("results") + .ignoreDiagnostics([annotationDeprecated.code]) .expectToEqual(results); }); @@ -29,14 +30,18 @@ describe("invalid usage", () => { util.testModule` /** @forRange */ function luaRange() {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { util.testModule` ${createForRangeDeclaration("...args: number[]")} for (const i of luaRange(${args})) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("non-declared loop variable", () => { @@ -44,28 +49,36 @@ describe("invalid usage", () => { ${createForRangeDeclaration()} let i: number; for (i of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("argument types", () => { util.testModule` ${createForRangeDeclaration("i: string, j: number")} for (const i of luaRange("foo", 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("variable destructuring", () => { util.testModule` ${createForRangeDeclaration(undefined, "number[][]")} for (const [i] of luaRange(1, 10, 2)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test("return type", () => { util.testModule` ${createForRangeDeclaration(undefined, "string[]")} for (const i of luaRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); test.each([ @@ -78,6 +91,8 @@ describe("invalid usage", () => { util.testModule` ${createForRangeDeclaration()} ${statement} - `.expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); }); }); diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap new file mode 100644 index 000000000..f066c1260 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -0,0 +1,88 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$range invalid control variable: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i + for ____ = 1, 5 do + end +end +return ____exports" +`; + +exports[`$range invalid control variable: diagnostics 1`] = `"main.ts(3,14): error TSTL: For loop using $range must declare a single control variable."`; + +exports[`$range invalid use ("const range = $range;"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local range = ____ +end +return ____exports" +`; + +exports[`$range invalid use ("const range = $range;"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const x = $range(1, 10);"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = ____(nil, 1, 10) +end +return ____exports" +`; + +exports[`$range invalid use ("const x = $range(1, 10);"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local y = { + __TS__Spread( + ____(nil, 1, 10) + ) + } +end +return ____exports" +`; + +exports[`$range invalid use ("const y = [...$range(1, 10)];"): diagnostics 1`] = `"main.ts(2,23): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for i in pairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + for ____, i in ipairs( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + for ____, i in __TS__Iterator( + ____(nil, 1, 10, 2) + ) do + end +end +return ____exports" +`; + +exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): diagnostics 1`] = `"main.ts(2,26): error TSTL: $range can only be used in a for...of loop."`; diff --git a/test/unit/language-extensions/range.spec.ts b/test/unit/language-extensions/range.spec.ts new file mode 100644 index 000000000..56ac65251 --- /dev/null +++ b/test/unit/language-extensions/range.spec.ts @@ -0,0 +1,68 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidRangeControlVariable, invalidRangeUse } from "../../../src/transformation/utils/diagnostics"; + +const rangeProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test("$range basic use", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 5)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([1, 2, 3, 4, 5]); +}); + +test("$range basic use with step", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(1, 10, 2)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([1, 3, 5, 7, 9]); +}); + +test("$range basic use reverse", () => { + util.testFunction` + const result: number[] = []; + for (const i of $range(5, 1, -1)) { + result.push(i); + } + return result; + ` + .setOptions(rangeProjectOptions) + .expectToEqual([5, 4, 3, 2, 1]); +}); + +test("$range invalid control variable", () => { + util.testFunction` + let i: number; + for (i of $range(1, 5)) {} + ` + .setOptions(rangeProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidRangeControlVariable.code]); +}); + +test.each([ + "for (const i in $range(1, 10, 2)) {}", + "const x = $range(1, 10);", + "const range = $range;", + "const y = [...$range(1, 10)];", + "for (const i of ($range(1, 10, 2))) {}", + "for (const i of $range(1, 10, 2) as number[]) {}", +])("$range invalid use (%p)", statement => { + util.testFunction` + ${statement} + ` + .setOptions(rangeProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidRangeUse.code]); +}); From eae12b6c96fc15418d3373b2b51718bf7490fbcd Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 8 Feb 2021 14:06:43 +0000 Subject: [PATCH 318/764] Multi-Return update (#978) * renamed MultiReturn to LuaMultiReturn and added some doc comments * refactored LuaMultiReturn to handle a number of cases it couldn't before * fixed issues found with tests * diagnostic for checking implicit cast from LuaMultiReturn and additional tests * fixed LuaMultiReturn used in assignment expressions * tests for mtulreturn in try/catch * removed unnecessary check in isMultiReturnType * fixed string.find declaration * addressing feedback * snapshot update * renamed multiReturnCallShouldBeWrapped to shouldMultiReturnCallBeWrapped Co-authored-by: Tom --- language-extensions/index.d.ts | 18 +- src/lualib/StringIncludes.ts | 3 +- src/lualib/declarations/string.d.ts | 2 +- src/transformation/utils/diagnostics.ts | 20 +- .../utils/language-extensions.ts | 2 +- .../visitors/binary-expression/assignments.ts | 10 +- src/transformation/visitors/call.ts | 5 +- src/transformation/visitors/errors.ts | 3 +- .../visitors/expression-statement.ts | 10 - src/transformation/visitors/function.ts | 5 - .../visitors/language-extensions/multi.ts | 175 +++++------------- src/transformation/visitors/return.ts | 39 +++- .../visitors/variable-declaration.ts | 14 +- .../__snapshots__/multi.spec.ts.snap | 145 ++++++++++++--- test/unit/language-extensions/multi.spec.ts | 124 ++++++++++++- 15 files changed, 356 insertions(+), 219 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 437db5a85..033012960 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,5 +1,19 @@ -declare function $multi(...values: T): MultiReturn; -declare type MultiReturn = T & { readonly " __multiBrand": unique symbol }; +/** + * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + * @param values Return values. + */ +declare function $multi(...values: T): LuaMultiReturn; + +/** + * Represents multiple return values as a tuple. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param T A tuple type with each element type representing a return value's type. + */ +declare type LuaMultiReturn = T & { readonly __luaMultiReturnBrand: unique symbol }; /** * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts index cba5bf15f..7508a2a42 100644 --- a/src/lualib/StringIncludes.ts +++ b/src/lualib/StringIncludes.ts @@ -5,5 +5,6 @@ function __TS__StringIncludes(this: string, searchString: string, position?: num } else { position += 1; } - return string.find(this, searchString, position, true) !== undefined; + const [index] = string.find(this, searchString, position, true); + return index !== undefined; } diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts index 778257d7f..ed5aa27e5 100644 --- a/src/lualib/declarations/string.d.ts +++ b/src/lualib/declarations/string.d.ts @@ -19,5 +19,5 @@ declare namespace string { pattern: string, start?: number, plainflag?: boolean - ): MultiReturn<[number, number]> | undefined; + ): LuaMultiReturn<[number, number] | [undefined]>; } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 79f21528e..76e8b4632 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -149,11 +149,11 @@ export const unsupportedVarDeclaration = createErrorDiagnosticFactory( ); export const invalidMultiFunctionUse = createErrorDiagnosticFactory( - "The $multi function must be called in an expression that is returned." + "The $multi function must be called in a return statement." ); -export const invalidMultiTypeToNonArrayBindingPattern = createErrorDiagnosticFactory( - "Expected an array destructuring pattern." +export const invalidMultiFunctionReturnType = createErrorDiagnosticFactory( + "The $multi function cannot be cast to a non-LuaMultiReturn type." ); export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); @@ -162,20 +162,8 @@ export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosti "There must be one or more elements specified here." ); -export const invalidMultiTypeArrayBindingPatternElementInitializer = createErrorDiagnosticFactory( - "This array binding pattern cannot have initializers." -); - -export const invalidMultiTypeArrayLiteralElementInitializer = createErrorDiagnosticFactory( - "This array literal pattern cannot have initializers." -); - export const invalidMultiReturnAccess = createErrorDiagnosticFactory( - "The MultiReturn type can only be accessed via an element access expression of a numeric type." -); - -export const unsupportedMultiFunctionAssignment = createErrorDiagnosticFactory( - "Omitted expressions and BindingElements are expected here." + "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); export const invalidOperatorMappingUse = createErrorDiagnosticFactory( diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index b260d9fae..391993f8a 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -49,7 +49,7 @@ const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { }; const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { - MultiReturn: ExtensionKind.MultiType, + LuaMultiReturn: ExtensionKind.MultiType, LuaAddition: ExtensionKind.AdditionOperatorType, LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, LuaSubtraction: ExtensionKind.SubtractionOperatorType, diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 94e17e9c7..df99a2a7d 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -11,6 +11,7 @@ import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; +import { isMultiReturnCall } from "../language-extensions/multi"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -91,7 +92,7 @@ export function transformAssignmentExpression( const rootIdentifier = lua.createAnonymousIdentifier(expression.left); let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } @@ -184,7 +185,10 @@ export function transformAssignmentStatement( const rightType = context.checker.getTypeAtLocation(expression.right); let right = context.transformExpression(expression.right); - if (!isTupleReturnCall(context, expression.right) && isArrayType(context, rightType)) { + if ( + !(isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) && + isArrayType(context, rightType) + ) { right = createUnpackCall(context, right, expression.right); } @@ -194,7 +198,7 @@ export function transformAssignmentStatement( } let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right)) { + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 20583d007..f29cbd4e9 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -11,7 +11,7 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; -import { returnsMultiType } from "./language-extensions/multi"; +import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -201,8 +201,9 @@ export const transformCallExpression: FunctionVisitor = (node node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); const isInSpread = node.parent && ts.isSpreadElement(node.parent); const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); - const wrapResult = + const wrapTupleReturn = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; + const wrapResult = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); const builtinResult = transformBuiltinCallExpression(context, node); if (builtinResult) { diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 6d683c475..e05ed55f3 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -6,6 +6,7 @@ import { createUnpackCall } from "../utils/lua-ast"; import { findScope, ScopeType } from "../utils/scope"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; +import { isInMultiReturnFunction } from "./language-extensions/multi"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); @@ -88,7 +89,7 @@ export const transformTryStatement: FunctionVisitor = (statemen returnValues.push(lua.createBooleanLiteral(true)); } - if (isInTupleReturnFunction(context, statement)) { + if (isInTupleReturnFunction(context, statement) || isInMultiReturnFunction(context, statement)) { returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); } else { returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 4901a3210..890695be0 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -4,18 +4,8 @@ import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; -import { returnsMultiType, transformMultiDestructuringAssignmentStatement } from "./language-extensions/multi"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - if ( - ts.isBinaryExpression(node.expression) && - node.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && - ts.isCallExpression(node.expression.right) && - returnsMultiType(context, node.expression.right) - ) { - return transformMultiDestructuringAssignmentStatement(context, node); - } - const luaTableResult = transformLuaTableExpressionStatement(context, node); if (luaTableResult) { return luaTableResult; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 424e75efe..d3fb88a5a 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -15,7 +15,6 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { transformIdentifier } from "./identifier"; -import { isMultiFunction, transformMultiCallExpressionToReturnStatement } from "./language-extensions/multi"; import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; @@ -56,10 +55,6 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { - if (ts.isCallExpression(body) && isMultiFunction(context, body)) { - return [transformMultiCallExpressionToReturnStatement(context, body)]; - } - const returnStatement = transformExpressionBodyToReturnStatement(context, body); return [returnStatement]; } diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index a6cb2a755..8ddb54c83 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -1,22 +1,8 @@ import * as ts from "typescript"; -import * as lua from "../../../LuaAST"; import * as extensions from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { transformAssignmentLeftHandSideExpression } from "../binary-expression/assignments"; -import { transformIdentifier } from "../identifier"; -import { transformArguments } from "../call"; -import { getDependenciesOfSymbol, createExportedIdentifier } from "../../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration } from "../../utils/lua-ast"; -import { - invalidMultiTypeArrayBindingPatternElementInitializer, - invalidMultiTypeArrayLiteralElementInitializer, - invalidMultiTypeToEmptyPatternOrArrayLiteral, - invalidMultiTypeToNonArrayBindingPattern, - invalidMultiTypeToNonArrayLiteral, - unsupportedMultiFunctionAssignment, - invalidMultiFunctionUse, -} from "../../utils/diagnostics"; -import { assert } from "../../../utils"; +import { invalidMultiFunctionUse } from "../../utils/diagnostics"; +import { findFirstNodeAbove } from "../../utils/typescript"; const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; @@ -24,14 +10,23 @@ const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; -export function isMultiFunction(context: TransformationContext, expression: ts.CallExpression): boolean { +export function isMultiReturnType(type: ts.Type): boolean { + return type.aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; +} + +export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { const type = context.checker.getTypeAtLocation(expression.expression); return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; } export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { const signature = context.checker.getResolvedSignature(node); - return signature?.getReturnType().aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; +} + +export function isMultiReturnCall(context: TransformationContext, expression: ts.Expression) { + return ts.isCallExpression(expression) && returnsMultiType(context, expression); } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { @@ -39,131 +34,59 @@ export function isMultiFunctionNode(context: TransformationContext, node: ts.Nod return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; } -export function transformMultiCallExpressionToReturnStatement( - context: TransformationContext, - expression: ts.Expression -): lua.Statement { - assert(ts.isCallExpression(expression)); - - const expressions = transformArguments(context, expression.arguments); - return lua.createReturnStatement(expressions, expression); -} - -export function transformMultiReturnStatement( - context: TransformationContext, - statement: ts.ReturnStatement -): lua.Statement { - assert(statement.expression); - - return transformMultiCallExpressionToReturnStatement(context, statement.expression); -} - -function transformMultiFunctionArguments( - context: TransformationContext, - expression: ts.CallExpression -): lua.Expression[] | lua.Expression { - if (!isMultiFunction(context, expression)) { - return context.transformExpression(expression); - } - - if (expression.arguments.length === 0) { - return lua.createNilLiteral(expression); +export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; } - - return expression.arguments.map(e => context.transformExpression(e)); + const signature = context.checker.getSignatureFromDeclaration(declaration); + const type = signature?.getReturnType(); + return type ? isMultiReturnType(type) : false; } -export function transformMultiVariableDeclaration( - context: TransformationContext, - declaration: ts.VariableDeclaration -): lua.Statement[] { - assert(declaration.initializer); - assert(ts.isCallExpression(declaration.initializer)); - - if (!ts.isArrayBindingPattern(declaration.name)) { - context.diagnostics.push(invalidMultiTypeToNonArrayBindingPattern(declaration.name)); - return []; +export function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression) { + if (!returnsMultiType(context, node)) { + return false; } - if (declaration.name.elements.length < 1) { - context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(declaration.name)); - return []; + // Variable declaration with destructuring + if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + return false; } - if (declaration.name.elements.some(e => ts.isBindingElement(e) && e.initializer)) { - context.diagnostics.push(invalidMultiTypeArrayBindingPatternElementInitializer(declaration.name)); - return []; + // Variable assignment with destructuring + if ( + ts.isBinaryExpression(node.parent) && + node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(node.parent.left) + ) { + return false; } - if (isMultiFunction(context, declaration.initializer)) { - context.diagnostics.push(invalidMultiFunctionUse(declaration.initializer)); - return []; + // Spread operator + if (ts.isSpreadElement(node.parent)) { + return false; } - const leftIdentifiers: lua.Identifier[] = []; - - for (const element of declaration.name.elements) { - if (ts.isBindingElement(element)) { - if (ts.isIdentifier(element.name)) { - leftIdentifiers.push(transformIdentifier(context, element.name)); - } else { - context.diagnostics.push(unsupportedMultiFunctionAssignment(element)); - } - } else if (ts.isOmittedExpression(element)) { - leftIdentifiers.push(lua.createAnonymousIdentifier(element)); - } + // Stand-alone expression + if (ts.isExpressionStatement(node.parent)) { + return false; } - const rightExpressions = transformMultiFunctionArguments(context, declaration.initializer); - return createLocalOrExportedOrGlobalDeclaration(context, leftIdentifiers, rightExpressions, declaration); -} - -export function transformMultiDestructuringAssignmentStatement( - context: TransformationContext, - statement: ts.ExpressionStatement -): lua.Statement[] | undefined { - assert(ts.isBinaryExpression(statement.expression)); - assert(ts.isCallExpression(statement.expression.right)); - - if (!ts.isArrayLiteralExpression(statement.expression.left)) { - context.diagnostics.push(invalidMultiTypeToNonArrayLiteral(statement.expression.left)); - return []; + // Forwarded multi-return call + if ( + (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + isInMultiReturnFunction(context, node) + ) { + return false; } - if (statement.expression.left.elements.some(ts.isBinaryExpression)) { - context.diagnostics.push(invalidMultiTypeArrayLiteralElementInitializer(statement.expression.left)); - return []; + // Element access expression 'foo()[0]' will be optimized using 'select' + if (ts.isElementAccessExpression(node.parent)) { + return false; } - if (statement.expression.left.elements.length < 1) { - context.diagnostics.push(invalidMultiTypeToEmptyPatternOrArrayLiteral(statement.expression.left)); - return []; - } - - if (isMultiFunction(context, statement.expression.right)) { - context.diagnostics.push(invalidMultiFunctionUse(statement.expression.right)); - return []; - } - - const transformLeft = (expression: ts.Expression): lua.AssignmentLeftHandSideExpression => - ts.isOmittedExpression(expression) - ? lua.createAnonymousIdentifier(expression) - : transformAssignmentLeftHandSideExpression(context, expression); - - const leftIdentifiers = statement.expression.left.elements.map(transformLeft); - - const rightExpressions = transformMultiFunctionArguments(context, statement.expression.right); - - const trailingStatements = statement.expression.left.elements.flatMap(expression => { - const symbol = context.checker.getSymbolAtLocation(expression); - const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; - return dependentSymbols.map(symbol => { - const identifierToAssign = createExportedIdentifier(context, lua.createIdentifier(symbol.name)); - return lua.createAssignmentStatement(identifierToAssign, transformLeft(expression)); - }); - }); - - return [lua.createAssignmentStatement(leftIdentifiers, rightExpressions, statement), ...trailingStatements]; + return true; } export function findMultiAssignmentViolations( diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index c13d571ff..7e7a7ddf8 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -6,13 +6,42 @@ import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; -import { isMultiFunction, transformMultiReturnStatement } from "./language-extensions/multi"; +import { transformArguments } from "./call"; +import { + returnsMultiType, + shouldMultiReturnCallBeWrapped, + isMultiFunctionCall, + isMultiReturnType, +} from "./language-extensions/multi"; +import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; function transformExpressionsInReturn( context: TransformationContext, node: ts.Expression, insideTryCatch: boolean ): lua.Expression[] { + if (ts.isCallExpression(node)) { + // $multi(...) + if (isMultiFunctionCall(context, node)) { + // Don't allow $multi to be implicitly cast to something other than LuaMultiReturn + const type = context.checker.getContextualType(node); + if (type && !isMultiReturnType(type)) { + context.diagnostics.push(invalidMultiFunctionReturnType(node)); + } + + let returnValues = transformArguments(context, node.arguments); + if (insideTryCatch) { + returnValues = [wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch + } + return returnValues; + } + + // Force-wrap LuaMultiReturn when returning inside try/catch + if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { + return [wrapInTable(context.transformExpression(node))]; + } + } + if (!isInTupleReturnFunction(context, node)) { return [context.transformExpression(node)]; } @@ -60,14 +89,6 @@ export const transformReturnStatement: FunctionVisitor = (st insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; } - if ( - statement.expression && - ts.isCallExpression(statement.expression) && - isMultiFunction(context, statement.expression) - ) { - return transformMultiReturnStatement(context, statement); - } - let results: lua.Expression[]; if (statement.expression) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 6ddd4acdc..12f6717c4 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -9,8 +9,8 @@ import { addExportToIdentifier } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; +import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; -import { returnsMultiType, transformMultiVariableDeclaration } from "./language-extensions/multi"; export function transformArrayBindingElement( context: TransformationContext, @@ -173,8 +173,8 @@ export function transformBindingVariableDeclaration( : lua.createAnonymousIdentifier(); if (initializer) { - if (isTupleReturnCall(context, initializer)) { - // Don't unpack @tupleReturn annotated functions + if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + // Don't unpack @tupleReturn or LuaMultiReturn functions statements.push( ...createLocalOrExportedOrGlobalDeclaration( context, @@ -230,14 +230,6 @@ export function transformVariableDeclaration( context: TransformationContext, statement: ts.VariableDeclaration ): lua.Statement[] { - if ( - statement.initializer && - ts.isCallExpression(statement.initializer) && - returnsMultiType(context, statement.initializer) - ) { - return transformMultiVariableDeclaration(context, statement); - } - if (statement.initializer && statement.type) { const initializerType = context.checker.getTypeAtLocation(statement.initializer); const varType = context.checker.getTypeFromTypeNode(statement.type); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index b745edf27..a280fe331 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`disallow MultiReturn non-numeric access: code 1`] = ` +exports[`disallow LuaMultiReturn non-numeric access: code 1`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) @@ -15,56 +15,113 @@ end return ____exports" `; -exports[`disallow MultiReturn non-numeric access: code 2`] = ` +exports[`disallow LuaMultiReturn non-numeric access: code 2`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) local args = {...} return table.unpack(args) end - return multi(nil).forEach + return ({ + multi(nil) + }).forEach end return ____exports" `; -exports[`disallow MultiReturn non-numeric access: diagnostics 1`] = `"main.ts(7,16): error TSTL: The MultiReturn type can only be accessed via an element access expression of a numeric type."`; +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 1`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; -exports[`disallow MultiReturn non-numeric access: diagnostics 2`] = `"main.ts(7,16): error TSTL: The MultiReturn type can only be accessed via an element access expression of a numeric type."`; +exports[`disallow LuaMultiReturn non-numeric access: diagnostics 2`] = `"main.ts(7,16): error TSTL: The LuaMultiReturn type can only be accessed via an element access expression of a numeric type."`; exports[`invalid $multi call ($multi()): code 1`] = `"____(_G)"`; -exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call ($multi()): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call ($multi): code 1`] = `"local ____ = ____"`; -exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` "local function ____(____, ____bindingPattern0) if ____bindingPattern0 == nil then - ____bindingPattern0 = ____(_G, 1) + ____bindingPattern0 = { + ____(_G, 1) + } end local a = ____bindingPattern0[1] end" `; -exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; -exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = ` +"a = ____(_G) +if a == nil then + a = 0 +end" +`; + +exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const {} = $multi();): code 1`] = ` +"local ____ = { + ____(_G) +}" +`; + +exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid $multi call (const a = $multi();): code 1`] = ` +"a = { + ____(_G) +}" +`; + +exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,19): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const [a = 0] = $multi()): code 1`] = `""`; +exports[`invalid $multi implicit cast: code 1`] = ` +"function badMulti(self) + return \\"foo\\", 42 +end" +`; -exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,15): error TSTL: This array binding pattern cannot have initializers."`; +exports[`invalid $multi implicit cast: diagnostics 1`] = `"main.ts(3,20): error TSTL: The $multi function cannot be cast to a non-LuaMultiReturn type."`; -exports[`invalid $multi call (const {} = $multi();): code 1`] = `""`; +exports[`invalid direct $multi function use (const [a = 1] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a = ____(nil) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; -exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; +exports[`invalid direct $multi function use (const [a = 1] = $multi()): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const a = $multi();): code 1`] = `""`; +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a = ____(nil, 2) +if a == nil then + a = 1 +end +____exports.a = a +return ____exports" +`; -exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,15): error TSTL: Expected an array destructuring pattern."`; +exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): diagnostics 1`] = `"main.ts(7,25): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` "local ____exports = {} @@ -72,11 +129,12 @@ local function multi(self, ...) local args = {...} return table.unpack(args) end +local a = ____(nil) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` "local ____exports = {} @@ -84,11 +142,12 @@ local function multi(self, ...) local args = {...} return table.unpack(args) end +local a = ____(nil, 1) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,21): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` "local ____exports = {} @@ -97,11 +156,12 @@ local function multi(self, ...) return table.unpack(args) end local _ = nil +local a = ____(nil, 1) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` "local ____exports = {} @@ -110,11 +170,15 @@ local function multi(self, ...) return table.unpack(args) end local ar = {1} +local a = ____( + nil, + table.unpack(ar) +) ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` "local ____exports = {} @@ -123,11 +187,16 @@ local function multi(self, ...) return table.unpack(args) end local a +local ____ = { + ____(nil) +} +a = ____[1] +____exports.a = a ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} @@ -137,6 +206,11 @@ local function multi(self, ...) end local a do + local ____ = { + ____(nil, 1, 2) + } + a = ____[1] + ____exports.a = a while false do local ____ = 1 end @@ -145,7 +219,7 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in a return statement."`; exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} @@ -155,6 +229,7 @@ local function multi(self, ...) end local a do + local a = ____(nil, 1, 2) while false do local ____ = 1 end @@ -163,4 +238,28 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in an expression that is returned."`; +exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + local args = {...} + return table.unpack(args) +end +local a +if (function() + local ____ = { + ____(nil, 1) + } + a = ____[1] + ____exports.a = a + return ____ +end)() then + a = a + 1 + ____exports.a = a +end +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): diagnostics 1`] = `"main.ts(7,26): error TSTL: The $multi function must be called in a return statement."`; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index c697cbad0..ff1fd403a 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -3,9 +3,8 @@ import * as util from "../../util"; import * as tstl from "../../../src"; import { invalidMultiFunctionUse, - invalidMultiTypeToNonArrayBindingPattern, - invalidMultiTypeArrayBindingPatternElementInitializer, invalidMultiReturnAccess, + invalidMultiFunctionReturnType, } from "../../../src/transformation/utils/diagnostics"; const multiProjectOptions: tstl.CompilerOptions = { @@ -14,7 +13,7 @@ const multiProjectOptions: tstl.CompilerOptions = { test("multi example use case", () => { util.testModule` - function multiReturn(): MultiReturn<[string, number]> { + function multiReturn(): LuaMultiReturn<[string, number]> { return $multi("foo", 5); } @@ -47,10 +46,13 @@ const createCasesThatCall = (name: string): Array<[string, any]> => [ [`let a; [a] = ${name}()`, undefined], [`const [a] = ${name}()`, undefined], [`const [a] = ${name}(1)`, 1], + [`const [a = 1] = ${name}()`, 1], + [`const [a = 1] = ${name}(2)`, 2], [`const ar = [1]; const [a] = ${name}(...ar)`, 1], [`const _ = null, [a] = ${name}(1)`, 1], [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], + [`let a; if ([a] = ${name}(1)) { ++a; }`, 2], ]; test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { @@ -82,10 +84,10 @@ test.each<[string, number[]]>([ ["$multi", [invalidMultiFunctionUse.code]], ["$multi()", [invalidMultiFunctionUse.code]], ["({ $multi });", [invalidMultiFunctionUse.code]], - ["const a = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], - ["const {} = $multi();", [invalidMultiTypeToNonArrayBindingPattern.code]], + ["const a = $multi();", [invalidMultiFunctionUse.code]], + ["const {} = $multi();", [invalidMultiFunctionUse.code]], ["([a] = $multi(1)) => {}", [invalidMultiFunctionUse.code]], - ["const [a = 0] = $multi()", [invalidMultiTypeArrayBindingPatternElementInitializer.code]], + ["const [a = 0] = $multi()", [invalidMultiFunctionUse.code]], ])("invalid $multi call (%s)", (statement, diagnostics) => { util.testModule` ${statement} @@ -128,7 +130,18 @@ test("allow $multi call in ArrowFunction body", () => { .expectToEqual(1); }); -test.each(["0", "i"])("allow MultiReturn numeric access", expression => { +test("forward $multi call in ArrowFunction body", () => { + util.testFunction` + const foo = () => $multi(1); + const call = () => foo(); + const [result] = call(); + return result; + ` + .setOptions(multiProjectOptions) + .expectToEqual(1); +}); + +test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { util.testFunction` ${multiFunction} const i = 0; @@ -138,7 +151,7 @@ test.each(["0", "i"])("allow MultiReturn numeric access", expression => { .expectToEqual(1); }); -test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-numeric access", expression => { +test.each(["multi()['forEach']", "multi().forEach"])("disallow LuaMultiReturn non-numeric access", expression => { util.testFunction` ${multiFunction} return ${expression}; @@ -146,3 +159,98 @@ test.each(["multi()['forEach']", "multi().forEach"])("disallow MultiReturn non-n .setOptions(multiProjectOptions) .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); }); + +test("invalid $multi implicit cast", () => { + util.testModule` + function badMulti(): [string, number] { + return $multi("foo", 42); + } + ` + .setOptions(multiProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionReturnType.code]); +}); + +test.each([ + { flag: true, result: 4 }, + { flag: false, result: 7 }, +])("overloaded $multi/non-$multi return", ({ flag, result }) => { + util.testFunction` + function multiOverload(flag: true): LuaMultiReturn<[string, number]>; + function multiOverload(flag: false): [string, number]; + function multiOverload(flag: boolean) { + if (flag) { + return $multi("foo", 4); + } else { + return ["bar", 7]; + } + } + const [x, y] = multiOverload(${flag}); + return y; + ` + .setOptions(multiProjectOptions) + .expectToEqual(result); +}); + +test("return $multi from try", () => { + util.testFunction` + function multiTest() { + try { + return $multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return $multi from catch", () => { + util.testFunction` + function multiTest() { + try { + throw "error"; + } catch { + return $multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return LuaMultiReturn from try", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + return multi(1, 2); + } catch { + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); + +test("return LuaMultiReturn from catch", () => { + util.testFunction` + ${multiFunction} + function multiTest() { + try { + throw "error"; + } catch { + return multi(1, 2); + } + } + const [_, a] = multiTest(); + return a; + ` + .setOptions(multiProjectOptions) + .expectToEqual(2); +}); From de18e7b8888ecd33cf52f36e491b6b1eca11694f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 11 Feb 2021 21:54:23 +0100 Subject: [PATCH 319/764] Implemented enum merging (#980) * Implemented enum merging * Made enum merging work over multiple files --- src/transformation/utils/typescript/nodes.ts | 13 ++++++ src/transformation/visitors/enum.ts | 9 +++- test/unit/enum.spec.ts | 49 ++++++++++++++++++++ test/util.ts | 7 ++- 4 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index db0f85641..3007c4d7d 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { TransformationContext } from "../../context"; export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { return ts.isObjectLiteralExpression(node) || ts.isArrayLiteralExpression(node); @@ -23,3 +24,15 @@ export function isInDestructingAssignment(node: ts.Node): boolean { (ts.isBinaryExpression(node.parent) && ts.isArrayLiteralExpression(node.parent.left))) ); } + +/** + * Quite hacky, avoid unless absolutely necessary! + */ +export function getSymbolOfNode(context: TransformationContext, node: ts.Node): ts.Symbol | undefined { + return (node as any).symbol ?? context.checker.getSymbolAtLocation(node); +} + +export function isFirstDeclaration(context: TransformationContext, node: ts.Node) { + const symbol = getSymbolOfNode(context, node); + return symbol ? symbol.valueDeclaration === node : true; +} diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index e915440c7..918e685f6 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -4,6 +4,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { getSymbolExportScope } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration } from "../utils/lua-ast"; +import { isFirstDeclaration } from "../utils/typescript"; import { transformIdentifier } from "./identifier"; import { transformPropertyName } from "./literal"; @@ -28,9 +29,13 @@ export const transformEnumDeclaration: FunctionVisitor = (no const membersOnly = getTypeAnnotations(type).has(AnnotationKind.CompileMembersOnly); const result: lua.Statement[] = []; - if (!membersOnly) { + if (!membersOnly && isFirstDeclaration(context, node)) { const name = transformIdentifier(context, node.name); - const table = lua.createTableExpression(); + const table = lua.createBinaryExpression( + lua.cloneIdentifier(name), + lua.createTableExpression(), + lua.SyntaxKind.OrOperator + ); result.push(...createLocalOrExportedOrGlobalDeclaration(context, name, table, node)); } diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 8da16355c..f421be2c5 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -154,3 +154,52 @@ test("toString", () => { return foo(TestEnum.A); `.expectToMatchJsResult(); }); + +test("enum merging", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 3, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging with overlap", () => { + util.testFunction` + enum TestEnum { + A, B + } + + enum TestEnum { + C = 1, + D + } + + return ${serializeEnum("TestEnum")} + `.expectToMatchJsResult(); +}); + +test("enum merging multiple files", () => { + util.testModule` + import "./otherfile" + enum TestEnum { + A, B + } + + export default ${serializeEnum("TestEnum")} + ` + .addExtraFile( + "otherfile.ts", + `enum TestEnum { + C = 3, + D + }` + ) + .expectToMatchJsResult(); +}); diff --git a/test/util.ts b/test/util.ts index 8cc36f6ca..5a59793be 100644 --- a/test/util.ts +++ b/test/util.ts @@ -237,9 +237,12 @@ export abstract class TestBuilder { // Actions public debug(): this { - const luaCode = this.getMainLuaCodeChunk().replace(/^/gm, " "); + const transpiledFiles = this.getLuaResult().transpiledFiles; + const luaCode = transpiledFiles.map( + f => `[${f.sourceFiles.map(sf => sf.fileName).join(",")}]:\n${f.lua?.replace(/^/gm, " ")}` + ); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); - console.log(`Lua Code:\n${luaCode}\n\nValue:\n${value}`); + console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; } From 5b01ee2d5e603ffc4c8f9f1bc011830bdcfcf1b7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Feb 2021 22:07:46 +0100 Subject: [PATCH 320/764] 0.38.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d98d38972..70e4a7f8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index d4d39ce59..b09cef649 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.37.1", + "version": "0.38.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 28d0a57cd3055f61406d78bfb9a5fe95f4ebcfff Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Feb 2021 22:44:52 +0100 Subject: [PATCH 321/764] CHANGELOG 0.38.0 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f277e056..ae1502099 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 0.38.0 + +- **[Breaking]** Renamed `MultiReturn` to `LuaMultiReturn` to be consistent with other language extensions all starting with Lua-. +- Fixed various bugs and issues related to `LuaMultiReturn`, including its value not correctly being wrapped in some cases. +- Added support for indexing `LuaMultiReturn` values without destructing. +- Added language extensions to allow translation directly to (overwritten) Lua operators like `+`,`-`,`..`. For more information see [Operator Map Types](https://typescripttolua.github.io/docs/advanced/language-extensions#operator-map-types). +- Added language extension `$range()`. This function can be used to create numeric lua loops, for example `for (const i of $range(1, 10)) {` translates to `for i=1,10 do`. For more information see [\$range Iterator Function](https://typescripttolua.github.io/docs/advanced/language-extensions#range-iterator-function). +- Added support for `Array.isArray`, formalizing tstl's isArray convention (**note:** Due to `[]` and `{}` being the same in Lua, `{}` - without any keys - is considered an array too.) +- Added support for `string.prototype.includes`. +- Added support for enum merging. +- Fixed missing lualib dependency in `string.prototype.split`. +- Added a not-supported diagnostic for not-yet-implemented optional chaining (`a?.b`). +- Moved remaining legacy tests to modern testing utils, removing the legacy testing code. + ## 0.37.0 - **[Important]** Deprecated the @phantom, @extension, @metaExtension and @pureAbstract annotations. This is done because there are good alternatives in regular TypeScript, and this helps us simplify the transpiler. For now, using these annotations will result in a warning but they will still continue to function. A few months from now these annotations will no longer be supported, so upgrade if possible. See [Compiler Annotations](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for more info. From 0fba69b06767811f554f21fa8f3d20cb51d5b25c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 14 Feb 2021 18:24:43 +0100 Subject: [PATCH 322/764] Added comments to statements in the Lua AST (#982) * Added comments to statements in the Lua AST * Added support for arrays as multiline comments * Removed pushed indent from multiline comments * factored out printComment --- src/LuaAST.ts | 2 + src/LuaPrinter.ts | 36 +++++++++++ .../__snapshots__/plugins.spec.ts.snap | 29 +++++++++ test/transpile/plugins/add-comments.ts | 62 +++++++++++++++++++ test/transpile/plugins/plugins.spec.ts | 10 +++ 5 files changed, 139 insertions(+) create mode 100644 test/transpile/plugins/__snapshots__/plugins.spec.ts.snap create mode 100644 test/transpile/plugins/add-comments.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 8efb23817..661500e4a 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -229,6 +229,8 @@ export function createBlock(statements: Statement[], tsOriginal?: ts.Node): Bloc export interface Statement extends Node { _statementBrand: any; + leadingComments?: Array; + trailingComments?: Array; } export interface DoStatement extends Statement { diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index a021ae7d5..912ab33f5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -297,6 +297,42 @@ export class LuaPrinter { } public printStatement(statement: lua.Statement): SourceNode { + let resultNode = this.printStatementExcludingComments(statement); + + if (statement.leadingComments) { + resultNode = this.concatNodes( + statement.leadingComments.map(c => this.printComment(c)).join("\n"), + "\n", + resultNode + ); + } + + if (statement.trailingComments) { + resultNode = this.concatNodes( + resultNode, + "\n", + statement.trailingComments.map(c => this.printComment(c)).join("\n") + ); + } + + return resultNode; + } + + public printComment(comment: string | string[]): SourceChunk { + if (Array.isArray(comment)) { + if (comment.length === 0) { + return this.indent("--[[]]"); + } else { + const [firstLine, ...restLines] = comment; + const commentLines = this.concatNodes(...restLines.map(c => this.concatNodes("\n", this.indent(c)))); + return this.concatNodes(this.indent("--[["), firstLine, commentLines, "]]"); + } + } else { + return this.indent(`--${comment}`); + } + } + + protected printStatementExcludingComments(statement: lua.Statement): SourceNode { switch (statement.kind) { case lua.SyntaxKind.DoStatement: return this.printDoStatement(statement as lua.DoStatement); diff --git a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap new file mode 100644 index 000000000..9902416ab --- /dev/null +++ b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap @@ -0,0 +1,29 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`statement comments 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + --This comment on variable declaration was added by a plugin! + --- This one too! + local foo = \\"bar\\" + -- This trailing comment was also added by a plugin! + --- Example luadoc comment + ---@param paramName ParamClass + foo = \\"baz\\" + --[[ This plugin can also (kinda) create multiline comments. + -- Line 2 + --]] + --[[Multiline comments are supported as arrays + This is the second line!]] + while true do + end + --Single line comments and multiline comments can also be mixed + --[[Like this + Pretty cool!]] + --Empty multiline comment below: + --[[]] + --Single line multiline comment: + --[[Single line]] +end +return ____exports" +`; diff --git a/test/transpile/plugins/add-comments.ts b/test/transpile/plugins/add-comments.ts new file mode 100644 index 000000000..9beb01432 --- /dev/null +++ b/test/transpile/plugins/add-comments.ts @@ -0,0 +1,62 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + visitors: { + [ts.SyntaxKind.VariableStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + "This comment on variable declaration was added by a plugin!", + "- This one too!", + ]; + + lastLuaStatement.trailingComments = [" This trailing comment was also added by a plugin!"]; + + return result; + }, + [ts.SyntaxKind.ExpressionStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = ["- Example luadoc comment", "-@param paramName ParamClass"]; + + lastLuaStatement.trailingComments = [ + "[[ This plugin can also (kinda) create multiline comments.", + " Line 2", + "]]", + ]; + + return result; + }, + [ts.SyntaxKind.WhileStatement](node, context) { + const result = context.superTransformStatements(node); + + const firstLuaStatement = result[0]; + const lastLuaStatement = result[result.length - 1]; + + firstLuaStatement.leadingComments = [ + ["Multiline comments are supported as arrays", "This is the second line!"], + ]; + + lastLuaStatement.trailingComments = [ + "Single line comments and multiline comments can also be mixed", + ["Like this", "Pretty cool!"], + "Empty multiline comment below:", + [], + "Single line multiline comment:", + ["Single line"], + ]; + + return result; + }, + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index e78cc4201..46988dae0 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -30,3 +30,13 @@ test("passing arguments", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "arguments.ts"), option: true }] }) .expectToEqual({ name: path.join(__dirname, "arguments.ts"), option: true }); }); + +test("statement comments", () => { + util.testFunction` + let foo = "bar"; + foo = "baz"; + while (true) {} + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "add-comments.ts") }] }) + .expectLuaToMatchSnapshot(); +}); From d075097c79413501f2ac66a4fea635b10953e772 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Fri, 19 Feb 2021 12:31:59 -0800 Subject: [PATCH 323/764] Precompile lualib and jsonlib for tests (#983) --- test/util.ts | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/test/util.ts b/test/util.ts index 5a59793be..67cfcef57 100644 --- a/test/util.ts +++ b/test/util.ts @@ -10,8 +10,32 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -const minimalTestLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +export function toByteCode(luaCode: string) { + const L = lauxlib.luaL_newstate(); + + if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); + + const writer = (_: any, newBytes: Uint8Array, size: number, data: number[]) => { + data.push(...newBytes.slice(0, size)); + return 0; + }; + + const data: number[] = []; + + const dumpExitCode = lua.lua_dump(L, writer, data, false); + + if (dumpExitCode !== 0) { + throw Error("Unable to dump byte code"); + } + + return Uint8Array.from(data); +} + +const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); +const jsonLibByteCode = toByteCode(jsonLib); + +const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +const luaLibByteCode = toByteCode(luaLib); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -345,7 +369,7 @@ export abstract class TestBuilder { // Json lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(minimalTestLib)); + lauxlib.luaL_loadstring(L, jsonLibByteCode); lua.lua_setfield(L, -2, "json"); // Lua lib if ( @@ -354,7 +378,7 @@ export abstract class TestBuilder { ) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(lualibContent)); + lauxlib.luaL_loadstring(L, luaLibByteCode); lua.lua_setfield(L, -2, "lualib_bundle"); } From 10117134324fb63bb94702c91033b9fd73cb0316 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 20 Feb 2021 10:50:36 -0700 Subject: [PATCH 324/764] LuaIterable language extension (#981) * added LuaIterable and LuaMultiIterable language extensions * indentation fix * remove LuaMultiIterable in favor of LuaIterable * switched from expectToHaveDiagnostics to expectDiagnosticsToMatchSnapshot * updates based on feedback and discussions - LuaIterable type reworked for better lua compatibility - language extensions now checked by brand instead of type alias name - fixed LuaMultiReturn indirect forward, which also affected LuaIterable - reorganized tests and added some for manual iterable usage * fixed issue with no-state vs state iterables, and updated tests to check both (also added test for property based iterables) * updated extension kind checking to reduce complexity * updated new multi tests to actually use multiple values * replaced raw brands with LuaExtension type Co-authored-by: Tom --- language-extensions/index.d.ts | 214 +++---- src/lualib/Iterator.ts | 4 +- src/lualib/declarations/global.d.ts | 8 +- src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 123 ++-- .../visitors/language-extensions/iterable.ts | 82 +++ .../visitors/language-extensions/multi.ts | 26 +- .../visitors/language-extensions/operators.ts | 21 +- .../visitors/language-extensions/range.ts | 8 +- src/transformation/visitors/loops/for-of.ts | 3 + src/transformation/visitors/return.ts | 7 +- .../__snapshots__/iterable.spec.ts.snap | 52 ++ .../unit/language-extensions/iterable.spec.ts | 552 ++++++++++++++++++ test/unit/language-extensions/multi.spec.ts | 30 +- 14 files changed, 913 insertions(+), 221 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/iterable.ts create mode 100644 test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap create mode 100644 test/unit/language-extensions/iterable.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 033012960..79067b1cd 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,3 +1,11 @@ +/** + * Indicates a type is a language extension provided by TypescriptToLua. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TBrand A string used to uniquely identify the language extension type + */ +declare type LuaExtension = { [T in TBrand]: { readonly __luaExtensionSymbol: unique symbol } }; + /** * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -5,7 +13,7 @@ * @param T A tuple type with each element type representing a return value's type. * @param values Return values. */ -declare function $multi(...values: T): LuaMultiReturn; +declare const $multi: ((...values: T) => LuaMultiReturn) & LuaExtension<"__luaMultiFunctionBrand">; /** * Represents multiple return values as a tuple. @@ -13,7 +21,7 @@ declare function $multi(...values: T): LuaMultiReturn; * * @param T A tuple type with each element type representing a return value's type. */ -declare type LuaMultiReturn = T & { readonly __luaMultiReturnBrand: unique symbol }; +declare type LuaMultiReturn = T & LuaExtension<"__luaMultiReturnBrand">; /** * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. @@ -23,7 +31,42 @@ declare type LuaMultiReturn = T & { readonly __luaMultiReturnBr * @param limit The last number in the sequence to iterate over. * @param step The amount to increment each iteration. */ -declare function $range(start: number, limit: number, step?: number): Iterable; +declare const $range: ((start: number, limit: number, step?: number) => Iterable) & + LuaExtension<"__luaRangeFunctionBrand">; + +/** + * Represents a Lua-style iterator which is returned from a LuaIterable. + * For simple iterators (with no state), this is just a function. + * For complex iterators that use a state, this is a LuaMultiReturn tuple containing a function, the state, and the initial value to pass to the function. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param state The state object returned from the LuaIterable. + * @param lastValue The last value returned from this function. If iterating LuaMultiReturn values, this is the first value of the tuple. + */ +declare type LuaIterator = TState extends undefined + ? (this: void) => TValue + : LuaMultiReturn< + [ + ( + this: void, + state: TState, + lastValue: TValue extends LuaMultiReturn ? TTuple[0] : TValue + ) => TValue, + TState, + TValue extends LuaMultiReturn ? TTuple[0] : TValue + ] + >; + +/** + * Represents a Lua-style iteratable which iterates single values in a `for...in` loop (ex. `for x in iter() do`). + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TValue The type of value returned each iteration. If this is LuaMultiReturn, multiple values will be returned each iteration. + * @param TState The type of the state value passed back to the iterator function each iteration. + */ +declare type LuaIterable = Iterable & + LuaIterator & + LuaExtension<"__luaIterableBrand">; /** * Calls to functions with this type are translated to `left + right`. @@ -33,9 +76,8 @@ declare function $range(start: number, limit: number, step?: number): Iterable = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaAdditionBrand: unique symbol; -}; +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaAdditionBrand">; /** * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. @@ -44,9 +86,8 @@ declare type LuaAddition = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaAdditionMethod = ((right: TRight) => TReturn) & { - readonly __luaAdditionMethodBrand: unique symbol; -}; +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaAdditionMethodBrand">; /** * Calls to functions with this type are translated to `left - right`. @@ -56,9 +97,8 @@ declare type LuaAdditionMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaSubtractionBrand: unique symbol; -}; +declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionBrand">; /** * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. @@ -67,9 +107,8 @@ declare type LuaSubtraction = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & { - readonly __luaSubtractionMethodBrand: unique symbol; -}; +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaSubtractionMethodBrand">; /** * Calls to functions with this type are translated to `left * right`. @@ -79,9 +118,8 @@ declare type LuaSubtractionMethod = ((right: TRight) => TReturn * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaMultiplicationBrand: unique symbol; -}; +declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationBrand">; /** * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. @@ -90,9 +128,8 @@ declare type LuaMultiplication = ((left: TLeft, right: T * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & { - readonly __luaMultiplicationMethodBrand: unique symbol; -}; +declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaMultiplicationMethodBrand">; /** * Calls to functions with this type are translated to `left / right`. @@ -102,9 +139,8 @@ declare type LuaMultiplicationMethod = ((right: TRight) => TRet * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaDivisionBrand: unique symbol; -}; +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaDivisionBrand">; /** * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. @@ -113,9 +149,8 @@ declare type LuaDivision = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivisionMethod = ((right: TRight) => TReturn) & { - readonly __luaDivisionMethodBrand: unique symbol; -}; +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaDivisionMethodBrand">; /** * Calls to functions with this type are translated to `left % right`. @@ -125,9 +160,8 @@ declare type LuaDivisionMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaModuloBrand: unique symbol; -}; +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaModuloBrand">; /** * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. @@ -136,9 +170,7 @@ declare type LuaModulo = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModuloMethod = ((right: TRight) => TReturn) & { - readonly __luaModuloMethodBrand: unique symbol; -}; +declare type LuaModuloMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaModuloMethodBrand">; /** * Calls to functions with this type are translated to `left ^ right`. @@ -148,9 +180,8 @@ declare type LuaModuloMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaPowerBrand: unique symbol; -}; +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaPowerBrand">; /** * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. @@ -159,9 +190,7 @@ declare type LuaPower = ((left: TLeft, right: TRight) => * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPowerMethod = ((right: TRight) => TReturn) & { - readonly __luaPowerMethodBrand: unique symbol; -}; +declare type LuaPowerMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaPowerMethodBrand">; /** * Calls to functions with this type are translated to `left // right`. @@ -171,9 +200,8 @@ declare type LuaPowerMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaFloorDivisionBrand: unique symbol; -}; +declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionBrand">; /** * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. @@ -182,9 +210,8 @@ declare type LuaFloorDivision = ((left: TLeft, right: TR * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & { - readonly __luaFloorDivisionMethodBrand: unique symbol; -}; +declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaFloorDivisionMethodBrand">; /** * Calls to functions with this type are translated to `left & right`. @@ -194,9 +221,8 @@ declare type LuaFloorDivisionMethod = ((right: TRight) => TRetu * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseAndBrand: unique symbol; -}; +declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndBrand">; /** * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. @@ -205,9 +231,8 @@ declare type LuaBitwiseAnd = ((left: TLeft, right: TRigh * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseAndMethodBrand: unique symbol; -}; +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseAndMethodBrand">; /** * Calls to functions with this type are translated to `left | right`. @@ -217,9 +242,8 @@ declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseOrBrand: unique symbol; -}; +declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrBrand">; /** * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. @@ -228,9 +252,8 @@ declare type LuaBitwiseOr = ((left: TLeft, right: TRight * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseOrMethodBrand: unique symbol; -}; +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseOrMethodBrand">; /** * Calls to functions with this type are translated to `left ~ right`. @@ -240,9 +263,8 @@ declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseExclusiveOrBrand: unique symbol; -}; +declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrBrand">; /** * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. @@ -251,9 +273,8 @@ declare type LuaBitwiseExclusiveOr = ((left: TLeft, righ * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseExclusiveOrMethodBrand: unique symbol; -}; +declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseExclusiveOrMethodBrand">; /** * Calls to functions with this type are translated to `left << right`. @@ -263,9 +284,8 @@ declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseLeftShiftBrand: unique symbol; -}; +declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftBrand">; /** * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. @@ -274,9 +294,8 @@ declare type LuaBitwiseLeftShift = ((left: TLeft, right: * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseLeftShiftMethodBrand: unique symbol; -}; +declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseLeftShiftMethodBrand">; /** * Calls to functions with this type are translated to `left >> right`. @@ -286,9 +305,8 @@ declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TR * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaBitwiseRightShiftBrand: unique symbol; -}; +declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftBrand">; /** * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. @@ -297,9 +315,8 @@ declare type LuaBitwiseRightShift = ((left: TLeft, right * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & { - readonly __luaBitwiseRightShiftMethodBrand: unique symbol; -}; +declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaBitwiseRightShiftMethodBrand">; /** * Calls to functions with this type are translated to `left .. right`. @@ -309,9 +326,8 @@ declare type LuaBitwiseRightShiftMethod = ((right: TRight) => T * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaConcatBrand: unique symbol; -}; +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaConcatBrand">; /** * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. @@ -320,9 +336,7 @@ declare type LuaConcat = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcatMethod = ((right: TRight) => TReturn) & { - readonly __luaConcatMethodBrand: unique symbol; -}; +declare type LuaConcatMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaConcatMethodBrand">; /** * Calls to functions with this type are translated to `left < right`. @@ -332,9 +346,8 @@ declare type LuaConcatMethod = ((right: TRight) => TReturn) & { * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaLessThanBrand: unique symbol; -}; +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaLessThanBrand">; /** * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. @@ -343,9 +356,8 @@ declare type LuaLessThan = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThanMethod = ((right: TRight) => TReturn) & { - readonly __luaLessThanMethodBrand: unique symbol; -}; +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaLessThanMethodBrand">; /** * Calls to functions with this type are translated to `left > right`. @@ -355,9 +367,8 @@ declare type LuaLessThanMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & { - readonly __luaGreaterThanBrand: unique symbol; -}; +declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanBrand">; /** * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. @@ -366,9 +377,8 @@ declare type LuaGreaterThan = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & { - readonly __luaGreaterThanMethodBrand: unique symbol; -}; +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & + LuaExtension<"__luaGreaterThanMethodBrand">; /** * Calls to functions with this type are translated to `-operand`. @@ -377,9 +387,7 @@ declare type LuaGreaterThanMethod = ((right: TRight) => TReturn * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegation = ((operand: TOperand) => TReturn) & { - readonly __luaNegationBrand: unique symbol; -}; +declare type LuaNegation = ((operand: TOperand) => TReturn) & LuaExtension<"__luaNegationBrand">; /** * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. @@ -387,7 +395,7 @@ declare type LuaNegation = ((operand: TOperand) => TReturn) & * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNegationMethodBrand: unique symbol }; +declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"__luaNegationMethodBrand">; /** * Calls to functions with this type are translated to `~operand`. @@ -396,9 +404,7 @@ declare type LuaNegationMethod = (() => TReturn) & { readonly __luaNega * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & { - readonly __luaBitwiseNotBrand: unique symbol; -}; +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & LuaExtension<"__luaBitwiseNotBrand">; /** * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. @@ -406,7 +412,7 @@ declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBitwiseNotMethodBrand: unique symbol }; +declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"__luaBitwiseNotMethodBrand">; /** * Calls to functions with this type are translated to `#operand`. @@ -415,9 +421,7 @@ declare type LuaBitwiseNotMethod = (() => TReturn) & { readonly __luaBi * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLength = ((operand: TOperand) => TReturn) & { - readonly __luaLengthBrand: unique symbol; -}; +declare type LuaLength = ((operand: TOperand) => TReturn) & LuaExtension<"__luaLengthBrand">; /** * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. @@ -425,4 +429,4 @@ declare type LuaLength = ((operand: TOperand) => TReturn) & { * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLengthMethod = (() => TReturn) & { readonly __luaLengthMethodBrand: unique symbol }; +declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 809ca69ee..d6112cd88 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -27,7 +27,7 @@ function __TS__IteratorStringStep(this: string, index: number): [number, string] function __TS__Iterator( this: void, iterable: string | GeneratorIterator | Iterable | readonly T[] -): [(...args: any[]) => [any, any] | [], ...any[]] { +): [(...args: any[]) => [any, any] | [], ...any[]] | LuaIterable> { if (typeof iterable === "string") { return [__TS__IteratorStringStep, iterable, 0]; } else if ("____coroutine" in iterable) { @@ -36,6 +36,6 @@ function __TS__Iterator( const iterator = iterable[Symbol.iterator](); return [__TS__IteratorIteratorStep, iterator]; } else { - return ipairs(iterable as readonly T[]) as any; + return ipairs(iterable as readonly T[]); } } diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 450fba8dc..117438817 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -25,10 +25,4 @@ declare function unpack(list: T[], i?: number, j?: number): T[]; declare function select(index: number, ...args: T[]): T; declare function select(index: "#", ...args: T[]): number; -/** - * @luaIterator - * @tupleReturn - */ -type LuaTupleIterator = Iterable & { " LuaTupleIterator": never }; - -declare function ipairs(t: Record): LuaTupleIterator<[number, T]>; +declare function ipairs(t: Record): LuaIterable, Record>; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 76e8b4632..e8873746a 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -118,6 +118,10 @@ export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( "the '@tupleReturn' annotation." ); +export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory( + "LuaIterable with a LuaMultiReturn return value type must be destructured." +); + export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( "Accessors in object literal are not supported." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 391993f8a..efcd7d810 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -1,10 +1,11 @@ import * as ts from "typescript"; -import * as path from "path"; +import { TransformationContext } from "../context"; export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", RangeFunction = "RangeFunction", + IterableType = "IterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -43,74 +44,66 @@ export enum ExtensionKind { LengthOperatorMethodType = "LengthOperatorMethodType", } -const functionNameToExtensionKind: { [name: string]: ExtensionKind } = { - $multi: ExtensionKind.MultiFunction, - $range: ExtensionKind.RangeFunction, +const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { + [ExtensionKind.MultiFunction]: "$multi", + [ExtensionKind.RangeFunction]: "$range", }; -const typeNameToExtensionKind: { [name: string]: ExtensionKind } = { - LuaMultiReturn: ExtensionKind.MultiType, - LuaAddition: ExtensionKind.AdditionOperatorType, - LuaAdditionMethod: ExtensionKind.AdditionOperatorMethodType, - LuaSubtraction: ExtensionKind.SubtractionOperatorType, - LuaSubtractionMethod: ExtensionKind.SubtractionOperatorMethodType, - LuaMultiplication: ExtensionKind.MultiplicationOperatorType, - LuaMultiplicationMethod: ExtensionKind.MultiplicationOperatorMethodType, - LuaDivision: ExtensionKind.DivisionOperatorType, - LuaDivisionMethod: ExtensionKind.DivisionOperatorMethodType, - LuaModulo: ExtensionKind.ModuloOperatorType, - LuaModuloMethod: ExtensionKind.ModuloOperatorMethodType, - LuaPower: ExtensionKind.PowerOperatorType, - LuaPowerMethod: ExtensionKind.PowerOperatorMethodType, - LuaFloorDivision: ExtensionKind.FloorDivisionOperatorType, - LuaFloorDivisionMethod: ExtensionKind.FloorDivisionOperatorMethodType, - LuaBitwiseAnd: ExtensionKind.BitwiseAndOperatorType, - LuaBitwiseAndMethod: ExtensionKind.BitwiseAndOperatorMethodType, - LuaBitwiseOr: ExtensionKind.BitwiseOrOperatorType, - LuaBitwiseOrMethod: ExtensionKind.BitwiseOrOperatorMethodType, - LuaBitwiseExclusiveOr: ExtensionKind.BitwiseExclusiveOrOperatorType, - LuaBitwiseExclusiveOrMethod: ExtensionKind.BitwiseExclusiveOrOperatorMethodType, - LuaBitwiseLeftShift: ExtensionKind.BitwiseLeftShiftOperatorType, - LuaBitwiseLeftShiftMethod: ExtensionKind.BitwiseLeftShiftOperatorMethodType, - LuaBitwiseRightShift: ExtensionKind.BitwiseRightShiftOperatorType, - LuaBitwiseRightShiftMethod: ExtensionKind.BitwiseRightShiftOperatorMethodType, - LuaConcat: ExtensionKind.ConcatOperatorType, - LuaConcatMethod: ExtensionKind.ConcatOperatorMethodType, - LuaLessThan: ExtensionKind.LessThanOperatorType, - LuaLessThanMethod: ExtensionKind.LessThanOperatorMethodType, - LuaGreaterThan: ExtensionKind.GreaterThanOperatorType, - LuaGreaterThanMethod: ExtensionKind.GreaterThanOperatorMethodType, - LuaNegation: ExtensionKind.NegationOperatorType, - LuaNegationMethod: ExtensionKind.NegationOperatorMethodType, - LuaBitwiseNot: ExtensionKind.BitwiseNotOperatorType, - LuaBitwiseNotMethod: ExtensionKind.BitwiseNotOperatorMethodType, - LuaLength: ExtensionKind.LengthOperatorType, - LuaLengthMethod: ExtensionKind.LengthOperatorMethodType, +const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { + [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", + [ExtensionKind.MultiType]: "__luaMultiReturnBrand", + [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", + [ExtensionKind.IterableType]: "__luaIterableBrand", + [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", + [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", + [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", + [ExtensionKind.SubtractionOperatorMethodType]: "__luaSubtractionMethodBrand", + [ExtensionKind.MultiplicationOperatorType]: "__luaMultiplicationBrand", + [ExtensionKind.MultiplicationOperatorMethodType]: "__luaMultiplicationMethodBrand", + [ExtensionKind.DivisionOperatorType]: "__luaDivisionBrand", + [ExtensionKind.DivisionOperatorMethodType]: "__luaDivisionMethodBrand", + [ExtensionKind.ModuloOperatorType]: "__luaModuloBrand", + [ExtensionKind.ModuloOperatorMethodType]: "__luaModuloMethodBrand", + [ExtensionKind.PowerOperatorType]: "__luaPowerBrand", + [ExtensionKind.PowerOperatorMethodType]: "__luaPowerMethodBrand", + [ExtensionKind.FloorDivisionOperatorType]: "__luaFloorDivisionBrand", + [ExtensionKind.FloorDivisionOperatorMethodType]: "__luaFloorDivisionMethodBrand", + [ExtensionKind.BitwiseAndOperatorType]: "__luaBitwiseAndBrand", + [ExtensionKind.BitwiseAndOperatorMethodType]: "__luaBitwiseAndMethodBrand", + [ExtensionKind.BitwiseOrOperatorType]: "__luaBitwiseOrBrand", + [ExtensionKind.BitwiseOrOperatorMethodType]: "__luaBitwiseOrMethodBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorType]: "__luaBitwiseExclusiveOrBrand", + [ExtensionKind.BitwiseExclusiveOrOperatorMethodType]: "__luaBitwiseExclusiveOrMethodBrand", + [ExtensionKind.BitwiseLeftShiftOperatorType]: "__luaBitwiseLeftShiftBrand", + [ExtensionKind.BitwiseLeftShiftOperatorMethodType]: "__luaBitwiseLeftShiftMethodBrand", + [ExtensionKind.BitwiseRightShiftOperatorType]: "__luaBitwiseRightShiftBrand", + [ExtensionKind.BitwiseRightShiftOperatorMethodType]: "__luaBitwiseRightShiftMethodBrand", + [ExtensionKind.ConcatOperatorType]: "__luaConcatBrand", + [ExtensionKind.ConcatOperatorMethodType]: "__luaConcatMethodBrand", + [ExtensionKind.LessThanOperatorType]: "__luaLessThanBrand", + [ExtensionKind.LessThanOperatorMethodType]: "__luaLessThanMethodBrand", + [ExtensionKind.GreaterThanOperatorType]: "__luaGreaterThanBrand", + [ExtensionKind.GreaterThanOperatorMethodType]: "__luaGreaterThanMethodBrand", + [ExtensionKind.NegationOperatorType]: "__luaNegationBrand", + [ExtensionKind.NegationOperatorMethodType]: "__luaNegationMethodBrand", + [ExtensionKind.BitwiseNotOperatorType]: "__luaBitwiseNotBrand", + [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", + [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", + [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", }; -function isSourceFileFromLanguageExtensions(sourceFile: ts.SourceFile): boolean { - const extensionDirectory = path.resolve(__dirname, "../../../language-extensions"); - const sourceFileDirectory = path.dirname(path.normalize(sourceFile.fileName)); - return extensionDirectory === sourceFileDirectory; +export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { + const typeBrand = extensionKindToTypeBrand[extensionKind]; + return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; } -export function getExtensionKind(declaration: ts.Declaration): ExtensionKind | undefined { - const sourceFile = declaration.getSourceFile(); - if (isSourceFileFromLanguageExtensions(sourceFile)) { - if (ts.isFunctionDeclaration(declaration) && declaration.name?.text) { - const extensionKind = functionNameToExtensionKind[declaration.name.text]; - if (extensionKind) { - return extensionKind; - } - } - - if (ts.isTypeAliasDeclaration(declaration)) { - const extensionKind = typeNameToExtensionKind[declaration.name.text]; - if (extensionKind) { - return extensionKind; - } - } - - throw new Error("Unknown extension kind"); - } +export function isExtensionFunction( + context: TransformationContext, + symbol: ts.Symbol, + extensionKind: ExtensionKind +): boolean { + return ( + symbol.getName() === extensionKindToFunctionName[extensionKind] && + symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) + ); } diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts new file mode 100644 index 000000000..769e15093 --- /dev/null +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -0,0 +1,82 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import * as extensions from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; +import { transformArrayBindingElement } from "../variable-declaration"; +import { invalidMultiIterableWithoutDestructuring } from "../../utils/diagnostics"; +import { cast } from "../../../utils"; +import { isMultiReturnType } from "./multi"; + +export function isIterableType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.IterableType); +} + +export function returnsIterableType(context: TransformationContext, node: ts.CallExpression): boolean { + const signature = context.checker.getResolvedSignature(node); + const type = signature?.getReturnType(); + return type ? isIterableType(type) : false; +} + +export function isIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { + const type = context.checker.getTypeAtLocation(expression); + return isIterableType(type); +} + +function transformForOfMultiIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const luaIterator = context.transformExpression(statement.expression); + let identifiers: lua.Identifier[] = []; + + if (ts.isVariableDeclarationList(statement.initializer)) { + // Variables declared in for loop + // for ${initializer} in ${iterable} do + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (ts.isArrayBindingPattern(binding)) { + identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(binding)); + } + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Variables NOT declared in for loop - catch iterator values in temps and assign + // for ____value0 in ${iterable} do + // ${initializer} = ____value0 + identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) + ), + identifiers + ) + ); + } + } else { + context.diagnostics.push(invalidMultiIterableWithoutDestructuring(statement.initializer)); + } + + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); + } + + return lua.createForInStatement(block, identifiers, [luaIterator], statement); +} + +export function transformForOfIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const type = context.checker.getTypeAtLocation(statement.expression); + if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { + return transformForOfMultiIterableStatement(context, statement, block); + } + + const luaIterator = context.transformExpression(statement.expression); + const identifier = transformForInitializer(context, statement.initializer, block); + return lua.createForInStatement(block, [identifier], [luaIterator], statement); +} diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 8ddb54c83..b292d9aa1 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -1,22 +1,16 @@ import * as ts from "typescript"; import * as extensions from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { invalidMultiFunctionUse } from "../../utils/diagnostics"; import { findFirstNodeAbove } from "../../utils/typescript"; - -const isMultiFunctionDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiFunction; - -const isMultiTypeDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.MultiType; +import { isIterableExpression } from "./iterable"; +import { invalidMultiFunctionUse } from "../../utils/diagnostics"; export function isMultiReturnType(type: ts.Type): boolean { - return type.aliasSymbol?.declarations?.some(isMultiTypeDeclaration) ?? false; + return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); } export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { - const type = context.checker.getTypeAtLocation(expression.expression); - return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; + return isMultiFunctionNode(context, expression.expression); } export function returnsMultiType(context: TransformationContext, node: ts.CallExpression): boolean { @@ -30,8 +24,8 @@ export function isMultiReturnCall(context: TransformationContext, expression: ts } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { - const type = context.checker.getTypeAtLocation(node); - return type.symbol?.declarations?.some(isMultiFunctionDeclaration) ?? false; + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.MultiFunction) : false; } export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { @@ -86,6 +80,11 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n return false; } + // LuaIterable in for...of + if (ts.isForOfStatement(node.parent) && isIterableExpression(context, node)) { + return false; + } + return true; } @@ -99,8 +98,7 @@ export function findMultiAssignmentViolations( if (!ts.isShorthandPropertyAssignment(element)) continue; const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); if (valueSymbol) { - const declaration = valueSymbol.valueDeclaration; - if (declaration && isMultiFunctionDeclaration(declaration)) { + if (extensions.isExtensionFunction(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { context.diagnostics.push(invalidMultiFunctionUse(element)); result.push(element); } diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index b217a26e8..dddecf338 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -49,10 +49,7 @@ const unaryOperatorMappings = new Map([ - ...binaryOperatorMappings.keys(), - ...unaryOperatorMappings.keys(), -]); +const operatorMapExtensions = [...binaryOperatorMappings.keys(), ...unaryOperatorMappings.keys()]; const bitwiseOperatorMapExtensions = new Set([ extensions.ExtensionKind.BitwiseAndOperatorType, @@ -84,25 +81,15 @@ function getOperatorMapExtensionKindForCall(context: TransformationContext, node if (!typeDeclaration) { return; } - const mapping = extensions.getExtensionKind(typeDeclaration); - if (mapping !== undefined && operatorMapExtensions.has(mapping)) { - return mapping; - } -} - -function isOperatorMapDeclaration(declaration: ts.Declaration) { - const typeDeclaration = getTypeDeclaration(declaration); - if (typeDeclaration) { - const extensionKind = extensions.getExtensionKind(typeDeclaration); - return extensionKind !== undefined ? operatorMapExtensions.has(extensionKind) : false; - } + const type = context.checker.getTypeFromTypeNode(typeDeclaration.type); + return operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); } function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { if (type.isUnionOrIntersection()) { return type.types.some(t => isOperatorMapType(context, t)); } else { - return type.symbol?.declarations?.some(isOperatorMapDeclaration); + return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); } } diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts index d68729c3c..00a3c249e 100644 --- a/src/transformation/visitors/language-extensions/range.ts +++ b/src/transformation/visitors/language-extensions/range.ts @@ -8,17 +8,13 @@ import { transformArguments } from "../call"; import { assert } from "../../../utils"; import { invalidRangeControlVariable } from "../../utils/diagnostics"; -const isRangeFunctionDeclaration = (declaration: ts.Declaration): boolean => - extensions.getExtensionKind(declaration) === extensions.ExtensionKind.RangeFunction; - export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { - const type = context.checker.getTypeAtLocation(expression.expression); - return type.symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; + return isRangeFunctionNode(context, expression.expression); } export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol?.declarations?.some(isRangeFunctionDeclaration) ?? false; + return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.RangeFunction) : false; } function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 047ed3535..e8241f40f 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -8,6 +8,7 @@ import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isNumberType } from "../../utils/typescript"; import { transformArguments } from "../call"; import { transformIdentifier } from "../identifier"; +import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformArrayBindingElement } from "../variable-declaration"; import { getVariableDeclarationBinding, transformForInitializer, transformLoopBody } from "./utils"; @@ -156,6 +157,8 @@ export const transformForOfStatement: FunctionVisitor = (node return transformRangeStatement(context, node, body); } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { return transformForRangeStatement(context, node, body); + } else if (isIterableExpression(context, node.expression)) { + return transformForOfIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { return transformForOfLuaIteratorStatement(context, node, body); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 7e7a7ddf8..f309874f7 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -12,6 +12,7 @@ import { shouldMultiReturnCallBeWrapped, isMultiFunctionCall, isMultiReturnType, + isInMultiReturnFunction, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; @@ -20,6 +21,8 @@ function transformExpressionsInReturn( node: ts.Expression, insideTryCatch: boolean ): lua.Expression[] { + const expressionType = context.checker.getTypeAtLocation(node); + if (ts.isCallExpression(node)) { // $multi(...) if (isMultiFunctionCall(context, node)) { @@ -40,6 +43,9 @@ function transformExpressionsInReturn( if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { return [wrapInTable(context.transformExpression(node))]; } + } else if (isInMultiReturnFunction(context, node) && isMultiReturnType(expressionType)) { + // Unpack objects typed as LuaMultiReturn + return [createUnpackCall(context, context.transformExpression(node), node)]; } if (!isInTupleReturnFunction(context, node)) { @@ -47,7 +53,6 @@ function transformExpressionsInReturn( } let results: lua.Expression[]; - const expressionType = context.checker.getTypeAtLocation(node); // Parent function is a TupleReturn function if (ts.isArrayLiteralExpression(node)) { diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap new file mode 100644 index 000000000..1f76110a4 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -0,0 +1,52 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("for (const s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,24): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function testIterable() + local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} + local i = 0 + return function() + local strs = strsArray[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] + if strs then + return table.unpack(strs) + end + end + end + local s + for ____ in testIterable() do + end +end +return ____exports" +`; + +exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable without destructuring ("let s; for (s of testIterable()) {}"): diagnostics 1`] = `"main.ts(14,25): error TSTL: LuaIterable with a LuaMultiReturn return value type must be destructured."`; diff --git a/test/unit/language-extensions/iterable.spec.ts b/test/unit/language-extensions/iterable.spec.ts new file mode 100644 index 000000000..b6f7ab141 --- /dev/null +++ b/test/unit/language-extensions/iterable.spec.ts @@ -0,0 +1,552 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidMultiIterableWithoutDestructuring } from "../../../src/transformation/utils/diagnostics"; + +const iterableProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +describe("simple LuaIterable", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strs = ["a", "b", "c"]; + let i = 0; + return (() => strs[i++]) as any; + } + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable using state", () => { + const testIterable = ` + function iterator(this: void, strs: string[], lastStr: string) { + return strs[strs.indexOf(lastStr) + 1]; + } + const testIterable = (() => $multi(iterator, ["a", "b", "c"], "")) as (() => LuaIterable); + `; + const testResults = ["a", "b", "c"]; + + test("const control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("let control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (let s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of testIterable()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let [iter, state, val] = testIterable(); + while (true) { + val = iter(state, val); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with array value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => strsArray[i++]) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); + +describe("LuaIterable with LuaMultiReturn value type", () => { + const testIterable = ` + function testIterable(this: void): LuaIterable> { + const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + let i = 0; + return (() => { + const strs = strsArray[i++]; + if (strs) { + return $multi(...strs); + } + }) as any; + } + `; + const testResults = [ + ["a1", "a2"], + ["b1", "b2"], + ["c1", "c2"], + ]; + + test("basic destructuring", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + for (const [x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + let x: string, y: string; + for ([x, y] of testIterable()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable(); } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure with function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable(); return iter; } + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable(); + const results: Array = []; + for (const [x, y] of forward()) { + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("destructure manual use", () => { + util.testFunction` + ${testIterable} + const results: Array = []; + const iter = testIterable(); + while (true) { + const [x, y] = iter(); + if (!x) { + break; + } + results.push([x, y]); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test.each(["for (const s of testIterable()) {}", "let s; for (s of testIterable()) {}"])( + "invalid LuaIterable without destructuring (%p)", + statement => { + util.testFunction` + ${testIterable} + ${statement} + ` + .setOptions(iterableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidMultiIterableWithoutDestructuring.code]); + } + ); +}); + +describe("LuaIterable property", () => { + const testIterable = ` + class IterableTester { + public strs = ["a", "b", "c"]; + + public get values(): LuaIterable { + let i = 0; + return (() => this.strs[i++]) as any; + } + } + const tester = new IterableTester(); + `; + const testResults = ["a", "b", "c"]; + + test("basic usage", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + for (const s of tester.values) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("external control variable", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + let s: string; + for (s of tester.values) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return tester.values; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = tester.values; return iter; } + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => tester.values; + const results: string[] = []; + for (const s of forward()) { + results.push(s); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); + + test("manual use", () => { + util.testFunction` + ${testIterable} + const results: string[] = []; + const iter = tester.values; + while (true) { + const val = iter(); + if (!val) { + break; + } + results.push(val); + } + return results; + ` + .setOptions(iterableProjectOptions) + .expectToEqual(testResults); + }); +}); diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index ff1fd403a..0b99cf4dc 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -130,15 +130,37 @@ test("allow $multi call in ArrowFunction body", () => { .expectToEqual(1); }); +test("forward $multi call", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { return foo(); } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .setOptions(multiProjectOptions) + .expectToEqual([1, 2]); +}); + +test("forward $multi call indirect", () => { + util.testFunction` + function foo() { return $multi(1, 2); } + function call() { const m = foo(); return m; } + const [resultA, resultB] = call(); + return [resultA, resultB]; + ` + .setOptions(multiProjectOptions) + .expectToEqual([1, 2]); +}); + test("forward $multi call in ArrowFunction body", () => { util.testFunction` - const foo = () => $multi(1); + const foo = () => $multi(1, 2); const call = () => foo(); - const [result] = call(); - return result; + const [resultA, resultB] = call(); + return [resultA, resultB]; ` .setOptions(multiProjectOptions) - .expectToEqual(1); + .expectToEqual([1, 2]); }); test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { From 0a5bd20a115e64db02186c6e9d84a30ecf918718 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 20 Feb 2021 19:00:34 +0100 Subject: [PATCH 325/764] 0.38.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 70e4a7f8c..4791e9650 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index b09cef649..078637493 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.38.0", + "version": "0.38.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e90fc31b1db83b7423710a73aa1feced265d43d8 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 21 Feb 2021 13:53:55 -0700 Subject: [PATCH 326/764] Lua table extensions (#991) * Lua table extensions * addressing feedback Co-authored-by: Tom --- language-extensions/index.d.ts | 78 ++++++++++ src/transformation/utils/diagnostics.ts | 8 + .../utils/language-extensions.ts | 10 ++ src/transformation/utils/typescript/index.ts | 12 ++ src/transformation/visitors/call.ts | 19 +++ src/transformation/visitors/class/new.ts | 5 + .../visitors/expression-statement.ts | 5 + src/transformation/visitors/identifier.ts | 6 + .../visitors/language-extensions/operators.ts | 36 +---- .../visitors/language-extensions/table.ts | 80 ++++++++++ .../__snapshots__/table.spec.ts.snap | 64 ++++++++ test/unit/language-extensions/table.spec.ts | 137 ++++++++++++++++++ 12 files changed, 429 insertions(+), 31 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/table.ts create mode 100644 test/unit/language-extensions/__snapshots__/table.spec.ts.snap create mode 100644 test/unit/language-extensions/table.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 79067b1cd..e5d3096a3 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -430,3 +430,81 @@ declare type LuaLength = ((operand: TOperand) => TReturn) & L * @param TReturn The resulting (return) type of the operation. */ declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key]`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGet = ((table: TTable, key: TKey) => TValue) & + LuaExtension<"__luaTableGetBrand">; + +/** + * Calls to methods with this type are translated to `table[key]`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value stored in the table. + */ +declare type LuaTableGetMethod = ((key: TKey) => TValue) & + LuaExtension<"__luaTableGetMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = value`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSet = (( + table: TTable, + key: TKey, + value: TValue +) => void) & + LuaExtension<"__luaTableSetBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = value`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + * @param TValue The type of the value to assign to the table. + */ +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & + LuaExtension<"__luaTableSetMethodBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare interface LuaTable { + length: LuaLengthMethod; + get: LuaTableGetMethod; + set: LuaTableSetMethod; +} + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare type LuaTableConstructor = (new () => LuaTable) & + LuaExtension<"__luaTableNewBrand">; + +/** + * A convenience type for working directly with a Lua table. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the keys used to access the table. + * @param TValue The type of the values stored in the table. + */ +declare const LuaTable: LuaTableConstructor; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index e8873746a..9b34e9547 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -174,6 +174,14 @@ export const invalidOperatorMappingUse = createErrorDiagnosticFactory( "This function must always be directly called and cannot be referred to." ); +export const invalidTableExtensionUse = createErrorDiagnosticFactory( + "This function must be called directly and cannot be referred to." +); + +export const invalidTableSetExpression = createErrorDiagnosticFactory( + "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." +); + export const annotationDeprecated = createWarningDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index efcd7d810..cb17987ad 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -42,6 +42,11 @@ export enum ExtensionKind { BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", LengthOperatorType = "LengthOperatorType", LengthOperatorMethodType = "LengthOperatorMethodType", + TableNewType = "TableNewType", + TableGetType = "TableGetType", + TableGetMethodType = "TableGetMethodType", + TableSetType = "TableSetType", + TableSetMethodType = "TableSetMethodType", } const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { @@ -90,6 +95,11 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", + [ExtensionKind.TableNewType]: "__luaTableNewBrand", + [ExtensionKind.TableGetType]: "__luaTableGetBrand", + [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", + [ExtensionKind.TableSetType]: "__luaTableSetBrand", + [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", }; export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 394d67656..46b4992ea 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -79,3 +79,15 @@ export function getAllCallSignatures(type: ts.Type): readonly ts.Signature[] { export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { return !(ts.isLiteralExpression(node) || ts.isIdentifier(node) || node.kind === ts.SyntaxKind.ThisKeyword); } + +export function getFunctionTypeForCall(context: TransformationContext, node: ts.CallExpression) { + const signature = context.checker.getResolvedSignature(node); + if (!signature || !signature.declaration) { + return; + } + const typeDeclaration = findFirstNodeAbove(signature.declaration, ts.isTypeAliasDeclaration); + if (!typeDeclaration) { + return; + } + return context.checker.getTypeFromTypeNode(typeDeclaration.type); +} diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index f29cbd4e9..7ea22eb34 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -13,6 +13,13 @@ import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; +import { + isTableGetCall, + isTableSetCall, + transformTableGetExpression, + transformTableSetExpression, +} from "./language-extensions/table"; +import { invalidTableSetExpression } from "../utils/diagnostics"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -214,6 +221,18 @@ export const transformCallExpression: FunctionVisitor = (node return transformOperatorMappingExpression(context, node); } + if (isTableGetCall(context, node)) { + return transformTableGetExpression(context, node); + } + + if (isTableSetCall(context, node)) { + context.diagnostics.push(invalidTableSetExpression(node)); + return createImmediatelyInvokedFunctionExpression( + [transformTableSetExpression(context, node)], + lua.createNilLiteral() + ); + } + if (ts.isPropertyAccessExpression(node.expression)) { const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index da1c2f124..bf3935b7d 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -5,6 +5,7 @@ import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; +import { isTableNewCall } from "../language-extensions/table"; import { transformLuaTableNewExpression } from "../lua-table"; const builtinErrorTypeNames = new Set([ @@ -53,6 +54,10 @@ export const transformNewExpression: FunctionVisitor = (node, return luaTableResult; } + if (isTableNewCall(context, node)) { + return lua.createTableExpression(undefined, node); + } + const name = context.transformExpression(node.expression); const signature = context.checker.getResolvedSignature(node); const params = node.arguments diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 890695be0..1932a6dc2 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; +import { isTableSetCall, transformTableSetExpression } from "./language-extensions/table"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -11,6 +12,10 @@ export const transformExpressionStatement: FunctionVisitor([ extensions.ExtensionKind.BitwiseNotOperatorMethodType, ]); -function getTypeDeclaration(declaration: ts.Declaration) { - return ts.isTypeAliasDeclaration(declaration) - ? declaration - : findFirstNodeAbove(declaration, ts.isTypeAliasDeclaration); -} - function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { - const signature = context.checker.getResolvedSignature(node); - if (!signature || !signature.declaration) { - return; - } - const typeDeclaration = getTypeDeclaration(signature.declaration); - if (!typeDeclaration) { - return; - } - const type = context.checker.getTypeFromTypeNode(typeDeclaration.type); - return operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); -} - -function isOperatorMapType(context: TransformationContext, type: ts.Type): boolean { - if (type.isUnionOrIntersection()) { - return type.types.some(t => isOperatorMapType(context, t)); - } else { - return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); - } -} - -function isOperatorMapIdentifier(context: TransformationContext, node: ts.Identifier) { - const type = context.checker.getTypeAtLocation(node); - return isOperatorMapType(context, type); + const type = getFunctionTypeForCall(context, node); + return type && operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); } export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { if (ts.isCallExpression(node)) { return getOperatorMapExtensionKindForCall(context, node) !== undefined; } else { - return isOperatorMapIdentifier(context, node); + const type = context.checker.getTypeAtLocation(node); + return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); } } diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts new file mode 100644 index 000000000..b1c26f2d9 --- /dev/null +++ b/src/transformation/visitors/language-extensions/table.ts @@ -0,0 +1,80 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { getFunctionTypeForCall } from "../../utils/typescript"; +import { assert } from "../../../utils"; + +const tableGetExtensions = [extensions.ExtensionKind.TableGetType, extensions.ExtensionKind.TableGetMethodType]; + +const tableSetExtensions = [extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType]; + +const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableGetExtensions, ...tableSetExtensions]; + +function getTableExtensionKindForCall( + context: TransformationContext, + node: ts.CallExpression, + validExtensions: extensions.ExtensionKind[] +) { + const type = getFunctionTypeForCall(context, node); + return type && validExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableExtensionIdentifier(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); +} + +export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; +} + +export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; +} + +export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { + const type = context.checker.getTypeAtLocation(node.expression); + return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); +} + +export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + return lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + node + ); +} + +export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 2 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args.unshift(node.expression.expression); + } + + return lua.createAssignmentStatement( + lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + node + ), + context.transformExpression(args[2]) + ); +} diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap new file mode 100644 index 000000000..9f6113df6 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -0,0 +1,64 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` +"foo = { + (function() + ({}).foo = 3 + return nil + end)() +}" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): code 1`] = ` +"foo = (function() + ({}).foo = 3 + return nil +end)()" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = 3 + return nil + end)() +)" +`; + +exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): code 1`] = `"foo = getTable(_G, 1, 2)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): code 1`] = `"foo = {getTable}"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = [getTable];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): code 1`] = `"foo = tostring(getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = \`\${getTable}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): code 1`] = `"foo = getTable"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = getTable;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): code 1`] = `"foo(_G, getTable)"`; + +exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): diagnostics 1`] = `"main.ts(3,88): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts new file mode 100644 index 000000000..8d3d0fde1 --- /dev/null +++ b/test/unit/language-extensions/table.spec.ts @@ -0,0 +1,137 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidTableExtensionUse, invalidTableSetExpression } from "../../../src/transformation/utils/diagnostics"; + +const tableProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +describe("LuaTableGet & LuaTableSet extensions", () => { + test("stand-alone function", () => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + declare const setTable: LuaTableSet<{}, string, number>; + const tbl = {}; + setTable(tbl, "foo", 3); + const result = getTable(tbl, "foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test("namespace function", () => { + util.testModule` + declare namespace Table { + export const get: LuaTableGet<{}, string, number>; + export const set: LuaTableSet<{}, string, number>; + } + const tbl = {}; + Table.set(tbl, "foo", 3); + const result = Table.get(tbl, "foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test("method", () => { + util.testModule` + interface Table { + get: LuaTableGetMethod; + set: LuaTableSetMethod; + } + const tbl = {} as Table; + tbl.set("foo", 3); + const result = tbl.get("foo"); + export { result } + ` + .setOptions(tableProjectOptions) + .setReturnExport("result") + .expectToEqual(3); + }); + + test.each([ + "const foo: unknown = getTable;", + "const foo = `${getTable}`;", + "declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);", + "const foo = (getTable as any)(1, 2);", + "const foo = [getTable];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const getTable: LuaTableGet<{}, string, number>; + ${statement} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); + + test.each([ + 'const foo = setTable({}, "foo", 3);', + 'const foo = `${setTable({}, "foo", 3)}`;', + 'declare function foo(arg: any): void; foo(setTable({}, "foo", 3));', + 'const foo = [setTable({}, "foo", 3)];', + ])("LuaTableSet invalid use as expression (%p)", expression => { + util.testModule` + declare const setTable: LuaTableSet<{}, string, number>; + ${expression} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableSetExpression.code]); + }); +}); + +describe("LuaTable extension interface", () => { + test("untyped table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("typed table", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 3); + return tbl.get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("object keyed table", () => { + util.testFunction` + interface Key { keyStr: string } + const key: Key = {keyStr: "foo"}; + const tbl = new LuaTable(); + tbl.set(key, 3); + return tbl.get(key); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test("table length", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(1, "foo"); + tbl.set(3, "bar"); + return tbl.length(); + ` + .setOptions(tableProjectOptions) + .expectToEqual(1); + }); + + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( + "table immediate access (%p)", + statement => { + util.testFunction(statement).setOptions(tableProjectOptions).expectToHaveNoDiagnostics(); + } + ); +}); From 0299d71a0e89184f5628b2e77f617fa165e55494 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Mar 2021 19:14:01 +0100 Subject: [PATCH 327/764] Fixed unexpected lua error from Object.GetOwnPropertyDescriptors returning nil (#994) --- src/lualib/ObjectGetOwnPropertyDescriptors.ts | 2 +- test/unit/builtins/object.spec.ts | 24 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts index 9adc0071e..04aee8b51 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptors.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -1,5 +1,5 @@ function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { const metatable = getmetatable(object); if (!metatable) return {}; - return rawget(metatable, "_descriptors"); + return rawget(metatable, "_descriptors") || {}; } diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index cc7e380d6..c6c89a8a8 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -211,3 +211,27 @@ describe("Object.getOwnPropertyDescriptors", () => { `.expectToMatchJsResult(); }); }); + +describe("delete from object", () => { + test("delete from object", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/993 + test("delete from object with metatable", () => { + util.testFunction` + const obj = { foo: "bar", bar: "baz" }; + setmetatable(obj, {}); + delete obj["foo"]; + return obj; + ` + .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") + .expectToEqual({ bar: "baz" }); + }); +}); From 22e60190aa46685e9b0d1a2592e6a52bf2eb5a07 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 4 Mar 2021 21:11:30 +0100 Subject: [PATCH 328/764] Use WASM version of Lua instead of fengari for testing (#996) * Use tstl/lua-wasm-bindings instead of fengari * Removed extra comma * Added missing semicolon * Fix an issue with Lua json encoder not detecting actual Lua Ininfity / NaN * Fixed test cases Most of the tests failed due to incorrect iteration order And unexpected JS/Lua differences * Removed fengari from lockfile * Revert NaN change * Removed unused import * Fixed small mistake * Change Lua vm version from 5.4 to 5.3 * Removed error filter comment and TODO --- jest.config.js | 2 +- package-lock.json | 73 ++---- package.json | 2 +- test/tsconfig.json | 3 +- test/types/fengari.d.ts | 347 ----------------------------- test/unit/builtins/array.spec.ts | 11 +- test/unit/builtins/numbers.spec.ts | 13 +- test/unit/builtins/object.spec.ts | 12 +- test/unit/loops.spec.ts | 17 +- test/util.ts | 49 ++-- 10 files changed, 78 insertions(+), 451 deletions(-) delete mode 100644 test/types/fengari.d.ts diff --git a/jest.config.js b/jest.config.js index 09d82545f..2d390c93d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -17,7 +17,7 @@ module.exports = { preset: "ts-jest", globals: { "ts-jest": { - tsConfig: "/test/tsconfig.json", + tsconfig: "/test/tsconfig.json", diagnostics: { warnOnly: !isCI }, }, }, diff --git a/package-lock.json b/package-lock.json index 4791e9650..59d842844 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,12 +27,12 @@ "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", - "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", + "lua-wasm-bindings": "^0.1.4", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -1460,7 +1460,6 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -3568,8 +3567,7 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -4439,17 +4437,6 @@ "bser": "2.1.1" } }, - "node_modules/fengari": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", - "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", - "dev": true, - "dependencies": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" - } - }, "node_modules/figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -6219,7 +6206,6 @@ "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-serializer": "^26.0.0", "jest-util": "^26.0.1", @@ -8808,6 +8794,12 @@ "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", "dev": true }, + "node_modules/lua-wasm-bindings": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", + "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "dev": true + }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -9668,15 +9660,6 @@ "node": ">=4" } }, - "node_modules/readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -10542,12 +10525,6 @@ "node": ">=0.10.0" } }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "node_modules/sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -10564,6 +10541,11 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, "engines": { "node": ">=0.10.0" } @@ -15318,17 +15300,6 @@ "bser": "2.1.1" } }, - "fengari": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.4.tgz", - "integrity": "sha512-6ujqUuiIYmcgkGz8MGAdERU57EIluGGPSUgGPTsco657EHa+srq0S3/YUl/r9kx1+D+d4rGfYObd+m8K22gB1g==", - "dev": true, - "requires": { - "readline-sync": "^1.4.9", - "sprintf-js": "^1.1.1", - "tmp": "^0.0.33" - } - }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -18856,6 +18827,12 @@ "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", "dev": true }, + "lua-wasm-bindings": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", + "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -19528,12 +19505,6 @@ } } }, - "readline-sync": { - "version": "1.4.9", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz", - "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=", - "dev": true - }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -20254,12 +20225,6 @@ "extend-shallow": "^3.0.0" } }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", diff --git a/package.json b/package.json index 078637493..573394f5a 100644 --- a/package.json +++ b/package.json @@ -56,12 +56,12 @@ "eslint": "^6.8.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", - "fengari": "^0.1.4", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", + "lua-wasm-bindings": "^0.1.4", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" diff --git a/test/tsconfig.json b/test/tsconfig.json index 2c06244c7..86d7c9359 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -3,8 +3,7 @@ "compilerOptions": { "rootDir": "..", "types": ["node", "jest"], - "baseUrl": ".", - "paths": { "*": ["types/*"] } + "baseUrl": "." }, "include": [".", "../src"], "exclude": [ diff --git a/test/types/fengari.d.ts b/test/types/fengari.d.ts deleted file mode 100644 index 8b13b169d..000000000 --- a/test/types/fengari.d.ts +++ /dev/null @@ -1,347 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention, @typescript-eslint/explicit-member-accessibility, @typescript-eslint/class-name-casing */ - -export const FENGARI_AUTHORS: string; -export const FENGARI_COPYRIGHT: string; -export const FENGARI_RELEASE: string; -export const FENGARI_VERSION: string; -export const FENGARI_VERSION_MAJOR: string; -export const FENGARI_VERSION_MINOR: string; -export const FENGARI_VERSION_NUM: number; -export const FENGARI_VERSION_RELEASE: string; -export namespace lauxlib { - const LUA_ERRFILE: number; - const LUA_FILEHANDLE: Uint8Array; - const LUA_LOADED_TABLE: Uint8Array; - const LUA_NOREF: number; - const LUA_PRELOAD_TABLE: Uint8Array; - const LUA_REFNIL: number; - class luaL_Buffer { - L: any; - b: any; - n: any; - } - function luaL_addchar(B: any, c: any): void; - function luaL_addlstring(B: any, s: any, l: any): void; - function luaL_addsize(B: any, s: any): void; - function luaL_addstring(B: any, s: any): void; - function luaL_addvalue(B: any): void; - function luaL_argcheck(L: any, cond: any, arg: any, extramsg: any): void; - function luaL_argerror(L: any, arg: any, extramsg: any): any; - function luaL_buffinit(L: any, B: any): void; - function luaL_buffinitsize(L: any, B: any, sz: any): any; - function luaL_callmeta(L: any, obj: any, event: any): any; - function luaL_checkany(L: any, arg: any): void; - function luaL_checkinteger(L: any, arg: any): any; - function luaL_checklstring(L: any, arg: any): any; - function luaL_checknumber(L: any, arg: any): any; - function luaL_checkoption(L: any, arg: any, def: any, lst: any): any; - function luaL_checkstack(L: any, space: any, msg: any): void; - function luaL_checkstring(L: any, arg: any): any; - function luaL_checktype(L: any, arg: any, t: any): void; - function luaL_checkudata(L: any, ud: any, tname: any): any; - function luaL_checkversion(L: any): void; - function luaL_checkversion_(L: any, ver: any, sz: any): void; - function luaL_dofile(L: any, filename: any): any; - function luaL_dostring(L: any, s: any): any; - function luaL_error(L: any, fmt: any, argp: any): any; - function luaL_execresult(L: any, e: any): any; - function luaL_fileresult(L: any, stat: any, fname: any, e: any): any; - function luaL_getmetafield(L: any, obj: any, event: any): any; - function luaL_getmetatable(L: any, n: any): any; - function luaL_getsubtable(L: any, idx: any, fname: any): any; - function luaL_gsub(L: any, s: any, p: any, r: any): any; - function luaL_len(L: any, idx: any): any; - function luaL_loadbuffer(L: any, s: any, sz: any, n: any): any; - function luaL_loadbufferx(L: any, buff: any, size: any, name: any, mode: any): any; - function luaL_loadfile(L: any, filename: any): any; - function luaL_loadfilex(L: any, filename: any, mode: any): any; - function luaL_loadstring(L: any, s: any): any; - function luaL_newlib(L: any, l: any): void; - function luaL_newlibtable(L: any): void; - function luaL_newmetatable(L: any, tname: any): any; - function luaL_newstate(): any; - function luaL_opt(L: any, f: any, n: any, d: any): any; - function luaL_optinteger(L: any, arg: any, def: any): any; - function luaL_optlstring(L: any, arg: any, def: any): any; - function luaL_optnumber(L: any, arg: any, def: any): any; - function luaL_optstring(L: any, arg: any, def: any): any; - function luaL_prepbuffer(B: any): any; - function luaL_prepbuffsize(B: any, sz: any): any; - function luaL_pushresult(B: any): void; - function luaL_pushresultsize(B: any, sz: any): void; - function luaL_ref(L: any, t: any): any; - function luaL_requiref(L: any, modname: any, openf: any, glb: any): void; - function luaL_setfuncs(L: any, l: any, nup: any): void; - function luaL_setmetatable(L: any, tname: any): void; - function luaL_testudata(L: any, ud: any, tname: any): any; - function luaL_tolstring(L: any, idx: any): any; - function luaL_traceback(L: any, L1: any, msg: any, level: any): void; - function luaL_typename(L: any, i: any): any; - function luaL_unref(L: any, t: any, ref: any): void; - function luaL_where(L: any, level: any): void; - function lua_writestringerror(...args: any[]): void; -} -export namespace lua { - const LUA_AUTHORS: string; - const LUA_COPYRIGHT: string; - const LUA_ERRERR: number; - const LUA_ERRGCMM: number; - const LUA_ERRMEM: number; - const LUA_ERRRUN: number; - const LUA_ERRSYNTAX: number; - const LUA_HOOKCALL: number; - const LUA_HOOKCOUNT: number; - const LUA_HOOKLINE: number; - const LUA_HOOKRET: number; - const LUA_HOOKTAILCALL: number; - const LUA_MASKCALL: number; - const LUA_MASKCOUNT: number; - const LUA_MASKLINE: number; - const LUA_MASKRET: number; - const LUA_MINSTACK: number; - const LUA_MULTRET: number; - const LUA_NUMTAGS: number; - const LUA_OK: number; - const LUA_OPADD: number; - const LUA_OPBAND: number; - const LUA_OPBNOT: number; - const LUA_OPBOR: number; - const LUA_OPBXOR: number; - const LUA_OPDIV: number; - const LUA_OPEQ: number; - const LUA_OPIDIV: number; - const LUA_OPLE: number; - const LUA_OPLT: number; - const LUA_OPMOD: number; - const LUA_OPMUL: number; - const LUA_OPPOW: number; - const LUA_OPSHL: number; - const LUA_OPSHR: number; - const LUA_OPSUB: number; - const LUA_OPUNM: number; - const LUA_REGISTRYINDEX: number; - const LUA_RELEASE: string; - const LUA_RIDX_GLOBALS: number; - const LUA_RIDX_LAST: number; - const LUA_RIDX_MAINTHREAD: number; - const LUA_SIGNATURE: Uint8Array; - const LUA_TBOOLEAN: number; - const LUA_TFUNCTION: number; - const LUA_TLIGHTUSERDATA: number; - const LUA_TNIL: number; - const LUA_TNONE: number; - const LUA_TNUMBER: number; - const LUA_TSTRING: number; - const LUA_TTABLE: number; - const LUA_TTHREAD: number; - const LUA_TUSERDATA: number; - const LUA_VERSION: string; - const LUA_VERSION_MAJOR: string; - const LUA_VERSION_MINOR: string; - const LUA_VERSION_NUM: number; - const LUA_VERSION_RELEASE: string; - const LUA_YIELD: number; - class lua_Debug { - event: any; - name: any; - namewhat: any; - what: any; - source: any; - currentline: any; - linedefined: any; - lastlinedefined: any; - nups: any; - nparams: any; - isvararg: any; - istailcall: any; - short_src: any; - i_ci: any; - } - function lua_absindex(L: any, idx: any): any; - function lua_arith(L: any, op: any): void; - function lua_atnativeerror(L: any, errorf: any): any; - function lua_atpanic(L: any, panicf: any): any; - function lua_call(L: any, n: any, r: any): void; - function lua_callk(L: any, nargs: any, nresults: any, ctx: any, k: any): void; - function lua_checkstack(L: any, n: any): any; - function lua_close(L: any): void; - function lua_compare(L: any, index1: any, index2: any, op: any): any; - function lua_concat(L: any, n: any): void; - function lua_copy(L: any, fromidx: any, toidx: any): void; - function lua_createtable(L: any, narray: any, nrec: any): void; - function lua_dump(L: any, writer: any, data: any, strip: any): any; - function lua_error(L: any): void; - function lua_gc(): void; - function lua_getallocf(): any; - function lua_getextraspace(): any; - function lua_getfield(L: any, idx: any, k: any): any; - function lua_getglobal(L: any, name: any): any; - function lua_gethook(L: any): any; - function lua_gethookcount(L: any): any; - function lua_gethookmask(L: any): any; - function lua_geti(L: any, idx: any, n: any): any; - function lua_getinfo(L: any, what: any, ar: any): any; - function lua_getlocal(L: any, ar: any, n: any): any; - function lua_getmetatable(L: any, objindex: any): any; - function lua_getstack(L: any, level: any, ar: any): any; - function lua_gettable(L: any, idx: any): any; - function lua_gettop(L: any): any; - function lua_getupvalue(L: any, funcindex: any, n: any): any; - function lua_getuservalue(L: any, idx: any): any; - function lua_insert(L: any, idx: any): void; - function lua_isboolean(L: any, n: any): any; - function lua_iscfunction(L: any, idx: any): any; - function lua_isfunction(L: any, idx: any): any; - function lua_isinteger(L: any, idx: any): any; - function lua_islightuserdata(L: any, idx: any): any; - function lua_isnil(L: any, n: any): any; - function lua_isnone(L: any, n: any): any; - function lua_isnoneornil(L: any, n: any): any; - function lua_isnumber(L: any, idx: any): any; - function lua_isproxy(p: any, L: any): any; - function lua_isstring(L: any, idx: any): any; - function lua_istable(L: any, idx: any): any; - function lua_isthread(L: any, idx: any): any; - function lua_isuserdata(L: any, idx: any): any; - function lua_isyieldable(L: any): any; - function lua_len(L: any, idx: any): void; - function lua_load(L: any, reader: any, data: any, chunkname: any, mode: any): any; - function lua_newstate(): any; - function lua_newtable(L: any): void; - function lua_newthread(L: any): any; - function lua_newuserdata(L: any, size: any): any; - function lua_next(L: any, idx: any): any; - function lua_pcall(L: any, n: any, r: any, f: any): any; - function lua_pcallk(L: any, nargs: any, nresults: any, errfunc: any, ctx: any, k: any): any; - function lua_pop(L: any, n: any): void; - function lua_pushboolean(L: any, b: any): void; - function lua_pushcclosure(L: any, fn: any, n: any): void; - function lua_pushcfunction(L: any, fn: any): void; - function lua_pushfstring(L: any, fmt: any, argp: any): any; - function lua_pushglobaltable(L: any): void; - function lua_pushinteger(L: any, n: any): void; - function lua_pushjsclosure(L: any, fn: any, n: any): void; - function lua_pushjsfunction(L: any, fn: any): void; - function lua_pushlightuserdata(L: any, p: any): void; - function lua_pushliteral(L: any, s: any): any; - function lua_pushlstring(L: any, s: any, len: any): any; - function lua_pushnil(L: any): void; - function lua_pushnumber(L: any, n: any): void; - function lua_pushstring(L: any, s: any): any; - function lua_pushthread(L: any): any; - function lua_pushvalue(L: any, idx: any): void; - function lua_pushvfstring(L: any, fmt: any, argp: any): any; - function lua_rawequal(L: any, index1: any, index2: any): any; - function lua_rawget(L: any, idx: any): any; - function lua_rawgeti(L: any, idx: any, n: any): any; - function lua_rawgetp(L: any, idx: any, p: any): any; - function lua_rawlen(L: any, idx: any): any; - function lua_rawset(L: any, idx: any): void; - function lua_rawseti(L: any, idx: any, n: any): void; - function lua_rawsetp(L: any, idx: any, p: any): void; - function lua_register(L: any, n: any, f: any): void; - function lua_remove(L: any, idx: any): void; - function lua_replace(L: any, idx: any): void; - function lua_resume(L: any, from: any, nargs: any): any; - function lua_rotate(L: any, idx: any, n: any): void; - const lua_setallof: any; - function lua_setfield(L: any, idx: any, k: any): void; - function lua_setglobal(L: any, name: any): void; - function lua_sethook(L: any, func: any, mask: any, count: any): void; - function lua_seti(L: any, idx: any, n: any): void; - function lua_setlocal(L: any, ar: any, n: any): any; - function lua_setmetatable(L: any, objindex: any): any; - function lua_settable(L: any, idx: any): void; - function lua_settop(L: any, idx: any): void; - function lua_setupvalue(L: any, funcindex: any, n: any): any; - function lua_setuservalue(L: any, idx: any): void; - function lua_status(L: any): any; - function lua_stringtonumber(L: any, s: any): any; - function lua_toboolean(L: any, idx: any): any; - function lua_tocfunction(L: any, idx: any): any; - function lua_todataview(L: any, idx: any): any; - function lua_tointeger(L: any, idx: any): any; - function lua_tointegerx(L: any, idx: any): any; - function lua_tojsstring(L: any, idx: any): any; - function lua_tolstring(L: any, idx: any): any; - function lua_tonumber(L: any, idx: any): any; - function lua_tonumberx(L: any, idx: any): any; - function lua_topointer(L: any, idx: any): any; - function lua_toproxy(L: any, idx: any): any; - function lua_tostring(L: any, idx: any): LuaString; - function lua_tothread(L: any, idx: any): any; - function lua_touserdata(L: any, idx: any): any; - function lua_type(L: any, idx: any): any; - function lua_typename(L: any, t: any): any; - function lua_upvalueid(L: any, fidx: any, n: any): any; - function lua_upvalueindex(i: any): any; - function lua_upvaluejoin(L: any, fidx1: any, n1: any, fidx2: any, n2: any): void; - function lua_version(L: any): any; - function lua_xmove(from: any, to: any, n: any): void; - function lua_yield(L: any, n: any): void; - function lua_yieldk(L: any, nresults: any, ctx: any, k: any): any; -} -export namespace luaconf { - const LUAI_MAXSTACK: number; - const LUAL_BUFFERSIZE: number; - const LUA_COMPAT_FLOATSTRING: boolean; - const LUA_DIRSEP: string; - const LUA_EXEC_DIR: string; - const LUA_IDSIZE: number; - const LUA_INTEGER_FMT: string; - const LUA_INTEGER_FRMLEN: string; - const LUA_JSDIR: string; - const LUA_JSPATH_DEFAULT: Uint8Array; - const LUA_LDIR: string; - const LUA_MAXINTEGER: number; - const LUA_MININTEGER: number; - const LUA_NUMBER_FMT: string; - const LUA_NUMBER_FRMLEN: string; - const LUA_PATH_DEFAULT: Uint8Array; - const LUA_PATH_MARK: string; - const LUA_PATH_SEP: string; - const LUA_SHRDIR: string; - const LUA_VDIR: string; - function frexp(value: any): any; - function ldexp(mantissa: any, exponent: any): any; - function lua_getlocaledecpoint(): any; - function lua_integer2str(n: any): any; - function lua_number2str(n: any): any; - function lua_numbertointeger(n: any): any; - function luai_apicheck(l: any, e: any): void; -} -export namespace lualib { - const LUA_BITLIBNAME: string; - const LUA_COLIBNAME: string; - const LUA_DBLIBNAME: string; - const LUA_FENGARILIBNAME: string; - const LUA_IOLIBNAME: string; - const LUA_LOADLIBNAME: string; - const LUA_MATHLIBNAME: string; - const LUA_OSLIBNAME: string; - const LUA_STRLIBNAME: string; - const LUA_TABLIBNAME: string; - const LUA_UTF8LIBNAME: string; - const LUA_VERSUFFIX: string; - function luaL_openlibs(L: any): void; - function lua_assert(c: any): void; - function luaopen_coroutine(L: any): any; - function luaopen_debug(L: any): any; - function luaopen_fengari(L: any): any; - function luaopen_io(L: any): any; - function luaopen_math(L: any): any; - function luaopen_os(L: any): any; - function luaopen_package(L: any): any; - function luaopen_string(L: any): any; - function luaopen_table(L: any): any; - function luaopen_utf8(L: any): any; -} - -export type LuaString = number[]; - -export function luastring_eq(a: any, b: any): any; -export function luastring_indexOf(s: any, v: any, i: any): any; -export function luastring_of(): any; -export function to_jsstring(value: LuaString, from?: any, to?: any, replacement_char?: any): string; -export function to_luastring(str: string, cache?: any): LuaString; -export function to_uristring(a: any): any; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 584f686bb..770387aea 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -160,12 +160,21 @@ describe("array.length", () => { util.testExpression`[1, 2, 3].length = ${length}`.expectToEqual(length); }); - test.each([-1, -7, 0.1, NaN, Infinity, -Infinity])("throws on invalid values (%p)", length => { + test.each([-1, -7, 0.1])("throws on invalid values (%p)", length => { util.testFunction` [1, 2, 3].length = ${length}; `.expectToEqual(new util.ExecutionError(`invalid array length: ${length}`)); }); + test.each([NaN, Infinity, -Infinity])("throws on invalid special values (%p)", length => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaSpecialValueString = util.testExpression`(${length}).toString()`.getLuaExecutionResult(); + util.testFunction` + [1, 2, 3].length = ${length}; + `.expectToEqual(new util.ExecutionError(`invalid array length: ${luaSpecialValueString}`)); + }); + test("in array destructuring", () => { util.testFunction` const array = [0, 1, 2]; diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 0ae65efb3..f58209c31 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -56,8 +56,17 @@ test.each(toStringPairs)("(%p).toString(%p)", (value, radix) => { util.testExpressionTemplate`(${value}).toString(${radix})`.expectToMatchJsResult(); }); -test.each([NaN, Infinity, -Infinity])("%p.toString(2)", value => { - util.testExpressionTemplate`(${value}).toString(2)`.expectToMatchJsResult(); +test.each([ + [NaN, "(0/0)"], + [Infinity, "(1/0)"], + [-Infinity, "(-(1/0))"], +])("%p.toString(2)", (value, luaNativeSpecialNum) => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaNativeSpecialNumString = util.testExpression`${luaNativeSpecialNum}.toString()`.getLuaExecutionResult(); + // Cannot use expectToMatchJsResult because this actually wont be the same in JS in Lua + // TODO fix this in lualib/NumberToString.ts + util.testExpressionTemplate`(${value}).toString(2)`.expectToEqual(luaNativeSpecialNumString); }); test.each(cases)("isNaN(%p)", value => { diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index c6c89a8a8..fb0fe26ba 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -11,15 +11,21 @@ test.each([ }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { - util.testExpressionTemplate`Object.entries(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.entries(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.keys (%p)", obj => { - util.testExpressionTemplate`Object.keys(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.keys(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each([{}, { abc: "def" }, { abc: 3, def: "xyz" }])("Object.values (%p)", obj => { - util.testExpressionTemplate`Object.values(${obj})`.expectToMatchJsResult(); + const testBuilder = util.testExpressionTemplate`Object.values(${obj})`; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test.each(["[]", '[["a", 1], ["b", 2]]', '[["a", 1], ["a", 2]]', 'new Map([["foo", "bar"]])'])( diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index c644776e5..8e9c22373 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -573,7 +573,7 @@ test("do...while double-negation", () => { }); test("for...in with pre-defined variable", () => { - util.testFunction` + const testBuilder = util.testFunction` const obj = { x: "y", foo: "bar" }; let x = ""; @@ -582,16 +582,23 @@ test("for...in with pre-defined variable", () => { result.push(x); } return result; - `.expectToMatchJsResult(); + `; + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect(testBuilder.getJsExecutionResult()).toEqual(expect.arrayContaining(testBuilder.getLuaExecutionResult())); }); test("for...in with pre-defined variable keeps last value", () => { - util.testFunction` - const obj = { x: "y", foo: "bar" }; + const keyX = "x"; + const keyFoo = "foo"; + + const result = util.testFunction` + const obj = { ${keyX}: "y", ${keyFoo}: "bar" }; let x = ""; for (x in obj) { } return x; - `.expectToMatchJsResult(); + `.getLuaExecutionResult(); + // Need custom matcher because order is not guaranteed in neither JS nor Lua + expect([keyX, keyFoo]).toContain(result); }); diff --git a/test/util.ts b/test/util.ts index 67cfcef57..a93b54995 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,7 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib, to_jsstring, to_luastring } from "fengari"; +import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.53"; +import { LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -10,32 +11,8 @@ import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -export function toByteCode(luaCode: string) { - const L = lauxlib.luaL_newstate(); - - if (lauxlib.luaL_loadstring(L, to_luastring(luaCode)) !== lua.LUA_OK) throw Error(lua.lua_tojsstring(L, -1)); - - const writer = (_: any, newBytes: Uint8Array, size: number, data: number[]) => { - data.push(...newBytes.slice(0, size)); - return 0; - }; - - const data: number[] = []; - - const dumpExitCode = lua.lua_dump(L, writer, data, false); - - if (dumpExitCode !== 0) { - throw Error("Unable to dump byte code"); - } - - return Uint8Array.from(data); -} - const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const jsonLibByteCode = toByteCode(jsonLib); - const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); -const luaLibByteCode = toByteCode(luaLib); // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; @@ -369,7 +346,7 @@ export abstract class TestBuilder { // Json lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, jsonLibByteCode); + lauxlib.luaL_loadstring(L, jsonLib); lua.lua_setfield(L, -2, "json"); // Lua lib if ( @@ -378,7 +355,7 @@ export abstract class TestBuilder { ) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, luaLibByteCode); + lauxlib.luaL_loadstring(L, luaLib); lua.lua_setfield(L, -2, "lualib_bundle"); } @@ -392,7 +369,7 @@ export abstract class TestBuilder { if (transpiledExtraFile?.lua) { lua.lua_getglobal(L, "package"); lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, to_luastring(transpiledExtraFile.lua)); + lauxlib.luaL_loadstring(L, transpiledExtraFile.lua); lua.lua_setfield(L, -2, fileName.replace(".ts", "")); } }); @@ -404,20 +381,22 @@ return JSON.stringify((function() ${this.getLuaCodeWithWrapper(mainFile)} end)());`; - const status = lauxlib.luaL_dostring(L, to_luastring(wrappedMainCode)); + const status = lauxlib.luaL_dostring(L, wrappedMainCode); - if (status === lua.LUA_OK) { + if (status === LUA_OK) { if (lua.lua_isstring(L, -1)) { - const result = eval(`(${lua.lua_tojsstring(L, -1)})`); + const result = eval(`(${lua.lua_tostring(L, -1)})`); + lua.lua_close(L); return result === null ? undefined : result; } else { - const returnType = to_jsstring(lua.lua_typename(L, lua.lua_type(L, -1))); + const returnType = lua.lua_typename(L, lua.lua_type(L, -1)); + lua.lua_close(L); throw new Error(`Unsupported Lua return type: ${returnType}`); } } else { - // Filter out control characters appearing on some systems - const luaStackString = lua.lua_tostring(L, -1).filter(c => c >= 20); - const message = to_jsstring(luaStackString).replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + const luaStackString = lua.lua_tostring(L, -1); + const message = luaStackString.replace(/^\[string "(--)?\.\.\."\]:\d+: /, ""); + lua.lua_close(L); return new ExecutionError(message); } } From f6a92c09275696eedc61e43463ac62a98b01da3a Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Fri, 5 Mar 2021 18:45:15 +0100 Subject: [PATCH 329/764] Remove phantom, metaExtension, extension, pureAbstract (#998) And replace the deprecation warning with an error Progress on #953 --- src/transformation/utils/diagnostics.ts | 30 +-- .../visitors/binary-expression/index.ts | 6 +- src/transformation/visitors/class/index.ts | 208 +++++------------- .../visitors/class/members/fields.ts | 5 +- .../visitors/class/members/method.ts | 15 +- src/transformation/visitors/class/new.ts | 6 +- src/transformation/visitors/class/utils.ts | 9 +- src/transformation/visitors/modules/import.ts | 10 +- src/transformation/visitors/namespace.ts | 7 +- .../__snapshots__/transformation.spec.ts.snap | 37 ---- .../transformation/classExtension1.ts | 4 - .../transformation/classExtension2.ts | 7 - .../transformation/classExtension3.ts | 9 - .../transformation/classExtension4.ts | 6 - .../transformation/classPureAbstract.ts | 3 - .../transformation/namespacePhantom.ts | 4 - .../__snapshots__/deprecated.spec.ts.snap | 34 ++- .../__snapshots__/extension.spec.ts.snap | 68 ------ .../__snapshots__/metaExtension.spec.ts.snap | 23 -- test/unit/annotations/deprecated.spec.ts | 14 +- test/unit/annotations/extension.spec.ts | 35 --- test/unit/annotations/metaExtension.spec.ts | 50 ----- 22 files changed, 113 insertions(+), 477 deletions(-) delete mode 100644 test/translation/transformation/classExtension1.ts delete mode 100644 test/translation/transformation/classExtension2.ts delete mode 100644 test/translation/transformation/classExtension3.ts delete mode 100644 test/translation/transformation/classExtension4.ts delete mode 100644 test/translation/transformation/classPureAbstract.ts delete mode 100644 test/translation/transformation/namespacePhantom.ts delete mode 100644 test/unit/annotations/__snapshots__/extension.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap delete mode 100644 test/unit/annotations/extension.spec.ts delete mode 100644 test/unit/annotations/metaExtension.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 9b34e9547..4086ee0f2 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -58,30 +58,6 @@ export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const extensionCannotConstruct = createErrorDiagnosticFactory( - "Cannot construct classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionCannotExtend = createErrorDiagnosticFactory( - "Cannot extend classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionCannotExport = createErrorDiagnosticFactory( - "Cannot export classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionInvalidInstanceOf = createErrorDiagnosticFactory( - "Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -); - -export const extensionAndMetaExtensionConflict = createErrorDiagnosticFactory( - "Cannot use both '@extension' and '@metaExtension' annotations on the same class." -); - -export const metaExtensionMissingExtends = createErrorDiagnosticFactory( - "'@metaExtension' annotation requires the extension of the metatable class." -); - export const invalidForRangeCall = createErrorDiagnosticFactory( (message: string) => `Invalid @forRange call: ${message}.` ); @@ -182,6 +158,12 @@ export const invalidTableSetExpression = createErrorDiagnosticFactory( "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); +export const annotationRemoved = createErrorDiagnosticFactory( + (kind: AnnotationKind) => + `'@${kind}' has been removed and will no longer have any effect.` + + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` +); + export const annotationDeprecated = createWarningDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 001591c01..d9e4746e0 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { extensionInvalidInstanceOf, luaTableInvalidInstanceOf } from "../../utils/diagnostics"; +import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -109,10 +109,6 @@ export const transformBinaryExpression: FunctionVisitor = ( const rhsType = context.checker.getTypeAtLocation(node.right); const annotations = getTypeAnnotations(rhsType); - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionInvalidInstanceOf(node)); - } - if (annotations.has(AnnotationKind.LuaTable)) { context.diagnostics.push(luaTableInvalidInstanceOf(node)); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index d9da80cf7..8b40eadcd 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -3,19 +3,10 @@ import * as lua from "../../../LuaAST"; import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { - annotationDeprecated, - extensionAndMetaExtensionConflict, - extensionCannotExport, - extensionCannotExtend, - luaTableCannotBeExtended, - luaTableMustBeAmbient, - metaExtensionMissingExtends, -} from "../../utils/diagnostics"; +import { annotationRemoved, luaTableCannotBeExtended, luaTableMustBeAmbient } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, - getIdentifierExportScope, hasDefaultExportModifier, isSymbolExported, } from "../../utils/export"; @@ -28,7 +19,6 @@ import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { popScope, pushScope, ScopeType } from "../../utils/scope"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; -import { transformPropertyName } from "../literal"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; @@ -90,25 +80,11 @@ function transformClassLikeDeclaration( const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); - // Find out if this class is extension of existing class - const extensionDirective = annotations.get(AnnotationKind.Extension); - const isExtension = extensionDirective !== undefined; - const isMetaExtension = annotations.has(AnnotationKind.MetaExtension); - - if (isExtension) { - context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.Extension)); + if (annotations.has(AnnotationKind.Extension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.Extension)); } - if (isMetaExtension) { - context.diagnostics.push(annotationDeprecated(classDeclaration, AnnotationKind.MetaExtension)); - } - - if (isExtension && isMetaExtension) { - context.diagnostics.push(extensionAndMetaExtensionConflict(classDeclaration)); - } - - if ((isExtension || isMetaExtension) && getIdentifierExportScope(context, className) !== undefined) { - // Cannot export extension classes - context.diagnostics.push(extensionCannotExport(classDeclaration)); + if (annotations.has(AnnotationKind.MetaExtension)) { + context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.MetaExtension)); } // Get type that is extended @@ -122,14 +98,6 @@ function transformClassLikeDeclaration( checkForLuaLibType(context, extendedType); } - if (!(isExtension || isMetaExtension) && extendedType) { - // Non-extensions cannot extend extension classes - const extendsAnnotations = getTypeAnnotations(extendedType); - if (extendsAnnotations.has(AnnotationKind.Extension) || extendsAnnotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotExtend(classDeclaration)); - } - } - // You cannot extend LuaTable classes if (extendedType) { const annotations = getTypeAnnotations(extendedType); @@ -150,43 +118,6 @@ function transformClassLikeDeclaration( const result: lua.Statement[] = []; - // Overwrite the original className with the class we are overriding for extensions - if (isMetaExtension) { - if (extendedType) { - const extendsName = lua.createStringLiteral(extendedType.symbol.name); - className = lua.createIdentifier("__meta__" + extendsName.value); - - // local className = debug.getregistry()["extendsName"] - const assignDebugCallIndex = lua.createVariableDeclarationStatement( - className, - lua.createTableIndexExpression( - lua.createCallExpression( - lua.createTableIndexExpression( - lua.createIdentifier("debug"), - lua.createStringLiteral("getregistry") - ), - [] - ), - extendsName - ), - classDeclaration - ); - - result.push(assignDebugCallIndex); - } else { - context.diagnostics.push(metaExtensionMissingExtends(classDeclaration)); - } - } - - if (extensionDirective !== undefined) { - const [extensionName] = extensionDirective.args; - if (extensionName) { - className = lua.createIdentifier(extensionName); - } else if (extendedType) { - className = lua.createIdentifier(extendedType.symbol.name); - } - } - let localClassName: lua.Identifier; if (isUnsafeName(className.text)) { localClassName = lua.createIdentifier( @@ -200,82 +131,60 @@ function transformClassLikeDeclaration( localClassName = className; } - if (!isExtension && !isMetaExtension) { - result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - } else { - for (const f of instanceFields) { - const fieldName = transformPropertyName(context, f.name); - - const value = f.initializer !== undefined ? context.transformExpression(f.initializer) : undefined; + result.push(...createClassSetup(context, classDeclaration, className, localClassName, extendedType)); - // className["fieldName"] - const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); - - // className["fieldName"] = value; - const assignClassField = lua.createAssignmentStatement(classField, value); + // Find first constructor with body + const constructor = classDeclaration.members.find( + (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + ); - result.push(assignClassField); - } - } + if (constructor) { + // Add constructor plus initialization of instance fields + const constructorResult = transformConstructorDeclaration( + context, + constructor, + localClassName, + instanceFields, + classDeclaration + ); - // Find first constructor with body - if (!isExtension && !isMetaExtension) { - const constructor = classDeclaration.members.find( - (n): n is ts.ConstructorDeclaration => ts.isConstructorDeclaration(n) && n.body !== undefined + if (constructorResult) result.push(constructorResult); + } else if (!extendedType) { + // Generate a constructor if none was defined in a base class + const constructorResult = transformConstructorDeclaration( + context, + ts.createConstructor([], [], [], ts.createBlock([], true)), + localClassName, + instanceFields, + classDeclaration ); - if (constructor) { - // Add constructor plus initialization of instance fields - const constructorResult = transformConstructorDeclaration( - context, - constructor, - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if (!extendedType) { - // Generate a constructor if none was defined in a base class - const constructorResult = transformConstructorDeclaration( - context, - ts.createConstructor([], [], [], ts.createBlock([], true)), - localClassName, - instanceFields, - classDeclaration - ); - - if (constructorResult) result.push(constructorResult); - } else if (instanceFields.length > 0) { - // Generate a constructor if none was defined in a class with instance fields that need initialization - // localClassName.prototype.____constructor = function(self, ...) - // baseClassName.prototype.____constructor(self, ...) - // ... - const constructorBody = transformClassInstanceFields(context, instanceFields); - const superCall = lua.createExpressionStatement( - lua.createCallExpression( - lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), - lua.createStringLiteral("____constructor") - ), - [createSelfIdentifier(), lua.createDotsLiteral()] - ) - ); - constructorBody.unshift(superCall); - const constructorFunction = lua.createFunctionExpression( - lua.createBlock(constructorBody), - [createSelfIdentifier()], - lua.createDotsLiteral(), - lua.FunctionExpressionFlags.Declaration - ); - result.push( - lua.createAssignmentStatement( - createConstructorName(localClassName), - constructorFunction, - classDeclaration - ) - ); - } + if (constructorResult) result.push(constructorResult); + } else if (instanceFields.length > 0) { + // Generate a constructor if none was defined in a class with instance fields that need initialization + // localClassName.prototype.____constructor = function(self, ...) + // baseClassName.prototype.____constructor(self, ...) + // ... + const constructorBody = transformClassInstanceFields(context, instanceFields); + const superCall = lua.createExpressionStatement( + lua.createCallExpression( + lua.createTableIndexExpression( + context.transformExpression(ts.createSuper()), + lua.createStringLiteral("____constructor") + ), + [createSelfIdentifier(), lua.createDotsLiteral()] + ) + ); + constructorBody.unshift(superCall); + const constructorFunction = lua.createFunctionExpression( + lua.createBlock(constructorBody), + [createSelfIdentifier()], + lua.createDotsLiteral(), + lua.FunctionExpressionFlags.Declaration + ); + result.push( + lua.createAssignmentStatement(createConstructorName(localClassName), constructorFunction, classDeclaration) + ); } // Transform accessors @@ -290,18 +199,17 @@ function transformClassLikeDeclaration( } } - const noPrototype = isExtension || isMetaExtension; const decorationStatements: lua.Statement[] = []; for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { - const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + const expression = createPropertyDecoratingExpression(context, member, localClassName); if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } else if (ts.isMethodDeclaration(member)) { - const statement = transformMethodDeclaration(context, member, localClassName, noPrototype); + const statement = transformMethodDeclaration(context, member, localClassName); if (statement) result.push(statement); if (member.body) { - const statement = createMethodDecoratingExpression(context, member, localClassName, noPrototype); + const statement = createMethodDecoratingExpression(context, member, localClassName); if (statement) decorationStatements.push(statement); } } else if (ts.isPropertyDeclaration(member)) { @@ -309,7 +217,7 @@ function transformClassLikeDeclaration( const statement = transformStaticPropertyDeclaration(context, member, localClassName); if (statement) decorationStatements.push(statement); } - const expression = createPropertyDecoratingExpression(context, member, localClassName, noPrototype); + const expression = createPropertyDecoratingExpression(context, member, localClassName); if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } } diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 5d07033dd..980c6f851 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -9,12 +9,11 @@ import { transformMemberExpressionOwnerName } from "./method"; export function createPropertyDecoratingExpression( context: TransformationContext, node: ts.PropertyDeclaration | ts.AccessorDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Expression | undefined { if (!node.decorators) return; const propertyName = transformPropertyName(context, node.name); - const propertyOwnerTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const propertyOwnerTable = transformMemberExpressionOwnerName(node, className); return createDecoratingExpression( context, node.kind, diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 24cd77f44..c902ea8de 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -11,10 +11,9 @@ import { isNonNull } from "../../../../utils"; export function transformMemberExpressionOwnerName( node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Expression { - return isStaticNode(node) || noPrototype ? lua.cloneIdentifier(className) : createPrototypeName(className); + return isStaticNode(node) ? lua.cloneIdentifier(className) : createPrototypeName(className); } export function transformMethodName(context: TransformationContext, node: ts.MethodDeclaration): lua.Expression { @@ -28,13 +27,12 @@ export function transformMethodName(context: TransformationContext, node: ts.Met export function transformMethodDeclaration( context: TransformationContext, node: ts.MethodDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Statement | undefined { // Don't transform methods without body (overload declarations) if (!node.body) return; - const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); @@ -48,10 +46,9 @@ export function transformMethodDeclaration( export function createMethodDecoratingExpression( context: TransformationContext, node: ts.MethodDeclaration, - className: lua.Identifier, - noPrototype: boolean + className: lua.Identifier ): lua.Statement | undefined { - const methodTable = transformMemberExpressionOwnerName(node, className, noPrototype); + const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); const parameterDecorators = node.parameters diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index bf3935b7d..1a9c5e8aa 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount, extensionCannotConstruct } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; @@ -70,10 +70,6 @@ export const transformNewExpression: FunctionVisitor = (node, const annotations = getTypeAnnotations(type); - if (annotations.has(AnnotationKind.Extension) || annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(extensionCannotConstruct(node)); - } - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 88388adf8..aea06680a 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationDeprecated } from "../../utils/diagnostics"; +import { annotationRemoved } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -20,13 +20,12 @@ export function getExtendedNode( const superType = context.checker.getTypeAtLocation(extendsClause.types[0]); const annotations = getTypeAnnotations(superType); - if (!annotations.has(AnnotationKind.PureAbstract)) { - return extendsClause.types[0]; - } if (annotations.has(AnnotationKind.PureAbstract)) { - context.diagnostics.push(annotationDeprecated(extendsClause, AnnotationKind.PureAbstract)); + context.diagnostics.push(annotationRemoved(extendsClause, AnnotationKind.PureAbstract)); } + + return extendsClause.types[0]; } export function getExtendedType( diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 34fa216d6..d36bb0509 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -3,7 +3,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getSymbolAnnotations, getTypeAnnotations } from "../../utils/annotations"; +import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; import { createSafeName } from "../../utils/safe-names"; @@ -60,13 +60,7 @@ export function createModuleRequire( } function shouldBeImported(context: TransformationContext, importNode: ts.ImportClause | ts.ImportSpecifier): boolean { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(importNode)); - - return ( - context.resolver.isReferencedAliasDeclaration(importNode) && - !annotations.has(AnnotationKind.Extension) && - !annotations.has(AnnotationKind.MetaExtension) - ); + return context.resolver.isReferencedAliasDeclaration(importNode); } function transformImportSpecifier( diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 3316ace4b..0244ac21c 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationDeprecated } from "../utils/diagnostics"; +import { annotationRemoved } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, @@ -53,9 +53,8 @@ const currentNamespaces = new WeakMap = (node, context) => { const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); // If phantom namespace elide the declaration and return the body - if (annotations.has(AnnotationKind.Phantom) && node.body && ts.isModuleBlock(node.body)) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Phantom)); - return context.transformStatements(node.body.statements); + if (annotations.has(AnnotationKind.Phantom)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Phantom)); } const currentNamespace = currentNamespaces.get(context); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index a299f2640..7fd968b00 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -24,38 +24,6 @@ escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \ nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. ((\\"Level 1: \\\\n\\\\t\\\\t \\" .. ((\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\"" `; -exports[`Transformation (classExtension1) 1`] = ` -"function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension2) 1`] = ` -"function TestClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension3) 1`] = ` -"function RenamedTestClass.myFunction(self) -end -function RenamedMyClass.myFunction(self) -end" -`; - -exports[`Transformation (classExtension4) 1`] = ` -"MyClass.test = \\"test\\" -MyClass.testP = \\"testP\\" -function MyClass.myFunction(self) -end" -`; - -exports[`Transformation (classPureAbstract) 1`] = ` -"require(\\"lualib_bundle\\"); -ClassB = __TS__Class() -ClassB.name = \\"ClassB\\" -function ClassB.prototype.____constructor(self) -end" -`; - exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 @@ -262,11 +230,6 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; -exports[`Transformation (namespacePhantom) 1`] = ` -"function nsMember(self) -end" -`; - exports[`Transformation (returnDefault) 1`] = ` "function myFunc(self) return diff --git a/test/translation/transformation/classExtension1.ts b/test/translation/transformation/classExtension1.ts deleted file mode 100644 index 5df5bdeac..000000000 --- a/test/translation/transformation/classExtension1.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @extension */ -class MyClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension2.ts b/test/translation/transformation/classExtension2.ts deleted file mode 100644 index 11145e9d5..000000000 --- a/test/translation/transformation/classExtension2.ts +++ /dev/null @@ -1,7 +0,0 @@ -/** @extension */ -class TestClass {} - -/** @extension */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension3.ts b/test/translation/transformation/classExtension3.ts deleted file mode 100644 index 3fa37f05e..000000000 --- a/test/translation/transformation/classExtension3.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** @extension RenamedTestClass */ -class TestClass { - public myFunction() {} -} - -/** @extension RenamedMyClass */ -class MyClass extends TestClass { - public myFunction() {} -} diff --git a/test/translation/transformation/classExtension4.ts b/test/translation/transformation/classExtension4.ts deleted file mode 100644 index 8cb996079..000000000 --- a/test/translation/transformation/classExtension4.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @extension */ -class MyClass { - public test: string = "test"; - private testP: string = "testP"; - public myFunction() {} -} diff --git a/test/translation/transformation/classPureAbstract.ts b/test/translation/transformation/classPureAbstract.ts deleted file mode 100644 index d9a661160..000000000 --- a/test/translation/transformation/classPureAbstract.ts +++ /dev/null @@ -1,3 +0,0 @@ -/** @pureAbstract */ -declare class ClassA {} -class ClassB extends ClassA {} diff --git a/test/translation/transformation/namespacePhantom.ts b/test/translation/transformation/namespacePhantom.ts deleted file mode 100644 index 2f003c28e..000000000 --- a/test/translation/transformation/namespacePhantom.ts +++ /dev/null @@ -1,4 +0,0 @@ -/** @phantom */ -namespace myNamespace { - function nsMember() {} -} diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 5be0a22b4..3b1d5e2af 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -1,12 +1,22 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`extension deprecation: code 1`] = `""`; +exports[`extension removed: code 1`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; -exports[`extension deprecation: code 2`] = `"local __meta__A = debug.getregistry().A"`; +exports[`extension removed: code 2`] = ` +"require(\\"lualib_bundle\\"); +B = __TS__Class() +B.name = \\"B\\" +__TS__ClassExtends(B, A)" +`; -exports[`extension deprecation: diagnostics 1`] = `"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; +exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@extension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; -exports[`extension deprecation: diagnostics 2`] = `"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; +exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; exports[`forRange deprecation: code 1`] = ` "for i = 1, 10 do @@ -15,19 +25,21 @@ end" exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; -exports[`phantom deprecation: code 1`] = ` -"function nsMember(self) +exports[`phantom removed: code 1`] = ` +"A = A or ({}) +do + local function nsMember(self) + end end" `; -exports[`phantom deprecation: diagnostics 1`] = `"main.ts(3,9): warning TSTL: '@phantom' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; +exports[`phantom removed: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@phantom' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; -exports[`pureAbstract deprecation: code 1`] = ` +exports[`pureAbstract removed: code 1`] = ` "require(\\"lualib_bundle\\"); ClassB = __TS__Class() ClassB.name = \\"ClassB\\" -function ClassB.prototype.____constructor(self) -end" +__TS__ClassExtends(ClassB, ClassA)" `; -exports[`pureAbstract deprecation: diagnostics 1`] = `"main.ts(4,22): warning TSTL: '@pureAbstract' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; +exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; diff --git a/test/unit/annotations/__snapshots__/extension.spec.ts.snap b/test/unit/annotations/__snapshots__/extension.spec.ts.snap deleted file mode 100644 index 606d21635..000000000 --- a/test/unit/annotations/__snapshots__/extension.spec.ts.snap +++ /dev/null @@ -1,68 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Class construct extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -b = __TS__New(B)" -`; - -exports[`Class construct extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class construct extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -b = __TS__New(B)" -`; - -exports[`Class construct extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class extends extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`Class extends extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -C = __TS__Class() -C.name = \\"C\\" -__TS__ClassExtends(C, B)" -`; - -exports[`Class extends extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,9): error TSTL: Cannot extend classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`instanceof extension ("extension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("extension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@extension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information. -main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`instanceof extension ("metaExtension"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta__A = debug.getregistry().A -result = __TS__InstanceOf(foo, B)" -`; - -exports[`instanceof extension ("metaExtension"): diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(6,24): error TSTL: Cannot use instanceof on classes with '@extension' or '@metaExtension' annotation." -`; diff --git a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap b/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap deleted file mode 100644 index ad3f2ac51..000000000 --- a/test/unit/annotations/__snapshots__/metaExtension.spec.ts.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`DontAllowInstantiation: code 1`] = ` -"require(\\"lualib_bundle\\"); -local __meta___LOADED = debug.getregistry()._LOADED -e = __TS__New(Ext)" -`; - -exports[`DontAllowInstantiation: diagnostics 1`] = ` -"main.ts(4,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information. -main.ts(5,19): error TSTL: Cannot construct classes with '@extension' or '@metaExtension' annotation." -`; - -exports[`IncorrectUsage: code 1`] = ` -"function LoadedExt.test(self) - return 5 -end" -`; - -exports[`IncorrectUsage: diagnostics 1`] = ` -"main.ts(3,9): error TSTL: '@metaExtension' annotation requires the extension of the metatable class. -main.ts(3,9): warning TSTL: '@metaExtension' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information." -`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 4fe836014..072ff6372 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -1,29 +1,29 @@ -import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; +import { annotationDeprecated, annotationRemoved } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; -test.each(["extension", "metaExtension"])("extension deprecation", extensionType => { +test.each(["extension", "metaExtension"])("extension removed", extensionType => { util.testModule` declare class A {} /** @${extensionType} **/ class B extends A {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("phantom deprecation", () => { +test("phantom removed", () => { util.testModule` /** @phantom **/ namespace A { function nsMember() {} } - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("pureAbstract deprecation", () => { +test("pureAbstract removed", () => { util.testModule` /** @pureAbstract */ declare class ClassA {} class ClassB extends ClassA {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); test("forRange deprecation", () => { diff --git a/test/unit/annotations/extension.spec.ts b/test/unit/annotations/extension.spec.ts deleted file mode 100644 index 27093801b..000000000 --- a/test/unit/annotations/extension.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { - annotationDeprecated, - extensionCannotConstruct, - extensionCannotExtend, - extensionInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test.each(["extension", "metaExtension"])("Class extends extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - class C extends B {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotExtend.code]); -}); - -test.each(["extension", "metaExtension"])("Class construct extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - const b = new B(); - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); -}); - -test.each(["extension", "metaExtension"])("instanceof extension (%p)", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} **/ - class B extends A {} - declare const foo: any; - const result = foo instanceof B; - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionInvalidInstanceOf.code]); -}); diff --git a/test/unit/annotations/metaExtension.spec.ts b/test/unit/annotations/metaExtension.spec.ts deleted file mode 100644 index b0fa56578..000000000 --- a/test/unit/annotations/metaExtension.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - annotationDeprecated, - extensionCannotConstruct, - metaExtensionMissingExtends, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test("MetaExtension", () => { - const tsHeader = ` - declare class _LOADED {} - declare namespace debug { - function getregistry(): any; - } - /** @metaExtension */ - class LoadedExt extends _LOADED { - public static test() { - return 5; - } - } - `; - - // Can't use expectToMatchJsResult because above is not valid TS/JS - util.testModule` - export default debug.getregistry()["_LOADED"].test(); - ` - .setTsHeader(tsHeader) - .ignoreDiagnostics([annotationDeprecated.code]) - .setReturnExport("default") - .expectToEqual(5); -}); - -test("IncorrectUsage", () => { - util.testModule` - /** @metaExtension */ - class LoadedExt { - public static test() { - return 5; - } - } - `.expectDiagnosticsToMatchSnapshot([metaExtensionMissingExtends.code, annotationDeprecated.code]); -}); - -test("DontAllowInstantiation", () => { - util.testModule` - declare class _LOADED {} - /** @metaExtension */ - class Ext extends _LOADED {} - const e = new Ext(); - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code, extensionCannotConstruct.code]); -}); From 5dffb6b8e4e84c37327fc7be4b4e482bc161c8b2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 5 Mar 2021 22:22:25 +0100 Subject: [PATCH 330/764] Official support for Lua 5.4 --- src/CompilerOptions.ts | 1 + test/cli/parse.spec.ts | 1 + .../__snapshots__/expressions.spec.ts.snap | 100 ++++++++++++++++++ test/unit/builtins/math.spec.ts | 1 + test/unit/expressions.spec.ts | 14 +++ .../language-extensions/operators.spec.ts | 2 +- test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 6 +- test/util.ts | 4 +- 9 files changed, 125 insertions(+), 5 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 889a5837a..439b29652 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -49,6 +49,7 @@ export enum LuaTarget { Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", + Lua54 = "5.4", LuaJIT = "JIT", } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 6b6349f9b..cb441ca2f 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -221,6 +221,7 @@ describe("tsconfig", () => { ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], + ["luaTarget", "5.4", { luaTarget: tstl.LuaTarget.Lua54 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], ["luaBundle", "foo", { luaBundle: "foo" }], diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index b743ed0c8..03bb46230 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -335,6 +335,87 @@ ____exports.__result = a | b return ____exports" `; +exports[`Bitop [5.4] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = ~a +return ____exports" +`; + +exports[`Bitop [5.4] ("a&=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a & b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = a & b +return ____exports" +`; + +exports[`Bitop [5.4] ("a<<=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a << b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a<>>=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Bitop [5.4] ("a^=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a ~ b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = a ~ b +return ____exports" +`; + +exports[`Bitop [5.4] ("a|=b") 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a | b + return a +end)() +return ____exports" +`; + +exports[`Bitop [5.4] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = a | b +return ____exports" +`; + exports[`Bitop [JIT] ("~a") 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) @@ -553,3 +634,22 @@ return ____exports" `; exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): code 1`] = ` +"local ____exports = {} +____exports.__result = (function() + a = a >> b + return a +end)() +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; + +exports[`Unsupported bitop 5.4 ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Unsupported bitop 5.4 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index faaeacbcd..8267cd0b3 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -34,6 +34,7 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); test("Math.atan2(4, 5)", () => { diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index fd6c8ab0d..9a874577f 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -77,6 +77,13 @@ test.each(supportedInAll)("Bitop [5.3] (%p)", input => { .expectLuaToMatchSnapshot(); }); +test.each(supportedInAll)("Bitop [5.4] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) @@ -84,6 +91,13 @@ test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); +test.each(unsupportedIn53)("Unsupported bitop 5.4 (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); +}); + test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( "Binary expressions ordering parentheses (%p)", input => { diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index 4559ff7e6..c84f8aac9 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -6,7 +6,7 @@ import { LuaTarget } from "../../../src"; import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; const operatorsProjectOptions: tstl.CompilerOptions = { - luaTarget: LuaTarget.Lua53, + luaTarget: LuaTarget.Lua54, types: [path.resolve(__dirname, "../../../language-extensions")], }; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 8e9c22373..987f53628 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -534,6 +534,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, + [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, }); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 3384b60fb..831b68842 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -77,7 +77,8 @@ describe("in function call", () => { [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); }); @@ -88,7 +89,8 @@ describe("in array literal", () => { [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); test("of array literal /w OmittedExpression", () => { diff --git a/test/util.ts b/test/util.ts index a93b54995..616d6cde9 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.53"; +import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.54"; import { LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; @@ -109,7 +109,7 @@ export abstract class TestBuilder { } private options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua53, + luaTarget: tstl.LuaTarget.Lua54, noHeader: true, skipLibCheck: true, target: ts.ScriptTarget.ES2017, From 079f215c1aa95cb2550a6101de94f0385210cfbb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 5 Mar 2021 22:36:37 +0100 Subject: [PATCH 331/764] Renamed unsupportedIn53 variable --- test/unit/expressions.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 9a874577f..71c014fda 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -46,8 +46,8 @@ test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions }); const supportedInAll = ["~a", "a&b", "a&=b", "a|b", "a|=b", "a^b", "a^=b", "a<>>b", "a>>>=b"]; -const unsupportedIn53 = ["a>>b", "a>>=b"]; -const allBinaryOperators = [...supportedInAll, ...unsupportedIn53]; +const unsupportedIn53And54 = ["a>>b", "a>>=b"]; +const allBinaryOperators = [...supportedInAll, ...unsupportedIn53And54]; test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception util.testExpression(input) @@ -84,14 +84,14 @@ test.each(supportedInAll)("Bitop [5.4] (%p)", input => { .expectLuaToMatchSnapshot(); }); -test.each(unsupportedIn53)("Unsupported bitop 5.3 (%p)", input => { +test.each(unsupportedIn53And54)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); -test.each(unsupportedIn53)("Unsupported bitop 5.4 (%p)", input => { +test.each(unsupportedIn53And54)("Unsupported bitop 5.4 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua54, luaLibImport: tstl.LuaLibImportKind.None }) .disableSemanticCheck() From b84686ffc7c5b00bbc517041f094b4b4b569eea4 Mon Sep 17 00:00:00 2001 From: Yan Soares Couto Date: Sat, 6 Mar 2021 17:19:48 +0000 Subject: [PATCH 332/764] Fix destructuring assignment of multiReturn (closes #995) (#997) * Fix destructuring assignment of multiReturn (closes #995) Added a test. * Rename test and add test for null return * Splitting tests --- .../visitors/variable-declaration.ts | 10 ++++--- .../__snapshots__/multi.spec.ts.snap | 4 ++- test/unit/language-extensions/multi.spec.ts | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 12f6717c4..d9f1624c1 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -6,7 +6,7 @@ import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall } from "../utils/lua-ast"; +import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; @@ -158,9 +158,11 @@ export function transformBindingVariableDeclaration( // Contain the expression in a temporary variable table = lua.createAnonymousIdentifier(); if (initializer) { - statements.push( - lua.createVariableDeclarationStatement(table, context.transformExpression(initializer)) - ); + let expression = context.transformExpression(initializer); + if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + expression = wrapInTable(expression); + } + statements.push(lua.createVariableDeclarationStatement(table, expression)); } } statements.push(...transformBindingPattern(context, bindingPattern, table)); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index a280fe331..b2b679d30 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -69,7 +69,9 @@ exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"mai exports[`invalid $multi call (const {} = $multi();): code 1`] = ` "local ____ = { - ____(_G) + { + ____(_G) + } }" `; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 0b99cf4dc..5d59aa4d0 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -24,6 +24,33 @@ test("multi example use case", () => { .expectToEqual({ a: "foo", b: 5 }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/995 +test("Destructuring assignment of LuaMultiReturn", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return $multi(1, 2, 3); + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: 1, b: [2, 3] }); +}); + +test("Destructuring assignment of LuaMultiReturn returning nil", () => { + util.testModule` + function multiReturn(): LuaMultiReturn<[number, number, number]> { + return; + } + + const [a, ...b] = multiReturn(); + export {a, b}; + ` + .setOptions(multiProjectOptions) + .expectToEqual({ a: undefined, b: [] }); +}); + test.each<[string, any]>([ ["$multi()", undefined], ["$multi(true)", true], From 0d22c0d9c4b9e6e40a8998acd6296944a2a0c102 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 6 Mar 2021 10:21:10 -0700 Subject: [PATCH 333/764] Vararg Update (#992) * wip vararg extension * vararg spread optimization working with handling for hoisting * refactoring and tests * deprecation test * updates from feedback * clarity for isOptimizableVarargSpread Co-authored-by: Tom --- language-extensions/index.d.ts | 6 + src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/Generator.ts | 4 +- src/lualib/New.ts | 2 +- src/lualib/declarations/tstl.d.ts | 3 - src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 9 +- src/transformation/utils/lua-ast.ts | 2 + src/transformation/utils/scope.ts | 42 ++- src/transformation/utils/symbols.ts | 7 +- src/transformation/utils/transform.ts | 22 ++ .../visitors/binary-expression/assignments.ts | 63 ++-- .../visitors/binary-expression/compound.ts | 58 ++-- .../visitors/binary-expression/index.ts | 12 +- src/transformation/visitors/call.ts | 96 +++--- src/transformation/visitors/class/index.ts | 21 +- src/transformation/visitors/function.ts | 22 +- src/transformation/visitors/identifier.ts | 7 + src/transformation/visitors/index.ts | 3 +- .../visitors/language-extensions/multi.ts | 4 +- .../visitors/language-extensions/range.ts | 2 +- .../visitors/language-extensions/vararg.ts | 16 + src/transformation/visitors/spread.ts | 82 +++++ src/transformation/visitors/template.ts | 26 +- test/unit/__snapshots__/spread.spec.ts.snap | 127 ++++++++ .../__snapshots__/deprecated.spec.ts.snap | 10 + test/unit/annotations/deprecated.spec.ts | 11 + test/unit/annotations/vararg.spec.ts | 7 +- .../__snapshots__/multi.spec.ts.snap | 36 +-- .../__snapshots__/vararg.spec.ts.snap | 37 +++ test/unit/language-extensions/vararg.spec.ts | 38 +++ test/unit/spread.spec.ts | 301 ++++++++++++++++++ 34 files changed, 914 insertions(+), 172 deletions(-) create mode 100644 src/transformation/utils/transform.ts create mode 100644 src/transformation/visitors/language-extensions/vararg.ts create mode 100644 src/transformation/visitors/spread.ts create mode 100644 test/unit/__snapshots__/spread.spec.ts.snap create mode 100644 test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap create mode 100644 test/unit/language-extensions/vararg.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index e5d3096a3..ad3692a97 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -34,6 +34,12 @@ declare type LuaMultiReturn = T & LuaExtension<"__luaMultiRetur declare const $range: ((start: number, limit: number, step?: number) => Iterable) & LuaExtension<"__luaRangeFunctionBrand">; +/** + * Transpiles to the global vararg (`...`) + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + */ +declare const $vararg: string[] & LuaExtension<"__luaVarargConstantBrand">; + /** * Represents a Lua-style iterator which is returned from a LuaIterable. * For simple iterators (with no state), this is just a function. diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index edb6825e6..c8ea2de50 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduce( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: T[] ): T { const len = arr.length; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 8e5336f61..a0d5933d2 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -3,7 +3,7 @@ function __TS__ArrayReduceRight( this: void, arr: T[], callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: Vararg + ...initial: T[] ): T { const len = arr.length; diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 1b0bf9cff..0fae685e8 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: Vararg): T[] { +function __TS__ArraySplice(this: void, list: T[], ...args: unknown[]): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index a71740761..1573f5ec3 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -8,7 +8,7 @@ function __TS__GeneratorIterator(this: GeneratorIterator) { return this; } -function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { +function __TS__GeneratorNext(this: GeneratorIterator, ...args: any[]) { const co = this.____coroutine; if (coroutine.status(co) === "dead") return { done: true }; @@ -19,7 +19,7 @@ function __TS__GeneratorNext(this: GeneratorIterator, ...args: Vararg) { } function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { - return function (this: void, ...args: Vararg): GeneratorIterator { + return function (this: void, ...args: any[]): GeneratorIterator { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil diff --git a/src/lualib/New.ts b/src/lualib/New.ts index 507ba120c..8b33ec837 100644 --- a/src/lualib/New.ts +++ b/src/lualib/New.ts @@ -1,4 +1,4 @@ -function __TS__New(this: void, target: LuaClass, ...args: Vararg): any { +function __TS__New(this: void, target: LuaClass, ...args: any[]): any { const instance: any = setmetatable({}, target.prototype); instance.____constructor(...args); return instance; diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 4a718a31a..f68237190 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,8 +1,5 @@ /** @noSelfInFile */ -/** @vararg */ -type Vararg = T & { __luaVararg?: never }; - interface Metatable { _descriptors?: Record; __index?: any; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 4086ee0f2..422a93cac 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -64,6 +64,10 @@ export const invalidForRangeCall = createErrorDiagnosticFactory( export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); +export const invalidVarargUse = createErrorDiagnosticFactory( + "$vararg can only be used in a spread element ('...$vararg') in global scope." +); + export const invalidRangeControlVariable = createErrorDiagnosticFactory( "For loop using $range must declare a single control variable." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index cb17987ad..2991204c2 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -5,6 +5,7 @@ export enum ExtensionKind { MultiFunction = "MultiFunction", MultiType = "MultiType", RangeFunction = "RangeFunction", + VarargConstant = "VarargConstant", IterableType = "IterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", @@ -49,15 +50,17 @@ export enum ExtensionKind { TableSetMethodType = "TableSetMethodType", } -const extensionKindToFunctionName: { [T in ExtensionKind]?: string } = { +const extensionKindToValueName: { [T in ExtensionKind]?: string } = { [ExtensionKind.MultiFunction]: "$multi", [ExtensionKind.RangeFunction]: "$range", + [ExtensionKind.VarargConstant]: "$vararg", }; const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", [ExtensionKind.MultiType]: "__luaMultiReturnBrand", [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", + [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", [ExtensionKind.IterableType]: "__luaIterableBrand", [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", @@ -107,13 +110,13 @@ export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): bo return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; } -export function isExtensionFunction( +export function isExtensionValue( context: TransformationContext, symbol: ts.Symbol, extensionKind: ExtensionKind ): boolean { return ( - symbol.getName() === extensionKindToFunctionName[extensionKind] && + symbol.getName() === extensionKindToValueName[extensionKind] && symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) ); } diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 91e81bc9a..5f3a21e4a 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -62,6 +62,8 @@ export function getNumberLiteralValue(expression?: lua.Expression) { return undefined; } +// Prefer use of transformToImmediatelyInvokedFunctionExpression to maintain correct scope. If you use this directly, +// ensure you push/pop a function scope appropriately to avoid incorrect vararg optimization. export function createImmediatelyInvokedFunctionExpression( statements: lua.Statement[], result: lua.Expression | lua.Expression[], diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 2c9f267dd..200b65860 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { assert, getOrUpdate, isNonNull } from "../../utils"; import { TransformationContext } from "../context"; import { getSymbolInfo } from "./symbols"; -import { getFirstDeclarationInFile } from "./typescript"; +import { findFirstNodeAbove, getFirstDeclarationInFile } from "./typescript"; export enum ScopeType { File = 1 << 0, @@ -24,6 +24,7 @@ interface FunctionDefinitionInfo { export interface Scope { type: ScopeType; id: number; + node?: ts.Node; referencedSymbols?: Map; variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; @@ -91,6 +92,45 @@ export function popScope(context: TransformationContext): Scope { return scope; } +function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { + return symbol?.declarations.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); +} + +// Checks for references to local functions which haven't been defined yet, +// and thus will be hoisted above the current position. +export function hasReferencedUndefinedLocalFunction(context: TransformationContext, scope: Scope) { + if (!scope.referencedSymbols || !scope.node) { + return false; + } + for (const [symbolId, nodes] of scope.referencedSymbols) { + const type = context.checker.getTypeAtLocation(nodes[0]); + if ( + !scope.functionDefinitions?.has(symbolId) && + type.getCallSignatures().length > 0 && + isDeclaredInScope(type.symbol, scope.node) + ) { + return true; + } + } + return false; +} + +export function hasReferencedSymbol(context: TransformationContext, scope: Scope, symbol: ts.Symbol) { + if (!scope.referencedSymbols) { + return; + } + for (const nodes of scope.referencedSymbols.values()) { + if (nodes.some(node => context.checker.getSymbolAtLocation(node) === symbol)) { + return true; + } + } + return false; +} + +export function isFunctionScopeWithDefinition(scope: Scope): scope is Scope & { node: ts.SignatureDeclaration } { + return scope.node !== undefined && ts.isFunctionLike(scope.node); +} + export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { const scope = peekScope(context); let result = statements; diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index c99b41a25..f800eea86 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; +import { isOptimizedVarArgSpread } from "../visitors/spread"; import { markSymbolAsReferencedInCurrentScopes } from "./scope"; const symbolIdCounters = new WeakMap(); @@ -44,7 +45,11 @@ export function trackSymbolReference( symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); } - markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + // If isOptimizedVarArgSpread returns true, the identifier will not appear in the resulting Lua. + // Only the optimized ellipses (...) will be used. + if (!isOptimizedVarArgSpread(context, symbol, identifier)) { + markSymbolAsReferencedInCurrentScopes(context, symbolId, identifier); + } return symbolId; } diff --git a/src/transformation/utils/transform.ts b/src/transformation/utils/transform.ts new file mode 100644 index 000000000..215a018d5 --- /dev/null +++ b/src/transformation/utils/transform.ts @@ -0,0 +1,22 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { castArray } from "../../utils"; +import { TransformationContext } from "../context"; +import { createImmediatelyInvokedFunctionExpression } from "./lua-ast"; +import { ScopeType, pushScope, popScope } from "./scope"; + +export interface ImmediatelyInvokedFunctionParameters { + statements: lua.Statement | lua.Statement[]; + result: lua.Expression | lua.Expression[]; +} + +export function transformToImmediatelyInvokedFunctionExpression( + context: TransformationContext, + transformFunction: () => ImmediatelyInvokedFunctionParameters, + tsOriginal?: ts.Node +): lua.CallExpression { + pushScope(context, ScopeType.Function); + const { statements, result } = transformFunction(); + popScope(context); + return createImmediatelyInvokedFunctionExpression(castArray(statements), result, tsOriginal); +} diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index df99a2a7d..0b1b7fe70 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -5,13 +5,18 @@ import { TransformationContext } from "../../context"; import { isTupleReturnCall } from "../../utils/annotations"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; +import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -68,6 +73,25 @@ export function transformAssignment( ]; } +function transformDestructuredAssignmentExpression( + context: TransformationContext, + expression: ts.DestructuringAssignment +): ImmediatelyInvokedFunctionParameters { + const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + + let right = context.transformExpression(expression.right); + if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { + right = wrapInTable(right); + } + + const statements = [ + lua.createVariableDeclarationStatement(rootIdentifier, right), + ...transformDestructuringAssignment(context, expression, rootIdentifier), + ]; + + return { statements, result: rootIdentifier }; +} + export function transformAssignmentExpression( context: TransformationContext, expression: ts.AssignmentExpression @@ -89,19 +113,11 @@ export function transformAssignmentExpression( } if (isDestructuringAssignment(expression)) { - const rootIdentifier = lua.createAnonymousIdentifier(expression.left); - - let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { - right = wrapInTable(right); - } - - const statements = [ - lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier), - ]; - - return createImmediatelyInvokedFunctionExpression(statements, rootIdentifier, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformDestructuredAssignmentExpression(context, expression), + expression + ); } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { @@ -120,6 +136,7 @@ export function transformAssignmentExpression( indexParameter, valueParameter, ]); + pushScope(context, ScopeType.Function); const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { @@ -134,15 +151,19 @@ export function transformAssignmentExpression( } const args = [objExpression, indexExpression, context.transformExpression(expression.right)]; + popScope(context); return lua.createCallExpression(iife, args, expression); } else { - // Simple assignment - // (function() ${left} = ${right}; return ${left} end)() - const left = context.transformExpression(expression.left); - const right = context.transformExpression(expression.right); - return createImmediatelyInvokedFunctionExpression( - transformAssignment(context, expression.left, right), - left, + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + // Simple assignment + // (function() ${left} = ${right}; return ${left} end)() + const left = context.transformExpression(expression.left); + const right = context.transformExpression(expression.right); + const statements = transformAssignment(context, expression.left, right); + return { statements, result: left }; + }, expression ); } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 3b92ade58..7a11454c8 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -2,7 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { createImmediatelyInvokedFunctionExpression } from "../../utils/lua-ast"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../../utils/transform"; import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; import { transformBinaryOperation } from "../binary-expression"; import { transformAssignment } from "./assignments"; @@ -75,15 +78,14 @@ export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; -export function transformCompoundAssignmentExpression( +export function transformCompoundAssignment( context: TransformationContext, expression: ts.Expression, - // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -): lua.CallExpression { +): ImmediatelyInvokedFunctionParameters { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const right = context.transformExpression(rhs); @@ -116,11 +118,7 @@ export function transformCompoundAssignmentExpression( assignStatement = lua.createAssignmentStatement(accessExpression, tmp); } // return ____tmp - return createImmediatelyInvokedFunctionExpression( - [objAndIndexDeclaration, tmpDeclaration, assignStatement], - tmp, - expression - ); + return { statements: [objAndIndexDeclaration, tmpDeclaration, assignStatement], result: tmp }; } else if (isPostfix) { // Postfix expressions need to cache original value in temp // local ____tmp = ${left}; @@ -130,11 +128,7 @@ export function transformCompoundAssignmentExpression( const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); const operatorExpression = transformBinaryOperation(context, tmpIdentifier, right, operator, expression); const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____tmp = ${left} ${replacementOperator} ${right}; @@ -146,27 +140,39 @@ export function transformCompoundAssignmentExpression( const assignStatements = transformAssignment(context, lhs, tmpIdentifier); if (isSetterSkippingCompoundAssignmentOperator(operator)) { - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs)], - tmpIdentifier, - expression - ); + const statements = [ + tmpDeclaration, + ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs), + ]; + return { statements, result: tmpIdentifier }; } - return createImmediatelyInvokedFunctionExpression( - [tmpDeclaration, ...assignStatements], - tmpIdentifier, - expression - ); + return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { // Simple expressions // ${left} = ${right}; return ${right} const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); - const assignStatements = transformAssignment(context, lhs, operatorExpression); - return createImmediatelyInvokedFunctionExpression(assignStatements, left, expression); + const statements = transformAssignment(context, lhs, operatorExpression); + return { statements, result: left }; } } +export function transformCompoundAssignmentExpression( + context: TransformationContext, + expression: ts.Expression, + // TODO: Change type to ts.LeftHandSideExpression? + lhs: ts.Expression, + rhs: ts.Expression, + operator: CompoundAssignmentToken, + isPostfix: boolean +): lua.CallExpression { + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix), + expression + ); +} + export function transformCompoundAssignmentStatement( context: TransformationContext, node: ts.Node, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index d9e4746e0..26e90ad67 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; -import { createImmediatelyInvokedFunctionExpression, wrapInToStringForConcat } from "../../utils/lua-ast"; +import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; @@ -16,6 +16,7 @@ import { unwrapCompoundAssignmentToken, } from "./compound"; import { assert } from "../../../utils"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -121,9 +122,12 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.CommaToken: { - return createImmediatelyInvokedFunctionExpression( - context.transformStatements(ts.createExpressionStatement(node.left)), - context.transformExpression(node.right), + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ + statements: context.transformStatements(ts.createExpressionStatement(node.left)), + result: context.transformExpression(node.right), + }), node ); } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 7ea22eb34..75f73db88 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,16 +2,16 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; -import { createImmediatelyInvokedFunctionExpression, createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; -import { isArrayType, isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; +import { isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { transformLuaTableCallExpression } from "./lua-table"; -import { shouldMultiReturnCallBeWrapped, returnsMultiType } from "./language-extensions/multi"; +import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { isTableGetCall, @@ -20,6 +20,10 @@ import { transformTableSetExpression, } from "./language-extensions/table"; import { invalidTableSetExpression } from "../utils/diagnostics"; +import { + ImmediatelyInvokedFunctionParameters, + transformToImmediatelyInvokedFunctionExpression, +} from "../utils/transform"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -113,10 +117,32 @@ export function transformArguments( return parameters; } +function transformElementAccessCall( + context: TransformationContext, + left: ts.PropertyAccessExpression | ts.ElementAccessExpression, + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature +): ImmediatelyInvokedFunctionParameters { + const transformedArguments = transformArguments(context, args, signature, ts.factory.createIdentifier("____self")); + + // Cache left-side if it has effects + // (function() local ____self = context; return ____self[argument](parameters); end)() + const argument = ts.isElementAccessExpression(left) + ? transformElementAccessArgument(context, left) + : lua.createStringLiteral(left.name.text); + const selfIdentifier = lua.createIdentifier("____self"); + const callContext = context.transformExpression(left.expression); + const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); + const index = lua.createTableIndexExpression(selfIdentifier, argument); + const callExpression = lua.createCallExpression(index, transformedArguments); + return { statements: selfAssignment, result: callExpression }; +} + export function transformContextualCallExpression( context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, - transformedArguments: lua.Expression[] + args: ts.Expression[] | ts.NodeArray, + signature?: ts.Signature ): lua.Expression { const left = ts.isCallExpression(node) ? node.expression : node.tag; if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { @@ -126,32 +152,25 @@ export function transformContextualCallExpression( return lua.createMethodCallExpression( table, lua.createIdentifier(left.name.text, left.name), - transformedArguments, + transformArguments(context, args, signature), node ); } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { - const callContext = context.transformExpression(left.expression); if (isExpressionWithEvaluationEffect(left.expression)) { - // Inject context parameter - transformedArguments.unshift(lua.createIdentifier("____self")); - - // Cache left-side if it has effects - // (function() local ____self = context; return ____self[argument](parameters); end)() - const argument = ts.isElementAccessExpression(left) - ? transformElementAccessArgument(context, left) - : lua.createStringLiteral(left.name.text); - const selfIdentifier = lua.createIdentifier("____self"); - const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); - const index = lua.createTableIndexExpression(selfIdentifier, argument); - const callExpression = lua.createCallExpression(index, transformedArguments); - return createImmediatelyInvokedFunctionExpression([selfAssignment], callExpression, node); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => transformElementAccessCall(context, left, args, signature), + node + ); } else { + const callContext = context.transformExpression(left.expression); const expression = context.transformExpression(left); + const transformedArguments = transformArguments(context, args, signature); return lua.createCallExpression(expression, [callContext, ...transformedArguments]); } } else if (ts.isIdentifier(left)) { - const callContext = context.isStrict ? lua.createNilLiteral() : lua.createIdentifier("_G"); - transformedArguments.unshift(callContext); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); + const transformedArguments = transformArguments(context, args, signature, callContext); const expression = context.transformExpression(left); return lua.createCallExpression(expression, transformedArguments, node); } else { @@ -168,17 +187,17 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal return lua.createCallExpression(context.transformExpression(node.expression), parameters); } - const parameters = transformArguments(context, node.arguments, signature); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // table:name() - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { const table = context.transformExpression(node.expression.expression); // table.name() const name = node.expression.name.text; const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); + const parameters = transformArguments(context, node.arguments, signature); return lua.createCallExpression(callPath, parameters, node); } } @@ -186,13 +205,13 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); - const parameters = transformArguments(context, node.arguments, signature); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { // A contextual parameter must be given to this call expression - return transformContextualCallExpression(context, node, parameters); + return transformContextualCallExpression(context, node, node.arguments, signature); } else { // No context const expression = context.transformExpression(node.expression); + const parameters = transformArguments(context, node.arguments, signature); return lua.createCallExpression(expression, parameters); } } @@ -227,9 +246,10 @@ export const transformCallExpression: FunctionVisitor = (node if (isTableSetCall(context, node)) { context.diagnostics.push(invalidTableSetExpression(node)); - return createImmediatelyInvokedFunctionExpression( - [transformTableSetExpression(context, node)], - lua.createNilLiteral() + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableSetExpression(context, node), result: lua.createNilLiteral() }), + node ); } @@ -272,21 +292,3 @@ export const transformCallExpression: FunctionVisitor = (node const callExpression = lua.createCallExpression(callPath, parameters, node); return wrapResult ? wrapInTable(callExpression) : callExpression; }; - -// TODO: Currently it's also used as an array member -export const transformSpreadElement: FunctionVisitor = (node, context) => { - const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) return innerExpression; - if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; - - if (ts.isIdentifier(node.expression) && isVarargType(context, node.expression)) { - return lua.createDotsLiteral(node); - } - - const type = context.checker.getTypeAtLocation(node.expression); - if (isArrayType(context, type)) { - return createUnpackCall(context, innerExpression, node); - } - - return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); -}; diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 8b40eadcd..9963c09f4 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -10,13 +10,9 @@ import { hasDefaultExportModifier, isSymbolExported, } from "../../utils/export"; -import { - createImmediatelyInvokedFunctionExpression, - createSelfIdentifier, - unwrapVisitorResult, -} from "../../utils/lua-ast"; +import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; -import { popScope, pushScope, ScopeType } from "../../utils/scope"; +import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; @@ -50,11 +46,14 @@ export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, context: TransformationContext ): lua.Expression { - pushScope(context, ScopeType.Function); - const { statements, name } = transformClassLikeDeclaration(expression, context); - popScope(context); - - return createImmediatelyInvokedFunctionExpression(unwrapVisitorResult(statements), name, expression); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => { + const { statements, name } = transformClassLikeDeclaration(expression, context); + return { statements: unwrapVisitorResult(statements), result: name }; + }, + expression + ); } const classSuperInfos = new WeakMap(); diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index d3fb88a5a..cb1d29bfd 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isVarargType } from "../utils/annotations"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { @@ -38,7 +37,7 @@ function transformParameterDefaultValueDeclaration( return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); } -function isRestParameterReferenced(context: TransformationContext, identifier: lua.Identifier, scope: Scope): boolean { +function isRestParameterReferenced(identifier: lua.Identifier, scope: Scope): boolean { if (!identifier.symbolId) { return true; } @@ -46,11 +45,7 @@ function isRestParameterReferenced(context: TransformationContext, identifier: l return false; } const references = scope.referencedSymbols.get(identifier.symbolId); - if (!references) { - return false; - } - // Ignore references to @vararg types in spread elements - return references.some(r => !r.parent || !ts.isSpreadElement(r.parent) || !isVarargType(context, r)); + return references !== undefined && references.length > 0; } export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { @@ -99,7 +94,7 @@ export function transformFunctionBodyHeader( } // Push spread operator here - if (spreadIdentifier && isRestParameterReferenced(context, spreadIdentifier, bodyScope)) { + if (spreadIdentifier && isRestParameterReferenced(spreadIdentifier, bodyScope)) { const spreadTable = wrapInTable(lua.createDotsLiteral()); headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } @@ -114,9 +109,11 @@ export function transformFunctionBody( context: TransformationContext, parameters: ts.NodeArray, body: ts.ConciseBody, - spreadIdentifier?: lua.Identifier + spreadIdentifier?: lua.Identifier, + node?: ts.FunctionLikeDeclaration ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); + scope.node = node; const bodyStatements = transformFunctionBodyContent(context, body); const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); @@ -195,7 +192,8 @@ export function transformFunctionToExpression( context, node.parameters, node.body, - spreadIdentifier + spreadIdentifier, + node ); const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), @@ -236,6 +234,10 @@ export function transformFunctionLikeDeclaration( // Only wrap if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); + // We cannot use transformToImmediatelyInvokedFunctionExpression() here because we need to transpile + // the function first to determine if it's self-referencing. Fortunately, this does not cause issues + // with var-arg optimization because the IIFE is just wrapping another function which will already push + // another scope. return createImmediatelyInvokedFunctionExpression( [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], lua.cloneIdentifier(nameIdentifier) diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 5905f1485..191319160 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -8,6 +8,7 @@ import { invalidMultiFunctionUse, invalidOperatorMappingUse, invalidRangeUse, + invalidVarargUse, invalidTableExtensionUse, } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; @@ -18,6 +19,7 @@ import { isMultiFunctionNode } from "./language-extensions/multi"; import { isOperatorMapping } from "./language-extensions/operators"; import { isRangeFunctionNode } from "./language-extensions/range"; import { isTableExtensionIdentifier } from "./language-extensions/table"; +import { isVarargConstantNode } from "./language-extensions/vararg"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isMultiFunctionNode(context, identifier)) { @@ -38,6 +40,11 @@ export function transformIdentifier(context: TransformationContext, identifier: return lua.createAnonymousIdentifier(identifier); } + if (isVarargConstantNode(context, identifier)) { + context.diagnostics.push(invalidVarargUse(identifier)); + return lua.createAnonymousIdentifier(identifier); + } + if (isForRangeType(context, identifier)) { const callExpression = findFirstNodeAbove(identifier, ts.isCallExpression); if (!callExpression || !callExpression.parent || !ts.isForOfStatement(callExpression.parent)) { diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 48469a84b..b9983ae31 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -4,7 +4,8 @@ import { transformElementAccessExpression, transformPropertyAccessExpression, tr import { transformBinaryExpression } from "./binary-expression"; import { transformBlock } from "./block"; import { transformBreakStatement, transformContinueStatement } from "./break-continue"; -import { transformCallExpression, transformSpreadElement } from "./call"; +import { transformCallExpression } from "./call"; +import { transformSpreadElement } from "./spread"; import { transformClassAsExpression, transformClassDeclaration, diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index b292d9aa1..85b3c6a29 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -25,7 +25,7 @@ export function isMultiReturnCall(context: TransformationContext, expression: ts export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.MultiFunction) : false; + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.MultiFunction) : false; } export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { @@ -98,7 +98,7 @@ export function findMultiAssignmentViolations( if (!ts.isShorthandPropertyAssignment(element)) continue; const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); if (valueSymbol) { - if (extensions.isExtensionFunction(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { + if (extensions.isExtensionValue(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { context.diagnostics.push(invalidMultiFunctionUse(element)); result.push(element); } diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts index 00a3c249e..43f297a9a 100644 --- a/src/transformation/visitors/language-extensions/range.ts +++ b/src/transformation/visitors/language-extensions/range.ts @@ -14,7 +14,7 @@ export function isRangeFunction(context: TransformationContext, expression: ts.C export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionFunction(context, symbol, extensions.ExtensionKind.RangeFunction) : false; + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.RangeFunction) : false; } function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { diff --git a/src/transformation/visitors/language-extensions/vararg.ts b/src/transformation/visitors/language-extensions/vararg.ts new file mode 100644 index 000000000..99eea82a9 --- /dev/null +++ b/src/transformation/visitors/language-extensions/vararg.ts @@ -0,0 +1,16 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../../context"; +import * as extensions from "../../utils/language-extensions"; +import { Scope, ScopeType } from "../../utils/scope"; + +export function isGlobalVarargConstant(context: TransformationContext, symbol: ts.Symbol, scope: Scope) { + return ( + scope.type === ScopeType.File && + extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) + ); +} + +export function isVarargConstantNode(context: TransformationContext, node: ts.Node): boolean { + const symbol = context.checker.getSymbolAtLocation(node); + return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) : false; +} diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts new file mode 100644 index 000000000..ca5e2fb85 --- /dev/null +++ b/src/transformation/visitors/spread.ts @@ -0,0 +1,82 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { createUnpackCall } from "../utils/lua-ast"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { + findScope, + hasReferencedSymbol, + hasReferencedUndefinedLocalFunction, + isFunctionScopeWithDefinition, + ScopeType, +} from "../utils/scope"; +import { isArrayType } from "../utils/typescript"; +import { returnsMultiType } from "./language-extensions/multi"; +import { annotationDeprecated } from "../utils/diagnostics"; +import { isGlobalVarargConstant } from "./language-extensions/vararg"; + +export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { + if (!ts.isSpreadElement(identifier.parent)) { + return false; + } + + // Walk up, stopping at any scope types which could stop optimization + const scope = findScope(context, ScopeType.Function | ScopeType.Try | ScopeType.Catch | ScopeType.File); + if (!scope) { + return; + } + + // $vararg global constant + if (isGlobalVarargConstant(context, symbol, scope)) { + return true; + } + + // Scope must be a function scope associated with a real ts function + if (!isFunctionScopeWithDefinition(scope)) { + return false; + } + + // Identifier must be a vararg in the local function scope's parameters + const isSpreadParameter = (p: ts.ParameterDeclaration) => + p.dotDotDotToken && ts.isIdentifier(p.name) && context.checker.getSymbolAtLocation(p.name) === symbol; + if (!scope.node.parameters.some(isSpreadParameter)) { + return false; + } + + // De-optimize if already referenced outside of a spread, as the array may have been modified + if (hasReferencedSymbol(context, scope, symbol)) { + return false; + } + + // De-optimize if a function is being hoisted from below to above, as it may have modified the array + if (hasReferencedUndefinedLocalFunction(context, scope)) { + return false; + } + return true; +} + +// TODO: Currently it's also used as an array member +export const transformSpreadElement: FunctionVisitor = (node, context) => { + if (ts.isIdentifier(node.expression)) { + if (isVarargType(context, node.expression)) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Vararg)); + return lua.createDotsLiteral(node); + } + const symbol = context.checker.getSymbolAtLocation(node.expression); + if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { + return lua.createDotsLiteral(node); + } + } + + const innerExpression = context.transformExpression(node.expression); + if (isTupleReturnCall(context, node.expression)) return innerExpression; + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; + + const type = context.checker.getTypeAtLocation(node.expression); + if (isArrayType(context, type)) { + return createUnpackCall(context, innerExpression, node); + } + + return transformLuaLibFunction(context, LuaLibFeature.Spread, node, innerExpression); +}; diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 1b714d765..9f9a19b33 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -65,29 +65,35 @@ export const transformTaggedTemplateExpression: FunctionVisitor lua.createTableFieldExpression(lua.createStringLiteral(text))) + const rawStringsArray = ts.factory.createArrayLiteralExpression( + rawStrings.map(text => ts.factory.createStringLiteral(text)) ); - const stringTableLiteral = lua.createTableExpression([ - ...strings.map(partialString => lua.createTableFieldExpression(lua.createStringLiteral(partialString))), - lua.createTableFieldExpression(rawStringsTable, lua.createStringLiteral("raw")), + const stringObject = ts.factory.createObjectLiteralExpression([ + ...strings.map((partialString, i) => + ts.factory.createPropertyAssignment( + ts.factory.createNumericLiteral(i + 1), + ts.factory.createStringLiteral(partialString) + ) + ), + ts.factory.createPropertyAssignment("raw", rawStringsArray), ]); + expressions.unshift(stringObject); + // Evaluate if there is a self parameter to be used. const signature = context.checker.getResolvedSignature(expression); const signatureDeclaration = signature?.getDeclaration(); const useSelfParameter = signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; - // Argument evaluation. - const callArguments = transformArguments(context, expressions, signature); - callArguments.unshift(stringTableLiteral); - if (useSelfParameter) { - return transformContextualCallExpression(context, expression, callArguments); + return transformContextualCallExpression(context, expression, expressions, signature); } + // Argument evaluation. + const callArguments = transformArguments(context, expressions, signature); + const leftHandSideExpression = context.transformExpression(expression.tag); return lua.createCallExpression(leftHandSideExpression, callArguments); }; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap new file mode 100644 index 000000000..f16bc746a --- /dev/null +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -0,0 +1,127 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`vararg spread optimization $multi 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function multi(self, ...) + return ... + end + local function test(self, ...) + return select( + 2, + multi(nil, ...) + ) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization basic use 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization block statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + local result + do + result = pick(nil, ...) + end + return result + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization body-less arrow function 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(____, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization finally clause 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + do + pcall( + function() + error(\\"foobar\\", 0) + end + ) + do + return pick(nil, ...) + end + end + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization if statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + if true then + return pick(nil, ...) + end + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + +exports[`vararg spread optimization loop statement 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + repeat + do + return pick(nil, ...) + end + until not false + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 3b1d5e2af..750b0596f 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -43,3 +43,13 @@ __TS__ClassExtends(ClassB, ClassA)" `; exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; + +exports[`vararg deprecation: code 1`] = ` +"function foo(self, ...) +end +function vararg(self, ...) + foo(_G, ...) +end" +`; + +exports[`vararg deprecation: diagnostics 1`] = `"main.ts(6,17): warning TSTL: '@vararg' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 072ff6372..9c81b2176 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -33,3 +33,14 @@ test("forRange deprecation", () => { for (const i of forRange(1, 10)) {} `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); }); + +test("vararg deprecation", () => { + util.testModule` + /** @vararg */ + type VarArg = T & { readonly __brand: unique symbol }; + function foo(...args: any[]) {} + function vararg(...args: VarArg) { + foo(...args); + } + `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); +}); diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts index 1635ef13a..1b80e73db 100644 --- a/test/unit/annotations/vararg.spec.ts +++ b/test/unit/annotations/vararg.spec.ts @@ -1,3 +1,4 @@ +import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const varargDeclaration = ` @@ -19,6 +20,7 @@ test("@vararg", () => { ` .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .ignoreDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -30,7 +32,9 @@ test("@vararg array access", () => { return c.join("") + b[0]; } return foo("A", "B", "C", "D"); - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("@vararg global", () => { @@ -41,5 +45,6 @@ test("@vararg global", () => { ` .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .ignoreDiagnostics([annotationDeprecated.code]) .expectToEqual({ result: "ABCD" }); }); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index b2b679d30..36b928202 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -4,8 +4,7 @@ exports[`disallow LuaMultiReturn non-numeric access: code 1`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end return select( \\"forEach\\", @@ -19,8 +18,7 @@ exports[`disallow LuaMultiReturn non-numeric access: code 2`] = ` "local ____exports = {} function ____exports.__main(self) local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end return ({ multi(nil) @@ -96,8 +94,7 @@ exports[`invalid $multi implicit cast: diagnostics 1`] = `"main.ts(3,20): error exports[`invalid direct $multi function use (const [a = 1] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil) if a == nil then @@ -112,8 +109,7 @@ exports[`invalid direct $multi function use (const [a = 1] = $multi()): diagnost exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil, 2) if a == nil then @@ -128,8 +124,7 @@ exports[`invalid direct $multi function use (const [a = 1] = $multi(2)): diagnos exports[`invalid direct $multi function use (const [a] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil) ____exports.a = a @@ -141,8 +136,7 @@ exports[`invalid direct $multi function use (const [a] = $multi()): diagnostics exports[`invalid direct $multi function use (const [a] = $multi(1)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a = ____(nil, 1) ____exports.a = a @@ -154,8 +148,7 @@ exports[`invalid direct $multi function use (const [a] = $multi(1)): diagnostics exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local _ = nil local a = ____(nil, 1) @@ -168,8 +161,7 @@ exports[`invalid direct $multi function use (const _ = null, [a] = $multi(1)): d exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local ar = {1} local a = ____( @@ -185,8 +177,7 @@ exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi( exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a local ____ = { @@ -203,8 +194,7 @@ exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a do @@ -226,8 +216,7 @@ exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); fal exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a do @@ -245,8 +234,7 @@ exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2 exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` "local ____exports = {} local function multi(self, ...) - local args = {...} - return table.unpack(args) + return ... end local a if (function() diff --git a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap new file mode 100644 index 000000000..819cc27a0 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap @@ -0,0 +1,37 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`$vararg invalid use ("const l = $vararg.length"): code 1`] = `"l = #____"`; + +exports[`$vararg invalid use ("const l = $vararg.length"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("const x = $vararg;"): code 1`] = `"x = ____"`; + +exports[`$vararg invalid use ("const x = $vararg;"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): code 1`] = ` +"for ____, x in ipairs(____) do +end" +`; + +exports[`$vararg invalid use ("for (const x of $vararg) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): code 1`] = ` +"function f(self, s) +end +f(_G, ____)" +`; + +exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): diagnostics 1`] = `"main.ts(2,38): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): code 1`] = ` +"function foo(self, ...) +end +function bar(self) + foo( + _G, + table.unpack(____) + ) +end" +`; + +exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): diagnostics 1`] = `"main.ts(2,68): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; diff --git a/test/unit/language-extensions/vararg.spec.ts b/test/unit/language-extensions/vararg.spec.ts new file mode 100644 index 000000000..f92cc0f96 --- /dev/null +++ b/test/unit/language-extensions/vararg.spec.ts @@ -0,0 +1,38 @@ +import * as path from "path"; +import * as util from "../../util"; +import * as tstl from "../../../src"; +import { invalidVarargUse } from "../../../src/transformation/utils/diagnostics"; + +const varargProjectOptions: tstl.CompilerOptions = { + types: [path.resolve(__dirname, "../../../language-extensions")], +}; + +test.each([ + 'const result = [...$vararg].join("")', + 'let result: string; { result = [...$vararg].join(""); }', + 'let result: string; if (true) { result = [...$vararg].join(""); }', + 'let result: string; do { result = [...$vararg].join(""); } while (false);', +])("$vararg valid use (%p)", statement => { + util.testModule` + ${statement} + export { result }; + ` + .setOptions(varargProjectOptions) + .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) + .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) + .expectToEqual({ result: "ABCD" }); +}); + +test.each([ + "const x = $vararg;", + "for (const x of $vararg) {}", + "const l = $vararg.length", + "function f(s: string[]) {} f($vararg);", + "function foo(...args: string[]) {} function bar() { foo(...$vararg); }", +])("$vararg invalid use (%p)", statement => { + util.testModule` + ${statement} + ` + .setOptions(varargProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]); +}); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 831b68842..344205ddb 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -1,3 +1,4 @@ +import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import { formatCode } from "../util"; @@ -130,3 +131,303 @@ describe("in object literal", () => { `.expectToMatchJsResult(); }); }); + +describe("vararg spread optimization", () => { + test("basic use", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return pick(...args); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("body-less arrow function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = (...args: string[]) => pick(...args); + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("if statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + if (true) { + return pick(...args); + } + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("loop statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + do { + return pick(...args); + } while (false); + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("block statement", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let result: string; + { + result = pick(...args); + } + return result; + } + return test("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("finally clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + } finally { + return pick(...args); + } + } + return test("a" ,"b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("$multi", () => { + util.testFunction` + function multi(...args: string[]) { + return $multi(...args); + } + function test(...args: string[]) { + return multi(...args)[1]; + } + return test("a" ,"b", "c"); + ` + .setOptions({ types: [path.resolve(__dirname, "../../language-extensions")] }) + .expectLuaToMatchSnapshot() + .expectToEqual("b"); + }); +}); + +describe("vararg spread de-optimization", () => { + test("array modification", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + args[1] = "foobar"; + return pick(...args); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + hoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("array modification in secondary hoisted function", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + function triggersHoisted() { hoisted(); } + triggersHoisted(); + const result = pick(...args); + function hoisted() { args[1] = "foobar"; } + return result; + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); +}); + +describe("vararg spread in IIFE", () => { + test("comma operator", () => { + util.testFunction` + function dummy() { return "foobar"; } + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + return (dummy(), pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: string; + return (x = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("destructured assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return [args[1]]; } + function test(...args: string[]) { + let x: string; + return ([x] = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("property-access assignment expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + let x: {val?: string} = {}; + return (x.val = pick(...args)); + } + return test("a", "b", "c"); + `.expectToMatchJsResult(); + }); + + test("binary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = 1; + return x += pick(...args); + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("postfix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return x[pick(...args)]++; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("prefix unary compound assignment", () => { + util.testFunction` + function pick(...args: number[]) { return args[1]; } + function test(...args: number[]) { + let x = [7, 8, 9]; + return ++x[pick(...args)]; + } + return test(1, 2, 3); + `.expectToMatchJsResult(); + }); + + test("try clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + return pick(...args) + } catch {} + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("catch clause", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + try { + throw "foobar"; + } catch { + return pick(...args) + } + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("class expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + function test(...args: string[]) { + const fooClass = class Foo { foo = pick(...args); }; + return new fooClass().foo; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("self-referencing function expression", () => { + util.testFunction` + function pick(...args: string[]) { return args[1]; } + const test = function testName(...args: string[]) { + return \`\${typeof testName}:\${pick(...args)}\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (access args)", () => { + util.testFunction` + const obj = { $method: () => obj.arg, arg: "foobar" }; + function getObj(...args: string[]) { obj.arg = args[1]; return obj; } + function test(...args: string[]) { + return getObj(...args).$method(); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("method indirect access (method args)", () => { + util.testFunction` + const obj = { $pick: (...args: string[]) => args[1] }; + function getObj() { return obj; } + function test(...args: string[]) { + return getObj().$pick(...args); + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); + + test("tagged template method indirect access", () => { + util.testFunction` + const obj = { $tag: (t: TemplateStringsArray, ...args: string[]) => args[1] }; + function getObj() { return obj; } + function pick(...args: string[]): string { return args[1]; } + function test(...args: string[]) { + return getObj().$tag\`FOO\${pick(...args)}BAR\`; + } + return test("a" ,"b", "c"); + `.expectToMatchJsResult(); + }); +}); From 3b950d44466cafe777958b087cad0454b0031986 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sat, 6 Mar 2021 22:49:11 +0100 Subject: [PATCH 334/764] Add actual multi version tests (#1001) * Add actual multi version tests Test now select the appropriate Lua runtime based on luaTarget option This works for all supported Lua versions except JIT * Updated testeachversion calls * Revert continue test multiversion tests * Added missing expectToMatchJsResult in spread tests * Throw if JIT is used in tests --- package-lock.json | 14 +++++++------- package.json | 2 +- test/unit/builtins/math.spec.ts | 9 +++++++-- test/unit/conditionals.spec.ts | 3 --- test/unit/spread.spec.ts | 16 ++++++++-------- test/util.ts | 26 ++++++++++++++++++++++++-- 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59d842844..9fecaff4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.1.4", + "lua-wasm-bindings": "^0.2.1", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -8795,9 +8795,9 @@ "dev": true }, "node_modules/lua-wasm-bindings": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", - "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", + "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", "dev": true }, "node_modules/make-dir": { @@ -18828,9 +18828,9 @@ "dev": true }, "lua-wasm-bindings": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.1.4.tgz", - "integrity": "sha512-Hos8hbdj7YJCOyiPN1ApsFMLZylyoaGA6J5J40zzGGRz+bcz8Ui7ocI3iwOLJJC1lEBbNA8wchV9i+PyRq2SYg==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", + "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", "dev": true }, "make-dir": { diff --git a/package.json b/package.json index 573394f5a..61452f116 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.1.4", + "lua-wasm-bindings": "^0.2.1", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 8267cd0b3..dd928c68d 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -37,6 +37,11 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); -test("Math.atan2(4, 5)", () => { - util.testExpression`Math.atan2(4, 5)`.expectToMatchJsResult(); +util.testEachVersion("Math.atan2(4, 5)", () => util.testExpression`Math.atan2(4, 5)`, { + [tstl.LuaTarget.Universal]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.LuaJIT]: false, + [tstl.LuaTarget.Lua51]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), }); diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 890c6dc71..1df76d6a1 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -368,9 +368,6 @@ test.each([ { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.Lua51 } }, - { input: "true ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "false ? false : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, - { input: "true ? undefined : true", options: { luaTarget: tstl.LuaTarget.LuaJIT } }, ])("Ternary operator (%p)", ({ input, options }) => { util.testFunction` const literalValue = "literal"; diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 344205ddb..a395ef2bd 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -74,11 +74,11 @@ describe("in function call", () => { return foo(...array); `, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); @@ -86,11 +86,11 @@ describe("in function call", () => { describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { - [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack), + [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack), - [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack), - [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); diff --git a/test/util.ts b/test/util.ts index 616d6cde9..b553ef359 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,7 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { lauxlib, lua, lualib } from "lua-wasm-bindings/dist/lua.54"; -import { LUA_OK } from "lua-wasm-bindings/dist/lua"; +import { LauxLib, Lua, LuaLib, LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -17,6 +16,27 @@ const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bu // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; +function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; lua: Lua; lualib: LuaLib } { + if (target === tstl.LuaTarget.Lua51) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.51"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua52) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.52"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.Lua53) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.53"); + return { lauxlib, lua, lualib }; + } + if (target === tstl.LuaTarget.LuaJIT) { + throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!"); + } + + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54"); + return { lauxlib, lua, lualib }; +} + export function assert(value: any, message?: string | Error): asserts value { nativeAssert(value, message); } @@ -339,6 +359,8 @@ export abstract class TestBuilder { // Main file const mainFile = this.getMainLuaCodeChunk(); + const { lauxlib, lua, lualib } = getLuaBindingsForVersion(this.options.luaTarget ?? tstl.LuaTarget.Lua54); + const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); From fe5a5cc822ecdba31f473ccfa58005fbbd40c2ec Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Mar 2021 16:19:20 +0100 Subject: [PATCH 335/764] CHANGELOG 0.39.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae1502099..fefbd8362 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 0.39.0 + +- **[Breaking]** Removed support for `@phantom`, `@metaExtension`, `@extension`, `@pureAbstract` compiler annotations. As of this version **these will no longer function!** For help upgrading your code see [the deprecated annotation docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#deprecated). +- Added official support for **Lua 5.4**. +- Added the `LuaTable` language extension. This allows the use of barebones Lua tables for key-value storage, without suffering from JS's forced string indexes. For more information see [the LuaTable docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types). +- Deprecated `@vararg`. Instead, tstl will figure out itself when use of the Lua ellipsis token (`...`) is appropriate. Also language extension `$vararg` was added to force use of the ellipsis token. See [the docs](https://typescripttolua.github.io/docs/advanced/language-extensions#vararg-constant) for more information. +- Added `trailingComments` and `leadingComments` fields to statements in the Lua AST. These can be modified by plugins to emit comments in the output lua. For an example see [the add-comments test plugin](https://github.com/TypeScriptToLua/TypeScriptToLua/blob/master/test/transpile/plugins/add-comments.ts). + +Under the hood: + +- Tests are now run on a WebAssembly-compiled version of official Lua releases. This means we can now execute test Lua on all Lua versions (except LuaJIT). Shoutout to [Fengari](https://github.com/fengari-lua/fengari) for serving us well for a long time. + ## 0.38.0 - **[Breaking]** Renamed `MultiReturn` to `LuaMultiReturn` to be consistent with other language extensions all starting with Lua-. From a6399982d8f5f9f1402aa9cd50dc1418ca271842 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Mar 2021 16:30:47 +0100 Subject: [PATCH 336/764] 0.39.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9fecaff4c..e04a792e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.0", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 61452f116..02a0c665a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.38.1", + "version": "0.39.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 759090a3aabc744f81883bb0d39929ecc740258c Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 7 Mar 2021 17:48:31 +0100 Subject: [PATCH 337/764] Bump lua-wasm-bindings version (#1002) Fixed an issue were errors would be printed for 5.1 tests even though the tests passed. --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index e04a792e3..8dbf1d54d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.2.1", + "lua-wasm-bindings": "^0.2.2", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" @@ -8795,9 +8795,9 @@ "dev": true }, "node_modules/lua-wasm-bindings": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", - "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", "dev": true }, "node_modules/make-dir": { @@ -18828,9 +18828,9 @@ "dev": true }, "lua-wasm-bindings": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.1.tgz", - "integrity": "sha512-8oig7XmwI/Tq/hSpuBZbjyBXrw3vngUSvQ5kV3/9mGaHfJrQVd993j1HVy6CN/griuPrKsLtSEbpn8Hu79dYhg==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", "dev": true }, "make-dir": { diff --git a/package.json b/package.json index 02a0c665a..677789323 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "jest": "^26.0.1", "jest-circus": "^25.1.0", "lua-types": "^2.8.0", - "lua-wasm-bindings": "^0.2.1", + "lua-wasm-bindings": "^0.2.2", "prettier": "^2.0.5", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" From 29dba98fe906972f2c29a5d15954b44ed95c255f Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 25 Mar 2021 19:22:30 +0100 Subject: [PATCH 338/764] Replaced deprecated factory functions (#1008) * Replaced deprecated factory functions Also enabled some eslint rules & fixed violations * Caught to more deprecated function calls * Fixed typo --- .eslintrc.js | 51 +++++++++++-------- src/LuaLib.ts | 2 + src/LuaPrinter.ts | 2 +- .../visitors/binary-expression/compound.ts | 8 +-- .../visitors/binary-expression/index.ts | 6 +-- src/transformation/visitors/call.ts | 8 +-- src/transformation/visitors/class/index.ts | 4 +- src/transformation/visitors/literal.ts | 4 +- src/transformation/visitors/loops/for.ts | 4 +- src/transformation/visitors/loops/utils.ts | 2 +- src/transformation/visitors/modules/export.ts | 11 ++-- .../visitors/unary-expression.ts | 12 ++--- .../visitors/variable-declaration.ts | 2 +- src/transpilation/transformers.ts | 6 +-- test/cli/parse.spec.ts | 1 + test/transpile/transformers/fixtures.ts | 8 +-- .../transformers/transformers.spec.ts | 1 + .../invalidFunctionAssignments.spec.ts | 16 +++--- test/unit/hoisting.spec.ts | 4 +- 19 files changed, 85 insertions(+), 67 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index fb8ec7488..dabc1db41 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -130,6 +130,8 @@ module.exports = { "no-useless-return": ["error"], "import/no-default-export": "error", + // TODO currently only works for direct imports (useless for now) https://github.com/benmosher/eslint-plugin-import/issues/1729 + // "import/no-deprecated": "error", "jest/expect-expect": "off", "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], @@ -154,31 +156,33 @@ module.exports = { "@typescript-eslint/no-require-imports": "off", "@typescript-eslint/no-unnecessary-condition": "off", "@typescript-eslint/prefer-for-of": "error", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1265 - // "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", "@typescript-eslint/prefer-readonly": "off", "@typescript-eslint/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], "@typescript-eslint/require-array-sort-compare": "off", "@typescript-eslint/camelcase": "off", - // TODO: https://github.com/typescript-eslint/typescript-eslint/issues/1712 - // "@typescript-eslint/naming-convention": [ - // "error", - // { - // selector: "default", - // format: ["camelCase"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "variable", - // format: ["camelCase", "UPPER_CASE"], - // leadingUnderscore: "allow", - // }, - // { - // selector: "typeLike", - // format: ["PascalCase"], - // }, - // ], + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "default", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "variable", + format: ["camelCase", "UPPER_CASE"], + leadingUnderscore: "allow", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "enumMember", + format: ["PascalCase"], + }, + ], }, }, { @@ -187,6 +191,13 @@ module.exports = { "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], "@typescript-eslint/no-throw-literal": "off", "@typescript-eslint/prefer-optional-chain": "off", + "@typescript-eslint/naming-convention": "off", + }, + }, + { + files: "language-extensions/index.d.ts", + rules: { + "@typescript-eslint/naming-convention": "off", }, }, { diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7168d0067..06742022d 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -87,6 +87,7 @@ export enum LuaLibFeature { Unpack = "Unpack", } +/* eslint-disable @typescript-eslint/naming-convention */ const luaLibDependencies: Partial> = { ArrayConcat: [LuaLibFeature.ArrayIsArray], ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], @@ -108,6 +109,7 @@ const luaLibDependencies: Partial> = { StringSplit: [LuaLibFeature.StringSubstring], SymbolRegistry: [LuaLibFeature.Symbol], }; +/* eslint-enable @typescript-eslint/naming-convention */ export function loadLuaLibFeatures(features: Iterable, emitHost: EmitHost): string { let result = ""; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 912ab33f5..b1cfb7f46 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -272,7 +272,7 @@ export class LuaPrinter { } } }); - return result || false; + return result ?? false; } protected printStatementArray(statements: lua.Statement[]): SourceChunk[] { diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 7a11454c8..febd7681e 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -22,15 +22,15 @@ export function parseAccessExpressionWithEvaluationEffects( const type = context.checker.getTypeAtLocation(node.expression); if (isArrayType(context, type)) { // Offset arrays by one - const oneLit = ts.createNumericLiteral("1"); - const exp = ts.createParen(node.argumentExpression); - const addExp = ts.createBinary(exp, ts.SyntaxKind.PlusToken, oneLit); + const oneLit = ts.factory.createNumericLiteral("1"); + const exp = ts.factory.createParenthesizedExpression(node.argumentExpression); + const addExp = ts.factory.createBinaryExpression(exp, ts.SyntaxKind.PlusToken, oneLit); return [node.expression, addExp]; } else { return [node.expression, node.argumentExpression]; } } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { - return [node.expression, ts.createStringLiteral(node.name.text)]; + return [node.expression, ts.factory.createStringLiteral(node.name.text)]; } return []; diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 26e90ad67..5ed023618 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -125,7 +125,7 @@ export const transformBinaryExpression: FunctionVisitor = ( return transformToImmediatelyInvokedFunctionExpression( context, () => ({ - statements: context.transformStatements(ts.createExpressionStatement(node.left)), + statements: context.transformStatements(ts.factory.createExpressionStatement(node.left)), result: context.transformExpression(node.right), }), node @@ -159,8 +159,8 @@ export function transformBinaryExpressionStatement( return transformAssignmentStatement(context, expression as ts.AssignmentExpression); } else if (operator === ts.SyntaxKind.CommaToken) { const statements = [ - ...context.transformStatements(ts.createExpressionStatement(expression.left)), - ...context.transformStatements(ts.createExpressionStatement(expression.right)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.left)), + ...context.transformStatements(ts.factory.createExpressionStatement(expression.right)), ]; return lua.createDoStatement(statements, expression); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 75f73db88..306968010 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -183,7 +183,7 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression(context.transformExpression(node.expression), parameters); } @@ -267,11 +267,11 @@ export const transformCallExpression: FunctionVisitor = (node // Handle super calls properly if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { - const parameters = transformArguments(context, node.arguments, signature, ts.createThis()); + const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression( lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), + context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), parameters @@ -285,7 +285,7 @@ export const transformCallExpression: FunctionVisitor = (node if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { parameters = transformArguments(context, node.arguments, signature); } else { - const callContext = context.isStrict ? ts.createNull() : ts.createIdentifier("_G"); + const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); parameters = transformArguments(context, node.arguments, signature, callContext); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 9963c09f4..4c0e05eee 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -152,7 +152,7 @@ function transformClassLikeDeclaration( // Generate a constructor if none was defined in a base class const constructorResult = transformConstructorDeclaration( context, - ts.createConstructor([], [], [], ts.createBlock([], true)), + ts.factory.createConstructorDeclaration([], [], [], ts.factory.createBlock([], true)), localClassName, instanceFields, classDeclaration @@ -168,7 +168,7 @@ function transformClassLikeDeclaration( const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( - context.transformExpression(ts.createSuper()), + context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), [createSelfIdentifier(), lua.createDotsLiteral()] diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 36c7e48c6..8fa85e4e4 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -38,7 +38,7 @@ export function createShorthandIdentifier( const name = isUnsafeName ? createSafeName(propertyName) : propertyName; - let identifier = context.transformExpression(ts.createIdentifier(name)); + let identifier = context.transformExpression(ts.factory.createIdentifier(name)); lua.setNodeOriginal(identifier, propertyIdentifier); if (valueSymbol !== undefined && lua.isIdentifier(identifier)) { identifier.symbolId = getSymbolIdOfSymbol(context, valueSymbol); @@ -137,7 +137,7 @@ const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => - ts.isOmittedExpression(e) ? ts.createIdentifier("undefined") : e + ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e ); const values = flattenSpreadExpressions(context, filteredElements).map(e => lua.createTableFieldExpression(e)); diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index f81a62199..98864082e 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -13,7 +13,7 @@ export const transformForStatement: FunctionVisitor = (statemen // local initializer = value result.push(...statement.initializer.declarations.flatMap(d => transformVariableDeclaration(context, d))); } else { - result.push(...context.transformStatements(ts.createExpressionStatement(statement.initializer))); + result.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.initializer))); } } @@ -25,7 +25,7 @@ export const transformForStatement: FunctionVisitor = (statemen const body: lua.Statement[] = transformLoopBody(context, statement); if (statement.incrementor) { - body.push(...context.transformStatements(ts.createExpressionStatement(statement.incrementor))); + body.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.incrementor))); } // while (condition) do ... end diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 8ee86f4ea..a7402b653 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -36,7 +36,7 @@ export function getVariableDeclarationBinding( checkVariableDeclarationList(context, node); if (node.declarations.length === 0) { - return ts.createIdentifier("____"); + return ts.factory.createIdentifier("____"); } return node.declarations[0].name; diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 0fa5d9ee4..955f56866 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -129,12 +129,15 @@ function transformExportSpecifiersFrom( exportSpecifiers: ts.ExportSpecifier[] ): lua.Statement { // First transpile as import clause - const importClause = ts.createImportClause( + const importClause = ts.factory.createImportClause( + false, undefined, - ts.createNamedImports(exportSpecifiers.map(s => ts.createImportSpecifier(s.propertyName, s.name))) + ts.factory.createNamedImports( + exportSpecifiers.map(s => ts.factory.createImportSpecifier(s.propertyName, s.name)) + ) ); - const importDeclaration = ts.createImportDeclaration( + const importDeclaration = ts.factory.createImportDeclaration( statement.decorators, statement.modifiers, importClause, @@ -142,7 +145,7 @@ function transformExportSpecifiersFrom( ); // Wrap in block to prevent imports from hoisting out of `do` statement - const [block] = transformScopeBlock(context, ts.createBlock([importDeclaration]), ScopeType.Block); + const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); const result = block.statements; // Now the module is imported, add the imports to the export table diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index 76b0e4941..5960c2200 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -25,7 +25,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } else if (ts.isPostfixUnaryExpression(expression)) { @@ -37,7 +37,7 @@ export function transformUnaryExpressionStatement( context, expression, expression.operand, - ts.createLiteral(1), + ts.factory.createNumericLiteral(1), replacementOperator ); } @@ -50,7 +50,7 @@ export const transformPostfixUnaryExpression: FunctionVisitor = () => node => { const transformSourceFile: ts.Transformer = node => { - const empty = ts.createNotEmittedStatement(undefined!); + const empty = ts.factory.createNotEmittedStatement(undefined!); ts.addSyntheticLeadingComment(empty, ts.SyntaxKind.MultiLineCommentTrivia, "* @noSelfInFile ", true); - return ts.updateSourceFileNode(node, [empty, ...node.statements], node.isDeclarationFile); + return ts.factory.updateSourceFile(node, [empty, ...node.statements], node.isDeclarationFile); }; return ts.isBundle(node) - ? ts.updateBundle(node, node.sourceFiles.map(transformSourceFile)) + ? ts.factory.updateBundle(node, node.sourceFiles.map(transformSourceFile)) : transformSourceFile(node); }; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index cb441ca2f..06ed05f75 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -158,6 +158,7 @@ describe("tsconfig", () => { }); test("should parse options case-sensitively", () => { + // eslint-disable-next-line @typescript-eslint/naming-convention const result = parseConfigFileContent({ tstl: { NoHeader: true } }); expect(result.errors).toHaveDiagnostics(); diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index c998d6efc..a69829d5d 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -9,7 +9,7 @@ export const program = (program: ts.Program, options: { value: any }): ts.Transf export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(value)); + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); }); export const checker = ( @@ -20,13 +20,13 @@ export const checker = ( if (!ts.isReturnStatement(node) || !node.expression) return; const type = checker.getTypeAtLocation(node.expression); if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; - return ts.updateReturn(node, ts.createLiteral(value)); + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); }); export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); export const compilerOptions = ( @@ -35,6 +35,6 @@ export const compilerOptions = ( assert(options.plugins?.length === 1); return visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; - return ts.updateReturn(node, ts.createLiteral(true)); + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); }; diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts index e166198bd..02290d9d1 100644 --- a/test/transpile/transformers/transformers.spec.ts +++ b/test/transpile/transformers/transformers.spec.ts @@ -23,6 +23,7 @@ test("transformer resolution error", () => { .expectToHaveDiagnostics(); }); +// This tests plugin transformers by transforming the `return false` statement to a `return true` statement. describe("factory types", () => { test.each(["program", "config", "checker", "raw", "compilerOptions"] as const)("%s", type => { util.testFunction` diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 7d678496b..cd12b4ba8 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -10,7 +10,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function variable declaration (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} const fn: ${functionType} = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], @@ -23,7 +23,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function assignment (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: ${functionType}; fn = ${testFunction.value}; `.expectDiagnosticsToMatchSnapshot( @@ -35,7 +35,7 @@ test.each(invalidTestFunctionAssignments)( test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} let fn: typeof ${testFunction.value}; fn = ${castedFunction}; `.expectDiagnosticsToMatchSnapshot( @@ -48,7 +48,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: ${functionType}); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -68,7 +68,7 @@ test("Invalid lua lib function argument", () => { test.each(invalidTestFunctionCasts)("Invalid function argument with cast (%p)", (testFunction, castedFunction) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: typeof ${testFunction.value}); takesFunction(${castedFunction}); `.expectDiagnosticsToMatchSnapshot( @@ -81,7 +81,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function generic argument (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} declare function takesFunction(fn: T); takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( @@ -95,7 +95,7 @@ test.each(invalidTestFunctionAssignments)( "Invalid function return (%p)", (testFunction, functionType, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): ${functionType} { return ${testFunction.value}; } @@ -110,7 +110,7 @@ test.each(invalidTestFunctionCasts)( "Invalid function return with cast (%p)", (testFunction, castedFunction, isSelfConversion) => { util.testModule` - ${testFunction.definition || ""} + ${testFunction.definition ?? ""} function returnsFunction(): typeof ${testFunction.value} { return ${castedFunction}; } diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 9caefb300..144460067 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -107,9 +107,9 @@ test("Hoisting with synthetic source file node", () => { .setCustomTransformers({ before: [ () => sourceFile => - ts.updateSourceFileNode( + ts.factory.updateSourceFile( sourceFile, - [ts.createNotEmittedStatement(undefined!), ...sourceFile.statements], + [ts.factory.createNotEmittedStatement(undefined!), ...sourceFile.statements], sourceFile.isDeclarationFile, sourceFile.referencedFiles, sourceFile.typeReferenceDirectives, From c09f98cd4ebcbc5bf07a662a11a7f771939dcac3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 25 Mar 2021 20:56:29 +0100 Subject: [PATCH 339/764] 0.39.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dbf1d54d..2c8f86ac9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 677789323..7a701c557 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.0", + "version": "0.39.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f3dea4271a4dae65cc2e4644ab44d2108a2094ce Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 2 Apr 2021 18:41:08 +0200 Subject: [PATCH 340/764] Use ts.getParseTreeNode before getSourceFile to handle transformer output (#1010) * Use getParseTreeNode before getSourceFile * npm audit fix --- package-lock.json | 29 +++++++++++--------- src/LuaAST.ts | 8 ++++-- src/transformation/utils/typescript/index.ts | 3 +- 3 files changed, 23 insertions(+), 17 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2c8f86ac9..72ffc8c45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1460,6 +1460,7 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", + "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -3567,7 +3568,8 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1" + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -6206,6 +6208,7 @@ "@types/graceful-fs": "^4.1.2", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-serializer": "^26.0.0", "jest-util": "^26.0.1", @@ -8762,9 +8765,9 @@ } }, "node_modules/lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.memoize": { @@ -11549,9 +11552,9 @@ "dev": true }, "node_modules/y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "node_modules/yargs": { @@ -18795,9 +18798,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.memoize": { @@ -21039,9 +21042,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yargs": { diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 661500e4a..2f0d2e880 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -174,10 +174,12 @@ export function setNodeOriginal(node: T | undefined, tsOriginal: } function getSourcePosition(sourceNode: ts.Node): TextRange | undefined { - if (sourceNode.getSourceFile() !== undefined && sourceNode.pos >= 0) { + const parseTreeNode = ts.getParseTreeNode(sourceNode) ?? sourceNode; + const sourceFile = parseTreeNode.getSourceFile(); + if (sourceFile !== undefined && parseTreeNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition( - sourceNode.getSourceFile(), - sourceNode.pos + sourceNode.getLeadingTriviaWidth() + sourceFile, + parseTreeNode.pos + parseTreeNode.getLeadingTriviaWidth() ); return { line, column: character }; diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 46b4992ea..6d7bfa68c 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -32,7 +32,8 @@ export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.Sour } function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { - const sourceFile = declaration.getSourceFile(); + const parseTreeNode = ts.getParseTreeNode(declaration) ?? declaration; + const sourceFile = parseTreeNode.getSourceFile(); if (!sourceFile) { return false; } From c0d7936598fef6b37ea6d1c9efcc8818b3eb1afb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 2 Apr 2021 19:01:46 +0200 Subject: [PATCH 341/764] 0.39.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72ffc8c45..683dd5035 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 7a701c557..790013fa5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.1", + "version": "0.39.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d86ef928d9965fc4e9e79413f3b10a444ae7b113 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 28 Apr 2021 08:52:36 +0200 Subject: [PATCH 342/764] Fix missing stringaccess lualib dependency (#1015) --- src/LuaLib.ts | 2 +- test/unit/builtins/string.spec.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 06742022d..dc4501d86 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -106,7 +106,7 @@ const luaLibDependencies: Partial> = { WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], - StringSplit: [LuaLibFeature.StringSubstring], + StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], SymbolRegistry: [LuaLibFeature.Symbol], }; /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 5e1790573..c31ef012f 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -200,6 +200,13 @@ test("string.split inline", () => { .expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1009 +test("string.split inline empty separator", () => { + util.testExpression`"a, b, c".split("")` + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToMatchJsResult(); +}); + test.each([ { inp: "hello test", index: 0 }, { inp: "hello test", index: 1 }, From a617fafa1463a71e00874f7ca229b6cb657723d9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 28 Apr 2021 20:59:48 +0200 Subject: [PATCH 343/764] Fixed invalid switch statement lua when default was not the last case (#1016) * Made switch default case always last * Actually fixed switch statement this time * Added extra default fallthrough test --- src/transformation/visitors/switch.ts | 9 +- ...onals.spec.ts.snap => switch.spec.ts.snap} | 0 test/unit/conditionals.spec.ts | 297 -------------- test/unit/switch.spec.ts | 363 ++++++++++++++++++ 4 files changed, 369 insertions(+), 300 deletions(-) rename test/unit/__snapshots__/{conditionals.spec.ts.snap => switch.spec.ts.snap} (100%) create mode 100644 test/unit/switch.spec.ts diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 99ff3df7d..a82ff0bf0 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -18,10 +18,13 @@ export const transformSwitchStatement: FunctionVisitor = (st let statements: lua.Statement[] = []; - const caseClauses = statement.caseBlock.clauses.filter(ts.isCaseClause); - // Starting from the back, concatenating ifs into one big if/elseif statement - const concatenatedIf = caseClauses.reduceRight((previousCondition, clause, index) => { + const concatenatedIf = statement.caseBlock.clauses.reduceRight((previousCondition, clause, index) => { + if (ts.isDefaultClause(clause)) { + // Skip default clause here (needs to be included to ensure index lines up with index later) + return previousCondition; + } + // If the clause condition holds, go to the correct label const condition = lua.createBinaryExpression( switchVariable, diff --git a/test/unit/__snapshots__/conditionals.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap similarity index 100% rename from test/unit/__snapshots__/conditionals.spec.ts.snap rename to test/unit/__snapshots__/switch.spec.ts.snap diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 1df76d6a1..c9717d0c0 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,4 @@ import * as tstl from "../../src"; -import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each([0, 1])("if (%p)", inp => { @@ -52,302 +51,6 @@ test.each([0, 1, 2, 3])("ifelseifelse (%p)", inp => { `.expectToMatchJsResult(); }); -test.each([0, 1, 2, 3])("switch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: - result = 0; - case 1: - result = 1; - break; - case 2: - result = 2; - case 3: - case 4: - result = 4; - break; - case 5: - result = 5; - case 6: - result += 10; - break; - case 7: - result = 7; - default: - result = -2; - break; - } - - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: - result = 0; - break; - case 1: - switch(${inp} as number) { - case 0: - result = 0; - break; - case 1: - result = 1; - break; - default: - result = -3; - break; - } - break; - case 2: - result = 2; - break; - default: - result = -2; - break; - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch cases scope", () => { - util.testFunction` - switch (0 as number) { - case 0: - let foo: number | undefined = 1; - case 1: - foo = 2; - case 2: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("variable in nested scope does not interfere with case scope", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: { - let foo = 1; - } - - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test("switch using variable re-declared in cases", () => { - util.testFunction` - let foo: number = 0; - switch (foo) { - case 0: - let foo = true; - case 1: - return foo; - } - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - let x = 0; - result = 0; - break; - } - case 1: { - let x = 1; - result = x; - } - case 2: { - let x = 2; - result = x; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { - util.testFunction` - switch (${inp}) { - case 0: - return 0; - break; - case 1: - return 1; - case 2: - return 2; - break; - } - - return -1; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp}) { - case 0: { - result = 0; - break; - } - case 1: { - result = 1; - - if (result == 1) break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { - util.testFunction` - let result: number = -1; - - switch (${inp} as number) { - case 0: { - result = 0; - - for (let i = 0; i < 5; i++) { - result++; - - if (i >= 2) { - break; - } - } - } - case 1: { - result++; - break; - } - case 2: { - result = 2; - break; - } - } - return result; - `.expectToMatchJsResult(); -}); - -test("switch uses elseif", () => { - test("array", () => { - util.testFunction` - let result: number = -1; - - switch (2 as number) { - case 0: { - result = 200; - break; - } - - case 1: { - result = 100; - break; - } - - case 2: { - result = 1; - break; - } - } - - return result; - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); -}); - -test("switch not allowed in 5.1", () => { - util.testFunction` - switch ("abc") {} - ` - .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); -}); - test.each([ { input: "true ? 'a' : 'b'" }, { input: "false ? 'a' : 'b'" }, diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts new file mode 100644 index 000000000..dd3e2a09c --- /dev/null +++ b/test/unit/switch.spec.ts @@ -0,0 +1,363 @@ +import * as tstl from "../../src"; +import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; +import * as util from "../util"; + +test.each([0, 1, 2, 3])("switch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchdefault (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 0, 2, 3, 4, 5, 7])("switchfallthrough (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: + result = 0; + case 1: + result = 1; + break; + case 2: + result = 2; + case 3: + case 4: + result = 4; + break; + case 5: + result = 5; + case 6: + result += 10; + break; + case 7: + result = 7; + default: + result = -2; + break; + } + + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("nestedSwitch (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: + result = 0; + break; + case 1: + switch(${inp} as number) { + case 0: + result = 0; + break; + case 1: + result = 1; + break; + default: + result = -3; + break; + } + break; + case 2: + result = 2; + break; + default: + result = -2; + break; + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch cases scope", () => { + util.testFunction` + switch (0 as number) { + case 0: + let foo: number | undefined = 1; + case 1: + foo = 2; + case 2: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("variable in nested scope does not interfere with case scope", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: { + let foo = 1; + } + + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test("switch using variable re-declared in cases", () => { + util.testFunction` + let foo: number = 0; + switch (foo) { + case 0: + let foo = true; + case 1: + return foo; + } + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2])("switch with block statement scope (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + let x = 0; + result = 0; + break; + } + case 1: { + let x = 1; + result = x; + } + case 2: { + let x = 2; + result = x; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchReturn (%p)", inp => { + util.testFunction` + switch (${inp}) { + case 0: + return 0; + break; + case 1: + return 1; + case 2: + return 2; + break; + } + + return -1; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp}) { + case 0: { + result = 0; + break; + } + case 1: { + result = 1; + + if (result == 1) break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { + util.testFunction` + let result: number = -1; + + switch (${inp} as number) { + case 0: { + result = 0; + + for (let i = 0; i < 5; i++) { + result++; + + if (i >= 2) { + break; + } + } + } + case 1: { + result++; + break; + } + case 2: { + result = 2; + break; + } + } + return result; + `.expectToMatchJsResult(); +}); + +test("switch uses elseif", () => { + test("array", () => { + util.testFunction` + let result: number = -1; + + switch (2 as number) { + case 0: { + result = 200; + break; + } + + case 1: { + result = 100; + break; + } + + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); +}); + +test("switch not allowed in 5.1", () => { + util.testFunction` + switch ("abc") {} + ` + .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/967 +test("switch default case not last - first", () => { + util.testFunction` + switch (3 as number) { + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch default case not last - second", () => { + util.testFunction` + switch (3 as number) { + case 4: + return "also wrong"; + default: + return "wrong"; + case 3: + return "right"; + } + `.expectToMatchJsResult(); +}); + +test("switch fallthrough enters default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + case 3: + out.push("3"); + default: + out.push("default"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough does not enter earlier default", () => { + util.testFunction` + const out = []; + switch (3 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); + +test("switch fallthrough stops after default", () => { + util.testFunction` + const out = []; + switch (4 as number) { + default: + out.push("default"); + case 3: + out.push("3"); + } + return out; + `.expectToMatchJsResult(); +}); From b26dac0469ba30c07557722ea6fb8487e022f1b3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 3 May 2021 21:57:50 +0200 Subject: [PATCH 344/764] Fix namespace and module resulting in invalid Lua when modified with TS transformer plugin (#1014) * Failing test * Fixed bug #1013 * Fix prettier * Switched transformer plugin to TS instead of JS --- src/transformation/visitors/namespace.ts | 2 +- test/transpile/plugins/plugins.spec.ts | 20 ++++++++++++++++++++ test/transpile/plugins/transformer-plugin.ts | 15 +++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 test/transpile/plugins/transformer-plugin.ts diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 0244ac21c..7ee32adac 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -76,7 +76,7 @@ export const transformModuleDeclaration: FunctionVisitor = const isFirstDeclaration = symbol === undefined || (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && - node === symbol.declarations.find(ts.isModuleDeclaration)); + ts.getOriginalNode(node) === symbol.declarations.find(ts.isModuleDeclaration)); if (isNonModuleMergeable) { // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 46988dae0..eaaee3dca 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -40,3 +40,23 @@ test("statement comments", () => { .setOptions({ luaPlugins: [{ name: path.join(__dirname, "add-comments.ts") }] }) .expectLuaToMatchSnapshot(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1013 +test.each(["namespace", "module"])("%s with TS transformer plugin", moduleOrNamespace => { + util.testModule` + import { ns } from "module"; + export const result = ns.returnsBool(); + ` + .addExtraFile( + "module.ts", + ` + export ${moduleOrNamespace} ns { + export function returnsBool() { + return false; + } + } + ` + ) + .setOptions({ plugins: [{ transform: path.join(__dirname, "transformer-plugin.ts") }] }) + .expectNoExecutionError(); +}); diff --git a/test/transpile/plugins/transformer-plugin.ts b/test/transpile/plugins/transformer-plugin.ts new file mode 100644 index 000000000..8b338723c --- /dev/null +++ b/test/transpile/plugins/transformer-plugin.ts @@ -0,0 +1,15 @@ +/** + * This is a TS tranformer plugin that replaces any return statement to 'return true'. + */ +import * as ts from "typescript"; + +const replaceNode = (node: ts.Node) => { + if (ts.isReturnStatement(node)) { + return ts.factory.createReturnStatement(ts.factory.createTrue()); + } +}; +const createTransformer = () => (context: ts.TransformationContext) => { + const visit = (node: ts.Node): ts.Node => replaceNode(node) ?? ts.visitEachChild(node, visit, context); + return (file: ts.SourceFile) => ts.visitNode(file, visit); +}; +exports.default = createTransformer; From 9ac496c24e9c5ca1d9531c95e6f3c40a61ff7ec3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 3 May 2021 22:05:37 +0200 Subject: [PATCH 345/764] 0.39.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 683dd5035..3f1cbb4f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 790013fa5..5cce58d65 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.2", + "version": "0.39.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 2ff677ce9263c2f2e43d9fd44cc49d85388c0cb9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 21 May 2021 15:50:17 +0200 Subject: [PATCH 346/764] deduped and audited package-lock (#1022) --- package-lock.json | 7344 +++++++++++++++++++++------------------------ 1 file changed, 3482 insertions(+), 3862 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3f1cbb4f4..a4be60bc2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42,12 +42,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "dependencies": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.12.13" } }, "node_modules/@babel/core": { @@ -77,80 +77,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/core/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/core/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/core/node_modules/@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "node_modules/@babel/core/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/core/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "node_modules/@babel/core/node_modules/source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -161,14 +87,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" } }, @@ -182,23 +107,23 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.14.2" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-member-expression-to-functions": { @@ -234,40 +159,6 @@ "lodash": "^4.17.13" } }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "node_modules/@babel/helper-module-transforms/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "node_modules/@babel/helper-optimise-call-expression": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", @@ -295,78 +186,6 @@ "@babel/types": "^7.9.6" } }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@babel/helper-replace-supers/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/helper-simple-access": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", @@ -378,18 +197,18 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "node_modules/@babel/helpers": { @@ -403,86 +222,14 @@ "@babel/types": "^7.9.6" } }, - "node_modules/@babel/helpers/node_modules/@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "dependencies": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "node_modules/@babel/helpers/node_modules/@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "node_modules/@babel/helpers/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, @@ -549,9 +296,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -651,41 +398,39 @@ } }, "node_modules/@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "node_modules/@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" } }, "node_modules/@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "dependencies": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, @@ -752,21 +497,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/console/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/core": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", @@ -806,15 +536,16 @@ } }, "node_modules/@jest/core/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -822,13 +553,13 @@ } }, "node_modules/@jest/core/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -837,13 +568,14 @@ } }, "node_modules/@jest/core/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -851,16 +583,31 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/core/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@jest/core/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/@jest/core/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -868,12 +615,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/core/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -889,79 +639,74 @@ } }, "node_modules/@jest/core/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/core/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -979,18 +724,18 @@ } }, "node_modules/@jest/core/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -998,25 +743,26 @@ } }, "node_modules/@jest/core/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -1024,51 +770,61 @@ } }, "node_modules/@jest/core/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/core/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/@jest/core/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/core/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -1107,20 +863,14 @@ "node": ">=8" } }, - "node_modules/@jest/core/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/@jest/core/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -1129,9 +879,9 @@ } }, "node_modules/@jest/core/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1154,21 +904,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/fake-timers": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", @@ -1185,21 +920,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/globals": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", @@ -1215,43 +935,46 @@ } }, "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1259,10 +982,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/globals/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1270,12 +1008,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/globals/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -1291,79 +1032,74 @@ } }, "node_modules/@jest/globals/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1372,12 +1108,13 @@ } }, "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -1393,40 +1130,47 @@ } }, "node_modules/@jest/globals/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/@jest/globals/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/globals/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1460,7 +1204,6 @@ "jest-resolve": "^26.0.1", "jest-util": "^26.0.1", "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -1475,15 +1218,16 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -1491,13 +1235,13 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1506,13 +1250,14 @@ } }, "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1520,10 +1265,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/reporters/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1531,6 +1291,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/reporters/node_modules/escape-string-regexp": { @@ -1542,24 +1305,19 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/reporters/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1568,18 +1326,18 @@ } }, "node_modules/@jest/reporters/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -1587,36 +1345,61 @@ } }, "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/@jest/reporters/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@jest/reporters/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" } }, + "node_modules/@jest/reporters/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/reporters/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -1655,15 +1438,6 @@ "node": ">=8" } }, - "node_modules/@jest/reporters/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/@jest/reporters/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1674,9 +1448,9 @@ } }, "node_modules/@jest/reporters/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1699,12 +1473,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/source-map/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/source-map/node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -1729,21 +1497,6 @@ "node": ">= 8.3" } }, - "node_modules/@jest/test-result/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/@jest/test-sequencer": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", @@ -1761,15 +1514,16 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -1777,13 +1531,13 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1792,13 +1546,14 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1806,10 +1561,25 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/test-sequencer/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@jest/test-sequencer/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/@jest/test-sequencer/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1817,6 +1587,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/@jest/test-sequencer/node_modules/escape-string-regexp": { @@ -1828,24 +1601,19 @@ "node": ">=8" } }, - "node_modules/@jest/test-sequencer/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -1854,25 +1622,47 @@ } }, "node_modules/@jest/test-sequencer/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/@jest/test-sequencer/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@jest/test-sequencer/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/@jest/test-sequencer/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -1908,13 +1698,14 @@ } }, "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -1922,10 +1713,19 @@ "node": ">= 10.14.2" } }, + "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -1933,14 +1733,11 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@jest/transform/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/@jest/transform/node_modules/jest-regex-util": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", @@ -1951,16 +1748,17 @@ } }, "node_modules/@jest/transform/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" @@ -1976,9 +1774,9 @@ } }, "node_modules/@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -2084,12 +1882,6 @@ "@babel/types": "^7.3.0" } }, - "node_modules/@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "node_modules/@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -2141,9 +1933,9 @@ } }, "node_modules/@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*", @@ -2151,13 +1943,13 @@ } }, "node_modules/@types/jest": { - "version": "25.1.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", - "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "dependencies": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, "node_modules/@types/json-schema": { @@ -2235,7 +2027,7 @@ "node": "^8.10.0 || ^10.13.0 || >=11.10.1" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "node_modules/@typescript-eslint/experimental-utils": { "version": "2.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", @@ -2248,59 +2040,28 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", + "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", - "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.23.0", - "eslint-scope": "^5.0.0" }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/@typescript-eslint/parser": { @@ -2338,10 +2099,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -2372,9 +2136,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", - "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -2387,6 +2151,15 @@ }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { @@ -2398,18 +2171,6 @@ "semver": "bin/semver.js" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/@typescript-eslint/visitor-keys": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", @@ -2424,9 +2185,9 @@ } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, "engines": { "node": ">=10" @@ -2439,9 +2200,9 @@ "dev": true }, "node_modules/acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2509,22 +2270,24 @@ } }, "node_modules/ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -2716,13 +2479,14 @@ } }, "node_modules/babel-jest/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -2730,10 +2494,19 @@ "node": ">= 10.14.2" } }, + "node_modules/babel-jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/babel-jest/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -2741,14 +2514,11 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/babel-jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/babel-plugin-istanbul": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", @@ -3280,12 +3050,20 @@ } }, "node_modules/debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/decamelize": { @@ -3418,9 +3196,9 @@ } }, "node_modules/diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true, "engines": { "node": ">= 8.3" @@ -3568,8 +3346,7 @@ "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "optionator": "^0.8.1" }, "bin": { "escodegen": "bin/escodegen.js", @@ -3864,9 +3641,9 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { "node": ">=4" @@ -3999,18 +3776,6 @@ "node": ">=6.0.0" } }, - "node_modules/espree/node_modules/acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", @@ -4173,84 +3938,6 @@ "node": ">= 8.3" } }, - "node_modules/expect/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -4578,12 +4265,6 @@ "node": ">=6 <7 || >=8" } }, - "node_modules/fs-extra/node_modules/graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -4606,8 +4287,7 @@ "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "node_modules/functional-red-black-tree": { "version": "1.0.1", @@ -4737,9 +4417,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "node_modules/growly": { @@ -4775,7 +4455,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "dependencies": { "function-bind": "^1.1.1" }, @@ -4865,9 +4544,9 @@ } }, "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/html-encoding-sniffer": { @@ -5086,6 +4765,17 @@ "is-ci": "bin.js" } }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -5451,13 +5141,14 @@ } }, "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5465,10 +5156,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-changed-files/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5476,6 +5176,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-changed-files/node_modules/cross-spawn": { @@ -5493,9 +5196,9 @@ } }, "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "dependencies": { "cross-spawn": "^7.0.0", @@ -5510,18 +5213,24 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { "pump": "^3.0.0" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-changed-files/node_modules/is-stream": { @@ -5647,13 +5356,14 @@ } }, "node_modules/jest-config/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5661,10 +5371,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-config/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-config/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5672,18 +5391,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-config/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-config/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -5699,18 +5415,18 @@ } }, "node_modules/jest-config/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -5718,51 +5434,61 @@ } }, "node_modules/jest-config/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-config/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-config/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-config/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -5801,25 +5527,16 @@ "node": ">=8" } }, - "node_modules/jest-config/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "dependencies": { "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { "node": ">= 8.3" @@ -5853,45 +5570,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-each/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-environment-jsdom": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", @@ -5910,43 +5588,46 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -5954,10 +5635,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-jsdom/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -5965,6 +5661,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { @@ -5976,24 +5675,19 @@ "node": ">=8" } }, - "node_modules/jest-environment-jsdom/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6002,37 +5696,60 @@ } }, "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-environment-jsdom/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-environment-jsdom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-environment-jsdom/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6058,43 +5775,46 @@ } }, "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6102,10 +5822,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-environment-node/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6113,6 +5848,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-environment-node/node_modules/escape-string-regexp": { @@ -6124,24 +5862,19 @@ "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6150,37 +5883,60 @@ } }, "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-environment-node/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-environment-node/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-environment-node/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6190,33 +5946,33 @@ } }, "node_modules/jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true, "engines": { "node": ">= 8.3" } }, "node_modules/jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "engines": { "node": ">= 10.14.2" @@ -6226,13 +5982,14 @@ } }, "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6240,10 +5997,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6251,45 +6017,37 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/jest-haste-map/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "node_modules/jest-haste-map/node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } }, "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-haste-map/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/jest-jasmine2": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", @@ -6319,15 +6077,16 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -6335,43 +6094,45 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -6380,13 +6141,14 @@ } }, "node_modules/jest-jasmine2/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6394,16 +6156,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-jasmine2/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-jasmine2/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6411,12 +6188,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-jasmine2/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -6432,95 +6212,90 @@ } }, "node_modules/jest-jasmine2/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-jasmine2/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-jasmine2/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -6529,12 +6304,13 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -6550,18 +6326,18 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -6569,25 +6345,26 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -6595,51 +6372,61 @@ } }, "node_modules/jest-jasmine2/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-jasmine2/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-jasmine2/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -6667,6 +6454,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-jasmine2/node_modules/read-pkg/node_modules/type-fest": { @@ -6678,20 +6468,14 @@ "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-jasmine2/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -6700,9 +6484,9 @@ } }, "node_modules/jest-jasmine2/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6725,13 +6509,14 @@ } }, "node_modules/jest-leak-detector/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6739,10 +6524,19 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-leak-detector/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6750,42 +6544,51 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", "dev": true, "dependencies": { "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { "node": ">= 8.3" @@ -6810,61 +6613,33 @@ "node": ">= 8.3" } }, - "node_modules/jest-message-util/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-message-util/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-mock": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@jest/types": "^25.5.0" }, "engines": { "node": ">= 8.3" } }, "node_modules/jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true, "engines": { "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, "node_modules/jest-regex-util": { @@ -6911,13 +6686,14 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -6925,16 +6701,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-resolve-dependencies/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-resolve-dependencies/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-resolve-dependencies/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -6942,12 +6733,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-resolve-dependencies/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -6963,79 +6757,74 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7053,18 +6842,18 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7072,25 +6861,26 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -7098,51 +6888,61 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-resolve-dependencies/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-resolve-dependencies/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-resolve-dependencies/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7170,6 +6970,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve-dependencies/node_modules/read-pkg/node_modules/type-fest": { @@ -7181,20 +6984,14 @@ "node": ">=8" } }, - "node_modules/jest-resolve-dependencies/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-resolve-dependencies/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -7203,9 +7000,9 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7214,40 +7011,22 @@ "node": ">=10" } }, - "node_modules/jest-resolve/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-resolve/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-resolve/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve/node_modules/read-pkg": { @@ -7288,15 +7067,6 @@ "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runner": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", @@ -7328,15 +7098,16 @@ } }, "node_modules/jest-runner/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -7344,43 +7115,45 @@ } }, "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -7389,13 +7162,14 @@ } }, "node_modules/jest-runner/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -7403,10 +7177,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-runner/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-runner/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-runner/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7414,6 +7203,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runner/node_modules/escape-string-regexp": { @@ -7425,24 +7217,19 @@ "node": ">=8" } }, - "node_modules/jest-runner/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7451,30 +7238,31 @@ } }, "node_modules/jest-runner/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7482,36 +7270,61 @@ } }, "node_modules/jest-runner/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runner/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-runner/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" } }, + "node_modules/jest-runner/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-runner/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7550,19 +7363,10 @@ "node": ">=8" } }, - "node_modules/jest-runner/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runner/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7612,15 +7416,16 @@ } }, "node_modules/jest-runtime/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -7628,43 +7433,45 @@ } }, "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -7673,13 +7480,14 @@ } }, "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -7687,16 +7495,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-runtime/node_modules/@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -7704,12 +7527,15 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-runtime/node_modules/diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { "node": ">= 10.14.2" @@ -7725,79 +7551,74 @@ } }, "node_modules/jest-runtime/node_modules/expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-runtime/node_modules/jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -7806,12 +7627,13 @@ } }, "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" @@ -7827,18 +7649,18 @@ } }, "node_modules/jest-runtime/node_modules/jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "engines": { @@ -7846,25 +7668,26 @@ } }, "node_modules/jest-runtime/node_modules/jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "dependencies": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "engines": { @@ -7872,51 +7695,61 @@ } }, "node_modules/jest-runtime/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-runtime/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-runtime/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-runtime/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7955,20 +7788,14 @@ "node": ">=8" } }, - "node_modules/jest-runtime/node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "dependencies": { - "path-parse": "^1.0.6" - } - }, "node_modules/jest-runtime/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -7977,9 +7804,9 @@ } }, "node_modules/jest-runtime/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7989,23 +7816,18 @@ } }, "node_modules/jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "dependencies": { + "@types/node": "*", "graceful-fs": "^4.2.4" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-serializer/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-snapshot": { "version": "25.5.1", "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", @@ -8032,90 +7854,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-snapshot/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-snapshot/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -8141,27 +7879,6 @@ "node": ">= 8.3" } }, - "node_modules/jest-util/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-util/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-validate": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", @@ -8180,13 +7897,14 @@ } }, "node_modules/jest-validate/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8194,19 +7912,31 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-validate/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-validate/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8214,32 +7944,41 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-watcher": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", @@ -8258,15 +7997,16 @@ } }, "node_modules/jest-watcher/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -8274,13 +8014,13 @@ } }, "node_modules/jest-watcher/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -8289,13 +8029,14 @@ } }, "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8303,10 +8044,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-watcher/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8314,6 +8070,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest-watcher/node_modules/escape-string-regexp": { @@ -8325,24 +8084,19 @@ "node": ">=8" } }, - "node_modules/jest-watcher/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest-watcher/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -8351,25 +8105,47 @@ } }, "node_modules/jest-watcher/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest-watcher/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest-watcher/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest-watcher/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -8379,28 +8155,30 @@ } }, "node_modules/jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "dependencies": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10.13.0" } }, "node_modules/jest/node_modules/@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" }, "engines": { @@ -8408,13 +8186,13 @@ } }, "node_modules/jest/node_modules/@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -8423,13 +8201,14 @@ } }, "node_modules/jest/node_modules/@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" }, @@ -8437,10 +8216,25 @@ "node": ">= 10.14.2" } }, + "node_modules/jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest/node_modules/@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "node_modules/jest/node_modules/chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { "ansi-styles": "^4.1.0", @@ -8448,6 +8242,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/jest/node_modules/escape-string-regexp": { @@ -8459,12 +8256,6 @@ "node": ">=8" } }, - "node_modules/jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "node_modules/jest/node_modules/jest-cli": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", @@ -8493,17 +8284,18 @@ } }, "node_modules/jest/node_modules/jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, @@ -8512,25 +8304,47 @@ } }, "node_modules/jest/node_modules/jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, + "node_modules/jest/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/jest/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/jest/node_modules/stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -8613,10 +8427,10 @@ "node": ">=4" } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "node_modules/json-schema": { @@ -8788,7 +8602,19 @@ "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" } }, "node_modules/lua-types": { @@ -8876,16 +8702,16 @@ } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/mime-db": { @@ -9050,11 +8876,14 @@ } }, "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -9299,15 +9128,18 @@ } }, "node_modules/p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { "p-try": "^2.0.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { @@ -9421,12 +9253,15 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true, "engines": { "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, "node_modules/pify": { @@ -9493,12 +9328,12 @@ } }, "node_modules/pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "dependencies": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -9564,9 +9399,9 @@ } }, "node_modules/react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "node_modules/read-pkg": { @@ -9826,11 +9661,15 @@ "dev": true }, "node_modules/resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dependencies": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/resolve-cwd": { @@ -10554,12 +10393,24 @@ } }, "node_modules/stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, "node_modules/static-extend": { @@ -10610,9 +10461,9 @@ } }, "node_modules/string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "dependencies": { "emoji-regex": "^8.0.0", @@ -10698,9 +10549,9 @@ } }, "node_modules/supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { "has-flag": "^4.0.0" @@ -10968,122 +10819,104 @@ } }, "node_modules/ts-jest/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/@types/jest": { - "version": "26.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", - "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "node_modules/ts-jest/node_modules/@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "dependencies": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "@types/istanbul-lib-report": "*" } }, - "node_modules/ts-jest/node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "node_modules/ts-jest/node_modules/@types/jest": { + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, - "engines": { - "node": ">= 8.3" + "dependencies": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" } }, - "node_modules/ts-jest/node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "node_modules/ts-jest/node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "node_modules/ts-jest/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 8.3" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/ts-jest/node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "node_modules/ts-jest/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", - "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "node_modules/ts-jest/node_modules/jest-diff": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "dependencies": { - "@jest/types": "^26.3.0", - "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/@jest/types": { + "node_modules/ts-jest/node_modules/jest-get-type": { "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/ts-jest/node_modules/jest-util/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "node_modules/ts-jest/node_modules/jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" }, "engines": { - "node": ">=10" + "node": ">= 10.14.2" } }, "node_modules/ts-jest/node_modules/mkdirp": { @@ -11099,25 +10932,34 @@ } }, "node_modules/ts-jest/node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" + "node": ">= 10" } }, + "node_modules/ts-jest/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, "bin": { "semver": "bin/semver.js" }, @@ -11152,15 +10994,18 @@ "dev": true }, "node_modules/tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "dependencies": { "tslib": "^1.8.1" }, "engines": { "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, "node_modules/tunnel-agent": { @@ -11557,6 +11402,12 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", @@ -11604,12 +11455,12 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", "dev": true, "requires": { - "@babel/highlight": "^7.8.3" + "@babel/highlight": "^7.12.13" } }, "@babel/core": { @@ -11636,74 +11487,6 @@ "source-map": "^0.5.0" }, "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -11713,14 +11496,13 @@ } }, "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", + "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", "dev": true, "requires": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.14.2", "jsesc": "^2.5.1", - "lodash": "^4.17.13", "source-map": "^0.5.0" }, "dependencies": { @@ -11733,23 +11515,23 @@ } }, "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", + "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.14.2" } }, "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "@babel/helper-member-expression-to-functions": { @@ -11783,36 +11565,6 @@ "@babel/template": "^7.8.6", "@babel/types": "^7.9.0", "lodash": "^4.17.13" - }, - "dependencies": { - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - } } }, "@babel/helper-optimise-call-expression": { @@ -11840,71 +11592,6 @@ "@babel/helper-optimise-call-expression": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" - }, - "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/helper-simple-access": { @@ -11918,18 +11605,18 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.12.13" } }, "@babel/helper-validator-identifier": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", - "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", "dev": true }, "@babel/helpers": { @@ -11941,81 +11628,16 @@ "@babel/template": "^7.8.3", "@babel/traverse": "^7.9.6", "@babel/types": "^7.9.6" - }, - "dependencies": { - "@babel/generator": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.6.tgz", - "integrity": "sha512-+htwWKJbH2bL72HRluF8zumBxzuX0ZZUFl3JLNyoUjM/Ho8wnVpPXM6aUz8cfKDqQ/h7zHqKt4xzJteUosckqQ==", - "dev": true, - "requires": { - "@babel/types": "^7.9.6", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - } - }, - "@babel/helper-function-name": { - "version": "7.9.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", - "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.9.5" - } - }, - "@babel/parser": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.6.tgz", - "integrity": "sha512-AoeIEJn8vt+d/6+PXDRPaksYhnlbMIiejioBZvvMQsOjW/JYK6k/0dKnvvP3EhK5GfMBWDPtrxRtegWdAcdq9Q==", - "dev": true - }, - "@babel/traverse": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.6.tgz", - "integrity": "sha512-b3rAHSjbxy6VEAvlxM8OV/0X4XrG72zoxme6q1MOoe2vd0bEc+TwayhuC1+Dfgqh1QEG+pj7atQqvUprHIccsg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-function-name": "^7.9.5", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.6", - "@babel/types": "^7.9.6", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.6.tgz", - "integrity": "sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.9.5", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } } }, "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", "dev": true, "requires": { + "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", - "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -12072,9 +11694,9 @@ } }, "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==", + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -12168,41 +11790,39 @@ } }, "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" } }, "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", + "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.2", + "@babel/helper-function-name": "^7.14.2", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.2", + "@babel/types": "^7.14.2", "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" + "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.14.0", "to-fast-properties": "^2.0.0" } }, @@ -12252,20 +11872,6 @@ "jest-message-util": "^25.5.0", "jest-util": "^25.5.0", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/core": { @@ -12304,52 +11910,69 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12357,9 +11980,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -12369,67 +11992,62 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } @@ -12441,81 +12059,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -12547,25 +12173,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12582,20 +12202,6 @@ "@jest/fake-timers": "^25.5.0", "@jest/types": "^25.5.0", "jest-mock": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/fake-timers": { @@ -12609,20 +12215,6 @@ "jest-mock": "^25.5.0", "jest-util": "^25.5.0", "lolex": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/globals": { @@ -12637,45 +12229,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12683,9 +12293,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -12695,78 +12305,74 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -12776,34 +12382,41 @@ "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12845,46 +12458,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -12897,69 +12527,83 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -12991,15 +12635,6 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -13007,9 +12642,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -13028,12 +12663,6 @@ "source-map": "^0.6.0" }, "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -13052,20 +12681,6 @@ "@jest/types": "^25.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "@jest/test-sequencer": { @@ -13082,46 +12697,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -13134,45 +12766,59 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -13204,33 +12850,37 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-regex-util": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", @@ -13238,16 +12888,17 @@ "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "source-map": { @@ -13259,9 +12910,9 @@ } }, "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13355,12 +13006,6 @@ "@babel/types": "^7.3.0" } }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true - }, "@types/events": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", @@ -13412,9 +13057,9 @@ } }, "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "*", @@ -13422,13 +13067,13 @@ } }, "@types/jest": { - "version": "25.1.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.1.3.tgz", - "integrity": "sha512-jqargqzyJWgWAJCXX96LBGR/Ei7wQcZBvRv0PLEu9ZByMfcs23keUJrKv9FMR6YZf9YCbfqDqgmY+JUBsnqhrg==", + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, "requires": { - "jest-diff": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, "@types/json-schema": { @@ -13495,67 +13140,35 @@ "version": "2.31.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "2.31.0", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - } - }, - "eslint-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.0.0.tgz", - "integrity": "sha512-0HCPuJv+7Wv1bACm8y5/ECVfYdfsAm9xmVb7saeFlxjPYALefjhbYoCkBjPdPzGH8wWyTpAez82Fh3VKYEZ8OA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.31.0", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" } }, "@typescript-eslint/experimental-utils": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", - "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", + "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.23.0", - "eslint-scope": "^5.0.0" + "@typescript-eslint/typescript-estree": "2.31.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + } } }, "@typescript-eslint/parser": { @@ -13587,10 +13200,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -13611,9 +13227,9 @@ "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", - "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "version": "2.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", + "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", "dev": true, "requires": { "debug": "^4.1.1", @@ -13630,15 +13246,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } } } }, @@ -13653,9 +13260,9 @@ }, "dependencies": { "eslint-visitor-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", - "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true } } @@ -13667,9 +13274,9 @@ "dev": true }, "acorn": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.2.0.tgz", - "integrity": "sha512-apwXVmYVpQ34m/i71vrApRrRKCWQnZZF1+npOD0WV5xZFfwWOmKGQ2RWlfdy9vWITsenisM8M0Qeq8agcFHNiQ==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true }, "acorn-globals": { @@ -13722,19 +13329,18 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -13883,32 +13489,36 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true } } }, @@ -14363,12 +13973,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "decamelize": { @@ -14470,9 +14080,9 @@ "dev": true }, "diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true }, "dir-glob": { @@ -14931,9 +14541,9 @@ } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true }, "espree": { @@ -14945,14 +14555,6 @@ "acorn": "^7.1.1", "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "acorn": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", - "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", - "dev": true - } } }, "esprima": { @@ -15080,68 +14682,6 @@ "jest-matcher-utils": "^25.5.0", "jest-message-util": "^25.5.0", "jest-regex-util": "^25.2.6" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - } } }, "extend": { @@ -15409,14 +14949,6 @@ "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "dev": true - } } }, "fs.realpath": { @@ -15435,8 +14967,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "functional-red-black-tree": { "version": "1.0.1", @@ -15538,9 +15069,9 @@ } }, "graceful-fs": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", "dev": true }, "growly": { @@ -15570,7 +15101,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -15640,9 +15170,9 @@ } }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "html-encoding-sniffer": { @@ -15816,6 +15346,14 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -16088,46 +15626,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16140,12 +15695,6 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-cli": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", @@ -16168,38 +15717,58 @@ } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16219,21 +15788,31 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16252,9 +15831,9 @@ } }, "execa": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.2.tgz", - "integrity": "sha512-QI2zLa6CjGWdiQsmSkZoGtDx2N+cQIGb3yNolGTdjSQzydzLgYYf8LRuagp7S7fPimjcrzUDSUFd/MgzELMi4Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -16269,9 +15848,9 @@ } }, "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -16375,37 +15954,41 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-regex-util": { @@ -16415,58 +15998,65 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -16497,28 +16087,19 @@ "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, "jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "requires": { "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, "jest-docblock": { @@ -16541,38 +16122,6 @@ "jest-get-type": "^25.2.6", "jest-util": "^25.5.0", "pretty-format": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - } } }, "jest-environment-jsdom": { @@ -16590,45 +16139,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16641,54 +16208,69 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16710,45 +16292,63 @@ }, "dependencies": { "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@types/istanbul-lib-report": "*" } }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16761,54 +16361,69 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -16817,80 +16432,83 @@ } }, "jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==", + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true }, "jest-haste-map": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.0.1.tgz", - "integrity": "sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", + "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", - "jest-serializer": "^26.0.0", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", "dev": true }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" + "micromatch": "^4.0.2" } } } @@ -16921,76 +16539,95 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -16998,9 +16635,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -17010,91 +16647,87 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-each": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.0.1.tgz", - "integrity": "sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1" + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -17104,81 +16737,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17210,25 +16851,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17247,21 +16882,31 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17269,35 +16914,41 @@ } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, "jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", "dev": true, "requires": { "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, "jest-message-util": { @@ -17314,26 +16965,6 @@ "micromatch": "^4.0.2", "slash": "^3.0.0", "stack-utils": "^1.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-mock": { @@ -17343,27 +16974,14 @@ "dev": true, "requires": { "@jest/types": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - } } }, "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==", - "dev": true + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "25.2.6", @@ -17388,33 +17006,15 @@ "slash": "^3.0.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, @@ -17448,15 +17048,6 @@ "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } - }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } } } }, @@ -17472,27 +17063,43 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17500,9 +17107,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -17512,67 +17119,62 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } @@ -17584,81 +17186,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17690,25 +17300,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17744,70 +17348,89 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -17820,78 +17443,93 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17923,19 +17561,10 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -17978,76 +17607,95 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/environment": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.0.1.tgz", - "integrity": "sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1" + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" } }, "@jest/fake-timers": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.0.1.tgz", - "integrity": "sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "@types/prettier": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.1.tgz", - "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", + "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18055,9 +17703,9 @@ } }, "diff-sequences": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.0.0.tgz", - "integrity": "sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "escape-string-regexp": { @@ -18067,78 +17715,74 @@ "dev": true }, "expect": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.0.1.tgz", - "integrity": "sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-diff": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.0.1.tgz", - "integrity": "sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.0.0", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-matcher-utils": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz", - "integrity": "sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-mock": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.0.1.tgz", - "integrity": "sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.0.1" + "@jest/types": "^26.6.2", + "@types/node": "*" } }, "jest-regex-util": { @@ -18148,81 +17792,89 @@ "dev": true }, "jest-resolve": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.0.1.tgz", - "integrity": "sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "jest-util": "^26.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" } }, "jest-snapshot": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.0.1.tgz", - "integrity": "sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.0.1", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "make-dir": "^3.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.0.1", + "pretty-format": "^26.6.2", "semver": "^7.3.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" } }, "parse-json": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", - "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1", + "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -18254,25 +17906,19 @@ "type-fest": "^0.8.1" } }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "requires": { - "path-parse": "^1.0.6" + "lru-cache": "^6.0.0" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -18281,20 +17927,13 @@ } }, "jest-serializer": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.0.0.tgz", - "integrity": "sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { + "@types/node": "*", "graceful-fs": "^4.2.4" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-snapshot": { @@ -18320,72 +17959,6 @@ "semver": "^6.3.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -18405,26 +17978,6 @@ "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "make-dir": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } } }, "jest-validate": { @@ -18442,27 +17995,37 @@ }, "dependencies": { "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18470,22 +18033,28 @@ } }, "jest-get-type": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", - "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "pretty-format": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", - "integrity": "sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true } } }, @@ -18504,46 +18073,63 @@ }, "dependencies": { "@jest/console": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.0.1.tgz", - "integrity": "sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.0.1", - "jest-util": "^26.0.1", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", "slash": "^3.0.0" } }, "@jest/test-result": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.0.1.tgz", - "integrity": "sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/types": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.0.1.tgz", - "integrity": "sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", "chalk": "^4.0.0" } }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "dev": true + }, "chalk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", - "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -18556,45 +18142,59 @@ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, "jest-message-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.0.1.tgz", - "integrity": "sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.0.1", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" } }, "jest-util": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.0.1.tgz", - "integrity": "sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.0.1", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "micromatch": "^4.0.2" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -18603,11 +18203,12 @@ } }, "jest-worker": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.0.0.tgz", - "integrity": "sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { + "@types/node": "*", "merge-stream": "^2.0.0", "supports-color": "^7.0.0" } @@ -18674,10 +18275,10 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema": { @@ -18824,6 +18425,15 @@ "@sinonjs/commons": "^1.7.0" } }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "lua-types": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", @@ -18896,13 +18506,13 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "requires": { "braces": "^3.0.1", - "picomatch": "^2.0.5" + "picomatch": "^2.2.3" } }, "mime-db": { @@ -19042,11 +18652,14 @@ }, "dependencies": { "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, - "optional": true + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "which": { "version": "2.0.2", @@ -19235,9 +18848,9 @@ "dev": true }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -19327,9 +18940,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", "dev": true }, "pify": { @@ -19375,12 +18988,12 @@ "dev": true }, "pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "requires": { - "@jest/types": "^25.1.0", + "@jest/types": "^25.5.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" @@ -19431,9 +19044,9 @@ "dev": true }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==", + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "read-pkg": { @@ -19639,10 +19252,11 @@ "dev": true }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "requires": { + "is-core-module": "^2.2.0", "path-parse": "^1.0.6" } }, @@ -20246,10 +19860,21 @@ } }, "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } }, "static-extend": { "version": "0.1.2", @@ -20289,9 +19914,9 @@ } }, "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", "dev": true, "requires": { "emoji-regex": "^8.0.0", @@ -20353,9 +19978,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -20570,103 +20195,83 @@ }, "dependencies": { "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" } }, "@types/jest": { - "version": "26.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", - "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "version": "26.0.23", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", + "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", "dev": true, "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" } }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", - "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", "micromatch": "^4.0.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "mkdirp": { @@ -20676,22 +20281,31 @@ "dev": true }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -20715,9 +20329,9 @@ "dev": true }, "tsutils": { - "version": "3.17.1", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", - "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -21047,6 +20661,12 @@ "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "yargs": { "version": "15.3.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", From 1945d93d2150c39cd67b87c0a5437024cb6e2d5d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 10 Jun 2021 17:42:37 +0200 Subject: [PATCH 347/764] Update TS and ESLint (#1027) * Upgrade to TS 4.3 * Upgrade eslint * npm audit fix * Fixed build issue * Fixed issue with benchmark json type --- .eslintrc.js | 153 +- benchmark/src/memory_benchmark.ts | 2 +- .../src/memory_benchmarks/graph_cylce.ts | 2 +- benchmark/src/util.ts | 2 +- language-extensions/index.d.ts | 22 +- package-lock.json | 2312 +++++++++-------- package.json | 8 +- src/LuaAST.ts | 2 +- src/LuaPrinter.ts | 2 +- src/cli/tsconfig.ts | 4 +- src/lualib/ArrayToObject.ts | 2 +- src/lualib/Decorate.ts | 13 +- src/lualib/DecorateParam.ts | 13 +- src/lualib/Error.ts | 2 +- src/lualib/ObjectAssign.ts | 1 + src/lualib/ObjectDefineProperty.ts | 2 +- src/lualib/WeakMap.ts | 2 +- src/lualib/WeakSet.ts | 2 +- src/lualib/declarations/debug.d.ts | 2 +- src/lualib/declarations/global.d.ts | 8 +- src/lualib/declarations/luatable.d.ts | 2 +- src/transformation/utils/annotations.ts | 18 +- src/transformation/utils/export.ts | 2 +- .../utils/language-extensions.ts | 2 +- src/transformation/utils/safe-names.ts | 2 +- src/transformation/utils/scope.ts | 2 +- src/transformation/visitors/call.ts | 6 +- src/transformation/visitors/namespace.ts | 4 +- src/utils.ts | 1 + test/setup.ts | 2 +- 30 files changed, 1416 insertions(+), 1181 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index dabc1db41..52df969ff 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,70 +1,3 @@ -// https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js -const typescriptBase = { - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "error", - { - types: { - Function: null, - CallableFunction: { fixWith: "(...args: any[]) => any" }, - NewableFunction: { fixWith: "new (...args: any[]) => any" }, - }, - }, - ], - camelcase: "off", - "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], - "@typescript-eslint/class-name-casing": "error", - "@typescript-eslint/consistent-type-assertions": [ - "error", - { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, - ], - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/explicit-member-accessibility": ["error", { overrides: { constructors: "no-public" } }], - "@typescript-eslint/generic-type-naming": ["error", "^(T([A-Z][A-Za-z]*)?|U|P|K|V)$"], - "@typescript-eslint/interface-name-prefix": "error", - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-extra-non-null-assertion": "error", - "@typescript-eslint/no-extraneous-class": "error", - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-misused-promises": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-require-imports": "error", - "@typescript-eslint/no-this-alias": "error", - "no-throw-literal": "off", - "@typescript-eslint/no-throw-literal": "error", - "no-constant-condition": "off", - "@typescript-eslint/no-unnecessary-condition": ["error", { ignoreRhs: true, allowConstantLoopConditions: true }], - "@typescript-eslint/no-unnecessary-qualifier": "error", - "@typescript-eslint/no-unnecessary-type-arguments": "error", - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": "error", - "@typescript-eslint/prefer-function-type": "error", - "@typescript-eslint/prefer-includes": "error", - "@typescript-eslint/prefer-optional-chain": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/prefer-readonly": "error", - "@typescript-eslint/prefer-string-starts-ends-with": "error", - "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], - quotes: "off", - "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], - "@typescript-eslint/require-array-sort-compare": "error", - "@typescript-eslint/require-await": "error", - "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], - "@typescript-eslint/return-await": "error", - "@typescript-eslint/triple-slash-reference": "error", - "@typescript-eslint/unified-signatures": "error", -}; - module.exports = { extends: ["plugin:jest/recommended", "plugin:jest/style"], parserOptions: { @@ -149,7 +82,74 @@ module.exports = { files: "**/*.ts", extends: ["plugin:@typescript-eslint/base"], rules: { - ...typescriptBase, + // https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": "error", + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/ban-types": [ + "error", + { + types: { + Function: null, + CallableFunction: { fixWith: "(...args: any[]) => any" }, + NewableFunction: { fixWith: "new (...args: any[]) => any" }, + }, + }, + ], + camelcase: "off", + "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], + "@typescript-eslint/consistent-type-assertions": [ + "error", + { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, + ], + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": [ + "error", + { overrides: { constructors: "no-public" } }, + ], + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-namespace": "error", + "@typescript-eslint/no-require-imports": "error", + "@typescript-eslint/no-this-alias": "error", + "no-throw-literal": "off", + "@typescript-eslint/no-throw-literal": "error", + "no-constant-condition": "off", + "@typescript-eslint/no-unnecessary-condition": [ + "error", + { ignoreRhs: true, allowConstantLoopConditions: true }, + ], + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-readonly": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + quotes: "off", + "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], + "@typescript-eslint/require-array-sort-compare": "error", + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", + // end of https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js "@typescript-eslint/array-type": ["error", { default: "array-simple" }], "@typescript-eslint/ban-types": ["error", { types: { null: null } }], "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], @@ -182,6 +182,23 @@ module.exports = { selector: "enumMember", format: ["PascalCase"], }, + { + selector: "typeParameter", + format: ["PascalCase"], + prefix: ["T"], + filter: { + regex: "K|V", + match: false, + }, + }, + { + selector: "interface", + format: ["PascalCase"], + custom: { + regex: "^I[A-Z]", + match: false, + }, + }, ], }, }, diff --git a/benchmark/src/memory_benchmark.ts b/benchmark/src/memory_benchmark.ts index 10934757a..51f8031be 100644 --- a/benchmark/src/memory_benchmark.ts +++ b/benchmark/src/memory_benchmark.ts @@ -1,7 +1,7 @@ import { BenchmarkKind, MemoryBenchmarkResult, ComparisonInfo, MemoryBenchmarkCategory } from "./benchmark_types"; import { toFixed, json, calculatePercentageChange } from "./util"; -export function runMemoryBenchmark(benchmarkFunction: Function): MemoryBenchmarkResult { +export function runMemoryBenchmark(benchmarkFunction: () => void): MemoryBenchmarkResult { const result: MemoryBenchmarkResult = { kind: BenchmarkKind.Memory, benchmarkName: "NO_NAME", diff --git a/benchmark/src/memory_benchmarks/graph_cylce.ts b/benchmark/src/memory_benchmarks/graph_cylce.ts index c78812dc5..c75372d07 100644 --- a/benchmark/src/memory_benchmarks/graph_cylce.ts +++ b/benchmark/src/memory_benchmarks/graph_cylce.ts @@ -1,4 +1,4 @@ -type Graph = Map; +type Graph = Map; function range(start: number, end: number): number[] { if (start > end) return []; diff --git a/benchmark/src/util.ts b/benchmark/src/util.ts index d1c9fcc1d..bd1c0a10f 100644 --- a/benchmark/src/util.ts +++ b/benchmark/src/util.ts @@ -12,7 +12,7 @@ export function calculatePercentageChange(oldValue: number, newValue: number): n export const isWindows = package.config.startsWith("\\"); export const json: { - decode: (this: void, str: string) => {}; + decode: (this: void, str: string) => Record | unknown[]; encode: (this: void, val: any) => string; } = require("json"); diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index ad3692a97..761d6a68e 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,3 +1,7 @@ +type AnyTable = Record; +// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/consistent-type-definitions +type AnyNotNil = {}; + /** * Indicates a type is a language extension provided by TypescriptToLua. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -445,7 +449,10 @@ declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLen * @param TKey The type of the key to use to access the table. * @param TValue The type of the value stored in the table. */ -declare type LuaTableGet = ((table: TTable, key: TKey) => TValue) & +declare type LuaTableGet = (( + table: TTable, + key: TKey +) => TValue) & LuaExtension<"__luaTableGetBrand">; /** @@ -455,7 +462,7 @@ declare type LuaTableGet = ((tab * @param TKey The type of the key to use to access the table. * @param TValue The type of the value stored in the table. */ -declare type LuaTableGetMethod = ((key: TKey) => TValue) & +declare type LuaTableGetMethod = ((key: TKey) => TValue) & LuaExtension<"__luaTableGetMethodBrand">; /** @@ -466,7 +473,7 @@ declare type LuaTableGetMethod = ((key: TKey) => TValue * @param TKey The type of the key to use to access the table. * @param TValue The type of the value to assign to the table. */ -declare type LuaTableSet = (( +declare type LuaTableSet = (( table: TTable, key: TKey, value: TValue @@ -480,7 +487,7 @@ declare type LuaTableSet = (( * @param TKey The type of the key to use to access the table. * @param TValue The type of the value to assign to the table. */ -declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; /** @@ -490,7 +497,7 @@ declare type LuaTableSetMethod = ((key: TKey, value: TV * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare interface LuaTable { +declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; @@ -503,7 +510,10 @@ declare interface LuaTable { * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare type LuaTableConstructor = (new () => LuaTable) & +declare type LuaTableConstructor = (new () => LuaTable< + TKey, + TValue +>) & LuaExtension<"__luaTableNewBrand">; /** diff --git a/package-lock.json b/package-lock.json index a4be60bc2..93b27be93 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": ">=4.0.2" + "typescript": "~4.3.2" }, "bin": { "tstl": "dist/tstl.js" @@ -22,9 +22,9 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^4.1.0", - "eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", "fs-extra": "^8.1.0", @@ -456,6 +456,69 @@ "node": ">=0.1.95" } }, + "node_modules/@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -584,9 +647,9 @@ } }, "node_modules/@jest/core/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -983,9 +1046,9 @@ } }, "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1266,9 +1329,9 @@ } }, "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1562,9 +1625,9 @@ } }, "node_modules/@jest/test-sequencer/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1714,9 +1777,9 @@ } }, "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -1789,12 +1852,12 @@ } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -1802,21 +1865,21 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -1953,9 +2016,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "node_modules/@types/minimatch": { @@ -2013,18 +2076,128 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", - "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", + "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/experimental-utils": "4.26.1", + "@typescript-eslint/scope-manager": "4.26.1", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" + "lodash": "^4.17.21", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", + "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, "node_modules/@typescript-eslint/experimental-utils": { @@ -2049,53 +2222,58 @@ "eslint": "*" } }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/@typescript-eslint/parser": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", + "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "debug": "^4.3.1" }, "engines": { - "node": ">=6" + "node": "^10.12.0 || >=12.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", - "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", - "debug": "^4.1.1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", - "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/parser/node_modules/semver": { @@ -2114,25 +2292,33 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", - "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", + "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0" + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", - "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", + "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/typescript-estree": { @@ -2172,16 +2358,20 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", - "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", + "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/types": "4.26.1", "eslint-visitor-keys": "^2.0.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { @@ -2222,10 +2412,13 @@ } }, "node_modules/acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, "node_modules/acorn-walk": { "version": "7.1.1", @@ -2248,6 +2441,15 @@ "uri-js": "^4.2.2" } }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", @@ -2418,12 +2620,12 @@ } }, "node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/asynckit": { @@ -2495,9 +2697,9 @@ } }, "node_modules/babel-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -2811,12 +3013,6 @@ "node": ">=10" } }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "node_modules/ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -2850,24 +3046,6 @@ "node": ">=0.10.0" } }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "node_modules/cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -3283,6 +3461,18 @@ "once": "^1.4.0" } }, + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -3370,46 +3560,48 @@ } }, "node_modules/eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -3417,7 +3609,10 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-import-resolver-node": { @@ -3616,12 +3811,12 @@ } }, "node_modules/eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "engines": { @@ -3629,15 +3824,18 @@ } }, "node_modules/eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { "eslint-visitor-keys": "^1.1.0" }, "engines": { "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, "node_modules/eslint-visitor-keys": { @@ -3649,131 +3847,216 @@ "node": ">=4" } }, - "node_modules/eslint/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "node_modules/eslint/node_modules/@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/eslint/node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "color-convert": "^1.9.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/eslint/node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "color-name": "1.1.3" + "engines": { + "node": ">=8" } }, - "node_modules/eslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "node_modules/eslint/node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "node_modules/eslint/node_modules/globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "node_modules/eslint/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/eslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/eslint/node_modules/regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">=6.5.0" + "node": ">=8" } }, - "node_modules/eslint/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/eslint/node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/eslint/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "node_modules/eslint/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=4" + "node": ">= 8" } }, "node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, "engines": { - "node": ">=6.0.0" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/esprima": { @@ -3790,29 +4073,47 @@ } }, "node_modules/esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=0.6" + "node": ">=0.10" + } + }, + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" } }, "node_modules/esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" }, "engines": { "node": ">=4.0" } }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, "node_modules/estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", @@ -3969,20 +4270,6 @@ "node": ">=0.10.0" } }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -4074,15 +4361,15 @@ ] }, "node_modules/fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -4109,9 +4396,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -4126,28 +4413,16 @@ "bser": "2.1.1" } }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" }, "engines": { - "node": ">=4" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/fill-range": { @@ -4176,35 +4451,22 @@ } }, "node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">=4" - } - }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "node": "^10.12.0 || >=12.0.0" } }, "node_modules/flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "node_modules/for-in": { @@ -4370,9 +4632,9 @@ } }, "node_modules/glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { "is-glob": "^4.0.1" @@ -4391,9 +4653,9 @@ } }, "node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "dependencies": { "array-union": "^2.1.0", @@ -4405,6 +4667,9 @@ }, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/globby/node_modules/ignore": { @@ -4675,30 +4940,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -4917,12 +5158,6 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "node_modules/is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "node_modules/is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -5157,9 +5392,9 @@ } }, "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5372,9 +5607,9 @@ } }, "node_modules/jest-config/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5636,9 +5871,9 @@ } }, "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5823,9 +6058,9 @@ } }, "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -5998,9 +6233,9 @@ } }, "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6157,9 +6392,9 @@ } }, "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6525,9 +6760,9 @@ } }, "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -6702,9 +6937,9 @@ } }, "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7178,9 +7413,9 @@ } }, "node_modules/jest-runner/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7496,9 +7731,9 @@ } }, "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -7913,9 +8148,9 @@ } }, "node_modules/jest-validate/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8045,9 +8280,9 @@ } }, "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8217,9 +8452,9 @@ } }, "node_modules/jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -8584,18 +8819,36 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "node_modules/lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "node_modules/lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -8787,30 +9040,12 @@ "node": ">=0.10.0" } }, - "node_modules/mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -9100,15 +9335,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", @@ -9398,6 +9624,26 @@ "node": ">=0.6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -9654,6 +9900,15 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -9688,30 +9943,17 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "dev": true, "engines": { "node": ">=8" } }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, "node_modules/ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -9752,34 +9994,27 @@ "node": "6.* || >= 7.*" } }, - "node_modules/run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "dependencies": { - "is-promise": "^2.1.0" - }, - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "node_modules/rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" + "queue-microtask": "^1.2.2" } }, "node_modules/safe-buffer": { @@ -10073,53 +10308,20 @@ } }, "node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">=6" - } - }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" + "node": ">=10" }, - "engines": { - "node": ">=4" - } - }, - "node_modules/slice-ansi/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/slice-ansi/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/snapdragon": { @@ -10540,12 +10742,15 @@ } }, "node_modules/strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/supports-color": { @@ -10580,69 +10785,43 @@ "dev": true }, "node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/table/node_modules/ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/table/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/table/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true, - "engines": { - "node": ">=4" + "node": ">=10.0.0" } }, - "node_modules/table/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "node_modules/table/node_modules/ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/table/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true }, "node_modules/terminal-link": { "version": "2.1.1", @@ -10683,24 +10862,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -10835,9 +10996,9 @@ } }, "node_modules/ts-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" @@ -11066,9 +11227,9 @@ } }, "node_modules/typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", + "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11351,18 +11512,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -11376,12 +11525,24 @@ } }, "node_modules/ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "dev": true, "engines": { "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/xml-name-validator": { @@ -11842,6 +12003,52 @@ "minimist": "^1.2.0" } }, + "@eslint/eslintrc": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", + "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -11949,9 +12156,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -12268,9 +12475,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -12497,9 +12704,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -12736,9 +12943,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -12863,9 +13070,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -12922,28 +13129,28 @@ } }, "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", + "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -13077,9 +13284,9 @@ } }, "@types/json-schema": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", - "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", "dev": true }, "@types/minimatch": { @@ -13137,15 +13344,74 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.31.0.tgz", - "integrity": "sha512-iIC0Pb8qDaoit+m80Ln/aaeu9zKQdOLF4SHcGLarSeY1gurW6aU4JsOPMjKQwXlw70MvWKZQc6S2NamA8SJ/gg==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", + "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.31.0", + "@typescript-eslint/experimental-utils": "4.26.1", + "@typescript-eslint/scope-manager": "4.26.1", + "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.0.0", - "tsutils": "^3.17.1" + "lodash": "^4.17.21", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", + "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/experimental-utils": { @@ -13158,45 +13424,33 @@ "@typescript-eslint/typescript-estree": "2.31.0", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - } } }, "@typescript-eslint/parser": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.1.0.tgz", - "integrity": "sha512-hM/WNCQTzDHgS0Ke3cR9zPndL3OTKr9OoN9CL3UqulsAjYDrglSwIIgswSmHBcSbOzLmgaMARwrQEbIumIglvQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", + "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.1.0", - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/typescript-estree": "4.1.0", - "debug": "^4.1.1" + "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/typescript-estree": "4.26.1", + "debug": "^4.3.1" }, "dependencies": { "@typescript-eslint/typescript-estree": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.1.0.tgz", - "integrity": "sha512-r6et57qqKAWU173nWyw31x7OfgmKfMEcjJl9vlJEzS+kf9uKNRr4AVTRXfTCwebr7bdiVEkfRY5xGnpPaNPe4Q==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", + "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0", - "debug": "^4.1.1", - "globby": "^11.0.1", + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, "semver": { @@ -13211,19 +13465,19 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.1.0.tgz", - "integrity": "sha512-HD1/u8vFNnxwiHqlWKC/Pigdn0Mvxi84Y6GzbZ5f5sbLrFKu0al02573Er+D63Sw67IffVUXR0uR8rpdfdk+vA==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", + "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", - "@typescript-eslint/visitor-keys": "4.1.0" + "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/visitor-keys": "4.26.1" } }, "@typescript-eslint/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.1.0.tgz", - "integrity": "sha512-rkBqWsO7m01XckP9R2YHVN8mySOKKY2cophGM8K5uDK89ArCgahItQYdbg/3n8xMxzu2elss+an1TphlUpDuJw==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", + "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", "dev": true }, "@typescript-eslint/typescript-estree": { @@ -13250,12 +13504,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.1.0.tgz", - "integrity": "sha512-+taO0IZGCtCEsuNTTF2Q/5o8+fHrlml8i9YsZt2AiDCdYEJzYlsmRY991l/6f3jNXFyAWepdQj7n8Na6URiDRQ==", + "version": "4.26.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", + "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", "dev": true, "requires": { - "@typescript-eslint/types": "4.1.0", + "@typescript-eslint/types": "4.26.1", "eslint-visitor-keys": "^2.0.0" }, "dependencies": { @@ -13290,10 +13544,11 @@ } }, "acorn-jsx": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", - "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", - "dev": true + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "requires": {} }, "acorn-walk": { "version": "7.1.1", @@ -13313,6 +13568,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, "ansi-escapes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", @@ -13443,9 +13704,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "asynckit": { @@ -13502,9 +13763,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -13770,12 +14031,6 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", @@ -13805,21 +14060,6 @@ } } }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", @@ -14153,6 +14393,15 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -14221,134 +14470,185 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", + "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.2", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - "globals": "^12.1.0", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.14", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", - "table": "^5.2.3", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "globals": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", + "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "type-fest": "^0.20.2" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "color-name": "1.1.3" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "prelude-ls": "^1.2.1" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "isexe": "^2.0.0" } } } @@ -14522,19 +14822,19 @@ } }, "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" @@ -14547,14 +14847,14 @@ "dev": true }, "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" } }, "esprima": { @@ -14564,21 +14864,37 @@ "dev": true }, "esquery": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "estraverse": { @@ -14711,17 +15027,6 @@ } } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -14794,15 +15099,15 @@ "dev": true }, "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -14826,9 +15131,9 @@ "dev": true }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -14843,22 +15148,13 @@ "bser": "2.1.1" } }, - "figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "fill-range": { @@ -14881,31 +15177,19 @@ } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "for-in": { @@ -15032,9 +15316,9 @@ } }, "glob-parent": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", - "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "requires": { "is-glob": "^4.0.1" @@ -15047,9 +15331,9 @@ "dev": true }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", + "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -15272,27 +15556,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "inquirer": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", - "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.4.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6" - } - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -15460,12 +15723,6 @@ "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", "dev": true }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -15665,9 +15922,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -15801,9 +16058,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -15967,9 +16224,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -16178,9 +16435,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -16331,9 +16588,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -16473,9 +16730,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -16604,9 +16861,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -16895,9 +17152,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -17076,9 +17333,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -17413,9 +17670,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -17672,9 +17929,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -18008,9 +18265,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -18112,9 +18369,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -18404,18 +18661,36 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", "dev": true }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", "dev": true }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, "lolex": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", @@ -18572,27 +18847,12 @@ } } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -18829,12 +19089,6 @@ "word-wrap": "~1.2.3" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, "p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", @@ -19043,6 +19297,12 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -19245,6 +19505,12 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -19281,16 +19547,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -19318,28 +19574,13 @@ "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true }, - "run-async": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true - }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "requires": { - "tslib": "^1.9.0" + "queue-microtask": "^1.2.2" } }, "safe-buffer": { @@ -19589,46 +19830,14 @@ "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - } + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, "snapdragon": { @@ -19972,9 +20181,9 @@ "dev": true }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true }, "supports-color": { @@ -20003,54 +20212,36 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", + "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" }, "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "ajv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", + "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" } }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true } } }, @@ -20087,21 +20278,6 @@ "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", "dev": true }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -20208,9 +20384,9 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" @@ -20383,9 +20559,9 @@ } }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==" + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", + "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" }, "union-value": { "version": "1.0.1", @@ -20616,15 +20792,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -20638,10 +20805,11 @@ } }, "ws": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz", - "integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==", - "dev": true + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} }, "xml-name-validator": { "version": "3.0.0", diff --git a/package.json b/package.json index 5cce58d65..5fac9629f 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": ">=4.0.2" + "typescript": "~4.3.2" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -51,9 +51,9 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^2.31.0", - "@typescript-eslint/parser": "^4.1.0", - "eslint": "^6.8.0", + "@typescript-eslint/eslint-plugin": "^4.26.1", + "@typescript-eslint/parser": "^4.26.1", + "eslint": "^7.28.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", "fs-extra": "^8.1.0", diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 2f0d2e880..1ac86d3f5 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -806,7 +806,7 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr return ( expression.body.statements?.length === 1 && isReturnStatement(expression.body.statements[0]) && - (expression.body.statements[0] as ReturnStatement).expressions !== undefined && + expression.body.statements[0].expressions !== undefined && (expression.flags & FunctionExpressionFlags.Inline) !== 0 ); } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index b1cfb7f46..e2a6eafe6 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -150,7 +150,7 @@ export class LuaPrinter { const sourceRoot = this.options.sourceRoot ? // According to spec, sourceRoot is simply prepended to the source name, so the slash should be included - this.options.sourceRoot.replace(/[\\/]+$/, "") + "/" + `${this.options.sourceRoot.replace(/[\\/]+$/, "")}/` : ""; const rootSourceNode = this.printFile(file); const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode); diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index bec7c2d31..bc6fb5ae9 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -12,7 +12,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic return undefined; } - const searchPath = normalizeSlashes(ts.sys.getCurrentDirectory()); + const searchPath = normalizeSlashes(process.cwd()); return ts.findConfigFile(searchPath, ts.sys.fileExists); } @@ -21,7 +21,7 @@ export function locateConfigFile(commandLine: ParsedCommandLine): ts.Diagnostic } // TODO: Unlike tsc, this resolves `.` to absolute path - const fileOrDirectory = normalizeSlashes(path.resolve(ts.sys.getCurrentDirectory(), project)); + const fileOrDirectory = normalizeSlashes(path.resolve(process.cwd(), project)); if (ts.sys.directoryExists(fileOrDirectory)) { const configFileName = path.posix.join(fileOrDirectory, "tsconfig.json"); if (ts.sys.fileExists(configFileName)) { diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts index 385906f0a..460a77250 100644 --- a/src/lualib/ArrayToObject.ts +++ b/src/lualib/ArrayToObject.ts @@ -1,4 +1,4 @@ -function __TS__ArrayToObject(this: void, array: any[]): object { +function __TS__ArrayToObject(this: void, array: T[]): Record { const object: Record = {}; for (let i = 0; i < array.length; i += 1) { object[i] = array[i]; diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index e5cad0218..816721da7 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,7 +1,18 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -function __TS__Decorate(this: void, decorators: Function[], target: any, key?: any, desc?: any): {} { +type Decorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; +function __TS__Decorate( + this: void, + decorators: Array>, + target: TTarget, + key?: TKey, + desc?: any +): TTarget { let result = target; for (let i = decorators.length; i >= 0; i--) { diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index ed0c28309..4e11f3e54 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -1,3 +1,12 @@ -function __TS__DecorateParam(this: void, paramIndex: number, decorator: Function): {} { - return (target: Function, key?: string) => decorator(target, key, paramIndex); +type ParamDecorator = ( + target: TTarget, + key: TKey, + index: number +) => TTarget; +function __TS__DecorateParam( + this: void, + paramIndex: number, + decorator: ParamDecorator +): Decorator { + return (target: TTarget, key?: TKey) => decorator(target, key, paramIndex); } diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index d44a3b9eb..197ff816b 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -3,7 +3,7 @@ interface ErrorType { new (...args: any[]): Error; } -function __TS__GetErrorStack(constructor: Function): string { +function __TS__GetErrorStack(constructor: () => any): string { let level = 1; while (true) { const info = debug.getinfo(level, "f"); diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index da49d9eb0..bcf521c07 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,4 +1,5 @@ // https://tc39.github.io/ecma262/#sec-object.assign +// eslint-disable-next-line @typescript-eslint/ban-types function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { if (to === undefined) { return to; diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index 68297c420..e9aa599d5 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,5 +1,5 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty(this: void, target: any, key: any, desc: PropertyDescriptor): object { +function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { const luaKey = typeof key === "number" ? key + 1 : key; const value = rawget(target, luaKey); diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 772f7bb58..7b7df1e99 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -WeakMap = class WeakMap { +WeakMap = class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index ebc950a5a..670b3c695 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -WeakSet = class WeakSet { +WeakSet = class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts index a451fe07f..2333f95d4 100644 --- a/src/lualib/declarations/debug.d.ts +++ b/src/lualib/declarations/debug.d.ts @@ -6,7 +6,7 @@ declare function error(...args: any[]): never; declare namespace debug { function traceback(...args: any[]): string; - interface FunctionInfo { + interface FunctionInfo any = () => any> { func: T; name?: string; namewhat: "global" | "local" | "method" | "field" | ""; diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts index 117438817..488586275 100644 --- a/src/lualib/declarations/global.d.ts +++ b/src/lualib/declarations/global.d.ts @@ -1,6 +1,10 @@ /* eslint-disable no-var */ /** @noSelfInFile */ +type AnyTable = Record; +// eslint-disable-next-line +type AnyNotNil = {}; + declare var __TS__sourcemap: Record | undefined; declare var __TS__originalTraceback: | ((this: void, thread?: any, message?: string, level?: number) => string) @@ -13,8 +17,8 @@ declare function tonumber(value: any, base?: number): number | undefined; declare function type( value: any ): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; -declare function setmetatable(table: T, metatable: any): T; -declare function getmetatable(table: T): any; +declare function setmetatable(table: T, metatable: any): T; +declare function getmetatable(table: T): any; declare function rawget(table: T, key: K): T[K]; declare function rawset(table: T, key: K, val: T[K]): void; /** @tupleReturn */ diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts index 63805d283..b802153c8 100644 --- a/src/lualib/declarations/luatable.d.ts +++ b/src/lualib/declarations/luatable.d.ts @@ -1,5 +1,5 @@ /** @LuaTable */ -declare class LuaTable { +declare class LuaTable { public readonly length: number; public set(key: K, value: V | undefined): void; public get(key: K): V | undefined; diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index bd9d052ab..212f30416 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -35,7 +35,7 @@ export type AnnotationsMap = Map; function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void { for (const tag of source.getJsDocTags()) { - const annotation = createAnnotation(tag.name, tag.text ? tag.text.split(" ") : []); + const annotation = createAnnotation(tag.name, tag.text?.map(p => p.text) ?? []); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -62,7 +62,7 @@ export function getNodeAnnotations(node: ts.Node): AnnotationsMap { for (const tag of ts.getJSDocTags(node)) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -80,7 +80,7 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { if (jsDoc) { for (const tag of jsDoc.flatMap(x => x.tags ?? [])) { const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, tag.comment ? tag.comment.split(" ") : []); + const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); if (annotation) { annotationsMap.set(annotation.kind, annotation); } @@ -178,3 +178,15 @@ export function isForRangeType(context: TransformationContext, node: ts.Node): b const type = context.checker.getTypeAtLocation(node); return getTypeAnnotations(type).has(AnnotationKind.ForRange); } + +export function getTagArgsFromComment(tag: ts.JSDocTag): string[] { + if (tag.comment) { + if (typeof tag.comment === "string") { + return tag.comment.split(" "); + } else { + return tag.comment.map(part => part.text); + } + } + + return []; +} diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index d11109427..1edee936c 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -96,7 +96,7 @@ export function getExportedSymbolsFromScope( export function getDependenciesOfSymbol(context: TransformationContext, originalSymbol: ts.Symbol): ts.Symbol[] { return getExportedSymbolsFromScope(context, context.sourceFile).filter(exportSymbol => exportSymbol.declarations - .filter(ts.isExportSpecifier) + ?.filter(ts.isExportSpecifier) .map(context.checker.getExportSpecifierLocalTargetSymbol) .includes(originalSymbol) ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 2991204c2..8b999ae56 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -117,6 +117,6 @@ export function isExtensionValue( ): boolean { return ( symbol.getName() === extensionKindToValueName[extensionKind] && - symbol.declarations.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) + symbol.declarations?.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) === true ); } diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index c072135f4..877196ba4 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -72,7 +72,7 @@ export function hasUnsafeSymbolName( symbol: ts.Symbol, tsOriginal: ts.Identifier ): boolean { - const isAmbient = symbol.declarations && symbol.declarations.some(d => isAmbientNode(d)); + const isAmbient = symbol.declarations?.some(d => isAmbientNode(d)) ?? false; // Catch ambient declarations of identifiers with bad names if (isAmbient && checkName(context, symbol.name, tsOriginal)) { diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 200b65860..72b267e2a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -93,7 +93,7 @@ export function popScope(context: TransformationContext): Scope { } function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { - return symbol?.declarations.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); + return symbol?.declarations?.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); } // Checks for references to local functions which haven't been defined yet, diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 306968010..9fa17711a 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -109,8 +109,10 @@ export function transformArguments( for (const [index, param] of params.entries()) { const signatureParameter = signature.parameters[index]; const paramType = context.checker.getTypeAtLocation(param); - const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); - validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + if (signatureParameter.valueDeclaration !== undefined) { + const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + validateAssignment(context, param, paramType, signatureType, signatureParameter.name); + } } } diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 7ee32adac..d41aefd75 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -75,8 +75,8 @@ export const transformModuleDeclaration: FunctionVisitor = // - declared as a class or function at all (TS requires these to be before module, unless module is empty) const isFirstDeclaration = symbol === undefined || - (!symbol.declarations.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && - ts.getOriginalNode(node) === symbol.declarations.find(ts.isModuleDeclaration)); + (!symbol.declarations?.some(d => ts.isClassLike(d) || ts.isFunctionDeclaration(d)) && + ts.getOriginalNode(node) === symbol.declarations?.find(ts.isModuleDeclaration)); if (isNonModuleMergeable) { // 'local NS = NS or {}' or 'exportTable.NS = exportTable.NS or {}' diff --git a/src/utils.ts b/src/utils.ts index 1244068a4..72e6ee168 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,6 +50,7 @@ export function formatPathToLuaPath(filePath: string): string { type NoInfer = [T][T extends any ? 0 : never]; export function getOrUpdate( + // eslint-disable-next-line @typescript-eslint/ban-types map: Map | (K extends object ? WeakMap : never), key: K, getDefaultValue: () => NoInfer diff --git a/test/setup.ts b/test/setup.ts index 6d92e3332..de78ad24b 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -5,7 +5,7 @@ import * as tstl from "../src"; declare global { // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { - // eslint-disable-next-line @typescript-eslint/generic-type-naming + // eslint-disable-next-line @typescript-eslint/naming-convention interface Matchers { toHaveDiagnostics(expected?: number[]): R; } From 0dd7008374e81cf90465ae1c4dcc6895e0aed585 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 10 Jun 2021 17:53:07 +0200 Subject: [PATCH 348/764] 0.39.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 93b27be93..575c0ee9f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 5fac9629f..3bbbfefe7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.3", + "version": "0.39.4", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9cbc04fa7ee861116c400789b88b03603f44924c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 10:18:30 +0200 Subject: [PATCH 349/764] Fixed typo in language extension and add a step to test procedure to make sure this does not happen again (#1029) --- language-extensions/index.d.ts | 2 +- package.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 761d6a68e..bcd609a27 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -487,7 +487,7 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & +declare type LuaTableSetMethod = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; /** diff --git a/package.json b/package.json index 3bbbfefe7..7e65103ab 100644 --- a/package.json +++ b/package.json @@ -25,12 +25,13 @@ "scripts": { "build": "tsc && npm run build-lualib", "build-lualib": "node build-lualib.js", - "pretest": "npm run lint && npm run build-lualib", + "pretest": "npm run lint && npm run check:language-extensions && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint . --ext .js,.ts", "fix:prettier": "prettier --write .", + "check:language-extensions": "tsc language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, From bd17ed78290bf81903250fe2621cf2ee521fc165 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 12 Jun 2021 10:24:47 +0200 Subject: [PATCH 350/764] 0.39.5 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 575c0ee9f..6211e0e84 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index 7e65103ab..b608ec87f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.4", + "version": "0.39.5", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From ffde3904440711629af06e8ba127de4042fa4f41 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 14:55:07 +0200 Subject: [PATCH 351/764] Implement array.entries() (#1031) * Implement array.entries * Added extra test for indirect use of array.entries() * Added destructuring test for array.entries * Fix prettier --- src/LuaLib.ts | 1 + src/lualib/ArrayEntries.ts | 14 ++++++++++++++ src/transformation/builtins/array.ts | 2 ++ test/unit/builtins/array.spec.ts | 29 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 src/lualib/ArrayEntries.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index dc4501d86..d98b78044 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -3,6 +3,7 @@ import { EmitHost } from "./transpilation"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", + ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", diff --git a/src/lualib/ArrayEntries.ts b/src/lualib/ArrayEntries.ts new file mode 100644 index 000000000..7d12f1347 --- /dev/null +++ b/src/lualib/ArrayEntries.ts @@ -0,0 +1,14 @@ +// https://262.ecma-international.org/10.0/#sec-array.prototype.entries +function __TS__ArrayEntries(this: void, array: T[]): IterableIterator<[number, T]> { + let key = 0; + return { + [Symbol.iterator](): IterableIterator<[number, T]> { + return this; + }, + next(): IteratorResult<[number, T]> { + const result = { done: array[key] === undefined, value: [key, array[key]] as [number, T] }; + key++; + return result; + }, + }; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index a04e0e98b..d8bd4dd3b 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -36,6 +36,8 @@ export function transformArrayPrototypeCall( switch (expressionName) { case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); + case "entries": + return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); case "push": return transformLuaLibFunction(context, LuaLibFeature.ArrayPush, node, caller, ...params); case "reverse": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 770387aea..037ebe2a7 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -594,6 +594,35 @@ describe.each(["reduce", "reduceRight"])("array.%s", reduce => { }); }); +test.each([{ array: [] }, { array: ["a", "b", "c"] }, { array: [{ foo: "foo" }, { bar: "bar" }] }])( + "array.entries (%p)", + ({ array }) => { + util.testFunction` + const array = ${util.formatCode(array)}; + const result = []; + for (const [i, v] of array.entries()) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); + } +); + +test("array.entries indirect use", () => { + util.testFunction` + const entries = ["a", "b", "c"].entries(); + const result = []; + for (const [i, v] of entries) { + result.push([i, v]); + } + return result; + `.expectToMatchJsResult(); +}); + +test("array.entries destructured", () => { + util.testExpression`[...["a", "b", "c"].entries()]`.expectToMatchJsResult(); +}); + const genericChecks = [ "function generic(array: T)", "function generic(array: T)", From bfb89e9e8c4678c9c86028066fc9881d388d69d4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jun 2021 14:55:17 +0200 Subject: [PATCH 352/764] Implemented LuaTableHas and LuaTableDelete (#1030) * Add tests for luatable has * Implement LuaTable has * LuaTableDelete declaration and tests * Implemented LuaTableDelete --- language-extensions/index.d.ts | 40 ++++ src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 8 + src/transformation/visitors/call.ts | 19 +- .../visitors/expression-statement.ts | 11 +- .../visitors/language-extensions/table.ts | 85 ++++++++- .../__snapshots__/table.spec.ts.snap | 63 +++++++ test/unit/language-extensions/table.spec.ts | 175 +++++++++++++++++- 8 files changed, 395 insertions(+), 10 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index bcd609a27..dbd9a1cd8 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -490,6 +490,44 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; +/** + * Calls to functions with this type are translated to `table[key] ~= nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHas = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableHasBrand">; + +/** + * Calls to methods with this type are translated to `table[key] ~= nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableHasMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableHasMethodBrand">; + +/** + * Calls to functions with this type are translated to `table[key] = nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDelete = ((table: TTable, key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & + LuaExtension<"__luaTableDeleteMethodBrand">; + /** * A convenience type for working directly with a Lua table. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -501,6 +539,8 @@ declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; + has: LuaTableHasMethod; + delete: LuaTableDeleteMethod; } /** diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 422a93cac..f25707443 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -158,6 +158,10 @@ export const invalidTableExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); +export const invalidTableDeleteExpression = createErrorDiagnosticFactory( + "Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." +); + export const invalidTableSetExpression = createErrorDiagnosticFactory( "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 8b999ae56..3861cbf57 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -44,8 +44,12 @@ export enum ExtensionKind { LengthOperatorType = "LengthOperatorType", LengthOperatorMethodType = "LengthOperatorMethodType", TableNewType = "TableNewType", + TableDeleteType = "TableDeleteType", + TableDeleteMethodType = "TableDeleteMethodType", TableGetType = "TableGetType", TableGetMethodType = "TableGetMethodType", + TableHasType = "TableHasType", + TableHasMethodType = "TableHasMethodType", TableSetType = "TableSetType", TableSetMethodType = "TableSetMethodType", } @@ -99,8 +103,12 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", [ExtensionKind.TableNewType]: "__luaTableNewBrand", + [ExtensionKind.TableDeleteType]: "__luaTableDeleteBrand", + [ExtensionKind.TableDeleteMethodType]: "__luaTableDeleteMethodBrand", [ExtensionKind.TableGetType]: "__luaTableGetBrand", [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", + [ExtensionKind.TableHasType]: "__luaTableHasBrand", + [ExtensionKind.TableHasMethodType]: "__luaTableHasMethodBrand", [ExtensionKind.TableSetType]: "__luaTableSetBrand", [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", }; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 9fa17711a..709ce1175 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -14,12 +14,16 @@ import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { + isTableDeleteCall, isTableGetCall, + isTableHasCall, isTableSetCall, + transformTableDeleteExpression, transformTableGetExpression, + transformTableHasExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { invalidTableSetExpression } from "../utils/diagnostics"; +import { invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, @@ -242,10 +246,23 @@ export const transformCallExpression: FunctionVisitor = (node return transformOperatorMappingExpression(context, node); } + if (isTableDeleteCall(context, node)) { + context.diagnostics.push(invalidTableDeleteExpression(node)); + return transformToImmediatelyInvokedFunctionExpression( + context, + () => ({ statements: transformTableDeleteExpression(context, node), result: lua.createNilLiteral() }), + node + ); + } + if (isTableGetCall(context, node)) { return transformTableGetExpression(context, node); } + if (isTableHasCall(context, node)) { + return transformTableHasExpression(context, node); + } + if (isTableSetCall(context, node)) { context.diagnostics.push(invalidTableSetExpression(node)); return transformToImmediatelyInvokedFunctionExpression( diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 1932a6dc2..ac020976f 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -2,7 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { isTableSetCall, transformTableSetExpression } from "./language-extensions/table"; +import { + isTableDeleteCall, + isTableSetCall, + transformTableDeleteExpression, + transformTableSetExpression, +} from "./language-extensions/table"; import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -12,6 +17,10 @@ export const transformExpressionStatement: FunctionVisitor extensions.isExtensionType(type, extensionKind)); } +export function isTableDeleteCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableDeleteExtensions) !== undefined; +} + export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; } +export function isTableHasCall(context: TransformationContext, node: ts.CallExpression) { + return getTableExtensionKindForCall(context, node, tableHasExtensions) !== undefined; +} + export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; } @@ -38,6 +59,27 @@ export function isTableNewCall(context: TransformationContext, node: ts.NewExpre return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); } +export function transformTableDeleteExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { + const extensionKind = getTableExtensionKindForCall(context, node, tableDeleteExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] = nil + return lua.createAssignmentStatement( + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + lua.createNilLiteral(), + node + ); +} + export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); assert(extensionKind); @@ -47,9 +89,11 @@ export function transformTableGetExpression(context: TransformationContext, node args.length === 1 && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { + // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } + // arg0[arg1] return lua.createTableIndexExpression( context.transformExpression(args[0]), context.transformExpression(args[1]), @@ -57,6 +101,34 @@ export function transformTableGetExpression(context: TransformationContext, node ); } +export function transformTableHasExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { + const extensionKind = getTableExtensionKindForCall(context, node, tableHasExtensions); + assert(extensionKind); + + const args = node.arguments.slice(); + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] + const tableIndexExpression = lua.createTableIndexExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]) + ); + + // arg0[arg1] ~= nil + return lua.createBinaryExpression( + tableIndexExpression, + lua.createNilLiteral(), + lua.SyntaxKind.InequalityOperator, + node + ); +} + export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); assert(extensionKind); @@ -66,15 +138,14 @@ export function transformTableSetExpression(context: TransformationContext, node args.length === 2 && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { + // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } + // arg0[arg1] = arg2 return lua.createAssignmentStatement( - lua.createTableIndexExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - node - ), - context.transformExpression(args[2]) + lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), + context.transformExpression(args[2]), + node ); } diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 9f6113df6..f8e3a895d 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -1,5 +1,48 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` +"foo = { + (function() + ({}).foo = nil + return nil + end)() +}" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` +"foo = tostring( + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): code 1`] = ` +"foo = (function() + ({}).foo = nil + return nil +end)()" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): code 1`] = ` +"foo( + _G, + (function() + ({}).foo = nil + return nil + end)() +)" +`; + +exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; + exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` "foo = { (function() @@ -62,3 +105,23 @@ exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo: unknown = exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): code 1`] = `"foo(_G, getTable)"`; exports[`LuaTableGet & LuaTableSet extensions invalid use ("declare function foo(getTable: LuaTableGet<{}, string, number>): void; foo(getTable);"): diagnostics 1`] = `"main.ts(3,88): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): code 1`] = `"foo = tableHas(_G, 1, 2)"`; + +exports[`LuaTableHas extension invalid use ("const foo = (tableHas as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): code 1`] = `"foo = {tableHas}"`; + +exports[`LuaTableHas extension invalid use ("const foo = [tableHas];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): code 1`] = `"foo = tostring(tableHas)"`; + +exports[`LuaTableHas extension invalid use ("const foo = \`\${tableHas}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): code 1`] = `"foo = tableHas"`; + +exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): diagnostics 1`] = `"main.ts(3,34): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): code 1`] = `"foo(_G, tableHas)"`; + +exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): diagnostics 1`] = `"main.ts(3,80): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 8d3d0fde1..8d0437fb0 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -1,7 +1,11 @@ import * as path from "path"; import * as util from "../../util"; import * as tstl from "../../../src"; -import { invalidTableExtensionUse, invalidTableSetExpression } from "../../../src/transformation/utils/diagnostics"; +import { + invalidTableDeleteExpression, + invalidTableExtensionUse, + invalidTableSetExpression, +} from "../../../src/transformation/utils/diagnostics"; const tableProjectOptions: tstl.CompilerOptions = { types: [path.resolve(__dirname, "../../../language-extensions")], @@ -84,6 +88,151 @@ describe("LuaTableGet & LuaTableSet extensions", () => { }); }); +describe("LuaTableHas extension", () => { + test("LuaTableHas standalone function", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const hasFoo = tableHas(table, "foo"); + export const hasBaz = tableHas(table, "baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas nested expression", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + export const result = \`table has foo: \${tableHas(table, "foo")}\`; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ result: "table has foo: true" }); + }); + + test("LuaTableHas namespace function", () => { + util.testModule` + declare namespace Table { + export const tableHas: LuaTableHas<{}, string>; + } + const table = { foo: "bar" }; + + export const hasFoo = Table.tableHas(table, "foo"); + export const hasBaz = Table.tableHas(table, "baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithHas { + has: LuaTableHasMethod; + set: LuaTableSetMethod; + } + const table = {} as TableWithHas; + table.set("foo", 42); + + export const hasFoo = table.has("foo"); + export const hasBaz = table.has("baz"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ hasFoo: true, hasBaz: false }); + }); + + test("LuaTableHas as statement", () => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + const table = { foo: "bar" }; + + let count = 0; + function getKey() { + count++; + return "foo"; + } + + // The result is not captured, but the expression will be evaulated + tableHas(table, getKey()); + + export const numCalls = count; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ numCalls: 1 }); + }); + + test.each([ + "const foo: unknown = tableHas;", + "const foo = `${tableHas}`;", + "declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);", + "const foo = (tableHas as any)(1, 2);", + "const foo = [tableHas];", + ])("invalid use (%p)", statement => { + util.testModule` + declare const tableHas: LuaTableHas<{}, string>; + ${statement} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + }); +}); + +describe("LuaTableDelete extension", () => { + test("LuaTableDelete standalone function", () => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + + export const table = { foo: "bar", baz: "baz" }; + tableDelete(table, "foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableDelete namespace function", () => { + util.testModule` + declare namespace Table { + export const tableDelete: LuaTableDelete<{}, string>; + } + + export const table = { foo: "bar", baz: "baz" }; + Table.tableDelete(table, "foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { baz: "baz" } }); + }); + + test("LuaTableHasMethod method", () => { + util.testModule` + interface TableWithDelete { + delete: LuaTableDeleteMethod; + set: LuaTableSetMethod; + } + export const table = {} as TableWithDelete; + table.set("foo", 42); + table.set("bar", 12); + table.delete("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual({ table: { bar: 12 } }); + }); + + test.each([ + 'const foo = tableDelete({}, "foo");', + 'const foo = `${tableDelete({}, "foo")}`;', + 'declare function foo(arg: any): void; foo(tableDelete({}, "foo"));', + 'const foo = [tableDelete({}, "foo")];', + ])("LuaTableDelete invalid use as expression (%p)", expression => { + util.testModule` + declare const tableDelete: LuaTableDelete<{}, string>; + ${expression} + ` + .setOptions(tableProjectOptions) + .expectDiagnosticsToMatchSnapshot([invalidTableDeleteExpression.code]); + }); +}); + describe("LuaTable extension interface", () => { test("untyped table", () => { util.testFunction` @@ -128,6 +277,30 @@ describe("LuaTable extension interface", () => { .expectToEqual(1); }); + test("table has", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set(3, "foo"); + return [tbl.has(1), tbl.has(3)]; + ` + .setOptions(tableProjectOptions) + .expectToEqual([false, true]); + }); + + test("table delete", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + tbl.set("bar", 3); + tbl.set("baz", 5); + tbl.delete("bar"); + tbl.delete("foo"); + return tbl; + ` + .setOptions(tableProjectOptions) + .expectToEqual({ baz: 5 }); + }); + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( "table immediate access (%p)", statement => { From 5b673302e661795aebe3ecc846fdb5c5d3d92a8f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 13 Jun 2021 22:48:48 +0200 Subject: [PATCH 353/764] Fixed language extensions LuaTable keys required to be tables (#1034) * Fixed another mistake in language extensions where luatable keys were accidentally required to be tables * update snapshot names --- language-extensions/index.d.ts | 2 +- .../__snapshots__/table.spec.ts.snap | 46 +++++++++++++++++++ test/unit/language-extensions/table.spec.ts | 23 ++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index dbd9a1cd8..30eb70009 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -535,7 +535,7 @@ declare type LuaTableDeleteMethod = ((key: TKey) => bool * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare interface LuaTable { +declare interface LuaTable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index f8e3a895d..5deed95c3 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -1,5 +1,51 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("null"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'null' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("number | undefined"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'number | undefined' does not satisfy the constraint 'AnyNotNil'. + Type 'undefined' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("string | null"): diagnostics 1`] = ` +"main.ts(1,38): error TS2344: Type 'string | null' does not satisfy the constraint 'AnyNotNil'. + Type 'null' is not assignable to type 'AnyNotNil'." +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("undefined"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'undefined' does not satisfy the constraint 'AnyNotNil'."`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): code 1`] = ` +"local ____exports = {} +____exports.__result = {} +return ____exports" +`; + +exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; + exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` "foo = { (function() diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 8d0437fb0..e6d485a04 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -254,6 +254,29 @@ describe("LuaTable extension interface", () => { .expectToEqual(3); }); + // Test to catch issue from https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1033 + test("typed table in type declaration", () => { + util.testFunction` + function fill(tbl: LuaTable) { + tbl.set("foo", 3); + return tbl; + } + return fill(new LuaTable()).get("foo"); + ` + .setOptions(tableProjectOptions) + .expectToEqual(3); + }); + + test.each([["null"], ["undefined"], ["number | undefined"], ["string | null"], ["unknown"]])( + "LuaTable in strict mode does not accept key type that could be nil (%p)", + keyType => { + util.testExpression`new LuaTable<${keyType}, unknown>()` + .setOptions({ ...tableProjectOptions, strict: true }) + .expectToHaveDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + } + ); + test("object keyed table", () => { util.testFunction` interface Key { keyStr: string } From 57fbef1a90d7ef5cee7e9e314549acaeafa61d3d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 13 Jun 2021 22:54:45 +0200 Subject: [PATCH 354/764] 0.39.6 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6211e0e84..5b210730c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "license": "MIT", "dependencies": { "resolve": "^1.15.1", diff --git a/package.json b/package.json index b608ec87f..0fc954467 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.5", + "version": "0.39.6", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5abb60ba6dbb619862c619781c672038a8e3f153 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 14 Jun 2021 18:50:30 +0200 Subject: [PATCH 355/764] Remove deprecated annotations (#1032) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Removed luaIterator, vararg, luaTable and forRange annotations * Fixed change missed in conflict resolve * Removed unused import * Remove unused diagnostics * Fixed deprecation tests working because tbl.new instead of get/set * Prettier 💅 --- src/lualib/declarations/luatable.d.ts | 6 - src/transformation/utils/diagnostics.ts | 30 --- src/transformation/visitors/access.ts | 52 ++--- .../visitors/binary-expression/assignments.ts | 8 +- .../visitors/binary-expression/index.ts | 7 - src/transformation/visitors/call.ts | 16 +- src/transformation/visitors/class/index.ts | 15 +- src/transformation/visitors/class/new.ts | 16 +- .../visitors/expression-statement.ts | 15 +- src/transformation/visitors/identifier.ts | 12 +- src/transformation/visitors/loops/for-of.ts | 124 +---------- src/transformation/visitors/lua-table.ts | 158 -------------- src/transformation/visitors/spread.ts | 5 +- .../__snapshots__/deprecated.spec.ts.snap | 66 +++++- .../__snapshots__/forRange.spec.ts.snap | 89 -------- .../__snapshots__/luaIterator.spec.ts.snap | 15 -- .../__snapshots__/luaTable.spec.ts.snap | 197 ------------------ test/unit/annotations/deprecated.spec.ts | 67 +++++- test/unit/annotations/forRange.spec.ts | 98 --------- test/unit/annotations/luaIterator.spec.ts | 191 ----------------- test/unit/annotations/luaTable.spec.ts | 151 -------------- test/unit/annotations/vararg.spec.ts | 50 ----- test/unit/loops.spec.ts | 48 ----- 23 files changed, 178 insertions(+), 1258 deletions(-) delete mode 100644 src/lualib/declarations/luatable.d.ts delete mode 100644 src/transformation/visitors/lua-table.ts delete mode 100644 test/unit/annotations/__snapshots__/forRange.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap delete mode 100644 test/unit/annotations/__snapshots__/luaTable.spec.ts.snap delete mode 100644 test/unit/annotations/forRange.spec.ts delete mode 100644 test/unit/annotations/luaIterator.spec.ts delete mode 100644 test/unit/annotations/luaTable.spec.ts delete mode 100644 test/unit/annotations/vararg.spec.ts diff --git a/src/lualib/declarations/luatable.d.ts b/src/lualib/declarations/luatable.d.ts deleted file mode 100644 index b802153c8..000000000 --- a/src/lualib/declarations/luatable.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** @LuaTable */ -declare class LuaTable { - public readonly length: number; - public set(key: K, value: V | undefined): void; - public get(key: K): V | undefined; -} diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index f25707443..ef699c07c 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -58,10 +58,6 @@ export const annotationInvalidArgumentCount = createErrorDiagnosticFactory( (kind: AnnotationKind, got: number, expected: number) => `'@${kind}' expects ${expected} arguments, but got ${got}.` ); -export const invalidForRangeCall = createErrorDiagnosticFactory( - (message: string) => `Invalid @forRange call: ${message}.` -); - export const invalidRangeUse = createErrorDiagnosticFactory("$range can only be used in a for...of loop."); export const invalidVarargUse = createErrorDiagnosticFactory( @@ -72,32 +68,6 @@ export const invalidRangeControlVariable = createErrorDiagnosticFactory( "For loop using $range must declare a single control variable." ); -export const luaTableMustBeAmbient = createErrorDiagnosticFactory( - "Classes with the '@luaTable' annotation must be ambient." -); - -export const luaTableCannotBeExtended = createErrorDiagnosticFactory( - "Cannot extend classes with the '@luaTable' annotation." -); - -export const luaTableInvalidInstanceOf = createErrorDiagnosticFactory( - "The instanceof operator cannot be used with a '@luaTable' class." -); - -export const luaTableCannotBeAccessedDynamically = createErrorDiagnosticFactory( - "@luaTable cannot be accessed dynamically." -); - -export const luaTableForbiddenUsage = createErrorDiagnosticFactory( - (description: string) => `Invalid @luaTable usage: ${description}.` -); - -export const luaIteratorForbiddenUsage = createErrorDiagnosticFactory( - "Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. " + - "You must use a destructuring statement to catch results from a lua iterator with " + - "the '@tupleReturn' annotation." -); - export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFactory( "LuaIterable with a LuaMultiReturn return value type must be destructured." ); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index d33c5c5c6..a41c4462f 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,13 +3,12 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; +import { annotationRemoved, invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { returnsMultiType } from "./language-extensions/multi"; -import { transformLuaTablePropertyAccessExpression, validateLuaTableElementAccessExpression } from "./lua-table"; export function transformElementAccessArgument( context: TransformationContext, @@ -27,8 +26,6 @@ export function transformElementAccessArgument( } export const transformElementAccessExpression: FunctionVisitor = (node, context) => { - validateLuaTableElementAccessExpression(context, node); - const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return constEnumValue; @@ -59,53 +56,50 @@ export const transformElementAccessExpression: FunctionVisitor = ( - expression, - context -) => { - if (ts.isOptionalChain(expression)) { - context.diagnostics.push(optionalChainingNotSupported(expression)); +export const transformPropertyAccessExpression: FunctionVisitor = (node, context) => { + const property = node.name.text; + const type = context.checker.getTypeAtLocation(node.expression); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } - const constEnumValue = tryGetConstEnumValue(context, expression); - if (constEnumValue) { - return constEnumValue; + if (ts.isOptionalChain(node)) { + context.diagnostics.push(optionalChainingNotSupported(node)); } - const luaTableResult = transformLuaTablePropertyAccessExpression(context, expression); - if (luaTableResult) { - return luaTableResult; + const constEnumValue = tryGetConstEnumValue(context, node); + if (constEnumValue) { + return constEnumValue; } - const builtinResult = transformBuiltinPropertyAccessExpression(context, expression); + const builtinResult = transformBuiltinPropertyAccessExpression(context, node); if (builtinResult) { return builtinResult; } - if (ts.isCallExpression(expression.expression) && returnsMultiType(context, expression.expression)) { - context.diagnostics.push(invalidMultiReturnAccess(expression)); + if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) { + context.diagnostics.push(invalidMultiReturnAccess(node)); } - const property = expression.name.text; - const type = context.checker.getTypeAtLocation(expression.expression); - - const annotations = getTypeAnnotations(type); // Do not output path for member only enums if (annotations.has(AnnotationKind.CompileMembersOnly)) { - if (ts.isPropertyAccessExpression(expression.expression)) { + if (ts.isPropertyAccessExpression(node.expression)) { // in case of ...x.enum.y transform to ...x.y return lua.createTableIndexExpression( - context.transformExpression(expression.expression.expression), + context.transformExpression(node.expression.expression), lua.createStringLiteral(property), - expression + node ); } else { - return lua.createIdentifier(property, expression); + return lua.createIdentifier(property, node); } } - const callPath = context.transformExpression(expression.expression); - return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), expression); + const callPath = context.transformExpression(node.expression); + return lua.createTableIndexExpression(callPath, lua.createStringLiteral(property), node); }; export const transformQualifiedName: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 0b1b7fe70..c8a1cd907 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -9,7 +9,6 @@ import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { transformElementAccessArgument } from "../access"; -import { transformLuaTablePropertyAccessInAssignment } from "../lua-table"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; import { popScope, pushScope, ScopeType } from "../../utils/scope"; @@ -23,9 +22,7 @@ export function transformAssignmentLeftHandSideExpression( node: ts.Expression ): lua.AssignmentLeftHandSideExpression { const symbol = context.checker.getSymbolAtLocation(node); - const left = ts.isPropertyAccessExpression(node) - ? transformLuaTablePropertyAccessInAssignment(context, node) ?? context.transformExpression(node) - : context.transformExpression(node); + const left = context.transformExpression(node); return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) ? createExportedIdentifier(context, left) @@ -140,9 +137,6 @@ export function transformAssignmentExpression( const objExpression = context.transformExpression(expression.left.expression); let indexExpression: lua.Expression; if (ts.isPropertyAccessExpression(expression.left)) { - // Called only for validation - transformLuaTablePropertyAccessInAssignment(context, expression.left); - // Property access indexExpression = lua.createStringLiteral(expression.left.name.text); } else { diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 5ed023618..0b4533a4a 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -1,8 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { luaTableInvalidInstanceOf } from "../../utils/diagnostics"; import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; @@ -108,11 +106,6 @@ export const transformBinaryExpression: FunctionVisitor = ( const lhs = context.transformExpression(node.left); const rhs = context.transformExpression(node.right); const rhsType = context.checker.getTypeAtLocation(node.right); - const annotations = getTypeAnnotations(rhsType); - - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableInvalidInstanceOf(node)); - } if (isStandardLibraryType(context, rhsType, "ObjectConstructor")) { return transformLuaLibFunction(context, LuaLibFeature.InstanceOfObject, node, lhs); diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 709ce1175..f7a1b004e 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { AnnotationKind, getTypeAnnotations, isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -10,7 +10,6 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; -import { transformLuaTableCallExpression } from "./lua-table"; import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { @@ -23,7 +22,7 @@ import { transformTableHasExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; +import { annotationRemoved, invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, @@ -223,11 +222,6 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre } export const transformCallExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableCallExpression(context, node); - if (luaTableResult) { - return luaTableResult; - } - const isTupleReturn = isTupleReturnCall(context, node); const isTupleReturnForward = node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); @@ -273,6 +267,12 @@ export const transformCallExpression: FunctionVisitor = (node } if (ts.isPropertyAccessExpression(node.expression)) { + const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const annotations = getTypeAnnotations(ownerType); + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); + } + const result = transformPropertyCall(context, node as PropertyCallExpression); return wrapResult ? wrapInTable(result) : result; } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 4c0e05eee..98d74f84a 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationRemoved, luaTableCannotBeExtended, luaTableMustBeAmbient } from "../../utils/diagnostics"; +import { annotationRemoved } from "../../utils/diagnostics"; import { createDefaultExportIdentifier, createExportedIdentifier, @@ -13,7 +13,6 @@ import { import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; -import { isAmbientNode } from "../../utils/typescript"; import { transformIdentifier } from "../identifier"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; @@ -97,18 +96,6 @@ function transformClassLikeDeclaration( checkForLuaLibType(context, extendedType); } - // You cannot extend LuaTable classes - if (extendedType) { - const annotations = getTypeAnnotations(extendedType); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeExtended(extendedTypeNode!)); - } - } - - if (annotations.has(AnnotationKind.LuaTable) && !isAmbientNode(classDeclaration)) { - context.diagnostics.push(luaTableMustBeAmbient(classDeclaration)); - } - // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 1a9c5e8aa..721cc26e5 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,11 +2,10 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; -import { transformLuaTableNewExpression } from "../lua-table"; const builtinErrorTypeNames = new Set([ "Error", @@ -49,9 +48,12 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type } export const transformNewExpression: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableNewExpression(context, node); - if (luaTableResult) { - return luaTableResult; + const type = context.checker.getTypeAtLocation(node); + + const annotations = getTypeAnnotations(type); + + if (annotations.has(AnnotationKind.LuaTable)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } if (isTableNewCall(context, node)) { @@ -64,12 +66,8 @@ export const transformNewExpression: FunctionVisitor = (node, ? transformArguments(context, node.arguments, signature) : [lua.createBooleanLiteral(true)]; - const type = context.checker.getTypeAtLocation(node); - checkForLuaLibType(context, type); - const annotations = getTypeAnnotations(type); - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index ac020976f..228307f25 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -8,21 +8,17 @@ import { transformTableDeleteExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { transformLuaTableExpressionStatement } from "./lua-table"; import { transformUnaryExpressionStatement } from "./unary-expression"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - const luaTableResult = transformLuaTableExpressionStatement(context, node); - if (luaTableResult) { - return luaTableResult; - } + const expression = node.expression; - if (ts.isCallExpression(node.expression) && isTableDeleteCall(context, node.expression)) { - return transformTableDeleteExpression(context, node.expression); + if (ts.isCallExpression(expression) && isTableDeleteCall(context, expression)) { + return transformTableDeleteExpression(context, expression); } - if (ts.isCallExpression(node.expression) && isTableSetCall(context, node.expression)) { - return transformTableSetExpression(context, node.expression); + if (ts.isCallExpression(expression) && isTableSetCall(context, expression)) { + return transformTableSetExpression(context, expression); } const unaryExpressionResult = transformUnaryExpressionStatement(context, node); @@ -35,7 +31,6 @@ export const transformExpressionStatement: FunctionVisitor !isNumberType(context, context.checker.getTypeAtLocation(a)))) { - context.diagnostics.push(invalidForRangeCall(statement.expression, "arguments must be numbers")); - } - - const controlVariable = getControlVariable() ?? lua.createAnonymousIdentifier(); - function getControlVariable(): lua.Identifier | undefined { - if (!ts.isVariableDeclarationList(statement.initializer)) { - context.diagnostics.push( - invalidForRangeCall(statement.initializer, "loop must declare it's own control variable") - ); - return; - } - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (!ts.isIdentifier(binding)) { - context.diagnostics.push(invalidForRangeCall(statement.initializer, "destructuring cannot be used")); - return; - } - - if (!isNumberType(context, context.checker.getTypeAtLocation(binding))) { - context.diagnostics.push( - invalidForRangeCall(statement.expression, "function must return Iterable") - ); - } - - return transformIdentifier(context, binding); - } - - const [start = lua.createNumericLiteral(0), limit = lua.createNumericLiteral(0), step] = transformArguments( - context, - callArguments, - context.checker.getResolvedSignature(statement.expression) - ); - - return lua.createForStatement(block, controlVariable, start, limit, step, statement); -} - -function transformForOfLuaIteratorStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - const luaIterator = context.transformExpression(statement.expression); - const type = context.checker.getTypeAtLocation(statement.expression); - const tupleReturn = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); - let identifiers: lua.Identifier[] = []; - - if (tupleReturn) { - // LuaIterator + TupleReturn - - if (ts.isVariableDeclarationList(statement.initializer)) { - // Variables declared in for loop - // for ${initializer} in ${iterable} do - - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (ts.isArrayBindingPattern(binding)) { - identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(binding)); - } - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____value0 in ${iterable} do - // ${initializer} = ____value0 - - identifiers = statement.initializer.elements.map((_, i) => lua.createIdentifier(`____value${i}`)); - if (identifiers.length > 0) { - block.statements.unshift( - lua.createAssignmentStatement( - statement.initializer.elements.map(e => - cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) - ), - identifiers - ) - ); - } - } else { - context.diagnostics.push(luaIteratorForbiddenUsage(statement.initializer)); - } - } else { - // LuaIterator (no TupleReturn) - - identifiers.push(transformForInitializer(context, statement.initializer, block)); - } - - if (identifiers.length === 0) { - identifiers.push(lua.createAnonymousIdentifier()); - } - - return lua.createForInStatement(block, identifiers, [luaIterator], statement); -} +import { transformForInitializer, transformLoopBody } from "./utils"; function transformForOfArrayStatement( context: TransformationContext, @@ -156,11 +44,11 @@ export const transformForOfStatement: FunctionVisitor = (node if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { return transformRangeStatement(context, node, body); } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { - return transformForRangeStatement(context, node, body); + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.ForRange)); } else if (isIterableExpression(context, node.expression)) { return transformForOfIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { - return transformForOfLuaIteratorStatement(context, node, body); + context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { return transformForOfArrayStatement(context, node, body); } else { diff --git a/src/transformation/visitors/lua-table.ts b/src/transformation/visitors/lua-table.ts deleted file mode 100644 index 300837c1e..000000000 --- a/src/transformation/visitors/lua-table.ts +++ /dev/null @@ -1,158 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../LuaAST"; -import { TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { luaTableCannotBeAccessedDynamically, luaTableForbiddenUsage, unsupportedProperty } from "../utils/diagnostics"; -import { transformArguments } from "./call"; - -const parseLuaTableExpression = (context: TransformationContext, node: ts.PropertyAccessExpression) => - [context.transformExpression(node.expression), node.name.text] as const; - -function validateLuaTableCall( - context: TransformationContext, - node: ts.Node, - methodName: string, - callArguments: ts.NodeArray -): void { - for (const argument of callArguments) { - if (ts.isSpreadElement(argument)) { - context.diagnostics.push(luaTableForbiddenUsage(argument, "Arguments cannot be spread")); - return; - } - } - - switch (methodName) { - case "get": - if (callArguments.length !== 1) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 1 arguments, but got ${callArguments.length}`) - ); - } - break; - - case "set": - if (callArguments.length !== 2) { - context.diagnostics.push( - luaTableForbiddenUsage(node, `Expected 2 arguments, but got ${callArguments.length}`) - ); - } - break; - } -} - -export function transformLuaTableExpressionStatement( - context: TransformationContext, - node: ts.ExpressionStatement -): lua.Statement | undefined { - const expression = ts.isExpressionStatement(node) ? node.expression : node; - - if (!ts.isCallExpression(expression) || !ts.isPropertyAccessExpression(expression.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(expression.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, expression.expression); - validateLuaTableCall(context, expression, methodName, expression.arguments); - const signature = context.checker.getResolvedSignature(expression); - const params = transformArguments(context, expression.arguments, signature); - - switch (methodName) { - case "get": - return lua.createVariableDeclarationStatement( - lua.createAnonymousIdentifier(expression), - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - expression - ); - case "set": - return lua.createAssignmentStatement( - lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), expression), - [params[1] ?? lua.createNilLiteral()], - expression - ); - default: - context.diagnostics.push(unsupportedProperty(expression.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTableCallExpression( - context: TransformationContext, - node: ts.CallExpression -): lua.Expression | undefined { - if (!ts.isPropertyAccessExpression(node.expression)) return; - - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); - const annotations = getTypeAnnotations(ownerType); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, methodName] = parseLuaTableExpression(context, node.expression); - validateLuaTableCall(context, node, methodName, node.arguments); - const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - - switch (methodName) { - case "get": - return lua.createTableIndexExpression(luaTable, params[0] ?? lua.createNilLiteral(), node); - default: - context.diagnostics.push(unsupportedProperty(node.expression.name, "LuaTable", methodName)); - } -} - -export function transformLuaTablePropertyAccessExpression( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - return lua.createUnaryExpression(luaTable, lua.SyntaxKind.LengthOperator, node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function transformLuaTablePropertyAccessInAssignment( - context: TransformationContext, - node: ts.PropertyAccessExpression -): lua.AssignmentLeftHandSideExpression | undefined { - if (!ts.isPropertyAccessExpression(node)) return; - - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - const [luaTable, propertyName] = parseLuaTableExpression(context, node); - if (propertyName === "length") { - context.diagnostics.push(luaTableForbiddenUsage(node, "A LuaTable object's length cannot be re-assigned")); - return lua.createTableIndexExpression(luaTable, lua.createStringLiteral(propertyName), node); - } - - context.diagnostics.push(unsupportedProperty(node.name, "LuaTable", propertyName)); -} - -export function validateLuaTableElementAccessExpression( - context: TransformationContext, - node: ts.ElementAccessExpression -): void { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node.expression)); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(luaTableCannotBeAccessedDynamically(node)); - } -} - -export function transformLuaTableNewExpression( - context: TransformationContext, - node: ts.NewExpression -): lua.Expression | undefined { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); - if (!annotations.has(AnnotationKind.LuaTable)) return; - - if (node.arguments && node.arguments.length > 0) { - context.diagnostics.push( - luaTableForbiddenUsage(node, "No parameters are allowed when constructing a LuaTable object") - ); - } - - return lua.createTableExpression(); -} diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index ca5e2fb85..d9da3ce44 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -13,7 +13,7 @@ import { } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; import { returnsMultiType } from "./language-extensions/multi"; -import { annotationDeprecated } from "../utils/diagnostics"; +import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { @@ -60,8 +60,7 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: export const transformSpreadElement: FunctionVisitor = (node, context) => { if (ts.isIdentifier(node.expression)) { if (isVarargType(context, node.expression)) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.Vararg)); - return lua.createDotsLiteral(node); + context.diagnostics.push(annotationRemoved(node, AnnotationKind.Vararg)); } const symbol = context.checker.getSymbolAtLocation(node.expression); if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 750b0596f..d612bc478 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -1,5 +1,42 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`LuaTable deprecation warning property access set: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:set(\\"foo\\", 0) +end +return ____exports" +`; + +exports[`LuaTable deprecation warning property access set: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning constructor: code 1`] = ` +"require(\\"lualib_bundle\\"); +____table = __TS__New(Table)" +`; + +exports[`LuaTable removed warning constructor: diagnostics 1`] = `"main.ts(11,15): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access get: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl:get(\\"foo\\") +end +return ____exports" +`; + +exports[`LuaTable removed warning property access get: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + +exports[`LuaTable removed warning property access length: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + return tbl.length +end +return ____exports" +`; + +exports[`LuaTable removed warning property access length: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; + exports[`extension removed: code 1`] = ` "require(\\"lualib_bundle\\"); B = __TS__Class() @@ -18,12 +55,29 @@ exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@exte exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; -exports[`forRange deprecation: code 1`] = ` -"for i = 1, 10 do -end" +exports[`forRange removed: code 1`] = `""`; + +exports[`forRange removed: diagnostics 1`] = `"main.ts(4,25): error TSTL: '@forRange' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; + +exports[`luaiterator removed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local arr = {\\"a\\", \\"b\\", \\"c\\"} + local function luaIter(self) + local i = 0 + return function() return arr[(function() + local ____tmp = i + i = ____tmp + 1 + return ____tmp + end)() + 1] end + end + local result = \\"\\" + return result +end +return ____exports" `; -exports[`forRange deprecation: diagnostics 1`] = `"main.ts(4,25): warning TSTL: '@forRange' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; +exports[`luaiterator removed: diagnostics 1`] = `"main.ts(10,23): error TSTL: '@luaIterator' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luaiterator for more information."`; exports[`phantom removed: code 1`] = ` "A = A or ({}) @@ -44,7 +98,7 @@ __TS__ClassExtends(ClassB, ClassA)" exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; -exports[`vararg deprecation: code 1`] = ` +exports[`vararg removed: code 1`] = ` "function foo(self, ...) end function vararg(self, ...) @@ -52,4 +106,4 @@ function vararg(self, ...) end" `; -exports[`vararg deprecation: diagnostics 1`] = `"main.ts(6,17): warning TSTL: '@vararg' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; +exports[`vararg removed: diagnostics 1`] = `"main.ts(6,17): error TSTL: '@vararg' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap b/test/unit/annotations/__snapshots__/forRange.spec.ts.snap deleted file mode 100644 index e752d0782..000000000 --- a/test/unit/annotations/__snapshots__/forRange.spec.ts.snap +++ /dev/null @@ -1,89 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`invalid usage argument count ([]): code 1`] = ` -"for i = 0, 0 do -end" -`; - -exports[`invalid usage argument count ([]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 0."`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): code 1`] = ` -"for i = 1, 2, 3 do -end" -`; - -exports[`invalid usage argument count ([1, 2, 3, 4]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 4."`; - -exports[`invalid usage argument count ([1]): code 1`] = ` -"for i = 1, 0 do -end" -`; - -exports[`invalid usage argument count ([1]): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: Expected 2-3 arguments, but got 1."`; - -exports[`invalid usage argument types: code 1`] = ` -"for i = \\"foo\\", 2 do -end" -`; - -exports[`invalid usage argument types: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: arguments must be numbers."`; - -exports[`invalid usage non-ambient declaration: code 1`] = ` -"function luaRange(self) -end" -`; - -exports[`invalid usage non-ambient declaration: diagnostics 1`] = `"main.ts(3,22): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage non-declared loop variable: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage non-declared loop variable: diagnostics 1`] = `"main.ts(7,18): error TSTL: Invalid @forRange call: loop must declare it's own control variable."`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): code 1`] = ` -"call = nil -call(_G, luaRange)" -`; - -exports[`invalid usage reference ("const call = undefined as any; call(luaRange);"): diagnostics 1`] = `"main.ts(6,49): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): code 1`] = `"range = luaRange(_G, 1, 10)"`; - -exports[`invalid usage reference ("const range = luaRange(1, 10);"): diagnostics 1`] = `"main.ts(6,27): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): code 1`] = ` -"for ____, i in ipairs( - { - table.unpack( - luaRange(_G, 1, 10) - ) - } -) do -end" -`; - -exports[`invalid usage reference ("for (const i of [...luaRange(1, 10)]) {}"): diagnostics 1`] = `"main.ts(6,33): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): code 1`] = `"array = {0, luaRange, 1}"`; - -exports[`invalid usage reference ("let array = [0, luaRange, 1];"): diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): code 1`] = `"luaRange(nil, 0, 0, 0)"`; - -exports[`invalid usage reference ("luaRange.call(null, 0, 0, 0);"): diagnostics 1`] = `"main.ts(6,13): error TSTL: Invalid @forRange call: can be used only as an iterable in a for...of loop."`; - -exports[`invalid usage return type: code 1`] = ` -"for i = 1, 10 do -end" -`; - -exports[`invalid usage return type: diagnostics 1`] = `"main.ts(6,29): error TSTL: Invalid @forRange call: function must return Iterable."`; - -exports[`invalid usage variable destructuring: code 1`] = ` -"for ____ = 1, 10, 2 do -end" -`; - -exports[`invalid usage variable destructuring: diagnostics 1`] = `"main.ts(6,18): error TSTL: Invalid @forRange call: destructuring cannot be used."`; diff --git a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap b/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap deleted file mode 100644 index 24761ca3a..000000000 --- a/test/unit/annotations/__snapshots__/luaIterator.spec.ts.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`forof lua iterator tuple-return single existing variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single existing variable: diagnostics 1`] = `"main.ts(9,14): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; - -exports[`forof lua iterator tuple-return single variable: code 1`] = ` -"for ____ in luaIter(_G) do -end" -`; - -exports[`forof lua iterator tuple-return single variable: diagnostics 1`] = `"main.ts(8,18): error TSTL: Unsupported use of lua iterator with '@tupleReturn' annotation in for...of statement. You must use a destructuring statement to catch results from a lua iterator with the '@tupleReturn' annotation."`; diff --git a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap b/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap deleted file mode 100644 index fae2b1f20..000000000 --- a/test/unit/annotations/__snapshots__/luaTable.spec.ts.snap +++ /dev/null @@ -1,197 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Ext = __TS__Class() -Ext.name = \\"Ext\\" -__TS__ClassExtends(Ext, Table)" -`; - -exports[`Cannot extend LuaTable class ("class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,19): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Ext = __TS__Class() - Ext.name = \\"Ext\\" - __TS__ClassExtends(Ext, Table) - return Ext -end)()" -`; - -exports[`Cannot extend LuaTable class ("const c = class Ext extends Table {}"): diagnostics 1`] = `"main.ts(11,29): error TSTL: Cannot extend classes with the '@luaTable' annotation."`; - -exports[`Cannot isolate LuaTable method ("get"): code 1`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): code 2`] = `"property = tbl.get"`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("get"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.get is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): code 1`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): code 2`] = `"property = tbl.set"`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 1`] = `"main.ts(11,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot isolate LuaTable method ("set"): diagnostics 2`] = `"main.ts(13,21): error TSTL: LuaTable.set is unsupported."`; - -exports[`Cannot set LuaTable length: code 1`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: code 2`] = `"tbl.length = 2"`; - -exports[`Cannot set LuaTable length: diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot set LuaTable length: diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: A LuaTable object's length cannot be re-assigned."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 1`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): code 2`] = `"tbl.get(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"get\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 1`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): code 2`] = `"local ____ = tbl.length"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"length\\"]"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 1`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): code 2`] = `"tbl.set(tbl, \\"field\\")"`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use ElementAccessExpression on a LuaTable ("tbl[\\"set\\"](\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: @luaTable cannot be accessed dynamically."`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): code 1`] = ` -"require(\\"lualib_bundle\\"); -__TS__InstanceOf(tbl, Table)" -`; - -exports[`Cannot use instanceof on a LuaTable class ("tbl instanceof Table"): diagnostics 1`] = `"main.ts(11,1): error TSTL: The instanceof operator cannot be used with a '@luaTable' class."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 1`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): code 2`] = `"local ____ = tbl[nil]"`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 1`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): code 2`] = `"local ____ = tbl.field"`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.get(\\"field\\", \\"field2\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 1 arguments, but got 2."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 1`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): code 2`] = `"tbl[nil] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set()"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 0."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 1`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): code 2`] = `"tbl[table.unpack({\\"field\\", 0})] = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 1`] = `"main.ts(11,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(...([\\"field\\", 0] as const))"): diagnostics 2`] = `"main.ts(13,9): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 1`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): code 2`] = `"tbl.field = nil"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\")"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 1."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 1`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): code 2`] = `"tbl.field = table.unpack({0})"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 1`] = `"main.ts(11,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", ...([0] as const))"): diagnostics 2`] = `"main.ts(13,18): error TSTL: Invalid @luaTable usage: Arguments cannot be spread."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 1`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): code 2`] = `"tbl.field = 0"`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 1`] = `"main.ts(11,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`Forbidden LuaTable use ("tbl.set(\\"field\\", 0, 1)"): diagnostics 2`] = `"main.ts(13,1): error TSTL: Invalid @luaTable usage: Expected 2 arguments, but got 3."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -Table = __TS__Class() -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -c = (function() - local Table = __TS__Class() - Table.name = \\"Table\\" - function Table.prototype.____constructor(self) - end - return Table -end)()" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ const c = class Table {}"): diagnostics 1`] = `"main.ts(1,28): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); -local ____exports = {} -____exports.Table = __TS__Class() -local Table = ____exports.Table -Table.name = \\"Table\\" -function Table.prototype.____constructor(self) -end -return ____exports" -`; - -exports[`LuaTable classes must be ambient ("/** @luaTable */ export class Table {}"): diagnostics 1`] = `"main.ts(1,18): error TSTL: Classes with the '@luaTable' annotation must be ambient."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 1`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: code 2`] = `"exp = tbl:set(\\"value\\", 5)"`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 1`] = `"main.ts(11,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTable set() cannot be used in a LuaTable call expression: diagnostics 2`] = `"main.ts(13,17): error TSTL: LuaTable.set is unsupported."`; - -exports[`LuaTables cannot be constructed with arguments: code 1`] = `"____table = {}"`; - -exports[`LuaTables cannot be constructed with arguments: diagnostics 1`] = `"main.ts(11,15): error TSTL: Invalid @luaTable usage: No parameters are allowed when constructing a LuaTable object."`; - -exports[`LuaTables cannot have other members: code 1`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 2`] = `"tbl:other()"`; - -exports[`LuaTables cannot have other members: code 3`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: code 4`] = `"x = tbl:other()"`; - -exports[`LuaTables cannot have other members: diagnostics 1`] = `"main.ts(11,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 2`] = `"main.ts(13,5): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 3`] = `"main.ts(11,13): error TSTL: LuaTable.other is unsupported."`; - -exports[`LuaTables cannot have other members: diagnostics 4`] = `"main.ts(13,13): error TSTL: LuaTable.other is unsupported."`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 9c81b2176..2f0edb105 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -1,4 +1,4 @@ -import { annotationDeprecated, annotationRemoved } from "../../../src/transformation/utils/diagnostics"; +import { annotationRemoved } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test.each(["extension", "metaExtension"])("extension removed", extensionType => { @@ -26,15 +26,15 @@ test("pureAbstract removed", () => { `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("forRange deprecation", () => { +test("forRange removed", () => { util.testModule` /** @forRange */ declare function forRange(start: number, limit: number, step?: number): number[]; for (const i of forRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); -test("vararg deprecation", () => { +test("vararg removed", () => { util.testModule` /** @vararg */ type VarArg = T & { readonly __brand: unique symbol }; @@ -42,5 +42,62 @@ test("vararg deprecation", () => { function vararg(...args: VarArg) { foo(...args); } - `.expectDiagnosticsToMatchSnapshot([annotationDeprecated.code]); + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("luaiterator removed", () => { + util.testFunction` + const arr = ["a", "b", "c"]; + /** @luaIterator */ + interface Iter extends Iterable {} + function luaIter(): Iter { + let i = 0; + return (() => arr[i++]) as any; + } + let result = ""; + for (let e of luaIter()) { result += e; } + return result; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +const tableLibClass = ` +/** @luaTable */ +declare class Table { + length: number; + constructor(notAllowed?: any); + set(key?: K, value?: V, notAllowed?: any): void; + get(key?: K, notAllowed?: any): V; + other(): void; +} +declare let tbl: Table; +`; + +test("LuaTable removed warning constructor", () => { + util.testModule("const table = new Table();") + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access length", () => { + util.testFunction` + return tbl.length; + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable removed warning property access get", () => { + util.testFunction` + return tbl.get("foo"); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("LuaTable deprecation warning property access set", () => { + util.testFunction` + return tbl.set("foo", 0); + ` + .setTsHeader(tableLibClass) + .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); diff --git a/test/unit/annotations/forRange.spec.ts b/test/unit/annotations/forRange.spec.ts deleted file mode 100644 index 35dc285b1..000000000 --- a/test/unit/annotations/forRange.spec.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { annotationDeprecated, invalidForRangeCall } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const createForRangeDeclaration = (args = "i: number, j: number, k?: number", returns = "number[]") => ` - /** @forRange */ - declare function luaRange(${args}): ${returns}; -`; - -test.each([ - { args: [1, 10], results: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { args: [1, 10, 2], results: [1, 3, 5, 7, 9] }, - { args: [10, 1, -1], results: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] }, - { args: [10, 1, -2], results: [10, 8, 6, 4, 2] }, -])("usage in for...of loop", ({ args, results }) => { - util.testModule` - ${createForRangeDeclaration()} - export const results: number[] = []; - - for (const i of luaRange(${args})) { - results.push(i); - } - ` - .setReturnExport("results") - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToEqual(results); -}); - -describe("invalid usage", () => { - test("non-ambient declaration", () => { - util.testModule` - /** @forRange */ - function luaRange() {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each<[number[]]>([[[]], [[1]], [[1, 2, 3, 4]]])("argument count (%p)", args => { - util.testModule` - ${createForRangeDeclaration("...args: number[]")} - for (const i of luaRange(${args})) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("non-declared loop variable", () => { - util.testModule` - ${createForRangeDeclaration()} - let i: number; - for (i of luaRange(1, 10, 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("argument types", () => { - util.testModule` - ${createForRangeDeclaration("i: string, j: number")} - for (const i of luaRange("foo", 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("variable destructuring", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "number[][]")} - for (const [i] of luaRange(1, 10, 2)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test("return type", () => { - util.testModule` - ${createForRangeDeclaration(undefined, "string[]")} - for (const i of luaRange(1, 10)) {} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); - - test.each([ - "const range = luaRange(1, 10);", - "luaRange.call(null, 0, 0, 0);", - "let array = [0, luaRange, 1];", - "const call = undefined as any; call(luaRange);", - "for (const i of [...luaRange(1, 10)]) {}", - ])("reference (%p)", statement => { - util.testModule` - ${createForRangeDeclaration()} - ${statement} - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectDiagnosticsToMatchSnapshot([invalidForRangeCall.code]); - }); -}); diff --git a/test/unit/annotations/luaIterator.spec.ts b/test/unit/annotations/luaIterator.spec.ts deleted file mode 100644 index b1efc62ca..000000000 --- a/test/unit/annotations/luaIterator.spec.ts +++ /dev/null @@ -1,191 +0,0 @@ -import * as util from "../../util"; -import { luaIteratorForbiddenUsage } from "../../../src/transformation/utils/diagnostics"; - -test("forof lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof array lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Array {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof lua iterator with existing variable", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - let e: string; - for (e of luaIter()) { result += e; } - return result; - `.expectToEqual("abc"); -}); - -test("forof lua iterator destructuring", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator destructuring with existing variables", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i] && [i.toString(), arr[i++]]) as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - for (let [a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return with existing variables", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - let result = ""; - let a: string; - let b: string; - for ([a, b] of luaIter()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); - -test("forof lua iterator tuple-return single variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - for (let x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof lua iterator tuple-return single existing variable", () => { - util.testModule` - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - declare function luaIter(): Iter; - let x: [string, string]; - for (x of luaIter()) {} - `.expectDiagnosticsToMatchSnapshot([luaIteratorForbiddenUsage.code]); -}); - -test("forof forwarded lua iterator", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - function iter() { return arr[i++]; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let a of forward()) { result += a; } - return result; - `.expectToEqual("abc"); -}); - -test("forof forwarded lua iterator with tupleReturn", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let i = 0; - /** @tupleReturn */ - function iter() { return arr[i] && [i.toString(), arr[i++]] || []; } - return iter as any; - } - function forward() { - const iter = luaIter(); - return iter; - } - let result = ""; - for (let [a, b] of forward()) { result += a + b; } - return result; - `.expectToEqual("0a1b2c"); -}); diff --git a/test/unit/annotations/luaTable.spec.ts b/test/unit/annotations/luaTable.spec.ts deleted file mode 100644 index 0f9cbbf36..000000000 --- a/test/unit/annotations/luaTable.spec.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { - luaTableCannotBeAccessedDynamically, - luaTableCannotBeExtended, - luaTableForbiddenUsage, - luaTableMustBeAmbient, - unsupportedProperty, - luaTableInvalidInstanceOf, -} from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const tableLibClass = ` -/** @luaTable */ -declare class Table { - length: number; - constructor(notAllowed?: any); - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} -declare let tbl: Table; -`; - -const tableLibInterface = ` -/** @luaTable */ -declare interface Table { - length: number; - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} - -/** @luaTable */ -declare const Table: new (notAllowed?: any) => Table; -declare let tbl: Table; -`; - -test.each([tableLibClass])("LuaTables cannot be constructed with arguments", tableLib => { - util.testModule("const table = new Table(true);") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); -}); - -test.each([tableLibClass, tableLibInterface])( - "LuaTable set() cannot be used in a LuaTable call expression", - tableLib => { - util.testModule('const exp = tbl.set("value", 5)') - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); - } -); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule("tbl.other()").setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass, tableLibInterface])("LuaTables cannot have other members", tableLib => { - util.testModule("let x = tbl.other()") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([unsupportedProperty.code]); -}); - -test.each([tableLibClass])("LuaTable new", tableLib => { - expect(util.testFunction("tbl = new Table();").setTsHeader(tableLib).getMainLuaCodeChunk()).toContain("tbl = {}"); -}); - -test.each([tableLibClass])("LuaTable length", tableLib => { - util.testFunction` - tbl = new Table(); - return tbl.length; - ` - .setTsHeader(tableLib) - .expectToEqual(0); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot set LuaTable length", tableLib => { - util.testModule("tbl.length = 2;") - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); -}); - -test.each([tableLibClass, tableLibInterface])("Forbidden LuaTable use", tableLib => { - test.each([ - "tbl.get()", - 'tbl.get("field", "field2")', - "tbl.set()", - 'tbl.set("field")', - 'tbl.set("field", 0, 1)', - 'tbl.set(...(["field", 0] as const))', - 'tbl.set("field", ...([0] as const))', - ])("Forbidden LuaTable use (%p)", invalidCode => { - util.testModule(invalidCode) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableForbiddenUsage.code]); - }); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["class Ext extends Table {}", "const c = class Ext extends Table {}"])( - "Cannot extend LuaTable class (%p)", - code => { - util.testModule(code) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableCannotBeExtended.code]); - } - ); -}); - -test.each([ - "/** @luaTable */ class Table {}", - "/** @luaTable */ export class Table {}", - "/** @luaTable */ const c = class Table {}", -])("LuaTable classes must be ambient (%p)", code => { - util.testModule(code).expectDiagnosticsToMatchSnapshot([luaTableMustBeAmbient.code]); -}); - -test.each([tableLibClass])("Cannot extend LuaTable class", tableLib => { - test.each(["tbl instanceof Table"])("Cannot use instanceof on a LuaTable class (%p)", code => { - util.testModule(code).setTsHeader(tableLib).expectDiagnosticsToMatchSnapshot([luaTableInvalidInstanceOf.code]); - }); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot use ElementAccessExpression on a LuaTable", tableLib => { - test.each(['tbl["get"]("field")', 'tbl["set"]("field")', 'tbl["length"]'])( - "Cannot use ElementAccessExpression on a LuaTable (%p)", - code => { - util.testModule(code) - .setTsHeader(tableLib) - .expectDiagnosticsToMatchSnapshot([luaTableCannotBeAccessedDynamically.code]); - } - ); -}); - -test.each([tableLibClass, tableLibInterface])("Cannot isolate LuaTable methods", tableLib => { - test.each(["set", "get"])("Cannot isolate LuaTable method (%p)", propertyName => { - util.testModule(`${tableLib} let property = tbl.${propertyName}`).expectDiagnosticsToMatchSnapshot([ - unsupportedProperty.code, - ]); - }); -}); - -test.each([tableLibClass])("LuaTable functional tests", tableLib => { - test.each<[string, any]>([ - ['const t = new Table(); t.set("field", "value"); return t.get("field");', "value"], - ['const t = new Table(); t.set("field", 0); return t.get("field");', 0], - ["const t = new Table(); t.set(1, true); return t.length", 1], - ["const t = new Table(); t.set(t.length + 1, true); t.set(t.length + 1, true); return t.length", 2], - ['const k = "k"; const t = { data: new Table() }; t.data.set(k, 3); return t.data.get(k);', 3], - ])("LuaTable test (%p)", (code, expectedReturnValue) => { - util.testFunction(code).setTsHeader(tableLib).expectToEqual(expectedReturnValue); - }); -}); diff --git a/test/unit/annotations/vararg.spec.ts b/test/unit/annotations/vararg.spec.ts deleted file mode 100644 index 1b80e73db..000000000 --- a/test/unit/annotations/vararg.spec.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const varargDeclaration = ` - /** @vararg */ - type LuaVararg = A & { __luaVararg?: never }; -`; - -test("@vararg", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join(""); - } - function bar(a: unknown, ...b: LuaVararg) { - return foo(a, ...b); - } - return bar("A", "B", "C", "D"); - ` - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("b = ")) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("@vararg array access", () => { - util.testFunction` - ${varargDeclaration} - function foo(a: unknown, ...b: LuaVararg) { - const c = [...b]; - return c.join("") + b[0]; - } - return foo("A", "B", "C", "D"); - ` - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("@vararg global", () => { - util.testModule` - ${varargDeclaration} - declare const arg: LuaVararg; - export const result = [...arg].join(""); - ` - .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) - .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) - .ignoreDiagnostics([annotationDeprecated.code]) - .expectToEqual({ result: "ABCD" }); -}); diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 987f53628..a3d4db239 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -465,54 +465,6 @@ describe("for...of empty destructuring", () => { return i; `.expectToMatchJsResult(); }); - - test("luaIterator", () => { - const luaResult = util.testFunction` - const arr = [["a"], ["b"], ["c"]]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let it = 0; - return (() => arr[it++]) as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `.getLuaExecutionResult(); - // Can't use expectToMatchJsResult because above is not valid TS/JS - expect(luaResult).toBe(3); - }); - - test("luaIterator+tupleReturn", () => { - const luaResult = util.testFunction` - const arr = [["a", "b"], ["c", "d"], ["e", "f"]]; - /** - * @luaIterator - * @tupleReturn - */ - interface Iter extends Iterable<[string, string]> {} - function luaIter(): Iter { - let it = 0; - /** @tupleReturn */ - function iter() { - const e = arr[it++]; - if (e) { - return e; - } - } - return iter as any; - } - let i = 0; - for (${destructuringPrefix}[] of luaIter()) { - ++i; - } - return i; - `.getLuaExecutionResult(); - // Can't use expectToMatchJsResult because above is not valid TS/JS - expect(luaResult).toBe(3); - }); }; describe("declaration", () => declareTests("const ")); From 691c9cc7bde8dfd89f44e61cf0777e4bdfbd3fcd Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 14 Jun 2021 18:51:26 +0200 Subject: [PATCH 356/764] Module resolution from node_modules (#1011) * Create test project with node_modules * testProject test util * Fix typos in module resolution test * Base case module resolution * Replace requires in source maps too * Fixed incorrect path behavior * More tests * add module resolution with sourceDir node_modules * Get all module-resolution testcases to work * Restrict resolver to only lua files * All tests working * Added more in-project dependency checks to sourceDir test * Fixed problem with lua sibling files * Also resolve JSON modules * Add debug to resolution test to try to figure out why CI is failing * fix test runner path preloading * Revert "Add debug to resolution test to try to figure out why CI is failing" This reverts commit 7b8bd80e2bc961037384863bf836b0c982b3372d. * Changed resolution failure from error to warning * move json.lua from dist to src in benchmark * Use commit version instead of master to compile benchmark scripts * Added module resolution test project with lua sources * Add library compilation mode * renamed compilemode to buildmode * clean up resolve * Fix tests * Removed old project test runner * PR comments * Remove file casing test * Resolution + library mode combined test * remove out path logic from printer * Fixed bundle entry point require not being resolved correctly * Add header to bundle * Made couldNotResolveRequire an error instead of warning * updated couldnotResolveRequire snapshot --- .eslintignore | 1 + .github/workflows/ci.yml | 8 +- .vscode/launch.json | 17 ++ benchmark/{dist => src}/json.lua | 0 package-lock.json | 46 ++- package.json | 1 + src/CompilerOptions.ts | 6 + src/LuaPrinter.ts | 24 +- src/cli/parse.ts | 8 +- src/transformation/utils/diagnostics.ts | 4 - src/transformation/visitors/modules/import.ts | 34 +-- src/transpilation/bundle.ts | 42 ++- src/transpilation/diagnostics.ts | 15 +- src/transpilation/index.ts | 2 +- src/transpilation/output-collector.ts | 3 +- src/transpilation/resolve.ts | 231 ++++++++++++++ src/transpilation/transpile.ts | 9 +- src/transpilation/transpiler.ts | 71 ++++- src/transpilation/utils.ts | 1 + test/cli/parse.spec.ts | 6 + test/translation/transformation.spec.ts | 3 +- .../__snapshots__/directories.spec.ts.snap | 8 - .../__snapshots__/project.spec.ts.snap | 12 +- test/transpile/bundle.spec.ts | 11 +- test/transpile/directories.spec.ts | 1 - .../baseurl/src/lib/nested/file.ts | 3 - .../transpile/directories/baseurl/src/main.ts | 3 - test/transpile/module-resolution.spec.ts | 282 ++++++++++++++++++ .../project-with-dependency-chain/main.ts | 4 + .../node_modules/dependency1/index.d.ts | 3 + .../node_modules/dependency1/index.lua | 7 + .../node_modules/dependency1/otherfile.lua | 5 + .../node_modules/dependency2/index.lua | 5 + .../node_modules/dependency3/index.lua | 3 + .../tsconfig.json | 10 + .../lua_sources/otherluaFile.d.ts | 2 + .../lua_sources/otherluaFile.lua | 3 + .../project-with-lua-sources/luafile.d.ts | 2 + .../project-with-lua-sources/luafile.lua | 3 + .../project-with-lua-sources/main.ts | 5 + .../project-with-lua-sources/tsconfig.json | 9 + .../lua-global-without-decls.d.ts | 4 + .../lua-module-without-decls.d.ts | 9 + .../project-with-node-modules/main.ts | 39 +++ .../lua-global-with-decls/baz.d.ts | 1 + .../lua-global-with-decls/baz.lua | 3 + .../lua-global-with-decls/index.d.ts | 3 + .../lua-global-with-decls/index.lua | 6 + .../lua-global-without-decls/baz.lua | 3 + .../lua-global-without-decls/index.lua | 6 + .../lua-module-with-decls/baz.d.ts | 2 + .../lua-module-with-decls/baz.lua | 5 + .../lua-module-with-decls/index.d.ts | 3 + .../lua-module-with-decls/index.lua | 8 + .../lua-module-with-dependency/index.d.ts | 2 + .../lua-module-with-dependency/index.lua | 7 + .../lua-module-without-decls/baz.lua | 5 + .../lua-module-without-decls/index.lua | 8 + .../project-with-node-modules/tsconfig.json | 12 + .../node_modules/dependency1/index.d.ts | 2 + .../node_modules/dependency1/index.lua | 5 + .../node_modules/dependency2/index.lua | 5 + .../node_modules/dependency3/index.lua | 3 + .../project-with-sourceDir/src/main.ts | 9 + .../src/subdir/otherfile.ts | 5 + .../src/subdir/otherfile2.ts | 3 + .../src/subdir/subdirofsubdir/nestedfile.ts | 9 + .../project-with-sourceDir/tsconfig.json | 10 + .../dependency1-ts/d1otherfile.ts | 3 + .../dependency1-ts/index.ts | 5 + .../dependency1-ts/tsconfig.json | 9 + .../dependency2-ts/d2otherfile.ts | 3 + .../dependency2-ts/main.ts | 5 + .../dependency2-ts/tsconfig.json | 9 + .../project-with-tstl-library-modules/main.ts | 8 + .../tsconfig.json | 1 + test/transpile/project.spec.ts | 15 +- test/transpile/run.ts | 10 - test/unit/bundle.spec.ts | 10 + test/unit/file.spec.ts | 14 + .../functions/noImplicitSelfOption.spec.ts | 6 +- .../__snapshots__/resolution.spec.ts.snap | 4 +- test/unit/modules/modules.spec.ts | 3 +- test/unit/modules/resolution.spec.ts | 5 +- test/unit/printer/sourcemaps.spec.ts | 24 +- test/util.ts | 75 +++-- 86 files changed, 1102 insertions(+), 197 deletions(-) create mode 100644 .vscode/launch.json rename benchmark/{dist => src}/json.lua (100%) create mode 100644 src/transpilation/resolve.ts delete mode 100644 test/transpile/directories/baseurl/src/lib/nested/file.ts delete mode 100644 test/transpile/directories/baseurl/src/main.ts create mode 100644 test/transpile/module-resolution.spec.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/main.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua create mode 100644 test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/luafile.lua create mode 100644 test/transpile/module-resolution/project-with-lua-sources/main.ts create mode 100644 test/transpile/module-resolution/project-with-lua-sources/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/main.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua create mode 100644 test/transpile/module-resolution/project-with-node-modules/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/main.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts create mode 100644 test/transpile/module-resolution/project-with-sourceDir/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 707cb8140..492195f96 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ /test/cli/errors /test/cli/watch /test/transpile/directories +/test/transpile/module-resolution/*/node_modules /test/transpile/outFile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 13df095ec..968cd9b87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,14 +76,14 @@ jobs: run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark # Run master benchmark first and output to commit benchmark data - name: Build benchmark Lua 5.3 master - run: node ../dist/tstl.js -p tsconfig.53.json + run: node ../../commit/dist/tstl.js -p tsconfig.53.json working-directory: master/benchmark - name: Run benchmark Lua 5.3 master id: benchmark-lua-master run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json working-directory: master/benchmark/dist - name: Build benchmark LuaJIT master - run: node ../dist/tstl.js -p tsconfig.jit.json + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json working-directory: master/benchmark - name: Run benchmark LuaJIT master id: benchmark-jit-master @@ -91,14 +91,14 @@ jobs: working-directory: master/benchmark/dist # Run commit benchmark and compare with master - name: Build benchmark Lua 5.3 commit - run: node ../dist/tstl.js -p tsconfig.53.json + run: node ../../commit/dist/tstl.js -p tsconfig.53.json working-directory: commit/benchmark - name: Run benchmark Lua 5.3 commit id: benchmark-lua-commit run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json working-directory: commit/benchmark/dist - name: Build benchmark LuaJIT commit - run: node ../dist/tstl.js -p tsconfig.jit.json + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json working-directory: commit/benchmark - name: Run benchmark LuaJIT commit id: benchmark-jit-commit diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..a50a68074 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug current jest test", + "type": "node", + "request": "launch", + "env": { "CI": "true" }, + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/jest", + "args": ["--runInBand", "--no-cache", "--runTestsByPath", "${relativeFile}"], + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + } + ] +} diff --git a/benchmark/dist/json.lua b/benchmark/src/json.lua similarity index 100% rename from benchmark/dist/json.lua rename to benchmark/src/json.lua diff --git a/package-lock.json b/package-lock.json index 5b210730c..43137cbae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.39.6", "license": "MIT", "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", "typescript": "~4.3.2" @@ -3461,6 +3462,18 @@ "once": "^1.4.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -4684,8 +4697,7 @@ "node_modules/graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "node_modules/growly": { "version": "1.3.0", @@ -10585,11 +10597,6 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, "engines": { "node": ">=0.10.0" } @@ -10823,6 +10830,14 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, + "node_modules/tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", + "engines": { + "node": ">=6" + } + }, "node_modules/terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", @@ -14393,6 +14408,15 @@ "once": "^1.4.0" } }, + "enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", @@ -15355,8 +15379,7 @@ "graceful-fs": { "version": "4.2.6", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", - "dev": true + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" }, "growly": { "version": "1.3.0", @@ -20245,6 +20268,11 @@ } } }, + "tapable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", + "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + }, "terminal-link": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", diff --git a/package.json b/package.json index 0fc954467..fc3604e49 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "node": ">=12.13.0" }, "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", "typescript": "~4.3.2" diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 439b29652..e06adc1f3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -25,6 +25,7 @@ export interface LuaPluginImport { } export type CompilerOptions = OmitIndexSignature & { + buildMode?: BuildMode; noImplicitSelf?: boolean; noHeader?: boolean; luaBundle?: string; @@ -53,6 +54,11 @@ export enum LuaTarget { LuaJIT = "JIT", } +export enum BuildMode { + Default = "default", + Library = "library", +} + export const isBundleEnabled = (options: CompilerOptions) => options.luaBundle !== undefined && options.luaBundleEntry !== undefined; diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index e2a6eafe6..390b62977 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,4 +1,3 @@ -import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; @@ -6,7 +5,7 @@ import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, normalizeSlashes, trimExtension } from "./utils"; +import { intersperse, trimExtension } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -25,6 +24,8 @@ const escapeStringMap: Record = { export const escapeString = (value: string) => `"${value.replace(escapeStringRegExp, char => escapeStringMap[char])}"`; +export const tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + /** * Checks that a name is valid for use in lua function declaration syntax: * @@ -124,22 +125,7 @@ export class LuaPrinter { constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { this.options = program.getCompilerOptions(); - - if (this.options.outDir) { - const relativeFileName = path.relative(program.getCommonSourceDirectory(), fileName); - if (this.options.sourceRoot) { - // When sourceRoot is specified, just use relative path inside rootDir - this.sourceFile = relativeFileName; - } else { - // Calculate relative path from rootDir to outDir - const outputPath = path.resolve(this.options.outDir, relativeFileName); - this.sourceFile = path.relative(path.dirname(outputPath), fileName); - } - // We want forward slashes, even in windows - this.sourceFile = normalizeSlashes(this.sourceFile); - } else { - this.sourceFile = path.basename(fileName); // File will be in same dir as source - } + this.sourceFile = fileName; } public print(file: lua.File): PrintResult { @@ -201,7 +187,7 @@ export class LuaPrinter { let header = file.trivia; if (!this.options.noHeader) { - header += "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n"; + header += tstlHeader; } const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index fff0ef0d0..d29bf4e83 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; +import { BuildMode, CompilerOptions, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; import * as cliDiagnostics from "./diagnostics"; export interface ParsedCommandLine extends ts.ParsedCommandLine { @@ -24,6 +24,12 @@ interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; export const optionDeclarations: CommandLineOption[] = [ + { + name: "buildMode", + description: "'default' or 'library'. Compiling as library will not resolve external dependencies.", + type: "enum", + choices: Object.values(BuildMode), + }, { name: "luaBundle", description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index ef699c07c..fcc37b6f0 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -94,10 +94,6 @@ export const invalidAmbientIdentifierName = createErrorDiagnosticFactory( (text: string) => `Invalid ambient identifier name '${text}'. Ambient identifiers must be valid lua identifiers.` ); -export const unresolvableRequirePath = createErrorDiagnosticFactory( - (path: string) => `Cannot create require path. Module '${path}' does not exist within --rootDir.` -); - export const unsupportedVarDeclaration = createErrorDiagnosticFactory( "`var` declarations are not supported. Use `let` or `const` instead." ); diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index d36bb0509..d8daba8c9 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { formatPathToLuaPath } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; @@ -10,36 +9,13 @@ import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; import { transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; -import { unresolvableRequirePath } from "../../utils/diagnostics"; -const getAbsoluteImportPath = (relativePath: string, directoryPath: string, options: ts.CompilerOptions): string => - !relativePath.startsWith(".") && options.baseUrl - ? path.resolve(options.baseUrl, relativePath) - : path.resolve(directoryPath, relativePath); - -function getImportPath(context: TransformationContext, relativePath: string, node: ts.Node): string { - const { options, sourceFile } = context; - const { fileName } = sourceFile; - const rootDir = options.rootDir ? path.resolve(options.rootDir) : path.resolve("."); - - const absoluteImportPath = path.format( - path.parse(getAbsoluteImportPath(relativePath, path.dirname(fileName), options)) - ); - const absoluteRootDirPath = path.format(path.parse(rootDir)); - if (absoluteImportPath.includes(absoluteRootDirPath)) { - return formatPathToLuaPath(absoluteImportPath.replace(absoluteRootDirPath, "").slice(1)); - } else { - context.diagnostics.push(unresolvableRequirePath(node, relativePath)); - return relativePath; - } -} - -function shouldResolveModulePath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { +function isNoResolutionPath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { const moduleOwnerSymbol = context.checker.getSymbolAtLocation(moduleSpecifier); - if (!moduleOwnerSymbol) return true; + if (!moduleOwnerSymbol) return false; const annotations = getSymbolAnnotations(moduleOwnerSymbol); - return !annotations.has(AnnotationKind.NoResolution); + return annotations.has(AnnotationKind.NoResolution); } export function createModuleRequire( @@ -49,8 +25,8 @@ export function createModuleRequire( ): lua.CallExpression { const params: lua.Expression[] = []; if (ts.isStringLiteral(moduleSpecifier)) { - const modulePath = shouldResolveModulePath(context, moduleSpecifier) - ? getImportPath(context, moduleSpecifier.text.replace(/"/g, ""), moduleSpecifier) + const modulePath = isNoResolutionPath(context, moduleSpecifier) + ? `@NoResolution:${moduleSpecifier.text}` : moduleSpecifier.text; params.push(lua.createStringLiteral(modulePath)); diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index c696c6900..31d58b27b 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -2,13 +2,14 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; -import { escapeString } from "../LuaPrinter"; +import { escapeString, tstlHeader } from "../LuaPrinter"; import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; -import { EmitFile, EmitHost, ProcessedFile } from "./utils"; +import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; +import { EmitFile, ProcessedFile } from "./utils"; -const createModulePath = (baseDir: string, pathToResolve: string) => - escapeString(formatPathToLuaPath(trimExtension(path.relative(baseDir, pathToResolve)))); +const createModulePath = (pathToResolve: string, program: ts.Program) => + escapeString(formatPathToLuaPath(trimExtension(getEmitPathRelativeToOutDir(pathToResolve, program)))); // Override `require` to read from ____modules table. const requireOverride = ` @@ -32,42 +33,37 @@ local function require(file) end `; -export function getBundleResult( - program: ts.Program, - emitHost: EmitHost, - files: ProcessedFile[] -): [ts.Diagnostic[], EmitFile] { +export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile] { const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; const bundleFile = cast(options.luaBundle, isNonNull); const entryModule = cast(options.luaBundleEntry, isNonNull); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; - const projectRootDir = options.configFilePath - ? path.dirname(options.configFilePath) - : emitHost.getCurrentDirectory(); - // Resolve project settings relative to project file. - const resolvedEntryModule = path.resolve(projectRootDir, entryModule); - const outputPath = normalizeSlashes(path.resolve(projectRootDir, bundleFile)); + const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); + const outputPath = normalizeSlashes(path.resolve(getEmitOutDir(program), bundleFile)); - if (!files.some(f => f.fileName === resolvedEntryModule)) { + if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); - return [diagnostics, { outputPath, code: "" }]; } // For each file: [""] = function() end, - const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(outDir, f.fileName))); + const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program))); // Create ____modules table containing all entries from moduleTableEntries const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(outDir, resolvedEntryModule)})\n`; + const entryPoint = `return require(${createModulePath(entryModule, program)})\n`; + + const sourceChunks = [requireOverride, moduleTable, entryPoint]; + + if (!options.noHeader) { + sourceChunks.unshift(tstlHeader); + } - const bundleNode = joinSourceChunks([requireOverride, moduleTable, entryPoint]); + const bundleNode = joinSourceChunks(sourceChunks); const { code, map } = bundleNode.toStringWithSourceMap(); return [ @@ -83,7 +79,7 @@ export function getBundleResult( function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { const tableEntryHead = `[${modulePath}] = function() `; - const tableEntryTail = "end,\n"; + const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); } diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index d0e609677..bfae6b140 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -1,8 +1,19 @@ import * as ts from "typescript"; import { createSerialDiagnosticFactory } from "../utils"; -const createDiagnosticFactory = (getMessage: (...args: TArgs) => string) => - createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args) })); +const createDiagnosticFactory = ( + getMessage: (...args: TArgs) => string, + category: ts.DiagnosticCategory = ts.DiagnosticCategory.Error +) => createSerialDiagnosticFactory((...args: TArgs) => ({ messageText: getMessage(...args), category })); + +export const couldNotResolveRequire = createDiagnosticFactory( + (requirePath: string, containingFile: string) => + `Could not resolve require path '${requirePath}' in file ${containingFile}.` +); + +export const couldNotReadDependency = createDiagnosticFactory( + (dependency: string) => `Could not read content of resolved dependency ${dependency}.` +); export const toLoadItShouldBeTranspiled = createDiagnosticFactory( (kind: string, transform: string) => diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 608b42818..59e83233a 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -45,7 +45,7 @@ const libCache: { [key: string]: ts.SourceFile } = {}; /** @internal */ export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { const compilerHost: ts.CompilerHost = { - fileExists: () => true, + fileExists: fileName => fileName in input || ts.sys.fileExists(fileName), getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", getDefaultLibFileName: ts.getDefaultLibFileName, diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts index d18137c5a..866c1f79a 100644 --- a/src/transpilation/output-collector.ts +++ b/src/transpilation/output-collector.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import { intersection, union } from "../utils"; export interface TranspiledFile { + outPath: string; sourceFiles: ts.SourceFile[]; lua?: string; luaSourceMap?: string; @@ -18,7 +19,7 @@ export function createEmitOutputCollector() { const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); if (!file) { - file = { sourceFiles: [...sourceFiles] }; + file = { outPath: fileName, sourceFiles: [...sourceFiles] }; files.push(file); } else { file.sourceFiles = union(file.sourceFiles, sourceFiles); diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts new file mode 100644 index 000000000..3eca25e2e --- /dev/null +++ b/src/transpilation/resolve.ts @@ -0,0 +1,231 @@ +import * as path from "path"; +import * as resolve from "enhanced-resolve"; +import * as ts from "typescript"; +import * as fs from "fs"; +import { EmitHost, ProcessedFile } from "./utils"; +import { SourceNode } from "source-map"; +import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./transpiler"; +import { formatPathToLuaPath, trimExtension } from "../utils"; +import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; +import { BuildMode } from "../CompilerOptions"; + +const resolver = resolve.ResolverFactory.createResolver({ + extensions: [".lua"], + enforceExtension: true, // Resolved file must be a lua file + fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, + useSyncFileSystemCalls: true, +}); + +interface ResolutionResult { + resolvedFiles: ProcessedFile[]; + diagnostics: ts.Diagnostic[]; +} + +export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { + const outFiles: ProcessedFile[] = [...files]; + const diagnostics: ts.Diagnostic[] = []; + + // Resolve dependencies for all processed files + for (const file of files) { + const resolutionResult = resolveFileDependencies(file, program, emitHost); + outFiles.push(...resolutionResult.resolvedFiles); + diagnostics.push(...resolutionResult.diagnostics); + } + + return { resolvedFiles: outFiles, diagnostics }; +} + +function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { + const dependencies: ProcessedFile[] = []; + const diagnostics: ts.Diagnostic[] = []; + + for (const required of findRequiredPaths(file.code)) { + // Do no resolve lualib + if (required === "lualib_bundle") { + continue; + } + + // Do not resolve noResolution paths + if (required.startsWith("@NoResolution:")) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + continue; + } + + // Try to resolve the import starting from the directory `file` is in + const fileDir = path.dirname(file.fileName); + const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); + if (resolvedDependency) { + // Figure out resolved require path and dependency output path + const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); + + if (shouldRewriteRequires(resolvedDependency, program)) { + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); + } + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + if (shouldIncludeDependency(resolvedDependency, program)) { + // If dependency resolved successfully, read its content + const dependencyContent = emitHost.readFile(resolvedDependency); + if (dependencyContent === undefined) { + diagnostics.push(couldNotReadDependency(resolvedDependency)); + continue; + } + + const dependency = { + fileName: resolvedDependency, + code: dependencyContent, + }; + const nestedDependencies = resolveFileDependencies(dependency, program, emitHost); + dependencies.push(dependency, ...nestedDependencies.resolvedFiles); + diagnostics.push(...nestedDependencies.diagnostics); + } + } else { + // Could not resolve dependency, add a diagnostic and make some fallback path + diagnostics.push(couldNotResolveRequire(required, path.relative(getProjectRoot(program), file.fileName))); + + const fallbackRequire = fallbackResolve(required, getSourceDir(program), fileDir); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); + } + } + return { resolvedFiles: dependencies, diagnostics }; +} + +function resolveDependency( + fileDirectory: string, + dependency: string, + program: ts.Program, + emitHost: EmitHost +): string | undefined { + // Check if file is a file in the project + const resolvedPath = path.join(fileDirectory, dependency); + + if (isProjectFile(resolvedPath, program)) { + // JSON files need their extension as part of the import path, caught by this branch + return resolvedPath; + } + + const resolvedFile = resolvedPath + ".ts"; + if (isProjectFile(resolvedFile, program)) { + return resolvedFile; + } + + const projectIndexPath = path.resolve(resolvedPath, "index.ts"); + if (isProjectFile(projectIndexPath, program)) { + return projectIndexPath; + } + + // Check if this is a sibling of a required lua file + const luaFilePath = path.resolve(fileDirectory, dependency + ".lua"); + if (emitHost.fileExists(luaFilePath)) { + return luaFilePath; + } + + // Not a TS file in our project sources, use resolver to check if we can find dependency + try { + const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); + if (resolveResult) { + return resolveResult; + } + } catch (e) { + // resolveSync errors if it fails to resolve + } + + return undefined; +} + +function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { + return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); +} + +function shouldIncludeDependency(resolvedDependency: string, program: ts.Program) { + // Never include lua files (again) that are transpiled from project sources + if (!hasSourceFileInProject(resolvedDependency, program)) { + // Always include lua files not in node_modules (internal lua sources) + if (!isNodeModulesFile(resolvedDependency)) { + return true; + } else { + // Only include node_modules files if not in library mode + return !isBuildModeLibrary(program); + } + } + return false; +} + +function isBuildModeLibrary(program: ts.Program) { + return program.getCompilerOptions().buildMode === BuildMode.Library; +} + +function findRequiredPaths(code: string): string[] { + // Find all require("") paths in a lua code string + const paths: string[] = []; + const pattern = /require\("(.+)"\)/g; + // eslint-disable-next-line @typescript-eslint/ban-types + let match: RegExpExecArray | null; + while ((match = pattern.exec(code))) { + paths.push(match[1]); + } + + return paths; +} + +function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + file.code = file.code.replace(`require("${originalRequire}")`, `require("${requirePath}")`); +} + +function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { + const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); + if (file.sourceMapNode) { + replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire}"`, `"${requirePath}"`); + } +} + +function replaceInSourceMap(node: SourceNode, parent: SourceNode, require: string, resolvedRequire: string): boolean { + if ((!node.children || node.children.length === 0) && node.toString() === require) { + parent.children = [new SourceNode(node.line, node.column, node.source, [resolvedRequire])]; + return true; // Stop after finding the first occurrence + } + + if (node.children) { + for (const c of node.children) { + if (replaceInSourceMap(c, node, require, resolvedRequire)) { + return true; // Occurrence found in one of the children + } + } + } + + return false; // Did not find the require +} + +function isNodeModulesFile(filePath: string): boolean { + return path + .normalize(filePath) + .split(path.sep) + .some(p => p === "node_modules"); +} + +function isProjectFile(file: string, program: ts.Program): boolean { + return program.getSourceFile(file) !== undefined; +} + +function hasSourceFileInProject(filePath: string, program: ts.Program) { + const pathWithoutExtension = trimExtension(filePath); + return ( + isProjectFile(pathWithoutExtension + ".ts", program) || isProjectFile(pathWithoutExtension + ".json", program) + ); +} + +// Transform an import path to a lua require that is probably not correct, but can be used as fallback when regular resolution fails +function fallbackResolve(required: string, sourceRootDir: string, fileDir: string): string { + return formatPathToLuaPath( + path + .normalize(path.join(path.relative(sourceRootDir, fileDir), required)) + .split(path.sep) + .filter(s => s !== "." && s !== "..") + .join(path.sep) + ); +} diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index cbc77c13c..0d3071f73 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -65,9 +65,12 @@ export function getProgramTranspileResult( diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { const printResult = printer(program, emitHost, sourceFile.fileName, file); - const sourceRootDir = program.getCommonSourceDirectory(); - const fileName = path.resolve(sourceRootDir, sourceFile.fileName); - transpiledFiles.push({ sourceFiles: [sourceFile], fileName, luaAst: file, ...printResult }); + transpiledFiles.push({ + sourceFiles: [sourceFile], + fileName: path.normalize(sourceFile.fileName), + luaAst: file, + ...printResult, + }); } }; diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 205b6b2db..7b5eb0f3f 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -4,6 +4,7 @@ import { isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; +import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; import { EmitFile, EmitHost, ProcessedFile } from "./utils"; @@ -33,6 +34,7 @@ export class Transpiler { writeFile, emitOptions ); + const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); const options = program.getCompilerOptions(); @@ -53,28 +55,79 @@ export class Transpiler { files: ProcessedFile[] ): { emitPlan: EmitFile[] } { const options = program.getCompilerOptions(); - const rootDir = program.getCommonSourceDirectory(); - const outDir = options.outDir ?? rootDir; const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); if (lualibRequired) { - const fileName = normalizeSlashes(path.resolve(rootDir, "lualib_bundle.lua")); + // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan + const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); } + // Resolve imported modules and modify output Lua requires + const resolutionResult = resolveDependencies(program, files, this.emitHost); + diagnostics.push(...resolutionResult.diagnostics); + let emitPlan: EmitFile[]; if (isBundleEnabled(options)) { - const [bundleDiagnostics, bundleFile] = getBundleResult(program, this.emitHost, files); + const [bundleDiagnostics, bundleFile] = getBundleResult(program, resolutionResult.resolvedFiles); diagnostics.push(...bundleDiagnostics); emitPlan = [bundleFile]; } else { - emitPlan = files.map(file => { - const pathInOutDir = path.resolve(outDir, path.relative(rootDir, file.fileName)); - const outputPath = normalizeSlashes(trimExtension(pathInOutDir) + ".lua"); - return { ...file, outputPath }; - }); + emitPlan = resolutionResult.resolvedFiles.map(file => ({ + ...file, + outputPath: getEmitPath(file.fileName, program), + })); } return { emitPlan }; } } + +export function getEmitPath(file: string, program: ts.Program): string { + const relativeOutputPath = getEmitPathRelativeToOutDir(file, program); + const outDir = getEmitOutDir(program); + + return path.join(outDir, relativeOutputPath); +} + +export function getEmitPathRelativeToOutDir(fileName: string, program: ts.Program): string { + const sourceDir = getSourceDir(program); + // Default output path is relative path in source dir + let emitPathSplits = path.relative(sourceDir, fileName).split(path.sep); + + // If source is in a parent directory of source dir, move it into the source dir + emitPathSplits = emitPathSplits.filter(s => s !== ".."); + + // To avoid overwriting lua sources in node_modules, emit into lua_modules + if (emitPathSplits[0] === "node_modules") { + emitPathSplits[0] = "lua_modules"; + } + + // Make extension lua + emitPathSplits[emitPathSplits.length - 1] = trimExtension(emitPathSplits[emitPathSplits.length - 1]) + ".lua"; + + return path.join(...emitPathSplits); +} + +export function getSourceDir(program: ts.Program): string { + const rootDir = program.getCompilerOptions().rootDir; + if (rootDir && rootDir.length > 0) { + return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir); + } + return program.getCommonSourceDirectory(); +} + +export function getEmitOutDir(program: ts.Program): string { + const outDir = program.getCompilerOptions().outDir; + if (outDir && outDir.length > 0) { + return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir); + } + return program.getCommonSourceDirectory(); +} + +export function getProjectRoot(program: ts.Program): string { + // Try to get the directory the tsconfig is in + const tsConfigPath = program.getCompilerOptions().configFilePath; + // If no tsconfig is known, use common source directory + return tsConfigPath ? path.dirname(tsConfigPath) : program.getCommonSourceDirectory(); +} diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 099dfd400..a4acdfbb4 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -8,6 +8,7 @@ import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; export interface EmitHost { + fileExists(path: string): boolean; getCurrentDirectory(): string; readFile(path: string): string | undefined; writeFile: ts.WriteFileCallback; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 06ed05f75..f66b97766 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -105,6 +105,9 @@ describe("command line", () => { ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], @@ -213,6 +216,9 @@ describe("tsconfig", () => { ["sourceMapTraceback", false, { sourceMapTraceback: false }], ["sourceMapTraceback", true, { sourceMapTraceback: true }], + ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], + ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], + ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 4e0d7dd9d..42a4b4355 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -2,6 +2,7 @@ import * as fs from "fs"; import * as path from "path"; import * as tstl from "../../src"; import { annotationDeprecated } from "../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../src/transpilation/diagnostics"; import * as util from "../util"; const fixturesPath = path.join(__dirname, "./transformation"); @@ -14,7 +15,7 @@ const fixtures = fs test.each(fixtures)("Transformation (%s)", (_name, content) => { util.testModule(content) .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) - .ignoreDiagnostics([annotationDeprecated.code]) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) .disableSemanticCheck() .expectLuaToMatchSnapshot(); }); diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index 901d885f4..eaf179a6c 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -1,13 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`should be able to resolve ({"name": "baseurl", "options": [Object]}) 1`] = ` -Array [ - "directories/baseurl/out/lualib_bundle.lua", - "directories/baseurl/out/src/lib/nested/file.lua", - "directories/baseurl/out/src/main.lua", -] -`; - exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` Array [ "directories/basic/src/lib/file.lua", diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 4db30085f..623480405 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -3,27 +3,23 @@ exports[`should transpile 1`] = ` Array [ Object { - "name": "project/otherFile.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "otherFile.lua", + "lua": "local ____exports = {} function ____exports.getNumber(self) return getAPIValue() end return ____exports ", - "writeByteOrderMark": false, }, Object { - "name": "project/index.lua", - "text": "--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]] -local ____exports = {} + "filePath": "index.lua", + "lua": "local ____exports = {} local ____otherFile = require(\\"otherFile\\") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) setAPIValue(myNumber * 5) return ____exports ", - "writeByteOrderMark": false, }, ] `; diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 0ccab7c70..69c86406e 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -1,20 +1,19 @@ import * as path from "path"; import * as util from "../util"; -import { transpileProjectResult } from "./run"; const projectDir = path.join(__dirname, "bundle"); const inputProject = path.join(projectDir, "tsconfig.json"); test("should transpile into one file", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(inputProject); + const { diagnostics, transpiledFiles } = util.testProject(inputProject).getLuaResult(); expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toHaveLength(1); + expect(transpiledFiles).toHaveLength(1); - const { name, text } = emittedFiles[0]; + const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(name).toBe("bundle/bundle.lua"); + expect(outPath.endsWith("bundle/bundle.lua")).toBe(true); // Verify exported module by executing // Use an empty TS string because we already transpiled the TS project - util.testModule("").setLuaHeader(text).expectToEqual({ myNumber: 3 }); + util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); }); diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 9141199e5..1c0bba994 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -13,7 +13,6 @@ test.each([ { name: "basic", options: { outDir: "out" } }, { name: "basic", options: { rootDir: "src" } }, { name: "basic", options: { rootDir: "src", outDir: "out" } }, - { name: "baseurl", options: { baseUrl: "./src/lib", rootDir: ".", outDir: "./out" } }, ])("should be able to resolve (%p)", ({ name, options: compilerOptions }) => { const projectPath = path.join(__dirname, "directories", name); jest.spyOn(process, "cwd").mockReturnValue(projectPath); diff --git a/test/transpile/directories/baseurl/src/lib/nested/file.ts b/test/transpile/directories/baseurl/src/lib/nested/file.ts deleted file mode 100644 index 4248a042b..000000000 --- a/test/transpile/directories/baseurl/src/lib/nested/file.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function test() { - return 1; -} diff --git a/test/transpile/directories/baseurl/src/main.ts b/test/transpile/directories/baseurl/src/main.ts deleted file mode 100644 index 1665f4e08..000000000 --- a/test/transpile/directories/baseurl/src/main.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { test } from "nested/file"; - -test(); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts new file mode 100644 index 000000000..c386e2d33 --- /dev/null +++ b/test/transpile/module-resolution.spec.ts @@ -0,0 +1,282 @@ +import * as path from "path"; +import * as tstl from "../../src"; +import * as util from "../util"; +import * as ts from "typescript"; +import { transpileProject } from "../../src"; + +describe("basic module resolution", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); + + const projectWithNodeModules = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")); + + test("can resolve global dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().globalWithDeclarationsResults).toEqual({ + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }); + }); + + test("can resolve global dependencies with hand-written declarations", () => { + // No declarations in the node_modules directory, but written by hand in project dir + expect(projectWithNodeModules.getLuaExecutionResult().globalWithoutDeclarationsResults).toEqual({ + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }); + }); + + test("can resolve module dependencies with declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDeclarationsResults).toEqual({ + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }); + }); + + test("can resolve module dependencies with hand-written declarations", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithoutDeclarationsResults).toEqual({ + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }); + }); + + test("can resolve package depencency with a dependency on another package", () => { + // Declarations in the node_modules directory + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDependencyResult).toEqual( + "Calling dependency: foo from lua module with decls" + ); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ + globalWithDeclarationsResults: { + foo: "foo from lua global with decls", + bar: "bar from lua global with decls: global with declarations!", + baz: "baz from lua global with decls", + }, + globalWithoutDeclarationsResults: { + foo: "foo from lua global without decls", + bar: "bar from lua global without decls: global without declarations!", + baz: "baz from lua global without decls", + }, + moduleWithDeclarationsResults: { + foo: "foo from lua module with decls", + bar: "bar from lua module with decls: module with declarations!", + baz: "baz from lua module with decls", + }, + moduleWithDependencyResult: "Calling dependency: foo from lua module with decls", + moduleWithoutDeclarationsResults: { + foo: "foo from lua module without decls", + bar: "bar from lua module without decls: module without declarations!", + baz: "baz from lua module without decls", + }, + }); + }); +}); + +describe("module resolution with chained dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("can resolve dependencies in chain", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .expectToEqual(expectedResult); + }); + + test("resolved package dependency included in bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); + + test("works with different module setting", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ module: ts.ModuleKind.ESNext }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution with outDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + const expectedResult = { result: "dependency3", result2: "someFunc from otherfile.lua" }; + + test("emits files in outDir", () => { + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(5); + expect(outPaths).toContain(path.join("tstl-out", "main.lua")); + // Note: outputs to lua_modules + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency1", "otherfile.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency2", "index.lua")); + expect(outPaths).toContain(path.join("tstl-out", "lua_modules", "dependency3", "index.lua")); + }); + + test("emits bundle in outDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + const builder = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ outDir: "tstl-out", luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + + // Get the output paths relative to the project path + const outPaths = builder.getLuaResult().transpiledFiles.map(f => path.relative(projectPath, f.outPath)); + expect(outPaths).toHaveLength(1); + expect(outPaths).toContain(path.join("tstl-out", "bundle.lua")); + }); +}); + +describe("module resolution with sourceDir", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-sourceDir"); + const expectedResult = { + result: "dependency3", + functionInSubDir: "non-node_modules import", + functionReExportedFromSubDir: "nested func result", + nestedFunctionInSubDirOfSubDir: "nested func result", + nestedFunctionUsingFunctionFromParentDir: "nested func: non-node_modules import 2", + }; + + test("can resolve dependencies with sourceDir", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "src", "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution project with lua sources", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + const expectedResult = { + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle files with sourceDir", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); + +describe("module resolution in library mode", () => { + test("result does not contain resolved paths", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-dependency-chain"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ buildMode: tstl.BuildMode.Library }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); + + test("project works in library mode because no external dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out", buildMode: tstl.BuildMode.Library }) + .expectToEqual({ + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }) + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); + + test("bundle works in library mode because no external dependencies", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); + const mainFile = path.join(projectPath, "main.ts"); + + const { transpiledFiles } = util + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ buildMode: tstl.BuildMode.Library, luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ + funcFromLuaFile: "lua file in subdir", + funcFromSubDirLuaFile: "lua file in subdir", + }) + .getLuaResult(); + + for (const file of transpiledFiles) { + expect(file.lua).not.toContain('require("lua_modules'); + } + }); +}); + +describe("module resolution project with dependencies built by tstl library mode", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-modules"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + transpileProject(path.join(projectPath, "dependency2-ts", "tsconfig.json")); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + dependency2MainResult: "dependency 2 main", + dependency2OtherFileResult: "Dependency 2 func: my string argument", + }; + + test("can resolve lua dependencies", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) + .setOptions({ outDir: "tstl-out" }) + .expectToEqual(expectedResult); + }); + + test("can resolve dependencies and bundle", () => { + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult); + }); +}); diff --git a/test/transpile/module-resolution/project-with-dependency-chain/main.ts b/test/transpile/module-resolution/project-with-dependency-chain/main.ts new file mode 100644 index 000000000..cda66cd55 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/main.ts @@ -0,0 +1,4 @@ +import * as dependency1 from "dependency1"; + +export const result = dependency1.f1(); +export const result2 = dependency1.otherFileFromDependency1(); diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..5155e72c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function f1(): string; +export declare function otherFileFromDependency1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua new file mode 100644 index 000000000..80cae6fb8 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/index.lua @@ -0,0 +1,7 @@ +local dependency2 = require("dependency2") +local otherfile = require("otherfile") + +return { + f1 = function() return dependency2.f2() end, + otherFileFromDependency1 = otherfile.someFunc +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..871964bf7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency1/otherfile.lua @@ -0,0 +1,5 @@ +return { + someFunc = function() + return "someFunc from otherfile.lua" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-chain/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts new file mode 100644 index 000000000..6166280f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcFromSubDir(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua new file mode 100644 index 000000000..a23007078 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/lua_sources/otherluaFile.lua @@ -0,0 +1,3 @@ +return { + funcFromSubDir = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts new file mode 100644 index 000000000..6294675a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function funcInLuaFile(): string; diff --git a/test/transpile/module-resolution/project-with-lua-sources/luafile.lua b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua new file mode 100644 index 000000000..56e61090f --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/luafile.lua @@ -0,0 +1,3 @@ +return { + funcInLuaFile = function() return "lua file in subdir" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-lua-sources/main.ts b/test/transpile/module-resolution/project-with-lua-sources/main.ts new file mode 100644 index 000000000..d4c19b440 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/main.ts @@ -0,0 +1,5 @@ +import { funcInLuaFile } from "./luafile"; +import { funcFromSubDir } from "./lua_sources/otherluaFile"; + +export const funcFromLuaFile = funcInLuaFile(); +export const funcFromSubDirLuaFile = funcFromSubDir(); diff --git a/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json new file mode 100644 index 000000000..a07455ed7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-lua-sources/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "outDir": "tstl-out" + } +} diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts new file mode 100644 index 000000000..4d1c1db1b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-global-without-decls.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ +declare function fooGlobalWithoutDecls(): string; +declare function barGlobalWithoutDecls(param: string): string; +declare function bazGlobalWithoutDecls(): string; diff --git a/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts new file mode 100644 index 000000000..9ccfc9bfe --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/lua-module-without-decls.d.ts @@ -0,0 +1,9 @@ +/** @noSelfInFile */ +declare module "lua-module-without-decls" { + function foo(this: void): string; + function bar(this: void, param: string): string; +} + +declare module "lua-module-without-decls/baz" { + function baz(this: void): string; +} diff --git a/test/transpile/module-resolution/project-with-node-modules/main.ts b/test/transpile/module-resolution/project-with-node-modules/main.ts new file mode 100644 index 000000000..8d9332190 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/main.ts @@ -0,0 +1,39 @@ +import "lua-global-with-decls"; +import "lua-global-with-decls/baz"; + +import "lua-global-without-decls"; +import "lua-global-without-decls/baz"; + +import * as moduleWithDeclarations from "lua-module-with-decls"; +import * as moduleWithDeclarationsBaz from "lua-module-with-decls/baz"; + +import * as moduleWithoutDeclarations from "lua-module-without-decls"; +import * as moduleWithoutDeclarationsBaz from "lua-module-without-decls/baz"; + +import * as moduleWithDependency from "lua-module-with-dependency"; + +export const globalWithDeclarationsResults = { + foo: fooGlobal(), + bar: barGlobal("global with declarations!"), + baz: bazGlobal(), +}; + +export const globalWithoutDeclarationsResults = { + foo: fooGlobalWithoutDecls(), + bar: barGlobalWithoutDecls("global without declarations!"), + baz: bazGlobalWithoutDecls(), +}; + +export const moduleWithDeclarationsResults = { + foo: moduleWithDeclarations.foo(), + bar: moduleWithDeclarations.bar("module with declarations!"), + baz: moduleWithDeclarationsBaz.baz(), +}; + +export const moduleWithoutDeclarationsResults = { + foo: moduleWithoutDeclarations.foo(), + bar: moduleWithoutDeclarations.bar("module without declarations!"), + baz: moduleWithoutDeclarationsBaz.baz(), +}; + +export const moduleWithDependencyResult = moduleWithDependency.callDependency(); diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts new file mode 100644 index 000000000..23f55b1ad --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.d.ts @@ -0,0 +1 @@ +declare function bazGlobal(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua new file mode 100644 index 000000000..952807f1a --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobal() + return "baz from lua global with decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts new file mode 100644 index 000000000..1339056b5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +declare function fooGlobal(): string; +declare function barGlobal(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua new file mode 100644 index 000000000..d10edd189 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-with-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobal() + return "foo from lua global with decls" +end +function barGlobal(param) + return "bar from lua global with decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua new file mode 100644 index 000000000..02980e662 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/baz.lua @@ -0,0 +1,3 @@ +function bazGlobalWithoutDecls() + return "baz from lua global without decls" +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua new file mode 100644 index 000000000..46dd970a0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-global-without-decls/index.lua @@ -0,0 +1,6 @@ +function fooGlobalWithoutDecls() + return "foo from lua global without decls" +end +function barGlobalWithoutDecls(param) + return "bar from lua global without decls: " .. param +end \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts new file mode 100644 index 000000000..5f46a6ce2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function baz(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua new file mode 100644 index 000000000..f4e16a0d7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module with decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts new file mode 100644 index 000000000..aa83ce4a6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.d.ts @@ -0,0 +1,3 @@ +/** @noSelfInFile */ +export declare function foo(): string; +export declare function bar(param: string): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua new file mode 100644 index 000000000..0c5d47fe6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module with decls" + end, + bar = function(param) + return "bar from lua module with decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts new file mode 100644 index 000000000..381596acd --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelf */ +export declare function callDependency(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua new file mode 100644 index 000000000..9bc475e5b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-with-dependency/index.lua @@ -0,0 +1,7 @@ +local dependency = require("lua-module-with-decls") + +return { + callDependency = function() + return "Calling dependency: " .. dependency.foo() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua new file mode 100644 index 000000000..7358f341b --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/baz.lua @@ -0,0 +1,5 @@ +return { + baz = function() + return "baz from lua module without decls" + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua new file mode 100644 index 000000000..e73581589 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/node_modules/lua-module-without-decls/index.lua @@ -0,0 +1,8 @@ +return { + foo = function() + return "foo from lua module without decls" + end, + bar = function(param) + return "bar from lua module without decls: " .. param + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-node-modules/tsconfig.json b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json new file mode 100644 index 000000000..935b64af6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..761d6bc02 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.d.ts @@ -0,0 +1,2 @@ +/** @noSelfInFile */ +export declare function f1(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua new file mode 100644 index 000000000..dcf28d6fd --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency1/index.lua @@ -0,0 +1,5 @@ +local dependency2 = require("dependency2") + +return { + f1 = function() return dependency2.f2() end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua new file mode 100644 index 000000000..10b36647e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency2/index.lua @@ -0,0 +1,5 @@ +local dependency3 = require("dependency3") + +return { + f2 = dependency3.f3 +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua new file mode 100644 index 000000000..112f9ba7e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/node_modules/dependency3/index.lua @@ -0,0 +1,3 @@ +return { + f3 = function() return "dependency3" end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/main.ts b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts new file mode 100644 index 000000000..9014f7b62 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/main.ts @@ -0,0 +1,9 @@ +import * as dependency1 from "dependency1"; +import { func, nestedFunc } from "./subdir/otherfile"; +import { nestedFunc as nestedFuncOriginal, nestedFuncUsingParent } from "./subdir/subdirofsubdir/nestedfile"; + +export const result = dependency1.f1(); +export const functionInSubDir = func(); +export const functionReExportedFromSubDir = nestedFunc(); +export const nestedFunctionInSubDirOfSubDir = nestedFuncOriginal(); +export const nestedFunctionUsingFunctionFromParentDir = nestedFuncUsingParent(); diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts new file mode 100644 index 000000000..c12dee955 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile.ts @@ -0,0 +1,5 @@ +export function func() { + return "non-node_modules import"; +} + +export { nestedFunc } from "./subdirofsubdir/nestedfile"; diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts new file mode 100644 index 000000000..1132c2ea1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/otherfile2.ts @@ -0,0 +1,3 @@ +export function func2() { + return "non-node_modules import 2"; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts new file mode 100644 index 000000000..d316f023e --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/src/subdir/subdirofsubdir/nestedfile.ts @@ -0,0 +1,9 @@ +import { func2 } from "../otherfile2"; + +export function nestedFunc() { + return "nested func result"; +} + +export function nestedFuncUsingParent() { + return `nested func: ${func2()}`; +} diff --git a/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json new file mode 100644 index 000000000..200df2468 --- /dev/null +++ b/test/transpile/module-resolution/project-with-sourceDir/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "src" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/d1otherfile.ts @@ -0,0 +1,3 @@ +export function dependency1OtherFileFunc() { + return "dependency1OtherFileFunc in dependency1/d1otherfile"; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts new file mode 100644 index 000000000..fc1cdddec --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts @@ -0,0 +1,5 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json new file mode 100644 index 000000000..5fcb76fbe --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency1", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts new file mode 100644 index 000000000..63e34f8b6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/d2otherfile.ts @@ -0,0 +1,3 @@ +export function dependency2OtherFileFunc(this: void, arg: string) { + return `Dependency 2 func: ${arg}`; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts new file mode 100644 index 000000000..03b90c231 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/main.ts @@ -0,0 +1,5 @@ +export function dependency2Main() { + return "dependency 2 main"; +} + +export * from "./d2otherfile"; diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json new file mode 100644 index 000000000..f77b336a2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency2-ts/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "outDir": "../node_modules/dependency2", + "declaration": true + }, + "tstl": { + "buildMode": "library" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts new file mode 100644 index 000000000..c1286088a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/main.ts @@ -0,0 +1,8 @@ +import { dependency1IndexFunc } from "dependency1"; +import { dependency1OtherFileFunc } from "dependency1/d1otherfile"; +import { dependency2Main, dependency2OtherFileFunc } from "dependency2/main"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); +export const dependency2MainResult = dependency2Main(); +export const dependency2OtherFileResult = dependency2OtherFileFunc("my string argument"); diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index 6f262dada..965c834d7 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,8 +1,15 @@ import * as path from "path"; -import { transpileProjectResult } from "./run"; +import * as util from "../util"; test("should transpile", () => { - const { diagnostics, emittedFiles } = transpileProjectResult(path.join(__dirname, "project", "tsconfig.json")); - expect(diagnostics).not.toHaveDiagnostics(); - expect(emittedFiles).toMatchSnapshot(); + const projectDir = path.join(__dirname, "project"); + const { transpiledFiles } = util + .testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect( + transpiledFiles.map(f => ({ filePath: path.relative(projectDir, f.outPath), lua: f.lua })) + ).toMatchSnapshot(); }); diff --git a/test/transpile/run.ts b/test/transpile/run.ts index 8890d7a18..a24a76b9f 100644 --- a/test/transpile/run.ts +++ b/test/transpile/run.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; import * as tstl from "../../src"; -import { parseConfigFileWithSystem } from "../../src/cli/tsconfig"; import { normalizeSlashes } from "../../src/utils"; export function transpileFilesResult(rootNames: string[], options: tstl.CompilerOptions) { @@ -16,12 +15,3 @@ export function transpileFilesResult(rootNames: string[], options: tstl.Compiler return { diagnostics, emittedFiles }; } - -export function transpileProjectResult(configFileName: string) { - const parseResult = parseConfigFileWithSystem(configFileName); - if (parseResult.errors.length > 0) { - return { diagnostics: parseResult.errors, emittedFiles: [] }; - } - - return transpileFilesResult(parseResult.fileNames, parseResult.options); -} diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index d28f4bf25..f961dddb0 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -59,6 +59,16 @@ test("entry point in directory", () => { .expectToEqual({ value: true }); }); +test("entry point in rootDir", () => { + util.testModule` + export { value } from "./module"; + ` + .setMainFileName("src/main.ts") + .addExtraFile("src/module.ts", "export const value = true") + .setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToEqual({ value: true }); +}); + test("LuaLibImportKind.Require", () => { util.testBundle` export const result = [1, 2]; diff --git a/test/unit/file.spec.ts b/test/unit/file.spec.ts index 3a810dc60..12a136408 100644 --- a/test/unit/file.spec.ts +++ b/test/unit/file.spec.ts @@ -10,6 +10,20 @@ describe("JSON", () => { .setMainFileName("main.json") .expectToEqual(new util.ExecutionError("Unexpected end of JSON input")); }); + + test("JSON modules can be imported", () => { + util.testModule` + import * as jsonData from "./jsonModule.json"; + export const result = jsonData; + ` + .addExtraFile("jsonModule.json", '{ "jsonField1": "hello, this is JSON", "jsonField2": ["a", "b", "c"] }') + .expectToEqual({ + result: { + jsonField1: "hello, this is JSON", + jsonField2: ["a", "b", "c"], + }, + }); + }); }); describe("shebang", () => { diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index f61e37cb2..2da1d9722 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -1,3 +1,4 @@ +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test("enables noSelfInFile behavior for functions", () => { @@ -31,10 +32,13 @@ test("generates declaration files with @noSelfInFile", () => { const fooDeclaration = fooBuilder.getLuaResult().transpiledFiles.find(f => f.declaration)?.declaration; util.assert(fooDeclaration !== undefined); + expect(fooDeclaration).toContain("@noSelfInFile"); + util.testModule` - import { bar } from "./foo.d"; + import { bar } from "./foo"; const test: (this: void) => void = bar; ` .addExtraFile("foo.d.ts", fooDeclaration) + .ignoreDiagnostics([couldNotResolveRequire.code]) // no foo implementation in the project to create foo.lua .expectToHaveNoDiagnostics(); }); diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index d4228141d..4db74c57f 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -2,9 +2,9 @@ exports[`doesn't resolve paths out of root dir: code 1`] = ` "local ____exports = {} -local module = require(\\"../module\\") +local module = require(\\"module\\") local ____ = module return ____exports" `; -exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"src/main.ts(2,33): error TSTL: Cannot create require path. Module '../module' does not exist within --rootDir."`; +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve require path '../module' in file main.ts."`; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index dd3d1dd7a..ffdc36ce9 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -58,8 +58,7 @@ test.each(["ke-bab", "dollar$", "singlequote'", "hash#", "s p a c e", "ɥɣɎɌ import { foo } from "./${name}"; export { foo }; ` - .disableSemanticCheck() - .setLuaHeader('setmetatable(package.loaded, { __index = function() return { foo = "bar" } end })') + .addExtraFile(`${name}.ts`, 'export const foo = "bar";') .setReturnExport("foo") .expectToEqual("bar"); } diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 541c28c56..791ae06b5 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { unresolvableRequirePath } from "../../../src/transformation/utils/diagnostics"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; @@ -69,6 +69,7 @@ test.each([ module; ` .setMainFileName(filePath) + .addExtraFile(`${usedPath}.ts`, "") .setOptions(options) .tap(expectToRequire(expected)); }); @@ -81,7 +82,7 @@ test("doesn't resolve paths out of root dir", () => { .setMainFileName("src/main.ts") .setOptions({ rootDir: "./src" }) .disableSemanticCheck() - .expectDiagnosticsToMatchSnapshot([unresolvableRequirePath.code]); + .expectDiagnosticsToMatchSnapshot([couldNotResolveRequire.code]); }); test.each([ diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 84a6596a6..371c50df9 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,5 +1,6 @@ import { Position, SourceMapConsumer } from "source-map"; import * as tstl from "../../../src"; +import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; test.each([ @@ -144,7 +145,11 @@ test.each([ ], }, ])("Source map has correct mapping (%p)", async ({ code, assertPatterns }) => { - const file = util.testModule(code).expectToHaveNoDiagnostics().getMainLuaFileResult(); + const file = util + .testModule(code) + .ignoreDiagnostics([couldNotResolveRequire.code]) + .expectToHaveNoDiagnostics() + .getMainLuaFileResult(); const consumer = await new SourceMapConsumer(file.luaSourceMap); for (const { luaPattern, typeScriptPattern } of assertPatterns) { @@ -157,32 +162,25 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {}, mapSource: "foo.ts", fullSource: "foo.ts" }, + { fileName: "/proj/foo.ts", config: {} }, { fileName: "/proj/src/foo.ts", config: { outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../src/foo.ts", - fullSource: "../src/foo.ts", }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, - mapSource: "../../src/sub/foo.ts", - fullSource: "../../src/sub/foo.ts", }, { fileName: "/proj/src/sub/main.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - mapSource: "sub/main.ts", - fullSource: "bin/sub/main.ts", + fullSource: "bin/proj/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, mapSource, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { const file = util.testModule` const foo = "foo" ` @@ -192,11 +190,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(mapSource); + expect(sourceMap.sources[0]).toBe(fileName); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource); + expect(consumer.sources[0]).toBe(fullSource ?? fileName); }); test.each([ diff --git a/test/util.ts b/test/util.ts index b553ef359..39259e784 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,6 +1,6 @@ /* eslint-disable jest/no-standalone-expect */ import * as nativeAssert from "assert"; -import { LauxLib, Lua, LuaLib, LUA_OK } from "lua-wasm-bindings/dist/lua"; +import { LauxLib, Lua, LuaLib, LuaState, LUA_OK } from "lua-wasm-bindings/dist/lua"; import * as fs from "fs"; import { stringify } from "javascript-stringify"; import * as path from "path"; @@ -9,6 +9,8 @@ import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; +import { getEmitOutDir, transpileProject } from "../src"; +import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); @@ -128,7 +130,7 @@ export abstract class TestBuilder { return this; } - private options: tstl.CompilerOptions = { + protected options: tstl.CompilerOptions = { luaTarget: tstl.LuaTarget.Lua54, noHeader: true, skipLibCheck: true, @@ -148,7 +150,7 @@ export abstract class TestBuilder { protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { expect(this.hasProgram).toBe(false); - this.mainFileName = mainFileName; + this.mainFileName = normalizeSlashes(mainFileName); return this; } @@ -176,7 +178,10 @@ export abstract class TestBuilder { @memoize public getProgram(): ts.Program { this.hasProgram = true; - return tstl.createVirtualProgram({ ...this.extraFiles, [this.mainFileName]: this.getTsCode() }, this.options); + return tstl.createVirtualProgram( + { ...this.extraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, + this.options + ); } @memoize @@ -202,7 +207,10 @@ export abstract class TestBuilder { const { transpiledFiles } = this.getLuaResult(); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)); + : transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => normalizeSlashes(f.fileName) === this.mainFileName) + ); + expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; } @@ -259,9 +267,7 @@ export abstract class TestBuilder { public debug(): this { const transpiledFiles = this.getLuaResult().transpiledFiles; - const luaCode = transpiledFiles.map( - f => `[${f.sourceFiles.map(sf => sf.fileName).join(",")}]:\n${f.lua?.replace(/^/gm, " ")}` - ); + const luaCode = transpiledFiles.map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; @@ -366,35 +372,23 @@ export abstract class TestBuilder { // Load modules // Json - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, jsonLib); - lua.lua_setfield(L, -2, "json"); + this.packagePreloadLuaFile(L, lua, lauxlib, "json", jsonLib); // Lua lib if ( this.options.luaLibImport === tstl.LuaLibImportKind.Require || mainFile.includes('require("lualib_bundle")') ) { - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, luaLib); - lua.lua_setfield(L, -2, "lualib_bundle"); + this.packagePreloadLuaFile(L, lua, lauxlib, "lualib_bundle", luaLib); } - // Extra files + // Load all transpiled files into Lua's package cache const { transpiledFiles } = this.getLuaResult(); - - Object.keys(this.extraFiles).forEach(fileName => { - const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => f.fileName === fileName) - ); - if (transpiledExtraFile?.lua) { - lua.lua_getglobal(L, "package"); - lua.lua_getfield(L, -1, "preload"); - lauxlib.luaL_loadstring(L, transpiledExtraFile.lua); - lua.lua_setfield(L, -2, fileName.replace(".ts", "")); + for (const transpiledFile of transpiledFiles) { + if (transpiledFile.lua) { + const filePath = path.relative(getEmitOutDir(this.getProgram()), transpiledFile.outPath); + this.packagePreloadLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); } - }); + } // Execute Main const wrappedMainCode = ` @@ -423,6 +417,14 @@ end)());`; } } + private packagePreloadLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { + // Adding source Lua to the package.preload cache will allow require to find it + lua.lua_getglobal(state, "package"); + lua.lua_getfield(state, -1, "preload"); + lauxlib.luaL_loadstring(state, fileContent); + lua.lua_setfield(state, -2, formatPathToLuaPath(fileName.replace(".lua", ""))); + } + private executeJs(): any { const { transpiledFiles } = this.getJsResult(); // Custom require for extra files. Really basic. Global support is hacky @@ -539,6 +541,22 @@ class ExpressionTestBuilder extends AccessorTestBuilder { } } +class ProjectTestBuilder extends ModuleTestBuilder { + constructor(private tsConfig: string) { + super(""); + this.setOptions({ configFilePath: this.tsConfig, ...tstl.parseConfigFileWithSystem(this.tsConfig) }); + } + + @memoize + public getLuaResult(): tstl.TranspileVirtualProjectResult { + // Override getLuaResult to use transpileProject with tsconfig.json instead + const collector = createEmitOutputCollector(); + const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile); + + return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; + } +} + const createTestBuilderFactory = ( builder: new (_tsCode: string) => T, serializeSubstitutions: boolean @@ -566,3 +584,4 @@ export const testFunction = createTestBuilderFactory(FunctionTestBuilder, false) export const testFunctionTemplate = createTestBuilderFactory(FunctionTestBuilder, true); export const testExpression = createTestBuilderFactory(ExpressionTestBuilder, false); export const testExpressionTemplate = createTestBuilderFactory(ExpressionTestBuilder, true); +export const testProject = createTestBuilderFactory(ProjectTestBuilder, false); From ca4428514cccf933ad031562fc7228a54f9eeed7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Jun 2021 21:11:35 +0200 Subject: [PATCH 357/764] Changelog 0.40.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fefbd8362..12a8fda3b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 0.40.0 + +- Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. +- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg) for instructions how to upgrade. +- Added support for `array.entries()`. +- Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info. +- Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua. + +- Fixed an issue where using TypeScript transformer plugins would cause invalid namespace and module code, as well as breaking hoisting. +- Fixed invalid switch statement output when the `default` clause was not the last clause in the switch. +- Fixed missing LuaLib dependency when using `string.split`. +- Fixed **lots** of bundling bugs and issues, also added the TypeScriptToLua header to the top of the bundle unless _noHeader_ is specified. + +Under the hood: + +- Various improvements to testing infrastructure for testing (virtual) projects with multiple files. + ## 0.39.0 - **[Breaking]** Removed support for `@phantom`, `@metaExtension`, `@extension`, `@pureAbstract` compiler annotations. As of this version **these will no longer function!** For help upgrading your code see [the deprecated annotation docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#deprecated). From c6e3555ae736db1ddc8c2e8c5b596cb437bf8322 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 14 Jun 2021 21:18:22 +0200 Subject: [PATCH 358/764] 0.40.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43137cbae..002afb94a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index fc3604e49..5cba2dd38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.39.6", + "version": "0.40.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 1e539f0af1461396c9dafbce9957f076febda6cd Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Jun 2021 09:10:25 +0200 Subject: [PATCH 359/764] Also resolve tsx files (#1039) --- src/transpilation/resolve.ts | 29 ++++++++++--------- test/transpile/module-resolution.spec.ts | 15 ++++++++++ .../project-with-tsx/dir/index.tsx | 3 ++ .../project-with-tsx/main.tsx | 5 ++++ .../project-with-tsx/other.tsx | 3 ++ .../project-with-tsx/tsconfig.json | 5 ++++ 6 files changed, 46 insertions(+), 14 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-tsx/dir/index.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/main.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/other.tsx create mode 100644 test/transpile/module-resolution/project-with-tsx/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 3eca25e2e..a9b6b4e1a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -103,19 +103,18 @@ function resolveDependency( // Check if file is a file in the project const resolvedPath = path.join(fileDirectory, dependency); - if (isProjectFile(resolvedPath, program)) { - // JSON files need their extension as part of the import path, caught by this branch - return resolvedPath; - } - - const resolvedFile = resolvedPath + ".ts"; - if (isProjectFile(resolvedFile, program)) { - return resolvedFile; - } - - const projectIndexPath = path.resolve(resolvedPath, "index.ts"); - if (isProjectFile(projectIndexPath, program)) { - return projectIndexPath; + const possibleProjectFiles = [ + resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, + resolvedPath + ".ts", // Regular ts file + path.join(resolvedPath, "index.ts"), // Index ts file, + resolvedPath + ".tsx", // tsx file + path.join(resolvedPath, "index.tsx"), // tsx index + ]; + + for (const possibleFile of possibleProjectFiles) { + if (isProjectFile(possibleFile, program)) { + return possibleFile; + } } // Check if this is a sibling of a required lua file @@ -215,7 +214,9 @@ function isProjectFile(file: string, program: ts.Program): boolean { function hasSourceFileInProject(filePath: string, program: ts.Program) { const pathWithoutExtension = trimExtension(filePath); return ( - isProjectFile(pathWithoutExtension + ".ts", program) || isProjectFile(pathWithoutExtension + ".json", program) + isProjectFile(pathWithoutExtension + ".ts", program) || + isProjectFile(pathWithoutExtension + ".tsx", program) || + isProjectFile(pathWithoutExtension + ".json", program) ); } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index c386e2d33..6c5bff4a2 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -280,3 +280,18 @@ describe("module resolution project with dependencies built by tstl library mode .expectToEqual(expectedResult); }); }); + +// Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1037 +describe("module resolution with tsx", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tsx"); + + test("project with tsx files", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.tsx")) + .debug() + .expectToEqual({ + result: "hello from other.tsx", + indexResult: "hello from dir/index.tsx", + }); + }); +}); diff --git a/test/transpile/module-resolution/project-with-tsx/dir/index.tsx b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx new file mode 100644 index 000000000..20c981b8a --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/dir/index.tsx @@ -0,0 +1,3 @@ +export function indexf() { + return "hello from dir/index.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/main.tsx b/test/transpile/module-resolution/project-with-tsx/main.tsx new file mode 100644 index 000000000..d17e2a7e4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/main.tsx @@ -0,0 +1,5 @@ +import { f } from "./other"; +import { indexf } from "./dir"; + +export const result = f(); +export const indexResult = indexf(); diff --git a/test/transpile/module-resolution/project-with-tsx/other.tsx b/test/transpile/module-resolution/project-with-tsx/other.tsx new file mode 100644 index 000000000..514705822 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/other.tsx @@ -0,0 +1,3 @@ +export function f() { + return "hello from other.tsx"; +} diff --git a/test/transpile/module-resolution/project-with-tsx/tsconfig.json b/test/transpile/module-resolution/project-with-tsx/tsconfig.json new file mode 100644 index 000000000..b5fbd521b --- /dev/null +++ b/test/transpile/module-resolution/project-with-tsx/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "jsx": "react" + } +} From 8d9c8afe27e707ef68f834088d92f9851c703a7e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Jun 2021 22:06:27 +0200 Subject: [PATCH 360/764] Fix getEmitOutDir not using project root if no outDir is provided (#1038) * Fix getEmitOutDir not using project root if no outDir is provided * Removed redundant tests --- CHANGELOG.md | 2 +- src/transpilation/bundle.ts | 4 +- src/transpilation/transpiler.ts | 4 +- test/transpile/bundle.spec.ts | 2 +- test/transpile/paths.spec.ts | 120 ++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 test/transpile/paths.spec.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a8fda3b..1a81be4d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 0.40.0 - Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. -- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg) for instructions how to upgrade. +- **[Breaking]** Removed support for deprecated annotations that have been replaced with language extensions: `/** @luaIterator */`, `/** @vararg */`, `/** @luatable */` and `/** forRange */`. If you were still using these, see [the docs](https://typescripttolua.github.io/docs/advanced/compiler-annotations) for instructions how to upgrade. - Added support for `array.entries()`. - Added support for `LuaTable.has(key)` and `LuaTable.delete(key)` to the language extensions. See [docs](https://typescripttolua.github.io/docs/advanced/language-extensions#lua-table-types) for more info. - Made language extension types more strict, disallowing `null` and `undefined` in some places where they would cause problems in Lua. diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 31d58b27b..579e84ee1 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -3,7 +3,7 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions } from "../CompilerOptions"; import { escapeString, tstlHeader } from "../LuaPrinter"; -import { cast, formatPathToLuaPath, isNonNull, normalizeSlashes, trimExtension } from "../utils"; +import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; import { EmitFile, ProcessedFile } from "./utils"; @@ -42,7 +42,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t // Resolve project settings relative to project file. const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); - const outputPath = normalizeSlashes(path.resolve(getEmitOutDir(program), bundleFile)); + const outputPath = path.resolve(getEmitOutDir(program), bundleFile); if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 7b5eb0f3f..2dc5a9fc7 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -122,7 +122,9 @@ export function getEmitOutDir(program: ts.Program): string { if (outDir && outDir.length > 0) { return path.isAbsolute(outDir) ? outDir : path.resolve(getProjectRoot(program), outDir); } - return program.getCommonSourceDirectory(); + + // If no outDir is provided, emit in project root + return getProjectRoot(program); } export function getProjectRoot(program: ts.Program): string { diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 69c86406e..718e1b112 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -12,7 +12,7 @@ test("should transpile into one file", () => { const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(outPath.endsWith("bundle/bundle.lua")).toBe(true); + expect(outPath.endsWith(path.join("bundle", "bundle.lua"))).toBe(true); // Verify exported module by executing // Use an empty TS string because we already transpiled the TS project util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts new file mode 100644 index 000000000..33d4f6258 --- /dev/null +++ b/test/transpile/paths.spec.ts @@ -0,0 +1,120 @@ +import * as path from "path"; +import * as ts from "typescript"; +import { getSourceDir } from "../../src"; +import * as util from "../util"; + +const cwd = process.cwd(); + +// Path for project tsconfig.json to resolve for +const configFilePath = path.join(cwd, "tsconfig.json"); + +describe("getSourceDir", () => { + test("with rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath, rootDir: "src" }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + expect(getSourceDir(program)).toBe(path.join(cwd, "src")); + }); + + test("without rootDir", () => { + const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); + + // Common sources directory is project root + expect(normalize(getSourceDir(program))).toBe(cwd); + }); + + test("without rootDir in src dir", () => { + const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], { + configFilePath, + }); + + // getCommonSourceDirectory does not work right so mock it + jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(path.join(cwd, "src")); + + // Common sources directory is src + expect(normalize(getSourceDir(program))).toBe(path.join(cwd, "src")); + }); +}); + +describe("getEmitPath", () => { + test("puts files next to input without options", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain("main.lua"); + expect(fileNames).toContain(path.join("dir", "extra.lua")); + }); + + test("puts files in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .setOptions({ outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "dir", "extra.lua")); + }); + + test("puts files from rootDir in outdir", () => { + const outDir = path.join(cwd, "tstl-out"); + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ rootDir: "src", outDir }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain(path.join(outDir, "main.lua")); + expect(fileNames).toContain(path.join(outDir, "extra.lua")); + }); + + test("puts bundle relative to project root", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ configFilePath, rootDir: "src", luaBundle: "out/bundle.lua", luaBundleEntry: "src/main.ts" }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out", "bundle.lua")); + }); + + test("puts bundle relative to outdir", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ + configFilePath, + rootDir: "src", + outDir: "out1", + luaBundle: "out2/bundle.lua", + luaBundleEntry: "src/main.ts", + }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.lua")); + }); +}); + +function normalize(path: string) { + return path.endsWith("/") ? path.slice(0, path.length - 1) : path; +} From b847804b2a6fa84ffadf84755cf4a36dffee219f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 21 Jun 2021 22:15:59 +0200 Subject: [PATCH 361/764] 0.40.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 002afb94a..c3acb08d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 5cba2dd38..f96178a81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.40.0", + "version": "0.40.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 6c7c3366c2873f9770a127b1797cbc252edfd502 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Fri, 9 Jul 2021 03:13:26 +0800 Subject: [PATCH 362/764] optimizing varargs on functions passed as parameters (#1042) --- src/transformation/utils/scope.ts | 4 +++- test/unit/__snapshots__/spread.spec.ts.snap | 15 +++++++++++++++ test/unit/spread.spec.ts | 11 +++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 72b267e2a..dcb877db7 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -93,7 +93,9 @@ export function popScope(context: TransformationContext): Scope { } function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { - return symbol?.declarations?.some(d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode)); + return symbol?.declarations?.some( + d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent) + ); } // Checks for references to local functions which haven't been defined yet, diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index f16bc746a..85d1c4ac3 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -66,6 +66,21 @@ end return ____exports" `; +exports[`vararg spread optimization curry 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, fn, ...) + return fn(nil, ...) + end + return test( + nil, + function(____, arg) return arg end, + \\"foobar\\" + ) +end +return ____exports" +`; + exports[`vararg spread optimization finally clause 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index a395ef2bd..e65ee7ee7 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -230,6 +230,17 @@ describe("vararg spread optimization", () => { .expectLuaToMatchSnapshot() .expectToEqual("b"); }); + + test("curry", () => { + util.testFunction` + function test(fn: (...args: A) => void, ...args: A) { + return fn(...args); + } + return test((arg: string) => arg, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); }); describe("vararg spread de-optimization", () => { From d79a2078d64336188f4708fef1b5c5cd9ee64ca5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 9 Jul 2021 10:04:17 +0200 Subject: [PATCH 363/764] Optional chaining (#1041) * Optional chaining * Added some more possibly undefined test cases * Added extra test and fixed bug * Removed double work from transformNullishCoalescingExpression * fix prettier --- src/LuaLib.ts | 3 + src/lualib/OptionalChainAccess.ts | 10 ++ src/lualib/OptionalFunctionCall.ts | 10 ++ src/lualib/OptionalMethodCall.ts | 14 ++ src/transformation/utils/diagnostics.ts | 2 - src/transformation/visitors/access.ts | 25 ++- .../visitors/binary-expression/index.ts | 17 +- src/transformation/visitors/call.ts | 95 ++++++++--- test/transpile/module-resolution.spec.ts | 1 - test/unit/optionalChaining.spec.ts | 161 +++++++++++++++++- 10 files changed, 296 insertions(+), 42 deletions(-) create mode 100644 src/lualib/OptionalChainAccess.ts create mode 100644 src/lualib/OptionalFunctionCall.ts create mode 100644 src/lualib/OptionalMethodCall.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index d98b78044..e1a8d9efd 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -57,6 +57,9 @@ export enum LuaLibFeature { ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", + OptionalChainAccess = "OptionalChainAccess", + OptionalFunctionCall = "OptionalFunctionCall", + OptionalMethodCall = "OptionalMethodCall", ParseFloat = "ParseFloat", ParseInt = "ParseInt", Set = "Set", diff --git a/src/lualib/OptionalChainAccess.ts b/src/lualib/OptionalChainAccess.ts new file mode 100644 index 000000000..7924aa282 --- /dev/null +++ b/src/lualib/OptionalChainAccess.ts @@ -0,0 +1,10 @@ +function __TS__OptionalChainAccess( + this: void, + table: Record, + key: TKey +): TReturn | undefined { + if (table) { + return table[key]; + } + return undefined; +} diff --git a/src/lualib/OptionalFunctionCall.ts b/src/lualib/OptionalFunctionCall.ts new file mode 100644 index 000000000..85b52a047 --- /dev/null +++ b/src/lualib/OptionalFunctionCall.ts @@ -0,0 +1,10 @@ +function __TS__OptionalFunctionCall( + this: void, + f: (this: void, ...args: [...TArgs]) => TReturn, + ...args: [...TArgs] +): TReturn | undefined { + if (f) { + return f(...args); + } + return undefined; +} diff --git a/src/lualib/OptionalMethodCall.ts b/src/lualib/OptionalMethodCall.ts new file mode 100644 index 000000000..8829e4a4d --- /dev/null +++ b/src/lualib/OptionalMethodCall.ts @@ -0,0 +1,14 @@ +function __TS__OptionalMethodCall( + this: void, + table: Record TReturn>, + methodName: string, + ...args: [...TArgs] +): TReturn | undefined { + if (table) { + const method = table[methodName]; + if (method) { + return method.call(table, ...args); + } + } + return undefined; +} diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index fcc37b6f0..16a0c7395 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -143,5 +143,3 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); - -export const optionalChainingNotSupported = createErrorDiagnosticFactory("Optional chaining is not supported yet."); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index a41c4462f..8b795426b 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationRemoved, invalidMultiReturnAccess, optionalChainingNotSupported } from "../utils/diagnostics"; +import { annotationRemoved, invalidMultiReturnAccess } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; @@ -53,6 +53,10 @@ export const transformElementAccessExpression: FunctionVisitor = (node, context) => { const right = lua.createStringLiteral(node.right.text, node.right); const left = context.transformExpression(node.left); diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 0b4533a4a..ce73a7a70 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -54,7 +54,7 @@ export function transformBinaryOperation( if (operator === ts.SyntaxKind.QuestionQuestionToken) { assert(ts.isBinaryExpression(node)); - return transformNullishCoalescingExpression(context, node); + return transformNullishCoalescingExpression(context, node, left, right); } let luaOperator = simpleOperatorsToLua[operator]; @@ -162,7 +162,9 @@ export function transformBinaryExpressionStatement( function transformNullishCoalescingExpression( context: TransformationContext, - node: ts.BinaryExpression + node: ts.BinaryExpression, + transformedLeft: lua.Expression, + transformedRight: lua.Expression ): lua.Expression { const lhsType = context.checker.getTypeAtLocation(node.left); @@ -181,20 +183,15 @@ function transformNullishCoalescingExpression( // if ____ == nil then return rhs else return ____ end const ifStatement = lua.createIfStatement( nilComparison, - lua.createBlock([lua.createReturnStatement([context.transformExpression(node.right)])]), + lua.createBlock([lua.createReturnStatement([transformedRight])]), lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]) ); // (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs) return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [ - context.transformExpression(node.left), + transformedLeft, ]); } else { // lhs or rhs - return lua.createBinaryExpression( - context.transformExpression(node.left), - context.transformExpression(node.right), - lua.SyntaxKind.OrOperator, - node - ); + return lua.createBinaryExpression(transformedLeft, transformedRight, lua.SyntaxKind.OrOperator, node); } } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index f7a1b004e..ced618c4c 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -148,18 +148,29 @@ export function transformContextualCallExpression( node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray, signature?: ts.Signature -): lua.Expression { +): lua.CallExpression | lua.MethodCallExpression { const left = ts.isCallExpression(node) ? node.expression : node.tag; if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { // table:name() const table = context.transformExpression(left.expression); - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformArguments(context, args, signature), - node - ); + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + table, + lua.createStringLiteral(left.name.text, left.name), + ...transformArguments(context, args, signature) + ); + } else { + return lua.createMethodCallExpression( + table, + lua.createIdentifier(left.name.text, left.name), + transformArguments(context, args, signature), + node + ); + } } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { return transformToImmediatelyInvokedFunctionExpression( @@ -183,7 +194,10 @@ export function transformContextualCallExpression( } } -function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { +function transformPropertyCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { @@ -197,17 +211,22 @@ function transformPropertyCall(context: TransformationContext, node: PropertyCal // table:name() return transformContextualCallExpression(context, node, node.arguments, signature); } else { - const table = context.transformExpression(node.expression.expression); - // table.name() - const name = node.expression.name.text; - const callPath = lua.createTableIndexExpression(table, lua.createStringLiteral(name), node.expression); + const callPath = context.transformExpression(node.expression); const parameters = transformArguments(context, node.arguments, signature); - return lua.createCallExpression(callPath, parameters, node); + + if (ts.isOptionalChain(node)) { + return transformLuaLibFunction(context, LuaLibFeature.OptionalFunctionCall, node, callPath, ...parameters); + } else { + return lua.createCallExpression(callPath, parameters, node); + } } } -function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { +function transformElementCall( + context: TransformationContext, + node: ts.CallExpression +): lua.CallExpression | lua.MethodCallExpression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { @@ -229,11 +248,12 @@ export const transformCallExpression: FunctionVisitor = (node const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); const wrapTupleReturn = isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; - const wrapResult = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInTable = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInOptional = ts.isOptionalChain(node); const builtinResult = transformBuiltinCallExpression(context, node); if (builtinResult) { - return wrapResult ? wrapInTable(builtinResult) : builtinResult; + return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; } if (isOperatorMapping(context, node)) { @@ -274,12 +294,13 @@ export const transformCallExpression: FunctionVisitor = (node } const result = transformPropertyCall(context, node as PropertyCallExpression); - return wrapResult ? wrapInTable(result) : result; + // transformPropertyCall already wraps optional so no need to do so here + return wrapResultInTable ? wrapInTable(result) : result; } if (ts.isElementAccessExpression(node.expression)) { const result = transformElementCall(context, node); - return wrapResult ? wrapInTable(result) : result; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, result, node); } const signature = context.checker.getResolvedSignature(node); @@ -309,5 +330,41 @@ export const transformCallExpression: FunctionVisitor = (node } const callExpression = lua.createCallExpression(callPath, parameters, node); - return wrapResult ? wrapInTable(callExpression) : callExpression; + return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, callExpression, node); }; + +function wrapIfRequired( + context: TransformationContext, + shouldWrapInTable: boolean, + shouldWrapOptional: boolean, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.Node +): lua.Expression { + const wrappedOptional = shouldWrapOptional ? wrapOptionalCall(context, call, node) : call; + return shouldWrapInTable ? wrapInTable(wrappedOptional) : wrappedOptional; +} + +function wrapOptionalCall( + context: TransformationContext, + call: lua.CallExpression | lua.MethodCallExpression, + node: ts.Node +): lua.CallExpression { + if (lua.isMethodCallExpression(call)) { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalMethodCall, + node, + call.prefixExpression, + lua.createStringLiteral(call.name.text), + ...call.params + ); + } else { + return transformLuaLibFunction( + context, + LuaLibFeature.OptionalFunctionCall, + node, + call.expression, + ...call.params + ); + } +} diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 6c5bff4a2..872bd47c7 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -288,7 +288,6 @@ describe("module resolution with tsx", () => { test("project with tsx files", () => { util.testProject(path.join(projectPath, "tsconfig.json")) .setMainFileName(path.join(projectPath, "main.tsx")) - .debug() .expectToEqual({ result: "hello from other.tsx", indexResult: "hello from dir/index.tsx", diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 33d0802db..26deff810 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,9 +1,160 @@ -import { optionalChainingNotSupported } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; -test("Diagnostic optional chaining is not supported yet", () => { +test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` - let func = (value: number) => value != 0 ? {value} : undefined; - return func(1)?.value; - `.expectToHaveDiagnostics([optionalChainingNotSupported.code]); + const obj: any = ${value}; + return obj?.foo; + `.expectToMatchJsResult(); +}); + +test("long optional chain", () => { + util.testFunction` + const a = { b: { c: { d: { e: { f: "hello!"}}}}}; + return a.b?.c?.d.e.f; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar; + `.expectToMatchJsResult(); +}); + +test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])( + "nested optional chaining combined with coalescing (%p)", + value => { + util.testFunction` + const obj: { foo?: { bar?: string } } | undefined = ${value}; + return obj?.foo?.bar ?? "not found"; + `.expectToMatchJsResult(); + } +); + +test.each(["[1, 2, 3, 4]", "undefined"])("optional array access (%p)", value => { + util.testFunction` + const arr: number[] | undefined = ${value}; + return arr?.[2]; + `.expectToMatchJsResult(); +}); + +test.each(["[1, [2, [3, [4, 5]]]]", "[1, [2, [3, undefined]]] ", "[1, undefined]"])( + "optional element access nested (%p)", + value => { + util.testFunction` + const arr: [number, [number, [number, [number, number] | undefined]]] | [number, undefined] = ${value}; + return arr[1]?.[1][1]?.[0]; + `.expectToMatchJsResult(); + } +); + +test.each(["{ }", "{ a: { } }", "{ a: { b: [{ c: 10 }] } }"])( + "optional nested element access properties (%p)", + value => { + util.testFunction` + const obj: {a?: {b?: Array<{c: number }> } } = ${value}; + return [obj["a"]?.["b"]?.[0]?.["c"] ?? "not found", obj["a"]?.["b"]?.[2]?.["c"] ?? "not found"]; + `.expectToMatchJsResult(); + } +); + +test("optional element function calls", () => { + util.testFunction` + const obj: { value: string; foo?(this: void, v: number): number; bar?(this: void, v: number): number; } = { + value: "foobar", + foo: (v: number) => v + 10 + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.(5) ?? obj[fooKey]?.(15); + `.expectToMatchJsResult(); +}); + +test("optional element access method calls", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + const fooKey = "foo"; + const barKey = "bar"; + return obj[barKey]?.("bar?") ?? obj[fooKey]?.("foo?"); + `.expectToMatchJsResult(); +}); + +test("no side effects", () => { + util.testFunction` + function getFoo(): { foo: number } | undefined { + return { foo: 42 }; + } + let barCalls = 0; + function getBar(): { bar: number } | undefined { + barCalls += 1; + return undefined; + } + const result = getFoo()?.foo ?? getBar()?.bar; + return { result, barCalls }; + `.expectToMatchJsResult(); +}); + +describe("optional chaining function calls", () => { + test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { + util.testFunction` + const f: (() => number) | undefined = ${value}; + return f?.(); + `.expectToMatchJsResult(); + }); + + test("methods present", () => { + util.testFunction` + const objWithMethods = { + foo() { + return 3; + }, + bar(this: void) { + return 5; + } + }; + + return [objWithMethods?.foo(), objWithMethods?.bar()]; + `.expectToMatchJsResult(); + }); + + test("object with method can be undefined", () => { + util.testFunction` + const objWithMethods: { foo: () => number, bar: (this: void) => number } | undefined = undefined; + return [objWithMethods?.foo() ?? "no foo", objWithMethods?.bar() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("nested optional method call", () => { + util.testFunction` + type typeWithOptional = { a?: { b: { c: () => number } } }; + + const objWithMethods: typeWithOptional = {}; + const objWithMethods2: typeWithOptional = { a: { b: { c: () => 4 } } }; + + return { + expectNil: objWithMethods.a?.b.c(), + expectFour: objWithMethods2.a?.b.c() + }; + `.expectToMatchJsResult(); + }); + + test("methods are undefined", () => { + util.testFunction` + const objWithMethods: { foo?: () => number, bar?: (this: void) => number } = {}; + return [objWithMethods.foo?.() ?? "no foo", objWithMethods.bar?.() ?? "no bar"]; + `.expectToMatchJsResult(); + }); + + test("optional method of optional method result", () => { + util.testFunction` + const obj: { a?: () => {b: {c?: () => number }}} = {}; + const obj2: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: {}})}; + const obj3: { a?: () => {b: {c?: () => number }}} = { a: () => ({b: { c: () => 5 }})}; + + return [obj.a?.().b.c?.() ?? "nil", obj2.a?.().b.c?.() ?? "nil", obj3.a?.().b.c?.() ?? "nil"]; + `.expectToMatchJsResult(); + }); }); From 213b204c7702bae70c3eb71172e8c7cabb73eff0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 11 Jul 2021 10:49:15 +0200 Subject: [PATCH 364/764] Bundle librarymode error & tstlverbose CLI flag (#1043) * Disallow bundling with buildmode library * Add tstl verbose CLI flag * Add tstlverbose to CLI parser --- package-lock.json | 14 ++--- package.json | 2 +- src/CompilerOptions.ts | 15 +++--- src/cli/parse.ts | 5 ++ src/transformation/context/context.ts | 3 +- src/transpilation/diagnostics.ts | 5 ++ src/transpilation/resolve.ts | 19 ++++++- src/transpilation/transpile.ts | 17 ++++++ src/transpilation/transpiler.ts | 25 ++++++++- src/typescript-internal.d.ts | 3 ++ test/cli/parse.spec.ts | 2 + .../__snapshots__/project.spec.ts.snap | 20 +++++++ test/transpile/module-resolution.spec.ts | 19 ------- test/transpile/project.spec.ts | 20 +++++++ test/transpile/transformers/fixtures.ts | 52 ++++++++++--------- test/unit/__snapshots__/bundle.spec.ts.snap | 2 + test/unit/bundle.spec.ts | 8 ++- test/unit/modules/resolution.spec.ts | 10 ++-- test/util.ts | 38 +++++++------- 19 files changed, 191 insertions(+), 88 deletions(-) diff --git a/package-lock.json b/package-lock.json index c3acb08d1..0d5b08870 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.0.5", + "prettier": "^2.3.2", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" }, @@ -9554,9 +9554,9 @@ } }, "node_modules/prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -19259,9 +19259,9 @@ "dev": true }, "prettier": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", - "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true }, "pretty-format": { diff --git a/package.json b/package.json index f96178a81..a45f56929 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "jest-circus": "^25.1.0", "lua-types": "^2.8.0", "lua-wasm-bindings": "^0.2.2", - "prettier": "^2.0.5", + "prettier": "^2.3.2", "ts-jest": "^26.3.0", "ts-node": "^8.6.2" } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index e06adc1f3..0610d26b3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,13 +1,9 @@ import * as ts from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; -type KnownKeys = { [K in keyof T]: string extends K ? never : number extends K ? never : K } extends { - [K in keyof T]: infer U; -} - ? U - : never; - -type OmitIndexSignature> = Pick>; +type OmitIndexSignature = { + [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; +}; export interface TransformerImport { transform: string; @@ -35,6 +31,7 @@ export type CompilerOptions = OmitIndexSignature & { sourceMapTraceback?: boolean; luaPlugins?: LuaPluginImport[]; plugins?: Array; + tstlVerbose?: boolean; [option: string]: any; }; @@ -73,5 +70,9 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.usingLuaBundleWithInlineMightGenerateDuplicateCode()); } + if (options.luaBundle && options.buildMode === BuildMode.Library) { + diagnostics.push(diagnosticFactories.cannotBundleLibrary()); + } + return diagnostics; } diff --git a/src/cli/parse.ts b/src/cli/parse.ts index d29bf4e83..b7ed906e3 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -73,6 +73,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "List of TypeScriptToLua plugins.", type: "object", }, + { + name: "tstlVerbose", + description: "Provide verbose output useful for diagnosing problems.", + type: "boolean", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 4ee4515c4..4dbcf9e10 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -27,8 +27,7 @@ export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { export class TransformationContext { public readonly diagnostics: ts.Diagnostic[] = []; - public readonly checker: DiagnosticsProducingTypeChecker = (this - .program as any).getDiagnosticsProducingTypeChecker(); + public readonly checker: DiagnosticsProducingTypeChecker = this.program.getDiagnosticsProducingTypeChecker(); public readonly resolver: EmitResolver; public readonly options: CompilerOptions = this.program.getCompilerOptions(); diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index bfae6b140..4b57c329d 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -48,3 +48,8 @@ export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDi "Using 'luaBundle' with 'luaLibImport: \"inline\"' might generate duplicate code. " + "It is recommended to use 'luaLibImport: \"require\"'.", })); + +export const cannotBundleLibrary = createDiagnosticFactory( + () => + 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' +); diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index a9b6b4e1a..5334c0ca7 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -5,9 +5,9 @@ import * as fs from "fs"; import { EmitHost, ProcessedFile } from "./utils"; import { SourceNode } from "source-map"; import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./transpiler"; -import { formatPathToLuaPath, trimExtension } from "../utils"; +import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; -import { BuildMode } from "../CompilerOptions"; +import { BuildMode, CompilerOptions } from "../CompilerOptions"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], @@ -24,9 +24,14 @@ interface ResolutionResult { export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { const outFiles: ProcessedFile[] = [...files]; const diagnostics: ts.Diagnostic[] = []; + const options = program.getCompilerOptions() as CompilerOptions; // Resolve dependencies for all processed files for (const file of files) { + if (options.tstlVerbose) { + console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); + } + const resolutionResult = resolveFileDependencies(file, program, emitHost); outFiles.push(...resolutionResult.resolvedFiles); diagnostics.push(...resolutionResult.diagnostics); @@ -38,6 +43,7 @@ export function resolveDependencies(program: ts.Program, files: ProcessedFile[], function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { const dependencies: ProcessedFile[] = []; const diagnostics: ts.Diagnostic[] = []; + const options = program.getCompilerOptions() as CompilerOptions; for (const required of findRequiredPaths(file.code)) { // Do no resolve lualib @@ -57,6 +63,10 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH const fileDir = path.dirname(file.fileName); const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); if (resolvedDependency) { + if (options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + } + // Figure out resolved require path and dependency output path const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); @@ -100,6 +110,11 @@ function resolveDependency( program: ts.Program, emitHost: EmitHost ): string | undefined { + const options = program.getCompilerOptions() as CompilerOptions; + if (options.tstlVerbose) { + console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); + } + // Check if file is a file in the project const resolvedPath = path.join(fileDirectory, dependency); diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index 0d3071f73..d78162fd8 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -27,6 +27,10 @@ export function getProgramTranspileResult( ): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; + if (options.tstlVerbose) { + console.log("Parsing project settings"); + } + const diagnostics = validateOptions(options); let transpiledFiles: ProcessedFile[] = []; @@ -57,13 +61,26 @@ export function getProgramTranspileResult( } const plugins = getPlugins(program, diagnostics, customPlugins); + + if (options.tstlVerbose) { + console.log(`Successfully loaded ${plugins.length} plugins`); + } + const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { + if (options.tstlVerbose) { + console.log(`Transforming ${sourceFile.fileName}`); + } + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); if (!options.noEmit && !options.emitDeclarationOnly) { + if (options.tstlVerbose) { + console.log(`Printing ${sourceFile.fileName}`); + } + const printResult = printer(program, emitHost, sourceFile.fileName, file); transpiledFiles.push({ sourceFiles: [sourceFile], diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 2dc5a9fc7..b19790b37 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { isBundleEnabled } from "../CompilerOptions"; +import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; @@ -29,6 +29,7 @@ export class Transpiler { public emit(emitOptions: EmitOptions): EmitResult { const { program, writeFile = this.emitHost.writeFile } = emitOptions; + const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose; const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( this.emitHost, writeFile, @@ -37,15 +38,27 @@ export class Transpiler { const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); + if (verbose) { + console.log("Emitting output"); + } + const options = program.getCompilerOptions(); const emitBOM = options.emitBOM ?? false; for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) { + if (verbose) { + console.log(`Emitting ${normalizeSlashes(outputPath)}`); + } + writeFile(outputPath, code, emitBOM, undefined, sourceFiles); if (options.sourceMap && sourceMap !== undefined) { writeFile(outputPath + ".map", sourceMap, emitBOM, undefined, sourceFiles); } } + if (verbose) { + console.log("Emit finished!"); + } + return { diagnostics, emitSkipped: emitPlan.length === 0 }; } @@ -54,10 +67,18 @@ export class Transpiler { diagnostics: ts.Diagnostic[], files: ProcessedFile[] ): { emitPlan: EmitFile[] } { - const options = program.getCompilerOptions(); + const options = program.getCompilerOptions() as CompilerOptions; + + if (options.tstlVerbose) { + console.log("Constructing emit plan"); + } const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); if (lualibRequired) { + if (options.tstlVerbose) { + console.log("Including lualib bundle"); + } + // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 7444d89d7..7bfd309ac 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -1,3 +1,5 @@ +import { DiagnosticsProducingTypeChecker } from "./transformation/context"; + export {}; declare module "typescript" { @@ -14,6 +16,7 @@ declare module "typescript" { interface Program { getCommonSourceDirectory(): string; + getDiagnosticsProducingTypeChecker(): DiagnosticsProducingTypeChecker; } interface CompilerOptions { diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index f66b97766..f157c9a21 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -104,6 +104,8 @@ describe("command line", () => { ["noHeader", "true", { noHeader: true }], ["sourceMapTraceback", "false", { sourceMapTraceback: false }], ["sourceMapTraceback", "true", { sourceMapTraceback: true }], + ["tstlVerbose", "true", { tstlVerbose: true }], + ["tstlVerbose", "false", { tstlVerbose: false }], ["buildMode", "default", { buildMode: tstl.BuildMode.Default }], ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 623480405..1effba209 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -1,5 +1,25 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`should give verbose output 1`] = ` +Array [ + "Parsing project settings", + "Successfully loaded 0 plugins", + "Transforming /test/transpile/project/otherFile.ts", + "Printing /test/transpile/project/otherFile.ts", + "Transforming /test/transpile/project/index.ts", + "Printing /test/transpile/project/index.ts", + "Constructing emit plan", + "Resolving dependencies for /test/transpile/project/otherFile.ts", + "Resolving dependencies for /test/transpile/project/index.ts", + "Resolving \\"./otherFile\\" from /test/transpile/project", + "Resolved ./otherFile to /test/transpile/project/otherFile.ts", + "Emitting output", + "Emitting /test/transpile/project/otherFile.lua", + "Emitting /test/transpile/project/index.lua", + "Emit finished!", +] +`; + exports[`should transpile 1`] = ` Array [ Object { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 872bd47c7..b995e75a5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -230,25 +230,6 @@ describe("module resolution in library mode", () => { expect(file.lua).not.toContain('require("lua_modules'); } }); - - test("bundle works in library mode because no external dependencies", () => { - const projectPath = path.resolve(__dirname, "module-resolution", "project-with-lua-sources"); - const mainFile = path.join(projectPath, "main.ts"); - - const { transpiledFiles } = util - .testProject(path.join(projectPath, "tsconfig.json")) - .setMainFileName(path.join(projectPath, "main.ts")) - .setOptions({ buildMode: tstl.BuildMode.Library, luaBundle: "bundle.lua", luaBundleEntry: mainFile }) - .expectToEqual({ - funcFromLuaFile: "lua file in subdir", - funcFromSubDirLuaFile: "lua file in subdir", - }) - .getLuaResult(); - - for (const file of transpiledFiles) { - expect(file.lua).not.toContain('require("lua_modules'); - } - }); }); describe("module resolution project with dependencies built by tstl library mode", () => { diff --git a/test/transpile/project.spec.ts b/test/transpile/project.spec.ts index 965c834d7..49234975b 100644 --- a/test/transpile/project.spec.ts +++ b/test/transpile/project.spec.ts @@ -1,4 +1,5 @@ import * as path from "path"; +import { normalizeSlashes } from "../../src/utils"; import * as util from "../util"; test("should transpile", () => { @@ -13,3 +14,22 @@ test("should transpile", () => { transpiledFiles.map(f => ({ filePath: path.relative(projectDir, f.outPath), lua: f.lua })) ).toMatchSnapshot(); }); + +test("should give verbose output", () => { + // Capture console logs + const consoleLogs: string[] = []; + const originalLog = console.log; + console.log = (...args: any[]) => { + consoleLogs.push(args.map(a => a.toString().replace(normalizeSlashes(process.cwd()), "")).join(",")); + }; + + const projectDir = path.join(__dirname, "project"); + util.testProject(path.join(projectDir, "tsconfig.json")) + .setMainFileName(path.join(projectDir, "index.ts")) + .setOptions({ tstlVerbose: true }) + .expectToHaveNoDiagnostics(); + + console.log = originalLog; + + expect(consoleLogs).toMatchSnapshot(); +}); diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index a69829d5d..dff7667be 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -6,22 +6,25 @@ import { visitAndReplace } from "./utils"; export const program = (program: ts.Program, options: { value: any }): ts.TransformerFactory => checker(program.getTypeChecker(), options); -export const config = ({ value }: { value: any }): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); - }); +export const config = + ({ value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); -export const checker = ( - checker: ts.TypeChecker, - { value }: { value: any } -): ts.TransformerFactory => context => file => - visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node) || !node.expression) return; - const type = checker.getTypeAtLocation(node.expression); - if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; - return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); - }); +export const checker = + (checker: ts.TypeChecker, { value }: { value: any }): ts.TransformerFactory => + context => + file => + visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node) || !node.expression) return; + const type = checker.getTypeAtLocation(node.expression); + if ((type.flags & ts.TypeFlags.BooleanLiteral) === 0) return; + return ts.factory.updateReturnStatement(node, value ? ts.factory.createTrue() : ts.factory.createFalse()); + }); export const raw: ts.TransformerFactory = context => file => visitAndReplace(context, file, node => { @@ -29,12 +32,13 @@ export const raw: ts.TransformerFactory = context => file => return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); }); -export const compilerOptions = ( - options: tstl.CompilerOptions -): ts.TransformerFactory => context => file => { - assert(options.plugins?.length === 1); - return visitAndReplace(context, file, node => { - if (!ts.isReturnStatement(node)) return; - return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); - }); -}; +export const compilerOptions = + (options: tstl.CompilerOptions): ts.TransformerFactory => + context => + file => { + assert(options.plugins?.length === 1); + return visitAndReplace(context, file, node => { + if (!ts.isReturnStatement(node)) return; + return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); + }); + }; diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 84c10f3d5..20d4ec657 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -2,6 +2,8 @@ exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; +exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle probjects with\\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; + exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; exports[`no entry point: diagnostics 1`] = `"error TSTL: 'luaBundleEntry' is required when 'luaBundle' is enabled."`; diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index f961dddb0..ddc678f34 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -1,4 +1,4 @@ -import { LuaLibImportKind } from "../../src"; +import { BuildMode, LuaLibImportKind } from "../../src"; import * as diagnosticFactories from "../../src/transpilation/diagnostics"; import * as util from "../util"; @@ -120,3 +120,9 @@ test("luaEntry doesn't exist", () => { .setEntryPoint("entry.ts") .expectDiagnosticsToMatchSnapshot([diagnosticFactories.couldNotFindBundleEntryPoint.code], true); }); + +test("bundling not allowed for buildmode library", () => { + util.testBundle`` + .setOptions({ buildMode: BuildMode.Library }) + .expectDiagnosticsToMatchSnapshot([diagnosticFactories.cannotBundleLibrary.code], true); +}); diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 791ae06b5..b2c7194b5 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -3,10 +3,12 @@ import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; -const expectToRequire = (expected: string): util.TapCallback => builder => { - const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; - expect(requiredPath).toBe(expected); -}; +const expectToRequire = + (expected: string): util.TapCallback => + builder => { + const [, requiredPath] = builder.getMainLuaCodeChunk().match(requireRegex) ?? []; + expect(requiredPath).toBe(expected); + }; test.each([ { diff --git a/test/util.ts b/test/util.ts index 39259e784..b493f43e0 100644 --- a/test/util.ts +++ b/test/util.ts @@ -239,8 +239,9 @@ export abstract class TestBuilder { @memoize public getMainJsCodeChunk(): string { const { transpiledFiles } = this.getJsResult(); - const code = transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === this.mainFileName)) - ?.js; + const code = transpiledFiles.find(({ sourceFiles }) => + sourceFiles.some(f => f.fileName === this.mainFileName) + )?.js; assert(code !== undefined); const header = this.jsHeader ? `${this.jsHeader.trimRight()}\n` : ""; @@ -557,25 +558,24 @@ class ProjectTestBuilder extends ModuleTestBuilder { } } -const createTestBuilderFactory = ( - builder: new (_tsCode: string) => T, - serializeSubstitutions: boolean -) => (...args: [string] | [TemplateStringsArray, ...any[]]): T => { - let tsCode: string; - if (typeof args[0] === "string") { - expect(serializeSubstitutions).toBe(false); - tsCode = args[0]; - } else { - let [raw, ...substitutions] = args; - if (serializeSubstitutions) { - substitutions = substitutions.map(s => formatCode(s)); - } +const createTestBuilderFactory = + (builder: new (_tsCode: string) => T, serializeSubstitutions: boolean) => + (...args: [string] | [TemplateStringsArray, ...any[]]): T => { + let tsCode: string; + if (typeof args[0] === "string") { + expect(serializeSubstitutions).toBe(false); + tsCode = args[0]; + } else { + let [raw, ...substitutions] = args; + if (serializeSubstitutions) { + substitutions = substitutions.map(s => formatCode(s)); + } - tsCode = String.raw(Object.assign([], { raw }), ...substitutions); - } + tsCode = String.raw(Object.assign([], { raw }), ...substitutions); + } - return new builder(tsCode); -}; + return new builder(tsCode); + }; export const testBundle = createTestBuilderFactory(BundleTestBuilder, false); export const testModule = createTestBuilderFactory(ModuleTestBuilder, false); From 1ab13ceaf028f01d6f7ce08b19332cecc14e6b73 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 11 Jul 2021 14:03:54 +0200 Subject: [PATCH 365/764] CHANGELOG 0.41.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a81be4d1..ce877a1d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 0.41.0 + +- Added support for [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) `a?.b`, `a?.[b]` and `a?.()`. +- Added an error when trying to bundle a library (`"buildmode": "library"`) project. +- Added `--tstlVerbose` CLI flag to help with diagnosing problems. +- Fixed a bug where vararg (`...`) was not correctly optimized. +- Fixed .tsx files not correctly being resolved. +- Fixed a bug where files were emitted to the wrong location if no `outDir` was specified. + ## 0.40.0 - Added support for using external Lua code in your project. This means you can create and install node_modules packages containing Lua code. It also lets you include Lua source files as part of your source files. Used Lua will automatically be added to your output. For more information, see the [External Lua Code](https://typescripttolua.github.io/docs/external-lua-code) page in the docs. From a879b971cc1605b70353d6c2b868d6036221896d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 11 Jul 2021 14:26:34 +0200 Subject: [PATCH 366/764] 0.41.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d5b08870..35fb97cf6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index a45f56929..548b86ef2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.40.1", + "version": "0.41.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f034d9f322a380facea0b39490ffc26d3ff9a41d Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 17 Jul 2021 02:50:03 +0800 Subject: [PATCH 367/764] fixed vararg optimization logic (#1046) --- src/transformation/utils/scope.ts | 6 ++-- test/unit/__snapshots__/spread.spec.ts.snap | 33 +++++++++++++++++++++ test/unit/spread.spec.ts | 24 +++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index dcb877db7..53169765a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -92,9 +92,9 @@ export function popScope(context: TransformationContext): Scope { return scope; } -function isDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { +function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { return symbol?.declarations?.some( - d => findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) && !ts.isParameter(d.parent) + d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) ); } @@ -109,7 +109,7 @@ export function hasReferencedUndefinedLocalFunction(context: TransformationConte if ( !scope.functionDefinitions?.has(symbolId) && type.getCallSignatures().length > 0 && - isDeclaredInScope(type.symbol, scope.node) + isHoistableFunctionDeclaredInScope(type.symbol, scope.node) ) { return true; } diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index 85d1c4ac3..0b49fd80a 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -81,6 +81,24 @@ end return ____exports" `; +exports[`vararg spread optimization curry with indirect type 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, obj, ...) + local fn = obj.fn + return fn(nil, ...) + end + return test( + nil, + { + fn = function(____, arg) return arg end + }, + \\"foobar\\" + ) +end +return ____exports" +`; + exports[`vararg spread optimization finally clause 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -105,6 +123,21 @@ end return ____exports" `; +exports[`vararg spread optimization function type declared inside scope 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function test(self, ...) + local function fn(____, ...) + local args = {...} + return args[1] + end + return fn(nil, ...) + end + test(nil, \\"foobar\\") +end +return ____exports" +`; + exports[`vararg spread optimization if statement 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index e65ee7ee7..5d7ed93a7 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -241,6 +241,30 @@ describe("vararg spread optimization", () => { .expectLuaToMatchSnapshot() .expectToMatchJsResult(); }); + + test("curry with indirect type", () => { + util.testFunction` + function test(obj: {fn: (...args: A) => void}, ...args: A) { + const fn = obj.fn; + return fn(...args); + } + return test({fn: (arg: string) => arg}, "foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); + + test("function type declared inside scope", () => { + util.testFunction` + function test(...args: A) { + const fn: (...args: A) => A[0] = (...args) => args[0]; + return fn(...args); + } + test("foobar"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); }); describe("vararg spread de-optimization", () => { From 987899c8acdaf14668d234a8470c9f29a33f7459 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sat, 31 Jul 2021 08:26:20 -0700 Subject: [PATCH 368/764] JSX support (#1052) * JSX support * Add jsx and jsxFrag pragma support * Remove unneeded flattenSpreadExpressions call. Typescript doesn't actually "spread out" jsx spread children, even though the syntax is supported. * Changes for PR. * Add license for functions copied from sucrase * Remove jsx snapshot test Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> --- src/CompilerOptions.ts | 5 + src/transformation/utils/annotations.ts | 2 + src/transformation/visitors/index.ts | 2 + src/transformation/visitors/jsx/jsx.ts | 264 +++++++++++++ src/transformation/visitors/jsx/xhtml.ts | 256 +++++++++++++ .../visitors/language-extensions/multi.ts | 2 +- src/transformation/visitors/literal.ts | 144 ++++--- src/transpilation/diagnostics.ts | 2 + test/unit/jsx.spec.ts | 361 ++++++++++++++++++ 9 files changed, 976 insertions(+), 62 deletions(-) create mode 100644 src/transformation/visitors/jsx/jsx.ts create mode 100644 src/transformation/visitors/jsx/xhtml.ts create mode 100644 test/unit/jsx.spec.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 0610d26b3..9fc232f68 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; type OmitIndexSignature = { @@ -74,5 +75,9 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.cannotBundleLibrary()); } + if (options.jsx && options.jsx !== JsxEmit.React) { + diagnostics.push(diagnosticFactories.unsupportedJsxEmit()); + } + return diagnostics; } diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 212f30416..d07df2808 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -17,6 +17,8 @@ export enum AnnotationKind { NoSelfInFile = "noSelfInFile", Vararg = "vararg", ForRange = "forRange", + Jsx = "jsx", + JsxFrag = "jsxFrag", } export interface Annotation { diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index b9983ae31..b05527364 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -40,6 +40,7 @@ import { transformTypeOfExpression } from "./typeof"; import { typescriptVisitors } from "./typescript"; import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; import { transformVariableStatement } from "./variable-declaration"; +import { jsxVisitors } from "./jsx/jsx"; const transformEmptyStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => @@ -48,6 +49,7 @@ const transformParenthesizedExpression: FunctionVisitor= charCodes.a && ch <= charCodes.z) || name.includes("-") || name.includes(":"); +} + +function transformTagName(name: ts.JsxTagNameExpression, context: TransformationContext): lua.Expression { + if (ts.isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { + return lua.createStringLiteral(ts.idText(name), name); + } else { + return context.transformExpression(name); + } +} + +function transformJsxChildren( + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression[] | undefined { + if (!children) return undefined; + + return children + .map(child => { + if (ts.isJsxText(child)) { + return processJsxText(child); + } + if (ts.isJsxExpression(child)) { + return child.expression; + } + return child; + }) + .filter(child => child !== undefined) + .map(child => context.transformExpression(child!)); +} + +function createJsxFactoryCall( + tagName: lua.Expression, + props: lua.Expression | undefined, + tsChildren: ts.NodeArray | undefined, + tsOriginal: ts.Node, + context: TransformationContext +): lua.Expression { + const transformedChildren = transformJsxChildren(tsChildren, context); + const jsxFactory = getJsxFactory(tsOriginal, context); + + const args = [tagName]; + if (props) { + args.push(props); + } + if (transformedChildren && transformedChildren.length > 0) { + if (!props) { + args.push(lua.createNilLiteral()); + } + args.push(...transformedChildren); + } + return lua.createCallExpression(jsxFactory, args, tsOriginal); +} + +function transformJsxOpeningLikeElement( + node: ts.JsxOpeningLikeElement, + children: ts.NodeArray | undefined, + context: TransformationContext +): lua.Expression { + const tagName = transformTagName(node.tagName, context); + const props = + node.attributes.properties.length !== 0 ? transformJsxAttributes(node.attributes, context) : undefined; + + return createJsxFactoryCall(tagName, props, children, node, context); +} + +const transformJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node.openingElement, node.children, context); +const transformSelfClosingJsxElement: FunctionVisitor = (node, context) => + transformJsxOpeningLikeElement(node, undefined, context); +const transformJsxFragment: FunctionVisitor = (node, context) => { + const tagName = getJsxFragmentName(node, context); + return createJsxFactoryCall(tagName, undefined, node.children, node, context); +}; + +export const jsxVisitors: Visitors = { + [ts.SyntaxKind.JsxElement]: transformJsxElement, + [ts.SyntaxKind.JsxSelfClosingElement]: transformSelfClosingJsxElement, + [ts.SyntaxKind.JsxFragment]: transformJsxFragment, +}; diff --git a/src/transformation/visitors/jsx/xhtml.ts b/src/transformation/visitors/jsx/xhtml.ts new file mode 100644 index 000000000..814191df0 --- /dev/null +++ b/src/transformation/visitors/jsx/xhtml.ts @@ -0,0 +1,256 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +export const XHTMLEntities: { [name: string]: string } = { + quot: "\u0022", + amp: "&", + apos: "\u0027", + lt: "<", + gt: ">", + nbsp: "\u00A0", + iexcl: "\u00A1", + cent: "\u00A2", + pound: "\u00A3", + curren: "\u00A4", + yen: "\u00A5", + brvbar: "\u00A6", + sect: "\u00A7", + uml: "\u00A8", + copy: "\u00A9", + ordf: "\u00AA", + laquo: "\u00AB", + not: "\u00AC", + shy: "\u00AD", + reg: "\u00AE", + macr: "\u00AF", + deg: "\u00B0", + plusmn: "\u00B1", + sup2: "\u00B2", + sup3: "\u00B3", + acute: "\u00B4", + micro: "\u00B5", + para: "\u00B6", + middot: "\u00B7", + cedil: "\u00B8", + sup1: "\u00B9", + ordm: "\u00BA", + raquo: "\u00BB", + frac14: "\u00BC", + frac12: "\u00BD", + frac34: "\u00BE", + iquest: "\u00BF", + Agrave: "\u00C0", + Aacute: "\u00C1", + Acirc: "\u00C2", + Atilde: "\u00C3", + Auml: "\u00C4", + Aring: "\u00C5", + AElig: "\u00C6", + Ccedil: "\u00C7", + Egrave: "\u00C8", + Eacute: "\u00C9", + Ecirc: "\u00CA", + Euml: "\u00CB", + Igrave: "\u00CC", + Iacute: "\u00CD", + Icirc: "\u00CE", + Iuml: "\u00CF", + ETH: "\u00D0", + Ntilde: "\u00D1", + Ograve: "\u00D2", + Oacute: "\u00D3", + Ocirc: "\u00D4", + Otilde: "\u00D5", + Ouml: "\u00D6", + times: "\u00D7", + Oslash: "\u00D8", + Ugrave: "\u00D9", + Uacute: "\u00DA", + Ucirc: "\u00DB", + Uuml: "\u00DC", + Yacute: "\u00DD", + THORN: "\u00DE", + szlig: "\u00DF", + agrave: "\u00E0", + aacute: "\u00E1", + acirc: "\u00E2", + atilde: "\u00E3", + auml: "\u00E4", + aring: "\u00E5", + aelig: "\u00E6", + ccedil: "\u00E7", + egrave: "\u00E8", + eacute: "\u00E9", + ecirc: "\u00EA", + euml: "\u00EB", + igrave: "\u00EC", + iacute: "\u00ED", + icirc: "\u00EE", + iuml: "\u00EF", + eth: "\u00F0", + ntilde: "\u00F1", + ograve: "\u00F2", + oacute: "\u00F3", + ocirc: "\u00F4", + otilde: "\u00F5", + ouml: "\u00F6", + divide: "\u00F7", + oslash: "\u00F8", + ugrave: "\u00F9", + uacute: "\u00FA", + ucirc: "\u00FB", + uuml: "\u00FC", + yacute: "\u00FD", + thorn: "\u00FE", + yuml: "\u00FF", + OElig: "\u0152", + oelig: "\u0153", + Scaron: "\u0160", + scaron: "\u0161", + Yuml: "\u0178", + fnof: "\u0192", + circ: "\u02C6", + tilde: "\u02DC", + Alpha: "\u0391", + Beta: "\u0392", + Gamma: "\u0393", + Delta: "\u0394", + Epsilon: "\u0395", + Zeta: "\u0396", + Eta: "\u0397", + Theta: "\u0398", + Iota: "\u0399", + Kappa: "\u039A", + Lambda: "\u039B", + Mu: "\u039C", + Nu: "\u039D", + Xi: "\u039E", + Omicron: "\u039F", + Pi: "\u03A0", + Rho: "\u03A1", + Sigma: "\u03A3", + Tau: "\u03A4", + Upsilon: "\u03A5", + Phi: "\u03A6", + Chi: "\u03A7", + Psi: "\u03A8", + Omega: "\u03A9", + alpha: "\u03B1", + beta: "\u03B2", + gamma: "\u03B3", + delta: "\u03B4", + epsilon: "\u03B5", + zeta: "\u03B6", + eta: "\u03B7", + theta: "\u03B8", + iota: "\u03B9", + kappa: "\u03BA", + lambda: "\u03BB", + mu: "\u03BC", + nu: "\u03BD", + xi: "\u03BE", + omicron: "\u03BF", + pi: "\u03C0", + rho: "\u03C1", + sigmaf: "\u03C2", + sigma: "\u03C3", + tau: "\u03C4", + upsilon: "\u03C5", + phi: "\u03C6", + chi: "\u03C7", + psi: "\u03C8", + omega: "\u03C9", + thetasym: "\u03D1", + upsih: "\u03D2", + piv: "\u03D6", + ensp: "\u2002", + emsp: "\u2003", + thinsp: "\u2009", + zwnj: "\u200C", + zwj: "\u200D", + lrm: "\u200E", + rlm: "\u200F", + ndash: "\u2013", + mdash: "\u2014", + lsquo: "\u2018", + rsquo: "\u2019", + sbquo: "\u201A", + ldquo: "\u201C", + rdquo: "\u201D", + bdquo: "\u201E", + dagger: "\u2020", + Dagger: "\u2021", + bull: "\u2022", + hellip: "\u2026", + permil: "\u2030", + prime: "\u2032", + Prime: "\u2033", + lsaquo: "\u2039", + rsaquo: "\u203A", + oline: "\u203E", + frasl: "\u2044", + euro: "\u20AC", + image: "\u2111", + weierp: "\u2118", + real: "\u211C", + trade: "\u2122", + alefsym: "\u2135", + larr: "\u2190", + uarr: "\u2191", + rarr: "\u2192", + darr: "\u2193", + harr: "\u2194", + crarr: "\u21B5", + lArr: "\u21D0", + uArr: "\u21D1", + rArr: "\u21D2", + dArr: "\u21D3", + hArr: "\u21D4", + forall: "\u2200", + part: "\u2202", + exist: "\u2203", + empty: "\u2205", + nabla: "\u2207", + isin: "\u2208", + notin: "\u2209", + ni: "\u220B", + prod: "\u220F", + sum: "\u2211", + minus: "\u2212", + lowast: "\u2217", + radic: "\u221A", + prop: "\u221D", + infin: "\u221E", + ang: "\u2220", + and: "\u2227", + or: "\u2228", + cap: "\u2229", + cup: "\u222A", + int: "\u222B", + there4: "\u2234", + sim: "\u223C", + cong: "\u2245", + asymp: "\u2248", + ne: "\u2260", + equiv: "\u2261", + le: "\u2264", + ge: "\u2265", + sub: "\u2282", + sup: "\u2283", + nsub: "\u2284", + sube: "\u2286", + supe: "\u2287", + oplus: "\u2295", + otimes: "\u2297", + perp: "\u22A5", + sdot: "\u22C5", + lceil: "\u2308", + rceil: "\u2309", + lfloor: "\u230A", + rfloor: "\u230B", + lang: "\u2329", + rang: "\u232A", + loz: "\u25CA", + spades: "\u2660", + clubs: "\u2663", + hearts: "\u2665", + diams: "\u2666", +}; diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 85b3c6a29..a433cd3f4 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -90,7 +90,7 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n export function findMultiAssignmentViolations( context: TransformationContext, - node: ts.ObjectLiteralExpression + node: ts.ObjectLiteralExpressionBase ): ts.Node[] { const result: ts.Node[] = []; diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 8fa85e4e4..75b4a3224 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { unsupportedAccessorInObjectLiteral, invalidMultiFunctionUse } from "../utils/diagnostics"; +import { invalidMultiFunctionUse, unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -11,6 +11,7 @@ import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; import { findMultiAssignmentViolations } from "./language-extensions/multi"; +import { formatJSXStringValueLiteral } from "./jsx/jsx"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -62,78 +63,99 @@ const transformNumericLiteralExpression: FunctionVisitor = ex return lua.createNumericLiteral(Number(expression.text), expression); }; -const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { - const violations = findMultiAssignmentViolations(context, expression); - if (violations.length > 0) { - context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); - return lua.createNilLiteral(expression); - } - - let properties: lua.TableFieldExpression[] = []; - const tableExpressions: lua.Expression[] = []; +const transformObjectLiteralExpressionOrJsxAttributes: FunctionVisitor = + (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } - for (const element of expression.properties) { - const name = element.name ? transformPropertyName(context, element.name) : undefined; + let properties: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; + + for (const element of expression.properties) { + const name = element.name ? transformPropertyName(context, element.name) : undefined; + + if (ts.isPropertyAssignment(element)) { + const expression = context.transformExpression(element.initializer); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isJsxAttribute(element)) { + const initializer = element.initializer; + let expression: lua.Expression; + if (initializer === undefined) { + expression = lua.createBooleanLiteral(true); + } else if (ts.isStringLiteral(initializer)) { + const text = formatJSXStringValueLiteral(initializer.text); + expression = lua.createStringLiteral(text, initializer); + } else if (ts.isJsxExpression(initializer)) { + expression = initializer.expression + ? context.transformExpression(initializer.expression) + : lua.createBooleanLiteral(true); + } else { + assertNever(initializer); + } + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + trackSymbolReference(context, valueSymbol, element.name); + } + + const identifier = createShorthandIdentifier(context, valueSymbol, element.name); + properties.push(lua.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { + const expression = transformFunctionLikeDeclaration(element, context); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element) || ts.isJsxSpreadAttribute(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); + properties = []; + } + + const type = context.checker.getTypeAtLocation(element.expression); + let tableExpression: lua.Expression; + if (isArrayType(context, type)) { + tableExpression = transformLuaLibFunction( + context, + LuaLibFeature.ArrayToObject, + element.expression, + context.transformExpression(element.expression) + ); + } else { + tableExpression = context.transformExpression(element.expression); + } - if (ts.isPropertyAssignment(element)) { - const expression = context.transformExpression(element.initializer); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { - const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - trackSymbolReference(context, valueSymbol, element.name); + tableExpressions.push(tableExpression); + } else if (ts.isAccessor(element)) { + context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); + } else { + assertNever(element); } + } - const identifier = createShorthandIdentifier(context, valueSymbol, element.name); - properties.push(lua.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { - const expression = transformFunctionLikeDeclaration(element, context); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isSpreadAssignment(element)) { - // Create a table for preceding properties to preserve property order - // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) + if (tableExpressions.length === 0) { + return lua.createTableExpression(properties, expression); + } else { if (properties.length > 0) { const tableExpression = lua.createTableExpression(properties, expression); tableExpressions.push(tableExpression); - properties = []; } - const type = context.checker.getTypeAtLocation(element.expression); - let tableExpression: lua.Expression; - if (isArrayType(context, type)) { - tableExpression = transformLuaLibFunction( - context, - LuaLibFeature.ArrayToObject, - element.expression, - context.transformExpression(element.expression) - ); - } else { - tableExpression = context.transformExpression(element.expression); + if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { + tableExpressions.unshift(lua.createTableExpression(undefined, expression)); } - tableExpressions.push(tableExpression); - } else if (ts.isAccessor(element)) { - context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); - } else { - assertNever(element); - } - } - - if (tableExpressions.length === 0) { - return lua.createTableExpression(properties, expression); - } else { - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); } - - if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { - tableExpressions.unshift(lua.createTableExpression(undefined, expression)); - } - - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); - } -}; + }; +const transformObjectLiteralExpression: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; +export const transformJsxAttributes: FunctionVisitor = + transformObjectLiteralExpressionOrJsxAttributes; const transformArrayLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 4b57c329d..098d78740 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -53,3 +53,5 @@ export const cannotBundleLibrary = createDiagnosticFactory( () => 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' ); + +export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts new file mode 100644 index 000000000..5734b33ee --- /dev/null +++ b/test/unit/jsx.spec.ts @@ -0,0 +1,361 @@ +import * as util from "../util"; +import { TestBuilder } from "../util"; +import { JsxEmit } from "typescript"; + +// language=TypeScript +const reactLib = ` + export class Component { + static isClass = true + } + + namespace React { + const isLua = typeof Component === "object" + + export function createElement( + this: void, + type: any, + props?: any, + ...children: any[] + ) { + let typeStr: string + if (isLua) { + typeStr = + typeof type === "function" ? "<< function >>" : + typeof type === "object" ? \`<< class \${type.name} >>\` : + type + } else { + typeStr = typeof type === "function" ? (type.isClass ? \`<< class \${type.name} >>\` : "<< function >>") + : type + } + + return { + type: typeStr, + props, + children + }; + } + + export class Fragment extends Component { + } + } + export default React; +`; +// language=TypeScript +const jsxTypings = `declare namespace JSX { + interface IntrinsicElements { + a: any + b: any + foo: any + bar: any + div: any + "with-dash": any + } +} +`; + +function testJsx(...args: [string] | [TemplateStringsArray, ...any[]]): TestBuilder { + return util + .testFunction(...args) + .setOptions({ + jsx: JsxEmit.React, + }) + .setMainFileName("main.tsx") + .addExtraFile("react.ts", reactLib) + .addExtraFile("jsx.d.ts", jsxTypings) + .setTsHeader('import React, { Component } from "./react";'); +} + +describe("jsx", () => { + test("element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("self closing element", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("element with dash name", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("custom element", () => { + testJsx` + function Foo() {} + return + `.expectToMatchJsResult(); + }); + test("fragment", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("fragment with children", () => { + testJsx` + return <> + `.expectToMatchJsResult(); + }); + test("esoteric component names", () => { + testJsx` + class _Foo extends Component {} + return <_Foo /> + `.expectToMatchJsResult(); + + testJsx` + class $ extends Component {} + return <$ /> + `.expectToMatchJsResult(); + + testJsx` + class é extends Component {} + return <é /> + `.expectToMatchJsResult(); + }); + test("nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("many nested elements", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("interpolated children", () => { + testJsx` + const x = 3 + return {x} + `.expectToMatchJsResult(); + }); + test("string prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("value prop", () => { + testJsx` + const x = 5 + return + `.expectToMatchJsResult(); + }); + test("quoted prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("shorthand prop", () => { + testJsx` + return + `.expectToMatchJsResult(); + }); + test("spaces in jsxText", () => { + testJsx` + return this + is somemultiline + text thing. + + + `.expectToMatchJsResult(); + }); + test("multiline string jsxText", () => { + testJsx` + return + foo bar + baz + + `.expectToMatchJsResult(); + }); + + test("access tag value", () => { + testJsx` + const a = { b(){} }; + return + `.expectToMatchJsResult(); + testJsx` + const a = { b: { c: { d(){} } } }; + return + `.expectToMatchJsResult(); + }); + + test("spread props", () => { + testJsx` + const x = {c: "d", e: "f"} + return + `.expectToMatchJsResult(); + testJsx` + const x = {c: "d", e: "no"} + return + `.expectToMatchJsResult(); + }); + + test("comment children", () => { + testJsx` + return + {/* comment */} + {/* another comment */} + + `.expectToMatchJsResult(); + testJsx` + return + + {/* comment */} + + + `.expectToMatchJsResult(); + }); + + test("multiline string prop value", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + testJsx` + return
+ `.expectToMatchJsResult(); + }); + + test("prop strings with entities", () => { + testJsx` + return
+ `.expectToMatchJsResult(); + }); + test("jsxText with entities", () => { + testJsx` + return 9+10<21 + `.expectToMatchJsResult(); + }); + + test("Spread children", () => { + // doesn't actually "spread" (typescript's current behavior) + testJsx` + const children = [, ] + return {...children} + `.expectToMatchJsResult(); + }); + + test("complex", () => { + testJsx` + const x = 3 + const props = {one: "two", three: 4} + return + `.expectToMatchJsResult(); + }); + + // language=TypeScript + const customJsxLib = `export namespace MyLib { + export function myCreate( + this: void, + type: any, + props: any, + ...children: any[] + ) { + return { type: typeof type, props, children, myThing: true }; + } + + export function MyFragment() { + } + } + `; + + test("custom JSX factory", () => { + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .setOptions({ jsxFactory: "myCreate2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment factory", () => { + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyLib.MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader('import { MyLib } from "./myJsx";function MyFragment2(){};') + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment2" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom JSX pragma", () => { + testJsx` + return c + ` + .setTsHeader('/** @jsx MyLib.myCreate */\nimport { MyLib } from "./myJsx";') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return c + ` + .setTsHeader('/** @jsx myCreate2 */import { MyLib } from "./myJsx";const myCreate2 = MyLib.myCreate;') + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + test("custom fragment pragma", () => { + testJsx` + return <>c + ` + .setTsHeader( + '/** @jsx MyLib.myCreate */\n/** @jsxFrag MyLib.MyFragment */\nimport { MyLib } from "./myJsx";' + ) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + testJsx` + return <>c + ` + .setTsHeader( + "/** @jsx MyLib.myCreate */\n/** @jsxFrag MyFragment2 */\n" + + 'import { MyLib } from "./myJsx";function MyFragment2(){};' + ) + .setOptions({ jsxFactory: "MyLib.myCreate", jsxFragmentFactory: "MyFragment" }) + .addExtraFile("myJsx.ts", customJsxLib) + .expectToMatchJsResult(); + }); + + test("forward declare components", () => { + testJsx` + const foo = + + function Foo(){} + + return foo + `.expectToMatchJsResult(); + }); + + test("invalid jsx config", () => { + testJsx(` + return + `) + .setOptions({ + jsx: JsxEmit.Preserve, + }) + .expectToHaveDiagnostics(); + }); +}); From 69a44a6dd3383d4609741e6ba42fc33805d7b243 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 3 Aug 2021 21:25:40 +0200 Subject: [PATCH 369/764] Fix crash when trying to assign to an optional chain (#1045) --- src/transformation/utils/diagnostics.ts | 4 ++++ .../visitors/binary-expression/assignments.ts | 6 ++++++ test/unit/optionalChaining.spec.ts | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 16a0c7395..dbbe9376a 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -143,3 +143,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); + +export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( + "The left-hand side of an assignment expression may not be an optional property access." +); diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index c8a1cd907..f6aa89d61 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -16,6 +16,7 @@ import { ImmediatelyInvokedFunctionParameters, transformToImmediatelyInvokedFunctionExpression, } from "../../utils/transform"; +import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, @@ -36,6 +37,11 @@ export function transformAssignment( right: lua.Expression, parent?: ts.Expression ): lua.Statement[] { + if (ts.isOptionalChain(lhs)) { + context.diagnostics.push(notAllowedOptionalAssignment(lhs)); + return []; + } + if (isArrayLength(context, lhs)) { const arrayLengthAssignment = lua.createExpressionStatement( transformLuaLibFunction( diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 26deff810..cf24b6702 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,3 +1,4 @@ +import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { @@ -97,6 +98,15 @@ test("no side effects", () => { `.expectToMatchJsResult(); }); +// Test for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1044 +test("does not crash when incorrectly used in assignment (#1044)", () => { + const { diagnostics } = util.testFunction` + foo?.bar = "foo"; + `.getLuaResult(); + + expect(diagnostics.find(d => d.code === notAllowedOptionalAssignment.code)).toBeDefined(); +}); + describe("optional chaining function calls", () => { test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { util.testFunction` From cac1656bff3c95e101c1b2117bf8c2b02e65211f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 3 Aug 2021 22:21:51 +0200 Subject: [PATCH 370/764] Module resolution fixes (#1060) * Deduplicate resolved files * Add resolution context with cache * Fix problem resolving lua siblings * Added forgotten path.normalize * add ignored test node_modules .d.ts * Fix lua files in sources no longer correctly resolving * fix prettier * Fix lua source file resolution this time for real --- src/transpilation/resolve.ts | 189 +++++++++++++----- src/transpilation/utils.ts | 1 + test/transpile/module-resolution.spec.ts | 34 ++++ .../main.ts | 5 + .../node_modules/dependency1/index.d.ts | 4 + .../node_modules/dependency1/index.lua | 14 ++ .../node_modules/dependency1/otherfile.lua | 10 + .../dependency1/subdir/othersubdirfile.lua | 3 + .../dependency1/subdir/subdirfile.lua | 5 + .../node_modules/dependency1/util.lua | 3 + .../tsconfig.json | 10 + 11 files changed, 230 insertions(+), 48 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/main.ts create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 5334c0ca7..089191d53 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -21,29 +21,110 @@ interface ResolutionResult { diagnostics: ts.Diagnostic[]; } +class ResolutionContext { + private resultsCache = new Map(); + + constructor( + public readonly program: ts.Program, + public readonly options: CompilerOptions, + private readonly emitHost: EmitHost + ) {} + + public resolve(file: ProcessedFile, required: string): ResolutionResult { + const resolvedDependency = resolveDependency(file, required, this.program, this.emitHost); + if (resolvedDependency) { + if (this.options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + } + + // Figure out resolved require path and dependency output path + const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, this.program); + + if (shouldRewriteRequires(resolvedDependency, this.program)) { + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); + } + + // Check cache to prevent resolving nested dependencies double to break dependency loops + if (this.resultsCache.has(resolvedDependency)) { + if (this.options.tstlVerbose) { + console.log(`Resolution cache hit for ${normalizeSlashes(resolvedDependency)}`); + } + return this.resultsCache.get(resolvedDependency)!; + } + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + if (shouldIncludeDependency(resolvedDependency, this.program)) { + // If dependency resolved successfully, read its content + const dependencyContent = this.emitHost.readFile(resolvedDependency); + if (dependencyContent === undefined) { + return { resolvedFiles: [], diagnostics: [couldNotReadDependency(resolvedDependency)] }; + } + + const dependency = { + fileName: resolvedDependency, + code: dependencyContent, + }; + const nestedDependencies = resolveFileDependencies(dependency, this); + + // Cache result and return + const result = { + resolvedFiles: [dependency, ...nestedDependencies.resolvedFiles], + diagnostics: [...nestedDependencies.diagnostics], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } else { + const result = { + resolvedFiles: [], + diagnostics: [], + }; + this.resultsCache.set(resolvedDependency, result); + return result; + } + } else { + const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); + + return { + resolvedFiles: [], + diagnostics: [ + couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)), + ], + }; + } + } +} + export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { const outFiles: ProcessedFile[] = [...files]; const diagnostics: ts.Diagnostic[] = []; const options = program.getCompilerOptions() as CompilerOptions; + const resolutionContext = new ResolutionContext(program, options, emitHost); + // Resolve dependencies for all processed files for (const file of files) { if (options.tstlVerbose) { console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); } - const resolutionResult = resolveFileDependencies(file, program, emitHost); + const resolutionResult = resolveFileDependencies(file, resolutionContext); outFiles.push(...resolutionResult.resolvedFiles); diagnostics.push(...resolutionResult.diagnostics); } - return { resolvedFiles: outFiles, diagnostics }; + return { resolvedFiles: deduplicateResolvedFiles(outFiles), diagnostics }; } -function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitHost: EmitHost): ResolutionResult { +function deduplicateResolvedFiles(files: ProcessedFile[]): ProcessedFile[] { + return [...new Map(files.map(f => [f.fileName, f])).values()]; +} + +function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext): ResolutionResult { const dependencies: ProcessedFile[] = []; const diagnostics: ts.Diagnostic[] = []; - const options = program.getCompilerOptions() as CompilerOptions; for (const required of findRequiredPaths(file.code)) { // Do no resolve lualib @@ -60,57 +141,22 @@ function resolveFileDependencies(file: ProcessedFile, program: ts.Program, emitH } // Try to resolve the import starting from the directory `file` is in - const fileDir = path.dirname(file.fileName); - const resolvedDependency = resolveDependency(fileDir, required, program, emitHost); - if (resolvedDependency) { - if (options.tstlVerbose) { - console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); - } - - // Figure out resolved require path and dependency output path - const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, program); - - if (shouldRewriteRequires(resolvedDependency, program)) { - replaceRequireInCode(file, required, resolvedRequire); - replaceRequireInSourceMap(file, required, resolvedRequire); - } - - // If dependency is not part of project, add dependency to output and resolve its dependencies recursively - if (shouldIncludeDependency(resolvedDependency, program)) { - // If dependency resolved successfully, read its content - const dependencyContent = emitHost.readFile(resolvedDependency); - if (dependencyContent === undefined) { - diagnostics.push(couldNotReadDependency(resolvedDependency)); - continue; - } - - const dependency = { - fileName: resolvedDependency, - code: dependencyContent, - }; - const nestedDependencies = resolveFileDependencies(dependency, program, emitHost); - dependencies.push(dependency, ...nestedDependencies.resolvedFiles); - diagnostics.push(...nestedDependencies.diagnostics); - } - } else { - // Could not resolve dependency, add a diagnostic and make some fallback path - diagnostics.push(couldNotResolveRequire(required, path.relative(getProjectRoot(program), file.fileName))); - - const fallbackRequire = fallbackResolve(required, getSourceDir(program), fileDir); - replaceRequireInCode(file, required, fallbackRequire); - replaceRequireInSourceMap(file, required, fallbackRequire); - } + const resolvedDependency = context.resolve(file, required); + dependencies.push(...resolvedDependency.resolvedFiles); + diagnostics.push(...resolvedDependency.diagnostics); } return { resolvedFiles: dependencies, diagnostics }; } function resolveDependency( - fileDirectory: string, + requiringFile: ProcessedFile, dependency: string, program: ts.Program, emitHost: EmitHost ): string | undefined { const options = program.getCompilerOptions() as CompilerOptions; + + const fileDirectory = path.dirname(requiringFile.fileName); if (options.tstlVerbose) { console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); } @@ -132,10 +178,24 @@ function resolveDependency( } } + // Check if this is a lua file in the project sources + const possibleLuaProjectFiles = [ + resolvedPath + ".lua", // lua file in sources + path.join(resolvedPath, "index.lua"), // lua index file in sources + ]; + + for (const possibleFile of possibleLuaProjectFiles) { + if (emitHost.fileExists(possibleFile)) { + return possibleFile; + } + } + // Check if this is a sibling of a required lua file - const luaFilePath = path.resolve(fileDirectory, dependency + ".lua"); - if (emitHost.fileExists(luaFilePath)) { - return luaFilePath; + if (requiringFile.fileName.endsWith(".lua")) { + const luaFilePath = resolveLuaPath(fileDirectory, dependency, emitHost); + if (luaFilePath) { + return luaFilePath; + } } // Not a TS file in our project sources, use resolver to check if we can find dependency @@ -151,6 +211,39 @@ function resolveDependency( return undefined; } +function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost) { + const splitDependency = dependency.split("."); + if (splitDependency.length === 1) { + // If dependency has just one part (the file), look for a lua file with that name + const fileDirectory = walkUpFileTreeUntil(fromPath, dir => + emitHost.fileExists(path.join(dir, dependency) + ".lua") + ); + if (fileDirectory) { + return path.join(fileDirectory, dependency) + ".lua"; + } + } else { + // If dependency has multiple parts, look for the first directory of the require path, which must be in the lua root + const luaRoot = walkUpFileTreeUntil(fromPath, dir => + emitHost.directoryExists(path.join(dir, splitDependency[0])) + ); + if (luaRoot) { + return path.join(luaRoot, dependency.replace(".", path.sep)) + ".lua"; + } + } +} + +function walkUpFileTreeUntil(fromDirectory: string, predicate: (dir: string) => boolean) { + const currentDir = path.normalize(fromDirectory).split(path.sep); + while (currentDir.length > 0) { + const dir = currentDir.join(path.sep); + if (predicate(dir)) { + return dir; + } + currentDir.pop(); + } + return undefined; +} + function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); } diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index a4acdfbb4..4b0a9c24f 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -8,6 +8,7 @@ import * as lua from "../LuaAST"; import * as diagnosticFactories from "./diagnostics"; export interface EmitHost { + directoryExists(path: string): boolean; fileExists(path: string): boolean; getCurrentDirectory(): string; readFile(path: string): string | undefined; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index b995e75a5..9f34407f3 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -275,3 +275,37 @@ describe("module resolution with tsx", () => { }); }); }); + +describe("dependency with complicated inner structure", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-complicated-dependency"); + const tsConfigPath = path.join(projectPath, "tsconfig.json"); + const mainFilePath = path.join(projectPath, "main.ts"); + + const expectedResult = { + otherFileResult: "someFunc from otherfile.lua", + otherFileUtil: "util", + utilResult: "util", + }; + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1055 + test("bundle should not contain duplicate files", () => { + const mainFile = path.join(projectPath, "main.ts"); + const { transpiledFiles } = util + .testProject(tsConfigPath) + .setMainFileName(mainFilePath) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual(expectedResult) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + const lua = transpiledFiles[0].lua!; + // util is used in 2 places, but should only occur once in the bundle + const utilModuleOccurrences = (lua.match(/\["lua_modules\.dependency1\.util"\]/g) ?? []).length; + expect(utilModuleOccurrences).toBe(1); + }); + + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1054 + test("should be able to resolve dependency files in subdirectories", () => { + util.testProject(tsConfigPath).setMainFileName(mainFilePath).expectToEqual(expectedResult); + }); +}); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts new file mode 100644 index 000000000..2149de5e4 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -0,0 +1,5 @@ +import * as dependency1 from "dependency1"; + +export const otherFileResult = dependency1.otherFileFromDependency1(); +export const utilResult = dependency1.callUtil(); +export const otherFileUtil = dependency1.otherFileUtil(); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts new file mode 100644 index 000000000..3c72ec27b --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ +export declare function otherFileFromDependency1(): string; +export declare function callUtil(): string; +export declare function otherFileUtil(): string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua new file mode 100644 index 000000000..a4f17376c --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -0,0 +1,14 @@ +local otherfile = require("otherfile") +local util = require("util") +local subdirfile = require("subdir.subdirfile") +local othersubdirfile = require("subdir.othersubdirfile") + +return { + otherFileFromDependency1 = otherfile.someFunc, + callUtil = function() + return util.utilf() + end, + otherFileUtil = otherfile.callUtil, + subdirfileResult = subdirfile.subdirfileResult, + othersubdirfileResult = othersubdirfile.othersubdirfileResult +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua new file mode 100644 index 000000000..0fb8719ac --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/otherfile.lua @@ -0,0 +1,10 @@ +local util = require("util") + +return { + someFunc = function() + return "someFunc from otherfile.lua" + end, + callUtil = function() + return util.utilf() + end +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua new file mode 100644 index 000000000..45e5c985f --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/othersubdirfile.lua @@ -0,0 +1,3 @@ +return { + result = "result from other subdirectory file" +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua new file mode 100644 index 000000000..fe26400a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subdirfile.lua @@ -0,0 +1,5 @@ +local othersubdirfile = require("subdir.othersubdirfile") +return { + subdirfileResult = "result from subdirectory file!", + othersubdirfileResult = othersubdirfile.result +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua new file mode 100644 index 000000000..e4e812406 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/util.lua @@ -0,0 +1,3 @@ +return { + utilf = function() return "util" end, +} \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json new file mode 100644 index 000000000..b76533290 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "strict": true, + "moduleResolution": "Node", + "target": "esnext", + "lib": ["esnext"], + "types": [], + "rootDir": "." + } +} From 7b39ce3dd3d7c75350413d254924f2c98c0cad5d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 3 Aug 2021 22:28:54 +0200 Subject: [PATCH 371/764] 0.41.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35fb97cf6..3aa24f585 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 548b86ef2..fc55ec87a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.41.0", + "version": "0.41.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 228d772cdf964a645fb4ca5e02bb87836d9a1457 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 20:35:04 +0200 Subject: [PATCH 372/764] More resolution fixes (#1064) * Fix files nested deeper in depedencies not correctly being resolved * Do not rewrite NoResolution imports in library build mode * Fix bundle require executing modules too often --- src/transpilation/bundle.ts | 6 +-- src/transpilation/resolve.ts | 13 ++++-- test/transpile/module-resolution.spec.ts | 43 ++++++++++++++++++- .../main.ts | 1 + .../node_modules/dependency1/index.d.ts | 3 +- .../node_modules/dependency1/index.lua | 4 +- .../subdir/subsubdir/subsubdirfile.lua | 3 ++ test/unit/bundle.spec.ts | 23 ++++++++++ 8 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 579e84ee1..78e03a7a6 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -18,11 +18,11 @@ local ____moduleCache = {} local ____originalRequire = require local function require(file) if ____moduleCache[file] then - return ____moduleCache[file] + return ____moduleCache[file].value end if ____modules[file] then - ____moduleCache[file] = ____modules[file]() - return ____moduleCache[file] + ____moduleCache[file] = { value = ____modules[file]() } + return ____moduleCache[file].value else if ____originalRequire then return ____originalRequire(file) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 089191d53..da74621aa 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -134,9 +134,14 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext // Do not resolve noResolution paths if (required.startsWith("@NoResolution:")) { - const path = required.replace("@NoResolution:", ""); - replaceRequireInCode(file, required, path); - replaceRequireInSourceMap(file, required, path); + // Remove @NoResolution prefix if not building in library mode + if (!isBuildModeLibrary(context.program)) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + } + + // Skip continue; } @@ -227,7 +232,7 @@ function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost emitHost.directoryExists(path.join(dir, splitDependency[0])) ); if (luaRoot) { - return path.join(luaRoot, dependency.replace(".", path.sep)) + ".lua"; + return path.join(luaRoot, dependency.replace(/\./g, path.sep)) + ".lua"; } } } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 9f34407f3..528b1f25d 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,7 +2,7 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; -import { transpileProject } from "../../src"; +import { BuildMode, transpileProject } from "../../src"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -284,6 +284,7 @@ describe("dependency with complicated inner structure", () => { const expectedResult = { otherFileResult: "someFunc from otherfile.lua", otherFileUtil: "util", + subsubresult: "result from subsub dir", utilResult: "util", }; @@ -309,3 +310,43 @@ describe("dependency with complicated inner structure", () => { util.testProject(tsConfigPath).setMainFileName(mainFilePath).expectToEqual(expectedResult); }); }); + +test("module resolution should not try to resolve @noResolution annotation", () => { + util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .expectToHaveNoDiagnostics(); +}); + +test("module resolution should not rewrite @NoResolution requires in library mode", () => { + const { transpiledFiles } = util.testModule` + import * as json from "json"; + const test = json.decode("{}"); + ` + .addExtraFile( + "json.d.ts", + ` + /** @noResolution */ + declare module "json" { + function encode(this: void, data: unknown): string; + function decode(this: void, data: string): unknown; + } + ` + ) + .setOptions({ buildMode: BuildMode.Library }) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); +}); diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts index 2149de5e4..20bc696ea 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -3,3 +3,4 @@ import * as dependency1 from "dependency1"; export const otherFileResult = dependency1.otherFileFromDependency1(); export const utilResult = dependency1.callUtil(); export const otherFileUtil = dependency1.otherFileUtil(); +export const subsubresult = dependency1.subsubdirfileResult; diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts index 3c72ec27b..2aaa0dfd6 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -1,4 +1,5 @@ /** @noSelfInFile */ export declare function otherFileFromDependency1(): string; export declare function callUtil(): string; -export declare function otherFileUtil(): string; \ No newline at end of file +export declare function otherFileUtil(): string; +export const subsubdirfileResult: string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua index a4f17376c..8068497d1 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -2,6 +2,7 @@ local otherfile = require("otherfile") local util = require("util") local subdirfile = require("subdir.subdirfile") local othersubdirfile = require("subdir.othersubdirfile") +local subsubdirfile = require("subdir.subsubdir.subsubdirfile") return { otherFileFromDependency1 = otherfile.someFunc, @@ -10,5 +11,6 @@ return { end, otherFileUtil = otherfile.callUtil, subdirfileResult = subdirfile.subdirfileResult, - othersubdirfileResult = othersubdirfile.othersubdirfileResult + othersubdirfileResult = othersubdirfile.othersubdirfileResult, + subsubdirfileResult = subsubdirfile.subsubresult } \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua new file mode 100644 index 000000000..581c8f858 --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdir/subsubdir/subsubdirfile.lua @@ -0,0 +1,3 @@ +return { + subsubresult = "result from subsub dir" +} \ No newline at end of file diff --git a/test/unit/bundle.spec.ts b/test/unit/bundle.spec.ts index ddc678f34..b8179363a 100644 --- a/test/unit/bundle.spec.ts +++ b/test/unit/bundle.spec.ts @@ -109,6 +109,29 @@ test("cyclic imports", () => { .expectToEqual(new util.ExecutionError("stack overflow")); }); +test("does not evaluate files multiple times", () => { + util.testBundle` + import "./countingfile"; + import "./otherfile"; + + export const count = _count; + ` + .addExtraFile( + "otherfile.ts", + ` + import "./countingfile"; + ` + ) + .addExtraFile( + "countingfile.ts", + ` + declare var _count: number | undefined; + _count = (_count ?? 0) + 1; + ` + ) + .expectToEqual({ count: 1 }); +}); + test("no entry point", () => { util.testBundle`` .setOptions({ luaBundleEntry: undefined }) From d47019903976015d8d61fe62758fdeff89826cac Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 21:54:18 +0200 Subject: [PATCH 373/764] Check baseUrl when resolving imported files (#1067) --- src/transpilation/resolve.ts | 2 +- test/transpile/module-resolution.spec.ts | 40 ++++++++++++++++++++++++ test/util.ts | 8 ++++- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index da74621aa..9829aa06d 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -167,7 +167,7 @@ function resolveDependency( } // Check if file is a file in the project - const resolvedPath = path.join(fileDirectory, dependency); + const resolvedPath = path.join(options.baseUrl ?? fileDirectory, dependency); const possibleProjectFiles = [ resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 528b1f25d..01386a146 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -350,3 +350,43 @@ test("module resolution should not rewrite @NoResolution requires in library mod expect(transpiledFiles).toHaveLength(1); expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); }); + +test("module resolution uses baseURL to resolve imported files", () => { + util.testModule` + import { foo } from "dep1"; + import { bar } from "dep2"; + import { baz } from "luadep"; + + export const fooResult = foo(); + export const barResult = bar(); + ` + .addExtraFile( + "myproject/mydeps/dep1.ts", + ` + export function foo() { return "foo"; } + ` + ) + .addExtraFile( + "myproject/mydeps/dep2.ts", + ` + export function bar() { return "bar"; } + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.d.ts", + ` + export function baz(): string; + ` + ) + .addExtraFile( + "myproject/mydeps/luadep.lua", + ` + return { baz = function() return "baz" end } + ` + ) + .setOptions({ baseUrl: "./myproject/mydeps" }) + .expectToEqual({ + fooResult: "foo", + barResult: "bar", + }); +}); diff --git a/test/util.ts b/test/util.ts index b493f43e0..b7f285777 100644 --- a/test/util.ts +++ b/test/util.ts @@ -178,8 +178,14 @@ export abstract class TestBuilder { @memoize public getProgram(): ts.Program { this.hasProgram = true; + + // Exclude lua files from TS program, but keep them in extraFiles so module resolution can find them + const nonLuaExtraFiles = Object.fromEntries( + Object.entries(this.extraFiles).filter(([fileName]) => !fileName.endsWith(".lua")) + ); + return tstl.createVirtualProgram( - { ...this.extraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, + { ...nonLuaExtraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, this.options ); } From 4910922a89bc7036abbe5e01fe63ea0c2e000d7a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 5 Aug 2021 22:03:08 +0200 Subject: [PATCH 374/764] Module resolution should ignore functions that look like requires but are not (#1066) * Module resolution should ignore functions that look like requires but are not * fix prettier * Escape special characters in require regex --- src/transpilation/resolve.ts | 13 +++++++-- test/transpile/module-resolution.spec.ts | 35 ++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 9829aa06d..bc5d098c4 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -274,11 +274,11 @@ function isBuildModeLibrary(program: ts.Program) { function findRequiredPaths(code: string): string[] { // Find all require("") paths in a lua code string const paths: string[] = []; - const pattern = /require\("(.+)"\)/g; + const pattern = /(^|\s|;|=)require\("(.+)"\)/g; // eslint-disable-next-line @typescript-eslint/ban-types let match: RegExpExecArray | null; while ((match = pattern.exec(code))) { - paths.push(match[1]); + paths.push(match[2]); } return paths; @@ -286,7 +286,14 @@ function findRequiredPaths(code: string): string[] { function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); - file.code = file.code.replace(`require("${originalRequire}")`, `require("${requirePath}")`); + + // Escape special characters to prevent the regex from breaking... + const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); + + file.code = file.code.replace( + new RegExp(`(^|\\s|;|=)require\\("${escapedRequire}"\\)`), + `$1require("${requirePath}")` + ); } function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 01386a146..f23f77988 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -329,6 +329,7 @@ test("module resolution should not try to resolve @noResolution annotation", () .expectToHaveNoDiagnostics(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 test("module resolution should not rewrite @NoResolution requires in library mode", () => { const { transpiledFiles } = util.testModule` import * as json from "json"; @@ -351,6 +352,40 @@ test("module resolution should not rewrite @NoResolution requires in library mod expect(transpiledFiles[0].lua).toContain('require("@NoResolution:'); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 +test("module resolution should not try to resolve resolve-like functions", () => { + util.testModule` + function custom_require(this: void, value: string) { + return value; + } + + namespace ns { + export function require(this: void, value: string) { + return value; + } + } + + class MyClass { + require(value: string) { + return value; + } + } + const inst = new MyClass(); + + export const result = [ + custom_require("value 1"), + ns.require("value 2"), + inst.require("value 3") + ]; + + ` + .expectToHaveNoDiagnostics() + .expectToEqual({ + result: ["value 1", "value 2", "value 3"], + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 test("module resolution uses baseURL to resolve imported files", () => { util.testModule` import { foo } from "dep1"; From d39de69570c949d5eebcbd2f1ef6715542c5308b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 5 Aug 2021 22:14:57 +0200 Subject: [PATCH 375/764] 0.41.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3aa24f585..d7055278b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index fc55ec87a..fa3fc0575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.41.1", + "version": "0.41.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 8a330e4c0ac5858d04cad4fb7c10e4cea1804bf8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Aug 2021 15:00:00 +0200 Subject: [PATCH 376/764] Fix lualib bundle not being included when external code requires it (#1074) * Fix lualib bundle not being included when external code requires it * fix prettier --- src/transpilation/resolve.ts | 1 + src/transpilation/transpiler.ts | 15 +++++++----- test/transpile/module-resolution.spec.ts | 30 ++++++++++++++++++++++++ test/util.ts | 15 ++++++++++-- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index bc5d098c4..59639e2c7 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -129,6 +129,7 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext for (const required of findRequiredPaths(file.code)) { // Do no resolve lualib if (required === "lualib_bundle") { + dependencies.push({ fileName: "lualib_bundle", code: "" }); continue; } diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index b19790b37..e30410f73 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -73,21 +73,24 @@ export class Transpiler { console.log("Constructing emit plan"); } - const lualibRequired = files.some(f => f.code.includes('require("lualib_bundle")')); + // Resolve imported modules and modify output Lua requires + const resolutionResult = resolveDependencies(program, files, this.emitHost); + diagnostics.push(...resolutionResult.diagnostics); + + const lualibRequired = resolutionResult.resolvedFiles.some(f => f.fileName === "lualib_bundle"); if (lualibRequired) { + // Remove lualib placeholders from resolution result + resolutionResult.resolvedFiles = resolutionResult.resolvedFiles.filter(f => f.fileName !== "lualib_bundle"); + if (options.tstlVerbose) { console.log("Including lualib bundle"); } // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); - files.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); + resolutionResult.resolvedFiles.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); } - // Resolve imported modules and modify output Lua requires - const resolutionResult = resolveDependencies(program, files, this.emitHost); - diagnostics.push(...resolutionResult.diagnostics); - let emitPlan: EmitFile[]; if (isBundleEnabled(options)) { const [bundleDiagnostics, bundleFile] = getBundleResult(program, resolutionResult.resolvedFiles); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index f23f77988..80e08ac46 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -394,6 +394,7 @@ test("module resolution uses baseURL to resolve imported files", () => { export const fooResult = foo(); export const barResult = bar(); + export const bazResult = baz(); ` .addExtraFile( "myproject/mydeps/dep1.ts", @@ -423,5 +424,34 @@ test("module resolution uses baseURL to resolve imported files", () => { .expectToEqual({ fooResult: "foo", barResult: "bar", + bazResult: "baz", + }); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1071 +test("includes lualib_bundle when external lua requests it", () => { + util.testModule` + export { foo } from "./lualibuser"; + ` + .addExtraFile( + "lualibuser.d.ts", + ` + export const foo: string[]; + ` + ) + .addExtraFile( + "lualibuser.lua", + ` + require("lualib_bundle") + + local result = {} + __TS__ArrayPush(result, "foo") + __TS__ArrayPush(result, "bar") + + return { foo = result } + ` + ) + .expectToEqual({ + foo: ["foo", "bar"], }); }); diff --git a/test/util.ts b/test/util.ts index b7f285777..55f06d6ac 100644 --- a/test/util.ts +++ b/test/util.ts @@ -9,7 +9,7 @@ import * as ts from "typescript"; import * as vm from "vm"; import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; -import { getEmitOutDir, transpileProject } from "../src"; +import { EmitHost, getEmitOutDir, transpileProject } from "../src"; import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); @@ -190,11 +190,22 @@ export abstract class TestBuilder { ); } + private getEmitHost(): EmitHost { + return { + fileExists: (path: string) => normalizeSlashes(path) in this.extraFiles, + directoryExists: (path: string) => + Object.keys(this.extraFiles).some(f => f.startsWith(normalizeSlashes(path))), + getCurrentDirectory: () => ".", + readFile: (path: string) => this.extraFiles[normalizeSlashes(path)] ?? ts.sys.readFile(path), + writeFile() {}, + }; + } + @memoize public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); const collector = createEmitOutputCollector(); - const { diagnostics: transpileDiagnostics } = new tstl.Transpiler().emit({ + const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({ program, customTransformers: this.customTransformers, writeFile: collector.writeFile, From e401bff833a8711e05429624b5d40b239c5e9c7e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Aug 2021 21:51:06 +0200 Subject: [PATCH 377/764] Deprecated @tupleReturn and various lualib improvements (#1075) * Add test for lualib dependencies and refactor tupleReturn/multiReturn * Deprecated @tupleReturn * No longer add not needed tostring calls to string += statements * upgrade lua-types version to one without @tupleReturn * Fix linter and make execution not fail when there are only warning diagnostics * Fix benchmark code for new lua-types * Disable benchmark workflow --- .github/workflows/ci.yml | 154 +++++++++--------- benchmark/src/util.ts | 13 +- package-lock.json | 52 +++++- package.json | 2 +- src/LuaLib.ts | 15 +- src/lualib/ArrayIsArray.ts | 2 + src/lualib/ArrayReduce.ts | 16 +- src/lualib/ArrayReduceRight.ts | 16 +- src/lualib/ArraySplice.ts | 8 +- src/lualib/Generator.ts | 2 +- src/lualib/Iterator.ts | 30 ++-- src/lualib/ObjectDefineProperty.ts | 4 +- src/lualib/ParseFloat.ts | 4 +- src/lualib/ParseInt.ts | 6 +- src/lualib/SetDescriptor.ts | 2 +- src/lualib/SourceMapTraceBack.ts | 4 +- src/lualib/Spread.ts | 4 +- src/lualib/Symbol.ts | 2 +- src/lualib/declarations/coroutine.d.ts | 19 --- src/lualib/declarations/debug.d.ts | 23 --- src/lualib/declarations/global.d.ts | 32 ---- src/lualib/declarations/math.d.ts | 14 -- src/lualib/declarations/string.d.ts | 23 --- src/lualib/declarations/table.d.ts | 8 - src/lualib/declarations/tstl.d.ts | 15 +- src/lualib/tsconfig.json | 2 +- src/transformation/utils/annotations.ts | 10 +- src/transformation/visitors/access.ts | 15 +- .../visitors/binary-expression/assignments.ts | 14 +- .../visitors/binary-expression/index.ts | 9 +- src/transformation/visitors/call.ts | 15 +- .../visitors/language-extensions/multi.ts | 12 +- src/transformation/visitors/return.ts | 8 +- src/transformation/visitors/spread.ts | 7 +- .../visitors/variable-declaration.ts | 7 +- src/tstl.ts | 2 +- test/transpile/lualib.spec.ts | 26 +++ test/unit/annotations/tupleReturn.spec.ts | 45 ++++- test/unit/assignments.spec.ts | 9 +- test/unit/error.spec.ts | 38 ++--- .../unit/language-extensions/iterable.spec.ts | 72 ++++---- test/unit/language-extensions/multi.spec.ts | 48 +++--- test/unit/language-extensions/range.spec.ts | 16 +- test/unit/language-extensions/table.spec.ts | 55 +++---- test/unit/language-extensions/vararg.spec.ts | 10 +- test/unit/spread.spec.ts | 12 +- test/util.ts | 9 + 47 files changed, 451 insertions(+), 460 deletions(-) delete mode 100644 src/lualib/declarations/coroutine.d.ts delete mode 100644 src/lualib/declarations/debug.d.ts delete mode 100644 src/lualib/declarations/global.d.ts delete mode 100644 src/lualib/declarations/math.d.ts delete mode 100644 src/lualib/declarations/string.d.ts delete mode 100644 src/lualib/declarations/table.d.ts create mode 100644 test/transpile/lualib.spec.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 968cd9b87..b0e0bf6cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,80 +39,80 @@ jobs: - if: matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v1 - benchmark: - name: Benchmark - runs-on: ubuntu-latest - steps: - - name: Lua Install - run: sudo apt-get install lua5.3 luajit - - name: Glow Install - run: brew install glow - # Checkout master & commit - - name: Checkout master - uses: actions/checkout@v2 - with: - ref: master - path: master - - name: Checkout commit - uses: actions/checkout@v2 - with: - path: commit - - name: Use Node.js 12.13.1 - uses: actions/setup-node@v1 - with: - node-version: 12.13.1 - # NPM - - name: NPM master - run: npm ci && npm run build - working-directory: master - - name: NPM commit - run: npm ci && npm run build - working-directory: commit - # Benchmark directory setup - - name: Ensure benchmark data dir exists - run: mkdir -p ./benchmark/data - working-directory: commit - - name: Copy commit benchmark to master - run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark - # Run master benchmark first and output to commit benchmark data - - name: Build benchmark Lua 5.3 master - run: node ../../commit/dist/tstl.js -p tsconfig.53.json - working-directory: master/benchmark - - name: Run benchmark Lua 5.3 master - id: benchmark-lua-master - run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json - working-directory: master/benchmark/dist - - name: Build benchmark LuaJIT master - run: node ../../commit/dist/tstl.js -p tsconfig.jit.json - working-directory: master/benchmark - - name: Run benchmark LuaJIT master - id: benchmark-jit-master - run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json - working-directory: master/benchmark/dist - # Run commit benchmark and compare with master - - name: Build benchmark Lua 5.3 commit - run: node ../../commit/dist/tstl.js -p tsconfig.53.json - working-directory: commit/benchmark - - name: Run benchmark Lua 5.3 commit - id: benchmark-lua-commit - run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json - working-directory: commit/benchmark/dist - - name: Build benchmark LuaJIT commit - run: node ../../commit/dist/tstl.js -p tsconfig.jit.json - working-directory: commit/benchmark - - name: Run benchmark LuaJIT commit - id: benchmark-jit-commit - run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json - working-directory: commit/benchmark/dist - - name: Combine benchmark results - id: script-combine-results - uses: actions/github-script@v3 - with: - benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json - benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json - result-encoding: string - script: | - const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); - return createBenchmarkCheck({ github, context, core }); - - name: Benchmark results - run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - + # benchmark: + # name: Benchmark + # runs-on: ubuntu-latest + # steps: + # - name: Lua Install + # run: sudo apt-get install lua5.3 luajit + # - name: Glow Install + # run: brew install glow + # # Checkout master & commit + # - name: Checkout master + # uses: actions/checkout@v2 + # with: + # ref: master + # path: master + # - name: Checkout commit + # uses: actions/checkout@v2 + # with: + # path: commit + # - name: Use Node.js 12.13.1 + # uses: actions/setup-node@v1 + # with: + # node-version: 12.13.1 + # # NPM + # - name: NPM master + # run: npm ci && npm run build + # working-directory: master + # - name: NPM commit + # run: npm ci && npm run build + # working-directory: commit + # # Benchmark directory setup + # - name: Ensure benchmark data dir exists + # run: mkdir -p ./benchmark/data + # working-directory: commit + # - name: Copy commit benchmark to master + # run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark + # # Run master benchmark first and output to commit benchmark data + # - name: Build benchmark Lua 5.3 master + # run: node ../../commit/dist/tstl.js -p tsconfig.53.json + # working-directory: master/benchmark + # - name: Run benchmark Lua 5.3 master + # id: benchmark-lua-master + # run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json + # working-directory: master/benchmark/dist + # - name: Build benchmark LuaJIT master + # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + # working-directory: master/benchmark + # - name: Run benchmark LuaJIT master + # id: benchmark-jit-master + # run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json + # working-directory: master/benchmark/dist + # # Run commit benchmark and compare with master + # - name: Build benchmark Lua 5.3 commit + # run: node ../../commit/dist/tstl.js -p tsconfig.53.json + # working-directory: commit/benchmark + # - name: Run benchmark Lua 5.3 commit + # id: benchmark-lua-commit + # run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json + # working-directory: commit/benchmark/dist + # - name: Build benchmark LuaJIT commit + # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + # working-directory: commit/benchmark + # - name: Run benchmark LuaJIT commit + # id: benchmark-jit-commit + # run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json + # working-directory: commit/benchmark/dist + # - name: Combine benchmark results + # id: script-combine-results + # uses: actions/github-script@v3 + # with: + # benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json + # benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json + # result-encoding: string + # script: | + # const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); + # return createBenchmarkCheck({ github, context, core }); + # - name: Benchmark results + # run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - diff --git a/benchmark/src/util.ts b/benchmark/src/util.ts index bd1c0a10f..41f2159f5 100644 --- a/benchmark/src/util.ts +++ b/benchmark/src/util.ts @@ -30,16 +30,21 @@ export function readFile(path: string): string { } export function readAll(file: LuaFile): string { - const content = file.read(_VERSION === "Lua 5.3" ? "a" : ("*a" as any)) as [string | undefined]; + const content = file.read(_VERSION === "Lua 5.3" ? "a" : ("*a" as any)); - if (content[0]) { - return content[0]; + if (content) { + return content as string; } throw Error(`Can't readAll for file ${file}`); } export function readDir(dir: string): string[] { - const findHandle = io.popen(isWindows ? `dir /A-D /B ${dir}` : `find '${dir}' -maxdepth 1 -type f`); + const [findHandle] = io.popen(isWindows ? `dir /A-D /B ${dir}` : `find '${dir}' -maxdepth 1 -type f`); + + if (!findHandle) { + throw new Error(`Failed to read dir ${dir}`); + } + const findResult = readAll(findHandle); if (!findHandle.close()) { diff --git a/package-lock.json b/package-lock.json index d7055278b..0c5c4360c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", - "lua-types": "^2.8.0", + "lua-types": "^2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^26.3.0", @@ -8883,10 +8883,13 @@ } }, "node_modules/lua-types": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", - "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", - "dev": true + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "dev": true, + "dependencies": { + "typescript-to-lua": "^0.39.0" + } }, "node_modules/lua-wasm-bindings": { "version": "0.2.2", @@ -11253,6 +11256,23 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-to-lua": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", + "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "dev": true, + "dependencies": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.2" + }, + "bin": { + "tstl": "dist/tstl.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -18733,10 +18753,13 @@ } }, "lua-types": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.8.0.tgz", - "integrity": "sha512-FJY32giHIqD/XW1XGkJnl8XotXIJsJ2M42fj9A2UudttWA6orJioToW1OpgPdayTr+S1/oTO7i+hfBY3UVG8Fg==", - "dev": true + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "dev": true, + "requires": { + "typescript-to-lua": "^0.39.0" + } }, "lua-wasm-bindings": { "version": "0.2.2", @@ -20591,6 +20614,17 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" }, + "typescript-to-lua": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", + "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "dev": true, + "requires": { + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.2" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", diff --git a/package.json b/package.json index fa3fc0575..b47d02558 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", - "lua-types": "^2.8.0", + "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^26.3.0", diff --git a/src/LuaLib.ts b/src/LuaLib.ts index e1a8d9efd..96f58ab7a 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -96,22 +96,27 @@ const luaLibDependencies: Partial> = { ArrayConcat: [LuaLibFeature.ArrayIsArray], ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], - Decorate: [LuaLibFeature.CloneDescriptor], + Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], + DelegatedYield: [LuaLibFeature.StringAccess], Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], - Error: [LuaLibFeature.New, LuaLibFeature.Class], + Error: [LuaLibFeature.Class, LuaLibFeature.ClassExtends, LuaLibFeature.New], FunctionBind: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], InstanceOf: [LuaLibFeature.Symbol], Iterator: [LuaLibFeature.Symbol], + NumberToString: [LuaLibFeature.StringAccess], ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], + ParseFloat: [LuaLibFeature.StringAccess], + ParseInt: [LuaLibFeature.StringSubstr, LuaLibFeature.StringSubstring], + SetDescriptor: [LuaLibFeature.CloneDescriptor], + StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], + SymbolRegistry: [LuaLibFeature.Symbol], Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - Spread: [LuaLibFeature.Iterator, LuaLibFeature.Unpack], - StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], - SymbolRegistry: [LuaLibFeature.Symbol], + Spread: [LuaLibFeature.Iterator, LuaLibFeature.StringAccess, LuaLibFeature.Unpack], }; /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts index 38a4525ef..d981ec0f2 100644 --- a/src/lualib/ArrayIsArray.ts +++ b/src/lualib/ArrayIsArray.ts @@ -1,3 +1,5 @@ +declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; + function __TS__ArrayIsArray(this: void, value: any): value is any[] { // Workaround to determine if value is an array or not (fails in case of objects without keys) // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/7 diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index c8ea2de50..5ac7bd856 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,20 +1,20 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduce( +function __TS__ArrayReduce( this: void, - arr: T[], - callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: T[] -): T { + arr: TElement[], + callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, + ...initial: TAccumulator[] +): TAccumulator { const len = arr.length; let k = 0; - let accumulator = undefined; + let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - accumulator = select(1, ...initial); + [accumulator] = select(1, ...initial); } else if (len > 0) { - accumulator = arr[0]; + accumulator = arr[0] as unknown as TAccumulator; k = 1; } else { throw "Reduce of empty array with no initial value"; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index a0d5933d2..26258b862 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,20 +1,20 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduceRight( +function __TS__ArrayReduceRight( this: void, - arr: T[], - callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T, - ...initial: T[] -): T { + arr: TElement[], + callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, + ...initial: TAccumulator[] +): TAccumulator { const len = arr.length; let k = len - 1; - let accumulator = undefined; + let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - accumulator = select(1, ...initial); + [accumulator] = select(1, ...initial); } else if (len > 0) { - accumulator = arr[k]; + accumulator = arr[k] as unknown as TAccumulator; k -= 1; } else { throw "Reduce of empty array with no initial value"; diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 0fae685e8..d4a122181 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,10 +1,10 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: unknown[]): T[] { +function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); - const start = select(1, ...args) as number; - const deleteCount = select(2, ...args) as number; + const start = select(1, ...args)[0] as unknown as number; + const deleteCount = select(2, ...args)[0] as unknown as number; let actualStart: number; @@ -67,7 +67,7 @@ function __TS__ArraySplice(this: void, list: T[], ...args: unknown[]): T[] { let j = actualStart; for (const i of $range(3, actualArgumentCount)) { - list[j] = select(i, ...args) as T; + list[j] = select(i, ...args)[0]; j++; } diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index 1573f5ec3..1e18f2e25 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -23,7 +23,7 @@ function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil - ____coroutine: coroutine.create(() => fn((unpack || table.unpack)(args, 1, argsLength))), + ____coroutine: coroutine.create(() => fn(...(unpack ?? table.unpack)(args, 1, argsLength))), [Symbol.iterator]: __TS__GeneratorIterator, next: __TS__GeneratorNext, }; diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index d6112cd88..29da08683 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,40 +1,36 @@ -/** @tupleReturn */ -function __TS__IteratorGeneratorStep(this: GeneratorIterator): [true, any] | [] { +function __TS__IteratorGeneratorStep(this: GeneratorIterator): LuaMultiReturn<[true, any] | []> { const co = this.____coroutine; const [status, value] = coroutine.resume(co); if (!status) throw value; - if (coroutine.status(co) === "dead") return []; - return [true, value]; + if (coroutine.status(co) === "dead") return $multi(); + return $multi(true, value); } -/** @tupleReturn */ -function __TS__IteratorIteratorStep(this: Iterator): [true, T] | [] { +function __TS__IteratorIteratorStep(this: Iterator): LuaMultiReturn<[true, T] | []> { const result = this.next(); - if (result.done) return []; - return [true, result.value]; + if (result.done) return $multi(); + return $multi(true, result.value); } -/** @tupleReturn */ -function __TS__IteratorStringStep(this: string, index: number): [number, string] | [] { +function __TS__IteratorStringStep(this: string, index: number): LuaMultiReturn<[number, string] | []> { index += 1; - if (index > this.length) return []; - return [index, string.sub(this, index, index)]; + if (index > this.length) return $multi(); + return $multi(index, string.sub(this, index, index)); } -/** @tupleReturn */ function __TS__Iterator( this: void, iterable: string | GeneratorIterator | Iterable | readonly T[] -): [(...args: any[]) => [any, any] | [], ...any[]] | LuaIterable> { +): LuaMultiReturn<[(...args: any[]) => [any, any] | [], ...any[]]> | LuaIterable> { if (typeof iterable === "string") { - return [__TS__IteratorStringStep, iterable, 0]; + return $multi(__TS__IteratorStringStep, iterable, 0); } else if ("____coroutine" in iterable) { - return [__TS__IteratorGeneratorStep, iterable]; + return $multi(__TS__IteratorGeneratorStep, iterable); } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); - return [__TS__IteratorIteratorStep, iterator]; + return $multi(__TS__IteratorIteratorStep, iterator); } else { return ipairs(iterable as readonly T[]); } diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index e9aa599d5..f37b36c2a 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,5 +1,7 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { + +// eslint-disable-next-line @typescript-eslint/ban-types +function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { const luaKey = typeof key === "number" ? key + 1 : key; const value = rawget(target, luaKey); diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts index 1cd069111..0c6d04d65 100644 --- a/src/lualib/ParseFloat.ts +++ b/src/lualib/ParseFloat.ts @@ -1,11 +1,11 @@ function __TS__ParseFloat(this: void, numberString: string): number { // Check if string is infinity - const infinityMatch = string.match(numberString, "^%s*(-?Infinity)"); + const [infinityMatch] = string.match(numberString, "^%s*(-?Infinity)"); if (infinityMatch) { // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with return infinityMatch[0] === "-" ? -Infinity : Infinity; } - const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")); + const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")[0]); return number ?? NaN; } diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index b1d5710a0..cb1d851f4 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -4,10 +4,10 @@ function __TS__ParseInt(this: void, numberString: string, base?: number): number // Check which base to use if none specified if (base === undefined) { base = 10; - const hexMatch = string.match(numberString, "^%s*-?0[xX]"); + const [hexMatch] = string.match(numberString, "^%s*-?0[xX]"); if (hexMatch) { base = 16; - numberString = string.match(hexMatch, "-") + numberString = string.match(hexMatch, "-")[0] ? "-" + numberString.substr(hexMatch.length) : numberString.substr(hexMatch.length); } @@ -26,7 +26,7 @@ function __TS__ParseInt(this: void, numberString: string, base?: number): number const pattern = `^%s*(-?[${allowedDigits}]*)`; // Try to parse with Lua tonumber - const number = tonumber(string.match(numberString, pattern), base); + const number = tonumber(string.match(numberString, pattern)[0], base); if (number === undefined) { return NaN; diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 49c7a0bf2..5659848d5 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -6,7 +6,7 @@ function ____descriptorIndex(this: any, key: string): void { let metatable = getmetatable(this); while (metatable) { - const rawResult = rawget(metatable, key); + const rawResult = rawget(metatable, key as any); if (rawResult !== undefined) { return rawResult; } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 3a264ead9..bf718a9b0 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -6,7 +6,7 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li if (globalThis.__TS__originalTraceback === undefined) { globalThis.__TS__originalTraceback = debug.traceback; - debug.traceback = (thread, message, level) => { + debug.traceback = ((thread, message, level) => { let trace: string; if (thread === undefined && message === undefined && level === undefined) { trace = globalThis.__TS__originalTraceback(); @@ -27,6 +27,6 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li }); return result; - }; + }) as typeof debug.traceback; } } diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 2bc96395b..6bc3bf628 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,4 +1,4 @@ -function __TS__Spread(this: void, iterable: string | Iterable): T[] { +function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { const arr = []; if (typeof iterable === "string") { // eslint-disable-next-line @typescript-eslint/prefer-for-of @@ -10,5 +10,5 @@ function __TS__Spread(this: void, iterable: string | Iterable): T[] { arr[arr.length] = item; } } - return __TS__Unpack(arr); + return $multi(...arr); } diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 61a5c0423..41be3fc28 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -5,7 +5,7 @@ const ____symbolMetatable = { }; function __TS__Symbol(this: void, description?: string | number): symbol { - return setmetatable({ description }, ____symbolMetatable) as any; + return setmetatable({ description }, ____symbolMetatable) as symbol; } Symbol = { diff --git a/src/lualib/declarations/coroutine.d.ts b/src/lualib/declarations/coroutine.d.ts deleted file mode 100644 index 1e648d6c8..000000000 --- a/src/lualib/declarations/coroutine.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** @noSelfInFile */ - -interface LuaThread { - readonly __internal__: unique symbol; -} - -declare namespace coroutine { - function create(f: (...args: any[]) => any): LuaThread; - - /** @tupleReturn */ - function resume(co: LuaThread, ...val: any[]): [true, ...any[]] | [false, string]; - - function status(co: LuaThread): "running" | "suspended" | "normal" | "dead"; - - function wrap(f: (...args: any[]) => any): /** @tupleReturn */ (...args: any[]) => any[]; - - /** @tupleReturn */ - function yield(...args: any[]): any[]; -} diff --git a/src/lualib/declarations/debug.d.ts b/src/lualib/declarations/debug.d.ts deleted file mode 100644 index 2333f95d4..000000000 --- a/src/lualib/declarations/debug.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** @noSelfInFile */ - -declare const _VERSION: string; -declare function error(...args: any[]): never; - -declare namespace debug { - function traceback(...args: any[]): string; - - interface FunctionInfo any = () => any> { - func: T; - name?: string; - namewhat: "global" | "local" | "method" | "field" | ""; - source: string; - short_src: string; - linedefined: number; - lastlinedefined: number; - what: "Lua" | "C" | "main"; - currentline: number; - nups: number; - } - - function getinfo(i: number, what?: string): Partial; -} diff --git a/src/lualib/declarations/global.d.ts b/src/lualib/declarations/global.d.ts deleted file mode 100644 index 488586275..000000000 --- a/src/lualib/declarations/global.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -/* eslint-disable no-var */ -/** @noSelfInFile */ - -type AnyTable = Record; -// eslint-disable-next-line -type AnyNotNil = {}; - -declare var __TS__sourcemap: Record | undefined; -declare var __TS__originalTraceback: - | ((this: void, thread?: any, message?: string, level?: number) => string) - | undefined; - -// Override next declaration so we can omit extra return values -declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; - -declare function tonumber(value: any, base?: number): number | undefined; -declare function type( - value: any -): "nil" | "number" | "string" | "boolean" | "table" | "function" | "thread" | "userdata"; -declare function setmetatable(table: T, metatable: any): T; -declare function getmetatable(table: T): any; -declare function rawget(table: T, key: K): T[K]; -declare function rawset(table: T, key: K, val: T[K]): void; -/** @tupleReturn */ -declare function next(table: Record, index?: K): [K, V]; -declare function pcall(func: () => any): any; -declare function unpack(list: T[], i?: number, j?: number): T[]; - -declare function select(index: number, ...args: T[]): T; -declare function select(index: "#", ...args: T[]): number; - -declare function ipairs(t: Record): LuaIterable, Record>; diff --git a/src/lualib/declarations/math.d.ts b/src/lualib/declarations/math.d.ts deleted file mode 100644 index 54568c031..000000000 --- a/src/lualib/declarations/math.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** @noSelf */ -declare namespace math { - /** @tupleReturn */ - function modf(x: number): [number, number]; - - function atan(x: number): number; - // eslint-disable-next-line @typescript-eslint/unified-signatures - function atan(y: number, x?: number): number; - - function atan2(y: number, x: number): number; - - function ceil(x: number): number; - function floor(x: number): number; -} diff --git a/src/lualib/declarations/string.d.ts b/src/lualib/declarations/string.d.ts deleted file mode 100644 index ed5aa27e5..000000000 --- a/src/lualib/declarations/string.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/** @noSelf */ -declare namespace string { - function byte(s: string, i?: number): number | undefined; - /** @tupleReturn */ - function byte(s: string, i?: number, j?: number): number[]; - - /** @tupleReturn */ - function gsub( - source: string, - searchValue: string, - replaceValue: string | ((...groups: string[]) => string), - n?: number - ): [string, number]; - function sub(s: string, i: number, j?: number): string; - function format(formatstring: string, ...args: any[]): string; - function match(string: string, pattern: string): string; - function find( - string: string, - pattern: string, - start?: number, - plainflag?: boolean - ): LuaMultiReturn<[number, number] | [undefined]>; -} diff --git a/src/lualib/declarations/table.d.ts b/src/lualib/declarations/table.d.ts deleted file mode 100644 index 776fe72b0..000000000 --- a/src/lualib/declarations/table.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -/** @noSelfInFile */ - -declare namespace table { - function sort(list: T[], compareFn?: (a: T, b: T) => boolean): void; - function remove(list: T[], idx: number): T; - function insert(list: T[], idx: number, val: T): void; - function unpack(list: T[], i?: number, j?: number): T[]; -} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index f68237190..90a3283ef 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -1,18 +1,27 @@ /** @noSelfInFile */ -interface Metatable { +interface LuaMetatable { _descriptors?: Record; __index?: any; __newindex?: any; __tostring?: any; + __errorToStringPatched?: boolean; } -interface LuaClass extends Metatable { +interface LuaClass extends LuaMetatable { prototype: LuaClassInstance; [Symbol.hasInstance]?(instance: LuaClassInstance): any; ____super?: LuaClass; } -interface LuaClassInstance extends Metatable { +interface LuaClassInstance extends LuaMetatable { constructor: LuaClass; } + +// Declare unpack for versions that have it instead of table.unpack +declare const unpack: typeof table.unpack | undefined; + +// Declare math atan2 for versions that have it instead of math.atan +declare namespace math { + const atan2: typeof atan; +} diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index f16968dc1..f9d65a555 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "../../dist/lualib", "target": "esnext", "lib": ["esnext"], - "types": ["../../language-extensions"], + "types": ["../../language-extensions", "lua-types/5.4"], "skipLibCheck": true, "noUnusedLocals": true, diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index d07df2808..a64b13788 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; +import { annotationDeprecated } from "./diagnostics"; import { findFirstNodeAbove, inferAssignedType } from "./typescript"; export enum AnnotationKind { @@ -117,6 +118,7 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) const signature = context.checker.getResolvedSignature(node); if (signature) { if (getSignatureAnnotations(context, signature).has(AnnotationKind.TupleReturn)) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.TupleReturn)); return true; } @@ -132,7 +134,13 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) } const type = context.checker.getTypeAtLocation(node.expression); - return getTypeAnnotations(type).has(AnnotationKind.TupleReturn); + const result = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); + + if (result) { + context.diagnostics.push(annotationDeprecated(node, AnnotationKind.TupleReturn)); + } + + return result; } export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 8b795426b..389bbde5f 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -8,7 +8,7 @@ import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; -import { returnsMultiType } from "./language-extensions/multi"; +import { isMultiReturnCall, returnsMultiType } from "./language-extensions/multi"; export function transformElementAccessArgument( context: TransformationContext, @@ -42,15 +42,20 @@ export const transformElementAccessExpression: FunctionVisitor context.transformExpression(e)); + } else if (!isMultiReturnCall(context, expression.right) && isArrayType(context, rightType)) { right = createUnpackCall(context, right, expression.right); } @@ -219,7 +217,7 @@ export function transformAssignmentStatement( } let right = context.transformExpression(expression.right); - if (isTupleReturnCall(context, expression.right) || isMultiReturnCall(context, expression.right)) { + if (isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index ce73a7a70..93ea66018 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -63,9 +63,12 @@ export function transformBinaryOperation( if (operator === ts.SyntaxKind.PlusToken && ts.isBinaryExpression(node)) { const typeLeft = context.checker.getTypeAtLocation(node.left); const typeRight = context.checker.getTypeAtLocation(node.right); - if (isStringType(context, typeLeft) || isStringType(context, typeRight)) { - left = wrapInToStringForConcat(left); - right = wrapInToStringForConcat(right); + + const isLeftString = isStringType(context, typeLeft); + const isRightString = isStringType(context, typeRight); + if (isLeftString || isRightString) { + left = isLeftString ? left : wrapInToStringForConcat(left); + right = isRightString ? right : wrapInToStringForConcat(right); luaOperator = lua.SyntaxKind.ConcatOperator; } } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index ced618c4c..7add12ddc 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,15 +2,15 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations, isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; -import { isExpressionWithEvaluationEffect, isInDestructingAssignment } from "../utils/typescript"; +import { isExpressionWithEvaluationEffect } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; -import { shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; +import { isMultiReturnCall, shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; import { isTableDeleteCall, @@ -241,14 +241,7 @@ function transformElementCall( } export const transformCallExpression: FunctionVisitor = (node, context) => { - const isTupleReturn = isTupleReturnCall(context, node); - const isTupleReturnForward = - node.parent && ts.isReturnStatement(node.parent) && isInTupleReturnFunction(context, node); - const isInSpread = node.parent && ts.isSpreadElement(node.parent); - const returnValueIsUsed = node.parent && !ts.isExpressionStatement(node.parent); - const wrapTupleReturn = - isTupleReturn && !isTupleReturnForward && !isInDestructingAssignment(node) && !isInSpread && returnValueIsUsed; - const wrapResultInTable = wrapTupleReturn || shouldMultiReturnCallBeWrapped(context, node); + const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); const wrapResultInOptional = ts.isOptionalChain(node); const builtinResult = transformBuiltinCallExpression(context, node); diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index a433cd3f4..edf3a1650 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -4,11 +4,16 @@ import { TransformationContext } from "../../context"; import { findFirstNodeAbove } from "../../utils/typescript"; import { isIterableExpression } from "./iterable"; import { invalidMultiFunctionUse } from "../../utils/diagnostics"; +import { isTupleReturnCall } from "../../utils/annotations"; export function isMultiReturnType(type: ts.Type): boolean { return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); } +export function canBeMultiReturnType(type: ts.Type): boolean { + return isMultiReturnType(type) || (type.isUnion() && type.types.some(canBeMultiReturnType)); +} + export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { return isMultiFunctionNode(context, expression.expression); } @@ -20,7 +25,10 @@ export function returnsMultiType(context: TransformationContext, node: ts.CallEx } export function isMultiReturnCall(context: TransformationContext, expression: ts.Expression) { - return ts.isCallExpression(expression) && returnsMultiType(context, expression); + return ( + (ts.isCallExpression(expression) && returnsMultiType(context, expression)) || + isTupleReturnCall(context, expression) + ); } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { @@ -39,7 +47,7 @@ export function isInMultiReturnFunction(context: TransformationContext, node: ts } export function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression) { - if (!returnsMultiType(context, node)) { + if (!returnsMultiType(context, node) && !isTupleReturnCall(context, node)) { return false; } diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index f309874f7..a3eff9ec7 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction, isTupleReturnCall } from "../utils/annotations"; +import { isInTupleReturnFunction } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; @@ -13,6 +13,8 @@ import { isMultiFunctionCall, isMultiReturnType, isInMultiReturnFunction, + isMultiReturnCall, + canBeMultiReturnType, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; @@ -28,7 +30,7 @@ function transformExpressionsInReturn( if (isMultiFunctionCall(context, node)) { // Don't allow $multi to be implicitly cast to something other than LuaMultiReturn const type = context.checker.getContextualType(node); - if (type && !isMultiReturnType(type)) { + if (type && !canBeMultiReturnType(type)) { context.diagnostics.push(invalidMultiFunctionReturnType(node)); } @@ -58,7 +60,7 @@ function transformExpressionsInReturn( if (ts.isArrayLiteralExpression(node)) { // If return expression is an array literal, leave out brackets. results = node.elements.map(e => context.transformExpression(e)); - } else if (!isTupleReturnCall(context, node) && isArrayType(context, expressionType)) { + } else if (!isMultiReturnCall(context, node) && isArrayType(context, expressionType)) { // If return expression is an array-type and not another TupleReturn call, unpack it results = [createUnpackCall(context, context.transformExpression(node), node)]; } else { diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index d9da3ce44..6e6ec391a 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, isTupleReturnCall, isVarargType } from "../utils/annotations"; +import { AnnotationKind, isVarargType } from "../utils/annotations"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { @@ -12,7 +12,7 @@ import { ScopeType, } from "../utils/scope"; import { isArrayType } from "../utils/typescript"; -import { returnsMultiType } from "./language-extensions/multi"; +import { isMultiReturnCall } from "./language-extensions/multi"; import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; @@ -69,8 +69,7 @@ export const transformSpreadElement: FunctionVisitor = (node, } const innerExpression = context.transformExpression(node.expression); - if (isTupleReturnCall(context, node.expression)) return innerExpression; - if (ts.isCallExpression(node.expression) && returnsMultiType(context, node.expression)) return innerExpression; + if (isMultiReturnCall(context, node.expression)) return innerExpression; const type = context.checker.getTypeAtLocation(node.expression); if (isArrayType(context, type)) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 708857741..4782fd157 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assert, assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; @@ -159,7 +158,7 @@ export function transformBindingVariableDeclaration( table = lua.createAnonymousIdentifier(); if (initializer) { let expression = context.transformExpression(initializer); - if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { + if (isMultiReturnCall(context, initializer)) { expression = wrapInTable(expression); } statements.push(lua.createVariableDeclarationStatement(table, expression)); @@ -175,8 +174,8 @@ export function transformBindingVariableDeclaration( : lua.createAnonymousIdentifier(); if (initializer) { - if (isTupleReturnCall(context, initializer) || isMultiReturnCall(context, initializer)) { - // Don't unpack @tupleReturn or LuaMultiReturn functions + if (isMultiReturnCall(context, initializer)) { + // Don't unpack LuaMultiReturn functions statements.push( ...createLocalOrExportedOrGlobalDeclaration( context, diff --git a/src/tstl.ts b/src/tstl.ts index fb011be3c..d7b6d1df1 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -111,7 +111,7 @@ function performCompilation( diagnostics.forEach(reportDiagnostic); const exitCode = - diagnostics.length === 0 + diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error).length === 0 ? ts.ExitStatus.Success : emitSkipped ? ts.ExitStatus.DiagnosticsPresent_OutputsSkipped diff --git a/test/transpile/lualib.spec.ts b/test/transpile/lualib.spec.ts new file mode 100644 index 000000000..0af391c46 --- /dev/null +++ b/test/transpile/lualib.spec.ts @@ -0,0 +1,26 @@ +import * as ts from "typescript"; +import { LuaLibFeature } from "../../src"; +import { loadLuaLibFeatures } from "../../src/LuaLib"; + +test.each(Object.entries(LuaLibFeature))("Lualib feature has correct dependencies (%p)", (_, feature) => { + const lualibCode = loadLuaLibFeatures([feature], ts.sys); + + // Find all used lualib features + const luaLibReferences = lualibCode.match(/__TS__[a-zA-Z_]+\(/g); + + // For every reference lualib function, check if its definition is also included + const missingReferences = []; + + if (luaLibReferences !== null) { + for (const reference of luaLibReferences) { + if ( + !lualibCode.includes(`function ${reference}`) && + !lualibCode.includes(`${reference.substring(0, reference.length - 1)} =`) + ) { + missingReferences.push(reference); + } + } + } + + expect(missingReferences).toHaveLength(0); +}); diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts index 337e52c37..c5077a744 100644 --- a/test/unit/annotations/tupleReturn.spec.ts +++ b/test/unit/annotations/tupleReturn.spec.ts @@ -1,3 +1,4 @@ +import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const expectNoUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack"); @@ -9,6 +10,7 @@ test("Tuple Return Access", () => { return tuple()[2]; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -20,6 +22,7 @@ test("Tuple Return Destruct Declaration", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -32,6 +35,7 @@ test("Tuple Return Destruct Assignment", () => { return a - b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -45,6 +49,7 @@ test("Tuple Static Method Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -58,6 +63,7 @@ test("Tuple Static Function Property Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -72,6 +78,7 @@ test("Tuple Non-Static Method Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -86,6 +93,7 @@ test("Tuple Non-Static Function Property Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -102,6 +110,7 @@ test("Tuple Interface Method Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -118,6 +127,7 @@ test("Tuple Interface Function Property Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -131,6 +141,7 @@ test("Tuple Object Literal Method Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -144,6 +155,7 @@ test("Tuple Object Literal Function Property Return Destruct", () => { return b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -154,6 +166,7 @@ test("Tuple Return on Arrow Function", () => { return a + b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -165,6 +178,7 @@ test("Tuple Return Inference", () => { return a + b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -178,6 +192,7 @@ test("Tuple Return Inference as Argument", () => { return foo(s => [s, "bar"]); ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -191,6 +206,7 @@ test("Tuple Return Inference as Elipsis Argument", () => { return foo(0, s => [s, "bar"]); ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -204,6 +220,7 @@ test("Tuple Return Inference as Elipsis Tuple Argument", () => { return foo(0, 0, s => [s, "bar"]); ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -218,6 +235,7 @@ test("Tuple Return in Spread", () => { return bar(...foo()); ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -229,6 +247,7 @@ test("Tuple Return on Type Alias", () => { return a + b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -240,6 +259,7 @@ test("Tuple Return on Interface", () => { return a + b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -253,6 +273,7 @@ test("Tuple Return on Interface Signature", () => { return a + b; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -272,6 +293,7 @@ test("Tuple Return on Overload", () => { return a + b + c ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -293,6 +315,7 @@ test("Tuple Return on Interface Overload", () => { return a + b + c ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -316,6 +339,7 @@ test("Tuple Return on Interface Method Overload", () => { return a + b + c; ` .tap(expectNoUnpack) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToMatchJsResult(); }); @@ -342,6 +366,7 @@ test("Tuple Return vs Non-Tuple Return Overload", () => { ` .setTsHeader(tsHeader) .setLuaHeader(luaHeader) + .expectToHaveDiagnostics([annotationDeprecated.code]) .expectToEqual("7foobar"); }); @@ -353,7 +378,9 @@ test("TupleReturn assignment", () => { } let [a, b] = abc(); return { a, b }; - `.expectToMatchJsResult(); + ` + .expectToHaveDiagnostics([annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("TupleReturn Single assignment", () => { @@ -365,7 +392,9 @@ test("TupleReturn Single assignment", () => { let a = abc(); a = abc(); return a; - `.expectToMatchJsResult(); + ` + .expectToHaveDiagnostics([annotationDeprecated.code, annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("TupleReturn interface assignment", () => { @@ -410,7 +439,9 @@ test("TupleReturn functional", () => { function abc(): [number, string] { return [3, "a"]; } const [a, b] = abc(); return b + a; - `.expectToMatchJsResult(); + ` + .expectToHaveDiagnostics([annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("TupleReturn single", () => { @@ -419,7 +450,9 @@ test("TupleReturn single", () => { function abc(): [number, string] { return [3, "a"]; } const res = abc(); return res.length - `.expectToMatchJsResult(); + ` + .expectToHaveDiagnostics([annotationDeprecated.code]) + .expectToMatchJsResult(); }); test("TupleReturn in expression", () => { @@ -427,5 +460,7 @@ test("TupleReturn in expression", () => { /** @tupleReturn */ function abc(): [number, string] { return [3, "a"]; } return abc()[1] + abc()[0]; - `.expectToMatchJsResult(); + ` + .expectToHaveDiagnostics([annotationDeprecated.code, annotationDeprecated.code]) + .expectToMatchJsResult(); }); diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 5f9209c41..71a7503e2 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -94,16 +94,17 @@ test.each([ "[x[1], x[0]] = tr()", "x = [y[1], y[0]]", "[x[0], x[1]] = [y[1], y[0]]", -])("Tuple assignment expressions (%p)", expression => { +])("multi return assignment expressions (%p)", expression => { util.testFunction` let x: [string, string] = ["x0", "x1"]; let y: [string, string] = ["y0", "y1"]; function t(): [string, string] { return ["t0", "t1"] }; - /** @tupleReturn */ - function tr(): [string, string] { return ["tr0", "tr1"] }; + function tr(): LuaMultiReturn<[string, string]> { return $multi("tr0", "tr1"); }; const r = ${expression}; return \`\${r[0]},\${r[1]}\` - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 9174f941c..0c24503f0 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -77,18 +77,17 @@ test("return nil from try", () => { `.expectToMatchJsResult(); }); -test("tuple return from try", () => { +test("multi return from try", () => { const testBuilder = util.testFunction` - /** @tupleReturn */ function foobar() { try { - return ["foo", "bar"]; + return $multi("foo", "bar"); } catch { } } const [foo, bar] = foobar(); return foo + bar; - `; + `.withLanguageExtensions(); expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); testBuilder.expectToMatchJsResult(); }); @@ -122,19 +121,18 @@ test("return nil from catch", () => { `.expectToMatchJsResult(); }); -test("tuple return from catch", () => { +test("multi return from catch", () => { const testBuilder = util.testFunction` - /** @tupleReturn */ - function foobar(): [string, string] { + function foobar(): LuaMultiReturn<[string, string]> { try { throw "foobar"; } catch (e) { - return [e.toString(), " catch"]; + return $multi(e.toString(), " catch"); } } const [foo, bar] = foobar(); return foo + bar; - `; + `.withLanguageExtensions(); expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); testBuilder.expectToMatchJsResult(); }); @@ -210,47 +208,49 @@ test("return from catch->finally", () => { `.expectToMatchJsResult(); }); -test("tuple return from try->finally", () => { +test("multi return from try->finally", () => { util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; return arg; } - /** @tupleReturn */ function foobar() { try { - return [evaluate("foo"), "bar"]; + return $multi(evaluate("foo"), "bar"); } catch { } finally { - return ["final", "ly"]; + return $multi("final", "ly"); } } const [foo, bar] = foobar(); return foo + bar + " " + x; - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); -test("tuple return from catch->finally", () => { +test("multi return from catch->finally", () => { util.testFunction` let x = "unevaluated"; function evaluate(arg: string) { x = "evaluated"; return arg; } - /** @tupleReturn */ function foobar() { try { throw "foo"; } catch (e) { - return [evaluate(e), "bar"]; + return $multi(evaluate(e), "bar"); } finally { - return ["final", "ly"]; + return $multi("final", "ly"); } } const [foo, bar] = foobar(); return foo + bar + " " + x; - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test("return from nested finally", () => { diff --git a/test/unit/language-extensions/iterable.spec.ts b/test/unit/language-extensions/iterable.spec.ts index b6f7ab141..7d79db509 100644 --- a/test/unit/language-extensions/iterable.spec.ts +++ b/test/unit/language-extensions/iterable.spec.ts @@ -1,12 +1,6 @@ -import * as path from "path"; import * as util from "../../util"; -import * as tstl from "../../../src"; import { invalidMultiIterableWithoutDestructuring } from "../../../src/transformation/utils/diagnostics"; -const iterableProjectOptions: tstl.CompilerOptions = { - types: [path.resolve(__dirname, "../../../language-extensions")], -}; - describe("simple LuaIterable", () => { const testIterable = ` function testIterable(this: void): LuaIterable { @@ -26,7 +20,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -39,7 +33,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -53,7 +47,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -67,7 +61,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -81,7 +75,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -95,7 +89,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -113,7 +107,7 @@ describe("simple LuaIterable", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); }); @@ -136,7 +130,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -149,7 +143,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -163,7 +157,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -177,7 +171,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -191,7 +185,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -205,7 +199,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -223,7 +217,7 @@ describe("LuaIterable using state", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); }); @@ -251,7 +245,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -265,7 +259,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -279,7 +273,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -293,7 +287,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -307,7 +301,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -325,7 +319,7 @@ describe("LuaIterable with array value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); }); @@ -358,7 +352,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -372,7 +366,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -386,7 +380,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -400,7 +394,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -414,7 +408,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -432,7 +426,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -443,7 +437,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { ${testIterable} ${statement} ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidMultiIterableWithoutDestructuring.code]); } ); @@ -472,7 +466,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -486,7 +480,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -500,7 +494,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -514,7 +508,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -528,7 +522,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); @@ -546,7 +540,7 @@ describe("LuaIterable property", () => { } return results; ` - .setOptions(iterableProjectOptions) + .withLanguageExtensions() .expectToEqual(testResults); }); }); diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 5d59aa4d0..50784a3db 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -1,16 +1,10 @@ -import * as path from "path"; import * as util from "../../util"; -import * as tstl from "../../../src"; import { invalidMultiFunctionUse, invalidMultiReturnAccess, invalidMultiFunctionReturnType, } from "../../../src/transformation/utils/diagnostics"; -const multiProjectOptions: tstl.CompilerOptions = { - types: [path.resolve(__dirname, "../../../language-extensions")], -}; - test("multi example use case", () => { util.testModule` function multiReturn(): LuaMultiReturn<[string, number]> { @@ -20,7 +14,7 @@ test("multi example use case", () => { const [a, b] = multiReturn(); export { a, b }; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual({ a: "foo", b: 5 }); }); @@ -34,7 +28,7 @@ test("Destructuring assignment of LuaMultiReturn", () => { const [a, ...b] = multiReturn(); export {a, b}; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual({ a: 1, b: [2, 3] }); }); @@ -47,7 +41,7 @@ test("Destructuring assignment of LuaMultiReturn returning nil", () => { const [a, ...b] = multiReturn(); export {a, b}; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual({ a: undefined, b: [] }); }); @@ -59,7 +53,7 @@ test.each<[string, any]>([ util.testFunction` return ${expression}; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(result); }); @@ -88,7 +82,7 @@ test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi f ${statement} export { a }; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .setReturnExport("a") .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionUse.code]); }); @@ -101,7 +95,7 @@ test.each<[string, any]>(createCasesThatCall("multi"))( ${statement} export { a }; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .setReturnExport("a") .expectToEqual(result); } @@ -119,7 +113,7 @@ test.each<[string, number[]]>([ util.testModule` ${statement} ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot(diagnostics); }); @@ -131,7 +125,7 @@ test("function to spread multi type result from multi type function", () => { } return m(); ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(true); }); @@ -142,7 +136,7 @@ test("$multi call with destructuring assignment side effects", () => { export { a }; [a] = multi(1); ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .setReturnExport("a") .expectToEqual(1); }); @@ -153,7 +147,7 @@ test("allow $multi call in ArrowFunction body", () => { const [result] = call(); return result; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(1); }); @@ -164,7 +158,7 @@ test("forward $multi call", () => { const [resultA, resultB] = call(); return [resultA, resultB]; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual([1, 2]); }); @@ -175,7 +169,7 @@ test("forward $multi call indirect", () => { const [resultA, resultB] = call(); return [resultA, resultB]; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual([1, 2]); }); @@ -186,7 +180,7 @@ test("forward $multi call in ArrowFunction body", () => { const [resultA, resultB] = call(); return [resultA, resultB]; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual([1, 2]); }); @@ -196,7 +190,7 @@ test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => const i = 0; return multi(1)[${expression}]; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(1); }); @@ -205,7 +199,7 @@ test.each(["multi()['forEach']", "multi().forEach"])("disallow LuaMultiReturn no ${multiFunction} return ${expression}; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidMultiReturnAccess.code]); }); @@ -215,7 +209,7 @@ test("invalid $multi implicit cast", () => { return $multi("foo", 42); } ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidMultiFunctionReturnType.code]); }); @@ -236,7 +230,7 @@ test.each([ const [x, y] = multiOverload(${flag}); return y; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(result); }); @@ -251,7 +245,7 @@ test("return $multi from try", () => { const [_, a] = multiTest(); return a; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(2); }); @@ -267,7 +261,7 @@ test("return $multi from catch", () => { const [_, a] = multiTest(); return a; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(2); }); @@ -283,7 +277,7 @@ test("return LuaMultiReturn from try", () => { const [_, a] = multiTest(); return a; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(2); }); @@ -300,6 +294,6 @@ test("return LuaMultiReturn from catch", () => { const [_, a] = multiTest(); return a; ` - .setOptions(multiProjectOptions) + .withLanguageExtensions() .expectToEqual(2); }); diff --git a/test/unit/language-extensions/range.spec.ts b/test/unit/language-extensions/range.spec.ts index 56ac65251..3fc5539f6 100644 --- a/test/unit/language-extensions/range.spec.ts +++ b/test/unit/language-extensions/range.spec.ts @@ -1,12 +1,6 @@ -import * as path from "path"; import * as util from "../../util"; -import * as tstl from "../../../src"; import { invalidRangeControlVariable, invalidRangeUse } from "../../../src/transformation/utils/diagnostics"; -const rangeProjectOptions: tstl.CompilerOptions = { - types: [path.resolve(__dirname, "../../../language-extensions")], -}; - test("$range basic use", () => { util.testFunction` const result: number[] = []; @@ -15,7 +9,7 @@ test("$range basic use", () => { } return result; ` - .setOptions(rangeProjectOptions) + .withLanguageExtensions() .expectToEqual([1, 2, 3, 4, 5]); }); @@ -27,7 +21,7 @@ test("$range basic use with step", () => { } return result; ` - .setOptions(rangeProjectOptions) + .withLanguageExtensions() .expectToEqual([1, 3, 5, 7, 9]); }); @@ -39,7 +33,7 @@ test("$range basic use reverse", () => { } return result; ` - .setOptions(rangeProjectOptions) + .withLanguageExtensions() .expectToEqual([5, 4, 3, 2, 1]); }); @@ -48,7 +42,7 @@ test("$range invalid control variable", () => { let i: number; for (i of $range(1, 5)) {} ` - .setOptions(rangeProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidRangeControlVariable.code]); }); @@ -63,6 +57,6 @@ test.each([ util.testFunction` ${statement} ` - .setOptions(rangeProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidRangeUse.code]); }); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index e6d485a04..0c652dca9 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -1,16 +1,10 @@ -import * as path from "path"; import * as util from "../../util"; -import * as tstl from "../../../src"; import { invalidTableDeleteExpression, invalidTableExtensionUse, invalidTableSetExpression, } from "../../../src/transformation/utils/diagnostics"; -const tableProjectOptions: tstl.CompilerOptions = { - types: [path.resolve(__dirname, "../../../language-extensions")], -}; - describe("LuaTableGet & LuaTableSet extensions", () => { test("stand-alone function", () => { util.testModule` @@ -21,7 +15,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { const result = getTable(tbl, "foo"); export { result } ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .setReturnExport("result") .expectToEqual(3); }); @@ -37,7 +31,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { const result = Table.get(tbl, "foo"); export { result } ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .setReturnExport("result") .expectToEqual(3); }); @@ -53,7 +47,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { const result = tbl.get("foo"); export { result } ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .setReturnExport("result") .expectToEqual(3); }); @@ -69,7 +63,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { declare const getTable: LuaTableGet<{}, string, number>; ${statement} ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); }); @@ -83,7 +77,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { declare const setTable: LuaTableSet<{}, string, number>; ${expression} ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidTableSetExpression.code]); }); }); @@ -97,7 +91,7 @@ describe("LuaTableHas extension", () => { export const hasFoo = tableHas(table, "foo"); export const hasBaz = tableHas(table, "baz"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ hasFoo: true, hasBaz: false }); }); @@ -108,7 +102,7 @@ describe("LuaTableHas extension", () => { export const result = \`table has foo: \${tableHas(table, "foo")}\`; ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ result: "table has foo: true" }); }); @@ -122,7 +116,7 @@ describe("LuaTableHas extension", () => { export const hasFoo = Table.tableHas(table, "foo"); export const hasBaz = Table.tableHas(table, "baz"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ hasFoo: true, hasBaz: false }); }); @@ -138,7 +132,7 @@ describe("LuaTableHas extension", () => { export const hasFoo = table.has("foo"); export const hasBaz = table.has("baz"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ hasFoo: true, hasBaz: false }); }); @@ -158,7 +152,7 @@ describe("LuaTableHas extension", () => { export const numCalls = count; ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ numCalls: 1 }); }); @@ -173,7 +167,7 @@ describe("LuaTableHas extension", () => { declare const tableHas: LuaTableHas<{}, string>; ${statement} ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); }); }); @@ -186,7 +180,7 @@ describe("LuaTableDelete extension", () => { export const table = { foo: "bar", baz: "baz" }; tableDelete(table, "foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ table: { baz: "baz" } }); }); @@ -199,7 +193,7 @@ describe("LuaTableDelete extension", () => { export const table = { foo: "bar", baz: "baz" }; Table.tableDelete(table, "foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ table: { baz: "baz" } }); }); @@ -214,7 +208,7 @@ describe("LuaTableDelete extension", () => { table.set("bar", 12); table.delete("foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ table: { bar: 12 } }); }); @@ -228,7 +222,7 @@ describe("LuaTableDelete extension", () => { declare const tableDelete: LuaTableDelete<{}, string>; ${expression} ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidTableDeleteExpression.code]); }); }); @@ -240,7 +234,7 @@ describe("LuaTable extension interface", () => { tbl.set("foo", 3); return tbl.get("foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual(3); }); @@ -250,7 +244,7 @@ describe("LuaTable extension interface", () => { tbl.set("foo", 3); return tbl.get("foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual(3); }); @@ -263,7 +257,7 @@ describe("LuaTable extension interface", () => { } return fill(new LuaTable()).get("foo"); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual(3); }); @@ -271,7 +265,8 @@ describe("LuaTable extension interface", () => { "LuaTable in strict mode does not accept key type that could be nil (%p)", keyType => { util.testExpression`new LuaTable<${keyType}, unknown>()` - .setOptions({ ...tableProjectOptions, strict: true }) + .withLanguageExtensions() + .setOptions({ strict: true }) .expectToHaveDiagnostics() .expectDiagnosticsToMatchSnapshot(); } @@ -285,7 +280,7 @@ describe("LuaTable extension interface", () => { tbl.set(key, 3); return tbl.get(key); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual(3); }); @@ -296,7 +291,7 @@ describe("LuaTable extension interface", () => { tbl.set(3, "bar"); return tbl.length(); ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual(1); }); @@ -306,7 +301,7 @@ describe("LuaTable extension interface", () => { tbl.set(3, "foo"); return [tbl.has(1), tbl.has(3)]; ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual([false, true]); }); @@ -320,14 +315,14 @@ describe("LuaTable extension interface", () => { tbl.delete("foo"); return tbl; ` - .setOptions(tableProjectOptions) + .withLanguageExtensions() .expectToEqual({ baz: 5 }); }); test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( "table immediate access (%p)", statement => { - util.testFunction(statement).setOptions(tableProjectOptions).expectToHaveNoDiagnostics(); + util.testFunction(statement).withLanguageExtensions().expectToHaveNoDiagnostics(); } ); }); diff --git a/test/unit/language-extensions/vararg.spec.ts b/test/unit/language-extensions/vararg.spec.ts index f92cc0f96..18872c161 100644 --- a/test/unit/language-extensions/vararg.spec.ts +++ b/test/unit/language-extensions/vararg.spec.ts @@ -1,12 +1,6 @@ -import * as path from "path"; import * as util from "../../util"; -import * as tstl from "../../../src"; import { invalidVarargUse } from "../../../src/transformation/utils/diagnostics"; -const varargProjectOptions: tstl.CompilerOptions = { - types: [path.resolve(__dirname, "../../../language-extensions")], -}; - test.each([ 'const result = [...$vararg].join("")', 'let result: string; { result = [...$vararg].join(""); }', @@ -17,7 +11,7 @@ test.each([ ${statement} export { result }; ` - .setOptions(varargProjectOptions) + .withLanguageExtensions() .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toMatch("unpack")) .expectToEqual({ result: "ABCD" }); @@ -33,6 +27,6 @@ test.each([ util.testModule` ${statement} ` - .setOptions(varargProjectOptions) + .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]); }); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 5d7ed93a7..6b29d0cae 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -1,4 +1,3 @@ -import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import { formatCode } from "../util"; @@ -23,15 +22,16 @@ describe.each(["function call", "array literal"] as const)("in %s", kind => { util.testExpression(factory(expression)).expectToMatchJsResult(); }); - test.each(arrayLiteralCases)("of tuple return call (%p)", expression => { + test.each(arrayLiteralCases)("of multi return call (%p)", expression => { util.testFunction` - /** @tupleReturn */ function tuple(...args: any[]) { - return args; + return $multi(...args); } return ${factory(`...tuple(${expression})`)}; - `.expectToMatchJsResult(); + ` + .withLanguageExtensions() + .expectToMatchJsResult(); }); test("of multiple string literals", () => { @@ -226,7 +226,7 @@ describe("vararg spread optimization", () => { } return test("a" ,"b", "c"); ` - .setOptions({ types: [path.resolve(__dirname, "../../language-extensions")] }) + .withLanguageExtensions() .expectLuaToMatchSnapshot() .expectToEqual("b"); }); diff --git a/test/util.ts b/test/util.ts index 55f06d6ac..d8fad5280 100644 --- a/test/util.ts +++ b/test/util.ts @@ -147,6 +147,15 @@ export abstract class TestBuilder { return this; } + public withLanguageExtensions(): this { + this.setOptions({ types: [path.resolve(__dirname, "..", "language-extensions")] }); + // Polyfill lualib for JS + this.setJsHeader(` + function $multi(...args) { return args; } + `); + return this; + } + protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { expect(this.hasProgram).toBe(false); From 6a353025fe47f50e7fd4dd843ecc3a55b83e6833 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Aug 2021 22:40:27 +0200 Subject: [PATCH 378/764] CHANGELOG 0.42.0 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce877a1d5..c498548f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 0.42.0 + +- **[Breaking]** The `/** @tupleReturn */` is now deprecated, and will be removed next release. If you are still using it, please upgrade to the [LuaMultiReturn language extension](https://typescripttolua.github.io/docs/advanced/language-extensions#luamultireturn-type). +- Added support for TSX, see [documentation](https://typescripttolua.github.io/docs/tsx) for more information. +- Added support for the `baseUrl` configuration key for module resolution. + +A large list of bugfixes: + +- Fixed an exception causing tstl to exit when trying to assign to an optional chain. +- Fixed resolved files appearing duplicated in lua bundles. +- Fixed a problem resolving external Lua files in nested directories. +- Fixed `@noResolution` in library packages losing their NoResolution tag, causing attempts to resolve them for package users. +- Fixed a bug in the bundling code causing modules not to be cached if they return nil (which happens if they are not a module) +- Fixed module resolution trying to incorrectly resolve and rewrite things like `myObject.require()` or `my_custom_require()`. +- Fixed lualib bundle not being included in the output if external packages use it, but the client code does not. + ## 0.41.0 - Added support for [optional chaining](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html) `a?.b`, `a?.[b]` and `a?.()`. From 77b2d65aa7cbd5d28568e0f46fa886e19b7d6cdf Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Aug 2021 22:48:40 +0200 Subject: [PATCH 379/764] 0.42.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c5c4360c..613666d0d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.41.2", + "version": "0.42.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.41.2", + "version": "0.42.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index b47d02558..1d508f0d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.41.2", + "version": "0.42.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d2d5ece4b4ad2493d721930a7e9b5039f5fdbb5a Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Mon, 9 Aug 2021 16:01:18 -0700 Subject: [PATCH 380/764] Change TSX to JSX in changelog (#1077) See https://github.com/TypeScriptToLua/TypeScriptToLua.github.io/pull/65 Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c498548f4..0f66f3057 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 0.42.0 - **[Breaking]** The `/** @tupleReturn */` is now deprecated, and will be removed next release. If you are still using it, please upgrade to the [LuaMultiReturn language extension](https://typescripttolua.github.io/docs/advanced/language-extensions#luamultireturn-type). -- Added support for TSX, see [documentation](https://typescripttolua.github.io/docs/tsx) for more information. +- Added support for JSX, see [documentation](https://typescripttolua.github.io/docs/jsx) for more information. - Added support for the `baseUrl` configuration key for module resolution. A large list of bugfixes: From ab99a73fbdc167c755883deaa41f34fe29abf8d4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 15 Aug 2021 21:04:00 +0200 Subject: [PATCH 381/764] Prevent TS from emitting json files (#1082) --- src/transpilation/transpile.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index d78162fd8..fc645147f 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -103,7 +103,7 @@ export function getProgramTranspileResult( options.noEmit = false; const writeFile: ts.WriteFileCallback = (fileName, ...rest) => { - if (!fileName.endsWith(".js") && !fileName.endsWith(".js.map")) { + if (!fileName.endsWith(".js") && !fileName.endsWith(".js.map") && !fileName.endsWith(".json")) { writeFileResult(fileName, ...rest); } }; From a738dfc864b67e29dfedc84f25ae023da4989fee Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 15 Aug 2021 12:25:42 -0700 Subject: [PATCH 382/764] Fix noSelf in object literal methods (#1088) * Fix noSelf in object literal methods * Add isObjectLiteralExpression check on parent This check is absent in the internal typescript method * Add more tests for PR Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> --- src/transformation/utils/function-context.ts | 20 +++++-- src/typescript-internal.d.ts | 1 + test/unit/objectLiteral.spec.ts | 63 ++++++++++++++++++++ 3 files changed, 78 insertions(+), 6 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 8bf05255c..b3e9ee2c5 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -113,17 +113,25 @@ function getSignatureDeclarations( ): ts.SignatureDeclaration[] { return signatures.flatMap(signature => { const signatureDeclaration = signature.getDeclaration(); + let inferredType: ts.Type | undefined; if ( + ts.isMethodDeclaration(signatureDeclaration) && + ts.isObjectLiteralExpression(signatureDeclaration.parent) && + !getExplicitThisParameter(signatureDeclaration) + ) { + inferredType = context.checker.getContextualTypeForObjectLiteralElement(signatureDeclaration); + } else if ( (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && !getExplicitThisParameter(signatureDeclaration) ) { // Infer type of function expressions/arrow functions - const inferredType = inferAssignedType(context, signatureDeclaration); - if (inferredType) { - const inferredSignatures = getAllCallSignatures(inferredType); - if (inferredSignatures.length > 0) { - return inferredSignatures.map(s => s.getDeclaration()); - } + inferredType = inferAssignedType(context, signatureDeclaration); + } + + if (inferredType) { + const inferredSignatures = getAllCallSignatures(inferredType); + if (inferredSignatures.length > 0) { + return inferredSignatures.map(s => s.getDeclaration()); } } diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 7bfd309ac..8fd8fd1ec 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -26,5 +26,6 @@ declare module "typescript" { interface TypeChecker { getElementTypeOfArrayType(type: Type): Type | undefined; + getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined; } } diff --git a/test/unit/objectLiteral.spec.ts b/test/unit/objectLiteral.spec.ts index 819143e1f..16e7582d0 100644 --- a/test/unit/objectLiteral.spec.ts +++ b/test/unit/objectLiteral.spec.ts @@ -63,3 +63,66 @@ test.each(['{x: "foobar"}.x', '{x: "foobar"}["x"]', '{x: () => "foobar"}.x()', ' util.testExpression(expression).expectToMatchJsResult(); } ); + +describe("noSelf in functions", () => { + test("Explicit this: void parameter", () => { + // language=TypeScript + util.testFunction` + const obj: Record string> = { + method(a) { + return a; + }, + func: function(a) { + return a; + }, + arrow: (a) => { + return a; + } + }; + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); + + test("No self annotation", () => { + // language=TypeScript + util.testFunction` + const obj: Record string> = { + method(a) { + return a; + }, + func: function(a) { + return a; + }, + arrow: (a) => { + return a; + } + }; + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); + + test("individual function types", () => { + // language=TypeScript + util.testFunction` + interface FunctionContainer { + method: (this: void, a: string) => string + func: (this: void, a: string) => string + arrow: (this: void, a: string) => string + } + + const obj: FunctionContainer = { + method(a) { + return a + }, + func: function(a) { + return a + }, + arrow: (a) => { + return a + } + } + + return [obj.method("a") ?? "nil", obj.func("b") ?? "nil", obj.arrow("c") ?? "nil"]; + `.expectToMatchJsResult(); + }); +}); From 716a2373f9f2a50fe3db9c96a25fd9fb01469f6d Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 15 Aug 2021 12:44:45 -0700 Subject: [PATCH 383/764] fix sourceMapTraceback (#1087) Co-authored-by: Benjamin Ye <24237065+enjoydambience@users.noreply.github.com> --- src/lualib/SourceMapTraceBack.ts | 1 + test/unit/printer/sourcemaps.spec.ts | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index bf718a9b0..b46ba4786 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,5 +1,6 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. +declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [line: number]: number }): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; globalThis.__TS__sourcemap[fileName] = sourceMap; diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 371c50df9..891945dc3 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -272,6 +272,15 @@ test("sourceMapTraceback saves sourcemap in _G", () => { } }); +test("sourceMapTraceback gives traceback", () => { + const builder = util.testFunction` + return (debug.traceback as (this: void)=>string)(); + `.setOptions({ sourceMapTraceback: true, luaLibImport: tstl.LuaLibImportKind.Inline }); + + const traceback = builder.getLuaExecutionResult(); + expect(traceback).toEqual(expect.any(String)); +}); + test("Inline sourcemaps", () => { const code = ` function abc() { From b5c6d3acd6df1cb7bdef07c6b786e00e5c82ffb4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 16 Aug 2021 11:15:46 +0200 Subject: [PATCH 384/764] Resolve lua required directory init.lua files (#1089) --- src/transpilation/resolve.ts | 1 + test/transpile/module-resolution.spec.ts | 1 + .../project-with-complicated-dependency/main.ts | 1 + .../node_modules/dependency1/index.d.ts | 3 ++- .../node_modules/dependency1/index.lua | 4 +++- .../node_modules/dependency1/subdirwithinit/init.lua | 3 +++ 6 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 59639e2c7..38c130e84 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -188,6 +188,7 @@ function resolveDependency( const possibleLuaProjectFiles = [ resolvedPath + ".lua", // lua file in sources path.join(resolvedPath, "index.lua"), // lua index file in sources + path.join(resolvedPath, "init.lua"), // lua looks for /init.lua if it cannot find .lua ]; for (const possibleFile of possibleLuaProjectFiles) { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 80e08ac46..0332d8c58 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -286,6 +286,7 @@ describe("dependency with complicated inner structure", () => { otherFileUtil: "util", subsubresult: "result from subsub dir", utilResult: "util", + subdirwithInitResult: "a", }; // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1055 diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts index 20bc696ea..70d8123fa 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/main.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/main.ts @@ -4,3 +4,4 @@ export const otherFileResult = dependency1.otherFileFromDependency1(); export const utilResult = dependency1.callUtil(); export const otherFileUtil = dependency1.otherFileUtil(); export const subsubresult = dependency1.subsubdirfileResult; +export const subdirwithInitResult = dependency1.subdirWithInitResult; diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts index 2aaa0dfd6..28f4f5baa 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.d.ts @@ -2,4 +2,5 @@ export declare function otherFileFromDependency1(): string; export declare function callUtil(): string; export declare function otherFileUtil(): string; -export const subsubdirfileResult: string; \ No newline at end of file +export const subsubdirfileResult: string; +export const subdirWithInitResult: string; \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua index 8068497d1..c3838b1f4 100644 --- a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/index.lua @@ -3,6 +3,7 @@ local util = require("util") local subdirfile = require("subdir.subdirfile") local othersubdirfile = require("subdir.othersubdirfile") local subsubdirfile = require("subdir.subsubdir.subsubdirfile") +local subdirwithinit = require("subdirwithinit") return { otherFileFromDependency1 = otherfile.someFunc, @@ -12,5 +13,6 @@ return { otherFileUtil = otherfile.callUtil, subdirfileResult = subdirfile.subdirfileResult, othersubdirfileResult = othersubdirfile.othersubdirfileResult, - subsubdirfileResult = subsubdirfile.subsubresult + subsubdirfileResult = subsubdirfile.subsubresult, + subdirWithInitResult = subdirwithinit.a() } \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua new file mode 100644 index 000000000..f26612a6f --- /dev/null +++ b/test/transpile/module-resolution/project-with-complicated-dependency/node_modules/dependency1/subdirwithinit/init.lua @@ -0,0 +1,3 @@ +return { + a = function() return "a" end +} \ No newline at end of file From f6fea1ec043cca4c3bfd78bda21851cc870a8c00 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 18 Aug 2021 10:05:59 +0200 Subject: [PATCH 385/764] Add support for Promises (#1049) * Initial lualib promise class implementation * First promise tests * More promise tests * Promise class implementation * Implemented Promise.all * Promise.any * Promise.race * Promise.allSettled * fix prettier * Add promise example usage test * Added missing lualib dependencies for PromiseConstructor functions * Immediately call then/catch/finally callbacks on promises that are already resolved * Transform all references to Promise to __TS__Promise * PR feedback * Removed incorrect asyncs * Add test for direct chaining * Add test for finally and correct wrong behavior it caught * Added test throwing in parallel and chained then onFulfilleds * Fixed pull request link in ArrayIsArray lualib comment --- src/LuaLib.ts | 31 +- src/lualib/ArrayIsArray.ts | 2 +- src/lualib/Promise.ts | 188 ++++ src/lualib/PromiseAll.ts | 54 + src/lualib/PromiseAllSettled.ts | 62 ++ src/lualib/PromiseAny.ts | 55 + src/lualib/PromiseRace.ts | 34 + src/transformation/builtins/index.ts | 3 + src/transformation/builtins/promise.ts | 53 + src/transformation/visitors/class/new.ts | 3 +- src/transformation/visitors/identifier.ts | 7 + test/unit/builtins/promise.spec.ts | 1175 +++++++++++++++++++++ test/util.ts | 6 +- 13 files changed, 1668 insertions(+), 5 deletions(-) create mode 100644 src/lualib/Promise.ts create mode 100644 src/lualib/PromiseAll.ts create mode 100644 src/lualib/PromiseAllSettled.ts create mode 100644 src/lualib/PromiseAny.ts create mode 100644 src/lualib/PromiseRace.ts create mode 100644 src/transformation/builtins/promise.ts create mode 100644 test/unit/builtins/promise.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 96f58ab7a..669c68941 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -62,6 +62,11 @@ export enum LuaLibFeature { OptionalMethodCall = "OptionalMethodCall", ParseFloat = "ParseFloat", ParseInt = "ParseInt", + Promise = "Promise", + PromiseAll = "PromiseAll", + PromiseAllSettled = "PromiseAllSettled", + PromiseAny = "PromiseAny", + PromiseRace = "PromiseRace", Set = "Set", SetDescriptor = "SetDescriptor", WeakMap = "WeakMap", @@ -107,16 +112,40 @@ const luaLibDependencies: Partial> = { NumberToString: [LuaLibFeature.StringAccess], ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], + Promise: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.Class, + LuaLibFeature.FunctionBind, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + ], + PromiseAll: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], + PromiseAllSettled: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], + PromiseAny: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + LuaLibFeature.Promise, + LuaLibFeature.Iterator, + ], + PromiseRace: [ + LuaLibFeature.ArrayPush, + LuaLibFeature.InstanceOf, + LuaLibFeature.New, + LuaLibFeature.Promise, + LuaLibFeature.Iterator, + ], ParseFloat: [LuaLibFeature.StringAccess], ParseInt: [LuaLibFeature.StringSubstr, LuaLibFeature.StringSubstring], SetDescriptor: [LuaLibFeature.CloneDescriptor], + Spread: [LuaLibFeature.Iterator, LuaLibFeature.StringAccess, LuaLibFeature.Unpack], StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], SymbolRegistry: [LuaLibFeature.Symbol], + Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - Spread: [LuaLibFeature.Iterator, LuaLibFeature.StringAccess, LuaLibFeature.Unpack], }; /* eslint-enable @typescript-eslint/naming-convention */ diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts index d981ec0f2..417ae6e6e 100644 --- a/src/lualib/ArrayIsArray.ts +++ b/src/lualib/ArrayIsArray.ts @@ -2,6 +2,6 @@ declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unkn function __TS__ArrayIsArray(this: void, value: any): value is any[] { // Workaround to determine if value is an array or not (fails in case of objects without keys) - // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/7 + // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); } diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts new file mode 100644 index 000000000..c8fdea117 --- /dev/null +++ b/src/lualib/Promise.ts @@ -0,0 +1,188 @@ +/* eslint-disable @typescript-eslint/promise-function-async */ + +// Promises implemented based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise +// and https://promisesaplus.com/ + +enum __TS__PromiseState { + Pending, + Fulfilled, + Rejected, +} + +type FulfillCallback = (value: TData) => TResult | PromiseLike; +type RejectCallback = (reason: any) => TResult | PromiseLike; + +function __TS__PromiseDeferred() { + let resolve: FulfillCallback; + let reject: RejectCallback; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + + return { promise, resolve, reject }; +} + +function __TS__IsPromiseLike(thing: unknown): thing is PromiseLike { + return thing instanceof __TS__Promise; +} + +class __TS__Promise implements Promise { + public state = __TS__PromiseState.Pending; + public value?: T; + public rejectionReason?: any; + + private fulfilledCallbacks: Array> = []; + private rejectedCallbacks: Array> = []; + private finallyCallbacks: Array<() => void> = []; + + public [Symbol.toStringTag]: string; // Required to implement interface, no output Lua + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve + public static resolve(this: void, data: TData): Promise { + // Create and return a promise instance that is already resolved + const promise = new __TS__Promise(() => {}); + promise.state = __TS__PromiseState.Fulfilled; + promise.value = data; + return promise; + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject + public static reject(this: void, reason: any): Promise { + // Create and return a promise instance that is already rejected + const promise = new __TS__Promise(() => {}); + promise.state = __TS__PromiseState.Rejected; + promise.rejectionReason = reason; + return promise; + } + + constructor(executor: (resolve: (data: T) => void, reject: (reason: any) => void) => void) { + try { + executor(this.resolve.bind(this), this.reject.bind(this)); + } catch (e) { + // When a promise executor throws, the promise should be rejected with the thrown object as reason + this.reject(e); + } + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then + public then( + onFulfilled?: FulfillCallback, + onRejected?: RejectCallback + ): Promise { + const { promise, resolve, reject } = __TS__PromiseDeferred(); + + if (onFulfilled) { + const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); + this.fulfilledCallbacks.push(internalCallback); + + if (this.state === __TS__PromiseState.Fulfilled) { + // If promise already resolved, immediately call callback + internalCallback(this.value); + } + } else { + // We always want to resolve our child promise if this promise is resolved, even if we have no handler + this.fulfilledCallbacks.push(() => resolve(undefined)); + } + + if (onRejected) { + const internalCallback = this.createPromiseResolvingCallback(onRejected, resolve, reject); + this.rejectedCallbacks.push(internalCallback); + + if (this.state === __TS__PromiseState.Rejected) { + // If promise already rejected, immediately call callback + internalCallback(this.rejectionReason); + } + } + + return promise; + } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch + public catch(onRejected?: (reason: any) => TResult | PromiseLike): Promise { + return this.then(undefined, onRejected); + } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally + public finally(onFinally?: () => void): Promise { + if (onFinally) { + this.finallyCallbacks.push(onFinally); + + if (this.state !== __TS__PromiseState.Pending) { + // If promise already resolved or rejected, immediately fire finally callback + onFinally(); + } + } + return this; + } + + private resolve(data: T): void { + // Resolve this promise, if it is still pending. This function is passed to the constructor function. + if (this.state === __TS__PromiseState.Pending) { + this.state = __TS__PromiseState.Fulfilled; + this.value = data; + + for (const callback of this.fulfilledCallbacks) { + callback(data); + } + for (const callback of this.finallyCallbacks) { + callback(); + } + } + } + + private reject(reason: any): void { + // Reject this promise, if it is still pending. This function is passed to the constructor function. + if (this.state === __TS__PromiseState.Pending) { + this.state = __TS__PromiseState.Rejected; + this.rejectionReason = reason; + + for (const callback of this.rejectedCallbacks) { + callback(reason); + } + for (const callback of this.finallyCallbacks) { + callback(); + } + } + } + + private createPromiseResolvingCallback( + f: FulfillCallback | RejectCallback, + resolve: FulfillCallback, + reject: RejectCallback + ) { + return value => { + try { + this.handleCallbackData(f(value), resolve, reject); + } catch (e) { + // If a handler function throws an error, the promise returned by then gets rejected with the thrown error as its value + reject(e); + } + }; + } + private handleCallbackData( + data: TResult | PromiseLike, + resolve: FulfillCallback, + reject: RejectCallback + ) { + if (__TS__IsPromiseLike(data)) { + const nextpromise = data as __TS__Promise; + if (nextpromise.state === __TS__PromiseState.Fulfilled) { + // If a handler function returns an already fulfilled promise, + // the promise returned by then gets fulfilled with that promise's value + resolve(nextpromise.value); + } else if (nextpromise.state === __TS__PromiseState.Rejected) { + // If a handler function returns an already rejected promise, + // the promise returned by then gets fulfilled with that promise's value + reject(nextpromise.rejectionReason); + } else { + // If a handler function returns another pending promise object, the resolution/rejection + // of the promise returned by then will be subsequent to the resolution/rejection of + // the promise returned by the handler. + data.then(resolve, reject); + } + } else { + // If a handler returns a value, the promise returned by then gets resolved with the returned value as its value + // If a handler doesn't return anything, the promise returned by then gets resolved with undefined + resolve(data); + } + } +} diff --git a/src/lualib/PromiseAll.ts b/src/lualib/PromiseAll.ts new file mode 100644 index 000000000..e0d940977 --- /dev/null +++ b/src/lualib/PromiseAll.ts @@ -0,0 +1,54 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAll(this: void, iterable: Iterable>): Promise { + const results: T[] = []; + + const toResolve = new LuaTable>(); + let numToResolve = 0; + + let i = 0; + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, add its value to our results array + results[i] = item.value; + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, return a rejected promise with the rejection reason + return Promise.reject(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + numToResolve++; + toResolve.set(i, item); + } + } else { + // If value is not a promise, add it to the results array + results[i] = item as T; + } + i++; + } + + // If there are no remaining pending promises, return a resolved promise with the results + if (numToResolve === 0) { + return Promise.resolve(results); + } + + return new Promise((resolve, reject) => { + for (const [index, promise] of pairs(toResolve)) { + promise.then( + data => { + // When resolved, store value in results array + results[index] = data; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + }, + reason => { + // When rejected, immediately reject the returned promise + reject(reason); + } + ); + } + }); +} diff --git a/src/lualib/PromiseAllSettled.ts b/src/lualib/PromiseAllSettled.ts new file mode 100644 index 000000000..165e226f4 --- /dev/null +++ b/src/lualib/PromiseAllSettled.ts @@ -0,0 +1,62 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAllSettled( + this: void, + iterable: Iterable +): Promise ? U : T>>> { + const results: Array ? U : T>> = []; + + const toResolve = new LuaTable>(); + let numToResolve = 0; + + let i = 0; + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, add a fulfilled PromiseSettledResult + results[i] = { status: "fulfilled", value: item.value }; + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, add a rejected PromiseSettledResult + results[i] = { status: "rejected", reason: item.rejectionReason }; + } else { + // If value is a pending promise, add it to the list of pending promises + numToResolve++; + toResolve.set(i, item); + } + } else { + // If value is not a promise, add it to the results as fulfilled PromiseSettledResult + results[i] = { status: "fulfilled", value: item as any }; + } + i++; + } + + // If there are no remaining pending promises, return a resolved promise with the results + if (numToResolve === 0) { + return Promise.resolve(results); + } + + return new Promise(resolve => { + for (const [index, promise] of pairs(toResolve)) { + promise.then( + data => { + // When resolved, add a fulfilled PromiseSettledResult + results[index] = { status: "fulfilled", value: data as any }; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + }, + reason => { + // When resolved, add a rejected PromiseSettledResult + results[index] = { status: "rejected", reason }; + numToResolve--; + if (numToResolve === 0) { + // If there are no more promises to resolve, resolve with our filled results array + resolve(results); + } + } + ); + } + }); +} diff --git a/src/lualib/PromiseAny.ts b/src/lualib/PromiseAny.ts new file mode 100644 index 000000000..eb70bf12f --- /dev/null +++ b/src/lualib/PromiseAny.ts @@ -0,0 +1,55 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseAny(this: void, iterable: Iterable>): Promise { + const rejections: string[] = []; + const pending: Array> = []; + + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a resolved promise, return a new resolved promise with its value + return Promise.resolve(item.value); + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, add its value to our list of rejections + rejections.push(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + pending.push(item); + } + } else { + // If value is not a promise, return a resolved promise with it as its value + return Promise.resolve(item); + } + } + + // If we have not returned yet and there are no pending promises, reject + if (pending.length === 0) { + return Promise.reject("No promises to resolve with .any()"); + } + + let numResolved = 0; + + return new Promise((resolve, reject) => { + for (const promise of pending) { + promise.then( + data => { + // If any pending promise resolves, resolve this promise with its data + resolve(data); + }, + reason => { + // If a pending promise rejects, add its rejection to our rejection list + rejections.push(reason); + numResolved++; + if (numResolved === pending.length) { + // If there are no more pending promises, reject with the list of rejections + reject({ + name: "AggregateError", + message: "All Promises rejected", + errors: rejections, + }); + } + } + ); + } + }); +} diff --git a/src/lualib/PromiseRace.ts b/src/lualib/PromiseRace.ts new file mode 100644 index 000000000..3b3a1fb7b --- /dev/null +++ b/src/lualib/PromiseRace.ts @@ -0,0 +1,34 @@ +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__PromiseRace(this: void, iterable: Iterable>): Promise { + const pending: Array> = []; + + for (const item of iterable) { + if (item instanceof __TS__Promise) { + if (item.state === __TS__PromiseState.Fulfilled) { + // If value is a fulfilled promise, return a resolved promise with its value + return Promise.resolve(item.value); + } else if (item.state === __TS__PromiseState.Rejected) { + // If value is a rejected promise, return rejected promise with its value + return Promise.reject(item.rejectionReason); + } else { + // If value is a pending promise, add it to the list of pending promises + pending.push(item); + } + } else { + // If value is not a promise, return a promise resolved with it as its value + return Promise.resolve(item); + } + } + + // If not yet returned, wait for any pending promise to resolve or reject. + // If there are no pending promise, this promise will be pending forever as per specification. + return new Promise((resolve, reject) => { + for (const promise of pending) { + promise.then( + value => resolve(value), + reason => reject(reason) + ); + } + }); +} diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 6d7f0bd8b..53473b420 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -22,6 +22,7 @@ import { transformGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; import { transformObjectConstructorCall, transformObjectPrototypeCall } from "./object"; +import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; @@ -93,6 +94,8 @@ export function transformBuiltinCallExpression( return transformSymbolConstructorCall(context, node); case "NumberConstructor": return transformNumberConstructorCall(context, node); + case "PromiseConstructor": + return transformPromiseConstructorCall(context, node); } } diff --git a/src/transformation/builtins/promise.ts b/src/transformation/builtins/promise.ts new file mode 100644 index 000000000..cd30aa718 --- /dev/null +++ b/src/transformation/builtins/promise.ts @@ -0,0 +1,53 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { isStandardLibraryType } from "../utils/typescript"; +import { PropertyCallExpression, transformArguments } from "../visitors/call"; + +export function isPromiseClass(context: TransformationContext, node: ts.Identifier) { + const type = context.checker.getTypeAtLocation(node); + return isStandardLibraryType(context, type, undefined) && node.text === "Promise"; +} + +export function createPromiseIdentifier(original: ts.Node) { + return lua.createIdentifier("__TS__Promise", original); +} + +export function transformPromiseConstructorCall( + context: TransformationContext, + node: PropertyCallExpression +): lua.Expression | undefined { + const expression = node.expression; + const signature = context.checker.getResolvedSignature(node); + const params = transformArguments(context, node.arguments, signature); + + const expressionName = expression.name.text; + switch (expressionName) { + case "all": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAll, node, ...params); + case "allSettled": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAllSettled, node, ...params); + case "any": + return transformLuaLibFunction(context, LuaLibFeature.PromiseAny, node, ...params); + case "race": + return transformLuaLibFunction(context, LuaLibFeature.PromiseRace, node, ...params); + case "resolve": + importLuaLibFeature(context, LuaLibFeature.Promise); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", expression), params, node); + case "reject": + importLuaLibFeature(context, LuaLibFeature.Promise); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("reject", expression), params, node); + default: + context.diagnostics.push(unsupportedProperty(expression.name, "Promise", expressionName)); + } +} + +function createStaticPromiseFunctionAccessor(functionName: string, node: ts.Node) { + return lua.createTableIndexExpression( + lua.createIdentifier("__TS__Promise"), + lua.createStringLiteral(functionName), + node + ); +} diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 721cc26e5..97e1c3407 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -60,7 +60,6 @@ export const transformNewExpression: FunctionVisitor = (node, return lua.createTableExpression(undefined, node); } - const name = context.transformExpression(node.expression); const signature = context.checker.getResolvedSignature(node); const params = node.arguments ? transformArguments(context, node.arguments, signature) @@ -68,6 +67,8 @@ export const transformNewExpression: FunctionVisitor = (node, checkForLuaLibType(context, type); + const name = context.transformExpression(node.expression); + const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 17706848c..3d39b16a4 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinIdentifierExpression } from "../builtins"; +import { createPromiseIdentifier, isPromiseClass } from "../builtins/promise"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, isForRangeType } from "../utils/annotations"; import { @@ -12,6 +13,7 @@ import { annotationRemoved, } from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; +import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName } from "../utils/safe-names"; import { getIdentifierSymbolId } from "../utils/symbols"; import { isMultiFunctionNode } from "./language-extensions/multi"; @@ -48,6 +50,11 @@ export function transformIdentifier(context: TransformationContext, identifier: context.diagnostics.push(annotationRemoved(identifier, AnnotationKind.ForRange)); } + if (isPromiseClass(context, identifier)) { + importLuaLibFeature(context, LuaLibFeature.Promise); + return createPromiseIdentifier(identifier); + } + const text = hasUnsafeIdentifierName(context, identifier) ? createSafeName(identifier.text) : identifier.text; const symbolId = getIdentifierSymbolId(context, identifier); diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts new file mode 100644 index 000000000..4a22f7514 --- /dev/null +++ b/test/unit/builtins/promise.spec.ts @@ -0,0 +1,1175 @@ +import * as util from "../../util"; + +const promiseTestLib = ` +// Some logging utility, useful for asserting orders of operations + +const allLogs: any[] = []; +function log(...values: any[]) { + allLogs.push(...values); +} + +// Create a promise and store its resolve and reject functions, useful for creating pending promises + +function defer() { + let resolve: (data: any) => void = () => {}; + let reject: (reason: string) => void = () => {}; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { promise, resolve, reject }; +}`; + +test("can create resolved promise", () => { + util.testFunction` + const { state, value } = Promise.resolve(42) as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: 42, + }); +}); + +test("can create rejected promise", () => { + util.testFunction` + const { state, rejectionReason } = Promise.reject("test rejection") as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test rejection", + }); +}); + +test("promise constructor executor throwing rejects promise", () => { + util.testFunction` + const { state, rejectionReason } = new Promise(() => { throw "executor exception"; }) as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "executor exception", + }); +}); + +test("promise can be resolved", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let result: string | undefined; + let rejectResult: string | undefined; + + promise.then( + data => { result = data; }, + reason => { rejectResult = reason; } + ); + + const beforeResolve = result; + + resolve("Hello!"); + + const afterResolve = result; + + return { beforeResolve, afterResolve, rejectResult }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + beforeResolve: undefined, + afterResolve: "Hello!", + rejectResult: undefined, + }); +}); + +test("promise can be rejected", () => { + util.testFunction` + const { promise, reject } = defer(); + + let resolveResult: string | undefined; + let rejectResult: string | undefined; + + promise.then( + data => { resolveResult = data; }, + reason => { rejectResult = reason; } + ); + + const beforeReject = rejectResult; + + reject("Hello!"); + + const afterReject = rejectResult; + + return { beforeReject, afterReject, resolveResult }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + beforeReject: undefined, + afterReject: "Hello!", + resolveResult: undefined, + }); +}); + +test("promise cannot be resolved more than once", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then( + data => { log(data); } + ); + + resolve("Hello!"); + resolve("World!"); // Second resolve should be ignored + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be rejected more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.then( + _ => {}, + reason => { log(reason); } + ); + + reject("Hello!"); + reject("World!"); // Second reject should be ignored + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be rejected after resolving", () => { + util.testFunction` + const { promise, resolve, reject } = defer(); + + promise.then( + data => { log(data); }, + reason => { log(reason); } + ); + + resolve("Hello!"); + reject("World!"); // should be ignored because already resolved + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise cannot be resolved after rejecting", () => { + util.testFunction` + const { promise, resolve, reject } = defer(); + + promise.then( + data => { log(data); }, + reason => { log(reason); } + ); + + reject("Hello!"); + resolve("World!"); // should be ignored because already rejected + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["Hello!"]); +}); + +test("promise can be (then-resolve) observed more than once", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then( + data => { log("then 1: " + data); } + ); + + promise.then( + data => { log("then 2: " + data); } + ); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then 1: Hello!", "then 2: Hello!"]); +}); + +test("promise can be (then-reject) observed more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.then( + undefined, + reason => { log("then 1: " + reason); } + ); + + promise.then( + undefined, + reason => { log("then 2: " + reason); }, + ); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then 1: Hello!", "then 2: Hello!"]); +}); + +test("promise can be (catch) observed more than once", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.catch( + reason => { log("catch 1: " + reason); } + ); + + promise.catch( + reason => { log("catch 2: " + reason); }, + ); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch 1: Hello!", "catch 2: Hello!"]); +}); + +test("promise chained resolve resolves all", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + promise3.then(data => { + log("promise3: " + data); + resolve2(data); + }); + promise2.then(data => { + log("promise2: " + data); + resolve1(data); + }); + promise1.then(data => { + log("promise1: " + data); + }); + + resolve3("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise3: Hello!", "promise2: Hello!", "promise1: Hello!"]); +}); + +test("promise then returns a literal", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return "promise 1 resolved: " + data; + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 resolved with: promise 1 resolved: Hello!"]); +}); + +test("promise then returns a resolved promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return Promise.resolve("promise 1 resolved: " + data); + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 resolved with: promise 1 resolved: Hello!"]); +}); + +test("promise then returns a rejected promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + return Promise.reject("promise 1: reject!"); + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise resolved with: Hello!", "promise2 rejected with: promise 1: reject!"]); +}); + +test("promise then returns a pending promise (resolves)", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let resolve2: any; + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + + const promise3 = new Promise((res) => { + resolve2 = res; + }); + + promise3.then(data2 => { + log("promise3 resolved with: " + data2); + }); + + return promise3; + }); + + promise2.then(data => { + log("promise2 resolved with: " + data); + }); + + // Resolve promise 1 + resolve("Hello!"); + + // Resolve promise 2 and 3 + resolve2("World!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "promise resolved with: Hello!", + "promise3 resolved with: World!", + "promise2 resolved with: World!", + ]); +}); + +test("promise then returns a pending promise (rejects)", () => { + util.testFunction` + const { promise, resolve } = defer(); + + let reject: any; + + const promise2 = promise.then(data => { + log("promise resolved with: " + data); + + const promise3 = new Promise((_, rej) => { + reject = rej; + }); + + promise3.catch(reason => { + log("promise3 rejected with: " + reason); + }); + + return promise3; + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + // Resolve promise 1 + resolve("Hello!"); + + // Reject promise 2 and 3 + reject("World!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "promise resolved with: Hello!", + "promise3 rejected with: World!", + "promise2 rejected with: World!", + ]); +}); + +test("promise then onFulfilled throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const promise2 = promise.then(data => { + throw "fulfill exception!" + }); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + resolve("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise2 rejected with: fulfill exception!"]); +}); + +test("promise then onRejected throws", () => { + util.testFunction` + const { promise, reject } = defer(); + + const promise2 = promise.then( + _ => {}, + reason => { throw "fulfill exception from onReject!" } + ); + + promise2.catch(reason => { + log("promise2 rejected with: " + reason); + }); + + reject("Hello!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise2 rejected with: fulfill exception from onReject!"]); +}); + +test("then on resolved promise immediately calls callback", () => { + util.testFunction` + Promise.resolve(42).then(data => { log(data); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([42]); +}); + +test("then on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").then(data => { log("resolved", data); }, reason => { log("rejected", reason); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejected", "already rejected"]); +}); + +test("second then throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then(data => { + // nothing + log("then1", data) + }); + + promise.then(data => { + log("then2", data) + throw "test throw"; + }).catch(err => { + // caught + log("rejected: ", err) + }); + + resolve("mydata"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then1", "mydata", "then2", "mydata", "rejected: ", "test throw"]); +}); + +test("chained then throws", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then(data => { + // nothing + log("then1", data) + }).then(data => { + log("then2", data) + throw "test throw"; + }).catch(err => { + // caught + log("rejected: ", err) + }); + + resolve("mydata"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "then1", + "mydata", + "then2", // Does not have data because first then returned undefined + "rejected: ", + "test throw", + ]); +}); + +test("catch on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").catch(reason => { log(reason); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["already rejected"]); +}); + +test("finally on resolved promise immediately calls callback", () => { + util.testFunction` + Promise.resolve(42).finally(() => { log("finally"); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally"]); +}); + +test("finally on rejected promise immediately calls callback", () => { + util.testFunction` + Promise.reject("already rejected").finally(() => { log("finally"); }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally"]); +}); + +test("direct chaining", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise + .then(data => { + log("resolving then1", data); + return "then 1 data"; + }).then(data => { + log("resolving then2", data); + throw "test throw"; + }).catch(reason => { + log("handling catch", reason); + }); + + resolve("test data"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving then1", + "test data", + "resolving then2", + "then 1 data", + "handling catch", + "test throw", + ]); +}); + +describe("finally behaves same as then/catch", () => { + const thenCatchPromise = ` + const { promise, resolve, reject } = defer(); + promise + .then(data => { + log("do something", data); + log("final code"); + }) + .catch(reason => { + log("handling error", data); + log("final code"); + }); + `; + + const finallyPromise = ` + const { promise, resolve, reject } = defer(); + promise + .then(data => { + log("do something", data); + }) + .catch(reason => { + log("handling error", reason); + }) + .finally(() => { + log("final code"); + }); + `; + + test("when resolving", () => { + const thenResult = util.testFunction` + ${thenCatchPromise} + resolve("test data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + const finallyResult = util.testFunction` + ${finallyPromise} + resolve("test data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + expect(finallyResult).toEqual(thenResult); + }); + + test("when rejecting", () => { + const thenResult = util.testFunction` + ${thenCatchPromise} + reject("test rejection reason"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + const finallyResult = util.testFunction` + ${finallyPromise} + reject("test rejection reason"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .getLuaExecutionResult(); + + expect(finallyResult).toEqual(thenResult); + }); +}); + +test("example: asynchronous web request", () => { + const testHarness = ` + interface UserData { name: string, age: number} + const requests = new Map void>(); + function getUserData(id: number, callback: (userData: UserData) => void) { + requests.set(id, callback); + } + function emulateRequestReturn(id: number, data: UserData) { + requests.get(id)!(data); + } + `; + + util.testFunction` + // Wrap function getUserData(id: number, callback: (userData: UserData) => void) into a Promise + function getUserDataAsync(id: number): Promise { + return new Promise(resolve => { + getUserData(id, resolve); + }); + } + + const user1DataPromise = getUserDataAsync(1); + const user2DataPromise = getUserDataAsync(2); + + user1DataPromise.then(() => log("received data for user 1")); + user2DataPromise.then(() => log("received data for user 2")); + + const allDataPromise = Promise.all([user1DataPromise, user2DataPromise]); + + allDataPromise.then(([user1data, user2data]) => { + log("all requests completed", user1data, user2data); + }); + + emulateRequestReturn(2, { name: "bar", age: 42 }); + emulateRequestReturn(1, { name: "foo", age: 35 }); + + return allLogs; + ` + .setTsHeader(testHarness + promiseTestLib) + .expectToEqual([ + "received data for user 2", + "received data for user 1", + "all requests completed", + { + name: "foo", + age: 35, + }, + { + name: "bar", + age: 42, + }, + ]); +}); + +test("promise is instanceof promise", () => { + util.testExpression`Promise.resolve(4) instanceof Promise`.expectToMatchJsResult(); +}); + +describe("Promise.all", () => { + test("resolves once all arguments are resolved", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.all([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve1("promise 1 result!"); + resolve2("promise 2 result!"); + resolve3("promise 3 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 1 result!", "promise 2 result!", "promise 3 result!"]); + }); + + test("rejects on first rejection", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.all([promise1, promise2, promise3]); + promise.then( + ([result1, result2, result3]) => { + log(result1, result2, result3); + }, + reason => { + log(reason); + } + ); + + resolve1("promise 1 result!"); + reject2("promise 2 rejects!"); + resolve3("promise 3 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 rejects!"]); + }); + + test("handles already-resolved promises", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + + const promise = Promise.all([promise1, Promise.resolve("already resolved!")]); + promise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve1("promise 1 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 1 result!", "already resolved!"]); + }); + + test("handles non-promise data", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + + const promise = Promise.all([42, promise1, "foo"]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve1("promise 1 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([42, "promise 1 result!", "foo"]); + }); + + test("returns already-resolved promise if no pending promises in arguments", () => { + util.testFunction` + const { state, value } = Promise.all([42, Promise.resolve("already resolved!"), "foo"]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: [42, "already resolved!", "foo"], + }); + }); + + test("returns already-rejected promise if already rejected promise in arguments", () => { + util.testFunction` + const { state, rejectionReason } = Promise.all([42, Promise.reject("already rejected!")]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "already rejected!", + }); + }); +}); + +describe("Promise.allSettled", () => { + test("resolves once all arguments are resolved", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve3("promise 3 result!"); + resolve1("promise 1 result!"); + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "promise 1 result!" }, + { status: "fulfilled", value: "promise 2 result!" }, + { status: "fulfilled", value: "promise 3 result!" }, + ]); + }); + + test("resolves once all arguments are rejected", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + reject2("promise 2 rejected!"); + reject1("promise 1 rejected!"); + reject3("promise 3 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "promise 1 rejected!" }, + { status: "rejected", reason: "promise 2 rejected!" }, + { status: "rejected", reason: "promise 3 rejected!" }, + ]); + }); + + test("resolves once all arguments are rejected or resolved", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.allSettled([promise1, promise2, promise3]); + promise.then(([result1, result2, result3]) => { + log(result1, result2, result3); + }); + + resolve2("promise 2 resolved!"); + reject1("promise 1 rejected!"); + reject3("promise 3 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "promise 1 rejected!" }, + { status: "fulfilled", value: "promise 2 resolved!" }, + { status: "rejected", reason: "promise 3 rejected!" }, + ]); + }); + + test("handles already resolved promises", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled([Promise.resolve("already resolved"), promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "already resolved" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("handles already rejected promises", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled([Promise.reject("already rejected"), promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "rejected", reason: "already rejected" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("handles literal arguments", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const returnedPromise = Promise.allSettled(["my literal", promise]); + returnedPromise.then(([result1, result2]) => { + log(result1, result2); + }); + + resolve("promise resolved!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { status: "fulfilled", value: "my literal" }, + { status: "fulfilled", value: "promise resolved!" }, + ]); + }); + + test("returns resolved promise for empty argument list", () => { + util.testFunction` + const { state, value } = Promise.allSettled([]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: [], + }); + }); +}); + +describe("Promise.any", () => { + test("resolves once first promise resolves", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.any([promise1, promise2, promise3]); + promise.then(data => { + log(data); + }); + + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 result!"]); + }); + + test("rejects once all promises reject", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, reject: reject3 } = defer(); + + const promise = Promise.any([promise1, promise2, promise3]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + reject3("promise 3 rejected!"); + reject1("promise 1 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { + name: "AggregateError", + message: "All Promises rejected", + errors: ["promise 2 rejected!", "promise 3 rejected!", "promise 1 rejected!"], + }, + ]); + }); + + test("handles already rejected promises", () => { + util.testFunction` + const { promise: promise1, reject: reject1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + + const promise = Promise.any([promise1, Promise.reject("already rejected!"), promise2]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + reject1("promise 1 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + { + name: "AggregateError", + message: "All Promises rejected", + errors: ["already rejected!", "promise 2 rejected!", "promise 1 rejected!"], + }, + ]); + }); + + test("rejects if iterable is empty", () => { + util.testFunction` + const { state, rejectionReason } = Promise.any([]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "No promises to resolve with .any()", + }); + }); + + test("immediately resolves with literal", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const { state, value } = Promise.any([promise, "my literal"]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my literal", + }); + }); + + test("immediately resolves with resolved promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + + const { state, value } = Promise.any([promise, Promise.resolve("my resolved promise")]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my resolved promise", + }); + }); +}); + +describe("Promise.race", () => { + test("resolves once first promise resolves", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.race([promise1, promise2, promise3]); + promise.then(data => { + log(data); + }); + + resolve2("promise 2 result!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 result!"]); + }); + + test("rejects once first promise rejects", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, reject: reject2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + + const promise = Promise.race([promise1, promise2, promise3]); + promise.catch(reason => { + log(reason); + }); + + reject2("promise 2 rejected!"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2 rejected!"]); + }); + + test("returns resolved promise if arguments contain resolved promise", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, value } = Promise.race([promise1, Promise.resolve("already resolved!"), promise2]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "already resolved!", + }); + }); + + test("returns resolved promise if arguments contain literal", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, value } = Promise.race([promise1, "my literal", promise2]) as any; + return { state, value }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "my literal", + }); + }); + + test("returns rejected promise if arguments contain rejected promise", () => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + + const { state, rejectionReason } = Promise.race([promise1, Promise.reject("already rejected!"), promise2]) as any; + return { state, rejectionReason }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "already rejected!", + }); + }); + + test("returns forever pending promise if argument array is empty", () => { + util.testFunction` + const { state } = Promise.race([]) as any; + return { state }; + ` + .setTsHeader(promiseTestLib) + .expectToEqual({ + state: 0, // __TS__PromiseState.Pending + }); + }); +}); diff --git a/test/util.ts b/test/util.ts index d8fad5280..4398b1098 100644 --- a/test/util.ts +++ b/test/util.ts @@ -292,9 +292,11 @@ export abstract class TestBuilder { // Actions - public debug(): this { + public debug(includeLualib = false): this { const transpiledFiles = this.getLuaResult().transpiledFiles; - const luaCode = transpiledFiles.map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); + const luaCode = transpiledFiles + .filter(f => includeLualib || f.outPath !== "lualib_bundle.lua") + .map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; From b0ef3b050cc090159fb8a0cc7eda1dac426237f7 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 20 Aug 2021 14:42:51 +0200 Subject: [PATCH 386/764] Fix context failed to be resolved due to parentheses (#1095) * Fix context failed to be resolved due to parentheses * Added test with more parentheses --- src/transpilation/transformers.ts | 25 ++++++++++++++++++++ test/unit/classes/classes.spec.ts | 38 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index e043704b8..7b5aacddd 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -36,6 +36,7 @@ export function getTransformers( ...(transformersFromOptions.after ?? []), ...(customTransformers.after ?? []), + stripParenthesisExpressionsTransformer, luaTransformer, ], }; @@ -53,6 +54,30 @@ export const noImplicitSelfTransformer: ts.TransformerFactory = context => sourceFile => { + // Remove parenthesis expressions before transforming to Lua, so transpiler is not hindered by extra ParenthesizedExpression nodes + function unwrapParentheses(node: ts.Expression) { + while (ts.isParenthesizedExpression(node)) { + node = node.expression; + } + return node; + } + function visit(node: ts.Node): ts.Node { + // For now only call expressions strip their expressions of parentheses, there could be more cases where this is required + if (ts.isCallExpression(node)) { + return ts.factory.updateCallExpression( + node, + unwrapParentheses(node.expression), + node.typeArguments, + node.arguments + ); + } + + return ts.visitEachChild(node, visit, context); + } + return ts.visitNode(sourceFile, visit); +}; + function loadTransformersFromOptions(program: ts.Program, diagnostics: ts.Diagnostic[]): ts.CustomTransformers { const customTransformers: Required = { before: [], diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index f4c14df34..f9ab4fe61 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -761,3 +761,41 @@ test("constructor class name available with constructor", () => { .setReturnExport("className") .expectToEqual("MyClass"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959 +test("methods accessed via this index pass correct context", () => { + util.testModule` + class Example { + baz = 3; + foo() { + this["bar"]() + } + + bar() { + return this.baz; + } + } + + const inst = new Example(); + export const result = inst.foo(); + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/959 +test.each(['(this["bar"])', '((((this["bar"]))))'])("methods in parentheses pass correct context %s", callPath => { + util.testModule` + class Example { + baz = 3; + foo() { + ${callPath}() + } + + bar() { + return this.baz; + } + } + + const inst = new Example(); + export const result = inst.foo(); + `.expectToMatchJsResult(); +}); From 98ffee61502835910d7ffa22b6045280e90fc151 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 20 Aug 2021 15:07:44 +0200 Subject: [PATCH 387/764] Async await (#1093) * Initial lualib promise class implementation * First promise tests * More promise tests * Promise class implementation * Implemented Promise.all * Promise.any * Promise.race * Promise.allSettled * fix prettier * Add promise example usage test * Added missing lualib dependencies for PromiseConstructor functions * Immediately call then/catch/finally callbacks on promises that are already resolved * Transform all references to Promise to __TS__Promise * PR feedback * Removed incorrect asyncs * Add test for direct chaining * Add test for finally and correct wrong behavior it caught * Added test throwing in parallel and chained then onFulfilleds * Fixed pull request link in ArrayIsArray lualib comment * Initial async await * Disallow await in top-level scope * Add await rejection test * Give await the correct lualib dependencies * use coroutine.status instead of lastData * Better top level await check * Add tests for async lambdas and throws in async functions * Moved toplevel await check to transformAwaitExpression and removed superfluous try/catch * fix for vararg access in async functions (#1096) Co-authored-by: Tom Co-authored-by: Tom <26638278+tomblind@users.noreply.github.com> Co-authored-by: Tom --- src/LuaLib.ts | 2 + src/lualib/Await.ts | 52 +++ src/transformation/utils/diagnostics.ts | 4 + src/transformation/visitors/async-await.ts | 36 ++ src/transformation/visitors/function.ts | 7 +- src/transformation/visitors/index.ts | 2 + src/transformation/visitors/sourceFile.ts | 1 + src/transformation/visitors/spread.ts | 5 + test/unit/builtins/async-await.spec.ts | 371 +++++++++++++++++++++ 9 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 src/lualib/Await.ts create mode 100644 src/transformation/visitors/async-await.ts create mode 100644 test/unit/builtins/async-await.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 669c68941..9c50019f5 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -28,6 +28,7 @@ export enum LuaLibFeature { ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", + Await = "Await", Class = "Class", ClassExtends = "ClassExtends", CloneDescriptor = "CloneDescriptor", @@ -101,6 +102,7 @@ const luaLibDependencies: Partial> = { ArrayConcat: [LuaLibFeature.ArrayIsArray], ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], + Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New], Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], DelegatedYield: [LuaLibFeature.StringAccess], Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts new file mode 100644 index 000000000..61f383e96 --- /dev/null +++ b/src/lualib/Await.ts @@ -0,0 +1,52 @@ +// The following is a translation of the TypeScript async awaiter which uses generators and yields. +// For Lua we use coroutines instead. +// +// Source: +// +// var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { +// function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } +// return new (P || (P = Promise))(function (resolve, reject) { +// function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } +// function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } +// function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } +// step((generator = generator.apply(thisArg, _arguments || [])).next()); +// }); +// }; +// + +// eslint-disable-next-line @typescript-eslint/promise-function-async +function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { + return new Promise((resolve, reject) => { + const asyncCoroutine = coroutine.create(generator); + + // eslint-disable-next-line @typescript-eslint/promise-function-async + function adopt(value: unknown) { + return value instanceof __TS__Promise ? value : Promise.resolve(value); + } + function fulfilled(value) { + const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); + if (success) { + step(resultOrError); + } else { + reject(resultOrError); + } + } + function step(result: unknown) { + if (coroutine.status(asyncCoroutine) === "dead") { + resolve(result); + } else { + adopt(result).then(fulfilled, reason => reject(reason)); + } + } + const [success, resultOrError] = coroutine.resume(asyncCoroutine); + if (success) { + step(resultOrError); + } else { + reject(resultOrError); + } + }); +} + +function __TS__Await(this: void, thing: unknown) { + return coroutine.yield(thing); +} diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index dbbe9376a..a7a63a717 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -147,3 +147,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory( export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( "The left-hand side of an assignment expression may not be an optional property access." ); + +export const awaitMustBeInAsyncFunction = createErrorDiagnosticFactory( + "Await can only be used inside async functions." +); diff --git a/src/transformation/visitors/async-await.ts b/src/transformation/visitors/async-await.ts new file mode 100644 index 000000000..c6dcc86dc --- /dev/null +++ b/src/transformation/visitors/async-await.ts @@ -0,0 +1,36 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { FunctionVisitor, TransformationContext } from "../context"; +import { awaitMustBeInAsyncFunction } from "../utils/diagnostics"; +import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { findFirstNodeAbove } from "../utils/typescript"; + +export const transformAwaitExpression: FunctionVisitor = (node, context) => { + // Check if await is inside an async function, it is not allowed at top level or in non-async functions + const containingFunction = findFirstNodeAbove(node, ts.isFunctionLike); + if ( + containingFunction === undefined || + !containingFunction.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) + ) { + context.diagnostics.push(awaitMustBeInAsyncFunction(node)); + } + + const expression = context.transformExpression(node.expression); + return transformLuaLibFunction(context, LuaLibFeature.Await, node, expression); +}; + +export function isAsyncFunction(declaration: ts.FunctionLikeDeclaration): boolean { + return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; +} + +export function wrapInAsyncAwaiter(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { + importLuaLibFeature(context, LuaLibFeature.Await); + + return [ + lua.createReturnStatement([ + lua.createCallExpression(lua.createIdentifier("__TS__AsyncAwaiter"), [ + lua.createFunctionExpression(lua.createBlock(statements)), + ]), + ]), + ]; +} diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index cb1d29bfd..0061ea749 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -13,6 +13,7 @@ import { } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; +import { isAsyncFunction, wrapInAsyncAwaiter } from "./async-await"; import { transformIdentifier } from "./identifier"; import { transformExpressionBodyToReturnStatement } from "./return"; import { transformBindingPattern } from "./variable-declaration"; @@ -114,7 +115,10 @@ export function transformFunctionBody( ): [lua.Statement[], Scope] { const scope = pushScope(context, ScopeType.Function); scope.node = node; - const bodyStatements = transformFunctionBodyContent(context, body); + let bodyStatements = transformFunctionBodyContent(context, body); + if (node && isAsyncFunction(node)) { + bodyStatements = wrapInAsyncAwaiter(context, bodyStatements); + } const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); return [[...headerStatements, ...bodyStatements], scope]; @@ -195,6 +199,7 @@ export function transformFunctionToExpression( spreadIdentifier, node ); + const functionExpression = lua.createFunctionExpression( lua.createBlock(transformedBody), paramNames, diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index b05527364..28f965932 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -41,6 +41,7 @@ import { typescriptVisitors } from "./typescript"; import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; import { transformVariableStatement } from "./variable-declaration"; import { jsxVisitors } from "./jsx/jsx"; +import { transformAwaitExpression } from "./async-await"; const transformEmptyStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => @@ -51,6 +52,7 @@ export const standardVisitors: Visitors = { ...typescriptVisitors, ...jsxVisitors, [ts.SyntaxKind.ArrowFunction]: transformFunctionLikeDeclaration, + [ts.SyntaxKind.AwaitExpression]: transformAwaitExpression, [ts.SyntaxKind.BinaryExpression]: transformBinaryExpression, [ts.SyntaxKind.Block]: transformBlock, [ts.SyntaxKind.BreakStatement]: transformBreakStatement, diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 604aa0c7e..41561c67f 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -23,6 +23,7 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } } else { pushScope(context, ScopeType.File); + statements = performHoisting(context, context.transformStatements(node.statements)); popScope(context); diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 6e6ec391a..f8ebdc79d 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -37,6 +37,11 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: return false; } + // Scope cannot be an async function + if (scope.node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) { + return false; + } + // Identifier must be a vararg in the local function scope's parameters const isSpreadParameter = (p: ts.ParameterDeclaration) => p.dotDotDotToken && ts.isIdentifier(p.name) && context.checker.getSymbolAtLocation(p.name) === symbol; diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts new file mode 100644 index 000000000..0a9c3513e --- /dev/null +++ b/test/unit/builtins/async-await.spec.ts @@ -0,0 +1,371 @@ +import { ModuleKind, ScriptTarget } from "typescript"; +import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics"; +import * as util from "../../util"; + +const promiseTestLib = ` +// Some logging utility, useful for asserting orders of operations + +const allLogs: any[] = []; +function log(...values: any[]) { + allLogs.push(...values); +} + +// Create a promise and store its resolve and reject functions, useful for creating pending promises + +function defer() { + let resolve: (data: any) => void = () => {}; + let reject: (reason: string) => void = () => {}; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return { promise, resolve, reject }; +}`; + +test("can await already resolved promise", () => { + util.testFunction` + const result = []; + async function abc() { + return await Promise.resolve(30); + } + abc().then(value => result.push(value)); + + return result; + `.expectToEqual([30]); +}); + +test("can await already rejected promise", () => { + util.testFunction` + const result = []; + async function abc() { + return await Promise.reject("test rejection"); + } + abc().catch(reason => result.push(reason)); + + return result; + `.expectToEqual(["test rejection"]); +}); + +test("can await pending promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + async function abc() { + return await promise; + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolving original promise", "resolved data", "resolving awaiting promise", "resolved data"]); +}); + +test("can await non-promise values", () => { + util.testFunction` + async function foo() { + return await "foo"; + } + + async function bar() { + return await { foo: await foo(), bar: "bar" }; + } + + async function baz() { + return (await bar()).foo + (await bar()).bar; + } + + const { state, value } = baz() as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "foobar", + }); +}); + +test.each(["async function abc() {", "const abc = async () => {"])( + "can return non-promise from async function (%p)", + functionHeader => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + ${functionHeader} + await promise; + return "abc return data" + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving original promise", + "resolved data", + "resolving awaiting promise", + "abc return data", + ]); + } +); + +test.each(["async function abc() {", "const abc = async () => {"])( + "can have multiple awaits in async function (%p)", + functionHeader => { + util.testFunction` + const { promise: promise1, resolve: resolve1 } = defer(); + const { promise: promise2, resolve: resolve2 } = defer(); + const { promise: promise3, resolve: resolve3 } = defer(); + promise1.then(data => log("resolving promise1", data)); + promise2.then(data => log("resolving promise2", data)); + promise3.then(data => log("resolving promise3", data)); + + ${functionHeader} + const result1 = await promise1; + const result2 = await promise2; + const result3 = await promise3; + return [result1, result2, result3]; + } + + const awaitingPromise = abc(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve1("data1"); + resolve2("data2"); + resolve3("data3"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving promise1", + "data1", + "resolving promise2", + "data2", + "resolving promise3", + "data3", + "resolving awaiting promise", + ["data1", "data2", "data3"], + ]); + } +); + +test("can make async lambdas with expression body", () => { + util.testFunction` + const foo = async () => "foo"; + const bar = async () => await foo(); + + const { state, value } = bar() as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "foo", + }); +}); + +test("can await async function from async function", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving original promise", data)); + + async function abc() { + return await promise; + } + + async function def() { + return await abc(); + } + + const awaitingPromise = def(); + awaitingPromise.then(data => log("resolving awaiting promise", data)); + + resolve("resolved data"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolving original promise", "resolved data", "resolving awaiting promise", "resolved data"]); +}); + +test("async function returning value is same as non-async function returning promise", () => { + util.testFunction` + function f(): Promise { + return Promise.resolve(42); + } + + async function fAsync(): Promise { + return 42; + } + + const { state: state1, value: value1 } = f() as any; + const { state: state2, value: value2 } = fAsync() as any; + + return { + state1, value1, + state2, value2 + }; + `.expectToEqual({ + state1: 1, // __TS__PromiseState.Fulfilled + value1: 42, + state2: 1, // __TS__PromiseState.Fulfilled + value2: 42, + }); +}); + +test("correctly handles awaited functions rejecting", () => { + util.testFunction` + const { promise: promise1, reject } = defer(); + const { promise: promise2 } = defer(); + + promise1.then(data => log("resolving promise1", data), reason => log("rejecting promise1", reason)); + promise2.then(data => log("resolving promise2", data)); + + async function abc() { + const result1 = await promise1; + const result2 = await promise2; + return [result1, result2]; + } + + const awaitingPromise = abc(); + awaitingPromise.catch(reason => log("awaiting promise was rejected because:", reason)); + + reject("test reject"); + + return allLogs; + + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejecting promise1", "test reject", "awaiting promise was rejected because:", "test reject"]); +}); + +test("can call async function at top-level", () => { + util.testModule` + export let aStarted = false; + async function a() { + aStarted = true; + return 42; + } + + a(); // Call async function (but cannot await) + ` + .setOptions({ module: ModuleKind.ESNext, target: ScriptTarget.ES2017 }) + .expectToEqual({ + aStarted: true, + }); +}); + +test("async function throws error", () => { + util.testFunction` + async function a() { + throw "test throw"; + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test throw", + }); +}); + +test("async lambda throws error", () => { + util.testFunction` + const a = async () => { + throw "test throw"; + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: "test throw", + }); +}); + +test("async function throws object", () => { + util.testFunction` + async function a() { + throw new Error("test throw"); + } + + const { state, rejectionReason } = a() as any; + return { state, rejectionReason }; + `.expectToEqual({ + state: 2, // __TS__PromiseState.Rejected + rejectionReason: { + message: "test throw", + name: "Error", + stack: expect.stringContaining("stack traceback"), + }, + }); +}); + +test.each([ + "await a();", + "const b = await a();", + "export const b = await a();", + "declare function foo(n: number): number; foo(await a());", + "declare function foo(n: number): number; const b = foo(await a());", + "const b = [await a()];", + "const b = [4, await a()];", + "const b = true ? 4 : await a();", +])("cannot await at top-level (%p)", awaitUsage => { + util.testModule` + async function a() { + return 42; + } + + ${awaitUsage} + export {} // Required to make TS happy, cannot await without import/exports + ` + .setOptions({ module: ModuleKind.ESNext, target: ScriptTarget.ES2017 }) + .expectToHaveDiagnostics([awaitMustBeInAsyncFunction.code]); +}); + +test("async function can access varargs", () => { + util.testFunction` + const { promise, resolve } = defer(); + + async function a(...args: string[]) { + log(await promise); + log(args[1]); + } + + const awaitingPromise = a("A", "B", "C"); + resolve("resolved"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolved", "B"]); +}); + +test("async function can forward varargs", () => { + util.testFunction` + const { promise, resolve } = defer(); + + async function a(...args: string[]) { + log(await promise); + log(...args); + } + + const awaitingPromise = a("A", "B", "C"); + resolve("resolved"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolved", "A", "B", "C"]); +}); From 6d9d6b192b084493a2e307566fa12f722591dd63 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 20 Aug 2021 16:42:32 +0200 Subject: [PATCH 388/764] Upgrade TypeScript (#1097) * upgrade typescript * Fix test * actually fixed test this time --- package-lock.json | 22899 +++++++++--------- package.json | 2 +- test/unit/__snapshots__/switch.spec.ts.snap | 26 +- test/unit/switch.spec.ts | 42 +- 4 files changed, 11517 insertions(+), 11452 deletions(-) diff --git a/package-lock.json b/package-lock.json index 613666d0d..6e8c38e85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "~4.3.2" + "typescript": "^4.3.5" }, "bin": { "tstl": "dist/tstl.js" @@ -32,7 +32,7 @@ "javascript-stringify": "^2.0.1", "jest": "^26.0.1", "jest-circus": "^25.1.0", - "lua-types": "^2.10.1", + "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^26.3.0", @@ -43,39 +43,72 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "dependencies": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.10.4" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", - "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.6", - "@babel/parser": "^7.9.6", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", + "gensync": "^1.0.0-beta.2", "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", + "semver": "^6.3.0", "source-map": "^0.5.0" }, "engines": { "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/core/node_modules/source-map": { @@ -88,14 +121,17 @@ } }, "node_modules/@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", "dev": true, "dependencies": { - "@babel/types": "^7.14.2", + "@babel/types": "^7.15.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/generator/node_modules/source-map": { @@ -107,131 +143,218 @@ "node": ">=0.10.0" } }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "dev": true, + "dependencies": { + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "dependencies": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", - "dev": true + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/helper-member-expression-to-functions": "^7.15.0", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "dev": true, "dependencies": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.8" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "dependencies": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", - "dev": true + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } }, "node_modules/@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", + "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", "dev": true, "dependencies": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/highlight/node_modules/ansi-styles": { @@ -275,6 +398,15 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "node_modules/@babel/highlight/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -297,9 +429,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", + "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -315,6 +447,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-bigint": { @@ -324,15 +459,33 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", - "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-json-strings": { @@ -342,15 +495,21 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", - "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { @@ -360,15 +519,21 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-object-rest-spread": { @@ -378,6 +543,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { @@ -387,6 +555,9 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/plugin-syntax-optional-chaining": { @@ -396,43 +567,104 @@ "dev": true, "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, "node_modules/@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", + "node_modules/@babel/template/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@bcoe/v8-coverage": { @@ -457,10 +689,35 @@ "node": ">=0.1.95" } }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -477,48 +734,25 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "node_modules/@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10.10.0" } }, - "node_modules/@eslint/eslintrc/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "node_modules/@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", @@ -536,463 +770,444 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/@jest/core": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", - "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/reporters": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.0.1", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-resolve-dependencies": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "jest-watcher": "^26.0.1", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/@jest/core/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "node": ">=6" }, - "engines": { - "node": ">= 10.14.2" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/core/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/@jest/core/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" + "engines": { + "node": ">=6" } }, - "node_modules/@jest/core/node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true - }, - "node_modules/@jest/core/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/@jest/core/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=8" } }, - "node_modules/@jest/core/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/@jest/core/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/@jest/core/node_modules/expect": { + "node_modules/@jest/console": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "jest-util": "^26.6.2", + "slash": "^3.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", "dev": true, "dependencies": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/@jest/core/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/@jest/core/node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/@jest/core/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, + "optional": true, + "peer": true, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/@jest/core/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/@jest/core/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/@jest/core/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/@jest/core/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/jest-resolve": { + "node_modules/@jest/core/node_modules/pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, - "node_modules/@jest/core/node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/@jest/core/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/@jest/core/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "typescript": ">=2.7" }, - "engines": { - "node": ">= 10.14.2" + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/@jest/core/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8.3" } }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">= 8.3" } }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "node_modules/@jest/environment/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } }, - "node_modules/@jest/core/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/@jest/environment/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=8" } }, - "node_modules/@jest/core/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/@jest/core/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/@jest/core/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/@jest/core/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/@jest/fake-timers/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/@jest/fake-timers/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/@jest/environment": { + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", - "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^25.5.0", + "@babel/code-frame": "^7.0.0", "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0" + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" }, "engines": { "node": ">= 8.3" } }, - "node_modules/@jest/fake-timers": { + "node_modules/@jest/fake-timers/node_modules/jest-util": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", - "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "dependencies": { "@jest/types": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "lolex": "^5.0.0" + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" }, "engines": { "node": ">= 8.3" } }, "node_modules/@jest/globals": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", - "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", "dev": true, "dependencies": { - "@jest/environment": "^26.0.1", - "@jest/types": "^26.0.1", - "expect": "^26.0.1" + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" }, "engines": { "node": ">= 10.14.2" @@ -1030,53 +1245,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/globals/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/@jest/globals/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/@jest/globals/node_modules/diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", @@ -1086,15 +1254,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@jest/globals/node_modules/expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", @@ -1151,26 +1310,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/@jest/globals/node_modules/jest-mock": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", @@ -1184,42 +1323,16 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/globals/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/jest-util": { + "node_modules/@jest/globals/node_modules/pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" }, "engines": { "node": ">= 10" @@ -1231,74 +1344,77 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/@jest/globals/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@jest/reporters": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", - "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.2", "graceful-fs": "^4.2.4", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-instrument": "^4.0.3", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" + "v8-to-istanbul": "^7.0.0" }, "engines": { "node": ">= 10.14.2" }, "optionalDependencies": { - "node-notifier": "^7.0.0" + "node-notifier": "^8.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@jest/reporters/node_modules/@jest/console": { + "node_modules/@jest/source-map": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/reporters/node_modules/@jest/test-result": { + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", @@ -1313,319 +1429,252 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/reporters/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/reporters/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/reporters/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/@jest/reporters/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@jest/reporters/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/reporters/node_modules/jest-message-util": { + "node_modules/@jest/transform": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.1.0", "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", + "babel-plugin-istanbul": "^6.0.0", "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", + "pirates": "^4.0.1", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/reporters/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/@jest/reporters/node_modules/jest-util": { + "node_modules/@jest/types": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/@jest/reporters/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/@jest/reporters/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, "engines": { - "node": ">= 10" + "node": ">= 8" } }, - "node_modules/@jest/reporters/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/@jest/reporters/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/@jest/reporters/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" + "type-detect": "4.0.8" } }, - "node_modules/@jest/reporters/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/@jest/reporters/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } + "optional": true, + "peer": true }, - "node_modules/@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/@types/babel__core": { + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@babel/types": "^7.0.0" } }, - "node_modules/@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 8.3" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", - "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "dependencies": { - "@jest/test-result": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1" - }, - "engines": { - "node": ">= 10.14.2" + "@babel/types": "^7.3.0" } }, - "node_modules/@jest/test-sequencer/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "@types/node": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/@types/istanbul-reports": { + "node_modules/@types/istanbul-reports": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", @@ -1634,2823 +1683,2952 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "node_modules/@types/jest": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "dev": true, + "dependencies": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, - "node_modules/@jest/test-sequencer/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "@types/node": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/yargs-parser": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/test-sequencer/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/@jest/test-sequencer/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/@typescript-eslint/parser": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "debug": "^4.3.1" }, "engines": { - "node": ">= 10" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/test-sequencer/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/@jest/test-sequencer/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" }, "engines": { - "node": ">=10" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/transform": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", - "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", + "node_modules/@typescript-eslint/types": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.0.1", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.0.1", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/transform/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/transform/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@typescript-eslint/types": "4.29.2", + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=10" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/transform/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/@jest/transform/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=0.4.0" } }, - "node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "debug": "4" }, "engines": { - "node": ">= 8.3" + "node": ">= 6.0.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">= 8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", "dev": true, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", - "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "type-fest": "^0.21.3" }, "engines": { - "node": ">= 8" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@sinonjs/commons": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", - "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "dependencies": { - "type-detect": "4.0.8" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" + "engines": { + "node": ">=8" } }, - "node_modules/@types/babel__core": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", - "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "sprintf-js": "~1.0.2" } }, - "node_modules/@types/babel__traverse": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", - "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, - "node_modules/@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true, - "dependencies": { - "@types/events": "*", - "@types/minimatch": "*", - "@types/node": "*" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", - "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "node_modules/array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "dependencies": { - "@types/node": "*" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", - "dev": true + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "node_modules/array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "dependencies": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "safer-buffer": "~2.1.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "node_modules/@types/node": { - "version": "13.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", - "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", - "dev": true + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", - "dev": true + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "node_modules/@types/resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true, - "dependencies": { - "@types/node": "*" + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" } }, - "node_modules/@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "node_modules/@types/yargs": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", - "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true, - "dependencies": { - "@types/yargs-parser": "*" + "engines": { + "node": "*" } }, - "node_modules/@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", - "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", + "node_modules/babel-jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.26.1", - "@typescript-eslint/scope-manager": "4.26.1", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.21", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">= 10.14.2" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", - "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", + "node_modules/babel-plugin-istanbul": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^4.0.0", + "test-exclude": "^6.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" + "node": ">=8" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "node_modules/babel-plugin-jest-hoist": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">= 10.14.2" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/babel-preset-jest": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">= 10.14.2" }, "peerDependencies": { - "eslint": ">=5" + "@babel/core": "^7.0.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "is-descriptor": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" + "tweetnacl": "^0.14.3" } }, - "node_modules/@typescript-eslint/parser": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", - "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "debug": "^4.3.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=8" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "dependencies": { + "resolve": "1.1.7" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", + "node_modules/browser-resolve/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + }, + "bin": { + "browserslist": "cli.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://opencollective.com/browserslist" } }, - "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "fast-json-stable-stringify": "2.x" }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", - "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1" + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/types": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", - "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=6" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001251", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", + "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "dev": true, "funding": { "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://opencollective.com/browserslist" } }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/capture-exit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", + "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "rsvp": "^4.8.4" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", - "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.26.1", - "eslint-visitor-keys": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "engines": { "node": ">=10" } }, - "node_modules/abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, "engines": { - "node": ">=0.4.0" + "node": ">=0.10.0" } }, - "node_modules/ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "dependencies": { - "type-fest": "^0.8.1" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" - }, + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, "engines": { - "node": ">=8" + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "color-name": "~1.1.4" }, "engines": { - "node": ">= 8" + "node": ">=7.0.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" } }, - "node_modules/argparse/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", "dev": true }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "safe-buffer": "~5.1.1" } }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "optional": true, + "peer": true }, - "node_modules/array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", - "is-string": "^1.0.5" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 8" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, "engines": { "node": ">=8" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true }, - "node_modules/array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "assert-plus": "^1.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, "engines": { - "node": ">=0.8" + "node": ">=10" } }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "node_modules/debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, + "dependencies": { + "ms": "2.1.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true, "engines": { - "node": "*" + "node": ">=0.10" } }, - "node_modules/aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "node_modules/babel-jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", - "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true, - "dependencies": { - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/babel-jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "object-keys": "^1.0.12" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.4" } }, - "node_modules/babel-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/babel-jest/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=0.4.0" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", - "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__traverse": "^7.0.6" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.3.1" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "node_modules/diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "engines": { + "node": ">= 8.3" } }, - "node_modules/babel-preset-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", - "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^26.0.0", - "babel-preset-current-node-syntax": "^0.1.2" + "path-type": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "esutils": "^2.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "webidl-conversions": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/base/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/base/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, - "node_modules/base/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, + "node_modules/electron-to-chromium": { + "version": "1.3.813", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", + "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", "dev": true, "dependencies": { - "tweetnacl": "^0.14.3" + "once": "^1.4.0" } }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, + "node_modules/enhanced-resolve": { + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "ansi-colors": "^4.1.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "resolve": "1.1.7" + "is-arrayish": "^0.2.1" } }, - "node_modules/browser-resolve/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "node_modules/es-abstract": { + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, "dependencies": { - "fast-json-stable-stringify": "2.x" + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" }, "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "dependencies": { - "node-int64": "^0.4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/capture-exit": { + "node_modules/escodegen": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "dependencies": { - "rsvp": "^4.8.4" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true + "node_modules/escodegen/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "node_modules/escodegen/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, + "optional": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "prelude-ls": "~1.1.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8.0" } }, - "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "node_modules/eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "debug": "^3.2.7", + "resolve": "^1.20.0" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "ms": "^2.1.1" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/eslint-module-utils": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" + "debug": "^3.2.7", + "pkg-dir": "^2.0.0" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.1" + "ms": "^2.1.1" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "node_modules/eslint-plugin-import": { + "version": "2.24.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", + "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", "dev": true, + "dependencies": { + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", + "has": "^1.0.3", + "is-core-module": "^2.6.0", + "minimatch": "^3.0.4", + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.10.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" } }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" + "ms": "2.0.0" } }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "cssom": "~0.3.6" + "esutils": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/eslint-plugin-jest": { + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "@typescript-eslint/experimental-utils": "^2.5.0" }, "engines": { - "node": ">=0.10" + "node": ">=8" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", "dev": true, "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" }, "engines": { - "node": ">=10" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", "dev": true, "dependencies": { - "ms": "2.1.2" + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" }, "engines": { - "node": ">=6.0" + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { - "supports-color": { + "typescript": { "optional": true } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "node_modules/eslint-plugin-jest/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/decimal.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", - "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", - "dev": true - }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "node_modules/eslint-plugin-jest/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": ">=0.10" + "node": ">=4" } }, - "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "object-keys": "^1.0.12" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">= 0.4" + "node": ">=8.0.0" } }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-property/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/define-property/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/define-property/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/eslint/node_modules/eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "eslint-visitor-keys": "^1.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": ">=4" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, + "dependencies": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, "engines": { - "node": ">=8" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=4" } }, - "node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">= 8.3" + "node": ">=4" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=0.10" } }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=4.0" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/exec-sh": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "node_modules/execa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, "engines": { - "node": ">=8.6" + "node": ">= 0.8.0" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "dev": true, - "dependencies": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" + "ms": "2.0.0" } }, - "node_modules/escodegen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", - "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "is-descriptor": "^0.1.0" }, "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": ">=0.10.0" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, - "optional": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "kind-of": "^3.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=0.10.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "dependencies": { - "ms": "2.0.0" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-module-utils": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", - "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "debug": "^2.6.9", - "pkg-dir": "^2.0.0" + "is-buffer": "^1.1.5" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "dependencies": { - "ms": "2.0.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint-module-utils/node_modules/ms": { + "node_modules/expand-brackets/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/expect": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", + "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "@jest/types": "^25.5.0", + "ansi-styles": "^4.0.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-regex-util": "^25.2.6" }, "engines": { - "node": ">=4" + "node": ">= 8.3" } }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/expect/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">= 8.3" } }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "node_modules/expect/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, - "engines": { - "node": ">=4" + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/eslint-module-utils/node_modules/path-exists": { + "node_modules/expect/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/expect/node_modules/chalk": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/eslint-module-utils/node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "node_modules/expect/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "dependencies": { - "find-up": "^2.1.0" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" }, "engines": { - "node": ">=4" + "node": ">= 8.3" } }, - "node_modules/eslint-plugin-import": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", - "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "node_modules/expect/node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true, - "dependencies": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", - "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", - "has": "^1.0.3", - "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" - }, "engines": { - "node": ">=4" + "node": ">= 8.3" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "dependencies": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-jest": { - "version": "23.8.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", - "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^2.5.0" + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "is-descriptor": "^1.0.0" }, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "is-extendable": "^0.1.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": ">=0.10.0" } }, - "node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" - } + "engines": [ + "node >=0.6.0" + ] }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=8" } }, - "node_modules/eslint/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastq": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", + "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" + "reusify": "^1.0.4" } }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "bser": "2.1.1" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": ">=10" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eslint/node_modules/globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "locate-path": "^2.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/eslint/node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eslint/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "dev": true + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": "*" } }, - "node_modules/eslint/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" }, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">= 6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/eslint/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "shebang-regex": "^3.0.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=8" + "node": ">=6 <7 || >=8" } }, - "node_modules/eslint/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=8" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/eslint/node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=6.9.0" } }, - "node_modules/eslint/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/eslint/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, "engines": { - "node": ">= 8" + "node": ">=8.0.0" } }, - "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "dependencies": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "pump": "^3.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "dependencies": { - "estraverse": "^5.1.0" + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=0.10" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, "engines": { - "node": ">=4.0" + "node": ">= 6" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=4.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" + }, "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/globby/node_modules/ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">= 4" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + }, + "node_modules/growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true, + "optional": true + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", - "dev": true - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", "dev": true, "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "ajv": "^6.12.3", + "har-schema": "^2.0.0" }, "engines": { "node": ">=6" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/expect": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", - "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-regex-util": "^25.2.6" + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=0.10.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "is-number": "^3.0.0", + "kind-of": "^4.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/extend-shallow/node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "dependencies": { - "is-plain-object": "^2.0.4" + "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/extglob/node_modules/extend-shallow": { + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-encoding-sniffer": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "whatwg-encoding": "^1.0.5" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/extglob/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/extglob/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8", + "npm": ">=1.3.7" } }, - "node_modules/extglob/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "agent-base": "6", + "debug": "4" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "engines": { + "node": ">=8.12.0" + } }, - "node_modules/fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", - "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "safer-buffer": ">= 2.1.2 < 3" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "engines": { + "node": ">= 4" } }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "bser": "2.1.1" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/import-local": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", + "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { "node": ">=8" } }, - "node_modules/find-up": { + "node_modules/import-local/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", @@ -4463,1015 +4641,1079 @@ "node": ">=8" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/import-local/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "p-locate": "^4.1.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=8" } }, - "node_modules/flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", - "dev": true - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "node_modules/import-local/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "node_modules/import-local/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "node_modules/import-local/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, "engines": { - "node": ">= 0.12" + "node": ">=6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "node_modules/import-local/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "find-up": "^4.0.0" }, "engines": { - "node": ">=6 <7 || >=8" + "node": ">=8" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=0.8.19" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", "dev": true, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=4" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" } }, - "node_modules/glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, + "node_modules/is-core-module": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "has": "^1.0.3" }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "dependencies": { - "is-glob": "^4.0.1" + "kind-of": "^6.0.0" }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, "engines": { - "node": ">= 4" + "node": ">=0.10.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" - }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, + "optional": true, + "bin": { + "is-docker": "cli.js" + }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "dependencies": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" + "is-plain-object": "^2.0.4" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, "engines": { - "node": ">= 0.4.0" + "node": ">=0.10.0" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=6" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "is-extglob": "^2.1.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, "engines": { - "node": ">=0.10.0" + "node": ">=0.12.0" } }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "isobject": "^3.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.5" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=8.12.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=0.10.0" } }, - "node_modules/import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", "dev": true, + "optional": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "is-docker": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true }, - "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true, "engines": { - "node": ">=0.8.19" + "node": ">=8" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "engines": { - "node": ">=4" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "node_modules/is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "node_modules/istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", "dev": true, "dependencies": { - "ci-info": "^2.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": ">=8" } }, - "node_modules/is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true }, - "node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "node_modules/jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", "dev": true, "dependencies": { - "kind-of": "^3.0.2" + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.14.2" } }, - "node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 10.14.2" } }, - "node_modules/is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "node_modules/jest-circus": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", + "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", "dev": true, + "dependencies": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">= 8.3" } }, - "node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "node_modules/jest-circus/node_modules/@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "node_modules/jest-circus/node_modules/@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", "dev": true, + "dependencies": { + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "node_modules/jest-circus/node_modules/@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "dev": true, - "optional": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "node_modules/jest-circus/node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "node_modules/jest-circus/node_modules/@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": ">= 8.3" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/jest-circus/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "node_modules/jest-circus/node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, - "node_modules/is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "node_modules/jest-circus/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "has": "^1.0.3" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=8" } }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "node_modules/jest-circus/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "node_modules/jest-circus/node_modules/jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, + "dependencies": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + }, "engines": { - "node": ">= 0.4" + "node": ">= 8.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" } }, - "node_modules/is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "dependencies": { - "has-symbols": "^1.0.1" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" }, "engines": { - "node": ">= 0.4" + "node": ">= 8.3" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "node_modules/jest-circus/node_modules/jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/jest-circus/node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, - "optional": true, "dependencies": { - "is-docker": "^2.0.0" + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "node_modules/jest-circus/node_modules/jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", "dev": true, + "dependencies": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "node_modules/jest-circus/node_modules/jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4" + }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "node_modules/jest-circus/node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", "semver": "^6.3.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/jest-circus/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "node_modules/jest-circus/node_modules/jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", "dev": true, "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "node_modules/jest-circus/node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", - "dev": true - }, - "node_modules/jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", - "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", + "node_modules/jest-circus/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jest/core": "^26.0.1", - "import-local": "^3.0.2", - "jest-cli": "^26.0.1" - }, - "bin": { - "jest": "bin/jest.js" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-changed-files": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", - "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "node_modules/jest-circus/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", - "execa": "^4.0.0", - "throat": "^5.0.0" + "p-try": "^2.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-circus/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-changed-files/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-circus/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" + "engines": { + "node": ">=6" } }, - "node_modules/jest-changed-files/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-circus/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/jest-circus/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/jest-changed-files/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "node_modules/jest-circus/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "node": ">=8" } }, - "node_modules/jest-changed-files/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/jest-circus/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "dependencies": { - "pump": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { "node": ">=8" @@ -5480,170 +5722,132 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-changed-files/node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "node_modules/jest-circus/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/jest-changed-files/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/jest-circus/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-changed-files/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/jest-circus/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest-changed-files/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/jest-circus/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, "engines": { "node": ">=8" } }, - "node_modules/jest-changed-files/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", "dev": true, + "dependencies": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=8" + "node": ">= 10.14.2" } }, - "node_modules/jest-changed-files/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/jest-cli/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, + "optional": true, + "peer": true, "bin": { - "node-which": "bin/node-which" + "acorn": "bin/acorn" }, "engines": { - "node": ">= 8" + "node": ">=0.4.0" } }, - "node_modules/jest-circus": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", - "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", + "node_modules/jest-cli/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.1.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0", - "stack-utils": "^1.0.1", - "throat": "^5.0.0" - }, + "optional": true, + "peer": true, "engines": { - "node": ">= 8.3" + "node": ">=0.4.0" } }, - "node_modules/jest-config": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", - "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "node_modules/jest-cli/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.0.1", - "@jest/types": "^26.0.1", - "babel-jest": "^26.0.1", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.0.1", - "jest-environment-node": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.0.1", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.0.1" + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-config/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-config/node_modules/jest-get-type": { + "node_modules/jest-cli/node_modules/jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", @@ -5652,70 +5856,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-config/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-config/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-config/node_modules/pretty-format": { + "node_modules/jest-cli/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", @@ -5730,1262 +5871,1365 @@ "node": ">= 10" } }, - "node_modules/jest-config/node_modules/react-is": { + "node_modules/jest-cli/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-config/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-cli/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">=8" + "node": ">=12.0.0" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/jest-config/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "micromatch": "^4.0.2", + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-diff": { + "node_modules/jest-config/node_modules/@jest/console": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "dependencies": { + "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" }, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "node_modules/jest-config/node_modules/@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-each": { + "node_modules/jest-config/node_modules/@jest/source-map": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", - "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" }, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", - "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", + "node_modules/jest-config/node_modules/@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "dependencies": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1", - "jsdom": "^16.2.2" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/jest-config/node_modules/@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/jest-config/node_modules/@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-config/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", + "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-config/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { + "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-environment-jsdom/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "node_modules/jest-config/node_modules/@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, - "node_modules/jest-environment-jsdom/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-config/node_modules/@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "node_modules/jest-config/node_modules/acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + } + }, + "node_modules/jest-config/node_modules/acorn-globals/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=0.4.0" } }, - "node_modules/jest-environment-jsdom/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/jest-config/node_modules/acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/jest-environment-jsdom/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-config/node_modules/babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-jsdom/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-config/node_modules/babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" }, - "engines": { - "node": ">= 10.14.2" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/jest-environment-jsdom/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/jest-config/node_modules/babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" }, "engines": { - "node": ">= 10" + "node": ">= 8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/jest-environment-jsdom/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-environment-jsdom/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/jest-config/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/jest-environment-node": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", - "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", + "node_modules/jest-config/node_modules/data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "dependencies": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - }, - "engines": { - "node": ">= 10.14.2" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/jest-config/node_modules/domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" + "webidl-conversions": "^4.0.2" } }, - "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/jest-config/node_modules/escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=4.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, - "node_modules/jest-environment-node/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-config/node_modules/html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "whatwg-encoding": "^1.0.1" } }, - "node_modules/jest-environment-node/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/jest-environment-node/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-config/node_modules/jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "detect-newline": "^3.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest-environment-node/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-environment-node/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-config/node_modules/jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/jest-config/node_modules/jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-environment-node/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-config/node_modules/jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" } }, - "node_modules/jest-environment-node/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/jest-config/node_modules/jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" }, "engines": { - "node": ">= 10" + "node": ">= 8.3" } }, - "node_modules/jest-environment-node/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "node_modules/jest-config/node_modules/jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "dev": true, + "dependencies": { + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } }, - "node_modules/jest-environment-node/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/jest-config/node_modules/jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" }, "engines": { - "node": ">=10" + "node": ">= 8.3" } }, - "node_modules/jest-get-type": { + "node_modules/jest-config/node_modules/jest-regex-util": { "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "node_modules/jest-config/node_modules/jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" + "node": ">= 8.3" } }, - "node_modules/jest-haste-map/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-config/node_modules/jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-haste-map/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-config/node_modules/jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + }, + "bin": { + "jest-runtime": "bin/jest-runtime.js" + }, + "engines": { + "node": ">= 8.3" } }, - "node_modules/jest-haste-map/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-config/node_modules/jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "graceful-fs": "^4.2.4" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 8.3" } }, - "node_modules/jest-haste-map/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/jest-config/node_modules/jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-haste-map/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-config/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "make-dir": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", - "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", + "node_modules/jest-config/node_modules/jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.0.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", - "throat": "^5.0.0" + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/jest-config/node_modules/jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/jest-config/node_modules/jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/jest-config/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.8.0" } }, - "node_modules/jest-jasmine2/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/jest-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-config/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.8.0" } }, - "node_modules/jest-jasmine2/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-jasmine2/node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true + "node_modules/jest-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } }, - "node_modules/jest-jasmine2/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true + "node_modules/jest-config/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "node_modules/jest-jasmine2/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-jasmine2/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/jest-config/node_modules/parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "node_modules/jest-config/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/jest-config/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true, "engines": { - "node": ">=8" + "node": ">= 0.8.0" } }, - "node_modules/jest-jasmine2/node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "node_modules/jest-config/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/jest-config/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-jasmine2/node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "xmlchars": "^2.1.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/jest-config/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/jest-config/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/jest-config/node_modules/tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=6" } }, - "node_modules/jest-jasmine2/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-config/node_modules/tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" + "punycode": "^2.1.0" } }, - "node_modules/jest-jasmine2/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/jest-config/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "prelude-ls": "~1.1.2" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.8.0" } }, - "node_modules/jest-jasmine2/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/jest-config/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/jest-config/node_modules/w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" } }, - "node_modules/jest-jasmine2/node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/jest-config/node_modules/webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "node_modules/jest-config/node_modules/whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - }, - "engines": { - "node": ">= 10.14.2" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, - "node_modules/jest-jasmine2/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/jest-diff/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">= 10.14.2" } }, - "node_modules/jest-jasmine2/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-jasmine2/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" }, "engines": { - "node": ">=8" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-each/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8.3" } }, - "node_modules/jest-jasmine2/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/jest-each/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-jasmine2/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/jest-each/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/jest-each/node_modules/jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">= 8.3" } }, - "node_modules/jest-leak-detector": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", - "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", + "node_modules/jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", "dev": true, "dependencies": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/@jest/types": { + "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-environment-jsdom/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", "dev": true, + "dependencies": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { + "node_modules/jest-environment-node/node_modules/@jest/environment": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { + "@jest/fake-timers": "^26.6.2", "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@types/node": "*", + "jest-mock": "^26.6.2" }, "engines": { - "node": ">= 10" + "node": ">= 10.14.2" } }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" } }, - "node_modules/jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-mock": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0" + "@jest/types": "^26.6.2", + "@types/node": "*" }, "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "node": ">= 10.14.2" } }, - "node_modules/jest-regex-util": { + "node_modules/jest-get-type": { "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "node_modules/jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" }, "engines": { - "node": ">= 8.3" + "node": ">= 10.14.2" + }, + "optionalDependencies": { + "fsevents": "^2.1.2" } }, - "node_modules/jest-resolve-dependencies": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", - "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", + "node_modules/jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", "dev": true, "dependencies": { - "@jest/types": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.0.1" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/@jest/types": { + "node_modules/jest-jasmine2/node_modules/@jest/environment": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "jest-mock": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true - }, - "node_modules/jest-resolve-dependencies/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/jest-resolve-dependencies/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/diff-sequences": { + "node_modules/jest-jasmine2/node_modules/diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", @@ -6994,16 +7238,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/expect": { + "node_modules/jest-jasmine2/node_modules/expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", @@ -7020,7 +7255,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-diff": { + "node_modules/jest-jasmine2/node_modules/jest-diff": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", @@ -7035,7 +7270,23 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-get-type": { + "node_modules/jest-jasmine2/node_modules/jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-jasmine2/node_modules/jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", @@ -7044,7 +7295,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-matcher-utils": { + "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", @@ -7059,117 +7310,141 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-message-util": { + "node_modules/jest-jasmine2/node_modules/jest-mock": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-resolve-dependencies/node_modules/jest-resolve": { + "node_modules/jest-jasmine2/node_modules/pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-snapshot": { + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-leak-detector": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-resolve-dependencies/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=8" + "node": ">= 10" + } + }, + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-message-util/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" } }, - "node_modules/jest-resolve-dependencies/node_modules/pretty-format": { + "node_modules/jest-message-util/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", @@ -7184,78 +7459,192 @@ "node": ">= 10" } }, - "node_modules/jest-resolve-dependencies/node_modules/react-is": { + "node_modules/jest-message-util/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-resolve-dependencies/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-message-util/node_modules/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jest-resolve-dependencies/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/types": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + }, + "engines": { + "node": ">= 8.3" + } + }, + "node_modules/jest-mock/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/jest-mock/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { "node": ">=8" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/jest-resolve-dependencies/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" + }, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-resolve/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/jest-resolve-dependencies/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/jest-resolve/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "p-locate": "^4.1.0" }, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-resolve-dependencies/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/jest-resolve/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" } }, "node_modules/jest-resolve/node_modules/parse-json": { @@ -7276,6 +7665,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jest-resolve/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-resolve/node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -7303,6 +7701,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { @@ -7314,48 +7715,41 @@ "node": ">=8" } }, + "node_modules/jest-resolve/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/jest-runner": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", - "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", "dev": true, "dependencies": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", + "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", + "jest-config": "^26.6.3", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.0.1", - "jest-jasmine2": "^26.0.1", - "jest-leak-detector": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", "jest-util": "^26.6.2", - "slash": "^3.0.0" + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" }, "engines": { "node": ">= 10.14.2" @@ -7393,164 +7787,90 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runner/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/jest-runner/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "node_modules/jest-runner/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-runner/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=0.4.0" } }, - "node_modules/jest-runner/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/jest-runner/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, + "optional": true, + "peer": true, "engines": { - "node": ">=8" + "node": ">=0.4.0" } }, - "node_modules/jest-runner/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/jest-runner/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" }, - "engines": { - "node": ">= 10.14.2" + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jest-runner/node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/jest-runner/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runner/node_modules/jest-util": { + "node_modules/jest-runner/node_modules/jest-mock": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "@types/node": "*" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runner/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/jest-runner/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -7572,88 +7892,85 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-runner/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-runner/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" + "node": ">=12.0.0" }, - "engines": { - "node": ">=10" + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, "node_modules/jest-runtime": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", - "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/globals": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "dependencies": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", - "yargs": "^15.3.1" + "yargs": "^15.4.1" }, "bin": { "jest-runtime": "bin/jest-runtime.js" @@ -7662,23 +7979,6 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, "node_modules/jest-runtime/node_modules/@jest/environment": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", @@ -7711,93 +8011,207 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/jest-runtime/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "optional": true, + "peer": true, + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/jest-runtime/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jest-runtime/node_modules/acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jest-runtime/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/jest-runtime/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true, + "engines": { + "node": ">= 10.14.2" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@jest/types": "^26.6.2", + "@types/node": "*" + }, + "engines": { + "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true + "node_modules/jest-runtime/node_modules/pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "dependencies": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": ">= 10" + } }, - "node_modules/jest-runtime/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "node_modules/jest-runtime/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-runtime/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/jest-runtime/node_modules/ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "optional": true, + "peer": true, + "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">=10" + "node": ">=12.0.0" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/jest-runtime/node_modules/diff-sequences": { + "node_modules/jest-serializer": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.4" + }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, + "dependencies": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", + "chalk": "^4.0.0", + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" + }, "engines": { - "node": ">=8" + "node": ">= 10.14.2" + } + }, + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true, + "engines": { + "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/expect": { + "node_modules/jest-snapshot/node_modules/expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", @@ -7814,7 +8228,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-diff": { + "node_modules/jest-snapshot/node_modules/jest-diff": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", @@ -7829,7 +8243,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-get-type": { + "node_modules/jest-snapshot/node_modules/jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", @@ -7838,7 +8252,7 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-matcher-utils": { + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", @@ -7853,130 +8267,83 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/jest-mock": { + "node_modules/jest-snapshot/node_modules/pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", - "@types/node": "*" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 10" } }, - "node_modules/jest-runtime/node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, - "node_modules/jest-runtime/node_modules/jest-resolve": { + "node_modules/jest-util": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "dependencies": { "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-snapshot": { + "node_modules/jest-validate": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "camelcase": "^6.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "leven": "^3.1.0", + "pretty-format": "^26.6.2" }, "engines": { "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-runtime/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/pretty-format": { + "node_modules/jest-validate/node_modules/pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", @@ -7991,1658 +8358,1561 @@ "node": ">= 10" } }, - "node_modules/jest-runtime/node_modules/react-is": { + "node_modules/jest-validate/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-runtime/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" }, "engines": { - "node": ">=8" + "node": ">= 10.14.2" } }, - "node_modules/jest-runtime/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-worker": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">=8" + "node": ">= 10.13.0" } }, - "node_modules/jest-runtime/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, - "node_modules/jest-runtime/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jest-runtime/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" }, "engines": { "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/jsdom/node_modules/acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": ">= 8.3" + "node": ">=4" } }, - "node_modules/jest-snapshot/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true }, - "node_modules/jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">= 8.3" + "node": ">=6" } }, - "node_modules/jest-validate": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", - "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, - "dependencies": { - "@jest/types": "^26.0.1", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "leven": "^3.1.0", - "pretty-format": "^26.0.1" - }, - "engines": { - "node": ">= 10.14.2" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/jest-validate/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, + "engines": [ + "node >=0.6.0" + ], "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-validate/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" + "engines": { + "node": ">=6" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 0.8.0" } }, - "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">=4" } }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, - "dependencies": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.0.1", - "string-length": "^4.0.1" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=4" } }, - "node_modules/jest-watcher/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=4" } }, - "node_modules/jest-watcher/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lolex": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", + "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/jest-watcher/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-watcher/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/lua-types": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "typescript-to-lua": "^0.39.0" } }, - "node_modules/jest-watcher/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "node_modules/lua-wasm-bindings": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", "dev": true }, - "node_modules/jest-watcher/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "semver": "^6.0.0" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-watcher/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "engines": { - "node": ">=8" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-watcher/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - }, - "engines": { - "node": ">= 10.14.2" + "tmpl": "1.0.x" } }, - "node_modules/jest-watcher/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-watcher/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "object-visit": "^1.0.0" }, "engines": { - "node": ">= 10" + "node": ">=0.10.0" } }, - "node_modules/jest-watcher/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true }, - "node_modules/jest-watcher/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, "engines": { - "node": ">=10" + "node": ">= 8" } }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "braces": "^3.0.1", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 10.13.0" + "node": ">=8.6" } }, - "node_modules/jest/node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "node_modules/mime-db": { + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.6" } }, - "node_modules/jest/node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "node_modules/mime-types": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "mime-db": "1.49.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 0.6" } }, - "node_modules/jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=6" } }, - "node_modules/jest/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/jest/node_modules/@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "node_modules/jest/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/jest/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/jest/node_modules/jest-cli": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", - "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true, - "dependencies": { - "@jest/core": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "prompts": "^2.0.1", - "yargs": "^15.3.1" - }, "bin": { - "jest": "bin/jest.js" + "mkdirp": "bin/cmd.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest/node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/node-notifier": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", "dev": true, + "optional": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" + "growly": "^1.3.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", + "shellwords": "^0.1.1", + "uuid": "^8.3.0", + "which": "^2.0.2" } }, - "node_modules/jest/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/node-releases": { + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", "dev": true }, - "node_modules/jest/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, "bin": { - "js-yaml": "bin/js-yaml.js" + "semver": "bin/semver" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, - "node_modules/jsdom": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", - "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "dependencies": { - "abab": "^2.0.3", - "acorn": "^7.1.1", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.2.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", - "domexception": "^2.0.1", - "escodegen": "^1.14.1", - "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", - "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.0.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", - "xml-name-validator": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "dependencies": { + "path-key": "^3.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } }, - "node_modules/json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { - "graceful-fs": "^4.1.6" + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, - "engines": [ - "node >=0.6.0" - ], "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "is-buffer": "^1.1.5" }, "engines": { - "node": ">= 0.8.0" + "node": ">=0.10.0" } }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "isobject": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.memoize": { + "node_modules/object.assign": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, - "node_modules/lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "isobject": "^3.0.1" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/lua-types": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", - "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "node_modules/object.values": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "dependencies": { - "typescript-to-lua": "^0.39.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lua-wasm-bindings": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", - "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", - "dev": true + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "semver": "^6.0.0" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "tmpl": "1.0.x" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "node_modules/p-each-series": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/map-visit": { + "node_modules/p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "p-limit": "^1.1.0" }, "engines": { - "node": ">=8.6" + "node": ">=4" } }, - "node_modules/mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true, "engines": { - "node": ">= 0.6" + "node": ">=4" } }, - "node_modules/mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { - "mime-db": "1.44.0" + "callsites": "^3.0.0" }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, "engines": { "node": ">=6" } }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" }, "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/mixin-deep/node_modules/is-extendable": { + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/node-notifier": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", - "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true, - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^7.2.1", - "shellwords": "^0.1.1", - "uuid": "^7.0.3", - "which": "^2.0.2" + "engines": { + "node": ">=4" } }, - "node_modules/node-notifier/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, - "optional": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "node-modules-regexp": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/node-notifier/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, - "optional": true, "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "find-up": "^2.1.0" }, "engines": { - "node": ">= 8" + "node": ">=4" } }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "node_modules/prettier": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, "engines": { - "node": "*" + "node": ">=10.13.0" } }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "node_modules/pretty-format": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "@jest/types": "^25.5.0", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/pretty-format/node_modules/@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">= 8.3" } }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/pretty-format/node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "dependencies": { - "is-buffer": "^1.1.5" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/pretty-format/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "dev": true - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=0.4.0" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "node_modules/prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", "dev": true, "dependencies": { - "isobject": "^3.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "dev": true, "dependencies": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - }, - "engines": { - "node": ">= 0.4" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true, - "dependencies": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" - }, "engines": { - "node": ">= 0.4" + "node": ">=0.6" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "dependencies": { - "wrappy": "1" + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" } }, - "node_modules/onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/read-pkg/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "pify": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/p-each-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "node_modules/realpath-native": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", + "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=0.10.0" } }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">=0.10" } }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", "dev": true, "dependencies": { - "error-ex": "^1.2.0" + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" }, "engines": { - "node": ">=0.10.0" + "node": ">= 6" } }, - "node_modules/parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", - "dev": true - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "node_modules/request-promise-core": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, + "dependencies": { + "lodash": "^4.17.19" + }, "engines": { "node": ">=0.10.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/request-promise-native": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", + "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", "dev": true, + "dependencies": { + "request-promise-core": "1.1.4", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + }, "engines": { - "node": ">=8" + "node": ">=0.12.0" + }, + "peerDependencies": { + "request": "^2.34" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "node_modules/request-promise-native/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=0.8" } }, - "node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, "engines": { - "node": ">=4" + "node": ">= 0.12" } }, - "node_modules/path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "dependencies": { - "pify": "^2.0.0" + "psl": "^1.1.28", + "punycode": "^2.1.1" }, "engines": { - "node": ">=4" + "node": ">=0.8" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", - "dev": true + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } }, - "node_modules/picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=0.10.0" } }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "dev": true, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dependencies": { - "node-modules-regexp": "^1.0.0" + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "resolve-from": "^5.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "node_modules/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, "engines": { - "node": ">=10.13.0" + "node": ">=0.12" } }, - "node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, "engines": { - "node": ">=0.4.0" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "glob": "^7.1.3" }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", "dev": true, "engines": { - "node": ">=0.6" + "node": "6.* || >= 7.*" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -9657,484 +9927,566 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sane": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", + "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "dev": true, + "dependencies": { + "@cnakazawa/watch": "^1.0.3", + "anymatch": "^2.0.0", + "capture-exit": "^2.0.0", + "exec-sh": "^0.3.2", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5" + }, + "bin": { + "sane": "src/cli.js" }, "engines": { - "node": ">=4" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/read-pkg-up": { + "node_modules/sane/node_modules/anymatch": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/sane/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { - "locate-path": "^2.0.0" + "is-extendable": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/sane/node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" }, "engines": { - "node": ">=4" + "node": ">=4.8" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "node_modules/sane/node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/sane/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "node_modules/sane/node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/realpath-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "node_modules/sane/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "node_modules/sane/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/remove-trailing-separator": { + "node_modules/sane/node_modules/is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "node_modules/repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "node_modules/sane/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" }, "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "node_modules/sane/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "dependencies": { - "lodash": "^4.17.15" + "remove-trailing-separator": "^1.0.1" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "node_modules/sane/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "dependencies": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" + "path-key": "^2.0.0" }, "engines": { - "node": ">=0.12.0" + "node": ">=4" } }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/sane/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, "engines": { - "node": ">=0.8" + "node": ">=4" } }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "node_modules/sane/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" + "bin": { + "semver": "bin/semver" } }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "node_modules/sane/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "bin": { - "uuid": "bin/uuid" + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "node_modules/sane/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/sane/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "node_modules/sane/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "isexe": "^2.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "bin": { + "which": "bin/which" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "dependencies": { - "resolve-from": "^5.0.0" + "xmlchars": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, "engines": { - "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "dependencies": { - "glob": "^7.1.3" + "is-extendable": "^0.1.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", "dev": true, "engines": { - "node": "6.* || >= 7.*" + "node": ">=0.10.0" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], "dependencies": { - "queue-microtask": "^1.2.2" + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true, + "optional": true + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { - "ret": "~0.1.10" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, - "bin": { - "sane": "src/cli.js" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "is-descriptor": "^1.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" + "kind-of": "^3.2.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", @@ -10146,10 +10498,10 @@ "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "dependencies": { "kind-of": "^3.0.2" @@ -10158,7 +10510,7 @@ "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", @@ -10170,271 +10522,252 @@ "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "remove-trailing-separator": "^1.0.1" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "bin": { - "semver": "bin/semver" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/set-blocking": { + "node_modules/snapdragon/node_modules/ms": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, "engines": { "node": ">=0.10.0" } }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" } }, - "node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { "node": ">=0.10.0" } }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "node_modules/signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "node_modules/spdx-license-ids": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "extend-shallow": "^3.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "node_modules/stack-utils": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", + "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", "dev": true, "dependencies": { - "is-descriptor": "^1.0.0" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/snapdragon-node/node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "dependencies": { - "kind-of": "^6.0.0" + "define-property": "^0.2.5", + "object-copy": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon-node/node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-descriptor": "^0.1.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "dependencies": { - "kind-of": "^3.2.0" + "kind-of": "^3.0.2" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon-util/node_modules/kind-of": { + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", @@ -10446,206 +10779,49 @@ "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "dependencies": { - "ms": "2.0.0" + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "dependencies": { - "is-descriptor": "^0.1.0" + "is-buffer": "^1.1.5" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "node_modules/spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stack-utils": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", - "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" }, "engines": { "node": ">=0.10.0" } }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { "node": ">=0.10.0" } @@ -10660,9 +10836,9 @@ } }, "node_modules/string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { "char-regex": "^1.0.2", @@ -10686,30 +10862,30 @@ "node": ">=8" } }, - "node_modules/string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "dependencies": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, - "engines": { - "node": ">= 0.4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/strip-ansi": { @@ -10776,9 +10952,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -10812,9 +10988,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -10852,6 +11028,9 @@ }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/test-exclude": { @@ -10947,23 +11126,23 @@ } }, "node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" }, "engines": { "node": ">=6" } }, "node_modules/tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "dependencies": { "punycode": "^2.1.1" @@ -10973,224 +11152,103 @@ } }, "node_modules/ts-jest": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", - "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", "dev": true, "dependencies": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "26.x", + "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "18.x" + "yargs-parser": "20.x" }, "bin": { "ts-jest": "cli.js" }, "engines": { "node": ">= 10" + }, + "peerDependencies": { + "jest": ">=26 <27", + "typescript": ">=3.8 <5.0" } }, - "node_modules/ts-jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "node_modules/ts-node": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=6.0.0" + }, + "peerDependencies": { + "typescript": ">=2.7" } }, - "node_modules/ts-jest/node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" } }, - "node_modules/ts-jest/node_modules/@types/jest": { - "version": "26.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", - "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" + "engines": { + "node": ">=4" } }, - "node_modules/ts-jest/node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "tslib": "^1.8.1" }, "engines": { - "node": ">=10" + "node": ">= 6" }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/ts-jest/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/ts-jest/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/ts-jest/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/ts-jest/node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/ts-jest/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-jest/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/ts-jest/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/ts-jest/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", - "dev": true, - "dependencies": { - "arg": "^4.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "source-map-support": "^0.5.6", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-script": "dist/script.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/tslib": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", - "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "dependencies": { "safe-buffer": "^5.0.1" @@ -11206,12 +11264,12 @@ "dev": true }, "node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" }, "engines": { "node": ">= 0.8.0" @@ -11227,12 +11285,15 @@ } }, "node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/typedarray-to-buffer": { @@ -11245,9 +11306,9 @@ } }, "node_modules/typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11273,6 +11334,21 @@ "node": ">=12.13.0" } }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -11288,6 +11364,15 @@ "node": ">=0.10.0" } }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", @@ -11346,9 +11431,9 @@ } }, "node_modules/uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { "punycode": "^2.1.0" @@ -11358,6 +11443,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", "dev": true }, "node_modules/use": { @@ -11370,9 +11456,9 @@ } }, "node_modules/uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "optional": true, "bin": { @@ -11380,15 +11466,15 @@ } }, "node_modules/v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "node_modules/v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -11396,7 +11482,7 @@ "source-map": "^0.7.3" }, "engines": { - "node": "8.x.x || >=10.10.0" + "node": ">=10.10.0" } }, "node_modules/validate-npm-package-license": { @@ -11478,38 +11564,48 @@ "dev": true }, "node_modules/whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" }, "engines": { "node": ">=10" } }, - "node_modules/whatwg-url/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, "dependencies": { - "isexe": "^2.0.0" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, - "bin": { - "which": "bin/which" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/which-module": { @@ -11560,9 +11656,9 @@ } }, "node_modules/ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", "dev": true, "engines": { "node": ">=8.3.0" @@ -11593,9 +11689,9 @@ "dev": true }, "node_modules/y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "node_modules/yallist": { @@ -11605,9 +11701,9 @@ "dev": true }, "node_modules/yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "dependencies": { "cliui": "^6.0.0", @@ -11620,87 +11716,186 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" }, "engines": { "node": ">=8" } }, "node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "node_modules/yargs/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dev": true, - "requires": { - "@babel/highlight": "^7.12.13" + "node": ">=8" } }, - "@babel/core": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.6.tgz", - "integrity": "sha512-nD3deLvbsApbHAHttzIssYqgb883yU/d9roe4RZymBCDaZryMJDbptVpEpeQuRh4BJ+SYI8le9YGxKvFEvl1Wg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.6", - "@babel/helper-module-transforms": "^7.9.0", - "@babel/helpers": "^7.9.6", - "@babel/parser": "^7.9.6", - "@babel/template": "^7.8.6", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, + "node_modules/yargs/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "@babel/generator": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.3.tgz", - "integrity": "sha512-bn0S6flG/j0xtQdz3hsjJ624h3W0r3llttBMfyHX3YrZ/KtLYr15bjA0FXkgW7FpvrDuTuElXeVjiKlYRpnOFA==", + "node_modules/yargs/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, - "requires": { - "@babel/types": "^7.14.2", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "dev": true, + "requires": { + "@babel/types": "^7.15.0", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + }, "dependencies": { "source-map": { "version": "0.5.7", @@ -11710,129 +11905,164 @@ } } }, + "@babel/helper-compilation-targets": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "@babel/helper-function-name": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.2.tgz", - "integrity": "sha512-NYZlkZRydxw+YT56IlhIcS8PAhb+FEUiOzuhFTfqDyPmzAhRge6ua0dQYT/Uh0t/EDHq05/i+e5M2d4XvjgarQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", + "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.12.13", - "@babel/template": "^7.12.13", - "@babel/types": "^7.14.2" + "@babel/helper-get-function-arity": "^7.14.5", + "@babel/template": "^7.14.5", + "@babel/types": "^7.14.5" } }, "@babel/helper-get-function-arity": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", - "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", + "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "dev": true, + "requires": { + "@babel/types": "^7.14.5" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", + "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-member-expression-to-functions": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", - "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.15.0" } }, "@babel/helper-module-imports": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", - "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", + "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.5" } }, "@babel/helper-module-transforms": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", - "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.8.3", - "@babel/helper-replace-supers": "^7.8.6", - "@babel/helper-simple-access": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/template": "^7.8.6", - "@babel/types": "^7.9.0", - "lodash": "^4.17.13" + "@babel/helper-module-imports": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" } }, "@babel/helper-optimise-call-expression": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", - "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", + "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.5" } }, "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, "@babel/helper-replace-supers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.9.6.tgz", - "integrity": "sha512-qX+chbxkbArLyCImk3bWV+jB5gTNU/rsze+JlcF6Nf8tVTigPJSI1o1oBow/9Resa1yehUO9lIipsmu9oG4RzA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.8.3", - "@babel/helper-optimise-call-expression": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/helper-member-expression-to-functions": "^7.15.0", + "@babel/helper-optimise-call-expression": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" } }, "@babel/helper-simple-access": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", - "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/types": "^7.14.8" } }, "@babel/helper-split-export-declaration": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", - "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", + "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", "dev": true, "requires": { - "@babel/types": "^7.12.13" + "@babel/types": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, "@babel/helpers": { - "version": "7.9.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.6.tgz", - "integrity": "sha512-tI4bUbldloLcHWoRUMAj4g1bF313M/o6fBKhIsb3QnGVPwRm9JsNf/gqMkQ7zjqReABiffPV6RWj7hEglID5Iw==", + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", + "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.6", - "@babel/types": "^7.9.6" + "@babel/template": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" } }, "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -11872,6 +12102,12 @@ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -11890,9 +12126,9 @@ } }, "@babel/parser": { - "version": "7.14.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", - "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", + "version": "7.15.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", + "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -11914,12 +12150,21 @@ } }, "@babel/plugin-syntax-class-properties": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz", - "integrity": "sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg==", + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-json-strings": { @@ -11932,12 +12177,12 @@ } }, "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.8.3.tgz", - "integrity": "sha512-Zpg2Sgc++37kuFl6ppq2Q7Awc6E6AIW671x5PY8E/f7MCIyPPGK/EoeZXvvY3P42exZ3Q4/t3YOzP/HiN79jDg==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-nullish-coalescing-operator": { @@ -11950,12 +12195,12 @@ } }, "@babel/plugin-syntax-numeric-separator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz", - "integrity": "sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw==", + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.8.3" + "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-syntax-object-rest-spread": { @@ -11985,40 +12230,78 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, - "@babel/template": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", - "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/parser": "^7.12.13", - "@babel/types": "^7.12.13" + "@babel/helper-plugin-utils": "^7.14.5" } }, - "@babel/traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.2.tgz", - "integrity": "sha512-TsdRgvBFHMyHOOzcP9S6QU0QQtjxlRpEYOy3mcCO5RgmC305ki42aSAmfZEMSSYBla2oZ9BMqYlncBaKmD/7iA==", + "@babel/template": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", + "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", "dev": true, "requires": { - "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.14.2", - "@babel/helper-function-name": "^7.14.2", - "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.14.2", - "@babel/types": "^7.14.2", + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.14.5", + "@babel/types": "^7.14.5" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + } + } + }, + "@babel/traverse": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.0", + "@babel/helper-function-name": "^7.14.5", + "@babel/helper-hoist-variables": "^7.14.5", + "@babel/helper-split-export-declaration": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", "debug": "^4.1.0", "globals": "^11.1.0" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, "@babel/types": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", - "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, @@ -12038,10 +12321,29 @@ "minimist": "^1.2.0" } }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "optional": true, + "peer": true + }, + "@cspotcode/source-map-support": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", + "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, "@eslint/eslintrc": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.2.tgz", - "integrity": "sha512-8nmGq/4ycLpIwzvhI4tNDmQztZ8sp+hI7cyG8i1nQDhkAbRzHpXPidRAHlNvCZQpJTKw5ItIpMw9RSToGF00mg==", + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -12053,37 +12355,25 @@ "js-yaml": "^3.13.1", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - } } }, + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -12095,144 +12385,381 @@ "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.0.1.tgz", - "integrity": "sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/reporters": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.0.1", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-resolve-dependencies": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "jest-watcher": "^26.0.1", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "p-locate": "^4.1.0" } }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true + }, + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } + } + } + }, + "@jest/environment": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", + "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", + "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" } }, "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { + "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, - "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "@jest/fake-timers": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", + "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "lolex": "^5.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + } + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + }, + "dependencies": { + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, "diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, "expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", @@ -12277,105 +12804,26 @@ "pretty-format": "^26.6.2" } }, - "jest-message-util": { + "jest-mock": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@types/node": "*" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { + "pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, "react-is": { @@ -12383,784 +12831,136 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } } } }, - "@jest/environment": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", - "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", "dev": true, "requires": { - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "@jest/fake-timers": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", - "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "lolex": "^5.0.0" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "@jest/globals": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.0.1.tgz", - "integrity": "sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA==", + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", "dev": true, "requires": { - "@jest/environment": "^26.0.1", - "@jest/types": "^26.0.1", - "expect": "^26.0.1" + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "@jest/reporters": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.0.1.tgz", - "integrity": "sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "node-notifier": "^7.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.1.3" - }, - "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "@jest/source-map": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.0.0.tgz", - "integrity": "sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz", - "integrity": "sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg==", - "dev": true, - "requires": { - "@jest/test-result": "^26.0.1", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-runner": "^26.0.1", - "jest-runtime": "^26.0.1" - }, - "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "@jest/transform": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.0.1.tgz", - "integrity": "sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.0.1", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.0.1", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true } } }, "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "chalk": "^4.0.0" } }, "@nodelib/fs.scandir": { @@ -13180,9 +12980,9 @@ "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz", - "integrity": "sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.5", @@ -13190,9 +12990,9 @@ } }, "@sinonjs/commons": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.0.tgz", - "integrity": "sha512-wEj54PfsZ5jGSwMX68G8ZXFawcSglQSXqCftWX3ec8MDUzQdHgcKvw97awHbY0efQEL5iKUOAmmVtoYgmrSG4Q==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -13207,10 +13007,48 @@ "@sinonjs/commons": "^1.7.0" } }, + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true, + "optional": true, + "peer": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true, + "optional": true, + "peer": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true, + "optional": true, + "peer": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true, + "optional": true, + "peer": true + }, "@types/babel__core": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", - "integrity": "sha512-RL62NqSFPCDK2FM1pSDH0scHpJvsXtZNiYlMB73DgPBaG1E38ZYVL+ei5EkWRbr+KC4YNiAUNBnRj+bgwpgjMw==", + "version": "7.1.15", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", + "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -13221,18 +13059,18 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -13240,53 +13078,46 @@ } }, "@types/babel__traverse": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.11.tgz", - "integrity": "sha512-ddHK5icION5U6q11+tV2f9Mo6CZVuT8GJKld2q9LqHSZbvLbH34Kcu2yFGckZut453+eQU6btIA3RihmnRgI+Q==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, - "@types/events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz", - "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==", - "dev": true - }, "@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", "dev": true, "requires": { "@types/node": "*" } }, "@types/glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", - "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, "requires": { - "@types/events": "*", "@types/minimatch": "*", "@types/node": "*" } }, "@types/graceful-fs": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", - "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, "requires": { "@types/node": "*" } }, "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, "@types/istanbul-lib-report": { @@ -13299,12 +13130,11 @@ } }, "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, @@ -13319,33 +13149,33 @@ } }, "@types/json-schema": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", - "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, "@types/minimatch": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", "dev": true }, "@types/node": { - "version": "13.7.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", - "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==", + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "dev": true }, "@types/normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", "dev": true }, "@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", + "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", "dev": true }, "@types/resolve": { @@ -13358,208 +13188,112 @@ } }, "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, "@types/yargs": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.4.tgz", - "integrity": "sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg==", + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.26.1.tgz", - "integrity": "sha512-aoIusj/8CR+xDWmZxARivZjbMBQTT9dImUtdZ8tVCVRXgBUuuZyM5Of5A9D9arQPxbi/0rlJLcuArclz/rCMJw==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", + "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.26.1", - "@typescript-eslint/scope-manager": "4.26.1", + "@typescript-eslint/experimental-utils": "4.29.2", + "@typescript-eslint/scope-manager": "4.29.2", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", - "lodash": "^4.17.21", "regexpp": "^3.1.0", "semver": "^7.3.5", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.26.1.tgz", - "integrity": "sha512-sQHBugRhrXzRCs9PaGg6rowie4i8s/iD/DpTB+EXte8OMDfdCG5TvO73XlO9Wc/zi0uyN4qOmX9hIjQEyhnbmQ==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/experimental-utils": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.31.0.tgz", - "integrity": "sha512-MI6IWkutLYQYTQgZ48IVnRXmLR/0Q6oAyJgiOror74arUMh7EWjJkADfirZhRsUMHeLJ85U2iySDwHTSnNi9vA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", + "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", "dev": true, "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.31.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.26.1.tgz", - "integrity": "sha512-q7F3zSo/nU6YJpPJvQveVlIIzx9/wu75lr6oDbDzoeIRWxpoc/HQ43G4rmMoCc5my/3uSj2VEpg/D83LYZF5HQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", + "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.26.1", - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/typescript-estree": "4.26.1", + "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/typescript-estree": "4.29.2", "debug": "^4.3.1" - }, - "dependencies": { - "@typescript-eslint/typescript-estree": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.26.1.tgz", - "integrity": "sha512-l3ZXob+h0NQzz80lBGaykdScYaiEbFqznEs99uwzm8fPHhDjwaBFfQkjUC/slw6Sm7npFL8qrGEAMxcfBsBJUg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@typescript-eslint/scope-manager": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.26.1.tgz", - "integrity": "sha512-TW1X2p62FQ8Rlne+WEShyd7ac2LA6o27S9i131W4NwDSfyeVlQWhw8ylldNNS8JG6oJB9Ha9Xyc+IUcqipvheQ==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", + "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", "dev": true, "requires": { - "@typescript-eslint/types": "4.26.1", - "@typescript-eslint/visitor-keys": "4.26.1" + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2" } }, "@typescript-eslint/types": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.26.1.tgz", - "integrity": "sha512-STyMPxR3cS+LaNvS8yK15rb8Y0iL0tFXq0uyl6gY45glyI7w0CsyqyEXl/Fa0JlQy+pVANeK3sbwPneCbWE7yg==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", + "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.31.0.tgz", - "integrity": "sha512-vxW149bXFXXuBrAak0eKHOzbcu9cvi6iNcJDzEtOkRwGHxJG15chiAQAwhLOsk+86p9GTr/TziYvw+H9kMaIgA==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", + "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", "dev": true, "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", + "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/visitor-keys": "4.29.2", + "debug": "^4.3.1", + "globby": "^11.0.3", "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^6.3.0", - "tsutils": "^3.17.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, "@typescript-eslint/visitor-keys": { - "version": "4.26.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.26.1.tgz", - "integrity": "sha512-IGouNSSd+6x/fHtYRyLOM6/C+QxMDzWlDtN41ea+flWuSF9g02iqcIlX8wM53JkfljoIjP0U+yp7SiTS1onEkw==", + "version": "4.29.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", + "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", "dev": true, "requires": { - "@typescript-eslint/types": "4.26.1", + "@typescript-eslint/types": "4.29.2", "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } } }, "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "acorn": { @@ -13579,22 +13313,31 @@ } }, "acorn-jsx": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", - "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, "requires": {} }, "acorn-walk": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", - "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, "ajv": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", - "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -13610,12 +13353,20 @@ "dev": true }, "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "type-fest": "^0.21.3" + }, + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, "ansi-regex": { @@ -13656,14 +13407,6 @@ "dev": true, "requires": { "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } } }, "arr-diff": { @@ -13684,14 +13427,22 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", "is-string": "^1.0.5" } }, @@ -13708,13 +13459,14 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", - "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "es-abstract": "^1.18.0-next.1" } }, "asn1": { @@ -13763,59 +13515,25 @@ "dev": true }, "aws4": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", - "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", "dev": true }, "babel-jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.0.1.tgz", - "integrity": "sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", "dev": true, "requires": { - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.0.0", + "babel-preset-jest": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } } }, "babel-plugin-istanbul": { @@ -13832,48 +13550,51 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz", - "integrity": "sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", "@types/babel__traverse": "^7.0.6" } }, "babel-preset-current-node-syntax": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.2.tgz", - "integrity": "sha512-u/8cS+dEiK1SFILbOC8/rUI3ml9lboKuuMvZ/4aQnQmhecQAgPw5ew066C1ObnEAUmlx7dv/s2z52psWEtLNiw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", "@babel/plugin-syntax-json-strings": "^7.8.3", "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", "@babel/plugin-syntax-numeric-separator": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" } }, "babel-preset-jest": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz", - "integrity": "sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.0.0", - "babel-preset-current-node-syntax": "^0.1.2" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base": { @@ -13899,35 +13620,6 @@ "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -13982,6 +13674,19 @@ } } }, + "browserslist": { + "version": "4.16.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", + "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001251", + "colorette": "^1.3.0", + "electron-to-chromium": "^1.3.811", + "escalade": "^3.1.1", + "node-releases": "^1.1.75" + } + }, "bs-logger": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", @@ -14001,9 +13706,9 @@ } }, "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, "cache-base": { @@ -14023,6 +13728,16 @@ "unset-value": "^1.0.0" } }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -14035,6 +13750,12 @@ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, + "caniuse-lite": { + "version": "1.0.30001251", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", + "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "dev": true + }, "capture-exit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", @@ -14051,9 +13772,9 @@ "dev": true }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -14072,6 +13793,12 @@ "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -14092,6 +13819,63 @@ "requires": { "is-descriptor": "^0.1.0" } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -14143,6 +13927,12 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "colorette": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", + "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", + "dev": true + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -14164,16 +13954,10 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" @@ -14191,17 +13975,23 @@ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "optional": true, + "peer": true + }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "cssom": { @@ -14248,9 +14038,9 @@ } }, "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, "requires": { "ms": "2.1.2" @@ -14263,9 +14053,9 @@ "dev": true }, "decimal.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", - "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, "decode-uri-component": { @@ -14303,37 +14093,6 @@ "requires": { "is-descriptor": "^1.0.2", "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } } }, "delayed-stream": { @@ -14367,14 +14126,6 @@ "dev": true, "requires": { "path-type": "^4.0.0" - }, - "dependencies": { - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - } } }, "doctrine": { @@ -14413,6 +14164,18 @@ "safer-buffer": "^2.1.0" } }, + "electron-to-chromium": { + "version": "1.3.813", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", + "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", + "dev": true + }, + "emittery": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "dev": true + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -14456,22 +14219,28 @@ } }, "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", + "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.11.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, "es-to-primitive": { @@ -14485,348 +14254,215 @@ "is-symbol": "^1.0.2" } }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, "escodegen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz", - "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, "requires": { "esprima": "^4.0.1", - "estraverse": "^4.2.0", + "estraverse": "^5.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1", "source-map": "~0.6.1" }, "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "eslint": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.28.0.tgz", - "integrity": "sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "globals": { - "version": "13.9.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.9.0.tgz", - "integrity": "sha512-74/FduwI/JaIrr1H8e71UbDE+5x7pIPs1C2rrwC52SszOo043CsWOZEMW7o2Y58xwm9b+0RBKDxY5n2sUpEFxA==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", "dev": true }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { - "shebang-regex": "^3.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "^1.2.1" + "prelude-ls": "~1.1.2" } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + } + } + }, + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, "requires": { - "isexe": "^2.0.0" + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } } } }, "eslint-import-resolver-node": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", - "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "requires": { - "debug": "^2.6.9", - "resolve": "^1.13.1" + "debug": "^3.2.7", + "resolve": "^1.20.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, "eslint-module-utils": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", - "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", + "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", "dev": true, "requires": { - "debug": "^2.6.9", + "debug": "^3.2.7", "pkg-dir": "^2.0.0" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "find-up": "^2.1.0" + "ms": "^2.1.1" } } } }, "eslint-plugin-import": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", - "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "version": "2.24.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", + "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", "dev": true, "requires": { - "array-includes": "^3.0.3", - "array.prototype.flat": "^1.2.1", - "contains-path": "^0.1.0", + "array-includes": "^3.1.3", + "array.prototype.flat": "^1.2.4", "debug": "^2.6.9", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "^0.3.2", - "eslint-module-utils": "^2.4.1", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.6.2", + "find-up": "^2.0.0", "has": "^1.0.3", + "is-core-module": "^2.6.0", "minimatch": "^3.0.4", - "object.values": "^1.1.0", - "read-pkg-up": "^2.0.0", - "resolve": "^1.12.0" + "object.values": "^1.1.4", + "pkg-up": "^2.0.0", + "read-pkg-up": "^3.0.0", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.10.1" }, "dependencies": { "debug": { @@ -14839,13 +14475,12 @@ } }, "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { - "esutils": "^2.0.2", - "isarray": "^1.0.0" + "esutils": "^2.0.2" } }, "ms": { @@ -14857,12 +14492,56 @@ } }, "eslint-plugin-jest": { - "version": "23.8.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.8.2.tgz", - "integrity": "sha512-xwbnvOsotSV27MtAe7s8uGWOori0nUsrXh2f1EnpmXua8sDfY6VZhHAhHg2sqK7HBNycRQExF074XSZ7DvfoFg==", + "version": "23.20.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", + "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", "dev": true, "requires": { "@typescript-eslint/experimental-utils": "^2.5.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", + "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.34.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^2.0.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.34.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", + "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "eslint-scope": { @@ -14876,18 +14555,18 @@ } }, "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" + "eslint-visitor-keys": "^2.0.0" } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true }, "espree": { @@ -14899,6 +14578,14 @@ "acorn": "^7.4.0", "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, "esprima": { @@ -14954,24 +14641,26 @@ "dev": true }, "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", + "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", "dev": true }, "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" } }, "exit": { @@ -15004,23 +14693,86 @@ "ms": "2.0.0" } }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true }, "ms": { "version": "2.0.0", @@ -15042,6 +14794,68 @@ "jest-matcher-utils": "^25.5.0", "jest-message-util": "^25.5.0", "jest-regex-util": "^25.2.6" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "@types/stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "dev": true + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + } } }, "extend": { @@ -15058,17 +14872,6 @@ "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, "extglob": { @@ -15105,34 +14908,11 @@ "is-extendable": "^0.1.0" } }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, @@ -15149,17 +14929,16 @@ "dev": true }, "fast-glob": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", - "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fast-json-stable-stringify": { @@ -15175,9 +14954,9 @@ "dev": true }, "fastq": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", - "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", + "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -15211,13 +14990,12 @@ } }, "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } }, "flat-cache": { @@ -15231,9 +15009,9 @@ } }, "flatted": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", - "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, "for-in": { @@ -15249,13 +15027,13 @@ "dev": true }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -15286,9 +15064,9 @@ "dev": true }, "fsevents": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", - "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, "optional": true }, @@ -15304,9 +15082,9 @@ "dev": true }, "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true }, "get-caller-file": { @@ -15315,6 +15093,17 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -15322,9 +15111,9 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", "dev": true, "requires": { "pump": "^3.0.0" @@ -15346,9 +15135,9 @@ } }, "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -15369,15 +15158,18 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } }, "globby": { - "version": "11.0.3", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.3.tgz", - "integrity": "sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==", + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, "requires": { "array-union": "^2.1.0", @@ -15397,9 +15189,9 @@ } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, "growly": { "version": "1.3.0", @@ -15415,12 +15207,12 @@ "dev": true }, "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", "dev": true, "requires": { - "ajv": "^6.5.5", + "ajv": "^6.12.3", "har-schema": "^2.0.0" } }, @@ -15432,6 +15224,12 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -15439,11 +15237,20 @@ "dev": true }, "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -15517,6 +15324,17 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -15528,6 +15346,16 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -15550,21 +15378,13 @@ "dev": true }, "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } } }, "import-local": { @@ -15575,6 +15395,66 @@ "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } } }, "imurmurhash": { @@ -15599,6 +15479,17 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -15606,23 +15497,12 @@ "dev": true }, "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "kind-of": "^6.0.0" } }, "is-arrayish": { @@ -15631,6 +15511,25 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", @@ -15638,9 +15537,9 @@ "dev": true }, "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-ci": { @@ -15653,70 +15552,57 @@ } }, "is-core-module": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", - "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", + "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", "requires": { "has": "^1.0.3" } }, "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "kind-of": "^6.0.0" } }, "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" } }, "is-docker": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.0.0.tgz", - "integrity": "sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", "dev": true, "optional": true }, "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } }, "is-extglob": { "version": "2.1.1", @@ -15745,12 +15631,27 @@ "is-extglob": "^2.1.1" } }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -15761,39 +15662,43 @@ } }, "is-potential-custom-element-name": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz", - "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", "dev": true }, "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "requires": { - "has": "^1.0.3" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" } }, "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.2" } }, "is-typedarray": { @@ -15836,872 +15741,590 @@ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", "dev": true }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "javascript-stringify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.0.1.tgz", - "integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==", - "dev": true - }, - "jest": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.0.1.tgz", - "integrity": "sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg==", - "dev": true, - "requires": { - "@jest/core": "^26.0.1", - "import-local": "^3.0.2", - "jest-cli": "^26.0.1" - }, - "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "jest-cli": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.0.1.tgz", - "integrity": "sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w==", - "dev": true, - "requires": { - "@jest/core": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "prompts": "^2.0.1", - "yargs": "^15.3.1" - } - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } - } - } - }, - "jest-changed-files": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.0.1.tgz", - "integrity": "sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw==", + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "execa": "^4.0.0", - "throat": "^5.0.0" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } } } }, - "jest-circus": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.1.0.tgz", - "integrity": "sha512-Axlcr2YMxVarMW4SiZhCFCjNKhdF4xF9AIdltyutQOKyyDT795Kl/fzI95O0l8idE51Npj2wDj5GhrV7uEoEJA==", + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.1.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0", - "stack-utils": "^1.0.1", - "throat": "^5.0.0" + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" } }, - "jest-config": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.0.1.tgz", - "integrity": "sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg==", + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.0.1", - "@jest/types": "^26.0.1", - "babel-jest": "^26.0.1", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.0.1", - "jest-environment-node": "^26.0.1", - "jest-get-type": "^26.0.0", - "jest-jasmine2": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "micromatch": "^4.0.2", - "pretty-format": "^26.0.1" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } } } }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "jest": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "@jest/core": "^26.6.3", + "import-local": "^3.0.2", + "jest-cli": "^26.6.3" } }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "jest-changed-files": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", "dev": true, "requires": { - "detect-newline": "^3.0.0" + "@jest/types": "^26.6.2", + "execa": "^4.0.0", + "throat": "^5.0.0" } }, - "jest-each": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", - "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "jest-circus": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", + "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", "dev": true, "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", "@jest/types": "^25.5.0", "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", "jest-util": "^25.5.0", - "pretty-format": "^25.5.0" - } - }, - "jest-environment-jsdom": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz", - "integrity": "sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g==", - "dev": true, - "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1", - "jsdom": "^16.2.2" + "pretty-format": "^25.5.0", + "stack-utils": "^1.0.1", + "throat": "^5.0.0" }, "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" } }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" + } + }, + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + } + }, + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", + "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" } }, "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { + "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, + "@types/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "dev": true + }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" + } }, "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "stack-utils": "^1.0.1" } }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "dev": true + }, + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", "graceful-fs": "^4.2.4", "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "make-dir": "^3.0.0" } }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" } - } - } - }, - "jest-environment-node": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.0.1.tgz", - "integrity": "sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ==", - "dev": true, - "requires": { - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/types": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-util": "^26.0.1" - }, - "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "p-locate": "^4.1.0" } }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "p-try": "^2.0.0" } }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "p-limit": "^2.2.0" } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" } }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "jest-cli": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "dev": true, + "requires": { + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "is-ci": "^2.0.0", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "prompts": "^2.0.1", + "yargs": "^15.4.1" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } + "optional": true, + "peer": true }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } + "optional": true, + "peer": true }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", "@jest/types": "^26.6.2", - "@types/node": "*", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -16720,592 +16343,670 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" } } } }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "jest-config": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", + "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^25.5.4", + "@jest/types": "^25.5.0", + "babel-jest": "^25.5.1", + "chalk": "^3.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", + "jest-environment-jsdom": "^25.5.0", + "jest-environment-node": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-jasmine2": "^25.5.4", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "pretty-format": "^25.5.0", + "realpath-native": "^2.0.0" }, "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "@jest/console": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", + "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-message-util": "^25.5.0", + "jest-util": "^25.5.0", + "slash": "^3.0.0" } }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "@jest/globals": { + "version": "25.5.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", + "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/environment": "^25.5.0", + "@jest/types": "^25.5.0", + "expect": "^25.5.0" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "@jest/source-map": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", + "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", + "callsites": "^3.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - } - } - }, - "jest-jasmine2": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz", - "integrity": "sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.0.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.0.1", - "jest-matcher-utils": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "pretty-format": "^26.0.1", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" + "source-map": "^0.6.0" } }, - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "@jest/test-result": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", + "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", "dev": true, "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "@jest/console": "^25.5.0", + "@jest/types": "^25.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "@jest/test-sequencer": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", + "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@jest/test-result": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-runner": "^25.5.4", + "jest-runtime": "^25.5.4" } }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "@jest/transform": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", + "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@babel/core": "^7.1.0", + "@jest/types": "^25.5.0", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^3.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^25.5.1", + "jest-regex-util": "^25.2.6", + "jest-util": "^25.5.0", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", + "@types/istanbul-reports": "^1.1.1", "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "chalk": "^3.0.0" } }, "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { + "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", "dev": true }, "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "acorn-globals": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", + "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + } } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "acorn-walk": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", + "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "dev": true + }, + "babel-jest": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", + "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", "dev": true, "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/babel__core": "^7.1.7", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" } }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "babel-plugin-jest-hoist": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", + "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__traverse": "^7.0.6" } }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "babel-preset-current-node-syntax": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", + "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true + "babel-preset-jest": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", + "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^25.5.0", + "babel-preset-current-node-syntax": "^0.1.2" + } }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", "dev": true, "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" } }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "webidl-conversions": "^4.0.2" } }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" } }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "jest-docblock": { + "version": "25.3.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", + "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "detect-newline": "^3.0.0" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "jest-environment-jsdom": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", + "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "jsdom": "^15.2.1" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "jest-environment-node": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", + "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "@jest/environment": "^25.5.0", + "@jest/fake-timers": "^25.5.0", + "@jest/types": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-util": "^25.5.0", + "semver": "^6.3.0" } }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "jest-haste-map": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", + "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "@jest/types": "^25.5.0", + "@types/graceful-fs": "^4.1.2", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-serializer": "^25.5.0", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7", + "which": "^2.0.2" } - } - } - }, - "jest-leak-detector": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz", - "integrity": "sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA==", - "dev": true, - "requires": { - "jest-get-type": "^26.0.0", - "pretty-format": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + }, + "jest-jasmine2": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", + "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^25.5.0", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "co": "^4.6.0", + "expect": "^25.5.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^25.5.0", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-runtime": "^25.5.4", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0", + "throat": "^5.0.0" } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "jest-leak-detector": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", + "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" } }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "jest-message-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", + "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/code-frame": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/stack-utils": "^1.0.1", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "slash": "^3.0.0", + "stack-utils": "^1.0.1" } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "jest-regex-util": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", + "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", "dev": true }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "jest-resolve": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", + "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@jest/types": "^25.5.0", + "browser-resolve": "^1.11.3", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", + "realpath-native": "^2.0.0", + "resolve": "^1.17.0", + "slash": "^3.0.0" } }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, - "jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" - }, - "dependencies": { + "jest-runner": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", + "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-docblock": "^25.3.0", + "jest-haste-map": "^25.5.1", + "jest-jasmine2": "^25.5.4", + "jest-leak-detector": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "jest-runtime": "^25.5.4", + "jest-util": "^25.5.0", + "jest-worker": "^25.5.0", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" + } + }, + "jest-runtime": { + "version": "25.5.4", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", + "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "dev": true, + "requires": { + "@jest/console": "^25.5.0", + "@jest/environment": "^25.5.0", + "@jest/globals": "^25.5.2", + "@jest/source-map": "^25.5.0", + "@jest/test-result": "^25.5.0", + "@jest/transform": "^25.5.1", + "@jest/types": "^25.5.0", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^25.5.4", + "jest-haste-map": "^25.5.1", + "jest-message-util": "^25.5.0", + "jest-mock": "^25.5.0", + "jest-regex-util": "^25.2.6", + "jest-resolve": "^25.5.1", + "jest-snapshot": "^25.5.1", + "jest-util": "^25.5.0", + "jest-validate": "^25.5.0", + "realpath-native": "^2.0.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.3.1" + } + }, + "jest-serializer": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", + "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "25.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", + "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^25.5.0", + "@types/prettier": "^1.19.0", + "chalk": "^3.0.0", + "expect": "^25.5.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "jest-matcher-utils": "^25.5.0", + "jest-message-util": "^25.5.0", + "jest-resolve": "^25.5.1", + "make-dir": "^3.0.0", + "natural-compare": "^1.4.0", + "pretty-format": "^25.5.0", + "semver": "^6.3.0" + } + }, + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" + } + }, + "jest-validate": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", + "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "camelcase": "^5.3.1", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "leven": "^3.1.0", + "pretty-format": "^25.5.0" + } + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + } + }, + "jsdom": { + "version": "15.2.1", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", + "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^7.1.0", + "acorn-globals": "^4.3.2", + "array-equal": "^1.0.0", + "cssom": "^0.4.1", + "cssstyle": "^2.0.0", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.1", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.2.0", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.7", + "saxes": "^3.1.9", + "symbol-tree": "^3.2.2", + "tough-cookie": "^3.0.1", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.1.2", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^7.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -17318,6 +17019,24 @@ "lines-and-columns": "^1.1.6" } }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -17348,319 +17067,201 @@ "read-pkg": "^5.2.0", "type-fest": "^0.8.1" } - } - } - }, - "jest-resolve-dependencies": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz", - "integrity": "sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw==", - "dev": true, - "requires": { - "@jest/types": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "saxes": { + "version": "3.1.11", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", + "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "xmlchars": "^2.1.1" } }, - "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "tough-cookie": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", + "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "ip-regex": "^2.1.0", + "psl": "^1.1.28", + "punycode": "^2.1.1" } }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "punycode": "^2.1.0" } }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "prelude-ls": "~1.1.2" } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" - } - }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "whatwg-url": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", + "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + } + } + }, + "jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + } + } + }, + "jest-docblock": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", + "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", + "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "jest-get-type": "^25.2.6", + "jest-util": "^25.5.0", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", "dev": true, "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "lru-cache": "^6.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "jest-util": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", + "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", "dev": true, "requires": { - "escape-string-regexp": "^2.0.0" + "@jest/types": "^25.5.0", + "chalk": "^3.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "make-dir": "^3.0.0" } } } }, - "jest-runner": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.0.1.tgz", - "integrity": "sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA==", + "jest-environment-jsdom": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", "dev": true, "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.0.1", - "jest-jasmine2": "^26.0.1", - "jest-leak-detector": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-resolve": "^26.0.1", - "jest-runtime": "^26.0.1", - "jest-util": "^26.0.1", - "jest-worker": "^26.0.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" }, "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, "@jest/environment": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", @@ -17687,79 +17288,6 @@ "jest-util": "^26.6.2" } }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" - } - }, "jest-mock": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", @@ -17769,157 +17297,115 @@ "@jest/types": "^26.6.2", "@types/node": "*" } - }, - "jest-resolve": { + } + } + }, + "jest-environment-node": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "dependencies": { + "@jest/environment": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { + "@jest/fake-timers": "^26.6.2", "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "@types/node": "*", + "jest-mock": "^26.6.2" } }, - "jest-util": { + "@jest/fake-timers": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "pretty-format": { + "jest-mock": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" + "@types/node": "*" } } } }, - "jest-runtime": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.0.1.tgz", - "integrity": "sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw==", - "dev": true, - "requires": { - "@jest/console": "^26.0.1", - "@jest/environment": "^26.0.1", - "@jest/fake-timers": "^26.0.1", - "@jest/globals": "^26.0.1", - "@jest/source-map": "^26.0.0", - "@jest/test-result": "^26.0.1", - "@jest/transform": "^26.0.1", - "@jest/types": "^26.0.1", - "@types/yargs": "^15.0.0", + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "dev": true + }, + "jest-haste-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.1.2", + "graceful-fs": "^4.2.4", + "jest-regex-util": "^26.0.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "micromatch": "^4.0.2", + "sane": "^4.0.3", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.0.1", - "jest-haste-map": "^26.0.1", - "jest-message-util": "^26.0.1", - "jest-mock": "^26.0.1", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.0.1", - "jest-snapshot": "^26.0.1", - "jest-util": "^26.0.1", - "jest-validate": "^26.0.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" + "co": "^4.6.0", + "expect": "^26.6.2", + "is-generator-fn": "^2.0.0", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", + "throat": "^5.0.0" }, "dependencies": { - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, "@jest/environment": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", @@ -17946,74 +17432,12 @@ "jest-util": "^26.6.2" } }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/prettier": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.3.tgz", - "integrity": "sha512-PijRCG/K3s3w1We6ynUKdxEc5AcuuH3NBmMDP8uvKVp6X43UY7NQlTzczakXP3DJR0F4dfNQIGjU2cUeRYs2AA==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, "diff-sequences": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - }, "expect": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", @@ -18040,6 +17464,19 @@ "pretty-format": "^26.6.2" } }, + "jest-each": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" + } + }, "jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", @@ -18052,99 +17489,269 @@ "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "chalk": "^4.0.0", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + } + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "jest-leak-detector": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "dev": true, + "requires": { + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "jest-matcher-utils": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", + "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "jest-diff": "^25.5.0", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-message-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", + "slash": "^3.0.0", + "stack-utils": "^2.0.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + } + } + } + }, + "jest-mock": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", + "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "dev": true, + "requires": { + "@jest/types": "^25.5.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" } }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" } }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "26.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", + "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "dev": true + }, + "jest-resolve": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^26.6.2", + "read-pkg-up": "^7.0.1", + "resolve": "^1.18.1", + "slash": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", - "dev": true - }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "p-locate": "^4.1.0" } }, - "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "p-try": "^2.0.0" } }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "p-limit": "^2.2.0" } }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -18157,22 +17764,10 @@ "lines-and-columns": "^1.1.6" } }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "read-pkg": { @@ -18206,130 +17801,280 @@ "type-fest": "^0.8.1" } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true } } }, - "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "jest-resolve-dependencies": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", "dev": true, "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "@jest/types": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-snapshot": "^26.6.2" } }, - "jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "jest-runner": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", "dev": true, "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.7.1", + "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" + "jest-config": "^26.6.3", + "jest-docblock": "^26.0.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "source-map-support": "^0.5.6", + "throat": "^5.0.0" }, "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + } + }, + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true + }, + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" + } + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true + }, + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } } } }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "jest-validate": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.0.1.tgz", - "integrity": "sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA==", + "jest-runtime": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", "dev": true, "requires": { - "@jest/types": "^26.0.1", - "camelcase": "^6.0.0", + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/yargs": "^15.0.0", "chalk": "^4.0.0", - "jest-get-type": "^26.0.0", - "leven": "^3.1.0", - "pretty-format": "^26.0.1" + "cjs-module-lexer": "^0.6.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^15.4.1" }, "dependencies": { - "@jest/types": { + "@jest/environment": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "jest-mock": "^26.6.2" } }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" } }, - "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true, + "optional": true, + "peer": true }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "acorn-walk": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", + "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", + "dev": true, + "optional": true, + "peer": true + }, + "jest-config": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-jasmine2": "^26.6.3", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "micromatch": "^4.0.2", + "pretty-format": "^26.6.2" } }, "jest-get-type": { @@ -18338,6 +18083,16 @@ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, + "jest-mock": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*" + } + }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -18355,124 +18110,175 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true + }, + "ts-node": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "dev": true, + "optional": true, + "peer": true, + "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" + } } } }, - "jest-watcher": { - "version": "26.0.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.0.1.tgz", - "integrity": "sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw==", + "jest-serializer": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { - "@jest/test-result": "^26.0.1", - "@jest/types": "^26.0.1", - "ansi-escapes": "^4.2.1", + "@types/node": "*", + "graceful-fs": "^4.2.4" + } + }, + "jest-snapshot": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "jest-util": "^26.0.1", - "string-length": "^4.0.1" + "expect": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "natural-compare": "^1.4.0", + "pretty-format": "^26.6.2", + "semver": "^7.3.2" }, "dependencies": { - "@jest/console": { + "diff-sequences": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "dev": true }, - "@jest/test-result": { + "expect": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/console": "^26.6.2", "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "ansi-styles": "^4.0.0", + "jest-get-type": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0" } }, - "@jest/types": { + "jest-diff": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", - "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", - "dev": true - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, - "jest-message-util": { + "jest-matcher-utils": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "jest-diff": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" } }, - "jest-util": { + "pretty-format": { "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" } }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + } + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "jest-validate": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "camelcase": "^6.0.0", + "chalk": "^4.0.0", + "jest-get-type": "^26.3.0", + "leven": "^3.1.0", + "pretty-format": "^26.6.2" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "jest-get-type": { + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "dev": true + }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", @@ -18490,18 +18296,24 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } } } }, + "jest-watcher": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^26.6.2", + "string-length": "^4.0.1" + } + }, "jest-worker": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", @@ -18520,9 +18332,9 @@ "dev": true }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -18536,37 +18348,46 @@ "dev": true }, "jsdom": { - "version": "16.2.2", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.2.tgz", - "integrity": "sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { - "abab": "^2.0.3", - "acorn": "^7.1.1", + "abab": "^2.0.5", + "acorn": "^8.2.4", "acorn-globals": "^6.0.0", "cssom": "^0.4.4", - "cssstyle": "^2.2.0", + "cssstyle": "^2.3.0", "data-urls": "^2.0.0", - "decimal.js": "^10.2.0", + "decimal.js": "^10.2.1", "domexception": "^2.0.1", - "escodegen": "^1.14.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", "html-encoding-sniffer": "^2.0.1", - "is-potential-custom-element-name": "^1.0.0", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", "nwsapi": "^2.2.0", - "parse5": "5.1.1", - "request": "^2.88.2", - "request-promise-native": "^1.0.8", - "saxes": "^5.0.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", "symbol-tree": "^3.2.4", - "tough-cookie": "^3.0.1", + "tough-cookie": "^4.0.0", "w3c-hr-time": "^1.0.2", "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.0.0", + "webidl-conversions": "^6.1.0", "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0", - "ws": "^7.2.3", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "acorn": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", + "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "dev": true + } } }, "jsesc": { @@ -18575,6 +18396,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -18606,9 +18433,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -18654,13 +18481,13 @@ "dev": true }, "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "lines-and-columns": { @@ -18670,14 +18497,14 @@ "dev": true }, "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", + "parse-json": "^4.0.0", + "pify": "^3.0.0", "strip-bom": "^3.0.0" }, "dependencies": { @@ -18690,12 +18517,13 @@ } }, "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { - "p-locate": "^4.1.0" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" } }, "lodash": { @@ -18710,12 +18538,6 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -18837,18 +18659,18 @@ } }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "dev": true }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dev": true, "requires": { - "mime-db": "1.44.0" + "mime-db": "1.49.0" } }, "mimic-fn": { @@ -18880,19 +18702,14 @@ "requires": { "for-in": "^1.0.2", "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } } }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -18943,42 +18760,26 @@ "dev": true }, "node-notifier": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-7.0.1.tgz", - "integrity": "sha512-VkzhierE7DBmQEElhTGJIoiZa1oqRijOtgOlsXg32KrJRXsPy0NXFBqWGW/wTswnJlDCs5viRYaqWguqzsKcmg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", "dev": true, "optional": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^7.2.1", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "uuid": "^7.0.3", + "uuid": "^8.3.0", "which": "^2.0.2" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "optional": true, - "requires": { - "isexe": "^2.0.0" - } - } } }, + "node-releases": { + "version": "1.1.75", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", + "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", + "dev": true + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -18989,6 +18790,14 @@ "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, "normalize-path": { @@ -18998,12 +18807,12 @@ "dev": true }, "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "requires": { - "path-key": "^2.0.0" + "path-key": "^3.0.0" } }, "nwsapi": { @@ -19038,6 +18847,43 @@ "is-descriptor": "^0.1.0" } }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -19050,9 +18896,9 @@ } }, "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true }, "object-keys": { @@ -19071,15 +18917,15 @@ } }, "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" } }, "object.pick": { @@ -19092,15 +18938,14 @@ } }, "object.values": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", - "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", + "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "function-bind": "^1.1.1", - "has": "^1.0.3" + "es-abstract": "^1.18.2" } }, "once": { @@ -19113,32 +18958,32 @@ } }, "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" } }, "p-each-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true }, "p-finally": { @@ -19148,27 +18993,27 @@ "dev": true }, "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "^1.0.0" } }, "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "^2.2.0" + "p-limit": "^1.1.0" } }, "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "parent-module": { @@ -19181,18 +19026,19 @@ } }, "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" } }, "parse5": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", - "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, "pascalcase": { @@ -19202,9 +19048,9 @@ "dev": true }, "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-is-absolute": { @@ -19214,24 +19060,21 @@ "dev": true }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true }, "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "performance-now": { "version": "2.1.0", @@ -19240,15 +19083,15 @@ "dev": true }, "picomatch": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", - "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "pirates": { @@ -19261,14 +19104,29 @@ } }, "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" } }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -19276,9 +19134,9 @@ "dev": true }, "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, "prettier": { @@ -19297,6 +19155,40 @@ "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" + }, + "dependencies": { + "@jest/types": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", + "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^15.0.0", + "chalk": "^3.0.0" + } + }, + "@types/istanbul-reports": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", + "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } } }, "progress": { @@ -19306,13 +19198,13 @@ "dev": true }, "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "sisteransi": "^1.0.5" } }, "psl": { @@ -19356,77 +19248,37 @@ "dev": true }, "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { - "load-json-file": "^2.0.0", + "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" + "path-type": "^3.0.0" }, "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "pify": "^3.0.0" } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true } } }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, "realpath-native": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", @@ -19444,9 +19296,9 @@ } }, "regexpp": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", - "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, "remove-trailing-separator": { @@ -19456,9 +19308,9 @@ "dev": true }, "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", "dev": true }, "repeat-string": { @@ -19495,6 +19347,17 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -19514,21 +19377,21 @@ } }, "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", + "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", "dev": true, "requires": { - "lodash": "^4.17.15" + "lodash": "^4.17.19" } }, "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", + "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", "dev": true, "requires": { - "request-promise-core": "1.1.3", + "request-promise-core": "1.1.4", "stealthy-require": "^1.1.1", "tough-cookie": "^2.3.3" }, @@ -19579,12 +19442,20 @@ "dev": true, "requires": { "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "resolve-url": { @@ -19706,6 +19577,34 @@ } } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -19729,6 +19628,21 @@ } } }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -19749,6 +19663,12 @@ } } }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", @@ -19779,6 +19699,42 @@ "remove-trailing-separator": "^1.0.1" } }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, "to-regex-range": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", @@ -19788,6 +19744,15 @@ "is-number": "^3.0.0", "repeat-string": "^1.6.1" } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -19801,10 +19766,13 @@ } }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "set-blocking": { "version": "2.0.0", @@ -19832,22 +19800,28 @@ "requires": { "is-extendable": "^0.1.0" } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true } } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, "shellwords": { @@ -19857,10 +19831,21 @@ "dev": true, "optional": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "sisteransi": { @@ -19929,6 +19914,69 @@ "is-extendable": "^0.1.0" } }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -19962,35 +20010,6 @@ "requires": { "is-descriptor": "^1.0.0" } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } } } }, @@ -20033,9 +20052,9 @@ } }, "source-map-support": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", - "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -20051,15 +20070,15 @@ } }, "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", "dev": true }, "spdx-correct": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", - "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -20067,15 +20086,15 @@ } }, "spdx-exceptions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", - "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -20083,9 +20102,9 @@ } }, "spdx-license-ids": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", + "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, "split-string": { @@ -20097,6 +20116,12 @@ "extend-shallow": "^3.0.0" } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", @@ -20147,8 +20172,65 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -20159,9 +20241,9 @@ "dev": true }, "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "requires": { "char-regex": "^1.0.2", @@ -20179,24 +20261,24 @@ "strip-ansi": "^6.0.0" } }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" } }, "strip-ansi": { @@ -20242,9 +20324,9 @@ } }, "supports-hyperlinks": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.1.0.tgz", - "integrity": "sha512-zoE5/e+dnEijk6ASB6/qrK+oYdm2do1hjoLWrqUC/8WEIW1gbxFcKuBof7sW8ArN6e+AYvsE8HBGiVRWL/F5CA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -20272,9 +20354,9 @@ }, "dependencies": { "ajv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.0.tgz", - "integrity": "sha512-cnUG4NSBiM4YFBxgZIj/In3/6KX+rQ2l2YPRVcvAMQGWEPKuXoPIhxzwqh31jA3IPbI4qEOp/5ILI4ynioXsGQ==", + "version": "8.6.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", + "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -20383,176 +20465,79 @@ } }, "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" } }, "tr46": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz", - "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "requires": { "punycode": "^2.1.1" } }, "ts-jest": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", - "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", + "version": "26.5.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", + "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", "dev": true, "requires": { - "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "26.x", + "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "18.x" - }, - "dependencies": { - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "26.0.23", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.23.tgz", - "integrity": "sha512-ZHLmWMJ9jJ9PTiT58juykZpL7KjwJywFN3Rr2pTSkyQfydf/rk22yS7W8p5DaVUMQ2BQC7oYiU3FjbTM/mYrOA==", - "dev": true, - "requires": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } + "yargs-parser": "20.x" } }, "ts-node": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.6.2.tgz", - "integrity": "sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==", + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", + "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.6", + "source-map-support": "^0.5.17", "yn": "3.1.1" } }, + "tsconfig-paths": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", + "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "dev": true, + "requires": { + "json5": "^2.2.0", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, "tslib": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.0.tgz", - "integrity": "sha512-BmndXUtiTn/VDDrJzQE7Mm22Ix3PxgLltW9bSNLoeCY31gnG2OPx0QqJnuc9oMIKioYrz487i6K9o4Pdn0j+Kg==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, "tsutils": { @@ -20580,12 +20565,12 @@ "dev": true }, "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "^1.2.1" } }, "type-detect": { @@ -20595,9 +20580,9 @@ "dev": true }, "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, "typedarray-to-buffer": { @@ -20610,9 +20595,9 @@ } }, "typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==" + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" }, "typescript-to-lua": { "version": "0.39.6", @@ -20625,6 +20610,18 @@ "typescript": "~4.3.2" } }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", @@ -20635,6 +20632,14 @@ "get-value": "^2.0.6", "is-extendable": "^0.1.1", "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } } }, "universalify": { @@ -20684,9 +20689,9 @@ } }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "requires": { "punycode": "^2.1.0" @@ -20705,22 +20710,22 @@ "dev": true }, "uuid": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.3.tgz", - "integrity": "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true, "optional": true }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", "dev": true }, "v8-to-istanbul": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.1.4.tgz", - "integrity": "sha512-Rw6vJHj1mbdK8edjR7+zuJrpDtKIgNdAvTSAcpYfgMIw+u2dPDntD3dgN4XQFLU2/fvFQdzj+EeSGfd/jnY5fQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", + "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -20798,33 +20803,38 @@ "dev": true }, "whatwg-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.1.0.tgz", - "integrity": "sha512-vEIkwNi9Hqt4TV9RdnaBPNt+E2Sgmo3gePebCRgZ1R7g6d23+53zCTnuB0amKI4AXq6VM8jj2DUAa0S1vjJxkw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^2.0.2", - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" } }, "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", @@ -20867,9 +20877,9 @@ } }, "ws": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", - "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", "dev": true, "requires": {} }, @@ -20886,9 +20896,9 @@ "dev": true }, "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { @@ -20898,9 +20908,9 @@ "dev": true }, "yargs": { - "version": "15.3.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", - "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", "dev": true, "requires": { "cliui": "^6.0.0", @@ -20913,18 +20923,75 @@ "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^18.1.1" + "yargs-parser": "^18.1.2" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } } }, "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true }, "yn": { "version": "3.1.1", diff --git a/package.json b/package.json index 1d508f0d1..f1d87b066 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "~4.3.2" + "typescript": "~4.3.5" }, "devDependencies": { "@types/fs-extra": "^8.1.0", diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index e7d003fa5..19a763566 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -1,6 +1,18 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`array 1`] = ` +exports[`switch not allowed in 5.1: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____switch3 = \\"abc\\" + goto ____switch3_end + ::____switch3_end:: +end +return ____exports" +`; + +exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; + +exports[`switch uses elseif 1`] = ` "local ____exports = {} function ____exports.__main(self) local result = -1 @@ -39,15 +51,3 @@ function ____exports.__main(self) end return ____exports" `; - -exports[`switch not allowed in 5.1: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local ____switch3 = \\"abc\\" - goto ____switch3_end - ::____switch3_end:: -end -return ____exports" -`; - -exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts index dd3e2a09c..c264850c2 100644 --- a/test/unit/switch.spec.ts +++ b/test/unit/switch.spec.ts @@ -262,32 +262,30 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { }); test("switch uses elseif", () => { - test("array", () => { - util.testFunction` - let result: number = -1; - - switch (2 as number) { - case 0: { - result = 200; - break; - } + util.testFunction` + let result: number = -1; - case 1: { - result = 100; - break; - } + switch (2 as number) { + case 0: { + result = 200; + break; + } - case 2: { - result = 1; - break; - } + case 1: { + result = 100; + break; } - return result; - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + case 2: { + result = 1; + break; + } + } + + return result; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); }); test("switch not allowed in 5.1", () => { From 3d1720fd30280d8098a89d32dee20e3fcceafd0d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 20 Aug 2021 19:33:42 +0200 Subject: [PATCH 389/764] Throw when a required method in optional chain is not present (#1091) * Throw when a required method is not present * Add issue link to test --- src/lualib/OptionalMethodCall.ts | 3 +++ src/transformation/visitors/call.ts | 6 ++++-- test/unit/optionalChaining.spec.ts | 12 ++++++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/lualib/OptionalMethodCall.ts b/src/lualib/OptionalMethodCall.ts index 8829e4a4d..5549a1c36 100644 --- a/src/lualib/OptionalMethodCall.ts +++ b/src/lualib/OptionalMethodCall.ts @@ -2,12 +2,15 @@ function __TS__OptionalMethodCall( this: void, table: Record TReturn>, methodName: string, + isMethodOptional: boolean, ...args: [...TArgs] ): TReturn | undefined { if (table) { const method = table[methodName]; if (method) { return method.call(table, ...args); + } else if (!isMethodOptional) { + throw `${methodName} is not a function`; } } return undefined; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 7add12ddc..b8036021e 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -161,6 +161,7 @@ export function transformContextualCallExpression( node, table, lua.createStringLiteral(left.name.text, left.name), + lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call ...transformArguments(context, args, signature) ); } else { @@ -331,7 +332,7 @@ function wrapIfRequired( shouldWrapInTable: boolean, shouldWrapOptional: boolean, call: lua.CallExpression | lua.MethodCallExpression, - node: ts.Node + node: ts.CallExpression ): lua.Expression { const wrappedOptional = shouldWrapOptional ? wrapOptionalCall(context, call, node) : call; return shouldWrapInTable ? wrapInTable(wrappedOptional) : wrappedOptional; @@ -340,7 +341,7 @@ function wrapIfRequired( function wrapOptionalCall( context: TransformationContext, call: lua.CallExpression | lua.MethodCallExpression, - node: ts.Node + node: ts.CallExpression ): lua.CallExpression { if (lua.isMethodCallExpression(call)) { return transformLuaLibFunction( @@ -349,6 +350,7 @@ function wrapOptionalCall( node, call.prefixExpression, lua.createStringLiteral(call.name.text), + lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call ...call.params ); } else { diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index cf24b6702..9763a91c6 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -144,8 +144,8 @@ describe("optional chaining function calls", () => { const objWithMethods: typeWithOptional = {}; const objWithMethods2: typeWithOptional = { a: { b: { c: () => 4 } } }; - return { - expectNil: objWithMethods.a?.b.c(), + return { + expectNil: objWithMethods.a?.b.c(), expectFour: objWithMethods2.a?.b.c() }; `.expectToMatchJsResult(); @@ -167,4 +167,12 @@ describe("optional chaining function calls", () => { return [obj.a?.().b.c?.() ?? "nil", obj2.a?.().b.c?.() ?? "nil", obj3.a?.().b.c?.() ?? "nil"]; `.expectToMatchJsResult(); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1085 + test("incorrect type, method is not a function", () => { + util.testFunction` + const obj: any = {}; + obj?.foo(); + `.expectToEqual(new util.ExecutionError("foo is not a function")); + }); }); From a01347661ee7a04bf9d881fe60d94c1d4ac0b954 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 20 Aug 2021 19:38:51 +0200 Subject: [PATCH 390/764] Remove tupleReturn annotation (#1090) * Remove tupleReturn annotation * Change places tuplereturn diagnostics are added --- src/transformation/utils/annotations.ts | 42 +- src/transformation/visitors/call.ts | 6 +- src/transformation/visitors/errors.ts | 3 +- src/transformation/visitors/function.ts | 10 + .../visitors/language-extensions/multi.ts | 8 +- src/transformation/visitors/return.ts | 27 +- .../__snapshots__/deprecated.spec.ts.snap | 40 ++ test/unit/annotations/deprecated.spec.ts | 21 + test/unit/annotations/tupleReturn.spec.ts | 466 ------------------ 9 files changed, 81 insertions(+), 542 deletions(-) delete mode 100644 test/unit/annotations/tupleReturn.spec.ts diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index a64b13788..7f7b19652 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -1,7 +1,5 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; -import { annotationDeprecated } from "./diagnostics"; -import { findFirstNodeAbove, inferAssignedType } from "./typescript"; export enum AnnotationKind { Extension = "extension", @@ -118,7 +116,6 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) const signature = context.checker.getResolvedSignature(node); if (signature) { if (getSignatureAnnotations(context, signature).has(AnnotationKind.TupleReturn)) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.TupleReturn)); return true; } @@ -134,44 +131,7 @@ export function isTupleReturnCall(context: TransformationContext, node: ts.Node) } const type = context.checker.getTypeAtLocation(node.expression); - const result = getTypeAnnotations(type).has(AnnotationKind.TupleReturn); - - if (result) { - context.diagnostics.push(annotationDeprecated(node, AnnotationKind.TupleReturn)); - } - - return result; -} - -export function isInTupleReturnFunction(context: TransformationContext, node: ts.Node): boolean { - const declaration = findFirstNodeAbove(node, ts.isFunctionLike); - if (!declaration) { - return false; - } - - let functionType: ts.Type | undefined; - if (ts.isFunctionExpression(declaration) || ts.isArrowFunction(declaration)) { - functionType = inferAssignedType(context, declaration); - } else if (ts.isMethodDeclaration(declaration) && ts.isObjectLiteralExpression(declaration.parent)) { - // Manually lookup type for object literal properties declared with method syntax - const interfaceType = inferAssignedType(context, declaration.parent); - const propertySymbol = interfaceType.getProperty(declaration.name.getText()); - if (propertySymbol) { - functionType = context.checker.getTypeOfSymbolAtLocation(propertySymbol, declaration); - } - } - - if (functionType === undefined) { - functionType = context.checker.getTypeAtLocation(declaration); - } - - // Check all overloads for directive - const signatures = functionType.getCallSignatures(); - if (signatures?.some(s => getSignatureAnnotations(context, s).has(AnnotationKind.TupleReturn))) { - return true; - } - - return getTypeAnnotations(functionType).has(AnnotationKind.TupleReturn); + return getTypeAnnotations(type).has(AnnotationKind.TupleReturn); } export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index b8036021e..22adb9a45 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; +import { AnnotationKind, getTypeAnnotations, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -250,6 +250,10 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; } + if (isTupleReturnCall(context, node)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + if (isOperatorMapping(context, node)) { return transformOperatorMappingExpression(context, node); } diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index e05ed55f3..0f067c939 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -1,7 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { isInTupleReturnFunction } from "../utils/annotations"; import { createUnpackCall } from "../utils/lua-ast"; import { findScope, ScopeType } from "../utils/scope"; import { transformScopeBlock } from "./block"; @@ -89,7 +88,7 @@ export const transformTryStatement: FunctionVisitor = (statemen returnValues.push(lua.createBooleanLiteral(true)); } - if (isInTupleReturnFunction(context, statement) || isInMultiReturnFunction(context, statement)) { + if (isInMultiReturnFunction(context, statement)) { returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); } else { returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 0061ea749..166a1b87a 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -2,6 +2,8 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; +import { AnnotationKind, getNodeAnnotations } from "../utils/annotations"; +import { annotationRemoved } from "../utils/diagnostics"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; import { @@ -225,6 +227,10 @@ export function transformFunctionLikeDeclaration( return lua.createNilLiteral(); } + if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + const [functionExpression, functionScope] = transformFunctionToExpression(context, node); // Handle named function expressions which reference themselves @@ -255,6 +261,10 @@ export function transformFunctionLikeDeclaration( } export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { + if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { + context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); + } + // Don't transform functions without body (overload declarations) if (node.body === undefined) { return undefined; diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index edf3a1650..a1c9c4030 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -4,7 +4,6 @@ import { TransformationContext } from "../../context"; import { findFirstNodeAbove } from "../../utils/typescript"; import { isIterableExpression } from "./iterable"; import { invalidMultiFunctionUse } from "../../utils/diagnostics"; -import { isTupleReturnCall } from "../../utils/annotations"; export function isMultiReturnType(type: ts.Type): boolean { return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); @@ -25,10 +24,7 @@ export function returnsMultiType(context: TransformationContext, node: ts.CallEx } export function isMultiReturnCall(context: TransformationContext, expression: ts.Expression) { - return ( - (ts.isCallExpression(expression) && returnsMultiType(context, expression)) || - isTupleReturnCall(context, expression) - ); + return ts.isCallExpression(expression) && returnsMultiType(context, expression); } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { @@ -47,7 +43,7 @@ export function isInMultiReturnFunction(context: TransformationContext, node: ts } export function shouldMultiReturnCallBeWrapped(context: TransformationContext, node: ts.CallExpression) { - if (!returnsMultiType(context, node) && !isTupleReturnCall(context, node)) { + if (!returnsMultiType(context, node)) { return false; } diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index a3eff9ec7..2ed0ebe3e 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -1,11 +1,9 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isInTupleReturnFunction } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { ScopeType, walkScopesUp } from "../utils/scope"; -import { isArrayType } from "../utils/typescript"; import { transformArguments } from "./call"; import { returnsMultiType, @@ -13,7 +11,6 @@ import { isMultiFunctionCall, isMultiReturnType, isInMultiReturnFunction, - isMultiReturnCall, canBeMultiReturnType, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; @@ -50,29 +47,7 @@ function transformExpressionsInReturn( return [createUnpackCall(context, context.transformExpression(node), node)]; } - if (!isInTupleReturnFunction(context, node)) { - return [context.transformExpression(node)]; - } - - let results: lua.Expression[]; - - // Parent function is a TupleReturn function - if (ts.isArrayLiteralExpression(node)) { - // If return expression is an array literal, leave out brackets. - results = node.elements.map(e => context.transformExpression(e)); - } else if (!isMultiReturnCall(context, node) && isArrayType(context, expressionType)) { - // If return expression is an array-type and not another TupleReturn call, unpack it - results = [createUnpackCall(context, context.transformExpression(node), node)]; - } else { - results = [context.transformExpression(node)]; - } - - // Wrap tupleReturn results when returning inside try/catch - if (insideTryCatch) { - results = [wrapInTable(...results)]; - } - - return results; + return [context.transformExpression(node)]; } export function transformExpressionBodyToReturnStatement( diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index d612bc478..6dacea3ad 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -98,6 +98,46 @@ __TS__ClassExtends(ClassB, ClassA)" exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; +exports[`tuplereturn lambda: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function f() + return {3, 4} + end +end +return ____exports" +`; + +exports[`tuplereturn lambda: diagnostics 1`] = `"main.ts(2,39): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; + +exports[`tuplereturn removed on function declaration: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function tuple(self) + return {3, 5, 1} + end +end +return ____exports" +`; + +exports[`tuplereturn removed on function declaration: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; + +exports[`tuplereturn removed: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function tuple(self) + return {3, 5, 1} + end + return tuple(nil)[3] +end +return ____exports" +`; + +exports[`tuplereturn removed: diagnostics 1`] = ` +"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information. +main.ts(4,16): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information." +`; + exports[`vararg removed: code 1`] = ` "function foo(self, ...) end diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index 2f0edb105..f7f0ac9b1 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -60,6 +60,27 @@ test("luaiterator removed", () => { `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); +test("tuplereturn removed", () => { + util.testFunction` + /** @tupleReturn */ + function tuple(): [number, number, number] { return [3, 5, 1]; } + return tuple()[2]; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code, annotationRemoved.code]); // One annotation on the function, one on the call +}); + +test("tuplereturn removed on function declaration", () => { + util.testFunction` + /** @tupleReturn */ + function tuple(): [number, number, number] { return [3, 5, 1]; } + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + +test("tuplereturn lambda", () => { + util.testFunction` + const f = /** @tupleReturn */ () => [3, 4]; + `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); +}); + const tableLibClass = ` /** @luaTable */ declare class Table { diff --git a/test/unit/annotations/tupleReturn.spec.ts b/test/unit/annotations/tupleReturn.spec.ts deleted file mode 100644 index c5077a744..000000000 --- a/test/unit/annotations/tupleReturn.spec.ts +++ /dev/null @@ -1,466 +0,0 @@ -import { annotationDeprecated } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -const expectNoUnpack: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).not.toContain("unpack"); - -test("Tuple Return Access", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3, 5, 1]; } - return tuple()[2]; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Destruct Declaration", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3,5,1]; } - const [,b,c] = tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Destruct Assignment", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number] { return [3,6]; } - let [a,b] = [1,2]; - [b,a] = tuple(); - return a - b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Static Method Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - static tuple(): [number, number, number] { return [3,5,1]; } - } - const [a,b,c] = Test.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Static Function Property Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - static tuple: () => [number, number, number] = () => [3,5,1]; - } - const [a,b,c] = Test.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Non-Static Method Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - tuple(): [number, number, number] { return [3,5,1]; } - } - const t = new Test(); - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Non-Static Function Property Return Destruct", () => { - util.testFunction` - class Test { - /** @tupleReturn */ - tuple: () => [number, number, number] = () => [3,5,1]; - } - const t = new Test(); - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Interface Method Return Destruct", () => { - util.testFunction` - interface Test { - /** @tupleReturn */ - tuple(): [number, number, number]; - } - const t: Test = { - tuple() { return [3,5,1]; } - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Interface Function Property Return Destruct", () => { - util.testFunction` - interface Test { - /** @tupleReturn */ - tuple: () => [number, number, number]; - } - const t: Test = { - tuple: () => [3,5,1] - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Object Literal Method Return Destruct", () => { - util.testFunction` - const t = { - /** @tupleReturn */ - tuple() { return [3,5,1]; } - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Object Literal Function Property Return Destruct", () => { - util.testFunction` - const t = { - /** @tupleReturn */ - tuple: () => [3,5,1] - }; - const [a,b,c] = t.tuple(); - return b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Arrow Function", () => { - util.testFunction` - const fn = /** @tupleReturn */ (s: string) => [s, "bar"]; - const [a, b] = fn("foo"); - return a + b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - const fn: Fn = s => [s, "bar"]; - const [a, b] = fn("foo"); - return a + b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(fn: Fn) { - const [a, b] = fn("foo"); - return a + b; - } - return foo(s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Elipsis Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(_: number, ...fn: Fn[]) { - const [a, b] = fn[0]("foo"); - return a + b; - } - return foo(0, s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return Inference as Elipsis Tuple Argument", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (s: string): [string, string] } - function foo(_: number, ...fn: [number, Fn]) { - const [a, b] = fn[1]("foo"); - return a + b; - } - return foo(0, 0, s => [s, "bar"]); - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return in Spread", () => { - util.testFunction` - /** @tupleReturn */ function foo(): [string, string] { - return ["foo", "bar"]; - } - function bar(a: string, b: string) { - return a + b; - } - return bar(...foo()); - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Type Alias", () => { - util.testFunction` - /** @tupleReturn */ type Fn = () => [number, number]; - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface", () => { - util.testFunction` - /** @tupleReturn */ interface Fn { (): [number, number]; } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Signature", () => { - util.testFunction` - interface Fn { - /** @tupleReturn */ (): [number, number]; - } - const fn: Fn = () => [1, 2]; - const [a, b] = fn(); - return a + b; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Overload", () => { - util.testFunction` - function fn(a: number): number; - /** @tupleReturn */ function fn(a: string, b: string): [string, string]; - function fn(a: number | string, b?: string): number | [string, string] { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - } - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Overload", () => { - util.testFunction` - interface Fn { - (a: number): number; - /** @tupleReturn */ (a: string, b: string): [string, string]; - } - const fn = ((a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - }) as Fn; - const a = fn(3); - const [b, c] = fn("foo", "bar"); - return a + b + c - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return on Interface Method Overload", () => { - util.testFunction` - interface Foo { - foo(a: number): number; - /** @tupleReturn */ foo(a: string, b: string): [string, string]; - } - const bar = { - foo: (a: number | string, b?: string): number | [string, string] => { - if (typeof a === "number") { - return a; - } else { - return [a, b as string]; - } - } - } as Foo; - const a = bar.foo(3); - const [b, c] = bar.foo("foo", "bar"); - return a + b + c; - ` - .tap(expectNoUnpack) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("Tuple Return vs Non-Tuple Return Overload", () => { - const luaHeader = ` - function fn(a, b) - if type(a) == "number" then - return {a, a + 1} - else - return a, b - end - end - `; - - const tsHeader = ` - declare function fn(this: void, a: number): [number, number]; - /** @tupleReturn */ declare function fn(this: void, a: string, b: string): [string, string]; - `; - - util.testFunction` - const [a, b] = fn(3); - const [c, d] = fn("foo", "bar"); - return (a + b) + c + d; - ` - .setTsHeader(tsHeader) - .setLuaHeader(luaHeader) - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToEqual("7foobar"); -}); - -test("TupleReturn assignment", () => { - util.testFunction` - /** @tupleReturn */ - function abc(this: void): number[] { - return [3, 5]; - } - let [a, b] = abc(); - return { a, b }; - ` - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("TupleReturn Single assignment", () => { - util.testFunction` - /** @tupleReturn */ - function abc(this: void): [number, string] { - return [3, "foo"]; - } - let a = abc(); - a = abc(); - return a; - ` - .expectToHaveDiagnostics([annotationDeprecated.code, annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("TupleReturn interface assignment", () => { - const lua = util.testFunction` - interface def { - /** @tupleReturn */ - abc(); - } declare const jkl : def; - let [a,b] = jkl.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = jkl:abc()"); -}); - -test("TupleReturn namespace assignment", () => { - const lua = util.testFunction` - declare namespace def { - /** @tupleReturn */ - function abc(this: void) {} - } - let [a,b] = def.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = def.abc()"); -}); - -test("TupleReturn method assignment", () => { - const lua = util.testFunction` - declare class def { - /** @tupleReturn */ - abc() { return [1,2,3]; } - } const jkl = new def(); - let [a,b] = jkl.abc(); - `.getMainLuaCodeChunk(); - - expect(lua).toContain("local a, b = jkl:abc()"); -}); - -test("TupleReturn functional", () => { - util.testFunction` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const [a, b] = abc(); - return b + a; - ` - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("TupleReturn single", () => { - util.testFunction` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - const res = abc(); - return res.length - ` - .expectToHaveDiagnostics([annotationDeprecated.code]) - .expectToMatchJsResult(); -}); - -test("TupleReturn in expression", () => { - util.testFunction` - /** @tupleReturn */ - function abc(): [number, string] { return [3, "a"]; } - return abc()[1] + abc()[0]; - ` - .expectToHaveDiagnostics([annotationDeprecated.code, annotationDeprecated.code]) - .expectToMatchJsResult(); -}); From 02469b997638ee66fc91b9ec5c29855cc1c47fe0 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 20 Aug 2021 20:43:56 +0200 Subject: [PATCH 391/764] CHANGELOG 1.0.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f66f3057..4ec913ca1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.0.0 + +- **[Breaking]** `/* @tupleReturn */` has been removed and will no longer have any effect. You will get an error if you try ot use it or if you use declarations that use it. +- Added support for the `Promise` class. +- Added support for `async` and `await` using coroutines. +- Module resolution now also correctly resolves `/init.lua` files for `require("")`. +- Fixed an error not being thrown when trying to call a method in an optional chain that does not exist. (If the method itself is not optional) +- Fixed a bug where parentheses could break the context parameter being resolved for a method. +- Fixed a bug where context parameters in object literal methods were not inferred correctly. +- Fixed a bug with sourceMapTraceback. +- Fixed TS emitting empty JSON files if you use JSON source files. + ## 0.42.0 - **[Breaking]** The `/** @tupleReturn */` is now deprecated, and will be removed next release. If you are still using it, please upgrade to the [LuaMultiReturn language extension](https://typescripttolua.github.io/docs/advanced/language-extensions#luamultireturn-type). From a6a89dfd0a72d10207ecbd2088acd89d2390723b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 20 Aug 2021 20:51:38 +0200 Subject: [PATCH 392/764] 1.0.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6e8c38e85..816c311bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "0.42.0", + "version": "1.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "0.42.0", + "version": "1.0.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index f1d87b066..d80bb1a36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "0.42.0", + "version": "1.0.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d6ef52901f718cebd11662929e4847cbd6337794 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 26 Aug 2021 13:37:08 +0200 Subject: [PATCH 393/764] Update TSTL extension ID in devcontainer (#1104) --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 311827173..fcfad7738 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -5,7 +5,7 @@ "terminal.integrated.shell.linux": "/bin/bash" }, "extensions": [ - "ark120202.vscode-typescript-to-lua", + "typescript-to-lua.vscode-typescript-to-lua", "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "esbenp.prettier-vscode" From 12cce1237af4387cddffd086f2f0fb2610728923 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 30 Aug 2021 12:01:10 -0600 Subject: [PATCH 394/764] support for global $vararg in bundles (#1107) * support for global $vararg in bundles fixes #1048 To emulate normal Lua functionality, the entry point receives the global vararg and sub-modules receive their own name when evaluating `$vararg` (`...`). * using dummy vararg when wrapping bundle tests to prevent lua error Co-authored-by: Tom --- src/transpilation/bundle.ts | 9 ++++---- test/unit/language-extensions/vararg.spec.ts | 23 ++++++++++++++++++++ test/util.ts | 2 +- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 78e03a7a6..02eb73e30 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -16,12 +16,13 @@ const requireOverride = ` local ____modules = {} local ____moduleCache = {} local ____originalRequire = require -local function require(file) +local function require(file, ...) if ____moduleCache[file] then return ____moduleCache[file].value end if ____modules[file] then - ____moduleCache[file] = { value = ____modules[file]() } + local module = ____modules[file] + ____moduleCache[file] = { value = (select("#", ...) > 0) and module(...) or module(file) } return ____moduleCache[file].value else if ____originalRequire then @@ -55,7 +56,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(entryModule, program)})\n`; + const entryPoint = `return require(${createModulePath(entryModule, program)}, ...)\n`; const sourceChunks = [requireOverride, moduleTable, entryPoint]; @@ -78,7 +79,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t } function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { - const tableEntryHead = `[${modulePath}] = function() `; + const tableEntryHead = `[${modulePath}] = function(...) `; const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); diff --git a/test/unit/language-extensions/vararg.spec.ts b/test/unit/language-extensions/vararg.spec.ts index 18872c161..d5aa9fc69 100644 --- a/test/unit/language-extensions/vararg.spec.ts +++ b/test/unit/language-extensions/vararg.spec.ts @@ -6,6 +6,7 @@ test.each([ 'let result: string; { result = [...$vararg].join(""); }', 'let result: string; if (true) { result = [...$vararg].join(""); }', 'let result: string; do { result = [...$vararg].join(""); } while (false);', + 'function foo(...args: unknown[]) { return args.join(""); } const result = foo(...$vararg);', ])("$vararg valid use (%p)", statement => { util.testModule` ${statement} @@ -30,3 +31,25 @@ test.each([ .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]); }); + +test("$vararg in bundle entry point", () => { + util.testModule` + export const result = [...$vararg].join(""); + ` + .setMainFileName("src/main.ts") + .setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" }) + .withLanguageExtensions() + .setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`) + .expectToEqual({ result: "ABCD" }); +}); + +test("$vararg in bundle sub-module", () => { + util.testModule` + export { result } from "./module"; + ` + .setMainFileName("src/main.ts") + .addExtraFile("src/module.ts", 'export const result = [...$vararg].join("")') + .setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" }) + .withLanguageExtensions() + .expectToEqual({ result: "module" }); +}); diff --git a/test/util.ts b/test/util.ts index 4398b1098..532ba944f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -529,7 +529,7 @@ class AccessorTestBuilder extends TestBuilder { protected accessor = ""; protected getLuaCodeWithWrapper(code: string) { - return `return (function()\n${code}\nend)()${this.accessor}`; + return `return (function(...)\n${code}\nend)()${this.accessor}`; } @memoize From dd8872251b06e58f0f6a5980db1e6599f35213e2 Mon Sep 17 00:00:00 2001 From: wildbook <1352092+wildbook@users.noreply.github.com> Date: Tue, 31 Aug 2021 18:06:30 +0200 Subject: [PATCH 395/764] Avoid using baseUrl for relative imports (#1111) --- src/transpilation/resolve.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 38c130e84..69895391b 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -167,8 +167,15 @@ function resolveDependency( console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); } + // Check if the import is relative + const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); + + // If the import is relative, always resolve it relative to the requiring file + // If the import is not relative, resolve it relative to options.baseUrl if it is set + const relativeTo = isRelative ? fileDirectory : options.baseUrl ?? fileDirectory; + // Check if file is a file in the project - const resolvedPath = path.join(options.baseUrl ?? fileDirectory, dependency); + const resolvedPath = path.join(relativeTo, dependency); const possibleProjectFiles = [ resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, From ec76f4baded328026edcd47902c45f605b6531bb Mon Sep 17 00:00:00 2001 From: Justin Walsh Date: Sat, 4 Sep 2021 11:03:59 -0700 Subject: [PATCH 396/764] feat: switch statements for lua 5.1+ (universal) (#1098) * feat: switch statements for lua 5.1 * refactor: cleanup & switch with only default * fix: lexical scoping create scope for switch and remove additional scope for each clause. * fix: test do not pollute parent scope * fix: scope switch in repeat-until, emit break * fix: non duplicating case body switch * chore: comments * refactor: handle side-effects plus test * fix: cleanup & feedback * chore: remove dead code * refactor: cleanup redundent break statement * refactor: cleanup for maintainability and review * chore: remove dead comment * fix: handle no initial statment fallthrough * test: async case * fix: containsBreakOrReturn & final default fallthrough * refactor: coalesceCondition function * fix: do not copy statements to check for break * refactor: cleanup clauses access * chore(nit): comment * fix: ensure final clause is evaluated * refactor: simplify and cleanup output * fix: remove redundant final default clause * fix: ensure we evaluate empty fallthrough clause --- src/transformation/visitors/break-continue.ts | 8 +- src/transformation/visitors/switch.ts | 179 +++++++++++++--- test/unit/__snapshots__/switch.spec.ts.snap | 101 +++++---- test/unit/switch.spec.ts | 197 ++++++++++++++++-- 4 files changed, 391 insertions(+), 94 deletions(-) diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 9211d4165..9e476b17e 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -6,12 +6,8 @@ import { unsupportedForTarget } from "../utils/diagnostics"; import { findScope, ScopeType } from "../utils/scope"; export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { - const breakableScope = findScope(context, ScopeType.Loop | ScopeType.Switch); - if (breakableScope?.type === ScopeType.Switch) { - return lua.createGotoStatement(`____switch${breakableScope.id}_end`); - } else { - return lua.createBreakStatement(breakStatement); - } + void context; + return lua.createBreakStatement(breakStatement); }; export const transformContinueStatement: FunctionVisitor = (statement, context) => { diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index a82ff0bf0..1a05bae41 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -1,61 +1,172 @@ import * as ts from "typescript"; -import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; -import { unsupportedForTarget } from "../utils/diagnostics"; +import { FunctionVisitor, TransformationContext } from "../context"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; -export const transformSwitchStatement: FunctionVisitor = (statement, context) => { - if (context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua51) { - context.diagnostics.push(unsupportedForTarget(statement, "Switch statements", LuaTarget.Lua51)); +const containsBreakOrReturn = (nodes: Iterable): boolean => { + for (const s of nodes) { + if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) { + return true; + } else if (ts.isBlock(s) && containsBreakOrReturn(s.getChildren())) { + return true; + } else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) { + return true; + } + } + + return false; +}; + +const coalesceCondition = ( + condition: lua.Expression | undefined, + switchVariable: lua.Identifier, + expression: ts.Expression, + context: TransformationContext +): lua.Expression => { + // Coalesce skipped statements + if (condition) { + return lua.createBinaryExpression( + condition, + lua.createBinaryExpression( + switchVariable, + context.transformExpression(expression), + lua.SyntaxKind.EqualityOperator + ), + lua.SyntaxKind.OrOperator + ); } + // Next condition + return lua.createBinaryExpression( + switchVariable, + context.transformExpression(expression), + lua.SyntaxKind.EqualityOperator + ); +}; + +export const transformSwitchStatement: FunctionVisitor = (statement, context) => { const scope = pushScope(context, ScopeType.Switch); - // Give the switch a unique name to prevent nested switches from acting up. + // Give the switch and condition accumulator a unique name to prevent nested switches from acting up. const switchName = `____switch${scope.id}`; + const conditionName = `____cond${scope.id}`; const switchVariable = lua.createIdentifier(switchName); + const conditionVariable = lua.createIdentifier(conditionName); + // If the switch only has a default clause, wrap it in a single do. + // Otherwise, we need to generate a set of if statements to emulate the switch. let statements: lua.Statement[] = []; - - // Starting from the back, concatenating ifs into one big if/elseif statement - const concatenatedIf = statement.caseBlock.clauses.reduceRight((previousCondition, clause, index) => { - if (ts.isDefaultClause(clause)) { - // Skip default clause here (needs to be included to ensure index lines up with index later) - return previousCondition; + const clauses = statement.caseBlock.clauses; + if (clauses.length === 1 && ts.isDefaultClause(clauses[0])) { + const defaultClause = clauses[0].statements; + if (defaultClause.length) { + statements.push(lua.createDoStatement(context.transformStatements(defaultClause))); } + } else { + // Build up the condition for each if statement + let isInitialCondition = true; + let condition: lua.Expression | undefined = undefined; + for (let i = 0; i < clauses.length; i++) { + const clause = clauses[i]; + const previousClause: ts.CaseOrDefaultClause | undefined = clauses[i - 1]; - // If the clause condition holds, go to the correct label - const condition = lua.createBinaryExpression( - switchVariable, - context.transformExpression(clause.expression), - lua.SyntaxKind.EqualityOperator - ); + // Skip redundant default clauses, will be handled in final default case + if (i === 0 && ts.isDefaultClause(clause)) continue; + if (ts.isDefaultClause(clause) && previousClause && containsBreakOrReturn(previousClause.statements)) { + continue; + } - const goto = lua.createGotoStatement(`${switchName}_case_${index}`); - return lua.createIfStatement(condition, lua.createBlock([goto]), previousCondition); - }, undefined as lua.IfStatement | undefined); + // Compute the condition for the if statement + if (!ts.isDefaultClause(clause)) { + condition = coalesceCondition(condition, switchVariable, clause.expression, context); - if (concatenatedIf) { - statements.push(concatenatedIf); - } + // Skip empty clauses unless final clause (i.e side-effects) + if (i !== clauses.length - 1 && clause.statements.length === 0) continue; - const hasDefaultCase = statement.caseBlock.clauses.some(ts.isDefaultClause); - statements.push(lua.createGotoStatement(`${switchName}_${hasDefaultCase ? "case_default" : "end"}`)); + // Declare or assign condition variable + statements.push( + isInitialCondition + ? lua.createVariableDeclarationStatement(conditionVariable, condition) + : lua.createAssignmentStatement( + conditionVariable, + lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator) + ) + ); + isInitialCondition = false; + } else { + // If the default is proceeded by empty clauses and will be emitted we may need to initialize the condition + if (isInitialCondition) { + statements.push( + lua.createVariableDeclarationStatement( + conditionVariable, + condition ?? lua.createBooleanLiteral(false) + ) + ); - for (const [index, clause] of statement.caseBlock.clauses.entries()) { - const labelName = `${switchName}_case_${ts.isCaseClause(clause) ? index : "default"}`; - statements.push(lua.createLabelStatement(labelName)); - statements.push(lua.createDoStatement(context.transformStatements(clause.statements))); - } + // Clear condition ot ensure it is not evaluated twice + condition = undefined; + isInitialCondition = false; + } + + // Allow default to fallthrough to final default clause + if (i === clauses.length - 1) { + // Evaluate the final condition that we may be skipping + if (condition) { + statements.push( + lua.createAssignmentStatement( + conditionVariable, + lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator) + ) + ); + } + continue; + } + } - statements.push(lua.createLabelStatement(`${switchName}_end`)); + // Transform the clause and append the final break statement if necessary + const clauseStatements = context.transformStatements(clause.statements); + if (i === clauses.length - 1 && !containsBreakOrReturn(clause.statements)) { + clauseStatements.push(lua.createBreakStatement()); + } + + // Push if statement for case + statements.push(lua.createIfStatement(conditionVariable, lua.createBlock(clauseStatements))); + + // Clear condition for next clause + condition = undefined; + } + + // If no conditions above match, we need to create the final default case code-path, + // as we only handle fallthrough into defaults in the previous if statement chain + const start = clauses.findIndex(c => ts.isDefaultClause(c)); + if (start >= 0) { + // Find the last clause that we can fallthrough to + const end = clauses.findIndex( + (clause, index) => index >= start && containsBreakOrReturn(clause.statements) + ); + + // Combine the default and all fallthrough statements + const defaultStatements: lua.Statement[] = []; + clauses + .slice(start, end >= 0 ? end + 1 : undefined) + .forEach(c => defaultStatements.push(...context.transformStatements(c.statements))); + + // Add the default clause if it has any statements + // The switch will always break on the final clause and skip execution if valid to do so + if (defaultStatements.length) { + statements.push(lua.createDoStatement(defaultStatements)); + } + } + } + // Hoist the variable, function, and import statements to the top of the switch statements = performHoisting(context, statements); popScope(context); + // Add the switch expression after hoisting const expression = context.transformExpression(statement.expression); statements.unshift(lua.createVariableDeclarationStatement(switchVariable, expression)); - return statements; + // Wrap the statements in a repeat until true statement to facilitate dynamic break/returns + return lua.createRepeatStatement(lua.createBlock(statements), lua.createBooleanLiteral(true)); }; diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index 19a763566..0fa333d93 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -1,53 +1,80 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`switch not allowed in 5.1: code 1`] = ` -"local ____exports = {} +exports[`switch empty fallthrough to default (0) 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - local ____switch3 = \\"abc\\" - goto ____switch3_end - ::____switch3_end:: + local out = {} + repeat + local ____switch3 = 0 + local ____cond3 = ____switch3 == 1 + do + __TS__ArrayPush(out, \\"default\\") + end + until true + return out end return ____exports" `; -exports[`switch not allowed in 5.1: diagnostics 1`] = `"main.ts(2,9): error TSTL: Switch statements is/are not supported for target Lua 5.1."`; - -exports[`switch uses elseif 1`] = ` -"local ____exports = {} +exports[`switch empty fallthrough to default (1) 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} function ____exports.__main(self) - local result = -1 - local ____switch3 = 2 - if ____switch3 == 0 then - goto ____switch3_case_0 - elseif ____switch3 == 1 then - goto ____switch3_case_1 - elseif ____switch3 == 2 then - goto ____switch3_case_2 - end - goto ____switch3_end - ::____switch3_case_0:: - do + local out = {} + repeat + local ____switch3 = 1 + local ____cond3 = ____switch3 == 1 do - result = 200 - goto ____switch3_end + __TS__ArrayPush(out, \\"default\\") end - end - ::____switch3_case_1:: - do - do - result = 100 - goto ____switch3_end + until true + return out +end +return ____exports" +`; + +exports[`switch produces optimal output 1`] = ` +"require(\\"lualib_bundle\\"); +local ____exports = {} +function ____exports.__main(self) + local x = 0 + local out = {} + repeat + local ____switch3 = 0 + local ____cond3 = ((____switch3 == 0) or (____switch3 == 1)) or (____switch3 == 2) + if ____cond3 then + __TS__ArrayPush(out, \\"0,1,2\\") + break + end + ____cond3 = ____cond3 or (____switch3 == 3) + if ____cond3 then + do + __TS__ArrayPush(out, \\"3\\") + break + end + end + ____cond3 = ____cond3 or (____switch3 == 4) + if ____cond3 then + break end - end - ::____switch3_case_2:: - do do - result = 1 - goto ____switch3_end + x = x + 1 + __TS__ArrayPush( + out, + \\"default = \\" .. tostring(x) + ) + do + __TS__ArrayPush(out, \\"3\\") + break + end end - end - ::____switch3_end:: - return result + until true + __TS__ArrayPush( + out, + tostring(x) + ) + return out end return ____exports" `; diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts index c264850c2..6ed965595 100644 --- a/test/unit/switch.spec.ts +++ b/test/unit/switch.spec.ts @@ -1,5 +1,3 @@ -import * as tstl from "../../src"; -import { unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test.each([0, 1, 2, 3])("switch (%p)", inp => { @@ -209,7 +207,7 @@ test.each([0, 1, 2, 3])("switchWithBrackets (%p)", inp => { `.expectToMatchJsResult(); }); -test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { +test.each([0, 1, 2, 3, 4])("switchWithBracketsBreakInConditional (%p)", inp => { util.testFunction` let result: number = -1; @@ -225,6 +223,11 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInConditional (%p)", inp => { } case 2: { result = 2; + + if (result != 2) break; + } + case 3: { + result = 3; break; } } @@ -261,10 +264,9 @@ test.each([0, 1, 2, 3])("switchWithBracketsBreakInInternalLoop (%p)", inp => { `.expectToMatchJsResult(); }); -test("switch uses elseif", () => { +test("switch executes only one clause", () => { util.testFunction` let result: number = -1; - switch (2 as number) { case 0: { result = 200; @@ -281,19 +283,8 @@ test("switch uses elseif", () => { break; } } - return result; - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); -}); - -test("switch not allowed in 5.1", () => { - util.testFunction` - switch ("abc") {} - ` - .setOptions({ luaTarget: tstl.LuaTarget.Lua51 }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/967 @@ -321,6 +312,17 @@ test("switch default case not last - second", () => { `.expectToMatchJsResult(); }); +test("switch default case only", () => { + util.testFunction` + let out = 0; + switch (4 as number) { + default: + out = 1 + } + return out; + `.expectToMatchJsResult(); +}); + test("switch fallthrough enters default", () => { util.testFunction` const out = []; @@ -359,3 +361,164 @@ test("switch fallthrough stops after default", () => { return out; `.expectToMatchJsResult(); }); + +test.each([0, 1])("switch empty fallthrough to default (%p)", inp => { + util.testFunction` + const out = []; + switch (${inp} as number) { + case 1: + default: + out.push("default"); + + } + return out; + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); +}); + +test("switch does not pollute parent scope", () => { + util.testFunction` + let x: number = 0; + let y = 1; + switch (x) { + case 0: + let y = 2; + } + return y; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3, 4])("switch handles side-effects (%p)", inp => { + util.testFunction` + const out = []; + + let y = 0; + function foo() { + return y++; + } + + let x = ${inp} as number; + switch (x) { + case foo(): + out.push(1); + case foo(): + out.push(2); + case foo(): + out.push(3); + default: + out.push("default"); + case foo(): + } + + out.push(y); + return out; + `.expectToMatchJsResult(); +}); + +test.each([1, 2])("switch handles side-effects with empty fallthrough (%p)", inp => { + util.testFunction` + const out = []; + + let y = 0; + function foo() { + return y++; + } + + let x = 0 as number; + switch (x) { + // empty fallthrough 1 or many times + ${new Array(inp).fill("case foo():").join("\n")} + default: + out.push("default"); + + } + + out.push(y); + return out; + `.expectToMatchJsResult(); +}); + +test.each([1, 2])("switch handles side-effects with empty fallthrough (preceding clause) (%p)", inp => { + util.testFunction` + const out = []; + + let y = 0; + function foo() { + return y++; + } + + let x = 0 as number; + switch (x) { + case 1: + out.push(1); + // empty fallthrough 1 or many times + ${new Array(inp).fill("case foo():").join("\n")} + default: + out.push("default"); + + } + + out.push(y); + return out; + `.expectToMatchJsResult(); +}); + +test.each([0, 1, 2, 3, 4])("switch handles async side-effects (%p)", inp => { + util.testFunction` + (async () => { + const out = []; + + let y = 0; + async function foo() { + return new Promise((resolve) => y++ && resolve(0)); + } + + let x = ${inp} as number; + switch (x) { + case await foo(): + out.push(1); + case await foo(): + out.push(2); + case await foo(): + out.push(3); + default: + out.push("default"); + case await foo(): + } + + out.push(y); + return out; + })(); + `.expectToMatchJsResult(); +}); + +const optimalOutput = (c: number) => util.testFunction` + let x: number = 0; + const out = []; + switch (${c} as number) { + case 0: + case 1: + case 2: + out.push("0,1,2"); + break; + default: + x++; + out.push("default = " + x); + case 3: { + out.push("3"); + break; + } + case 4: + } + out.push(x.toString()); + return out; +`; + +test("switch produces optimal output", () => { + optimalOutput(0).expectLuaToMatchSnapshot(); +}); + +test.each([0, 1, 2, 3, 4, 5])("switch produces valid optimal output (%p)", inp => { + optimalOutput(inp).expectToMatchJsResult(); +}); From c5967f34564274171541eb8abf6b57c60320c28c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 4 Sep 2021 20:54:29 +0200 Subject: [PATCH 397/764] 1.0.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 816c311bd..6f493d557 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index d80bb1a36..eb4002ba1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.0.0", + "version": "1.0.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From dc78114867a05d4641d4e46b4ac7a04e4cb5ee62 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Wed, 8 Sep 2021 01:12:18 -0700 Subject: [PATCH 398/764] Use `ts.transformJsx` instead for jsx. (#1123) * Use `ts.transformJsx` instead for jsx. Reverts "JSX support (#1052)". This reverts commit 987899c8acdaf14668d234a8470c9f29a33f7459. * Add comment explaining overriding compiler options --- src/transformation/utils/annotations.ts | 2 - src/transformation/visitors/index.ts | 2 - src/transformation/visitors/jsx/jsx.ts | 264 ------------------ src/transformation/visitors/jsx/xhtml.ts | 256 ----------------- .../visitors/language-extensions/multi.ts | 2 +- src/transformation/visitors/literal.ts | 142 ++++------ src/transpilation/transformers.ts | 67 +++-- src/typescript-internal.d.ts | 2 + test/unit/jsx.spec.ts | 12 +- 9 files changed, 109 insertions(+), 640 deletions(-) delete mode 100644 src/transformation/visitors/jsx/jsx.ts delete mode 100644 src/transformation/visitors/jsx/xhtml.ts diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 7f7b19652..2b2309941 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -16,8 +16,6 @@ export enum AnnotationKind { NoSelfInFile = "noSelfInFile", Vararg = "vararg", ForRange = "forRange", - Jsx = "jsx", - JsxFrag = "jsxFrag", } export interface Annotation { diff --git a/src/transformation/visitors/index.ts b/src/transformation/visitors/index.ts index 28f965932..f6bb8b697 100644 --- a/src/transformation/visitors/index.ts +++ b/src/transformation/visitors/index.ts @@ -40,7 +40,6 @@ import { transformTypeOfExpression } from "./typeof"; import { typescriptVisitors } from "./typescript"; import { transformPostfixUnaryExpression, transformPrefixUnaryExpression } from "./unary-expression"; import { transformVariableStatement } from "./variable-declaration"; -import { jsxVisitors } from "./jsx/jsx"; import { transformAwaitExpression } from "./async-await"; const transformEmptyStatement: FunctionVisitor = () => undefined; @@ -50,7 +49,6 @@ const transformParenthesizedExpression: FunctionVisitor= charCodes.a && ch <= charCodes.z) || name.includes("-") || name.includes(":"); -} - -function transformTagName(name: ts.JsxTagNameExpression, context: TransformationContext): lua.Expression { - if (ts.isIdentifier(name) && isIntrinsicJsxName(name.escapedText)) { - return lua.createStringLiteral(ts.idText(name), name); - } else { - return context.transformExpression(name); - } -} - -function transformJsxChildren( - children: ts.NodeArray | undefined, - context: TransformationContext -): lua.Expression[] | undefined { - if (!children) return undefined; - - return children - .map(child => { - if (ts.isJsxText(child)) { - return processJsxText(child); - } - if (ts.isJsxExpression(child)) { - return child.expression; - } - return child; - }) - .filter(child => child !== undefined) - .map(child => context.transformExpression(child!)); -} - -function createJsxFactoryCall( - tagName: lua.Expression, - props: lua.Expression | undefined, - tsChildren: ts.NodeArray | undefined, - tsOriginal: ts.Node, - context: TransformationContext -): lua.Expression { - const transformedChildren = transformJsxChildren(tsChildren, context); - const jsxFactory = getJsxFactory(tsOriginal, context); - - const args = [tagName]; - if (props) { - args.push(props); - } - if (transformedChildren && transformedChildren.length > 0) { - if (!props) { - args.push(lua.createNilLiteral()); - } - args.push(...transformedChildren); - } - return lua.createCallExpression(jsxFactory, args, tsOriginal); -} - -function transformJsxOpeningLikeElement( - node: ts.JsxOpeningLikeElement, - children: ts.NodeArray | undefined, - context: TransformationContext -): lua.Expression { - const tagName = transformTagName(node.tagName, context); - const props = - node.attributes.properties.length !== 0 ? transformJsxAttributes(node.attributes, context) : undefined; - - return createJsxFactoryCall(tagName, props, children, node, context); -} - -const transformJsxElement: FunctionVisitor = (node, context) => - transformJsxOpeningLikeElement(node.openingElement, node.children, context); -const transformSelfClosingJsxElement: FunctionVisitor = (node, context) => - transformJsxOpeningLikeElement(node, undefined, context); -const transformJsxFragment: FunctionVisitor = (node, context) => { - const tagName = getJsxFragmentName(node, context); - return createJsxFactoryCall(tagName, undefined, node.children, node, context); -}; - -export const jsxVisitors: Visitors = { - [ts.SyntaxKind.JsxElement]: transformJsxElement, - [ts.SyntaxKind.JsxSelfClosingElement]: transformSelfClosingJsxElement, - [ts.SyntaxKind.JsxFragment]: transformJsxFragment, -}; diff --git a/src/transformation/visitors/jsx/xhtml.ts b/src/transformation/visitors/jsx/xhtml.ts deleted file mode 100644 index 814191df0..000000000 --- a/src/transformation/visitors/jsx/xhtml.ts +++ /dev/null @@ -1,256 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -export const XHTMLEntities: { [name: string]: string } = { - quot: "\u0022", - amp: "&", - apos: "\u0027", - lt: "<", - gt: ">", - nbsp: "\u00A0", - iexcl: "\u00A1", - cent: "\u00A2", - pound: "\u00A3", - curren: "\u00A4", - yen: "\u00A5", - brvbar: "\u00A6", - sect: "\u00A7", - uml: "\u00A8", - copy: "\u00A9", - ordf: "\u00AA", - laquo: "\u00AB", - not: "\u00AC", - shy: "\u00AD", - reg: "\u00AE", - macr: "\u00AF", - deg: "\u00B0", - plusmn: "\u00B1", - sup2: "\u00B2", - sup3: "\u00B3", - acute: "\u00B4", - micro: "\u00B5", - para: "\u00B6", - middot: "\u00B7", - cedil: "\u00B8", - sup1: "\u00B9", - ordm: "\u00BA", - raquo: "\u00BB", - frac14: "\u00BC", - frac12: "\u00BD", - frac34: "\u00BE", - iquest: "\u00BF", - Agrave: "\u00C0", - Aacute: "\u00C1", - Acirc: "\u00C2", - Atilde: "\u00C3", - Auml: "\u00C4", - Aring: "\u00C5", - AElig: "\u00C6", - Ccedil: "\u00C7", - Egrave: "\u00C8", - Eacute: "\u00C9", - Ecirc: "\u00CA", - Euml: "\u00CB", - Igrave: "\u00CC", - Iacute: "\u00CD", - Icirc: "\u00CE", - Iuml: "\u00CF", - ETH: "\u00D0", - Ntilde: "\u00D1", - Ograve: "\u00D2", - Oacute: "\u00D3", - Ocirc: "\u00D4", - Otilde: "\u00D5", - Ouml: "\u00D6", - times: "\u00D7", - Oslash: "\u00D8", - Ugrave: "\u00D9", - Uacute: "\u00DA", - Ucirc: "\u00DB", - Uuml: "\u00DC", - Yacute: "\u00DD", - THORN: "\u00DE", - szlig: "\u00DF", - agrave: "\u00E0", - aacute: "\u00E1", - acirc: "\u00E2", - atilde: "\u00E3", - auml: "\u00E4", - aring: "\u00E5", - aelig: "\u00E6", - ccedil: "\u00E7", - egrave: "\u00E8", - eacute: "\u00E9", - ecirc: "\u00EA", - euml: "\u00EB", - igrave: "\u00EC", - iacute: "\u00ED", - icirc: "\u00EE", - iuml: "\u00EF", - eth: "\u00F0", - ntilde: "\u00F1", - ograve: "\u00F2", - oacute: "\u00F3", - ocirc: "\u00F4", - otilde: "\u00F5", - ouml: "\u00F6", - divide: "\u00F7", - oslash: "\u00F8", - ugrave: "\u00F9", - uacute: "\u00FA", - ucirc: "\u00FB", - uuml: "\u00FC", - yacute: "\u00FD", - thorn: "\u00FE", - yuml: "\u00FF", - OElig: "\u0152", - oelig: "\u0153", - Scaron: "\u0160", - scaron: "\u0161", - Yuml: "\u0178", - fnof: "\u0192", - circ: "\u02C6", - tilde: "\u02DC", - Alpha: "\u0391", - Beta: "\u0392", - Gamma: "\u0393", - Delta: "\u0394", - Epsilon: "\u0395", - Zeta: "\u0396", - Eta: "\u0397", - Theta: "\u0398", - Iota: "\u0399", - Kappa: "\u039A", - Lambda: "\u039B", - Mu: "\u039C", - Nu: "\u039D", - Xi: "\u039E", - Omicron: "\u039F", - Pi: "\u03A0", - Rho: "\u03A1", - Sigma: "\u03A3", - Tau: "\u03A4", - Upsilon: "\u03A5", - Phi: "\u03A6", - Chi: "\u03A7", - Psi: "\u03A8", - Omega: "\u03A9", - alpha: "\u03B1", - beta: "\u03B2", - gamma: "\u03B3", - delta: "\u03B4", - epsilon: "\u03B5", - zeta: "\u03B6", - eta: "\u03B7", - theta: "\u03B8", - iota: "\u03B9", - kappa: "\u03BA", - lambda: "\u03BB", - mu: "\u03BC", - nu: "\u03BD", - xi: "\u03BE", - omicron: "\u03BF", - pi: "\u03C0", - rho: "\u03C1", - sigmaf: "\u03C2", - sigma: "\u03C3", - tau: "\u03C4", - upsilon: "\u03C5", - phi: "\u03C6", - chi: "\u03C7", - psi: "\u03C8", - omega: "\u03C9", - thetasym: "\u03D1", - upsih: "\u03D2", - piv: "\u03D6", - ensp: "\u2002", - emsp: "\u2003", - thinsp: "\u2009", - zwnj: "\u200C", - zwj: "\u200D", - lrm: "\u200E", - rlm: "\u200F", - ndash: "\u2013", - mdash: "\u2014", - lsquo: "\u2018", - rsquo: "\u2019", - sbquo: "\u201A", - ldquo: "\u201C", - rdquo: "\u201D", - bdquo: "\u201E", - dagger: "\u2020", - Dagger: "\u2021", - bull: "\u2022", - hellip: "\u2026", - permil: "\u2030", - prime: "\u2032", - Prime: "\u2033", - lsaquo: "\u2039", - rsaquo: "\u203A", - oline: "\u203E", - frasl: "\u2044", - euro: "\u20AC", - image: "\u2111", - weierp: "\u2118", - real: "\u211C", - trade: "\u2122", - alefsym: "\u2135", - larr: "\u2190", - uarr: "\u2191", - rarr: "\u2192", - darr: "\u2193", - harr: "\u2194", - crarr: "\u21B5", - lArr: "\u21D0", - uArr: "\u21D1", - rArr: "\u21D2", - dArr: "\u21D3", - hArr: "\u21D4", - forall: "\u2200", - part: "\u2202", - exist: "\u2203", - empty: "\u2205", - nabla: "\u2207", - isin: "\u2208", - notin: "\u2209", - ni: "\u220B", - prod: "\u220F", - sum: "\u2211", - minus: "\u2212", - lowast: "\u2217", - radic: "\u221A", - prop: "\u221D", - infin: "\u221E", - ang: "\u2220", - and: "\u2227", - or: "\u2228", - cap: "\u2229", - cup: "\u222A", - int: "\u222B", - there4: "\u2234", - sim: "\u223C", - cong: "\u2245", - asymp: "\u2248", - ne: "\u2260", - equiv: "\u2261", - le: "\u2264", - ge: "\u2265", - sub: "\u2282", - sup: "\u2283", - nsub: "\u2284", - sube: "\u2286", - supe: "\u2287", - oplus: "\u2295", - otimes: "\u2297", - perp: "\u22A5", - sdot: "\u22C5", - lceil: "\u2308", - rceil: "\u2309", - lfloor: "\u230A", - rfloor: "\u230B", - lang: "\u2329", - rang: "\u232A", - loz: "\u25CA", - spades: "\u2660", - clubs: "\u2663", - hearts: "\u2665", - diams: "\u2666", -}; diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index a1c9c4030..caaae7470 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -94,7 +94,7 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n export function findMultiAssignmentViolations( context: TransformationContext, - node: ts.ObjectLiteralExpressionBase + node: ts.ObjectLiteralExpression ): ts.Node[] { const result: ts.Node[] = []; diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 75b4a3224..c0e9a6256 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -11,7 +11,6 @@ import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { flattenSpreadExpressions } from "./call"; import { findMultiAssignmentViolations } from "./language-extensions/multi"; -import { formatJSXStringValueLiteral } from "./jsx/jsx"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -63,99 +62,78 @@ const transformNumericLiteralExpression: FunctionVisitor = ex return lua.createNumericLiteral(Number(expression.text), expression); }; -const transformObjectLiteralExpressionOrJsxAttributes: FunctionVisitor = - (expression, context) => { - const violations = findMultiAssignmentViolations(context, expression); - if (violations.length > 0) { - context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); - return lua.createNilLiteral(expression); - } +const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { + const violations = findMultiAssignmentViolations(context, expression); + if (violations.length > 0) { + context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); + return lua.createNilLiteral(expression); + } - let properties: lua.TableFieldExpression[] = []; - const tableExpressions: lua.Expression[] = []; - - for (const element of expression.properties) { - const name = element.name ? transformPropertyName(context, element.name) : undefined; - - if (ts.isPropertyAssignment(element)) { - const expression = context.transformExpression(element.initializer); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isJsxAttribute(element)) { - const initializer = element.initializer; - let expression: lua.Expression; - if (initializer === undefined) { - expression = lua.createBooleanLiteral(true); - } else if (ts.isStringLiteral(initializer)) { - const text = formatJSXStringValueLiteral(initializer.text); - expression = lua.createStringLiteral(text, initializer); - } else if (ts.isJsxExpression(initializer)) { - expression = initializer.expression - ? context.transformExpression(initializer.expression) - : lua.createBooleanLiteral(true); - } else { - assertNever(initializer); - } - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isShorthandPropertyAssignment(element)) { - const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - trackSymbolReference(context, valueSymbol, element.name); - } - - const identifier = createShorthandIdentifier(context, valueSymbol, element.name); - properties.push(lua.createTableFieldExpression(identifier, name, element)); - } else if (ts.isMethodDeclaration(element)) { - const expression = transformFunctionLikeDeclaration(element, context); - properties.push(lua.createTableFieldExpression(expression, name, element)); - } else if (ts.isSpreadAssignment(element) || ts.isJsxSpreadAttribute(element)) { - // Create a table for preceding properties to preserve property order - // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); - properties = []; - } - - const type = context.checker.getTypeAtLocation(element.expression); - let tableExpression: lua.Expression; - if (isArrayType(context, type)) { - tableExpression = transformLuaLibFunction( - context, - LuaLibFeature.ArrayToObject, - element.expression, - context.transformExpression(element.expression) - ); - } else { - tableExpression = context.transformExpression(element.expression); - } + let properties: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; - tableExpressions.push(tableExpression); - } else if (ts.isAccessor(element)) { - context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); - } else { - assertNever(element); + for (const element of expression.properties) { + const name = element.name ? transformPropertyName(context, element.name) : undefined; + + if (ts.isPropertyAssignment(element)) { + const expression = context.transformExpression(element.initializer); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isShorthandPropertyAssignment(element)) { + const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); + if (valueSymbol) { + trackSymbolReference(context, valueSymbol, element.name); } - } - if (tableExpressions.length === 0) { - return lua.createTableExpression(properties, expression); - } else { + const identifier = createShorthandIdentifier(context, valueSymbol, element.name); + properties.push(lua.createTableFieldExpression(identifier, name, element)); + } else if (ts.isMethodDeclaration(element)) { + const expression = transformFunctionLikeDeclaration(element, context); + properties.push(lua.createTableFieldExpression(expression, name, element)); + } else if (ts.isSpreadAssignment(element)) { + // Create a table for preceding properties to preserve property order + // { x: 0, ...{ y: 2 }, y: 1, z: 2 } --> __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) if (properties.length > 0) { const tableExpression = lua.createTableExpression(properties, expression); tableExpressions.push(tableExpression); + properties = []; } - if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { - tableExpressions.unshift(lua.createTableExpression(undefined, expression)); + const type = context.checker.getTypeAtLocation(element.expression); + let tableExpression: lua.Expression; + if (isArrayType(context, type)) { + tableExpression = transformLuaLibFunction( + context, + LuaLibFeature.ArrayToObject, + element.expression, + context.transformExpression(element.expression) + ); + } else { + tableExpression = context.transformExpression(element.expression); } - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); + tableExpressions.push(tableExpression); + } else if (ts.isAccessor(element)) { + context.diagnostics.push(unsupportedAccessorInObjectLiteral(element)); + } else { + assertNever(element); + } + } + + if (tableExpressions.length === 0) { + return lua.createTableExpression(properties, expression); + } else { + if (properties.length > 0) { + const tableExpression = lua.createTableExpression(properties, expression); + tableExpressions.push(tableExpression); } - }; -const transformObjectLiteralExpression: FunctionVisitor = - transformObjectLiteralExpressionOrJsxAttributes; -export const transformJsxAttributes: FunctionVisitor = - transformObjectLiteralExpressionOrJsxAttributes; + + if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { + tableExpressions.unshift(lua.createTableExpression(undefined, expression)); + } + + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); + } +}; const transformArrayLiteralExpression: FunctionVisitor = (expression, context) => { const filteredElements = expression.elements.map(e => diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index 7b5aacddd..386d7f475 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -86,40 +86,53 @@ function loadTransformersFromOptions(program: ts.Program, diagnostics: ts.Diagno }; const options = program.getCompilerOptions() as CompilerOptions; - if (!options.plugins) return customTransformers; - - for (const [index, transformerImport] of options.plugins.entries()) { - if (!("transform" in transformerImport)) continue; - const optionName = `compilerOptions.plugins[${index}]`; + if (options.plugins) { + for (const [index, transformerImport] of options.plugins.entries()) { + if (!("transform" in transformerImport)) continue; + const optionName = `compilerOptions.plugins[${index}]`; + + const { error: resolveError, result: factory } = resolvePlugin( + "transformer", + `${optionName}.transform`, + getConfigDirectory(options), + transformerImport.transform, + transformerImport.import + ); - const { error: resolveError, result: factory } = resolvePlugin( - "transformer", - `${optionName}.transform`, - getConfigDirectory(options), - transformerImport.transform, - transformerImport.import - ); + if (resolveError) diagnostics.push(resolveError); + if (factory === undefined) continue; - if (resolveError) diagnostics.push(resolveError); - if (factory === undefined) continue; + const { error: loadError, transformer } = loadTransformer(optionName, program, factory, transformerImport); + if (loadError) diagnostics.push(loadError); + if (transformer === undefined) continue; - const { error: loadError, transformer } = loadTransformer(optionName, program, factory, transformerImport); - if (loadError) diagnostics.push(loadError); - if (transformer === undefined) continue; + if (transformer.before) { + customTransformers.before.push(transformer.before); + } - if (transformer.before) { - customTransformers.before.push(transformer.before); - } + if (transformer.after) { + customTransformers.after.push(transformer.after); + } - if (transformer.after) { - customTransformers.after.push(transformer.after); - } - - if (transformer.afterDeclarations) { - customTransformers.afterDeclarations.push(transformer.afterDeclarations); + if (transformer.afterDeclarations) { + customTransformers.afterDeclarations.push(transformer.afterDeclarations); + } } } - + if (options.jsx === ts.JsxEmit.React) { + customTransformers.before.push(context => { + // if target < ES2017, typescript generates some unnecessary additional transformations in transformJSX. + // We can't control the target compiler option, so we override here. + const patchedContext: ts.TransformationContext = { + ...context, + getCompilerOptions: () => ({ + ...context.getCompilerOptions(), + target: ts.ScriptTarget.ESNext, + }), + }; + return ts.transformJsx(patchedContext); + }); + } return customTransformers; } diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 8fd8fd1ec..3fde219f5 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -28,4 +28,6 @@ declare module "typescript" { getElementTypeOfArrayType(type: Type): Type | undefined; getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined; } + + function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; } diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts index 5734b33ee..37cdc14c5 100644 --- a/test/unit/jsx.spec.ts +++ b/test/unit/jsx.spec.ts @@ -12,7 +12,6 @@ const reactLib = ` const isLua = typeof Component === "object" export function createElement( - this: void, type: any, props?: any, ...children: any[] @@ -21,11 +20,13 @@ const reactLib = ` if (isLua) { typeStr = typeof type === "function" ? "<< function >>" : - typeof type === "object" ? \`<< class \${type.name} >>\` : - type + typeof type === "object" ? \`<< class \${type.name} >>\` : + type } else { - typeStr = typeof type === "function" ? (type.isClass ? \`<< class \${type.name} >>\` : "<< function >>") - : type + typeStr = typeof type === "function" ? (type.isClass + ? \`<< class \${type.name} >>\` + : "<< function >>") + : type } return { @@ -259,7 +260,6 @@ describe("jsx", () => { // language=TypeScript const customJsxLib = `export namespace MyLib { export function myCreate( - this: void, type: any, props: any, ...children: any[] From 09c8f0fd2562aada87b1390beae3a6b213d9ae3a Mon Sep 17 00:00:00 2001 From: Toliak Date: Wed, 8 Sep 2021 21:33:02 +0300 Subject: [PATCH 399/764] Fixes bundle mode with enabled sourceMapTraceback (#1110) * #1109 In Progress - Join code chunk, due to its correctness and existness * Removed unused `sourceMapNode` * Provided SourceMapTraceBack for bundled files (#1109) * Moved helpful function `lineAndColumnOf` into utils.ts file * Covered bundling with source map traceback (#1109) * Removed unnecessary comments --- src/LuaPrinter.ts | 12 +- src/lualib/SourceMapTraceBack.ts | 31 ++++- src/transpilation/bundle.ts | 58 +++++++- test/transpile/bundle.spec.ts | 131 ++++++++++++++++-- .../bundle/bundle-source-maps/index.ts | 8 ++ .../bundle/bundle-source-maps/largeFile.ts | 53 +++++++ .../bundle/bundle-source-maps/tsconfig.json | 17 +++ .../bundle/{ => bundle-two-files}/index.ts | 0 .../{ => bundle-two-files}/otherFile.ts | 0 .../{ => bundle-two-files}/tsconfig.json | 0 test/unit/printer/sourcemaps.spec.ts | 27 +--- test/unit/printer/utils.ts | 25 ++++ 12 files changed, 315 insertions(+), 47 deletions(-) create mode 100644 test/transpile/bundle/bundle-source-maps/index.ts create mode 100644 test/transpile/bundle/bundle-source-maps/largeFile.ts create mode 100644 test/transpile/bundle/bundle-source-maps/tsconfig.json rename test/transpile/bundle/{ => bundle-two-files}/index.ts (100%) rename test/transpile/bundle/{ => bundle-two-files}/otherFile.ts (100%) rename test/transpile/bundle/{ => bundle-two-files}/tsconfig.json (100%) create mode 100644 test/unit/printer/utils.ts diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 390b62977..65c33b88a 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,6 +1,6 @@ import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; +import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; @@ -123,6 +123,8 @@ export class LuaPrinter { private sourceFile: string; private options: CompilerOptions; + public static readonly sourceMapTracebackPlaceholder = "{#SourceMapTraceback}"; + constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { this.options = program.getCompilerOptions(); this.sourceFile = fileName; @@ -149,7 +151,7 @@ export class LuaPrinter { if (this.options.sourceMapTraceback) { const stackTraceOverride = this.printStackTraceOverride(rootSourceNode); - code = code.replace("{#SourceMapTraceback}", stackTraceOverride); + code = code.replace(LuaPrinter.sourceMapTracebackPlaceholder, stackTraceOverride); } return { code, sourceMap: sourceMap.toString(), sourceMapNode: rootSourceNode }; @@ -203,8 +205,10 @@ export class LuaPrinter { header += loadLuaLibFeatures(file.luaLibFeatures, this.emitHost); } - if (this.options.sourceMapTraceback) { - header += "{#SourceMapTraceback}\n"; + if (this.options.sourceMapTraceback && !isBundleEnabled(this.options)) { + // In bundle mode the traceback is being generated for the entire file in getBundleResult + // Otherwise, traceback is being generated locally + header += `${LuaPrinter.sourceMapTracebackPlaceholder}\n`; } return this.concatNodes(header, ...this.printStatementArray(file.statements)); diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index b46ba4786..542a8c483 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,7 +1,13 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. + +interface SourceMap { + [line: number]: number | { line: number; file: string }; +} + declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); -function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [line: number]: number }): void { + +function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; globalThis.__TS__sourcemap[fileName] = sourceMap; @@ -19,13 +25,26 @@ function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: { [li return trace; } - const [result] = string.gsub(trace, "(%S+).lua:(%d+)", (file, line) => { - const fileSourceMap = globalThis.__TS__sourcemap[file + ".lua"]; + const replacer = (file: string, srcFile: string, line: string) => { + const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; if (fileSourceMap && fileSourceMap[line]) { - return `${file}.ts:${fileSourceMap[line]}`; + const data = fileSourceMap[line]; + if (typeof data === "number") { + return `${srcFile}:${data}`; + } + + return `${data.file}:${data.line}`; } - return `${file}.lua:${line}`; - }); + + return `${file}:${line}`; + }; + + let [result] = string.gsub(trace, "(%S+)%.lua:(%d+)", (file, line) => + replacer(`${file}.lua`, `${file}.ts`, line) + ); + [result] = string.gsub(result, '(%[string "[^"]+"%]):(%d+)', (file, line) => + replacer(file, "unknown", line) + ); return result; }) as typeof debug.traceback; diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 02eb73e30..45fe6d409 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -34,6 +34,49 @@ local function require(file, ...) end `; +export const sourceMapTracebackBundlePlaceholder = "{#SourceMapTracebackBundle}"; + +type SourceMapLineData = number | { line: number; file: string }; + +export function printStackTraceBundleOverride(rootNode: SourceNode): string { + const map: Record = {}; + const getLineNumber = (line: number, fallback: number) => { + const data: SourceMapLineData | undefined = map[line]; + if (data === undefined) { + return fallback; + } + if (typeof data === "number") { + return data; + } + return data.line; + }; + const transformLineData = (data: SourceMapLineData) => { + if (typeof data === "number") { + return data; + } + return `{line = ${data.line}, file = "${data.file}"}`; + }; + + let currentLine = 1; + rootNode.walk((chunk, mappedPosition) => { + if (mappedPosition.line !== undefined && mappedPosition.line > 0) { + const line = getLineNumber(currentLine, mappedPosition.line); + + map[currentLine] = { + line, + file: path.basename(mappedPosition.source), + }; + } + + currentLine += chunk.split("\n").length - 1; + }); + + const mapItems = Object.entries(map).map(([line, original]) => `["${line}"] = ${transformLineData(original)}`); + const mapString = "{" + mapItems.join(",") + "}"; + + return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; +} + export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [ts.Diagnostic[], EmitFile] { const diagnostics: ts.Diagnostic[] = []; @@ -58,14 +101,22 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t // return require("") const entryPoint = `return require(${createModulePath(entryModule, program)}, ...)\n`; - const sourceChunks = [requireOverride, moduleTable, entryPoint]; + const footers: string[] = []; + if (options.sourceMapTraceback) { + // Generates SourceMapTraceback for the entire file + footers.push('require("lualib_bundle")\n'); + footers.push(`${sourceMapTracebackBundlePlaceholder}\n`); + } + + const sourceChunks = [requireOverride, moduleTable, ...footers, entryPoint]; if (!options.noHeader) { sourceChunks.unshift(tstlHeader); } const bundleNode = joinSourceChunks(sourceChunks); - const { code, map } = bundleNode.toStringWithSourceMap(); + let { code, map } = bundleNode.toStringWithSourceMap(); + code = code.replace(sourceMapTracebackBundlePlaceholder, printStackTraceBundleOverride(bundleNode)); return [ diagnostics, @@ -79,7 +130,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t } function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode { - const tableEntryHead = `[${modulePath}] = function(...) `; + const tableEntryHead = `[${modulePath}] = function(...) \n`; const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]); @@ -93,6 +144,7 @@ function createModuleTableNode(fileChunks: SourceChunk[]): SourceNode { } type SourceChunk = string | SourceNode; + function joinSourceChunks(chunks: SourceChunk[]): SourceNode { return new SourceNode(null, null, null, chunks); } diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 718e1b112..95ab76a96 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -1,19 +1,132 @@ import * as path from "path"; import * as util from "../util"; +import { TranspileVirtualProjectResult } from "../../src"; +import { lineAndColumnOf } from "../unit/printer/utils"; +import * as fs from "fs"; -const projectDir = path.join(__dirname, "bundle"); -const inputProject = path.join(projectDir, "tsconfig.json"); +describe("bundle two files", () => { + const projectDir = path.join(__dirname, "bundle", "bundle-two-files"); + const inputProject = path.join(projectDir, "tsconfig.json"); -test("should transpile into one file", () => { - const { diagnostics, transpiledFiles } = util.testProject(inputProject).getLuaResult(); + let transpileResult: TranspileVirtualProjectResult = { + transpiledFiles: [], + diagnostics: [], + }; - expect(diagnostics).not.toHaveDiagnostics(); - expect(transpiledFiles).toHaveLength(1); + beforeAll(() => { + transpileResult = util.testProject(inputProject).getLuaResult(); + }); + + test("should transpile into one file (with no errors)", () => { + expect(transpileResult.diagnostics).not.toHaveDiagnostics(); + expect(transpileResult.transpiledFiles).toHaveLength(1); + }); - const { outPath, lua } = transpiledFiles[0]; // Verify the name is as specified in tsconfig - expect(outPath.endsWith(path.join("bundle", "bundle.lua"))).toBe(true); + test("should have name, specified in tsconfig.json", () => { + const { outPath } = transpileResult.transpiledFiles[0]; + expect(outPath.endsWith(path.join(projectDir, "bundle.lua"))).toBe(true); + }); + + // Verify exported module by executing + // Use an empty TS string because we already transpiled the TS project + test("executing should act correctly", () => { + const { lua } = transpileResult.transpiledFiles[0]; + util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); + }); +}); + +describe("bundle with source maps", () => { + const projectDir = path.join(__dirname, "bundle", "bundle-source-maps"); + const inputProject = path.join(projectDir, "tsconfig.json"); + + let transpileResult: TranspileVirtualProjectResult = { + transpiledFiles: [], + diagnostics: [], + }; + + beforeAll(() => { + transpileResult = util.testProject(inputProject).getLuaResult(); + }); + + // See https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1109 + test('the result file should not contain "{#SourceMapTraceback}" macro-string', () => { + const { lua } = transpileResult.transpiledFiles[0]; + expect(lua).not.toBeUndefined(); + expect(lua!).not.toContain("{#SourceMapTraceback}"); + }); + // Verify exported module by executing // Use an empty TS string because we already transpiled the TS project - util.testModule("").setLuaHeader(lua!).expectToEqual({ myNumber: 3 }); + test("executing should act correctly", () => { + const { lua } = transpileResult.transpiledFiles[0]; + const result = util.testModule("").setLuaHeader(lua!).getLuaExecutionResult(); + + expect(result.myNumber).toEqual(3 * 4 * (5 + 6)); + }); + + test("sourceMapTraceback saves correct sourcemap", () => { + const code = { + index: fs.readFileSync(path.join(projectDir, "index.ts"), "utf8"), + largeFile: fs.readFileSync(path.join(projectDir, "largeFile.ts"), "utf8"), + }; + + const { lua } = transpileResult.transpiledFiles[0]; + const builder = util.testModule("").setLuaHeader(lua!); + const result = builder.getLuaExecutionResult(); + const sourceMap = result.sourceMap; + + expect(sourceMap).toEqual(expect.any(Object)); + const sourceMapFiles = Object.keys(sourceMap); + expect(sourceMapFiles).toHaveLength(1); + const mainSourceMap = sourceMap[sourceMapFiles[0]]; + + const transpiledLua = builder.getMainLuaCodeChunk(); + + const assertPatterns: Array<{ + file: keyof typeof code; + luaPattern: string; + typeScriptPattern: string; + }> = [ + { + file: "index", + luaPattern: "____exports.myNumber = getNumber(", + typeScriptPattern: "const myNumber = getNumber(", + }, + { + file: "largeFile", + luaPattern: "local Calculator = __TS__Class()", + typeScriptPattern: "abstract class Calculator", + }, + { + file: "largeFile", + luaPattern: "local CalculatorMul = __TS__Class()", + typeScriptPattern: "class CalculatorMul extends Calculator {", + }, + { + file: "largeFile", + luaPattern: "local function resolveCalculatorClass(", + typeScriptPattern: "function resolveCalculatorClass(", + }, + { + file: "largeFile", + luaPattern: "function ____exports.getNumber(", + typeScriptPattern: "export function getNumber(", + }, + { + file: "largeFile", + luaPattern: 'Error,\n "Unknown operation "', + typeScriptPattern: "throw new Error(", + }, + ]; + + for (const { file: currentFile, luaPattern, typeScriptPattern } of assertPatterns) { + const luaPosition = lineAndColumnOf(transpiledLua, luaPattern); + const mappedLine: { file: string; line: number } = mainSourceMap[luaPosition.line.toString()]; + + const typescriptPosition = lineAndColumnOf(code[currentFile], typeScriptPattern); + expect(mappedLine.line).toEqual(typescriptPosition.line); + expect(mappedLine.file).toEqual(`${currentFile}.ts`); + } + }); }); diff --git a/test/transpile/bundle/bundle-source-maps/index.ts b/test/transpile/bundle/bundle-source-maps/index.ts new file mode 100644 index 000000000..22a2f499e --- /dev/null +++ b/test/transpile/bundle/bundle-source-maps/index.ts @@ -0,0 +1,8 @@ +import { getNumber, Operation } from "./largeFile"; + +// Local variables +const left = getNumber(3, 4, Operation.MUL); +const right = getNumber(5, 6, Operation.SUM); + +export const myNumber = getNumber(left, right, Operation.MUL); +export const sourceMap = (globalThis as any).__TS__sourcemap; diff --git a/test/transpile/bundle/bundle-source-maps/largeFile.ts b/test/transpile/bundle/bundle-source-maps/largeFile.ts new file mode 100644 index 000000000..ae0a9be7a --- /dev/null +++ b/test/transpile/bundle/bundle-source-maps/largeFile.ts @@ -0,0 +1,53 @@ +// Some comments here to check source map correctness +// Some comments here to check source map correctness + +abstract class Calculator { + protected left: number; + protected right: number; + + constructor(left: number, right: number) { + this.left = left; + this.right = right; + } + + public abstract calc(): number; +} + +/** + * Sums two numbers + */ +class CalculatorSum extends Calculator { + public calc(): number { + return this.left + this.right; + } +} + +class CalculatorMul extends Calculator { + public calc(): number { + return this.left * this.right; + } +} + +// Some comments here to check source map correctness + +export const enum Operation { + SUM = "SUM", + MUL = "MUL", +} + +// Local internal function +function resolveCalculatorClass(left: number, right: number, operation: Operation): Calculator { + if (operation === Operation.MUL) { + return new CalculatorMul(left, right); + } + if (operation === Operation.SUM) { + return new CalculatorSum(left, right); + } + + throw new Error(`Unknown operation ${operation}`); +} + +// Some comments here to check source map correctness +export function getNumber(left: number, right: number, operation: Operation): number { + return resolveCalculatorClass(left, right, operation).calc(); +} diff --git a/test/transpile/bundle/bundle-source-maps/tsconfig.json b/test/transpile/bundle/bundle-source-maps/tsconfig.json new file mode 100644 index 000000000..6614ac5d7 --- /dev/null +++ b/test/transpile/bundle/bundle-source-maps/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "target": "esnext", + "lib": ["esnext"], + "types": ["lua-types/5.3"], + "rootDir": "." + }, + "tstl": { + "luaBundle": "bundle.lua", + "luaBundleEntry": "index.ts", + "sourceMapTraceback": true + }, + "include": ["."] +} diff --git a/test/transpile/bundle/index.ts b/test/transpile/bundle/bundle-two-files/index.ts similarity index 100% rename from test/transpile/bundle/index.ts rename to test/transpile/bundle/bundle-two-files/index.ts diff --git a/test/transpile/bundle/otherFile.ts b/test/transpile/bundle/bundle-two-files/otherFile.ts similarity index 100% rename from test/transpile/bundle/otherFile.ts rename to test/transpile/bundle/bundle-two-files/otherFile.ts diff --git a/test/transpile/bundle/tsconfig.json b/test/transpile/bundle/bundle-two-files/tsconfig.json similarity index 100% rename from test/transpile/bundle/tsconfig.json rename to test/transpile/bundle/bundle-two-files/tsconfig.json diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 891945dc3..6c5857120 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,7 +1,8 @@ -import { Position, SourceMapConsumer } from "source-map"; +import { SourceMapConsumer } from "source-map"; import * as tstl from "../../../src"; import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; +import { lineAndColumnOf } from "./utils"; test.each([ { @@ -306,27 +307,3 @@ test("Inline sourcemaps", () => { const inlineSourceMap = Buffer.from(inlineSourceMapMatch, "base64").toString(); expect(inlineSourceMap).toBe(file.luaSourceMap); }); - -// Helper functions - -function lineAndColumnOf(text: string, pattern: string): Position { - const pos = text.indexOf(pattern); - if (pos === -1) { - return { line: -1, column: -1 }; - } - - const lineLengths = text.split("\n").map(s => s.length); - - let totalPos = 0; - for (let line = 1; line <= lineLengths.length; line++) { - // Add + 1 for the removed \n - const lineLength = lineLengths[line - 1] + 1; - if (pos < totalPos + lineLength) { - return { line, column: pos - totalPos }; - } - - totalPos += lineLengths[line - 1] + 1; - } - - return { line: -1, column: -1 }; -} diff --git a/test/unit/printer/utils.ts b/test/unit/printer/utils.ts new file mode 100644 index 000000000..a9f58b44f --- /dev/null +++ b/test/unit/printer/utils.ts @@ -0,0 +1,25 @@ +// Helper functions + +import { Position } from "source-map"; + +export function lineAndColumnOf(text: string, pattern: string): Position { + const pos = text.indexOf(pattern); + if (pos === -1) { + return { line: -1, column: -1 }; + } + + const lineLengths = text.split("\n").map(s => s.length); + + let totalPos = 0; + for (let line = 1; line <= lineLengths.length; line++) { + // Add + 1 for the removed \n + const lineLength = lineLengths[line - 1] + 1; + if (pos < totalPos + lineLength) { + return { line, column: pos - totalPos }; + } + + totalPos += lineLengths[line - 1] + 1; + } + + return { line: -1, column: -1 }; +} From 3a3465b93b78bb28db61c1421f1ead6b6626606e Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:24:30 -0700 Subject: [PATCH 400/764] Runtime benchmarks (#1126) * Basic runtime benchmarks * Add basic doc for runtime benchmarks * Fix runtime benchmark text formatting * Add /benchmark/dist to .prettierignore * Sort benchmarks by name * Remove benchmark/dist/json.lua from gitignore there's already benchmark/src/json.lua * Enable benchmark in ci * Refactor comparison Markdown formatting --- .eslintrc.js | 2 +- .github/workflows/ci.yml | 154 +++++++++--------- .gitignore | 1 - .prettierignore | 1 + benchmark/README.md | 18 +- benchmark/src/benchmark_types.ts | 13 +- benchmark/src/benchmark_util.ts | 60 +++++++ benchmark/src/memory_benchmark.ts | 53 +----- benchmark/src/run.ts | 57 ++++++- benchmark/src/runtime_benchmark.ts | 43 +++++ .../src/runtime_benchmarks/array_push.ts | 8 + 11 files changed, 267 insertions(+), 143 deletions(-) create mode 100644 benchmark/src/benchmark_util.ts create mode 100644 benchmark/src/runtime_benchmark.ts create mode 100644 benchmark/src/runtime_benchmarks/array_push.ts diff --git a/.eslintrc.js b/.eslintrc.js index 52df969ff..a32cc13f7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -218,7 +218,7 @@ module.exports = { }, }, { - files: "benchmark/src/memory_benchmarks/**/*.ts", + files: "benchmark/src/*_benchmarks/**/*.ts", rules: { "import/no-default-export": "off", }, diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b0e0bf6cd..968cd9b87 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -39,80 +39,80 @@ jobs: - if: matrix.os == 'ubuntu-latest' uses: codecov/codecov-action@v1 - # benchmark: - # name: Benchmark - # runs-on: ubuntu-latest - # steps: - # - name: Lua Install - # run: sudo apt-get install lua5.3 luajit - # - name: Glow Install - # run: brew install glow - # # Checkout master & commit - # - name: Checkout master - # uses: actions/checkout@v2 - # with: - # ref: master - # path: master - # - name: Checkout commit - # uses: actions/checkout@v2 - # with: - # path: commit - # - name: Use Node.js 12.13.1 - # uses: actions/setup-node@v1 - # with: - # node-version: 12.13.1 - # # NPM - # - name: NPM master - # run: npm ci && npm run build - # working-directory: master - # - name: NPM commit - # run: npm ci && npm run build - # working-directory: commit - # # Benchmark directory setup - # - name: Ensure benchmark data dir exists - # run: mkdir -p ./benchmark/data - # working-directory: commit - # - name: Copy commit benchmark to master - # run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark - # # Run master benchmark first and output to commit benchmark data - # - name: Build benchmark Lua 5.3 master - # run: node ../../commit/dist/tstl.js -p tsconfig.53.json - # working-directory: master/benchmark - # - name: Run benchmark Lua 5.3 master - # id: benchmark-lua-master - # run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json - # working-directory: master/benchmark/dist - # - name: Build benchmark LuaJIT master - # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json - # working-directory: master/benchmark - # - name: Run benchmark LuaJIT master - # id: benchmark-jit-master - # run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json - # working-directory: master/benchmark/dist - # # Run commit benchmark and compare with master - # - name: Build benchmark Lua 5.3 commit - # run: node ../../commit/dist/tstl.js -p tsconfig.53.json - # working-directory: commit/benchmark - # - name: Run benchmark Lua 5.3 commit - # id: benchmark-lua-commit - # run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json - # working-directory: commit/benchmark/dist - # - name: Build benchmark LuaJIT commit - # run: node ../../commit/dist/tstl.js -p tsconfig.jit.json - # working-directory: commit/benchmark - # - name: Run benchmark LuaJIT commit - # id: benchmark-jit-commit - # run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json - # working-directory: commit/benchmark/dist - # - name: Combine benchmark results - # id: script-combine-results - # uses: actions/github-script@v3 - # with: - # benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json - # benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json - # result-encoding: string - # script: | - # const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); - # return createBenchmarkCheck({ github, context, core }); - # - name: Benchmark results - # run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - + benchmark: + name: Benchmark + runs-on: ubuntu-latest + steps: + - name: Lua Install + run: sudo apt-get install lua5.3 luajit + - name: Glow Install + run: brew install glow + # Checkout master & commit + - name: Checkout master + uses: actions/checkout@v2 + with: + ref: master + path: master + - name: Checkout commit + uses: actions/checkout@v2 + with: + path: commit + - name: Use Node.js 12.13.1 + uses: actions/setup-node@v1 + with: + node-version: 12.13.1 + # NPM + - name: NPM master + run: npm ci && npm run build + working-directory: master + - name: NPM commit + run: npm ci && npm run build + working-directory: commit + # Benchmark directory setup + - name: Ensure benchmark data dir exists + run: mkdir -p ./benchmark/data + working-directory: commit + - name: Copy commit benchmark to master + run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark + # Run master benchmark first and output to commit benchmark data + - name: Build benchmark Lua 5.3 master + run: node ../../commit/dist/tstl.js -p tsconfig.53.json + working-directory: master/benchmark + - name: Run benchmark Lua 5.3 master + id: benchmark-lua-master + run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json + working-directory: master/benchmark/dist + - name: Build benchmark LuaJIT master + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + working-directory: master/benchmark + - name: Run benchmark LuaJIT master + id: benchmark-jit-master + run: luajit -- run.lua ../../../commit/benchmark/data/benchmark_master_jit.json + working-directory: master/benchmark/dist + # Run commit benchmark and compare with master + - name: Build benchmark Lua 5.3 commit + run: node ../../commit/dist/tstl.js -p tsconfig.53.json + working-directory: commit/benchmark + - name: Run benchmark Lua 5.3 commit + id: benchmark-lua-commit + run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json + working-directory: commit/benchmark/dist + - name: Build benchmark LuaJIT commit + run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + working-directory: commit/benchmark + - name: Run benchmark LuaJIT commit + id: benchmark-jit-commit + run: luajit -- run.lua ../data/benchmark_master_vs_commit_jit.json ../data/benchmark_master_jit.json + working-directory: commit/benchmark/dist + - name: Combine benchmark results + id: script-combine-results + uses: actions/github-script@v3 + with: + benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json + benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json + result-encoding: string + script: | + const createBenchmarkCheck = require(`${process.env.GITHUB_WORKSPACE}/commit/.github/scripts/create_benchmark_check.js`); + return createBenchmarkCheck({ github, context, core }); + - name: Benchmark results + run: echo "${{steps.script-combine-results.outputs.result}}" | glow -s dark -w 120 - diff --git a/.gitignore b/.gitignore index 5546914da..c2bc56893 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,3 @@ yarn.lock benchmark/data/* benchmark/dist/* -!benchmark/dist/json.lua diff --git a/.prettierignore b/.prettierignore index cbfe6aa04..23b85e3bd 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,4 @@ /dist /coverage /test/translation/transformation/characterEscapeSequence.ts +/benchmark/dist diff --git a/benchmark/README.md b/benchmark/README.md index c7b7d39c2..321218c9c 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -2,12 +2,12 @@ These benchmarks are written in typescript and transpiled to lua by using tstl. -### Currently only memory benchmarks are supported +### Memory benchmarks To add a new benchmark add a new file to `memory_benchmarks` and **default** export a function with the following type: `() => void`. To prevent the benchmark from reporting "useful" results of your benchmark function as garbage, simply return the result. -The memory used by the returned result wont count towards the total garbage amount. +The memory used by the returned result won't count towards the total garbage amount. For example (memory_benchmarks/my_benchmark.ts): @@ -25,19 +25,23 @@ export default function myBenchmark() { **Goal** The goal of memory benchmarks is to track how much (memory) `"garbage"` is created by tstl. -For that reason garabage collection is disabled in the benchmarks. +For that reason garbage collection is disabled in the benchmarks. You can force the creation of `"garbage"` by creating a lot of anonymous functions or temporary tables (see [lua-users.org](http://lua-users.org/wiki/OptimisingGarbageCollection) for more information). To avoid crashes in the CI your benchmark should not use more than 500MB of memory. -**Running locally** +### Runtime benchmarks -1. Create a benchmark baseline called "benchmark_baseline.json": +To add a new runtime benchmark (execution time), add a new file to `runtime_benchmarks` and **default** export a function with the following type: `() => void`. + +### Running locally + +1. Create a benchmark baseline called "benchmark_baseline.json": `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_baseline.json` 2. Make some changes to tstl. -3. Create an updated benchmark and compare with the baseline: +3. Create an updated benchmark and compare with the baseline: `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_updated.json benchmark_baseline.json` 4. The above command will output comparison data as json to stdout. - If you provide a path as third argument the comparison data will be written to that path instead. + If you provide a path as third argument the comparison data will be written to that path instead. `tstl -p tsconfig.53.json && cd dist && lua -- run.lua benchmark_updated.json benchmark_baseline.json result.md` diff --git a/benchmark/src/benchmark_types.ts b/benchmark/src/benchmark_types.ts index 6ec80efe6..38c2c1fd6 100644 --- a/benchmark/src/benchmark_types.ts +++ b/benchmark/src/benchmark_types.ts @@ -1,10 +1,11 @@ export enum BenchmarkKind { Memory = "memory", + Runtime = "runtime", } export type BenchmarkFunction = () => void; -export type BenchmarkResult = MemoryBenchmarkResult; +export type BenchmarkResult = MemoryBenchmarkResult | RuntimeBenchmarkResult; export enum MemoryBenchmarkCategory { TotalMemory = "totalMemory", @@ -21,6 +22,16 @@ export function isMemoryBenchmarkResult(result: BenchmarkResult): result is Memo return result.kind === BenchmarkKind.Memory; } +export interface RuntimeBenchmarkResult { + kind: BenchmarkKind.Runtime; + time: number; + benchmarkName: string; +} + +export function isRuntimeBenchmarkResult(result: BenchmarkResult): result is RuntimeBenchmarkResult { + return result.kind === BenchmarkKind.Runtime; +} + export interface ComparisonInfo { summary: string; text: string; diff --git a/benchmark/src/benchmark_util.ts b/benchmark/src/benchmark_util.ts new file mode 100644 index 000000000..fedbfdb93 --- /dev/null +++ b/benchmark/src/benchmark_util.ts @@ -0,0 +1,60 @@ +import { BenchmarkResult } from "./benchmark_types"; +import { calculatePercentageChange, toFixed } from "./util"; + +export const makeMarkdownTableRow = (cells: string[]) => `| ${cells.join(" | ")} |\n`; +export const makeBold = (input: string) => `**${input}**`; + +export function compareNumericBenchmarks( + newResults: T[], + oldResults: T[], + unit: string, + extractValue: (result: T) => number, + formatValue: (value: number) => string +): string { + let comparisonTable = makeMarkdownTableRow([ + "name", + `master (${unit})`, + `commit (${unit})`, + `change (${unit})`, + "change (%)", + ]); + comparisonTable += makeMarkdownTableRow(["---", "---", "---", "---", "---"]); + + let oldValueSum = 0; + let newValueSum = 0; + + newResults.forEach(newResult => { + const oldResult = oldResults.find(r => r.benchmarkName === newResult.benchmarkName); + const newValue = extractValue(newResult); + if (oldResult) { + const oldValue = extractValue(oldResult); + const percentageChange = calculatePercentageChange(oldValue, newValue); + const change = newValue - oldValue; + const row = [ + newResult.benchmarkName, + formatValue(oldValue), + formatValue(newValue), + formatValue(change), + toFixed(percentageChange, 2), + ]; + comparisonTable += makeMarkdownTableRow(row); + oldValueSum += oldValue; + newValueSum += newValue; + } else { + // No master found => new benchmark + const row = [newResult.benchmarkName, formatValue(newValue), "/", "/", "/"]; + comparisonTable += makeMarkdownTableRow(row); + } + }); + + const sumPercentageChange = calculatePercentageChange(oldValueSum, newValueSum); + comparisonTable += makeMarkdownTableRow([ + makeBold("sum"), + makeBold(formatValue(oldValueSum)), + makeBold(formatValue(newValueSum)), + makeBold(formatValue(newValueSum - oldValueSum)), + makeBold(toFixed(sumPercentageChange, 2)), + ]); + + return comparisonTable; +} diff --git a/benchmark/src/memory_benchmark.ts b/benchmark/src/memory_benchmark.ts index 51f8031be..8434f3881 100644 --- a/benchmark/src/memory_benchmark.ts +++ b/benchmark/src/memory_benchmark.ts @@ -1,5 +1,6 @@ import { BenchmarkKind, MemoryBenchmarkResult, ComparisonInfo, MemoryBenchmarkCategory } from "./benchmark_types"; -import { toFixed, json, calculatePercentageChange } from "./util"; +import { compareNumericBenchmarks } from "./benchmark_util"; +import { toFixed, json } from "./util"; export function runMemoryBenchmark(benchmarkFunction: () => void): MemoryBenchmarkResult { const result: MemoryBenchmarkResult = { @@ -42,8 +43,6 @@ export function runMemoryBenchmark(benchmarkFunction: () => void): MemoryBenchma } const formatMemory = (memInKB: number) => toFixed(memInKB / 1024, 3); -const makeMarkdownTableRow = (cells: string[]) => `| ${cells.join(" | ")} |\n`; -const makeBold = (input: string) => `**${input}**`; export function compareMemoryBenchmarks( oldResults: MemoryBenchmarkResult[], @@ -53,10 +52,10 @@ export function compareMemoryBenchmarks( const categories = [MemoryBenchmarkCategory.TotalMemory, MemoryBenchmarkCategory.Garbage]; const summary = categories - .map(category => `${makeBold(category)}\n${compareCategory(newResults, oldResults, category)}`) + .map(category => `### ${category}\n\n${compareCategory(newResults, oldResults, category)}`) .join("\n"); - const text = `**master:**\n\`\`\`json\n${json.encode(oldResults)}\n\`\`\`\n**commit:**\n\`\`\`json\n${json.encode( + const text = `### master:\n\`\`\`json\n${json.encode(oldResults)}\n\`\`\`\n### commit:\n\`\`\`json\n${json.encode( newResults )}\n\`\`\``; @@ -68,47 +67,5 @@ function compareCategory( oldResults: MemoryBenchmarkResult[], category: MemoryBenchmarkCategory ): string { - let comparisonTable = makeMarkdownTableRow(["name", "master (mb)", "commit (mb)", "change (mb)", "change (%)"]); - comparisonTable += makeMarkdownTableRow(["-", "-", "-", "-", "-"]); - - let oldValueSum = 0; - let newValueSum = 0; - - newResults.forEach(newResult => { - const oldResult = oldResults.find(r => r.benchmarkName === newResult.benchmarkName); - if (oldResult) { - const oldValue = oldResult.categories[category]; - const newValue = newResult.categories[category]; - const percentageChange = calculatePercentageChange( - newResult.categories[category], - oldResult.categories[category] - ); - const change = newResult.categories[category] - oldResult.categories[category]; - const row = [ - newResult.benchmarkName, - formatMemory(oldValue), - formatMemory(newValue), - formatMemory(change), - toFixed(percentageChange, 2), - ]; - comparisonTable += makeMarkdownTableRow(row); - oldValueSum += oldValue; - newValueSum += newValue; - } else { - // No master found => new benchmark - const row = [newResult.benchmarkName, formatMemory(newResult.categories[category]), "/", "/", "/"]; - comparisonTable += makeMarkdownTableRow(row); - } - }); - - const sumPercentageChange = calculatePercentageChange(oldValueSum, newValueSum); - comparisonTable += makeMarkdownTableRow([ - makeBold("sum"), - makeBold(formatMemory(oldValueSum)), - makeBold(formatMemory(newValueSum)), - makeBold(formatMemory(newValueSum - oldValueSum)), - makeBold(toFixed(sumPercentageChange, 2)), - ]); - - return comparisonTable; + return compareNumericBenchmarks(newResults, oldResults, "mb", result => result.categories[category], formatMemory); } diff --git a/benchmark/src/run.ts b/benchmark/src/run.ts index b880537e5..8b02cc7da 100644 --- a/benchmark/src/run.ts +++ b/benchmark/src/run.ts @@ -1,5 +1,14 @@ import { runMemoryBenchmark, compareMemoryBenchmarks } from "./memory_benchmark"; -import { isMemoryBenchmarkResult, BenchmarkResult, MemoryBenchmarkResult, ComparisonInfo } from "./benchmark_types"; +import { + isMemoryBenchmarkResult, + BenchmarkResult, + MemoryBenchmarkResult, + ComparisonInfo, + RuntimeBenchmarkResult, + isRuntimeBenchmarkResult, + BenchmarkKind, +} from "./benchmark_types"; +import { runRuntimeBenchmark, compareRuntimeBenchmarks } from "./runtime_benchmark"; import { json, loadBenchmarksFromDirectory, readFile } from "./util"; // CLI arguments @@ -10,15 +19,16 @@ declare const arg: [string | undefined, string | undefined, string | undefined]; function benchmark(): void { // Memory tests - let memoryBenchmarkNewResults: MemoryBenchmarkResult[] = []; const memoryBenchmarks = loadBenchmarksFromDirectory("memory_benchmarks"); + const memoryBenchmarkNewResults: MemoryBenchmarkResult[] = memoryBenchmarks.map(runMemoryBenchmark); - memoryBenchmarkNewResults = memoryBenchmarks.map(runMemoryBenchmark); + // Run time tests - // run future benchmarks types here + const runtimeBenchmarks = loadBenchmarksFromDirectory("runtime_benchmarks"); + const runtimeBenchmarkNewResults: RuntimeBenchmarkResult[] = runtimeBenchmarks.map(runRuntimeBenchmark); - const newBenchmarkResults = [...memoryBenchmarkNewResults]; + const newBenchmarkResults = [...memoryBenchmarkNewResults, ...runtimeBenchmarkNewResults]; // Try to read the baseline benchmark result let oldBenchmarkResults: BenchmarkResult[] = []; @@ -28,17 +38,48 @@ function benchmark(): void { } // Output comparison info + oldBenchmarkResults.sort(sortByName); + newBenchmarkResults.sort(sortByName); outputBenchmarkData(oldBenchmarkResults, newBenchmarkResults); } benchmark(); -function compareBenchmarks(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): ComparisonInfo { +function sortByName({ benchmarkName: a }: BenchmarkResult, { benchmarkName: b }: BenchmarkResult): number { + if (a < b) return -1; + if (a > b) return 1; + return 0; +} + +function compareBenchmarks( + oldResults: BenchmarkResult[], + newResults: BenchmarkResult[] +): Record { const oldResultsMemory = oldResults.filter(isMemoryBenchmarkResult); const newResultsMemory = newResults.filter(isMemoryBenchmarkResult); const memoryComparisonInfo = compareMemoryBenchmarks(oldResultsMemory, newResultsMemory); - return { summary: memoryComparisonInfo.summary, text: memoryComparisonInfo.text }; + const oldResultsRuntime = oldResults.filter(isRuntimeBenchmarkResult); + const newResultsRuntime = newResults.filter(isRuntimeBenchmarkResult); + + const runtimeComparisonInfo = compareRuntimeBenchmarks(oldResultsRuntime, newResultsRuntime); + + return { + [BenchmarkKind.Memory]: memoryComparisonInfo, + [BenchmarkKind.Runtime]: runtimeComparisonInfo, + }; +} + +function formatComparisonMarkdownFile(comparisonInfo: Record): string { + let result = ""; + const benchmarkKinds = [BenchmarkKind.Memory, BenchmarkKind.Runtime]; + for (const kind of benchmarkKinds) { + result += comparisonInfo[kind].summary + "\n"; + } + for (const kind of benchmarkKinds) { + result += comparisonInfo[kind].text + "\n"; + } + return result; } function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: BenchmarkResult[]): void { @@ -59,6 +100,6 @@ function outputBenchmarkData(oldResults: BenchmarkResult[], newResults: Benchmar // Compare results const comparisonInfo = compareBenchmarks(oldResults, newResults); const markdownDataFile = io.open(arg[2], "w+")[0]!; - markdownDataFile.write(comparisonInfo.summary + comparisonInfo.text); + markdownDataFile.write(formatComparisonMarkdownFile(comparisonInfo)); } } diff --git a/benchmark/src/runtime_benchmark.ts b/benchmark/src/runtime_benchmark.ts new file mode 100644 index 000000000..c56cd1b0d --- /dev/null +++ b/benchmark/src/runtime_benchmark.ts @@ -0,0 +1,43 @@ +import { BenchmarkKind, ComparisonInfo, RuntimeBenchmarkResult } from "./benchmark_types"; +import { compareNumericBenchmarks } from "./benchmark_util"; +import { json, toFixed } from "./util"; + +export function runRuntimeBenchmark(benchmarkFunction: () => void): RuntimeBenchmarkResult { + const result: RuntimeBenchmarkResult = { + kind: BenchmarkKind.Runtime, + benchmarkName: "NO_NAME", + time: 0, + }; + + // normalize times a bit + collectgarbage("collect"); + + const startTime = os.clock(); + benchmarkFunction(); + const time = os.clock() - startTime; + + result.benchmarkName = debug.getinfo(benchmarkFunction).short_src; + result.time = time; + return result; +} + +export function compareRuntimeBenchmarks( + oldResults: RuntimeBenchmarkResult[], + newResults: RuntimeBenchmarkResult[] +): ComparisonInfo { + const summary = + "### runtime\n\n" + + compareNumericBenchmarks( + newResults, + oldResults, + "s", + result => result.time, + time => toFixed(time, 4) + ); + + const text = `### master\n\`\`\`json\n${json.encode(oldResults)}\n\`\`\`\n### commit\n\`\`\`json\n${json.encode( + newResults + )}\n\`\`\``; + + return { summary, text }; +} diff --git a/benchmark/src/runtime_benchmarks/array_push.ts b/benchmark/src/runtime_benchmarks/array_push.ts new file mode 100644 index 000000000..e0d2d0b87 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_push.ts @@ -0,0 +1,8 @@ +export default function arrayPush(): number[] { + const n = 1000000; + const numberList: number[] = []; + for (let i = 0; i < n; i++) { + numberList[numberList.length] = i * i; + } + return numberList; +} From 8b8223284d1ec13313e612cacadad44032c06a08 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:34:40 -0700 Subject: [PATCH 401/764] Add `string.replaceAll` lualib and optimize/fix `string.replace` (#1129) * Optimize StringReplace * Add `string.replaceAll` lualib function This makes Node v15 (for ES2021 support) minimum required to run tests * Add tests for string.replace(All) function call arguments * Use node 16.9.0 for tests (for es2021 support) * Use node 15.14.0 for tests (for es2021 support) Node 16 with "vm" currently has a bug which prevents some js tests from compiling at all, somehow * Changes for PR --- .github/workflows/ci.yml | 4 +- src/LuaLib.ts | 1 + src/lualib/StringReplace.ts | 25 +++++-------- src/lualib/StringReplaceAll.ts | 40 ++++++++++++++++++++ src/transformation/builtins/string.ts | 2 + test/unit/builtins/string.spec.ts | 53 +++++++++++++++++++-------- 6 files changed, 92 insertions(+), 33 deletions(-) create mode 100644 src/lualib/StringReplaceAll.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 968cd9b87..7a60d65a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,10 +27,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 12.13.1 + - name: Use Node.js 15.14.0 uses: actions/setup-node@v1 with: - node-version: 12.13.1 + node-version: 15.14.0 - run: npm ci - run: npm run build - run: npx jest --maxWorkers 2 --coverage diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 9c50019f5..03483d2cc 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -83,6 +83,7 @@ export enum LuaLibFeature { StringPadEnd = "StringPadEnd", StringPadStart = "StringPadStart", StringReplace = "StringReplace", + StringReplaceAll = "StringReplaceAll", StringSlice = "StringSlice", StringSplit = "StringSplit", StringStartsWith = "StringStartsWith", diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index 51a093bef..ab96d5329 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -2,21 +2,16 @@ function __TS__StringReplace( this: void, source: string, searchValue: string, - replaceValue: string | ((substring: string) => string) + replaceValue: string | ((match: string, offset: number, string: string) => string) ): string { - [searchValue] = string.gsub(searchValue, "[%%%(%)%.%+%-%*%?%[%^%$]", "%%%1"); - - if (typeof replaceValue === "string") { - [replaceValue] = string.gsub(replaceValue, "%%", "%%%%"); - const [result] = string.gsub(source, searchValue, replaceValue, 1); - return result; - } else { - const [result] = string.gsub( - source, - searchValue, - match => (replaceValue as (substring: string) => string)(match), - 1 - ); - return result; + const [startPos, endPos] = string.find(source, searchValue, undefined, true); + if (!startPos) { + return source; } + const sub = string.sub; + const before = sub(source, 1, startPos - 1); + const replacement = + typeof replaceValue === "string" ? replaceValue : replaceValue(searchValue, startPos - 1, source); + const after = sub(source, endPos + 1); + return before + replacement + after; } diff --git a/src/lualib/StringReplaceAll.ts b/src/lualib/StringReplaceAll.ts new file mode 100644 index 000000000..e288a1497 --- /dev/null +++ b/src/lualib/StringReplaceAll.ts @@ -0,0 +1,40 @@ +function __TS__StringReplaceAll( + this: void, + source: string, + searchValue: string, + replaceValue: string | ((match: string, offset: number, string: string) => string) +): string { + let replacer: (match: string, offset: number, string: string) => string; + if (typeof replaceValue === "string") { + replacer = () => replaceValue; + } else { + replacer = replaceValue; + } + const parts: string[] = []; + let partsIndex = 1; + + const sub = string.sub; + if (searchValue.length === 0) { + parts[0] = replacer("", 0, source); + partsIndex = 2; + for (const i of $range(1, source.length)) { + parts[partsIndex - 1] = sub(source, i, i); + parts[partsIndex] = replacer("", i, source); + partsIndex += 2; + } + } else { + const find = string.find; + let currentPos = 1; + while (true) { + const [startPos, endPos] = find(source, searchValue, currentPos, true); + if (!startPos) break; + parts[partsIndex - 1] = sub(source, currentPos, startPos - 1); + parts[partsIndex] = replacer(searchValue, startPos - 1, source); + partsIndex += 2; + + currentPos = endPos + 1; + } + parts[partsIndex - 1] = sub(source, currentPos); + } + return table.concat(parts); +} diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 4cb21ea93..952d18c7e 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -28,6 +28,8 @@ export function transformStringPrototypeCall( switch (expressionName) { case "replace": return transformLuaLibFunction(context, LuaLibFeature.StringReplace, node, caller, ...params); + case "replaceAll": + return transformLuaLibFunction(context, LuaLibFeature.StringReplaceAll, node, caller, ...params); case "concat": return transformLuaLibFunction(context, LuaLibFeature.StringConcat, node, caller, ...params); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index c31ef012f..70d7e2463 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -54,22 +54,43 @@ test("string index (side effect)", () => { `.expectToMatchJsResult(); }); -test.each([ - { inp: "hello test", searchValue: "", replaceValue: "" }, - { inp: "hello test", searchValue: " ", replaceValue: "" }, - { inp: "hello test", searchValue: "hello", replaceValue: "" }, - { inp: "hello test", searchValue: "test", replaceValue: "" }, - { inp: "hello test", searchValue: "test", replaceValue: "world" }, - { inp: "hello test", searchValue: "test", replaceValue: "%world" }, - { inp: "hello test", searchValue: "test", replaceValue: "." }, - { inp: "hello %test", searchValue: "test", replaceValue: "world" }, - { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, - { inp: "hello test.", searchValue: ".", replaceValue: "$" }, - { inp: "hello test", searchValue: "test", replaceValue: () => "a" }, - { inp: "hello test", searchValue: "test", replaceValue: () => "%a" }, - { inp: "aaa", searchValue: "a", replaceValue: "b" }, -])("string.replace (%p)", ({ inp, searchValue, replaceValue }) => { - util.testExpression`"${inp}".replace(${util.formatCode(searchValue, replaceValue)})`.expectToMatchJsResult(); +describe.each(["replace", "replaceAll"])("string.%s", method => { + const testCases = [ + { inp: "hello test", searchValue: "", replaceValue: "" }, + { inp: "hello test", searchValue: "", replaceValue: "_" }, + { inp: "hello test", searchValue: " ", replaceValue: "" }, + { inp: "hello test", searchValue: "hello", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "" }, + { inp: "hello test", searchValue: "test", replaceValue: "world" }, + { inp: "hello test", searchValue: "test", replaceValue: "%world" }, + { inp: "hello test", searchValue: "test", replaceValue: "." }, + { inp: "hello %test", searchValue: "test", replaceValue: "world" }, + { inp: "hello %test", searchValue: "%test", replaceValue: "world" }, + { inp: "hello test.", searchValue: ".", replaceValue: "$" }, + { inp: "aaa", searchValue: "a", replaceValue: "b" }, + ]; + + test.each(testCases)("string replacer %p", ({ inp, searchValue, replaceValue }) => { + util.testExpression`"${inp}${inp}".${method}(${util.formatCode( + searchValue, + replaceValue + )})`.expectToMatchJsResult(); + }); + + test.each(testCases)("function replacer %p", ({ inp, searchValue, replaceValue }) => { + util.testFunction` + const result = { + args: [], + string: "" + } + function replacer(...args: any[]): string { + result.args.push(...args) + return ${util.formatCode(replaceValue)} + } + result.string = "${inp}${inp}".${method}(${util.formatCode(searchValue)}, replacer) + return result + `.expectToMatchJsResult(); + }); }); test.each([ From a8325da5bd62fe56e669a62a6477a857caac23a1 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 9 Sep 2021 12:55:27 -0700 Subject: [PATCH 402/764] Use separate master and commit compiler for benchmark compiling (#1133) --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7a60d65a3..4c778f21f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -76,14 +76,14 @@ jobs: run: rm -rf ./master/benchmark && cp -rf ./commit/benchmark ./master/benchmark # Run master benchmark first and output to commit benchmark data - name: Build benchmark Lua 5.3 master - run: node ../../commit/dist/tstl.js -p tsconfig.53.json + run: node ../dist/tstl.js -p tsconfig.53.json working-directory: master/benchmark - name: Run benchmark Lua 5.3 master id: benchmark-lua-master run: lua5.3 -- run.lua ../../../commit/benchmark/data/benchmark_master_53.json working-directory: master/benchmark/dist - name: Build benchmark LuaJIT master - run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + run: node ../dist/tstl.js -p tsconfig.jit.json working-directory: master/benchmark - name: Run benchmark LuaJIT master id: benchmark-jit-master @@ -91,14 +91,14 @@ jobs: working-directory: master/benchmark/dist # Run commit benchmark and compare with master - name: Build benchmark Lua 5.3 commit - run: node ../../commit/dist/tstl.js -p tsconfig.53.json + run: node ../dist/tstl.js -p tsconfig.53.json working-directory: commit/benchmark - name: Run benchmark Lua 5.3 commit id: benchmark-lua-commit run: lua5.3 -- run.lua ../data/benchmark_master_vs_commit_53.json ../data/benchmark_master_53.json working-directory: commit/benchmark/dist - name: Build benchmark LuaJIT commit - run: node ../../commit/dist/tstl.js -p tsconfig.jit.json + run: node ../dist/tstl.js -p tsconfig.jit.json working-directory: commit/benchmark - name: Run benchmark LuaJIT commit id: benchmark-jit-commit From 73a4ed0ffbb423d604b91d232888a3e06486b70b Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 11 Sep 2021 07:56:30 -0600 Subject: [PATCH 403/764] Hoisting switch fix (#1125) * fixes and refactors for hoisting to fix switch statements and make logic more clear * applied hoisting fix to new switch implementation also refactored a few things for clarity and added tests * fixed issues with hoisting from default clause * added snapshots for a couple tests and a comment * fixed edge case with hoisting in a solo default clause * addressing review feedback Co-authored-by: Tom --- src/transformation/utils/lua-ast.ts | 16 +-- src/transformation/utils/scope.ts | 118 +++++++++++----- src/transformation/visitors/switch.ts | 59 ++++++-- test/unit/__snapshots__/switch.spec.ts.snap | 76 ++++++++++ test/unit/switch.spec.ts | 146 +++++++++++++++++++- 5 files changed, 360 insertions(+), 55 deletions(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 5f3a21e4a..091cd73f4 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -175,7 +175,7 @@ export function createLocalOrExportedOrGlobalDeclaration( const isTopLevelVariable = scope.type === ScopeType.File; if (context.isModule || !isTopLevelVariable) { - if (scope.type === ScopeType.Switch || (!isFunctionDeclaration && hasMultipleReferences(scope, lhs))) { + if (!isFunctionDeclaration && hasMultipleReferences(scope, lhs)) { // Split declaration and assignment of identifiers that reference themselves in their declaration declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); if (rhs) { @@ -185,15 +185,13 @@ export function createLocalOrExportedOrGlobalDeclaration( declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); } - // Remember local variable declarations for hoisting later - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } - - scope.variableDeclarations.push(declaration); + if (!isFunctionDeclaration) { + // Remember local variable declarations for hoisting later + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } - if (scope.type === ScopeType.Switch) { - declaration = undefined; + scope.variableDeclarations.push(declaration); } } else if (rhs) { // global diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 53169765a..bed90da76 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -33,6 +33,12 @@ export interface Scope { functionReturned?: boolean; } +export interface HoistingResult { + statements: lua.Statement[]; + hoistedStatements: lua.Statement[]; + hoistedIdentifiers: lua.Identifier[]; +} + const scopeStacks = new WeakMap(); function getScopeStack(context: TransformationContext): Scope[] { return getOrUpdate(scopeStacks, context, () => []); @@ -133,16 +139,47 @@ export function isFunctionScopeWithDefinition(scope: Scope): scope is Scope & { return scope.node !== undefined && ts.isFunctionLike(scope.node); } -export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { +export function separateHoistedStatements(context: TransformationContext, statements: lua.Statement[]): HoistingResult { const scope = peekScope(context); - let result = statements; - result = hoistFunctionDefinitions(context, scope, result); - result = hoistVariableDeclarations(context, scope, result); - result = hoistImportStatements(scope, result); - return result; + const allHoistedStatments: lua.Statement[] = []; + const allHoistedIdentifiers: lua.Identifier[] = []; + + let { unhoistedStatements, hoistedStatements, hoistedIdentifiers } = hoistFunctionDefinitions( + context, + scope, + statements + ); + allHoistedStatments.push(...hoistedStatements); + allHoistedIdentifiers.push(...hoistedIdentifiers); + + ({ unhoistedStatements, hoistedIdentifiers } = hoistVariableDeclarations(context, scope, unhoistedStatements)); + allHoistedIdentifiers.push(...hoistedIdentifiers); + + ({ unhoistedStatements, hoistedStatements } = hoistImportStatements(scope, unhoistedStatements)); + allHoistedStatments.unshift(...hoistedStatements); + + return { + statements: unhoistedStatements, + hoistedStatements: allHoistedStatments, + hoistedIdentifiers: allHoistedIdentifiers, + }; +} + +export function performHoisting(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { + const result = separateHoistedStatements(context, statements); + const modifiedStatements = [...result.hoistedStatements, ...result.statements]; + if (result.hoistedIdentifiers.length > 0) { + modifiedStatements.unshift(lua.createVariableDeclarationStatement(result.hoistedIdentifiers)); + } + return modifiedStatements; } function shouldHoistSymbol(context: TransformationContext, symbolId: lua.SymbolId, scope: Scope): boolean { + // Always hoist in top-level of switch statements + if (scope.type === ScopeType.Switch) { + return true; + } + const symbolInfo = getSymbolInfo(context, symbolId); if (!symbolInfo) { return false; @@ -183,65 +220,80 @@ function hoistVariableDeclarations( context: TransformationContext, scope: Scope, statements: lua.Statement[] -): lua.Statement[] { +): { unhoistedStatements: lua.Statement[]; hoistedIdentifiers: lua.Identifier[] } { if (!scope.variableDeclarations) { - return statements; + return { unhoistedStatements: statements, hoistedIdentifiers: [] }; } - const result = [...statements]; - const hoistedLocals: lua.Identifier[] = []; + const unhoistedStatements = [...statements]; + const hoistedIdentifiers: lua.Identifier[] = []; for (const declaration of scope.variableDeclarations) { const symbols = declaration.left.map(i => i.symbolId).filter(isNonNull); if (symbols.some(s => shouldHoistSymbol(context, s, scope))) { - const index = result.indexOf(declaration); - assert(index > -1); + const index = unhoistedStatements.indexOf(declaration); + if (index < 0) { + continue; // statements array may not contain all statements in the scope (switch-case) + } if (declaration.right) { const assignment = lua.createAssignmentStatement(declaration.left, declaration.right); lua.setNodePosition(assignment, declaration); // Preserve position info for sourcemap - result.splice(index, 1, assignment); + unhoistedStatements.splice(index, 1, assignment); } else { - result.splice(index, 1); + unhoistedStatements.splice(index, 1); } - hoistedLocals.push(...declaration.left); - } else if (scope.type === ScopeType.Switch) { - assert(!declaration.right); - hoistedLocals.push(...declaration.left); + hoistedIdentifiers.push(...declaration.left); } } - if (hoistedLocals.length > 0) { - result.unshift(lua.createVariableDeclarationStatement(hoistedLocals)); - } - - return result; + return { unhoistedStatements, hoistedIdentifiers }; } function hoistFunctionDefinitions( context: TransformationContext, scope: Scope, statements: lua.Statement[] -): lua.Statement[] { +): { unhoistedStatements: lua.Statement[]; hoistedStatements: lua.Statement[]; hoistedIdentifiers: lua.Identifier[] } { if (!scope.functionDefinitions) { - return statements; + return { unhoistedStatements: statements, hoistedStatements: [], hoistedIdentifiers: [] }; } - const result = [...statements]; - const hoistedFunctions: Array = []; + const unhoistedStatements = [...statements]; + const hoistedStatements: lua.Statement[] = []; + const hoistedIdentifiers: lua.Identifier[] = []; for (const [functionSymbolId, functionDefinition] of scope.functionDefinitions) { assert(functionDefinition.definition); if (shouldHoistSymbol(context, functionSymbolId, scope)) { - const index = result.indexOf(functionDefinition.definition); - result.splice(index, 1); - hoistedFunctions.push(functionDefinition.definition); + const index = unhoistedStatements.indexOf(functionDefinition.definition); + if (index < 0) { + continue; // statements array may not contain all statements in the scope (switch-case) + } + unhoistedStatements.splice(index, 1); + + if (lua.isVariableDeclarationStatement(functionDefinition.definition)) { + // Separate function definition and variable declaration + assert(functionDefinition.definition.right); + hoistedIdentifiers.push(...functionDefinition.definition.left); + hoistedStatements.push( + lua.createAssignmentStatement( + functionDefinition.definition.left, + functionDefinition.definition.right + ) + ); + } else { + hoistedStatements.push(functionDefinition.definition); + } } } - return [...hoistedFunctions, ...result]; + return { unhoistedStatements, hoistedStatements, hoistedIdentifiers }; } -function hoistImportStatements(scope: Scope, statements: lua.Statement[]): lua.Statement[] { - return scope.importStatements ? [...scope.importStatements, ...statements] : statements; +function hoistImportStatements( + scope: Scope, + statements: lua.Statement[] +): { unhoistedStatements: lua.Statement[]; hoistedStatements: lua.Statement[] } { + return { unhoistedStatements: statements, hoistedStatements: scope.importStatements ?? [] }; } diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 1a05bae41..ae01ff10d 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { popScope, pushScope, ScopeType, separateHoistedStatements } from "../utils/scope"; const containsBreakOrReturn = (nodes: Iterable): boolean => { for (const s of nodes) { @@ -55,15 +55,25 @@ export const transformSwitchStatement: FunctionVisitor = (st // If the switch only has a default clause, wrap it in a single do. // Otherwise, we need to generate a set of if statements to emulate the switch. - let statements: lua.Statement[] = []; + const statements: lua.Statement[] = []; + const hoistedStatements: lua.Statement[] = []; + const hoistedIdentifiers: lua.Identifier[] = []; const clauses = statement.caseBlock.clauses; if (clauses.length === 1 && ts.isDefaultClause(clauses[0])) { const defaultClause = clauses[0].statements; if (defaultClause.length) { - statements.push(lua.createDoStatement(context.transformStatements(defaultClause))); + const { + statements: defaultStatements, + hoistedStatements: defaultHoistedStatements, + hoistedIdentifiers: defaultHoistedIdentifiers, + } = separateHoistedStatements(context, context.transformStatements(defaultClause)); + hoistedStatements.push(...defaultHoistedStatements); + hoistedIdentifiers.push(...defaultHoistedIdentifiers); + statements.push(lua.createDoStatement(defaultStatements)); } } else { // Build up the condition for each if statement + let defaultTransformed = false; let isInitialCondition = true; let condition: lua.Expression | undefined = undefined; for (let i = 0; i < clauses.length; i++) { @@ -124,10 +134,21 @@ export const transformSwitchStatement: FunctionVisitor = (st } // Transform the clause and append the final break statement if necessary - const clauseStatements = context.transformStatements(clause.statements); + const { + statements: clauseStatements, + hoistedStatements: clauseHoistedStatements, + hoistedIdentifiers: clauseHoistedIdentifiers, + } = separateHoistedStatements(context, context.transformStatements(clause.statements)); if (i === clauses.length - 1 && !containsBreakOrReturn(clause.statements)) { clauseStatements.push(lua.createBreakStatement()); } + hoistedStatements.push(...clauseHoistedStatements); + hoistedIdentifiers.push(...clauseHoistedIdentifiers); + + // Remember that we transformed default clause so we don't duplicate hoisted statements later + if (ts.isDefaultClause(clause)) { + defaultTransformed = true; + } // Push if statement for case statements.push(lua.createIfStatement(conditionVariable, lua.createBlock(clauseStatements))); @@ -145,11 +166,25 @@ export const transformSwitchStatement: FunctionVisitor = (st (clause, index) => index >= start && containsBreakOrReturn(clause.statements) ); - // Combine the default and all fallthrough statements - const defaultStatements: lua.Statement[] = []; - clauses - .slice(start, end >= 0 ? end + 1 : undefined) - .forEach(c => defaultStatements.push(...context.transformStatements(c.statements))); + const { + statements: defaultStatements, + hoistedStatements: defaultHoistedStatements, + hoistedIdentifiers: defaultHoistedIdentifiers, + } = separateHoistedStatements(context, context.transformStatements(clauses[start].statements)); + + // Only push hoisted statements if this is the first time we're transforming the default clause + if (!defaultTransformed) { + hoistedStatements.push(...defaultHoistedStatements); + hoistedIdentifiers.push(...defaultHoistedIdentifiers); + } + + // Combine the fallthrough statements + for (const clause of clauses.slice(start + 1, end >= 0 ? end + 1 : undefined)) { + let statements = context.transformStatements(clause.statements); + // Drop hoisted statements as they were already added when clauses were initially transformed above + ({ statements } = separateHoistedStatements(context, statements)); + defaultStatements.push(...statements); + } // Add the default clause if it has any statements // The switch will always break on the final clause and skip execution if valid to do so @@ -160,7 +195,11 @@ export const transformSwitchStatement: FunctionVisitor = (st } // Hoist the variable, function, and import statements to the top of the switch - statements = performHoisting(context, statements); + statements.unshift(...hoistedStatements); + if (hoistedIdentifiers.length > 0) { + statements.unshift(lua.createVariableDeclarationStatement(hoistedIdentifiers)); + } + popScope(context); // Add the switch expression after hoisting diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index 0fa333d93..1349374bb 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -34,6 +34,82 @@ end return ____exports" `; +exports[`switch hoisting hoisting from default clause is not duplicated when falling through 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = 1 + local result = \\"\\" + repeat + local ____switch3 = x + local hoisted + function hoisted(self) + return \\"hoisted\\" + end + local ____cond3 = ____switch3 == 1 + if ____cond3 then + result = hoisted(nil) + break + end + ____cond3 = ____cond3 or (____switch3 == 2) + if ____cond3 then + result = \\"2\\" + end + if ____cond3 then + result = \\"default\\" + end + ____cond3 = ____cond3 or (____switch3 == 3) + if ____cond3 then + result = \\"3\\" + break + end + do + result = \\"default\\" + result = \\"3\\" + end + until true + return result +end +return ____exports" +`; + +exports[`switch hoisting hoisting from fallthrough clause after default is not duplicated 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = 1 + local result = \\"\\" + repeat + local ____switch3 = x + local hoisted + function hoisted(self) + return \\"hoisted\\" + end + local ____cond3 = ____switch3 == 1 + if ____cond3 then + result = hoisted(nil) + break + end + ____cond3 = ____cond3 or (____switch3 == 2) + if ____cond3 then + result = \\"2\\" + end + if ____cond3 then + result = \\"default\\" + end + ____cond3 = ____cond3 or (____switch3 == 3) + if ____cond3 then + result = \\"3\\" + break + end + do + result = \\"default\\" + result = \\"3\\" + end + until true + return result +end +return ____exports" +`; + exports[`switch produces optimal output 1`] = ` "require(\\"lualib_bundle\\"); local ____exports = {} diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts index 6ed965595..4fb72c40c 100644 --- a/test/unit/switch.spec.ts +++ b/test/unit/switch.spec.ts @@ -369,7 +369,7 @@ test.each([0, 1])("switch empty fallthrough to default (%p)", inp => { case 1: default: out.push("default"); - + } return out; ` @@ -431,7 +431,7 @@ test.each([1, 2])("switch handles side-effects with empty fallthrough (%p)", inp ${new Array(inp).fill("case foo():").join("\n")} default: out.push("default"); - + } out.push(y); @@ -456,7 +456,7 @@ test.each([1, 2])("switch handles side-effects with empty fallthrough (preceding ${new Array(inp).fill("case foo():").join("\n")} default: out.push("default"); - + } out.push(y); @@ -522,3 +522,143 @@ test("switch produces optimal output", () => { test.each([0, 1, 2, 3, 4, 5])("switch produces valid optimal output (%p)", inp => { optimalOutput(inp).expectToMatchJsResult(); }); + +describe("switch hoisting", () => { + test("hoisting between cases", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case 1: + result = hoisted(); + break; + case 2: + function hoisted() { + return "hoisted"; + } + break; + } + return result; + `.expectToMatchJsResult(); + }); + + test("indirect hoisting between cases", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case 1: + function callHoisted() { + return hoisted(); + } + result = callHoisted(); + break; + case 2: + function hoisted() { + return "hoisted"; + } + break; + } + return result; + `.expectToMatchJsResult(); + }); + + test("hoisting in case expression", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case hoisted(): + result = "hoisted"; + break; + case 2: + function hoisted() { + return 1; + } + break; + } + return result; + `.expectToMatchJsResult(); + }); + + test("hoisting from default clause", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case 1: + result = hoisted(); + break; + default: + function hoisted() { + return "hoisted"; + } + break; + } + return result; + `.expectToMatchJsResult(); + }); + + test("hoisting from default clause is not duplicated when falling through", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case 1: + result = hoisted(); + break; + case 2: + result = "2"; + default: + function hoisted() { + return "hoisted"; + } + result = "default"; + case 3: + result = "3"; + } + return result; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + }); + + test("hoisting from fallthrough clause after default is not duplicated", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + case 1: + result = hoisted(); + break; + case 2: + result = "2"; + default: + result = "default"; + case 3: + function hoisted() { + return "hoisted"; + } + result = "3"; + } + return result; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + }); + + test("hoisting in a solo default clause", () => { + util.testFunction` + let x = 1; + let result = ""; + switch (x) { + default: + result = hoisted(); + function hoisted() { + return "hoisted"; + } + } + return result; + `.expectToMatchJsResult(); + }); +}); From 0364cdf2b21fd24aba32cc380e8245ce446934a4 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 13 Sep 2021 12:31:41 -0600 Subject: [PATCH 404/764] validating assignment of functions to object literal method types (#1136) * validating assignment of functions to object literal method types * fixed indentation in tests Co-authored-by: Tom --- .../utils/assignment-validation.ts | 3 +- .../invalidFunctionAssignments.spec.ts.snap | 1227 ++++++++++++++++- .../validation/functionPermutations.ts | 28 +- .../invalidFunctionAssignments.spec.ts | 63 +- .../validFunctionAssignments.spec.ts | 35 + 5 files changed, 1305 insertions(+), 51 deletions(-) diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index e62045248..15279bca2 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -60,7 +60,8 @@ export function validateAssignment( if ( (toType.flags & ts.TypeFlags.Object) !== 0 && - ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0 && + (ts.isTypeLiteralNode(toTypeNode) || + ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0) && toType.symbol && toType.symbol.members && fromType.symbol && diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index 7ed8e7560..ad66dfec4 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -179,15 +179,15 @@ exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMerged exports[`Invalid function argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { +exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { +exports[`Invalid function argument ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; @@ -249,16 +249,16 @@ exports[`Invalid function argument ({"definition": "interface FuncPropInterface exports[`Invalid function argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { noSelfMethod: function(s: string): string { return s; } };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -571,15 +571,15 @@ exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMerg exports[`Invalid function assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { +exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { +exports[`Invalid function assignment ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; @@ -641,16 +641,16 @@ exports[`Invalid function assignment ({"definition": "interface FuncPropInterfac exports[`Invalid function assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { noSelfMethod: function(s: string): string { return s; } };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -963,15 +963,15 @@ exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFunc exports[`Invalid function generic argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { +exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { +exports[`Invalid function generic argument ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; @@ -1033,16 +1033,16 @@ exports[`Invalid function generic argument ({"definition": "interface FuncPropIn exports[`Invalid function generic argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { noSelfMethod: function(s: string): string { return s; } };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function generic argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -1323,15 +1323,15 @@ exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedCl exports[`Invalid function return ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(5,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"definition": "class NoSelfMethodClass { +exports[`Invalid function return ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(8,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"definition": "class NoSelfMethodClass { +exports[`Invalid function return ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(8,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; @@ -1393,16 +1393,16 @@ exports[`Invalid function return ({"definition": "interface FuncPropInterface { exports[`Invalid function return ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { noSelfMethod: function(s: string): string { return s; } };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(10,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function return ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -1723,15 +1723,15 @@ exports[`Invalid function variable declaration ({"definition": "class NoSelfAnon exports[`Invalid function variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}): diagnostics 2`] = `"main.ts(4,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { +exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 1`] = `"main.ts(7,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { +exports[`Invalid function variable declaration ({"definition": "class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}): diagnostics 2`] = `"main.ts(7,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; @@ -1793,16 +1793,16 @@ exports[`Invalid function variable declaration ({"definition": "interface FuncPr exports[`Invalid function variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { noSelfMethod: function(s: string): string { return s; } };", "value": "noSelfMethodInterface.noSelfMethod"}): diagnostics 1`] = `"main.ts(9,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { - /** @noSelf */ +exports[`Invalid function variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -1901,3 +1901,1150 @@ exports[`Invalid interface method assignment: diagnostics 1`] = `"main.ts(5,22): exports[`Invalid lua lib function argument: diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'callbackfn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid method tuple assignment: diagnostics 1`] = `"main.ts(5,38): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(10,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(10,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(9,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(11,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(8,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(8,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(7,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(10,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(10,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(9,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(9,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(9,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(9,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method argument ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method argument ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(10,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(10,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(9,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(11,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(8,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(8,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(7,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(10,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(10,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(9,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(9,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(9,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(9,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(6,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method assignment ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(noSelfInFileFunc) as ((this: any, s: string) => string)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "<(this: any, s: string) => string>(noSelfInFileFunc)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}, "(selfFunc) as ((this: void, s: string) => string)", true): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'. +main.ts(4,24): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}, "<(this: void, s: string) => string>(selfFunc)", true): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'. +main.ts(4,24): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(voidFunc) as ((s: string) => string)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(voidFunc) as ((this: any, s: string) => string)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "<(s: string) => string>(voidFunc)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method assignment with cast ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "<(this: any, s: string) => string>(voidFunc)", false): diagnostics 1`] = ` +"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. +main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'." +`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } + namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class AnonFunctionNestedInNoSelfClass { + method() { return function(s: string) { return s; } } + } + const anonFunctionNestedInNoSelfClass = (new AnonFunctionNestedInNoSelfClass).method();", "value": "anonFunctionNestedInNoSelfClass"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(6,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfAnonMethodClassMergedNS { method(s: string): string { return s; } } + namespace NoSelfAnonMethodClassMergedNS { export function nsFunc(s: string) { return s; } } + const noSelfAnonMethodClassMergedNS = new NoSelfAnonMethodClassMergedNS();", "value": "noSelfAnonMethodClassMergedNS.method"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(4,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfFuncPropClass { noSelfFuncProp: (s: string) => string = s => s; } + const noSelfFuncPropClass = new NoSelfFuncPropClass();", "value": "noSelfFuncPropClass.noSelfFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(4,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(4,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfMethodClass { noSelfMethod(s: string): string { return s; } } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(4,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticFuncPropClass { + static noSelfStaticFuncProp: (s: string) => string = s => s; + }", "value": "NoSelfStaticFuncPropClass.noSelfStaticFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ class NoSelfStaticMethodClass { + static noSelfStaticMethod(s: string): string { return s; } + }", "value": "NoSelfStaticMethodClass.noSelfStaticMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ const NoSelfMethodClassExpression = class { + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClassExpression = new NoSelfMethodClassExpression();", "value": "noSelfMethodClassExpression.noSelfMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ interface NoSelfFuncPropInterface { noSelfFuncProp(s: string): string; } + const noSelfFuncPropInterface: NoSelfFuncPropInterface = { + noSelfFuncProp: (s: string): string => s + };", "value": "noSelfFuncPropInterface.noSelfFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ interface NoSelfMethodInterface { noSelfMethod(s: string): string; } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(9,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace AnonFunctionNestedInClassInNoSelfNs { + export class AnonFunctionNestedInClass { + method() { return function(s: string) { return s; } } + } + } + const anonFunctionNestedInClassInNoSelfNs = + (new AnonFunctionNestedInClassInNoSelfNs.AnonFunctionNestedInClass).method();", "value": "anonFunctionNestedInClassInNoSelfNs"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(9,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace AnonMethodClassInNoSelfNs { + export class MethodClass { + method(s: string): string { return s; } + } + } + const anonMethodClassInNoSelfNs = new AnonMethodClassInNoSelfNs.MethodClass();", "value": "anonMethodClassInNoSelfNs.method"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(8,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace AnonMethodInterfaceInNoSelfNs { + export interface MethodInterface { + method(s: string): string; + } + } + const anonMethodInterfaceInNoSelfNs: AnonMethodInterfaceInNoSelfNs.MethodInterface = { + method: function(s: string): string { return s; } + };", "value": "anonMethodInterfaceInNoSelfNs.method"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(10,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNestedNs { + export namespace NestedNs { export function noSelfNestedNsFunc(s: string) { return s; } } + }", "value": "NoSelfFuncNestedNs.NestedNs.noSelfNestedNsFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfFuncNs { export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNestedNs { + export namespace NestedNs { export let noSelfNestedNsLambda: (s: string) => string = s => s } + }", "value": "NoSelfLambdaNestedNs.NestedNs.noSelfNestedNsLambda"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelf */ namespace NoSelfLambdaNs { + export let noSelfNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfLambdaNs.noSelfNsLambda"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ class NoSelfInFileFuncNestedInClass { + method() { return function(s: string) { return s; } } + } + const noSelfInFileFuncNestedInClass = (new NoSelfInFileFuncNestedInClass).method();", "value": "noSelfInFileFuncNestedInClass"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ let noSelfInFileLambda: (s: string) => string = s => s;", "value": "noSelfInFileLambda"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileFuncNs { + export function noSelfInFileNsFunc(s: string) { return s; } + }", "value": "NoSelfInFileFuncNs.noSelfInFileNsFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "/** @noSelfInFile */ namespace NoSelfInFileLambdaNs { + export let noSelfInFileNsLambda: (s: string) => string = s => s; + }", "value": "NoSelfInFileLambdaNs.noSelfInFileNsLambda"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class AnonFuncPropClass { anonFuncProp: (s: string) => string = s => s; } + const anonFuncPropClass = new AnonFuncPropClass();", "value": "anonFuncPropClass.anonFuncProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class AnonMethodClass { anonMethod(s: string): string { return s; } } + const anonMethodClass = new AnonMethodClass();", "value": "anonMethodClass.anonMethod"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class AnonMethodClassMergedNoSelfNS { method(s: string): string { return s; } } + /** @noSelf */ namespace AnonMethodClassMergedNoSelfNS { export function nsFunc(s: string) { return s; } } + const anonMethodClassMergedNoSelfNS = new AnonMethodClassMergedNoSelfNS();", "value": "anonMethodClassMergedNoSelfNS.method"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class AnonStaticFuncPropClass { + static anonStaticFuncProp: (s: string) => string = s => s; + }", "value": "AnonStaticFuncPropClass.anonStaticFuncProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class AnonStaticMethodClass { static anonStaticMethod(s: string): string { return s; } }", "value": "AnonStaticMethodClass.anonStaticMethod"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class FuncPropClass { funcProp: (this: any, s: string) => string = s => s; } + const funcPropClass = new FuncPropClass();", "value": "funcPropClass.funcProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class MethodClass { method(this: any, s: string): string { return s; } } + const methodClass = new MethodClass();", "value": "methodClass.method"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(4,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class NoSelfAnonFuncNSMergedClass { method(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedClass { export function nsFunc(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedClass.nsFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(4,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(7,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class NoSelfMethodClass { + /** @noSelf */ + noSelfMethod(s: string): string { return s; } + } + const noSelfMethodClass = new NoSelfMethodClass();", "value": "noSelfMethodClass.noSelfMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(7,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticFuncPropClass { + static staticFuncProp: (this: any, s: string) => string = s => s; + }", "value": "StaticFuncPropClass.staticFuncProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticMethodClass { + static staticMethod(this: any, s: string): string { return s; } + }", "value": "StaticMethodClass.staticMethod"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticVoidFuncPropClass { + static staticVoidFuncProp: (this: void, s: string) => string = s => s; + }", "value": "StaticVoidFuncPropClass.staticVoidFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class StaticVoidMethodClass { + static staticVoidMethod(this: void, s: string): string { return s; } + }", "value": "StaticVoidMethodClass.staticVoidMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class VoidFuncPropClass { + voidFuncProp: (this: void, s: string) => string = s => s; + } + const voidFuncPropClass = new VoidFuncPropClass();", "value": "voidFuncPropClass.voidFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(6,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "class VoidMethodClass { + voidMethod(this: void, s: string): string { return s; } + } + const voidMethodClass = new VoidMethodClass();", "value": "voidMethodClass.voidMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(6,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface AnonFuncPropInterface { anonFuncProp: (s: string) => string; } + const anonFuncPropInterface: AnonFuncPropInterface = { anonFuncProp: (s: string): string => s };", "value": "anonFuncPropInterface.anonFuncProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface AnonMethodInterface { anonMethod(s: string): string; } + const anonMethodInterface: AnonMethodInterface = { + anonMethod: function(this: any, s: string): string { return s; } + };", "value": "anonMethodInterface.anonMethod"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(6,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface FuncPropInterface { funcProp: (this: any, s: string) => string; } + const funcPropInterface: FuncPropInterface = { funcProp: function(this: any, s: string) { return s; } };", "value": "funcPropInterface.funcProp"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface MethodInterface { method(this: any, s: string): string; } + const methodInterface: MethodInterface = { method: function(this: any, s: string): string { return s; } };", "value": "methodInterface.method"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(9,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface NoSelfMethodInterface { + /** @noSelf */ + noSelfMethod(s: string): string; + } + const noSelfMethodInterface: NoSelfMethodInterface = { + noSelfMethod: function(s: string): string { return s; } + };", "value": "noSelfMethodInterface.noSelfMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(9,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(8,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface VoidFuncPropInterface { + voidFuncProp: (this: void, s: string) => string; + } + const voidFuncPropInterface: VoidFuncPropInterface = { + voidFuncProp: function(this: void, s: string): string { return s; } + };", "value": "voidFuncPropInterface.voidFuncProp"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(8,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(8,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "interface VoidMethodInterface { + voidMethod(this: void, s: string): string; + } + const voidMethodInterface: VoidMethodInterface = { + voidMethod(this: void, s: string): string { return s; } + };", "value": "voidMethodInterface.voidMethod"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(8,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let anonFunc: {(s: string): string} = function(s) { return s; };", "value": "anonFunc"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let anonLambda: (s: string) => string = s => s;", "value": "anonLambda"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let selfFunc: {(this: any, s: string): string} = function(s) { return s; };", "value": "selfFunc"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let selfLambda: (this: any, s: string) => string = s => s;", "value": "selfLambda"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let voidFunc: {(this: void, s: string): string} = function(s) { return s; };", "value": "voidFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "let voidLambda: (this: void, s: string) => string = s => s;", "value": "voidLambda"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace FuncNestedNs { + export namespace NestedNs { export function nestedNsFunc(s: string) { return s; } } + }", "value": "FuncNestedNs.NestedNs.nestedNsFunc"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace FuncNs { export function nsFunc(s: string) { return s; } }", "value": "FuncNs.nsFunc"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace LambdaNestedNs { + export namespace NestedNs { export let nestedNsLambda: (s: string) => string = s => s } + }", "value": "LambdaNestedNs.NestedNs.nestedNsLambda"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace LambdaNs { + export let nsLambda: (s: string) => string = s => s; + }", "value": "LambdaNs.nsLambda"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(5,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(4,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace NoSelfAnonFuncNSMergedSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "NoSelfAnonFuncNSMergedSelfNS.nsFuncNoSelf"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(4,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(5,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace NoSelfFuncNs { + /** @noSelf */ + export function noSelfNsFunc(s: string) { return s; } }", "value": "NoSelfFuncNs.noSelfNsFunc"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(5,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } + /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; + +exports[`Invalid object with method variable declaration ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; + +exports[`Invalid object with method variable declaration ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index f95af8ab3..14e478498 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -221,9 +221,9 @@ export const noSelfTestFunctions: TestFunction[] = [ }, { value: "noSelfMethodClass.noSelfMethod", - definition: `class NoSelfMethodClass { + definition: `class NoSelfMethodClass { /** @noSelf */ - noSelfMethod(s: string): string { return s; } + noSelfMethod(s: string): string { return s; } } const noSelfMethodClass = new NoSelfMethodClass();`, }, @@ -271,8 +271,8 @@ export const noSelfTestFunctions: TestFunction[] = [ }, { value: "noSelfMethodInterface.noSelfMethod", - definition: `interface NoSelfMethodInterface { - /** @noSelf */ + definition: `interface NoSelfMethodInterface { + /** @noSelf */ noSelfMethod(s: string): string; } const noSelfMethodInterface: NoSelfMethodInterface = { @@ -377,18 +377,21 @@ type TestFunctionCast = [ /* castedFunction: */ string, /* isSelfConversion?: */ boolean? ]; -export const validTestFunctionCasts: TestFunctionCast[] = [ +export const validTestMethodCasts: TestFunctionCast[] = [ [selfTestFunctions[0], `<${anonTestFunctionType}>(${selfTestFunctions[0].value})`], [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${anonTestFunctionType})`], [selfTestFunctions[0], `<${selfTestFunctionType}>(${selfTestFunctions[0].value})`], [selfTestFunctions[0], `(${selfTestFunctions[0].value}) as (${selfTestFunctionType})`], [noSelfTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfTestFunctions[0].value})`], [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${noSelfTestFunctionType})`], - [noSelfInFileTestFunctions[0], `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], - [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`], [noSelfInFileTestFunctions[0], `<${noSelfTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${noSelfTestFunctionType})`], ]; +export const validTestFunctionCasts: TestFunctionCast[] = [ + ...validTestMethodCasts, + [noSelfInFileTestFunctions[0], `<${anonTestFunctionType}>(${noSelfInFileTestFunctions[0].value})`], + [noSelfInFileTestFunctions[0], `(${noSelfInFileTestFunctions[0].value}) as (${anonTestFunctionType})`], +]; export const invalidTestFunctionCasts: TestFunctionCast[] = [ [noSelfTestFunctions[0], `<${anonTestFunctionType}>(${noSelfTestFunctions[0].value})`, false], [noSelfTestFunctions[0], `(${noSelfTestFunctions[0].value}) as (${anonTestFunctionType})`, false], @@ -405,11 +408,10 @@ export type TestFunctionAssignment = [ /* functionType: */ string, /* isSelfConversion?: */ boolean? ]; -export const validTestFunctionAssignments: TestFunctionAssignment[] = [ +export const validTestMethodAssignments: TestFunctionAssignment[] = [ ...selfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), ...selfTestFunctions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), - ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), ...anonTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), @@ -418,6 +420,10 @@ export const validTestFunctionAssignments: TestFunctionAssignment[] = [ ...selfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType]), ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType]), ]; +export const validTestFunctionAssignments: TestFunctionAssignment[] = [ + ...validTestMethodAssignments, + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType]), +]; export const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ ...selfTestFunctions.map((f): TestFunctionAssignment => [f, noSelfTestFunctionType, false]), ...noSelfTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), @@ -427,3 +433,7 @@ export const invalidTestFunctionAssignments: TestFunctionAssignment[] = [ ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), ...noSelfTestFunctionExpressions.map((f): TestFunctionAssignment => [f, selfTestFunctionType, true]), ]; +export const invalidTestMethodAssignments: TestFunctionAssignment[] = [ + ...invalidTestFunctionAssignments, + ...noSelfInFileTestFunctions.map((f): TestFunctionAssignment => [f, anonTestFunctionType, true]), +]; diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index cd12b4ba8..caf3576a7 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -4,7 +4,11 @@ import { unsupportedSelfFunctionConversion, } from "../../../../src/transformation/utils/diagnostics"; import * as util from "../../../util"; -import { invalidTestFunctionAssignments, invalidTestFunctionCasts } from "./functionPermutations"; +import { + invalidTestFunctionAssignments, + invalidTestFunctionCasts, + invalidTestMethodAssignments, +} from "./functionPermutations"; test.each(invalidTestFunctionAssignments)( "Invalid function variable declaration (%p)", @@ -19,6 +23,19 @@ test.each(invalidTestFunctionAssignments)( } ); +test.each(invalidTestMethodAssignments)( + "Invalid object with method variable declaration (%p, %p)", + (testFunction, functionType, isSelfConversion) => { + util.testModule` + ${testFunction.definition ?? ""} + const obj: { fn: ${functionType} } = {fn: ${testFunction.value}}; + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); + } +); + test.each(invalidTestFunctionAssignments)( "Invalid function assignment (%p)", (testFunction, functionType, isSelfConversion) => { @@ -33,6 +50,20 @@ test.each(invalidTestFunctionAssignments)( } ); +test.each(invalidTestMethodAssignments)( + "Invalid object with method assignment (%p, %p, %p)", + (testFunction, functionType, isSelfConversion) => { + util.testModule` + ${testFunction.definition ?? ""} + let obj: { fn: ${functionType} }; + obj = {fn: ${testFunction.value}}; + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); + } +); + test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)", (testFunction, castedFunction) => { util.testModule` ${testFunction.definition ?? ""} @@ -44,6 +75,22 @@ test.each(invalidTestFunctionCasts)("Invalid function assignment with cast (%p)" ); }); +test.each(invalidTestFunctionCasts)( + "Invalid object with method assignment with cast (%p, %p, %p)", + (testFunction, castedFunction, isSelfConversion) => { + util.testModule` + ${testFunction.definition ?? ""} + let obj: { fn: typeof ${testFunction.value} }; + obj = {fn: ${castedFunction}}; + `.expectDiagnosticsToMatchSnapshot( + isSelfConversion + ? [unsupportedSelfFunctionConversion.code, unsupportedNoSelfFunctionConversion.code] + : [unsupportedNoSelfFunctionConversion.code, unsupportedSelfFunctionConversion.code], + true + ); + } +); + test.each(invalidTestFunctionAssignments)( "Invalid function argument (%p)", (testFunction, functionType, isSelfConversion) => { @@ -58,6 +105,20 @@ test.each(invalidTestFunctionAssignments)( } ); +test.each(invalidTestMethodAssignments)( + "Invalid object with method argument (%p, %p, %p)", + (testFunction, functionType, isSelfConversion) => { + util.testModule` + ${testFunction.definition ?? ""} + declare function takesObjectWithMethod(obj: { fn: ${functionType} }); + takesObjectWithMethod({fn: ${testFunction.value}}); + `.expectDiagnosticsToMatchSnapshot( + [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], + true + ); + } +); + test("Invalid lua lib function argument", () => { util.testModule` declare function foo(this: void, value: string): void; diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index d9613692d..8c98196d9 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -12,6 +12,8 @@ import { TestFunctionAssignment, validTestFunctionAssignments, validTestFunctionCasts, + validTestMethodAssignments, + validTestMethodCasts, } from "./functionPermutations"; test.each(validTestFunctionAssignments)("Valid function variable declaration (%p)", (testFunction, functionType) => { @@ -23,6 +25,15 @@ test.each(validTestFunctionAssignments)("Valid function variable declaration (%p .expectToMatchJsResult(); }); +test.each(validTestMethodAssignments)("Valid object wit method declaration (%p, %p)", (testFunction, functionType) => { + util.testFunction` + const obj: { fn: ${functionType} } = {fn: ${testFunction.value}}; + return obj.fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); +}); + test.each(validTestFunctionAssignments)("Valid function assignment (%p)", (testFunction, functionType) => { util.testFunction` let fn: ${functionType}; @@ -43,6 +54,19 @@ test.each(validTestFunctionCasts)("Valid function assignment with cast (%p)", (t .expectToMatchJsResult(); }); +test.each(validTestMethodCasts)( + "Valid object with method assignment with cast (%p, %p)", + (testFunction, castedFunction) => { + util.testFunction` + let obj: { fn: typeof ${testFunction.value} }; + obj = {fn: ${castedFunction}}; + return obj.fn("foobar"); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); + } +); + test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFunction, functionType) => { util.testFunction` function takesFunction(fn: ${functionType}) { @@ -54,6 +78,17 @@ test.each(validTestFunctionAssignments)("Valid function argument (%p)", (testFun .expectToMatchJsResult(); }); +test.each(validTestMethodAssignments)("Valid object with method argument (%p, %p)", (testFunction, functionType) => { + util.testFunction` + function takesObjectWithMethod(obj: { fn: ${functionType} }) { + return obj.fn("foobar"); + } + return takesObjectWithMethod({fn: ${testFunction.value}}); + ` + .setTsHeader(testFunction.definition ?? "") + .expectToMatchJsResult(); +}); + test("Valid lua lib function argument", () => { util.testFunction` let result = ""; From 0bfdaf5c267371dc00f68cab3f03e7adccb77241 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 14 Sep 2021 18:09:30 +0200 Subject: [PATCH 405/764] Upgrade TypeScript to 4.4 (#1138) * Upgrade TypeScript to 4.4 * Add back direct dependency to ts * Add assert to test runner * Removed unused import * fix assert issue again --- .eslintrc.js | 2 + package-lock.json | 968 +++++------------- package.json | 17 +- src/lualib/Symbol.ts | 2 +- src/transpilation/utils.ts | 6 +- test/unit/builtins/numbers.spec.ts | 2 + test/unit/error.spec.ts | 2 + .../invalidFunctionAssignments.spec.ts.snap | 7 +- test/unit/loops.spec.ts | 8 +- test/util.ts | 2 + 10 files changed, 291 insertions(+), 725 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index a32cc13f7..78be76c72 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -68,7 +68,9 @@ module.exports = { "jest/expect-expect": "off", "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], + "jest/no-disabled-tests": "error", "jest/no-expect-resolves": "error", + "jest/no-identical-title": "off", "jest/no-test-return-statement": "error", "jest/no-truthy-falsy": "error", "jest/prefer-spy-on": "error", diff --git a/package-lock.json b/package-lock.json index 6f493d557..7e26dac46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,7 @@ "dependencies": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "^4.3.5" + "source-map": "^0.7.3" }, "bin": { "tstl": "dist/tstl.js" @@ -23,11 +22,11 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^4.26.1", - "@typescript-eslint/parser": "^4.26.1", - "eslint": "^7.28.0", - "eslint-plugin-import": "^2.20.1", - "eslint-plugin-jest": "^23.8.2", + "@typescript-eslint/eslint-plugin": "^4.31.0", + "@typescript-eslint/parser": "^4.31.0", + "eslint": "^7.32.0", + "eslint-plugin-import": "^2.24.2", + "eslint-plugin-jest": "^24.4.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", @@ -36,10 +35,13 @@ "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^26.3.0", - "ts-node": "^8.6.2" + "ts-node": "^10.2.1" }, "engines": { "node": ">=12.13.0" + }, + "peerDependencies": { + "typescript": "~4.4.3" } }, "node_modules/@babel/code-frame": { @@ -694,8 +696,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", "dev": true, - "optional": true, - "peer": true, "engines": { "node": ">= 12" } @@ -705,8 +705,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", "dev": true, - "optional": true, - "peer": true, "dependencies": { "@cspotcode/source-map-consumer": "0.8.0" }, @@ -914,31 +912,6 @@ "node": ">= 10.14.2" } }, - "node_modules/@jest/core/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/@jest/core/node_modules/acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/@jest/core/node_modules/jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -1006,52 +979,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/@jest/core/node_modules/ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/@jest/environment": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", @@ -1562,33 +1489,25 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/@types/babel__core": { "version": "7.1.15", @@ -1699,6 +1618,12 @@ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -1754,13 +1679,13 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", - "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.0.tgz", + "integrity": "sha512-iPKZTZNavAlOhfF4gymiSuUkgLne/nh5Oz2/mdiUmuZVD42m9PapnCnzjxuDsnpnbH3wT5s2D8bw6S39TC6GNw==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.29.2", - "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/experimental-utils": "4.31.0", + "@typescript-eslint/scope-manager": "4.31.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -1785,15 +1710,15 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", - "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.0.tgz", + "integrity": "sha512-Hld+EQiKLMppgKKkdUsLeVIeEOrwKc2G983NmznY/r5/ZtZCDvIOXnXtwqJIgYz/ymsy7n7RGvMyrzf1WaSQrw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.29.2", - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/typescript-estree": "4.29.2", + "@typescript-eslint/scope-manager": "4.31.0", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/typescript-estree": "4.31.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -1809,14 +1734,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", - "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz", + "integrity": "sha512-oWbzvPh5amMuTmKaf1wp0ySxPt2ZXHnFQBN2Szu1O//7LmOvgaKTCIDNLK2NvzpmVd5A2M/1j/rujBqO37hj3w==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.29.2", - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/typescript-estree": "4.29.2", + "@typescript-eslint/scope-manager": "4.31.0", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/typescript-estree": "4.31.0", "debug": "^4.3.1" }, "engines": { @@ -1836,13 +1761,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", - "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.0.tgz", + "integrity": "sha512-LJ+xtl34W76JMRLjbaQorhR0hfRAlp3Lscdiz9NeI/8i+q0hdBZ7BsiYieLoYWqy+AnRigaD3hUwPFugSzdocg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/visitor-keys": "4.29.2" + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/visitor-keys": "4.31.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1853,9 +1778,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", - "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.0.tgz", + "integrity": "sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1866,13 +1791,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", - "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz", + "integrity": "sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/visitor-keys": "4.29.2", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/visitor-keys": "4.31.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -1893,12 +1818,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", - "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz", + "integrity": "sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/types": "4.31.0", "eslint-visitor-keys": "^2.0.0" }, "engines": { @@ -2787,9 +2712,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -3353,9 +3276,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", - "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "dependencies": { "array-includes": "^3.1.3", @@ -3372,7 +3295,7 @@ "pkg-up": "^2.0.0", "read-pkg-up": "^3.0.0", "resolve": "^1.20.0", - "tsconfig-paths": "^3.10.1" + "tsconfig-paths": "^3.11.0" }, "engines": { "node": ">=4" @@ -3409,93 +3332,26 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "23.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", - "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", + "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^2.5.0" + "@typescript-eslint/experimental-utils": "^4.0.1" }, "engines": { - "node": ">=8" + "node": ">=10" }, "peerDependencies": { + "@typescript-eslint/eslint-plugin": ">= 4", "eslint": ">=5" - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/eslint-plugin-jest/node_modules/@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { - "typescript": { + "@typescript-eslint/eslint-plugin": { "optional": true } } }, - "node_modules/eslint-plugin-jest/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/eslint-plugin-jest/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5785,31 +5641,6 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-cli/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jest-cli/node_modules/acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jest-cli/node_modules/jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -5877,52 +5708,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-cli/node_modules/ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/jest-config": { "version": "25.5.4", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", @@ -7787,31 +7572,6 @@ "node": ">= 10.14.2" } }, - "node_modules/jest-runner/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jest-runner/node_modules/acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jest-runner/node_modules/jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -7892,52 +7652,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-runner/node_modules/ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/jest-runtime": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", @@ -8002,38 +7716,13 @@ "dependencies": { "@jest/types": "^26.6.2", "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runtime/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/jest-runtime/node_modules/acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true, + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, "engines": { - "node": ">=0.4.0" + "node": ">= 10.14.2" } }, "node_modules/jest-runtime/node_modules/jest-config": { @@ -8116,52 +7805,6 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-runtime/node_modules/ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "dependencies": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, "node_modules/jest-serializer": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", @@ -11180,41 +10823,94 @@ } }, "node_modules/ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, "dependencies": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" }, "engines": { - "node": ">=6.0.0" + "node": ">=12.0.0" }, "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" } }, "node_modules/tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "dependencies": { - "json5": "^2.2.0", + "@types/json5": "^0.0.29", + "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" } }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -11306,9 +11002,11 @@ } }, "node_modules/typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11334,6 +11032,20 @@ "node": ">=12.13.0" } }, + "node_modules/typescript-to-lua/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", @@ -12325,17 +12037,13 @@ "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@cspotcode/source-map-support": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", "dev": true, - "optional": true, - "peer": true, "requires": { "@cspotcode/source-map-consumer": "0.8.0" } @@ -12500,22 +12208,6 @@ "strip-ansi": "^6.0.0" }, "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true - }, - "acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -12565,28 +12257,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - } } } }, @@ -13017,33 +12687,25 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@tsconfig/node12": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@tsconfig/node14": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@tsconfig/node16": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "@types/babel__core": { "version": "7.1.15", @@ -13154,6 +12816,12 @@ "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -13209,13 +12877,13 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz", - "integrity": "sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.0.tgz", + "integrity": "sha512-iPKZTZNavAlOhfF4gymiSuUkgLne/nh5Oz2/mdiUmuZVD42m9PapnCnzjxuDsnpnbH3wT5s2D8bw6S39TC6GNw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.29.2", - "@typescript-eslint/scope-manager": "4.29.2", + "@typescript-eslint/experimental-utils": "4.31.0", + "@typescript-eslint/scope-manager": "4.31.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.1.0", @@ -13224,55 +12892,55 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz", - "integrity": "sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.0.tgz", + "integrity": "sha512-Hld+EQiKLMppgKKkdUsLeVIeEOrwKc2G983NmznY/r5/ZtZCDvIOXnXtwqJIgYz/ymsy7n7RGvMyrzf1WaSQrw==", "dev": true, "requires": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.29.2", - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/typescript-estree": "4.29.2", + "@typescript-eslint/scope-manager": "4.31.0", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/typescript-estree": "4.31.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/parser": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.29.2.tgz", - "integrity": "sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz", + "integrity": "sha512-oWbzvPh5amMuTmKaf1wp0ySxPt2ZXHnFQBN2Szu1O//7LmOvgaKTCIDNLK2NvzpmVd5A2M/1j/rujBqO37hj3w==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.29.2", - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/typescript-estree": "4.29.2", + "@typescript-eslint/scope-manager": "4.31.0", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/typescript-estree": "4.31.0", "debug": "^4.3.1" } }, "@typescript-eslint/scope-manager": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz", - "integrity": "sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.0.tgz", + "integrity": "sha512-LJ+xtl34W76JMRLjbaQorhR0hfRAlp3Lscdiz9NeI/8i+q0hdBZ7BsiYieLoYWqy+AnRigaD3hUwPFugSzdocg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/visitor-keys": "4.29.2" + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/visitor-keys": "4.31.0" } }, "@typescript-eslint/types": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.29.2.tgz", - "integrity": "sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.0.tgz", + "integrity": "sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz", - "integrity": "sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz", + "integrity": "sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.2", - "@typescript-eslint/visitor-keys": "4.29.2", + "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/visitor-keys": "4.31.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -13281,12 +12949,12 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "4.29.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz", - "integrity": "sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag==", + "version": "4.31.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz", + "integrity": "sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.29.2", + "@typescript-eslint/types": "4.31.0", "eslint-visitor-keys": "^2.0.0" } }, @@ -13979,9 +13647,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "optional": true, - "peer": true + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -14443,9 +14109,9 @@ } }, "eslint-plugin-import": { - "version": "2.24.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz", - "integrity": "sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ==", + "version": "2.24.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", + "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", "dev": true, "requires": { "array-includes": "^3.1.3", @@ -14462,7 +14128,7 @@ "pkg-up": "^2.0.0", "read-pkg-up": "^3.0.0", "resolve": "^1.20.0", - "tsconfig-paths": "^3.10.1" + "tsconfig-paths": "^3.11.0" }, "dependencies": { "debug": { @@ -14492,56 +14158,12 @@ } }, "eslint-plugin-jest": { - "version": "23.20.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-23.20.0.tgz", - "integrity": "sha512-+6BGQt85OREevBDWCvhqj1yYA4+BFK4XnRZSGJionuEYmcglMZYLNNBBemwzbqUAckURaHdJSBcjHPyrtypZOw==", + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", + "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "^2.5.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.34.0.tgz", - "integrity": "sha512-eS6FTkq+wuMJ+sgtuNTtcqavWXqsflWcfBnlYhg/nS4aZ1leewkXGbvBhaapn1q6qf4M71bsR1tez5JTRMuqwA==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.34.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^2.0.0" - } - }, - "@typescript-eslint/typescript-estree": { - "version": "2.34.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.34.0.tgz", - "integrity": "sha512-OMAr+nJWKdlVM9LOqCqh3pQQPwxHAN7Du8DR6dmwCrAmxtiXQnhHJ6tBNtf+cggqfo51SG/FCwnKhXCIM7hnVg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "eslint-visitor-keys": "^1.1.0", - "glob": "^7.1.6", - "is-glob": "^4.0.1", - "lodash": "^4.17.15", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "@typescript-eslint/experimental-utils": "^4.0.1" } }, "eslint-scope": { @@ -16277,22 +15899,6 @@ "yargs": "^15.4.1" }, "dependencies": { - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true - }, - "acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -16342,28 +15948,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - } } } }, @@ -17874,22 +17458,6 @@ "jest-util": "^26.6.2" } }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true - }, - "acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -17949,28 +17517,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - } } } }, @@ -18035,22 +17581,6 @@ "jest-util": "^26.6.2" } }, - "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", - "dev": true, - "optional": true, - "peer": true - }, - "acorn-walk": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz", - "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==", - "dev": true, - "optional": true, - "peer": true - }, "jest-config": { "version": "26.6.3", "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", @@ -18110,28 +17640,6 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - } } } }, @@ -20503,29 +20011,60 @@ } }, "ts-node": { - "version": "8.10.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", - "integrity": "sha512-ISJJGgkIpDdBhWVu3jufsWpK3Rzo7bdiIXJjQc0ynKxVOVcg2oIrf2H2cejminGrptVc6q6/uynAHNCuWGbpVA==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", + "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", "dev": true, "requires": { + "@cspotcode/source-map-support": "0.6.1", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", - "source-map-support": "^0.5.17", "yn": "3.1.1" + }, + "dependencies": { + "acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", + "dev": true + }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + } } }, "tsconfig-paths": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz", - "integrity": "sha512-rETidPDgCpltxF7MjBZlAFPUHv5aHH2MymyPvh+vEyWAED4Eb/WeMbsnD/JDr4OKPOA1TssDHgIcpTN5Kh0p6Q==", + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "requires": { - "json5": "^2.2.0", + "@types/json5": "^0.0.29", + "json5": "^1.0.1", "minimist": "^1.2.0", "strip-bom": "^3.0.0" }, "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -20595,9 +20134,10 @@ } }, "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==" + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", + "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", + "peer": true }, "typescript-to-lua": { "version": "0.39.6", @@ -20608,6 +20148,14 @@ "resolve": "^1.15.1", "source-map": "^0.7.3", "typescript": "~4.3.2" + }, + "dependencies": { + "typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", + "dev": true + } } }, "unbox-primitive": { diff --git a/package.json b/package.json index eb4002ba1..da92f606d 100644 --- a/package.json +++ b/package.json @@ -41,11 +41,14 @@ "engines": { "node": ">=12.13.0" }, + "peerDependencies": { + "typescript": "~4.4.3" + }, "dependencies": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3", - "typescript": "~4.3.5" + "typescript": "~4.4.3" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -53,11 +56,11 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^4.26.1", - "@typescript-eslint/parser": "^4.26.1", - "eslint": "^7.28.0", - "eslint-plugin-import": "^2.20.1", - "eslint-plugin-jest": "^23.8.2", + "@typescript-eslint/eslint-plugin": "^4.31.0", + "@typescript-eslint/parser": "^4.31.0", + "eslint": "^7.32.0", + "eslint-plugin-import": "^2.24.2", + "eslint-plugin-jest": "^24.4.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^26.0.1", @@ -66,6 +69,6 @@ "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^26.3.0", - "ts-node": "^8.6.2" + "ts-node": "^10.2.1" } } diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 41be3fc28..67a1fd71b 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -5,7 +5,7 @@ const ____symbolMetatable = { }; function __TS__Symbol(this: void, description?: string | number): symbol { - return setmetatable({ description }, ____symbolMetatable) as symbol; + return setmetatable({ description }, ____symbolMetatable) as unknown as symbol; } Symbol = { diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 4b0a9c24f..9ac888a9e 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -46,11 +46,13 @@ export function resolvePlugin( return { error: cliDiagnostics.compilerOptionRequiresAValueOfType(optionName, "string") }; } + const isModuleNotFoundError = (error: any) => error.code === "MODULE_NOT_FOUND"; + let resolved: string; try { resolved = resolve.sync(query, { basedir, extensions: [".js", ".ts", ".tsx"] }); } catch (err) { - if (err.code !== "MODULE_NOT_FOUND") throw err; + if (!isModuleNotFoundError(err)) throw err; return { error: diagnosticFactories.couldNotResolveFrom(kind, query, basedir) }; } @@ -61,7 +63,7 @@ export function resolvePlugin( const tsNode: typeof import("ts-node") = require(tsNodePath); tsNode.register({ transpileOnly: true }); } catch (err) { - if (err.code !== "MODULE_NOT_FOUND") throw err; + if (!isModuleNotFoundError(err)) throw err; return { error: diagnosticFactories.toLoadItShouldBeTranspiled(kind, query) }; } } diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index f58209c31..ad9ae0c79 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -22,6 +22,8 @@ test.each([ util.testExpression(code).expectToMatchJsResult(); }); +// Current implementation does not allow this +// eslint-disable-next-line jest/no-disabled-tests test.skip.each(["NaN", "Infinity"])("%s reassignment", name => { util.testFunction` const ${name} = 1; diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 0c24503f0..705ee77f0 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -6,6 +6,8 @@ test("throwString", () => { `.expectToEqual(new util.ExecutionError("Some Error")); }); +// TODO: Finally does not behave like it should, see #1137 +// eslint-disable-next-line jest/no-disabled-tests test.skip.each([0, 1, 2])("re-throw (%p)", i => { util.testFunction` const i: number = ${i}; diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index ad66dfec4..b7175df75 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -1538,9 +1538,10 @@ main.ts(4,24): error TSTL: Unable to convert function with no 'this' parameter t exports[`Invalid function tuple assignment: diagnostics 1`] = ` "main.ts(5,13): error TS2322: Type '[number, Meth]' is not assignable to type '[number, Func]'. - Type 'Meth' is not assignable to type 'Func'. - The 'this' types of each signature are incompatible. - Type 'void' is not assignable to type '{}'. + Type at position 1 in source is not compatible with type at position 1 in target. + Type 'Meth' is not assignable to type 'Func'. + The 'this' types of each signature are incompatible. + Type 'void' is not assignable to type '{}'. main.ts(5,38): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'." `; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index a3d4db239..cdb0c3e71 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -467,8 +467,12 @@ describe("for...of empty destructuring", () => { }); }; - describe("declaration", () => declareTests("const ")); - describe("assignment", () => declareTests("")); + describe("declaration", () => { + declareTests("const "); + }); + describe("assignment", () => { + declareTests(""); + }); }); for (const testCase of [ diff --git a/test/util.ts b/test/util.ts index 532ba944f..7752496a6 100644 --- a/test/util.ts +++ b/test/util.ts @@ -491,6 +491,8 @@ end)());`; try { result = vm.runInContext(this.getJsCodeWithWrapper(), globalContext); } catch (error) { + const hasMessage = (error: any): error is { message: string } => error.message !== undefined; + assert(hasMessage(error)); return new ExecutionError(error.message); } From ae762b6dbb276aeb73aa39ff8430bc3a3012707e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 20 Sep 2021 13:46:39 +0200 Subject: [PATCH 406/764] Add noResolvePaths option (#1139) --- src/CompilerOptions.ts | 7 ++-- src/transpilation/resolve.ts | 12 +++++- test/transpile/module-resolution.spec.ts | 47 ++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 9fc232f68..952de19ef 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -23,15 +23,16 @@ export interface LuaPluginImport { export type CompilerOptions = OmitIndexSignature & { buildMode?: BuildMode; - noImplicitSelf?: boolean; - noHeader?: boolean; luaBundle?: string; luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; - sourceMapTraceback?: boolean; luaPlugins?: LuaPluginImport[]; + noImplicitSelf?: boolean; + noHeader?: boolean; + noResolvePaths?: string[]; plugins?: Array; + sourceMapTraceback?: boolean; tstlVerbose?: boolean; [option: string]: any; }; diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 69895391b..bfdf44b06 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -23,14 +23,24 @@ interface ResolutionResult { class ResolutionContext { private resultsCache = new Map(); + private noResolvePaths: Set; constructor( public readonly program: ts.Program, public readonly options: CompilerOptions, private readonly emitHost: EmitHost - ) {} + ) { + this.noResolvePaths = new Set(options.noResolvePaths); + } public resolve(file: ProcessedFile, required: string): ResolutionResult { + if (this.noResolvePaths.has(required)) { + if (this.options.tstlVerbose) { + console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`); + } + return { resolvedFiles: [], diagnostics: [] }; + } + const resolvedDependency = resolveDependency(file, required, this.program, this.emitHost); if (resolvedDependency) { if (this.options.tstlVerbose) { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 0332d8c58..75d025218 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -330,6 +330,53 @@ test("module resolution should not try to resolve @noResolution annotation", () .expectToHaveNoDiagnostics(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1101 +test("module resolution inline require of environment library workaround", () => { + util.testModule` + declare function require(this: void, module: string): any; + + const test = require("@NoResolution:luasource"); + test.foo(); + `.expectToHaveNoDiagnostics(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1118 +describe("module resolution should not try to resolve modules in noResolvePaths", () => { + test("as used in direct import", () => { + util.testModule` + import * as lua from "directimport"; + lua.foo(); + ` + .addExtraFile( + "directimport.d.ts", + `declare module "directimport" { + export function foo(): void; + }` + ) + .setOptions({ noResolvePaths: ["directimport"] }) + .expectToHaveNoDiagnostics(); + }); + + test("as used in imported lua sources", () => { + util.testModule` + import * as lua from "./luasource"; + lua.foo(); + ` + .addExtraFile("luasource.d.ts", "export function foo(): void;") + .addExtraFile( + "luasource.lua", + ` + require("dontResolveThis") + require("a.b.c.foo") + + return { foo = function() return "bar" end } + ` + ) + .setOptions({ noResolvePaths: ["a.b.c.foo", "somethingExtra", "dontResolveThis"] }) + .expectToHaveNoDiagnostics(); + }); +}); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 test("module resolution should not rewrite @NoResolution requires in library mode", () => { const { transpiledFiles } = util.testModule` From 1f9be79174f0c3d5743feb9f00333a3c0b9fb3cf Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 27 Sep 2021 12:46:59 +0200 Subject: [PATCH 407/764] Made source file paths in sourcemaps relative again (#1140) * Sourcemap source files are relative to project root * Updated unit test * use getEmitPathRelativeToOutDir * Updated unclear require diagnostic * updated diagnostic snapshot * Change sourcenode paths to relative * fixed once and for all (hopefully) * fix weird auto-import * Make sourcemap file property only the file name, not the entire path --- src/LuaPrinter.ts | 23 +++++++++++------- src/transpilation/diagnostics.ts | 2 +- .../__snapshots__/resolution.spec.ts.snap | 2 +- test/unit/printer/sourcemaps.spec.ts | 24 +++++++++++++------ 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 65c33b88a..4bfe53f5c 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,11 +1,13 @@ +import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; +import { getEmitPath } from "."; import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; -import { intersperse, trimExtension } from "./utils"; +import { intersperse, normalizeSlashes } from "./utils"; // https://www.lua.org/pil/2.4.html // https://www.ecma-international.org/ecma-262/10.0/index.html#table-34 @@ -120,14 +122,17 @@ export class LuaPrinter { }; private currentIndent = ""; - private sourceFile: string; + private luaFile: string; + private relativeSourcePath: string; private options: CompilerOptions; public static readonly sourceMapTracebackPlaceholder = "{#SourceMapTraceback}"; - constructor(private emitHost: EmitHost, program: ts.Program, fileName: string) { + constructor(private emitHost: EmitHost, private program: ts.Program, private sourceFile: string) { this.options = program.getCompilerOptions(); - this.sourceFile = fileName; + this.luaFile = normalizeSlashes(getEmitPath(this.sourceFile, this.program)); + // Source nodes contain relative path from mapped lua file to original TS source file + this.relativeSourcePath = normalizeSlashes(path.relative(path.dirname(this.luaFile), this.sourceFile)); } public print(file: lua.File): PrintResult { @@ -230,12 +235,12 @@ export class LuaPrinter { const { line, column } = lua.getOriginalPos(node); return line !== undefined && column !== undefined - ? new SourceNode(line + 1, column, this.sourceFile, chunks, name) - : new SourceNode(null, null, this.sourceFile, chunks, name); + ? new SourceNode(line + 1, column, this.relativeSourcePath, chunks, name) + : new SourceNode(null, null, this.relativeSourcePath, chunks, name); } protected concatNodes(...chunks: SourceChunk[]): SourceNode { - return new SourceNode(null, null, this.sourceFile, chunks); + return new SourceNode(null, null, this.relativeSourcePath, chunks); } protected printBlock(block: lua.Block): SourceNode { @@ -757,7 +762,7 @@ export class LuaPrinter { } public printOperator(kind: lua.Operator): SourceNode { - return new SourceNode(null, null, this.sourceFile, LuaPrinter.operatorMap[kind]); + return new SourceNode(null, null, this.relativeSourcePath, LuaPrinter.operatorMap[kind]); } protected joinChunksWithComma(chunks: SourceChunk[]): SourceChunk[] { @@ -787,7 +792,7 @@ export class LuaPrinter { // will not generate 'empty' mappings in the source map that point to nothing in the original TS. private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator { const map = new SourceMapGenerator({ - file: trimExtension(this.sourceFile) + ".lua", + file: path.basename(this.luaFile), sourceRoot, }); diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 098d78740..0aa772cd3 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -8,7 +8,7 @@ const createDiagnosticFactory = ( export const couldNotResolveRequire = createDiagnosticFactory( (requirePath: string, containingFile: string) => - `Could not resolve require path '${requirePath}' in file ${containingFile}.` + `Could not resolve lua source files for require path '${requirePath}' in file ${containingFile}.` ); export const couldNotReadDependency = createDiagnosticFactory( diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index 4db74c57f..a250dbd46 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -7,4 +7,4 @@ local ____ = module return ____exports" `; -exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve require path '../module' in file main.ts."`; +exports[`doesn't resolve paths out of root dir: diagnostics 1`] = `"error TSTL: Could not resolve lua source files for require path '../module' in file main.ts."`; diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 6c5857120..fdc21a13a 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -163,25 +163,35 @@ test.each([ }); test.each([ - { fileName: "/proj/foo.ts", config: {} }, + { + fileName: "/proj/foo.ts", + config: {}, + expectedSourcePath: "foo.ts", // ts and lua will be emitted to same directory + }, { fileName: "/proj/src/foo.ts", - config: { outDir: "/proj/dst" }, + config: { + outDir: "/proj/dst", + }, + expectedSourcePath: "../src/foo.ts", // path from proj/dst outDir to proj/src/foo.ts }, { fileName: "/proj/src/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + expectedSourcePath: "../src/foo.ts", // path from proj/dst outDir to proj/src/foo.ts }, { fileName: "/proj/src/sub/foo.ts", config: { rootDir: "/proj/src", outDir: "/proj/dst" }, + expectedSourcePath: "../../src/sub/foo.ts", // path from proj/dst/sub outDir to proj/src/sub/foo.ts }, { fileName: "/proj/src/sub/main.ts", - config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin" }, - fullSource: "bin/proj/src/sub/main.ts", + config: { rootDir: "/proj/src", outDir: "/proj/dst", sourceRoot: "bin/binsub/binsubsub" }, + expectedSourcePath: "../../src/sub/main.ts", // path from proj/dst/sub outDir to proj/src/sub/foo.ts + fullSource: "bin/src/sub/main.ts", }, -])("Source map has correct sources (%p)", async ({ fileName, config, fullSource }) => { +])("Source map has correct sources (%p)", async ({ fileName, config, fullSource, expectedSourcePath }) => { const file = util.testModule` const foo = "foo" ` @@ -191,11 +201,11 @@ test.each([ const sourceMap = JSON.parse(file.luaSourceMap); expect(sourceMap.sources).toHaveLength(1); - expect(sourceMap.sources[0]).toBe(fileName); + expect(sourceMap.sources[0]).toBe(expectedSourcePath); const consumer = await new SourceMapConsumer(file.luaSourceMap); expect(consumer.sources).toHaveLength(1); - expect(consumer.sources[0]).toBe(fullSource ?? fileName); + expect(consumer.sources[0]).toBe(fullSource ?? expectedSourcePath); }); test.each([ From a38a86b256374c9db774cb258d2329d3beed45c8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 19 Oct 2021 17:45:15 +0200 Subject: [PATCH 408/764] Fix ts crash and upgrade dependencies (#1147) * Fix ts crash and upgrade dependencies * add TS as dev dependency and fix eslint --- .eslintrc.js | 7 +- language-extensions/tsconfig.json | 7 + package-lock.json | 19860 ++++++++-------------------- package.json | 14 +- src/lualib/tsconfig.json | 2 +- 5 files changed, 5606 insertions(+), 14284 deletions(-) create mode 100644 language-extensions/tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index 78be76c72..27bc25da8 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -2,7 +2,12 @@ module.exports = { extends: ["plugin:jest/recommended", "plugin:jest/style"], parserOptions: { sourceType: "module", - project: ["test/tsconfig.json", "src/lualib/tsconfig.json", "benchmark/tsconfig.json"], + project: [ + "test/tsconfig.json", + "src/lualib/tsconfig.json", + "benchmark/tsconfig.json", + "language-extensions/tsconfig.json", + ], }, env: { es6: true, node: true }, plugins: ["import"], diff --git a/language-extensions/tsconfig.json b/language-extensions/tsconfig.json new file mode 100644 index 000000000..92894f9c4 --- /dev/null +++ b/language-extensions/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "esnext", + "lib": ["esnext"], + "strict": true + } +} diff --git a/package-lock.json b/package-lock.json index 7e26dac46..e885ae74e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,19 +29,20 @@ "eslint-plugin-jest": "^24.4.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^26.0.1", - "jest-circus": "^25.1.0", + "jest": "^27.3.0", + "jest-circus": "^27.3.0", "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^26.3.0", - "ts-node": "^10.2.1" + "ts-jest": "^27.0.7", + "ts-node": "^10.3.0", + "typescript": "~4.4.4" }, "engines": { "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.4.3" + "typescript": "~4.4.4" } }, "node_modules/@babel/code-frame": { @@ -63,20 +64,20 @@ } }, "node_modules/@babel/core": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", - "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.0", - "@babel/helper-module-transforms": "^7.15.0", - "@babel/helpers": "^7.14.8", - "@babel/parser": "^7.15.0", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -93,9 +94,9 @@ } }, "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "dependencies": { "@babel/highlight": "^7.14.5" @@ -123,12 +124,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", - "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, "dependencies": { - "@babel/types": "^7.15.0", + "@babel/types": "^7.15.6", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -146,9 +147,9 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", - "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, "dependencies": { "@babel/compat-data": "^7.15.0", @@ -173,93 +174,93 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, "dependencies": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", - "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.0" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", - "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, "dependencies": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-simple-access": "^7.14.8", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" @@ -275,48 +276,48 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", - "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", - "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, "dependencies": { - "@babel/types": "^7.14.8" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -332,14 +333,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", - "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, "dependencies": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" @@ -431,9 +432,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", - "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -589,24 +590,39 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { + "node_modules/@babel/plugin-syntax-typescript": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "dependencies": { "@babel/highlight": "^7.14.5" @@ -616,18 +632,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", - "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.15.0", - "@babel/types": "^7.15.0", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -636,9 +652,9 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "dependencies": { "@babel/highlight": "^7.14.5" @@ -657,9 +673,9 @@ } }, "node_modules/@babel/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", - "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", "dev": true, "dependencies": { "@babel/helper-validator-identifier": "^7.14.9", @@ -675,22 +691,6 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "dependencies": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "bin": { - "watch": "cli.js" - }, - "engines": { - "node": ">=0.1.95" - } - }, "node_modules/@cspotcode/source-map-consumer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", @@ -701,9 +701,9 @@ } }, "node_modules/@cspotcode/source-map-support": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", - "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "dev": true, "dependencies": { "@cspotcode/source-map-consumer": "0.8.0" @@ -732,6 +732,15 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", @@ -857,632 +866,332 @@ } }, "node_modules/@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", + "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.2.5", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", + "jest-message-util": "^27.3.0", + "jest-util": "^27.3.0", "slash": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", + "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", "dev": true, "dependencies": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/console": "^27.3.0", + "@jest/reporters": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", + "emittery": "^0.8.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", + "jest-changed-files": "^27.3.0", + "jest-config": "^27.3.0", + "jest-haste-map": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-resolve-dependencies": "^27.3.0", + "jest-runner": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "jest-watcher": "^27.3.0", + "micromatch": "^4.0.4", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { - "ts-node": ">=9.0.0" + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "peerDependenciesMeta": { - "ts-node": { + "node-notifier": { "optional": true } } }, - "node_modules/@jest/core/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/@jest/environment": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", + "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/core/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/@jest/environment": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", - "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", + "node_modules/@jest/fake-timers": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", + "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", "dev": true, "dependencies": { - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0" + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.3.0", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/@jest/globals": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", + "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@jest/environment": "^27.3.0", + "@jest/types": "^27.2.5", + "expect": "^27.3.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/environment/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@jest/environment/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/@jest/reporters": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", + "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@jest/fake-timers": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", - "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", + "node_modules/@jest/reporters/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "lolex": "^5.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=0.10.0" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "node_modules/@jest/source-map/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/@jest/fake-timers/node_modules/@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "node_modules/@jest/fake-timers/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/@jest/test-result": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", + "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@jest/console": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "node_modules/@jest/test-sequencer": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", + "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", + "@jest/test-result": "^27.3.0", "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" + "jest-haste-map": "^27.3.0", + "jest-runtime": "^27.3.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "node_modules/@jest/transform": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", + "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-haste-map": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.3.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "node_modules/@jest/transform/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "jest-mock": "^26.6.2" + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8" } }, - "node_modules/@jest/globals/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">= 8" } }, - "node_modules/@jest/globals/node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8" } }, - "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" + "type-detect": "4.0.8" } }, - "node_modules/@jest/globals/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/@sinonjs/fake-timers": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", + "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", "dev": true, - "engines": { - "node": ">= 10.14.2" + "dependencies": { + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@jest/globals/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "node-notifier": "^8.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" + "node": ">= 6" } }, "node_modules/@tsconfig/node10": { @@ -1510,9 +1219,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.15", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", - "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1636,16 +1345,10 @@ "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "dev": true }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, "node_modules/@types/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", "dev": true }, "node_modules/@types/resolve": { @@ -1664,9 +1367,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -1679,15 +1382,16 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.0.tgz", - "integrity": "sha512-iPKZTZNavAlOhfF4gymiSuUkgLne/nh5Oz2/mdiUmuZVD42m9PapnCnzjxuDsnpnbH3wT5s2D8bw6S39TC6GNw==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.31.0", - "@typescript-eslint/scope-manager": "4.31.0", + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", "debug": "^4.3.1", "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", "regexpp": "^3.1.0", "semver": "^7.3.5", "tsutils": "^3.21.0" @@ -1710,15 +1414,15 @@ } }, "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.0.tgz", - "integrity": "sha512-Hld+EQiKLMppgKKkdUsLeVIeEOrwKc2G983NmznY/r5/ZtZCDvIOXnXtwqJIgYz/ymsy7n7RGvMyrzf1WaSQrw==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.31.0", - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/typescript-estree": "4.31.0", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -1734,14 +1438,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz", - "integrity": "sha512-oWbzvPh5amMuTmKaf1wp0ySxPt2ZXHnFQBN2Szu1O//7LmOvgaKTCIDNLK2NvzpmVd5A2M/1j/rujBqO37hj3w==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.31.0", - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/typescript-estree": "4.31.0", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", "debug": "^4.3.1" }, "engines": { @@ -1761,13 +1465,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.0.tgz", - "integrity": "sha512-LJ+xtl34W76JMRLjbaQorhR0hfRAlp3Lscdiz9NeI/8i+q0hdBZ7BsiYieLoYWqy+AnRigaD3hUwPFugSzdocg==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/visitor-keys": "4.31.0" + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" }, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1778,9 +1482,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.0.tgz", - "integrity": "sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" @@ -1791,13 +1495,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz", - "integrity": "sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/visitor-keys": "4.31.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", "debug": "^4.3.1", "globby": "^11.0.3", "is-glob": "^4.0.1", @@ -1818,12 +1522,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz", - "integrity": "sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w==", + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.31.0", + "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" }, "engines": { @@ -1945,9 +1649,9 @@ } }, "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, "engines": { "node": ">=8" @@ -1996,50 +1700,17 @@ "sprintf-js": "~1.0.2" } }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, "node_modules/array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", + "es-abstract": "^1.19.1", "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" + "is-string": "^1.0.7" }, "engines": { "node": ">= 0.4" @@ -2057,24 +1728,15 @@ "node": ">=8" } }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", + "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" + "es-abstract": "^1.19.0" }, "engines": { "node": ">= 0.4" @@ -2083,33 +1745,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -2125,75 +1760,73 @@ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "node_modules/babel-jest": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", + "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", "dev": true, - "bin": { - "atob": "bin/atob.js" + "dependencies": { + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" }, "engines": { - "node": ">= 4.5.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "node_modules/babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "dependencies": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=8" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", + "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "engines": { "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -2202,7 +1835,7 @@ "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/babel-preset-current-node-syntax": { @@ -2229,16 +1862,16 @@ } }, "node_modules/babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^26.6.2", + "babel-plugin-jest-hoist": "^27.2.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, "peerDependencies": { "@babel/core": "^7.0.0" @@ -2250,45 +1883,6 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -2317,32 +1911,17 @@ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, - "node_modules/browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, - "dependencies": { - "resolve": "1.1.7" - } - }, - "node_modules/browser-resolve/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - }, "node_modules/browserslist": { - "version": "4.16.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", - "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001251", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.811", + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", "escalade": "^3.1.1", - "node-releases": "^1.1.75" + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" }, "bin": { "browserslist": "cli.js" @@ -2382,26 +1961,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2434,33 +1993,15 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", + "version": "1.0.30001269", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", + "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", "dev": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/browserslist" } }, - "node_modules/capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "dependencies": { - "rsvp": "^4.8.4" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -2487,124 +2028,26 @@ } }, "node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", "dev": true }, "node_modules/cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" + "wrap-ansi": "^7.0.0" } }, "node_modules/co": { @@ -2623,19 +2066,6 @@ "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2654,12 +2084,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/colorette": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", - "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", - "dev": true - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2672,12 +2096,6 @@ "node": ">= 0.8" } }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2693,21 +2111,6 @@ "safe-buffer": "~5.1.1" } }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2752,18 +2155,6 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -2795,34 +2186,22 @@ } } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/decimal.js": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", "dev": true }, - "node_modules/decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true, - "engines": { - "node": ">=0.10" - } + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true }, "node_modules/deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, "node_modules/deepmerge": { @@ -2846,19 +2225,6 @@ "node": ">= 0.4" } }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -2940,26 +2306,16 @@ "node": ">=8" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/electron-to-chromium": { - "version": "1.3.813", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", - "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", + "version": "1.3.871", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", + "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", "dev": true }, "node_modules/emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", "dev": true, "engines": { "node": ">=10" @@ -2974,19 +2330,10 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -3007,32 +2354,26 @@ "node": ">=8.6" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, "node_modules/es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", "has-symbols": "^1.0.2", "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", + "is-callable": "^1.2.4", "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", "object-inspect": "^1.11.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", @@ -3254,12 +2595,13 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", - "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, "dependencies": { "debug": "^3.2.7", + "find-up": "^2.1.0", "pkg-dir": "^2.0.0" }, "engines": { @@ -3276,24 +2618,22 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", - "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", + "version": "2.25.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", + "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", "dev": true, "dependencies": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.6.2", - "find-up": "^2.0.0", + "eslint-module-utils": "^2.7.0", "has": "^1.0.3", - "is-core-module": "^2.6.0", + "is-core-module": "^2.7.0", + "is-glob": "^4.0.3", "minimatch": "^3.0.4", - "object.values": "^1.1.4", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", + "object.values": "^1.1.5", "resolve": "^1.20.0", "tsconfig-paths": "^3.11.0" }, @@ -3301,7 +2641,7 @@ "node": ">=4" }, "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, "node_modules/eslint-plugin-import/node_modules/debug": { @@ -3332,9 +2672,9 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", - "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", + "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", "dev": true, "dependencies": { "@typescript-eslint/experimental-utils": "^4.0.1" @@ -3416,6 +2756,15 @@ "node": ">=4" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, "node_modules/espree": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", @@ -3512,26 +2861,20 @@ "node": ">=0.10.0" } }, - "node_modules/exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, "node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" }, "engines": { @@ -3550,329 +2893,61 @@ "node": ">= 0.8.0" } }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "node_modules/expect": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", + "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", "dev": true, "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-regex-util": "^27.0.6" }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "ms": "2.0.0" + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "node_modules/expect/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/expect": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", - "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-regex-util": "^25.2.6" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/expect/node_modules/@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "node_modules/expect/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/expect/node_modules/jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/expect/node_modules/jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true, - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" }, "engines": { "node": ">=8" @@ -3891,9 +2966,9 @@ "dev": true }, "node_modules/fastq": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", - "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -3963,24 +3038,6 @@ "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", @@ -3995,18 +3052,6 @@ "node": ">= 6" } }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -4094,42 +3139,37 @@ } }, "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "dependencies": { - "assert-plus": "^1.0.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, "dependencies": { "fs.realpath": "^1.0.0", @@ -4193,50 +3233,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/globby/node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/graceful-fs": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "node_modules/growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dev": true, - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -4293,79 +3294,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, "dependencies": { "whatwg-encoding": "^1.0.5" @@ -4394,21 +3326,6 @@ "node": ">= 6" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/https-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", @@ -4423,12 +3340,12 @@ } }, "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "engines": { - "node": ">=8.12.0" + "node": ">=10.17.0" } }, "node_modules/iconv-lite": { @@ -4444,9 +3361,9 @@ } }, "node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true, "engines": { "node": ">= 4" @@ -4469,9 +3386,9 @@ } }, "node_modules/import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", "dev": true, "dependencies": { "pkg-dir": "^4.2.0", @@ -4605,33 +3522,6 @@ "node": ">= 0.4" } }, - "node_modules/ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, "node_modules/is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -4660,12 +3550,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, "node_modules/is-callable": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", @@ -4679,21 +3563,21 @@ } }, "node_modules/is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", "dev": true, "dependencies": { - "ci-info": "^2.0.0" + "ci-info": "^3.1.1" }, "bin": { "is-ci": "bin.js" } }, "node_modules/is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", "dependencies": { "has": "^1.0.3" }, @@ -4701,18 +3585,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-date-object": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", @@ -4728,48 +3600,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4798,9 +3628,9 @@ } }, "node_modules/is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { "is-extglob": "^2.1.1" @@ -4845,18 +3675,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-potential-custom-element-name": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", @@ -4879,6 +3697,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -4927,59 +3754,28 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "node_modules/is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", "dev": true, - "optional": true, "dependencies": { - "is-docker": "^2.0.0" + "call-bind": "^1.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, "node_modules/istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, "engines": { "node": ">=8" @@ -5024,9 +3820,9 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { "debug": "^4.1.1", @@ -5034,7 +3830,7 @@ "source-map": "^0.6.1" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps/node_modules/source-map": { @@ -5047,9 +3843,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", "dev": true, "dependencies": { "html-escaper": "^2.0.0", @@ -5066,188 +3862,239 @@ "dev": true }, "node_modules/jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", + "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", + "@jest/core": "^27.3.0", "import-local": "^3.0.2", - "jest-cli": "^26.6.3" + "jest-cli": "^27.3.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, "node_modules/jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", + "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-circus": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", - "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", + "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", + "@jest/environment": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^25.5.0", + "dedent": "^0.7.0", + "expect": "^27.3.0", "is-generator-fn": "^2.0.0", - "jest-each": "^25.5.0", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-runtime": "^25.5.4", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0", - "stack-utils": "^1.0.1", - "throat": "^5.0.0" + "jest-each": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/@jest/globals": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", - "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@jest/environment": "^25.5.0", - "@jest/types": "^25.5.0", - "expect": "^25.5.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/source-map": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", - "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "node_modules/jest-circus/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-cli": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", + "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", "dev": true, "dependencies": { - "callsites": "^3.0.0", + "@jest/core": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "import-local": "^3.0.2", + "jest-config": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "prompts": "^2.0.1", + "yargs": "^16.2.0" }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-circus/node_modules/@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", - "dev": true, - "dependencies": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/jest-circus/node_modules/@jest/transform": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", - "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", + "node_modules/jest-config": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", + "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", "dev": true, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^25.5.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", + "@jest/test-sequencer": "^27.3.0", + "@jest/types": "^27.2.5", + "babel-jest": "^27.3.0", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.5.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "is-ci": "^3.0.0", + "jest-circus": "^27.3.0", + "jest-environment-jsdom": "^27.3.0", + "jest-environment-node": "^27.3.0", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-runner": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "engines": { - "node": ">= 8.3" + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } } }, - "node_modules/jest-circus/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "node_modules/jest-config/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", + "node_modules/jest-config/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-circus/node_modules/@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true + "node_modules/jest-diff": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "diff-sequences": "^25.2.6", + "jest-get-type": "^25.2.6", + "pretty-format": "^25.5.0" + }, + "engines": { + "node": ">= 8.3" + } }, - "node_modules/jest-circus/node_modules/chalk": { + "node_modules/jest-diff/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", @@ -5260,1485 +4107,1468 @@ "node": ">=8" } }, - "node_modules/jest-circus/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-haste-map": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", - "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "node_modules/jest-each": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", + "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-serializer": "^25.5.0", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0" }, "engines": { - "node": ">= 8.3" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - }, "engines": { - "node": ">= 8.3" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "node_modules/jest-each/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "node_modules/jest-each/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-runtime": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", - "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "node_modules/jest-each/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-environment-jsdom": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", + "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", "dev": true, "dependencies": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/globals": "^25.5.2", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-haste-map": "^25.5.1", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "@jest/environment": "^27.3.0", + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0", + "jsdom": "^16.6.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-serializer": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", - "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "node_modules/jest-environment-node": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", + "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.4" + "@jest/environment": "^27.3.0", + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "node_modules/jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true, - "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" - }, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-circus/node_modules/jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "node_modules/jest-haste-map": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", + "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/jest-circus/node_modules/jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "node_modules/jest-jasmine2": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", + "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.3.0", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.3.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0", + "throat": "^6.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "node_modules/jest-jasmine2/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/jest-jasmine2/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/jest-jasmine2/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-leak-detector": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", + "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/jest-leak-detector/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, - "node_modules/jest-circus/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/jest-matcher-utils": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", + "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "chalk": "^4.0.0", + "jest-diff": "^27.3.0", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/jest-matcher-utils/node_modules/diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/jest-matcher-utils/node_modules/jest-diff": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", + "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/jest-matcher-utils/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, "engines": { - "node": ">=0.10.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/jest-matcher-utils/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, + "dependencies": { + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", + "node_modules/jest-matcher-utils/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-message-util": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", + "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", "dev": true, "dependencies": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "bin": { - "jest": "bin/jest.js" + "micromatch": "^4.0.4", + "pretty-format": "^27.3.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 10.14.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-cli/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/jest-message-util/node_modules/@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "@babel/highlight": "^7.14.5" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "node": ">=6.9.0" } }, - "node_modules/jest-cli/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-cli/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "engines": { - "node": ">= 10" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-cli/node_modules/react-is": { + "node_modules/jest-message-util/node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-config": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", - "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", + "node_modules/jest-mock": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", + "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.5.4", - "@jest/types": "^25.5.0", - "babel-jest": "^25.5.1", - "chalk": "^3.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^25.5.0", - "jest-environment-node": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-jasmine2": "^25.5.4", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "micromatch": "^4.0.2", - "pretty-format": "^25.5.0", - "realpath-native": "^2.0.0" + "@jest/types": "^27.2.5", + "@types/node": "*" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/jest-config/node_modules/@jest/globals": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", - "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", + "node_modules/jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", "dev": true, - "dependencies": { - "@jest/environment": "^25.5.0", - "@jest/types": "^25.5.0", - "expect": "^25.5.0" - }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/source-map": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", - "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", + "node_modules/jest-resolve": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", + "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", "dev": true, "dependencies": { - "callsites": "^3.0.0", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "jest-haste-map": "^27.3.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", + "node_modules/jest-resolve-dependencies": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", + "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", "dev": true, "dependencies": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.3.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/test-sequencer": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", - "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", + "node_modules/jest-runner": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", + "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", "dev": true, "dependencies": { - "@jest/test-result": "^25.5.0", + "@jest/console": "^27.3.0", + "@jest/environment": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-runner": "^25.5.4", - "jest-runtime": "^25.5.4" + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.3.0", + "jest-environment-node": "^27.3.0", + "jest-haste-map": "^27.3.0", + "jest-leak-detector": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/transform": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", - "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.5.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", + "node_modules/jest-runtime": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", + "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.3.0", + "@jest/environment": "^27.3.0", + "@jest/globals": "^27.3.0", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.5.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", + "jest-haste-map": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-mock": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/jest-serializer": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "@types/node": "*", + "graceful-fs": "^4.2.4" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "node_modules/jest-snapshot": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", + "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.3.0", + "graceful-fs": "^4.2.4", + "jest-diff": "^27.3.0", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-util": "^27.3.0", + "natural-compare": "^1.4.0", + "pretty-format": "^27.3.0", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", - "dev": true - }, - "node_modules/jest-config/node_modules/@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/jest-config/node_modules/acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", "dev": true, - "dependencies": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/acorn-globals/node_modules/acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", + "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" }, "engines": { - "node": ">=0.4.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", + "node_modules/jest-snapshot/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/babel-jest": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", - "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/babel-plugin-jest-hoist": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", - "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-util": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", + "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", "dev": true, "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__traverse": "^7.0.6" + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/babel-preset-current-node-syntax": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", - "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", + "node_modules/jest-validate": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", + "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", "dev": true, "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.0.6", + "leven": "^3.1.0", + "pretty-format": "^27.3.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/babel-preset-jest": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", - "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^25.5.0", - "babel-preset-current-node-syntax": "^0.1.2" - }, "engines": { - "node": ">= 8.3" + "node": ">=10" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-config/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "node_modules/jest-validate/node_modules/jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true, - "dependencies": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "dependencies": { - "webidl-conversions": "^4.0.2" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "node_modules/jest-validate/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true + }, + "node_modules/jest-watcher": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", + "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", "dev": true, "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.3.0", + "string-length": "^4.0.1" }, "engines": { - "node": ">=4.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-worker": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", + "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/jest-config/node_modules/html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.1" + "node": ">= 10.13.0" } }, - "node_modules/jest-config/node_modules/jest-docblock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", - "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-config/node_modules/jest-environment-jsdom": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", - "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", - "dev": true, - "dependencies": { - "@jest/environment": "^25.5.0", - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "jsdom": "^15.2.1" + "node": ">=10" }, - "engines": { - "node": ">= 8.3" + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-config/node_modules/jest-environment-node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", - "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { - "@jest/environment": "^25.5.0", - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "semver": "^6.3.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": ">= 8.3" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jest-config/node_modules/jest-haste-map": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", - "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-serializer": "^25.5.0", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=10" }, - "optionalDependencies": { - "fsevents": "^2.1.2" + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } } }, - "node_modules/jest-config/node_modules/jest-jasmine2": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", - "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", + "node_modules/jsdom/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.5.0", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.5.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.5.0", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-runtime": "^25.5.4", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0", - "throat": "^5.0.0" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": ">= 8.3" + "node": ">=0.4.0" } }, - "node_modules/jest-config/node_modules/jest-leak-detector": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", - "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "dependencies": { - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": ">= 8.3" + "node": ">=4" } }, - "node_modules/jest-config/node_modules/jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": ">= 8.3" + "node": ">=6" } }, - "node_modules/jest-config/node_modules/jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, - "engines": { - "node": ">= 8.3" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/jest-config/node_modules/jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=6" } }, - "node_modules/jest-config/node_modules/jest-runner": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", - "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, - "dependencies": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-docblock": "^25.3.0", - "jest-haste-map": "^25.5.1", - "jest-jasmine2": "^25.5.4", - "jest-leak-detector": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "jest-runtime": "^25.5.4", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=6" } }, - "node_modules/jest-config/node_modules/jest-runtime": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", - "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/globals": "^25.5.2", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-haste-map": "^25.5.1", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" - }, - "bin": { - "jest-runtime": "bin/jest-runtime.js" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">= 8.3" + "node": ">= 0.8.0" } }, - "node_modules/jest-config/node_modules/jest-serializer": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", - "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", + "node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "dependencies": { - "graceful-fs": "^4.2.4" + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=4" } }, - "node_modules/jest-config/node_modules/jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" + "yallist": "^4.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=10" } }, - "node_modules/jest-config/node_modules/jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "node_modules/lua-types": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", + "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" + "typescript-to-lua": "^0.39.0" } }, - "node_modules/jest-config/node_modules/jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", + "node_modules/lua-wasm-bindings": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", + "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", + "dev": true + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" + "semver": "^6.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">= 8.3" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-config/node_modules/jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "node_modules/makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", "dev": true, "dependencies": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", - "xml-name-validator": "^3.0.0" - }, + "tmpl": "1.0.x" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { - "node": ">=8" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "node": ">= 8" } }, - "node_modules/jest-config/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "braces": "^3.0.1", + "picomatch": "^2.2.3" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8.6" } }, - "node_modules/jest-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/mime-db": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/jest-config/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/mime-types": { + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "mime-db": "1.50.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.6" } }, - "node_modules/jest-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, "engines": { "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/jest-config/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/jest-config/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/node-releases": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "path-key": "^3.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "node_modules/jest-config/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/object-inspect": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", + "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", "dev": true, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" } }, - "node_modules/jest-config/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/object.values": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "wrappy": "1" } }, - "node_modules/jest-config/node_modules/saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "xmlchars": "^2.1.1" + "mimic-fn": "^2.1.0" }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/jest-config/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/jest-config/node_modules/tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", + "node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "dependencies": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" + "p-limit": "^1.1.0" }, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/jest-config/node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true, - "dependencies": { - "punycode": "^2.1.0" + "engines": { + "node": ">=4" } }, - "node_modules/jest-config/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "callsites": "^3.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/jest-config/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "engines": { "node": ">=8" } }, - "node_modules/jest-config/node_modules/w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/jest-config/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/jest-config/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "node_modules/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true, - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "node_modules/pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "node-modules-regexp": "^1.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">= 6" } }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "find-up": "^2.1.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10.13.0" } }, - "node_modules/jest-each": { + "node_modules/pretty-format": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", - "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", + "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", "dev": true, "dependencies": { "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0" + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^16.12.0" }, "engines": { "node": ">= 8.3" } }, - "node_modules/jest-each/node_modules/@jest/types": { + "node_modules/pretty-format/node_modules/@jest/types": { "version": "25.5.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", @@ -6753,7 +5583,7 @@ "node": ">= 8.3" } }, - "node_modules/jest-each/node_modules/@types/istanbul-reports": { + "node_modules/pretty-format/node_modules/@types/istanbul-reports": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", @@ -6763,7 +5593,16 @@ "@types/istanbul-lib-report": "*" } }, - "node_modules/jest-each/node_modules/chalk": { + "node_modules/pretty-format/node_modules/@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/pretty-format/node_modules/chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", @@ -6776,9772 +5615,3738 @@ "node": ">=8" } }, - "node_modules/jest-each/node_modules/jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - }, "engines": { - "node": ">= 8.3" + "node": ">=0.4.0" } }, - "node_modules/jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 6" } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=6" } }, - "node_modules/jest-environment-jsdom/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true }, - "node_modules/jest-environment-jsdom/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", - "dev": true, - "dependencies": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" }, - "engines": { - "node": ">= 10.14.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" + "resolve-from": "^5.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "engines": { - "node": ">= 8.3" + "node": ">=8" } }, - "node_modules/jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - }, "engines": { - "node": ">= 10.14.2" - }, - "optionalDependencies": { - "fsevents": "^2.1.2" + "node": ">=4" } }, - "node_modules/jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true, - "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^26.6.2", - "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-jasmine2/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/jest-jasmine2/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "glob": "^7.1.3" }, - "engines": { - "node": ">= 10.14.2" + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-jasmine2/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "engines": { - "node": ">= 10.14.2" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "node_modules/jest-jasmine2/node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "xmlchars": "^2.2.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-jasmine2/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-jasmine2/node_modules/jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" + "shebang-regex": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, - "engines": { - "node": ">= 10.14.2" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-jasmine2/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/jest-jasmine2/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", - "dev": true, - "dependencies": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", "engines": { - "node": ">= 10.14.2" + "node": ">= 8" } }, - "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/source-map-support": { + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, - "engines": { - "node": ">= 10.14.2" + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, "engines": { - "node": ">= 10" + "node": ">=0.10.0" } }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "node_modules/jest-matcher-utils": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "dependencies": { - "chalk": "^3.0.0", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">= 8.3" + "node": ">=10" } }, - "node_modules/jest-matcher-utils/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=8" } }, - "node_modules/jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-message-util/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">= 10" + "node": ">=8" } }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-message-util/node_modules/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", "dev": true, "dependencies": { - "escape-string-regexp": "^2.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-mock": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" }, - "engines": { - "node": ">= 8.3" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-mock/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "node": ">=8" } }, - "node_modules/jest-mock/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=8" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "engines": { "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } } }, - "node_modules/jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, + "node_modules/table": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "engines": { - "node": ">=8" + "node": ">=10.0.0" } }, - "node_modules/jest-resolve/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/table/node_modules/ajv": { + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/jest-resolve/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-resolve/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/jest-resolve/node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "is-number": "^7.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.0" } }, - "node_modules/jest-resolve/node_modules/path-exists": { + "node_modules/tough-cookie": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/jest-resolve/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", "dev": true, "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" + "punycode": "^2.1.1" }, "engines": { "node": ">=8" } }, - "node_modules/jest-resolve/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/ts-jest": { + "version": "27.0.7", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", + "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", "dev": true, "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-resolve/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-resolve/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "bin": { + "ts-jest": "cli.js" }, "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" }, - "engines": { - "node": ">= 10.14.2" + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + } } }, - "node_modules/jest-runner/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/ts-node": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", + "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "yn": "3.1.1" }, - "engines": { - "node": ">= 10.14.2" + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" }, "peerDependencies": { - "ts-node": ">=9.0.0" + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" }, "peerDependenciesMeta": { - "ts-node": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { "optional": true } } }, - "node_modules/jest-runner/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/ts-node/node_modules/acorn": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true, + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/jest-runner/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/ts-node/node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=0.4.0" } }, - "node_modules/jest-runner/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/tsconfig-paths": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", + "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" } }, - "node_modules/jest-runner/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", - "dev": true, - "dependencies": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" }, "bin": { - "jest-runtime": "bin/jest-runtime.js" - }, - "engines": { - "node": ">= 10.14.2" + "json5": "lib/cli.js" } }, - "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true, - "dependencies": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=4" } }, - "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "tslib": "^1.8.1" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/jest-runtime/node_modules/jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "prelude-ls": "^1.2.1" }, "engines": { - "node": ">= 10.14.2" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "node": ">= 0.8.0" } }, - "node_modules/jest-runtime/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=4" } }, - "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*" - }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-runtime/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" + "is-typedarray": "^1.0.0" } }, - "node_modules/jest-runtime/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "node_modules/typescript": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">= 10.14.2" + "node": ">=4.2.0" } }, - "node_modules/jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "node_modules/typescript-to-lua": { + "version": "0.39.6", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", + "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", - "chalk": "^4.0.0", - "expect": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", - "semver": "^7.3.2" + "resolve": "^1.15.1", + "source-map": "^0.7.3", + "typescript": "~4.3.2" + }, + "bin": { + "tstl": "dist/tstl.js" }, "engines": { - "node": ">= 10.14.2" + "node": ">=12.13.0" } }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "node_modules/typescript-to-lua/node_modules/typescript": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", + "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, "engines": { - "node": ">= 10.14.2" + "node": ">=4.2.0" } }, - "node_modules/jest-snapshot/node_modules/expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">= 4.0.0" } }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10.12.0" } }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", "dev": true, - "engines": { - "node": ">= 10.14.2" + "dependencies": { + "browser-process-hrtime": "^1.0.0" } }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "xml-name-validator": "^3.0.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, + "makeerror": "1.0.x" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, "engines": { - "node": ">= 10" + "node": ">=10.4" } }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", "dev": true }, - "node_modules/jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" }, "engines": { - "node": ">= 10.14.2" + "node": ">=10" } }, - "node_modules/jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">= 10.14.2" + "node": ">= 8" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { - "node": ">= 10.14.2" + "node": ">=0.10.0" } }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "node_modules/jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "dependencies": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^26.6.2", - "string-length": "^4.0.1" - }, - "engines": { - "node": ">= 10.14.2" + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" } }, - "node_modules/jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "node_modules/ws": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, "engines": { - "node": ">= 10.13.0" + "node": ">=10" } }, - "node_modules/js-tokens": { + "node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=10" } }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" + "node": ">=6" + } + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/compat-data": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "dev": true + }, + "@babel/core": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", + "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.15.8", + "@babel/generator": "^7.15.8", + "@babel/helper-compilation-targets": "^7.15.4", + "@babel/helper-module-transforms": "^7.15.8", + "@babel/helpers": "^7.15.4", + "@babel/parser": "^7.15.8", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" }, - "peerDependenciesMeta": { - "canvas": { - "optional": true + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "@babel/generator": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", + "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "requires": { + "@babel/types": "^7.15.6", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" }, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "@babel/helper-compilation-targets": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", + "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" + "requires": { + "@babel/compat-data": "^7.15.0", + "@babel/helper-validator-option": "^7.14.5", + "browserslist": "^4.16.6", + "semver": "^6.3.0" }, - "engines": { - "node": ">=4" + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "@babel/helper-function-name": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", + "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" + "requires": { + "@babel/helper-get-function-arity": "^7.15.4", + "@babel/template": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "@babel/helper-get-function-arity": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", + "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "@babel/helper-hoist-variables": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", + "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "@babel/helper-member-expression-to-functions": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", + "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "@babel/helper-module-imports": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", + "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "@babel/helper-module-transforms": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", + "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@babel/helper-module-imports": "^7.15.4", + "@babel/helper-replace-supers": "^7.15.4", + "@babel/helper-simple-access": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/helper-validator-identifier": "^7.15.7", + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.6" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "@babel/helper-optimise-call-expression": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", + "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "@babel/helper-plugin-utils": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", + "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", "dev": true }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "@babel/helper-replace-supers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", + "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@babel/helper-member-expression-to-functions": "^7.15.4", + "@babel/helper-optimise-call-expression": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "@babel/helper-simple-access": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", + "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "@babel/helper-split-export-declaration": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", + "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@babel/types": "^7.15.4" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "@babel/helper-validator-identifier": { + "version": "7.15.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", + "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", "dev": true }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "@babel/helper-validator-option": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", + "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", "dev": true }, - "node_modules/lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", + "@babel/helpers": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", + "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" + "requires": { + "@babel/template": "^7.15.4", + "@babel/traverse": "^7.15.4", + "@babel/types": "^7.15.4" } }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "@babel/highlight": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" + "requires": { + "@babel/helper-validator-identifier": "^7.14.5", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lua-types": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", - "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", - "dev": true, "dependencies": { - "typescript-to-lua": "^0.39.0" + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "node_modules/lua-wasm-bindings": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", - "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", + "@babel/parser": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", + "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", "dev": true }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "dependencies": { - "tmpl": "1.0.x" + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" } }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "engines": { - "node": ">= 8" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - }, - "engines": { - "node": ">=8.6" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "engines": { - "node": ">= 0.6" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "dependencies": { - "mime-db": "1.49.0" - }, - "engines": { - "node": ">= 0.6" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "@babel/plugin-syntax-typescript": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", + "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "@babel/template": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", + "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4" }, - "engines": { - "node": ">=10" + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + } } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "@babel/traverse": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", + "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "requires": { + "@babel/code-frame": "^7.14.5", + "@babel/generator": "^7.15.4", + "@babel/helper-function-name": "^7.15.4", + "@babel/helper-hoist-variables": "^7.15.4", + "@babel/helper-split-export-declaration": "^7.15.4", + "@babel/parser": "^7.15.4", + "@babel/types": "^7.15.4", + "debug": "^4.1.0", + "globals": "^11.1.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "dev": true, + "requires": { + "@babel/highlight": "^7.14.5" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "@babel/types": { + "version": "7.15.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", + "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.9", + "to-fast-properties": "^2.0.0" + } }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", "dev": true, - "optional": true, - "dependencies": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" } }, - "node_modules/node-releases": { - "version": "1.1.75", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", - "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "@eslint/eslintrc": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", + "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^13.9.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } } }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "@humanwhocodes/config-array": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", + "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", "dev": true, - "bin": { - "semver": "bin/semver" + "requires": { + "@humanwhocodes/object-schema": "^1.2.0", + "debug": "^4.1.1", + "minimatch": "^3.0.4" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "@humanwhocodes/object-schema": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", + "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "dev": true }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, - "dependencies": { - "path-key": "^3.0.0" + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, - "engines": { - "node": ">=8" + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "@jest/console": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", + "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.3.0", + "jest-util": "^27.3.0", + "slash": "^3.0.0" } }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "@jest/core": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", + "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jest/console": "^27.3.0", + "@jest/reporters": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^27.3.0", + "jest-config": "^27.3.0", + "jest-haste-map": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-resolve-dependencies": "^27.3.0", + "jest-runner": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "jest-watcher": "^27.3.0", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" } }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "@jest/environment": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", + "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0" } }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "@jest/fake-timers": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", + "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jest/types": "^27.2.5", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.3.0", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0" } }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "@jest/globals": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", + "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@jest/environment": "^27.3.0", + "@jest/types": "^27.2.5", + "expect": "^27.3.0" } }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "@jest/reporters": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", + "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "@jest/source-map": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", + "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "@jest/test-result": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", + "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@jest/console": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "@jest/test-sequencer": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", + "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", "dev": true, - "engines": { - "node": ">= 0.4" + "requires": { + "@jest/test-result": "^27.3.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.0", + "jest-runtime": "^27.3.0" } }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "@jest/transform": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", + "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", "dev": true, - "dependencies": { - "isobject": "^3.0.0" + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.2.5", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-util": "^27.3.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } } }, - "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "@jest/types": { + "version": "27.2.5", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", + "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" } }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" } }, - "node_modules/object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, - "dependencies": { - "wrappy": "1" + "requires": { + "type-detect": "4.0.8" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "@sinonjs/fake-timers": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", + "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@sinonjs/commons": "^1.7.0" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "@types/babel__core": { + "version": "7.1.16", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", + "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", + "@types/babel__generator": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", + "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "requires": { + "@babel/types": "^7.0.0" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@babel/types": "^7.3.0" } }, - "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@types/node": "*" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "@types/glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" + "requires": { + "@types/node": "*" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "@types/istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", "dev": true }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-exists": { + "@types/istanbul-lib-report": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@types/istanbul-lib-report": "*" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "@types/jest": { + "version": "25.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", + "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "jest-diff": "^25.2.1", + "pretty-format": "^25.2.1" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "@types/json-schema": { + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "dev": true }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", + "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "dev": true + }, + "@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "dev": true + }, + "@types/prettier": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "dev": true + }, + "@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@types/node": "*" } }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, - "node_modules/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "requires": { + "@types/yargs-parser": "*" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "@types/yargs-parser": { + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "dev": true, - "dependencies": { - "node-modules-regexp": "^1.0.0" - }, - "engines": { - "node": ">= 6" + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" } }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" } }, - "node_modules/pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" } }, - "node_modules/pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "dev": true }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "dev": true, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" } }, - "node_modules/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" } }, - "node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } + "requires": {} }, - "node_modules/pretty-format/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" + "requires": { + "debug": "4" } }, - "node_modules/pretty-format/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, - "node_modules/pretty-format/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "requires": { + "type-fest": "^0.21.3" }, - "engines": { - "node": ">=8" + "dependencies": { + "type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true + } } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "engines": { - "node": ">=0.4.0" + "requires": { + "color-convert": "^2.0.1" } }, - "node_modules/prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "requires": { + "sprintf-js": "~1.0.2" } }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "array-includes": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", + "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.1", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.7" } }, - "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", + "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", "dev": true, - "engines": { - "node": ">=0.6" + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "babel-jest": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", + "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.0.0", + "babel-preset-jest": "^27.2.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "slash": "^3.0.0" } }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" }, - "engines": { - "node": ">=4" + "dependencies": { + "istanbul-lib-instrument": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", + "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "babel-plugin-jest-hoist": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", + "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" } }, - "node_modules/realpath-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" } }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "babel-preset-jest": { + "version": "27.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", + "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "requires": { + "babel-plugin-jest-hoist": "^27.2.0", + "babel-preset-current-node-syntax": "^1.0.0" } }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, - "engines": { - "node": ">=0.10" + "requires": { + "fill-range": "^7.0.1" } }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dev": true, - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", + "browserslist": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", + "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", "dev": true, - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" + "requires": { + "caniuse-lite": "^1.0.30001265", + "electron-to-chromium": "^1.3.867", + "escalade": "^3.1.1", + "node-releases": "^2.0.0", + "picocolors": "^1.0.0" } }, - "node_modules/request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, - "dependencies": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.12.0" - }, - "peerDependencies": { - "request": "^2.34" + "requires": { + "fast-json-stable-stringify": "2.x" } }, - "node_modules/request-promise-native/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" + "requires": { + "node-int64": "^0.4.0" } }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true }, - "node_modules/request/node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "dev": true, - "bin": { - "uuid": "bin/uuid" - } + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "caniuse-lite": { + "version": "1.0.30001269", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", + "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, - "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "ci-info": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", + "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "dev": true }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "engines": { - "node": ">=0.12" + "requires": { + "color-name": "~1.1.4" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "requires": { + "delayed-stream": "~1.0.0" } }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", "dev": true, - "engines": { - "node": "6.* || >= 7.*" + "requires": { + "safe-buffer": "~5.1.1" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, - "dependencies": { - "ret": "~0.1.10" + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", "dev": true }, - "node_modules/sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "deprecated": "some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added", + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", "dev": true, - "dependencies": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "bin": { - "sane": "src/cli.js" + "requires": { + "cssom": "~0.3.6" }, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } } }, - "node_modules/sane/node_modules/anymatch": { + "data-urls": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", "dev": true, - "dependencies": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" } }, - "node_modules/sane/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "ms": "2.1.2" } }, - "node_modules/sane/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true }, - "node_modules/sane/node_modules/cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" + "requires": { + "object-keys": "^1.0.12" } }, - "node_modules/sane/node_modules/execa": { + "delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, - "node_modules/sane/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true }, - "node_modules/sane/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true }, - "node_modules/sane/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } + "diff-sequences": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", + "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "dev": true }, - "node_modules/sane/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "path-type": "^4.0.0" } }, - "node_modules/sane/node_modules/is-number": { + "doctrine": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "esutils": "^2.0.2" } }, - "node_modules/sane/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" + "requires": { + "webidl-conversions": "^5.0.0" }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } } }, - "node_modules/sane/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } + "electron-to-chromium": { + "version": "1.3.871", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", + "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", + "dev": true }, - "node_modules/sane/node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true }, - "node_modules/sane/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "engines": { - "node": ">=4" - } + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, - "node_modules/sane/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" + "enhanced-resolve": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", + "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" } }, - "node_modules/sane/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", "dev": true, - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "ansi-colors": "^4.1.1" } }, - "node_modules/sane/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sane/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "es-abstract": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", + "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.1", + "is-string": "^1.0.7", + "is-weakref": "^1.0.1", + "object-inspect": "^1.11.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" } }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" } }, - "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } } }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "eslint": { + "version": "7.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", + "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.3", + "@humanwhocodes/config-array": "^0.5.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.1.2", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.9", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } } }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "eslint-module-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", + "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0", + "pkg-dir": "^2.0.0" }, - "engines": { - "node": ">=8" + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "eslint-plugin-import": { + "version": "2.25.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", + "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.0", + "has": "^1.0.3", + "is-core-module": "^2.7.0", + "is-glob": "^4.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.5", + "resolve": "^1.20.0", + "tsconfig-paths": "^3.11.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } } }, - "node_modules/shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "eslint-plugin-jest": { + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", + "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", "dev": true, - "optional": true + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" } }, - "node_modules/signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { + "eslint-utils": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "eslint-visitor-keys": "^2.0.0" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } } }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "requires": { + "estraverse": "^5.1.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" + "requires": { + "estraverse": "^5.2.0" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" } }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", + "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" + "requires": { + "@jest/types": "^27.2.5", + "ansi-styles": "^5.0.0", + "jest-get-type": "^27.0.6", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-regex-util": "^27.0.6" }, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true + } } }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, - "dependencies": { - "ms": "2.0.0" + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" } }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "reusify": "^1.0.4" } }, - "node_modules/snapdragon/node_modules/extend-shallow": { + "fb-watchman": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "bser": "2.1.1" } }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "flat-cache": "^3.0.4" } }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "to-regex-range": "^5.0.1" } }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "locate-path": "^2.0.0" } }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "flatted": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", + "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", "dev": true }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" } }, - "node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" } }, - "node_modules/source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "optional": true }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, - "node_modules/sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" } }, - "node_modules/stack-utils": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", - "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "is-glob": "^4.0.1" } }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "globals": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", + "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "type-fest": "^0.20.2" } }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "globby": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", + "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" + "requires": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" } }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" } }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.0" - }, - "engines": { - "node": ">=8" - } + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true }, - "node_modules/strip-bom": { + "has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true }, - "node_modules/strip-eof": { + "has-tostringtag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "has-symbols": "^1.0.2" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "whatwg-encoding": "^1.0.5" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" } }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "agent-base": "6", + "debug": "4" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "node_modules/table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", - "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "requires": { + "safer-buffer": ">= 2.1.2 < 3" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, - "node_modules/tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-jest": { - "version": "26.5.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", - "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": ">= 10" - }, - "peerDependencies": { - "jest": ">=26 <27", - "typescript": ">=3.8 <5.0" - } - }, - "node_modules/ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "0.6.1", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.0", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", - "license": "Apache-2.0", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typescript-to-lua": { - "version": "0.39.6", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", - "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", - "dev": true, - "dependencies": { - "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.3.2" - }, - "bin": { - "tstl": "dist/tstl.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/typescript-to-lua/node_modules/typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/yargs/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yargs/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, - "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", - "dev": true - }, - "@babel/core": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", - "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-compilation-targets": "^7.15.0", - "@babel/helper-module-transforms": "^7.15.0", - "@babel/helpers": "^7.14.8", - "@babel/parser": "^7.15.0", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", - "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", - "dev": true, - "requires": { - "@babel/types": "^7.15.0", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", - "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-function-name": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz", - "integrity": "sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.14.5", - "@babel/template": "^7.14.5", - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz", - "integrity": "sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz", - "integrity": "sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", - "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", - "dev": true, - "requires": { - "@babel/types": "^7.15.0" - } - }, - "@babel/helper-module-imports": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.14.5.tgz", - "integrity": "sha512-SwrNHu5QWS84XlHwGYPDtCxcA0hrSlL2yhWYLgeOc0w7ccOl2qv4s/nARI0aYZW+bSwAL5CukeXA47B/1NKcnQ==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", - "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.15.0", - "@babel/helper-simple-access": "^7.14.8", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.9", - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz", - "integrity": "sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", - "dev": true - }, - "@babel/helper-replace-supers": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", - "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.0", - "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" - } - }, - "@babel/helper-simple-access": { - "version": "7.14.8", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", - "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", - "dev": true, - "requires": { - "@babel/types": "^7.14.8" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz", - "integrity": "sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==", - "dev": true, - "requires": { - "@babel/types": "^7.14.5" - } - }, - "@babel/helper-validator-identifier": { - "version": "7.14.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", - "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", - "dev": true - }, - "@babel/helpers": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.3.tgz", - "integrity": "sha512-HwJiz52XaS96lX+28Tnbu31VeFSQJGOeKHJeaEPQlTl7PnlhFElWPj8tUXtqFIzeN86XxXoBr+WFAyK2PPVz6g==", - "dev": true, - "requires": { - "@babel/template": "^7.14.5", - "@babel/traverse": "^7.15.0", - "@babel/types": "^7.15.0" - } - }, - "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.5", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.15.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.3.tgz", - "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/template": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", - "integrity": "sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.14.5", - "@babel/types": "^7.14.5" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - } - } - }, - "@babel/traverse": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", - "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.0", - "@babel/helper-function-name": "^7.14.5", - "@babel/helper-hoist-variables": "^7.14.5", - "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.15.0", - "@babel/types": "^7.15.0", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", - "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", - "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.14.9", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz", - "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.0", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", - "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.6.2", - "jest-util": "^26.6.2", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", - "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/reporters": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.6.2", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-resolve-dependencies": "^26.6.3", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "jest-watcher": "^26.6.2", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "@jest/environment": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.5.0.tgz", - "integrity": "sha512-U2VXPEqL07E/V7pSZMSQCvV5Ea4lqOlT+0ZFijl/i316cRMHvZ4qC+jBdryd+lmRetjQo0YIQr6cVPNxxK87mA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } - }, - "@jest/fake-timers": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.5.0.tgz", - "integrity": "sha512-9y2+uGnESw/oyOI3eww9yaxdZyHq7XvprfP/eeoCsjqKYts2yRlsHS/SgjPDV8FyMfn2nbMy8YzUk6nyvdLOpQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "lolex": "^5.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - } - } - }, - "@jest/globals": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", - "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", - "dev": true, - "requires": { - "@jest/environment": "^26.6.2", - "@jest/types": "^26.6.2", - "expect": "^26.6.2" - }, - "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "@jest/reporters": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", - "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^7.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/source-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", - "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/test-result": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", - "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", - "dev": true, - "requires": { - "@jest/console": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", - "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", - "dev": true, - "requires": { - "@jest/test-result": "^26.6.2", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-runner": "^26.6.3", - "jest-runtime": "^26.6.3" - } - }, - "@jest/transform": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", - "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.6.2", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.6.2", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/babel__core": { - "version": "7.1.15", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", - "integrity": "sha512-bxlMKPDbY8x5h6HBwVzEOk2C8fb6SLfYQ5Jw3uBYuYF1lfWk/kbLd81la82vrIkBb0l+JdmrZaDikPrNxpS/Ew==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", - "dev": true, - "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" - } - }, - "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "@types/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==", - "dev": true - }, - "@types/resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.31.0.tgz", - "integrity": "sha512-iPKZTZNavAlOhfF4gymiSuUkgLne/nh5Oz2/mdiUmuZVD42m9PapnCnzjxuDsnpnbH3wT5s2D8bw6S39TC6GNw==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.31.0", - "@typescript-eslint/scope-manager": "4.31.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.31.0.tgz", - "integrity": "sha512-Hld+EQiKLMppgKKkdUsLeVIeEOrwKc2G983NmznY/r5/ZtZCDvIOXnXtwqJIgYz/ymsy7n7RGvMyrzf1WaSQrw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.31.0", - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/typescript-estree": "4.31.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, - "@typescript-eslint/parser": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.31.0.tgz", - "integrity": "sha512-oWbzvPh5amMuTmKaf1wp0ySxPt2ZXHnFQBN2Szu1O//7LmOvgaKTCIDNLK2NvzpmVd5A2M/1j/rujBqO37hj3w==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.31.0", - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/typescript-estree": "4.31.0", - "debug": "^4.3.1" - } - }, - "@typescript-eslint/scope-manager": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.31.0.tgz", - "integrity": "sha512-LJ+xtl34W76JMRLjbaQorhR0hfRAlp3Lscdiz9NeI/8i+q0hdBZ7BsiYieLoYWqy+AnRigaD3hUwPFugSzdocg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/visitor-keys": "4.31.0" - } - }, - "@typescript-eslint/types": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.31.0.tgz", - "integrity": "sha512-9XR5q9mk7DCXgXLS7REIVs+BaAswfdHhx91XqlJklmqWpTALGjygWVIb/UnLh4NWhfwhR5wNe1yTyCInxVhLqQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.31.0.tgz", - "integrity": "sha512-QHl2014t3ptg+xpmOSSPn5hm4mY8D4s97ftzyk9BZ8RxYQ3j73XcwuijnJ9cMa6DO4aLXeo8XS3z1omT9LA/Eg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.31.0", - "@typescript-eslint/visitor-keys": "4.31.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.31.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.31.0.tgz", - "integrity": "sha512-HUcRp2a9I+P21+O21yu3ezv3GEPGjyGiXoEUQwZXjR8UxRApGeLyWH4ZIIUSalE28aG4YsV6GjtaAVB3QKOu0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.31.0", - "eslint-visitor-keys": "^2.0.0" - } - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "array-includes": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", - "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.2", - "get-intrinsic": "^1.1.1", - "is-string": "^1.0.5" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "array.prototype.flat": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", - "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "es-abstract": "^1.18.0-next.1" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "dev": true, - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", - "dev": true - }, - "aws4": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", - "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", - "dev": true - }, - "babel-jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", - "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", - "dev": true, - "requires": { - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.6.2", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", - "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", - "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^26.6.2", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "dev": true, - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "dev": true, - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "browserslist": { - "version": "4.16.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.8.tgz", - "integrity": "sha512-sc2m9ohR/49sWEbPj14ZSSZqp+kbi16aLao42Hmn3Z8FpjuMaq2xCA2l4zl9ITfyzvnvyE0hcg62YkIGKxgaNQ==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001251", - "colorette": "^1.3.0", - "electron-to-chromium": "^1.3.811", - "escalade": "^3.1.1", - "node-releases": "^1.1.75" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001251", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001251.tgz", - "integrity": "sha512-HOe1r+9VkU4TFmnU70z+r7OLmtR+/chB1rdcJUeQlAinjEeb0cKL20tlAtOagNZhbrtLnCvV19B4FmF1rgzl6A==", - "dev": true - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "dev": true, - "requires": { - "rsvp": "^4.8.4" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, - "cjs-module-lexer": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", - "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "colorette": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.3.0.tgz", - "integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==", - "dev": true - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "dev": true, - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "electron-to-chromium": { - "version": "1.3.813", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.813.tgz", - "integrity": "sha512-YcSRImHt6JZZ2sSuQ4Bzajtk98igQ0iKkksqlzZLzbh4p0OIyJRSvUbsgqfcR8txdfsoYCc4ym306t4p2kP/aw==", - "dev": true - }, - "emittery": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", - "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", - "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.18.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.5.tgz", - "integrity": "sha512-DDggyJLoS91CkJjgauM5c0yZMjiD1uK3KcaCeAmffGwZ+ODWzOkPN4QwRbsK5DOFf06fywmyLci3ZD8jLGhVYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.3", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.3", - "is-string": "^1.0.6", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", - "dev": true, - "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "enquirer": "^2.3.5", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", - "globals": "^13.6.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - "table": "^6.0.9", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.2.tgz", - "integrity": "sha512-QG8pcgThYOuqxupd06oYTZoNOGaUdTY1PqK+oS6ElF6vs4pBdk/aYxFVQQXzcrAqp9m7cl7lb2ubazX+g16k2Q==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "pkg-dir": "^2.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.24.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.24.2.tgz", - "integrity": "sha512-hNVtyhiEtZmpsabL4neEj+6M5DCLgpYyG9nzJY8lZQeQXEn5UPW1DpUdsMHMXsq98dbNm7nt1w9ZMSVpfJdi8Q==", - "dev": true, - "requires": { - "array-includes": "^3.1.3", - "array.prototype.flat": "^1.2.4", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.6.2", - "find-up": "^2.0.0", - "has": "^1.0.3", - "is-core-module": "^2.6.0", - "minimatch": "^3.0.4", - "object.values": "^1.1.4", - "pkg-up": "^2.0.0", - "read-pkg-up": "^3.0.0", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-jest": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.4.0.tgz", - "integrity": "sha512-8qnt/hgtZ94E9dA6viqfViKBfkJwFHXgJmTWlMGDgunw1XJEGqm3eiPjDsTanM3/u/3Az82nyQM9GX7PM/QGmg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^4.0.1" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - } - }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - }, - "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", - "dev": true, - "requires": { - "acorn": "^7.4.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "exec-sh": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.6.tgz", - "integrity": "sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==", - "dev": true - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "expect": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.5.0.tgz", - "integrity": "sha512-w7KAXo0+6qqZZhovCaBVPSIqQp7/UTcx4M9uKt2m6pd2VB1voyC8JizLRqeEqud3AAVP02g+hbErDu5gu64tlA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-regex-util": "^25.2.6" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastq": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", - "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.7", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", - "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - }, - "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "dev": true, - "optional": true - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", - "dev": true - }, - "har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "dev": true, - "requires": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "dev": true - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "dev": true, - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-core-module": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.6.0.tgz", - "integrity": "sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "optional": true - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "optional": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", - "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "dev": true - }, - "jest": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", - "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "import-local": "^3.0.2", - "jest-cli": "^26.6.3" - } - }, - "jest-changed-files": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", - "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "execa": "^4.0.0", - "throat": "^5.0.0" - } - }, - "jest-circus": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-25.5.4.tgz", - "integrity": "sha512-nOLJXZjWuV2i8yQ2w+MZ8NhFuqrbgpPAa4mh+DWPYmNI377YYpDKvDUrLMW8U1sa2iGt5mjKQbmJz2SK9AYjWg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.5.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.5.0", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-runtime": "^25.5.4", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0", - "stack-utils": "^1.0.1", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - } - }, - "@jest/globals": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", - "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", - "dev": true, - "requires": { - "@jest/environment": "^25.5.0", - "@jest/types": "^25.5.0", - "expect": "^25.5.0" - } - }, - "@jest/source-map": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", - "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/transform": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", - "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.5.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.5.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", - "dev": true - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "jest-haste-map": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", - "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-serializer": "^25.5.0", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, - "jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } - }, - "jest-runtime": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", - "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/globals": "^25.5.2", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-haste-map": "^25.5.1", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" - } - }, - "jest-serializer": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", - "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" - } - }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - } - }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, - "jest-cli": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", - "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", - "dev": true, - "requires": { - "@jest/core": "^26.6.3", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^26.6.3", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "prompts": "^2.0.1", - "yargs": "^15.4.1" - }, - "dependencies": { - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true - }, - "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "jest-config": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.5.4.tgz", - "integrity": "sha512-SZwR91SwcdK6bz7Gco8qL7YY2sx8tFJYzvg216DLihTWf+LKY/DoJXpM9nTzYakSyfblbqeU48p/p7Jzy05Atg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.5.4", - "@jest/types": "^25.5.0", - "babel-jest": "^25.5.1", - "chalk": "^3.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^25.5.0", - "jest-environment-node": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-jasmine2": "^25.5.4", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "micromatch": "^4.0.2", - "pretty-format": "^25.5.0", - "realpath-native": "^2.0.0" - }, - "dependencies": { - "@jest/console": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.5.0.tgz", - "integrity": "sha512-T48kZa6MK1Y6k4b89sexwmSF4YLeZS/Udqg3Jj3jG/cHH+N/sLFCEoXEDMOKugJQ9FxPN1osxIknvKkxt6MKyw==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-message-util": "^25.5.0", - "jest-util": "^25.5.0", - "slash": "^3.0.0" - } - }, - "@jest/globals": { - "version": "25.5.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-25.5.2.tgz", - "integrity": "sha512-AgAS/Ny7Q2RCIj5kZ+0MuKM1wbF0WMLxbCVl/GOMoCNbODRdJ541IxJ98xnZdVSZXivKpJlNPIWa3QmY0l4CXA==", - "dev": true, - "requires": { - "@jest/environment": "^25.5.0", - "@jest/types": "^25.5.0", - "expect": "^25.5.0" - } - }, - "@jest/source-map": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.5.0.tgz", - "integrity": "sha512-eIGx0xN12yVpMcPaVpjXPnn3N30QGJCJQSkEDUt9x1fI1Gdvb07Ml6K5iN2hG7NmMP6FDmtPEssE3z6doOYUwQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.5.0.tgz", - "integrity": "sha512-oV+hPJgXN7IQf/fHWkcS99y0smKLU2czLBJ9WA0jHITLst58HpQMtzSYxzaBvYc6U5U6jfoMthqsUlUlbRXs0A==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/types": "^25.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.5.4.tgz", - "integrity": "sha512-pTJGEkSeg1EkCO2YWq6hbFvKNXk8ejqlxiOg1jBNLnWrgXOkdY6UmqZpwGFXNnRt9B8nO1uWMzLLZ4eCmhkPNA==", - "dev": true, - "requires": { - "@jest/test-result": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-runner": "^25.5.4", - "jest-runtime": "^25.5.4" - } - }, - "@jest/transform": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.5.1.tgz", - "integrity": "sha512-Y8CEoVwXb4QwA6Y/9uDkn0Xfz0finGkieuV0xkdF9UtZGJeLukD5nLkaVrVsODB1ojRWlaoD0AJZpVHCSnJEvg==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.5.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^25.5.1", - "jest-regex-util": "^25.2.6", - "jest-util": "^25.5.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ==", - "dev": true - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", - "dev": true - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "dev": true, - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", - "dev": true - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", - "dev": true - }, - "babel-jest": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.5.1.tgz", - "integrity": "sha512-9dA9+GmMjIzgPnYtkhBg73gOo/RHqPmLruP3BaGL4KEX3Dwz6pI8auSN8G8+iuEG90+GSswyKvslN+JYSaacaQ==", - "dev": true, - "requires": { - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/babel__core": "^7.1.7", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.5.0.tgz", - "integrity": "sha512-u+/W+WAjMlvoocYGTwthAiQSxDcJAyHpQ6oWlHdFZaaN+Rlk8Q7iiwDPg2lN/FyJtAYnKjFxbn7xus4HCFkg5g==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.4.tgz", - "integrity": "sha512-5/INNCYhUGqw7VbVjT/hb3ucjgkVHKXY7lX3ZjlN4gm565VyFmJUrJ/h+h16ECVB38R/9SF6aACydpKMLZ/c9w==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.5.0.tgz", - "integrity": "sha512-8ZczygctQkBU+63DtSOKGh7tFL0CeCuz+1ieud9lJ1WPQ9O6A1a/r+LGn6Y705PA6whHQ3T1XuB/PmpfNYf8Fw==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^25.5.0", - "babel-preset-current-node-syntax": "^0.1.2" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - } - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "dev": true, - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "escodegen": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", - "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "jest-docblock": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.3.0.tgz", - "integrity": "sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-environment-jsdom": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.5.0.tgz", - "integrity": "sha512-7Jr02ydaq4jaWMZLY+Skn8wL5nVIYpWvmeatOHL3tOcV3Zw8sjnPpx+ZdeBfc457p8jCR9J6YCc+Lga0oIy62A==", - "dev": true, - "requires": { - "@jest/environment": "^25.5.0", - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "jsdom": "^15.2.1" - } - }, - "jest-environment-node": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.5.0.tgz", - "integrity": "sha512-iuxK6rQR2En9EID+2k+IBs5fCFd919gVVK5BeND82fYeLWPqvRcFNPKu9+gxTwfB5XwBGBvZ0HFQa+cHtIoslA==", - "dev": true, - "requires": { - "@jest/environment": "^25.5.0", - "@jest/fake-timers": "^25.5.0", - "@jest/types": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-util": "^25.5.0", - "semver": "^6.3.0" - } - }, - "jest-haste-map": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.5.1.tgz", - "integrity": "sha512-dddgh9UZjV7SCDQUrQ+5t9yy8iEgKc1AKqZR9YDww8xsVOtzPQSMVLDChc21+g29oTRexb9/B0bIlZL+sWmvAQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "@types/graceful-fs": "^4.1.2", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-serializer": "^25.5.0", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7", - "which": "^2.0.2" - } - }, - "jest-jasmine2": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.5.4.tgz", - "integrity": "sha512-9acbWEfbmS8UpdcfqnDO+uBUgKa/9hcRh983IHdM+pKmJPL77G0sWAAK0V0kr5LK3a8cSBfkFSoncXwQlRZfkQ==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.5.0", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.5.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.5.0", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-runtime": "^25.5.4", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0", - "throat": "^5.0.0" - } - }, - "jest-leak-detector": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.5.0.tgz", - "integrity": "sha512-rV7JdLsanS8OkdDpZtgBf61L5xZ4NnYLBq72r6ldxahJWWczZjXawRsoHyXzibM5ed7C2QRjpp6ypgwGdKyoVA==", - "dev": true, - "requires": { - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - } - }, - "jest-message-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.5.0.tgz", - "integrity": "sha512-ezddz3YCT/LT0SKAmylVyWWIGYoKHOFOFXx3/nA4m794lfVUskMcwhip6vTgdVrOtYdjeQeis2ypzes9mZb4EA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-regex-util": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.2.6.tgz", - "integrity": "sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw==", - "dev": true - }, - "jest-resolve": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.5.1.tgz", - "integrity": "sha512-Hc09hYch5aWdtejsUZhA+vSzcotf7fajSlPA6EZPE1RmPBAD39XtJhvHWFStid58iit4IPDLI/Da4cwdDmAHiQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.1", - "read-pkg-up": "^7.0.1", - "realpath-native": "^2.0.0", - "resolve": "^1.17.0", - "slash": "^3.0.0" - } - }, - "jest-runner": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.5.4.tgz", - "integrity": "sha512-V/2R7fKZo6blP8E9BL9vJ8aTU4TH2beuqGNxHbxi6t14XzTb+x90B3FRgdvuHm41GY8ch4xxvf0ATH4hdpjTqg==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-docblock": "^25.3.0", - "jest-haste-map": "^25.5.1", - "jest-jasmine2": "^25.5.4", - "jest-leak-detector": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "jest-runtime": "^25.5.4", - "jest-util": "^25.5.0", - "jest-worker": "^25.5.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - } - }, - "jest-runtime": { - "version": "25.5.4", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.5.4.tgz", - "integrity": "sha512-RWTt8LeWh3GvjYtASH2eezkc8AehVoWKK20udV6n3/gC87wlTbE1kIA+opCvNWyyPeBs6ptYsc6nyHUb1GlUVQ==", - "dev": true, - "requires": { - "@jest/console": "^25.5.0", - "@jest/environment": "^25.5.0", - "@jest/globals": "^25.5.2", - "@jest/source-map": "^25.5.0", - "@jest/test-result": "^25.5.0", - "@jest/transform": "^25.5.1", - "@jest/types": "^25.5.0", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-config": "^25.5.4", - "jest-haste-map": "^25.5.1", - "jest-message-util": "^25.5.0", - "jest-mock": "^25.5.0", - "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.5.1", - "jest-snapshot": "^25.5.1", - "jest-util": "^25.5.0", - "jest-validate": "^25.5.0", - "realpath-native": "^2.0.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.3.1" - } - }, - "jest-serializer": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.5.0.tgz", - "integrity": "sha512-LxD8fY1lByomEPflwur9o4e2a5twSQ7TaVNLlFUuToIdoJuBt8tzHfCsZ42Ok6LkKXWzFWf3AGmheuLAA7LcCA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4" - } - }, - "jest-snapshot": { - "version": "25.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.5.1.tgz", - "integrity": "sha512-C02JE1TUe64p2v1auUJ2ze5vcuv32tkv9PyhEb318e8XOKF7MOyXdJ7kdjbvrp3ChPLU2usI7Rjxs97Dj5P0uQ==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.5.0", - "@types/prettier": "^1.19.0", - "chalk": "^3.0.0", - "expect": "^25.5.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^25.5.0", - "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.5.0", - "jest-message-util": "^25.5.0", - "jest-resolve": "^25.5.1", - "make-dir": "^3.0.0", - "natural-compare": "^1.4.0", - "pretty-format": "^25.5.0", - "semver": "^6.3.0" - } - }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } - }, - "jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - } - }, - "jest-worker": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", - "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", - "dev": true, - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", - "dev": true, - "requires": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", - "xml-name-validator": "^3.0.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", + "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "locate-path": { @@ -16553,20 +9358,6 @@ "p-locate": "^4.1.0" } }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -16591,513 +9382,358 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - } - }, - "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "dev": true, - "requires": { - "xmlchars": "^2.1.1" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "dev": true, - "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - }, - "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "dev": true, - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" + "find-up": "^4.0.0" } } } }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true + }, + "is-ci": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", + "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "dev": true, + "requires": { + "ci-info": "^3.1.1" + } + }, + "is-core-module": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", + "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", + "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", + "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "dev": true + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + "has-symbols": "^1.0.2" } }, - "jest-docblock": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-26.0.0.tgz", - "integrity": "sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w==", + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-weakref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", + "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", "dev": true, "requires": { - "detect-newline": "^3.0.0" + "call-bind": "^1.0.0" } }, - "jest-each": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.5.0.tgz", - "integrity": "sha512-QBogUxna3D8vtiItvn54xXde7+vuzqRrEeaw8r1s+1TG9eZLVJE5ZkKoSUlqFwRjnlaA4hyKGiu9OlkFIuKnjA==", + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "jest-util": "^25.5.0", - "pretty-format": "^25.5.0" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "jest-util": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.5.0.tgz", - "integrity": "sha512-KVlX+WWg1zUTB9ktvhsg2PXZVdkI1NBevOJSkTKYAyXyH4QSvh+Lay/e/v+bmaFfrkfx43xD8QTfgobzlEXdIA==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "chalk": "^3.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "make-dir": "^3.0.0" - } + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true } } }, - "jest-environment-jsdom": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", - "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2", - "jsdom": "^16.4.0" - }, - "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - } + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" } }, - "jest-environment-node": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", - "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "requires": { - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "istanbul-reports": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", + "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", "dev": true }, - "jest-haste-map": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", - "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", + "jest": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", + "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.6.2", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" + "@jest/core": "^27.3.0", + "import-local": "^3.0.2", + "jest-cli": "^27.3.0" } }, - "jest-jasmine2": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", - "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", + "jest-changed-files": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", + "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", "dev": true, "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/types": "^27.2.5", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", + "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", + "dev": true, + "requires": { + "@jest/environment": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.6.2", + "dedent": "^0.7.0", + "expect": "^27.3.0", "is-generator-fn": "^2.0.0", - "jest-each": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2", - "throat": "^5.0.0" - }, - "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true - }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } - }, - "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-each": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", - "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-util": "^26.6.2", - "pretty-format": "^26.6.2" - } - }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "jest-each": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17109,31 +9745,76 @@ } } }, - "jest-leak-detector": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", - "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", + "jest-cli": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", + "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", + "dev": true, + "requires": { + "@jest/core": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "import-local": "^3.0.2", + "jest-config": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", + "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", "dev": true, "requires": { - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "@babel/core": "^7.1.0", + "@jest/test-sequencer": "^27.3.0", + "@jest/types": "^27.2.5", + "babel-jest": "^27.3.0", + "chalk": "^4.0.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.4", + "is-ci": "^3.0.0", + "jest-circus": "^27.3.0", + "jest-environment-jsdom": "^27.3.0", + "jest-environment-node": "^27.3.0", + "jest-get-type": "^27.0.6", + "jest-jasmine2": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-runner": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.0" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17145,14 +9826,14 @@ } } }, - "jest-matcher-utils": { + "jest-diff": { "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.5.0.tgz", - "integrity": "sha512-VWI269+9JS5cpndnpCwm7dy7JtGQT30UHfrnM3mXl22gHGt/b7NkjBqXfbhZ8V4B7ANUsjK18PlSBmG0YH7gjw==", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", + "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", "dev": true, "requires": { "chalk": "^3.0.0", - "jest-diff": "^25.5.0", + "diff-sequences": "^25.2.6", "jest-get-type": "^25.2.6", "pretty-format": "^25.5.0" }, @@ -17169,38 +9850,49 @@ } } }, - "jest-message-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", - "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", + "jest-docblock": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", + "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.6.2", - "@types/stack-utils": "^2.0.0", + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", + "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2", - "slash": "^3.0.0", - "stack-utils": "^2.0.2" + "jest-get-type": "^27.0.6", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0" }, "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17209,306 +9901,210 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - } } } }, - "jest-mock": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.5.0.tgz", - "integrity": "sha512-eXWuTV8mKzp/ovHc5+3USJMYsTBhyQ+5A1Mak35dey/RG8GlM4YWVylZuGgVXinaW6tpvk/RSecmF37FKUlpXA==", + "jest-environment-jsdom": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", + "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", "dev": true, "requires": { - "@jest/types": "^25.5.0" - }, - "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } + "@jest/environment": "^27.3.0", + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0", + "jsdom": "^16.6.0" } }, - "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "jest-environment-node": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", + "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", "dev": true, - "requires": {} + "requires": { + "@jest/environment": "^27.3.0", + "@jest/fake-timers": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "jest-mock": "^27.3.0", + "jest-util": "^27.3.0" + } }, - "jest-regex-util": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", - "integrity": "sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==", + "jest-get-type": { + "version": "25.2.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", + "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", "dev": true }, - "jest-resolve": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", - "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", + "jest-haste-map": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", + "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "chalk": "^4.0.0", + "@jest/types": "^27.2.5", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", "graceful-fs": "^4.2.4", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.6.2", - "read-pkg-up": "^7.0.1", - "resolve": "^1.18.1", - "slash": "^3.0.0" + "jest-regex-util": "^27.0.6", + "jest-serializer": "^27.0.6", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", + "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@jest/environment": "^27.3.0", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.3.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "pretty-format": "^27.3.0", + "throat": "^6.0.1" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true - }, - "parse-json": { + } + } + }, + "jest-leak-detector": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", + "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", + "dev": true, + "requires": { + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" + }, + "dependencies": { + "ansi-styles": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } + "jest-get-type": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "dev": true }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "pretty-format": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" } }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true } } }, - "jest-resolve-dependencies": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", - "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.6.2" - } - }, - "jest-runner": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", - "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", + "jest-matcher-utils": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", + "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.7.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.6.2", - "jest-leak-detector": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", - "jest-runtime": "^26.6.3", - "jest-util": "^26.6.2", - "jest-worker": "^26.6.2", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" + "jest-diff": "^27.3.0", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" }, "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } + "diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true }, - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "jest-diff": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", + "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" } }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17520,118 +10116,47 @@ } } }, - "jest-runtime": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", - "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "jest-message-util": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", + "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", "dev": true, "requires": { - "@jest/console": "^26.6.2", - "@jest/environment": "^26.6.2", - "@jest/fake-timers": "^26.6.2", - "@jest/globals": "^26.6.2", - "@jest/source-map": "^26.6.2", - "@jest/test-result": "^26.6.2", - "@jest/transform": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/yargs": "^15.0.0", + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.2.5", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "cjs-module-lexer": "^0.6.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.6.3", - "jest-haste-map": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-snapshot": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", + "micromatch": "^4.0.4", + "pretty-format": "^27.3.0", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.4.1" + "stack-utils": "^2.0.3" }, "dependencies": { - "@jest/environment": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", - "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.6.2", - "@jest/types": "^26.6.2", - "@types/node": "*", - "jest-mock": "^26.6.2" - } - }, - "@jest/fake-timers": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", - "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.6.2", - "jest-mock": "^26.6.2", - "jest-util": "^26.6.2" - } - }, - "jest-config": { - "version": "26.6.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", - "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", + "@babel/code-frame": { + "version": "7.15.8", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", + "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.6.3", - "@jest/types": "^26.6.2", - "babel-jest": "^26.6.3", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.6.2", - "jest-environment-node": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.6.3", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.6.2", - "jest-util": "^26.6.2", - "jest-validate": "^26.6.2", - "micromatch": "^4.0.2", - "pretty-format": "^26.6.2" + "@babel/highlight": "^7.14.5" } }, - "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "jest-mock": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", - "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "@types/node": "*" - } - }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17643,10 +10168,126 @@ } } }, + "jest-mock": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", + "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", + "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "dev": true + }, + "jest-resolve": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", + "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", + "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", + "dev": true, + "requires": { + "@jest/types": "^27.2.5", + "jest-regex-util": "^27.0.6", + "jest-snapshot": "^27.3.0" + } + }, + "jest-runner": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", + "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", + "dev": true, + "requires": { + "@jest/console": "^27.3.0", + "@jest/environment": "^27.3.0", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-docblock": "^27.0.6", + "jest-environment-jsdom": "^27.3.0", + "jest-environment-node": "^27.3.0", + "jest-haste-map": "^27.3.0", + "jest-leak-detector": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-runtime": "^27.3.0", + "jest-util": "^27.3.0", + "jest-worker": "^27.3.0", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", + "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", + "dev": true, + "requires": { + "@jest/console": "^27.3.0", + "@jest/environment": "^27.3.0", + "@jest/globals": "^27.3.0", + "@jest/source-map": "^27.0.6", + "@jest/test-result": "^27.3.0", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-mock": "^27.3.0", + "jest-regex-util": "^27.0.6", + "jest-resolve": "^27.3.0", + "jest-snapshot": "^27.3.0", + "jest-util": "^27.3.0", + "jest-validate": "^27.3.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0", + "yargs": "^16.2.0" + } + }, "jest-serializer": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", - "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", + "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", "dev": true, "requires": { "@types/node": "*", @@ -17654,88 +10295,76 @@ } }, "jest-snapshot": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", - "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", + "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", "dev": true, "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/parser": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/types": "^26.6.2", + "@jest/transform": "^27.3.0", + "@jest/types": "^27.2.5", "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.0.0", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^26.6.2", + "expect": "^27.3.0", "graceful-fs": "^4.2.4", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.6.2", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-resolve": "^26.6.2", + "jest-diff": "^27.3.0", + "jest-get-type": "^27.0.6", + "jest-haste-map": "^27.3.0", + "jest-matcher-utils": "^27.3.0", + "jest-message-util": "^27.3.0", + "jest-resolve": "^27.3.0", + "jest-util": "^27.3.0", "natural-compare": "^1.4.0", - "pretty-format": "^26.6.2", + "pretty-format": "^27.3.0", "semver": "^7.3.2" }, "dependencies": { - "diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "expect": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", - "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", - "dev": true, - "requires": { - "@jest/types": "^26.6.2", - "ansi-styles": "^4.0.0", - "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.6.2", - "jest-message-util": "^26.6.2", - "jest-regex-util": "^26.0.0" - } + "diff-sequences": { + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", + "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "dev": true }, "jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", + "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" + "diff-sequences": "^27.0.6", + "jest-get-type": "^27.0.6", + "pretty-format": "^27.3.0" } }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, - "jest-matcher-utils": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", - "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - } - }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17748,33 +10377,39 @@ } }, "jest-util": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", - "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", + "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.2.5", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", - "is-ci": "^2.0.0", - "micromatch": "^4.0.2" + "is-ci": "^3.0.0", + "picomatch": "^2.2.3" } }, "jest-validate": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", - "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", + "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "camelcase": "^6.0.0", + "@jest/types": "^27.2.5", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^26.3.0", + "jest-get-type": "^27.0.6", "leven": "^3.1.0", - "pretty-format": "^26.6.2" + "pretty-format": "^27.3.0" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -17782,20 +10417,20 @@ "dev": true }, "jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", + "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", + "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", "dev": true, "requires": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "@jest/types": "^27.2.5", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, @@ -17808,29 +10443,40 @@ } }, "jest-watcher": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", - "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", + "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", "dev": true, "requires": { - "@jest/test-result": "^26.6.2", - "@jest/types": "^26.6.2", + "@jest/test-result": "^27.3.0", + "@jest/types": "^27.2.5", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.6.2", + "jest-util": "^27.3.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", - "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", + "version": "27.3.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", + "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", "dev": true, "requires": { "@types/node": "*", "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" + "supports-color": "^8.0.0" + }, + "dependencies": { + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "js-tokens": { @@ -17849,12 +10495,6 @@ "esprima": "^4.0.0" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true - }, "jsdom": { "version": "16.7.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", @@ -17891,9 +10531,9 @@ }, "dependencies": { "acorn": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz", - "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", + "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", "dev": true } } @@ -17904,24 +10544,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -17934,12 +10556,6 @@ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, "json5": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", @@ -17958,24 +10574,6 @@ "graceful-fs": "^4.1.6" } }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", @@ -17998,32 +10596,6 @@ "type-check": "~0.4.0" } }, - "lines-and-columns": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -18046,33 +10618,24 @@ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", "dev": true }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, "lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", - "dev": true - }, "lodash.truncate": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", "dev": true }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -18129,21 +10692,6 @@ "tmpl": "1.0.x" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, "merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -18167,18 +10715,18 @@ } }, "mime-db": { - "version": "1.49.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", - "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", + "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", "dev": true }, "mime-types": { - "version": "2.1.32", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", - "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", + "version": "2.1.33", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", + "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", "dev": true, "requires": { - "mime-db": "1.49.0" + "mime-db": "1.50.0" } }, "mimic-fn": { @@ -18202,59 +10750,18 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -18267,47 +10774,12 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, - "node-notifier": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", - "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", - "dev": true, - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.2.0", - "semver": "^7.3.2", - "shellwords": "^0.1.1", - "uuid": "^8.3.0", - "which": "^2.0.2" - } - }, "node-releases": { - "version": "1.1.75", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", - "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", + "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", "dev": true }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -18329,80 +10801,6 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, "object-inspect": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", @@ -18415,15 +10813,6 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, "object.assign": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", @@ -18436,24 +10825,15 @@ "object-keys": "^1.1.1" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, "object.values": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.4.tgz", - "integrity": "sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", + "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.18.2" + "es-abstract": "^1.19.1" } }, "once": { @@ -18488,18 +10868,6 @@ "word-wrap": "^1.2.3" } }, - "p-each-series": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", - "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, "p-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", @@ -18533,28 +10901,12 @@ "callsites": "^3.0.0" } }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", "dev": true }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", @@ -18584,10 +10936,10 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, "picomatch": { @@ -18596,12 +10948,6 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", "dev": true }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, "pirates": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", @@ -18620,27 +10966,6 @@ "find-up": "^2.1.0" } }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -18648,9 +10973,9 @@ "dev": true }, "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", + "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", "dev": true }, "pretty-format": { @@ -18687,6 +11012,15 @@ "@types/istanbul-lib-report": "*" } }, + "@types/yargs": { + "version": "15.0.14", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", + "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", @@ -18706,9 +11040,9 @@ "dev": true }, "prompts": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", - "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "requires": { "kleur": "^3.0.3", @@ -18721,28 +11055,12 @@ "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, - "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", - "dev": true - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -18750,58 +11068,10 @@ "dev": true }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "dependencies": { - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - } - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "realpath-native": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-2.0.0.tgz", - "integrity": "sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q==", - "dev": true - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true }, "regexpp": { "version": "3.2.0", @@ -18809,113 +11079,6 @@ "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", "dev": true }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dev": true, - "requires": { - "lodash": "^4.17.19" - } - }, - "request-promise-native": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz", - "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==", - "dev": true, - "requires": { - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "dependencies": { - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dev": true, - "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18928,12 +11091,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -18966,16 +11123,10 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", "dev": true }, "reusify": { @@ -18993,12 +11144,6 @@ "glob": "^7.1.3" } }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -19014,256 +11159,12 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "dev": true, - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, "saxes": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", @@ -19282,41 +11183,6 @@ "lru-cache": "^6.0.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } - } - }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -19332,213 +11198,44 @@ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "dev": true, - "optional": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" } }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "signal-exit": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", + "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, "source-map": { @@ -19546,23 +11243,10 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, "source-map-support": { - "version": "0.5.19", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", - "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "version": "0.5.20", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", + "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -19577,80 +11261,16 @@ } } }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.10", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.10.tgz", - "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "dev": true, - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, "stack-utils": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.5.tgz", - "integrity": "sha512-KZiTzuV3CnSnSvgMRrARVCj+Ht7rMbauGDK0LdVFRGyenwdylpajAp4Q0i6SX8rEmbTpMMf6ryq2gb8pPq2WgQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -19664,90 +11284,6 @@ } } }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -19759,14 +11295,14 @@ } }, "string-width": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", - "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" + "strip-ansi": "^6.0.1" } }, "string.prototype.trimend": { @@ -19790,12 +11326,12 @@ } }, "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "requires": { - "ansi-regex": "^5.0.0" + "ansi-regex": "^5.0.1" } }, "strip-bom": { @@ -19804,12 +11340,6 @@ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, "strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -19848,23 +11378,23 @@ "dev": true }, "table": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz", - "integrity": "sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", + "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", "dev": true, "requires": { "ajv": "^8.0.1", "lodash.clonedeep": "^4.5.0", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0" + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" }, "dependencies": { "ajv": { - "version": "8.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.2.tgz", - "integrity": "sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w==", + "version": "8.6.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", + "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -19882,9 +11412,9 @@ } }, "tapable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.0.tgz", - "integrity": "sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==" + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, "terminal-link": { "version": "2.1.1", @@ -19914,15 +11444,15 @@ "dev": true }, "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", "dev": true }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-fast-properties": { @@ -19931,38 +11461,6 @@ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -19993,30 +11491,28 @@ } }, "ts-jest": { - "version": "26.5.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.6.tgz", - "integrity": "sha512-rua+rCP8DxpA8b4DQD/6X2HQS8Zy/xzViVYfEs2OQu68tkCuKLV0Md8pmX55+W24uRIyAsf/BajRfxOs+R2MKA==", + "version": "27.0.7", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", + "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", "dev": true, "requires": { "bs-logger": "0.x", - "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^26.1.0", + "jest-util": "^27.0.0", "json5": "2.x", - "lodash": "4.x", + "lodash.memoize": "4.x", "make-error": "1.x", - "mkdirp": "1.x", "semver": "7.x", "yargs-parser": "20.x" } }, "ts-node": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz", - "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", + "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", "dev": true, "requires": { - "@cspotcode/source-map-support": "0.6.1", + "@cspotcode/source-map-support": "0.7.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -20088,21 +11584,6 @@ "tslib": "^1.8.1" } }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -20134,10 +11615,10 @@ } }, "typescript": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.3.tgz", - "integrity": "sha512-4xfscpisVgqqDfPaJo5vkd+Qd/ItkoagnHpufr+i2QCHBsNYp+G7UAoyFl8aPtx879u38wPV65rZ8qbGZijalA==", - "peer": true + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", + "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "dev": true }, "typescript-to-lua": { "version": "0.39.6", @@ -20170,72 +11651,12 @@ "which-boxed-primitive": "^1.0.2" } }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - } - } - }, "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -20245,25 +11666,6 @@ "punycode": "^2.1.0" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "optional": true - }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -20271,9 +11673,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.2.tgz", - "integrity": "sha512-TxNb7YEUwkLXCQYeudi6lgQ/SZrzNO4kMdlqVxaZPUIUjCv6iSSypUQX70kNBSERpQ8fk48+d61FXk+tgqcWow==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", + "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -20281,27 +11683,6 @@ "source-map": "^0.7.3" } }, - "validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "dev": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, "w3c-hr-time": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", @@ -20383,12 +11764,6 @@ "is-symbol": "^1.0.3" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -20396,9 +11771,9 @@ "dev": true }, "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "requires": { "ansi-styles": "^4.0.0", @@ -20425,9 +11800,9 @@ } }, "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", + "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", "dev": true, "requires": {} }, @@ -20444,9 +11819,9 @@ "dev": true }, "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true }, "yallist": { @@ -20456,83 +11831,18 @@ "dev": true }, "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" } }, "yargs-parser": { diff --git a/package.json b/package.json index da92f606d..0fa2592ff 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,12 @@ "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.4.3" + "typescript": "~4.4.4" }, "dependencies": { "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.4.3" + "source-map": "^0.7.3" }, "devDependencies": { "@types/fs-extra": "^8.1.0", @@ -63,12 +62,13 @@ "eslint-plugin-jest": "^24.4.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^26.0.1", - "jest-circus": "^25.1.0", + "jest": "^27.3.0", + "jest-circus": "^27.3.0", "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^26.3.0", - "ts-node": "^10.2.1" + "ts-jest": "^27.0.7", + "ts-node": "^10.3.0", + "typescript": "~4.4.4" } } diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index f9d65a555..5897dbad9 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -3,7 +3,7 @@ "outDir": "../../dist/lualib", "target": "esnext", "lib": ["esnext"], - "types": ["../../language-extensions", "lua-types/5.4"], + "types": ["lua-types/5.4"], "skipLibCheck": true, "noUnusedLocals": true, From 3235c6c77362b8a176c6fcc9afa0de2f456957f1 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 25 Oct 2021 22:22:47 +0200 Subject: [PATCH 409/764] Correctly handle awaited promises rejecting in a try/catch (#1144) * Make await throw if awaited thing is a rejected promise * fix almost all tests * Also fix lambas in async * Fix bug in try/catch adding extra return twice * Fix prettier --- src/lualib/Await.ts | 39 +++++++++---- src/transformation/visitors/async-await.ts | 3 +- src/transformation/visitors/errors.ts | 56 ++++++++---------- src/transformation/visitors/return.ts | 63 ++++++++++++++------ test/unit/builtins/async-await.spec.ts | 67 ++++++++++++++++++++++ 5 files changed, 167 insertions(+), 61 deletions(-) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index 61f383e96..0bbfdd09f 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -14,6 +14,8 @@ // }; // +type ErrorHandler = (this: void, error: unknown) => unknown; + // eslint-disable-next-line @typescript-eslint/promise-function-async function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { return new Promise((resolve, reject) => { @@ -23,30 +25,47 @@ function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { function adopt(value: unknown) { return value instanceof __TS__Promise ? value : Promise.resolve(value); } - function fulfilled(value) { - const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); + function fulfilled(value: unknown) { + const [success, errorOrErrorHandler, resultOrError] = coroutine.resume(asyncCoroutine, value); if (success) { - step(resultOrError); + step(resultOrError, errorOrErrorHandler); } else { reject(resultOrError); } } - function step(result: unknown) { + function rejected(handler: ErrorHandler | undefined) { + if (handler) { + return (value: unknown) => { + const [success, valueOrError] = pcall(handler, value); + if (success) { + step(valueOrError, handler); + } else { + reject(valueOrError); + } + }; + } else { + // If no catch clause, just reject + return value => { + reject(value); + }; + } + } + function step(result: unknown, errorHandler: ErrorHandler | undefined) { if (coroutine.status(asyncCoroutine) === "dead") { resolve(result); } else { - adopt(result).then(fulfilled, reason => reject(reason)); + adopt(result).then(fulfilled, rejected(errorHandler)); } } - const [success, resultOrError] = coroutine.resume(asyncCoroutine); + const [success, errorOrErrorHandler, resultOrError] = coroutine.resume(asyncCoroutine); if (success) { - step(resultOrError); + step(resultOrError, errorOrErrorHandler); } else { - reject(resultOrError); + reject(errorOrErrorHandler); } }); } -function __TS__Await(this: void, thing: unknown) { - return coroutine.yield(thing); +function __TS__Await(this: void, errorHandler: ErrorHandler, thing: unknown) { + return coroutine.yield(errorHandler, thing); } diff --git a/src/transformation/visitors/async-await.ts b/src/transformation/visitors/async-await.ts index c6dcc86dc..6b43d4c84 100644 --- a/src/transformation/visitors/async-await.ts +++ b/src/transformation/visitors/async-await.ts @@ -16,7 +16,8 @@ export const transformAwaitExpression: FunctionVisitor = (no } const expression = context.transformExpression(node.expression); - return transformLuaLibFunction(context, LuaLibFeature.Await, node, expression); + const catchIdentifier = lua.createIdentifier("____catch"); + return transformLuaLibFunction(context, LuaLibFeature.Await, node, catchIdentifier, expression); }; export function isAsyncFunction(declaration: ts.FunctionLikeDeclaration): boolean { diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 0f067c939..05601d8c8 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -2,10 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { createUnpackCall } from "../utils/lua-ast"; -import { findScope, ScopeType } from "../utils/scope"; +import { ScopeType } from "../utils/scope"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; import { isInMultiReturnFunction } from "./language-extensions/multi"; +import { createReturnStatement } from "./return"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); @@ -15,7 +16,7 @@ export const transformTryStatement: FunctionVisitor = (statemen const result: lua.Statement[] = []; - let returnedIdentifier: lua.Identifier | undefined; + const returnedIdentifier = lua.createIdentifier("____hasReturned"); let returnCondition: lua.Expression | undefined; const pCall = lua.createIdentifier("pcall"); @@ -23,16 +24,16 @@ export const transformTryStatement: FunctionVisitor = (statemen if (statement.catchClause && statement.catchClause.block.statements.length > 0) { // try with catch - let [catchBlock, catchScope] = transformScopeBlock(context, statement.catchClause.block, ScopeType.Catch); - if (statement.catchClause.variableDeclaration) { - // Replace ____returned with catch variable - returnedIdentifier = transformIdentifier( - context, - statement.catchClause.variableDeclaration.name as ts.Identifier - ); - } else if (tryScope.functionReturned || catchScope.functionReturned) { - returnedIdentifier = lua.createIdentifier("____returned"); - } + const [catchBlock, catchScope] = transformScopeBlock(context, statement.catchClause.block, ScopeType.Catch); + + const catchParameter = statement.catchClause.variableDeclaration + ? transformIdentifier(context, statement.catchClause.variableDeclaration.name as ts.Identifier) + : undefined; + const catchParameters = () => (catchParameter ? [lua.cloneIdentifier(catchParameter)] : []); + + const catchIdentifier = lua.createIdentifier("____catch"); + const catchFunction = lua.createFunctionExpression(catchBlock, catchParameters()); + result.push(lua.createVariableDeclarationStatement(catchIdentifier, catchFunction)); const tryReturnIdentifiers = [tryResultIdentifier]; // ____try if (returnedIdentifier) { @@ -44,20 +45,18 @@ export const transformTryStatement: FunctionVisitor = (statemen } result.push(lua.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); - if ((tryScope.functionReturned || catchScope.functionReturned) && returnedIdentifier) { - // Wrap catch in function if try or catch has return - const catchCall = lua.createCallExpression(lua.createFunctionExpression(catchBlock), []); - const catchAssign = lua.createAssignmentStatement( - [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], - catchCall - ); - catchBlock = lua.createBlock([catchAssign]); - } + // Wrap catch in function if try or catch has return + const catchCall = lua.createCallExpression(catchIdentifier, [lua.cloneIdentifier(returnedIdentifier)]); + const catchAssign = lua.createAssignmentStatement( + [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], + catchCall + ); + const notTryCondition = lua.createUnaryExpression(tryResultIdentifier, lua.SyntaxKind.NotOperator); - result.push(lua.createIfStatement(notTryCondition, catchBlock)); + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([catchAssign]))); } else if (tryScope.functionReturned) { // try with return, but no catch - returnedIdentifier = lua.createIdentifier("____returned"); + // returnedIdentifier = lua.createIdentifier("____returned"); const returnedVariables = [tryResultIdentifier, returnedIdentifier, returnValueIdentifier]; result.push(lua.createVariableDeclarationStatement(returnedVariables, tryCall)); @@ -77,16 +76,7 @@ export const transformTryStatement: FunctionVisitor = (statemen } if (returnCondition && returnedIdentifier) { - // With catch clause: - // if ____returned then return ____returnValue end - // No catch clause: - // if ____try and ____returned then return ____returnValue end const returnValues: lua.Expression[] = []; - const parentTryCatch = findScope(context, ScopeType.Function | ScopeType.Try | ScopeType.Catch); - if (parentTryCatch && parentTryCatch.type !== ScopeType.Function) { - // Nested try/catch needs to prefix a 'true' return value - returnValues.push(lua.createBooleanLiteral(true)); - } if (isInMultiReturnFunction(context, statement)) { returnValues.push(createUnpackCall(context, lua.cloneIdentifier(returnValueIdentifier))); @@ -94,7 +84,7 @@ export const transformTryStatement: FunctionVisitor = (statemen returnValues.push(lua.cloneIdentifier(returnValueIdentifier)); } - const returnStatement = lua.createReturnStatement(returnValues); + const returnStatement = createReturnStatement(context, returnValues, statement); const ifReturnedStatement = lua.createIfStatement(returnCondition, lua.createBlock([returnStatement])); result.push(ifReturnedStatement); } diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 2ed0ebe3e..6a5b1bbb8 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -14,6 +14,7 @@ import { canBeMultiReturnType, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; +import { findFirstNodeAbove } from "../utils/typescript"; function transformExpressionsInReturn( context: TransformationContext, @@ -55,22 +56,10 @@ export function transformExpressionBodyToReturnStatement( node: ts.Expression ): lua.Statement { const expressions = transformExpressionsInReturn(context, node, false); - return lua.createReturnStatement(expressions, node); + return createReturnStatement(context, expressions, node); } export const transformReturnStatement: FunctionVisitor = (statement, context) => { - // Bubble up explicit return flag and check if we're inside a try/catch block - let insideTryCatch = false; - for (const scope of walkScopesUp(context)) { - scope.functionReturned = true; - - if (scope.type === ScopeType.Function) { - break; - } - - insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; - } - let results: lua.Expression[]; if (statement.expression) { @@ -80,15 +69,55 @@ export const transformReturnStatement: FunctionVisitor = (st validateAssignment(context, statement, expressionType, returnType); } - results = transformExpressionsInReturn(context, statement.expression, insideTryCatch); + results = transformExpressionsInReturn(context, statement.expression, isInTryCatch(context)); } else { // Empty return results = []; } - if (insideTryCatch) { + return createReturnStatement(context, results, statement); +}; + +export function createReturnStatement( + context: TransformationContext, + values: lua.Expression[], + node: ts.Node +): lua.ReturnStatement { + const results = [...values]; + + if (isInTryCatch(context)) { + // Bubble up explicit return flag and check if we're inside a try/catch block results.unshift(lua.createBooleanLiteral(true)); + } else if (isInAsyncFunction(node)) { + // Add nil error handler in async function and not in try + results.unshift(lua.createNilLiteral()); } - return lua.createReturnStatement(results, statement); -}; + return lua.createReturnStatement(results, node); +} + +function isInAsyncFunction(node: ts.Node): boolean { + // Check if node is in function declaration with `async` + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; + } + + return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; +} + +function isInTryCatch(context: TransformationContext): boolean { + // Check if context is in a try or catch + let insideTryCatch = false; + for (const scope of walkScopesUp(context)) { + scope.functionReturned = true; + + if (scope.type === ScopeType.Function) { + break; + } + + insideTryCatch = insideTryCatch || scope.type === ScopeType.Try || scope.type === ScopeType.Catch; + } + + return insideTryCatch; +} diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 0a9c3513e..668551bd0 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -161,6 +161,19 @@ test.each(["async function abc() {", "const abc = async () => {"])( } ); +test("can make inline async functions", () => { + util.testFunction` + const foo = async function() { return "foo"; }; + const bar = async function() { return await foo(); }; + + const { state, value } = bar() as any; + return { state, value }; + `.expectToEqual({ + state: 1, // __TS__PromiseState.Fulfilled + value: "foo", + }); +}); + test("can make async lambdas with expression body", () => { util.testFunction` const foo = async () => "foo"; @@ -369,3 +382,57 @@ test("async function can forward varargs", () => { .setTsHeader(promiseTestLib) .expectToEqual(["resolved", "A", "B", "C"]); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1105 +describe("try/catch in async function", () => { + test("await inside try/catch returns inside async function", () => { + util.testModule` + export let result = 0; + async function foo(): Promise { + try { + return await new Promise(resolve => resolve(4)); + } catch { + throw "an error occurred in the async function" + } + } + foo().then(value => { + result = value; + }); + `.expectToEqual({ result: 4 }); + }); + + test("await inside try/catch throws inside async function", () => { + util.testModule` + export let reason = ""; + async function foo(): Promise { + try { + return await new Promise((resolve, reject) => reject("test error")); + } catch (e) { + throw "an error occurred in the async function: " + e; + } + } + foo().catch(e => { + reason = e; + }); + `.expectToEqual({ reason: "an error occurred in the async function: test error" }); + }); + + test("await inside try/catch deferred rejection uses catch clause", () => { + util.testModule` + export let reason = ""; + let reject: (reason: string) => void; + + async function foo(): Promise { + try { + return await new Promise((res, rej) => { reject = rej; }); + } catch (e) { + throw "an error occurred in the async function: " + e; + } + } + foo().catch(e => { + reason = e; + }); + reject("test error"); + `.expectToEqual({ reason: "an error occurred in the async function: test error" }); + }); +}); From 8f70f506f18c3954d85600a33437dc95264849db Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Oct 2021 19:41:04 +0200 Subject: [PATCH 410/764] Implement support for void expression (#1148) * Implement support for void expression * PR feedback --- src/transformation/utils/diagnostics.ts | 6 ++-- .../visitors/expression-statement.ts | 5 +++ src/transformation/visitors/index.ts | 2 ++ src/transformation/visitors/void.ts | 33 ++++++++++++++++++ src/transpilation/transformers.ts | 2 ++ test/unit/void.spec.ts | 34 +++++++++++++++++++ 6 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 src/transformation/visitors/void.ts create mode 100644 test/unit/void.spec.ts diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index a7a63a717..d6d151de9 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -10,9 +10,9 @@ const createDiagnosticFactory = ( message: MessageProvider ) => createSerialDiagnosticFactory((node: ts.Node, ...args: TArgs) => ({ - file: node.getSourceFile(), - start: node.getStart(), - length: node.getWidth(), + file: ts.getOriginalNode(node).getSourceFile(), + start: ts.getOriginalNode(node).getStart(), + length: ts.getOriginalNode(node).getWidth(), messageText: typeof message === "string" ? message : message(...args), category, })); diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 228307f25..2f64ec9d8 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -9,6 +9,7 @@ import { transformTableSetExpression, } from "./language-extensions/table"; import { transformUnaryExpressionStatement } from "./unary-expression"; +import { transformVoidExpressionStatement } from "./void"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { const expression = node.expression; @@ -21,6 +22,10 @@ export const transformExpressionStatement: FunctionVisitor = () => undefined; const transformParenthesizedExpression: FunctionVisitor = (node, context) => @@ -98,4 +99,5 @@ export const standardVisitors: Visitors = { [ts.SyntaxKind.VariableStatement]: transformVariableStatement, [ts.SyntaxKind.WhileStatement]: transformWhileStatement, [ts.SyntaxKind.YieldExpression]: transformYieldExpression, + [ts.SyntaxKind.VoidExpression]: transformVoidExpression, }; diff --git a/src/transformation/visitors/void.ts b/src/transformation/visitors/void.ts new file mode 100644 index 000000000..569198a93 --- /dev/null +++ b/src/transformation/visitors/void.ts @@ -0,0 +1,33 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; +import { FunctionVisitor } from "../context/visitors"; +import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void +export const transformVoidExpression: FunctionVisitor = (node, context) => { + // If content is a literal it is safe to replace the entire expression with nil + if (ts.isLiteralExpression(node.expression)) { + return lua.createNilLiteral(node); + } + + // (function() local ____ = end)() + return createImmediatelyInvokedFunctionExpression( + [ + lua.createVariableDeclarationStatement( + lua.createAnonymousIdentifier(), + context.transformExpression(node.expression) + ), + ], + [], + node + ); +}; + +export const transformVoidExpressionStatement = (node: ts.VoidExpression, context: TransformationContext) => + // In case of a void expression statement we can omit the IIFE + lua.createVariableDeclarationStatement( + lua.createAnonymousIdentifier(), + context.transformExpression(node.expression), + node + ); diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index 386d7f475..ac81f6d68 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -71,6 +71,8 @@ export const stripParenthesisExpressionsTransformer: ts.TransformerFactory { + util.testExpression`void (${value})`.expectToMatchJsResult(); +}); + +test("void applies to function declarations", () => { + util.testFunction` + let result = 0; + void function setResult() { + result = 1; + }(); + return result; + `.expectToMatchJsResult(); +}); + +test("void used to ignore function return values", () => { + util.testFunction` + let result = 0; + function setResult() { + result = 1; + return 3 + }; + + void(setResult()); + + return result; + `.expectToMatchJsResult(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1102 +test("void works with lambdas", () => { + util.testExpression`void (() => {})()`.expectToMatchJsResult(); +}); From 1b9d48fbffa60fff721aa92ce5328aa1dbf9d38f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Oct 2021 19:41:25 +0200 Subject: [PATCH 411/764] Fix promise then chaining and disallow using try/catch in 5.1 in async and generator functions (#1150) * Make await throw if awaited thing is a rejected promise * fix almost all tests * Also fix lambas in async * Fix bug in try/catch adding extra return twice * Fix prettier * Add failing tests * Add diagnostic to prevent 5.1 users from trying to use try/catch in async function * Diagnostic for try/catch in generator or async function in 5.1 * Fix missing case in promise then --- src/lualib/Promise.ts | 21 +++++++-- src/transformation/utils/typescript/nodes.ts | 21 +++++++++ src/transformation/visitors/errors.ts | 15 ++++++ src/transformation/visitors/return.ts | 12 +---- test/unit/builtins/async-await.spec.ts | 48 ++++++++++++++------ test/unit/builtins/promise.spec.ts | 42 +++++++++++++++++ test/unit/functions/generators.spec.ts | 21 +++++++++ test/util.ts | 13 ++++++ 8 files changed, 165 insertions(+), 28 deletions(-) diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index c8fdea117..76f119c38 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -70,13 +70,16 @@ class __TS__Promise implements Promise { onFulfilled?: FulfillCallback, onRejected?: RejectCallback ): Promise { - const { promise, resolve, reject } = __TS__PromiseDeferred(); + const { promise, resolve, reject } = __TS__PromiseDeferred(); + + const isFulfilled = this.state === __TS__PromiseState.Fulfilled; + const isRejected = this.state === __TS__PromiseState.Rejected; if (onFulfilled) { const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); this.fulfilledCallbacks.push(internalCallback); - if (this.state === __TS__PromiseState.Fulfilled) { + if (isFulfilled) { // If promise already resolved, immediately call callback internalCallback(this.value); } @@ -89,13 +92,23 @@ class __TS__Promise implements Promise { const internalCallback = this.createPromiseResolvingCallback(onRejected, resolve, reject); this.rejectedCallbacks.push(internalCallback); - if (this.state === __TS__PromiseState.Rejected) { + if (isRejected) { // If promise already rejected, immediately call callback internalCallback(this.rejectionReason); } } - return promise; + if (isFulfilled) { + // If promise already resolved, also resolve returned promise + resolve(this.value); + } + + if (isRejected) { + // If promise already rejected, also reject returned promise + reject(this.rejectionReason); + } + + return promise as Promise; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch public catch(onRejected?: (reason: any) => TResult | PromiseLike): Promise { diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index 3007c4d7d..ef6cec08f 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { findFirstNodeAbove } from "."; import { TransformationContext } from "../../context"; export function isAssignmentPattern(node: ts.Node): node is ts.AssignmentPattern { @@ -25,6 +26,26 @@ export function isInDestructingAssignment(node: ts.Node): boolean { ); } +export function isInAsyncFunction(node: ts.Node): boolean { + // Check if node is in function declaration with `async` + const declaration = findFirstNodeAbove(node, ts.isFunctionLike); + if (!declaration) { + return false; + } + + return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; +} + +export function isInGeneratorFunction(node: ts.Node): boolean { + // Check if node is in function declaration with `async` + const declaration = findFirstNodeAbove(node, ts.isFunctionDeclaration); + if (!declaration) { + return false; + } + + return declaration.asteriskToken !== undefined; +} + /** * Quite hacky, avoid unless absolutely necessary! */ diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 05601d8c8..2b58428b2 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -1,8 +1,11 @@ import * as ts from "typescript"; +import { LuaTarget } from "../.."; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; +import { unsupportedForTarget } from "../utils/diagnostics"; import { createUnpackCall } from "../utils/lua-ast"; import { ScopeType } from "../utils/scope"; +import { isInAsyncFunction, isInGeneratorFunction } from "../utils/typescript"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; import { isInMultiReturnFunction } from "./language-extensions/multi"; @@ -11,6 +14,18 @@ import { createReturnStatement } from "./return"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); + if (context.options.luaTarget === LuaTarget.Lua51 && isInAsyncFunction(statement)) { + context.diagnostics.push(unsupportedForTarget(statement, "try/catch inside async functions", LuaTarget.Lua51)); + return tryBlock.statements; + } + + if (context.options.luaTarget === LuaTarget.Lua51 && isInGeneratorFunction(statement)) { + context.diagnostics.push( + unsupportedForTarget(statement, "try/catch inside generator functions", LuaTarget.Lua51) + ); + return tryBlock.statements; + } + const tryResultIdentifier = lua.createIdentifier("____try"); const returnValueIdentifier = lua.createIdentifier("____returnValue"); diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 6a5b1bbb8..1bd1bb0fe 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -14,7 +14,7 @@ import { canBeMultiReturnType, } from "./language-extensions/multi"; import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; -import { findFirstNodeAbove } from "../utils/typescript"; +import { isInAsyncFunction } from "../utils/typescript"; function transformExpressionsInReturn( context: TransformationContext, @@ -96,16 +96,6 @@ export function createReturnStatement( return lua.createReturnStatement(results, node); } -function isInAsyncFunction(node: ts.Node): boolean { - // Check if node is in function declaration with `async` - const declaration = findFirstNodeAbove(node, ts.isFunctionLike); - if (!declaration) { - return false; - } - - return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; -} - function isInTryCatch(context: TransformationContext): boolean { // Check if context is in a try or catch let insideTryCatch = false; diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 668551bd0..c08514236 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -1,5 +1,6 @@ import { ModuleKind, ScriptTarget } from "typescript"; -import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../../src"; +import { awaitMustBeInAsyncFunction, unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const promiseTestLib = ` @@ -385,8 +386,9 @@ test("async function can forward varargs", () => { // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1105 describe("try/catch in async function", () => { - test("await inside try/catch returns inside async function", () => { - util.testModule` + util.testEachVersion( + "await inside try/catch returns inside async function", + () => util.testModule` export let result = 0; async function foo(): Promise { try { @@ -398,11 +400,17 @@ describe("try/catch in async function", () => { foo().then(value => { result = value; }); - `.expectToEqual({ result: 4 }); - }); + `, + // Cannot execute LuaJIT with test runner + { + ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: 4 })), + [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + } + ); - test("await inside try/catch throws inside async function", () => { - util.testModule` + util.testEachVersion( + "await inside try/catch throws inside async function", + () => util.testModule` export let reason = ""; async function foo(): Promise { try { @@ -414,11 +422,19 @@ describe("try/catch in async function", () => { foo().catch(e => { reason = e; }); - `.expectToEqual({ reason: "an error occurred in the async function: test error" }); - }); + `, + { + ...util.expectEachVersionExceptJit(builder => + builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) + ), + [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + } + ); - test("await inside try/catch deferred rejection uses catch clause", () => { - util.testModule` + util.testEachVersion( + "await inside try/catch deferred rejection uses catch clause", + () => + util.testModule` export let reason = ""; let reject: (reason: string) => void; @@ -433,6 +449,12 @@ describe("try/catch in async function", () => { reason = e; }); reject("test error"); - `.expectToEqual({ reason: "an error occurred in the async function: test error" }); - }); + `, + { + ...util.expectEachVersionExceptJit(builder => + builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) + ), + [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + } + ); }); diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index 4a22f7514..60e30dcf1 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -709,6 +709,48 @@ test("promise is instanceof promise", () => { util.testExpression`Promise.resolve(4) instanceof Promise`.expectToMatchJsResult(); }); +test("chained then on resolved promise", () => { + util.testFunction` + Promise.resolve("result1").then(undefined, () => {}).then(value => log(value)); + Promise.resolve("result2").then(value => "then1", () => {}).then(value => log(value)); + Promise.resolve("result3").then(value => undefined, () => {}).then(value => log(value ?? "undefined")); + Promise.resolve("result4").then(value => "then2").then(value => [value, "then3"]).then(([v1, v2]) => log(v1, v2)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["result1", "then1", "undefined", "then2", "then3"]); +}); + +test("chained catch on rejected promise", () => { + util.testFunction` + Promise.reject("reason1").then(() => {}).then(v => log("resolved", v), reason => log("rejected", reason)); + Promise.reject("reason2").then(() => {}, () => "reason3").then(v => log("resolved", v)); + Promise.reject("reason4").then(() => {}, () => undefined).then(v => log("resolved", v ?? "undefined")); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejected", "reason1", "resolved", "reason3", "resolved", "undefined"]); +}); + +// Issue 2 from https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1105 +test("catch after then catches rejected promise", () => { + util.testFunction` + Promise.reject('test error') + .then(result => { + log("then", result); + }) + .catch(e => { + log("catch", e); + }) + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch", "test error"]); +}); + describe("Promise.all", () => { test("resolves once all arguments are resolved", () => { util.testFunction` diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 7065aecf6..03b7f3bfd 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -1,3 +1,5 @@ +import { LuaTarget } from "../../../src/CompilerOptions"; +import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("generator parameters", () => { @@ -147,3 +149,22 @@ test("hoisting", () => { } `.expectToMatchJsResult(); }); + +util.testEachVersion( + "generator yield inside try/catch", + () => util.testFunction` + function* generator() { + try { + yield 4; + } catch { + throw "something went wrong"; + } + } + return generator().next(); + `, + // Cannot execute LuaJIT with test runner + { + ...util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()), + [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + } +); diff --git a/test/util.ts b/test/util.ts index 7752496a6..7d5ea6b95 100644 --- a/test/util.ts +++ b/test/util.ts @@ -65,6 +65,19 @@ export function testEachVersion( } } +export function expectEachVersionExceptJit( + expectation: (builder: T) => void +): Record void) | boolean> { + return { + [tstl.LuaTarget.Universal]: expectation, + [tstl.LuaTarget.Lua51]: expectation, + [tstl.LuaTarget.Lua52]: expectation, + [tstl.LuaTarget.Lua53]: expectation, + [tstl.LuaTarget.Lua54]: expectation, + [tstl.LuaTarget.LuaJIT]: false, // Exclude JIT + }; +} + const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { const originalFunction = descriptor.value as any; const memoized = new WeakMap(); From 446a4b711b313c4a0a1cfa4c89f82baffd86e5cf Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 26 Oct 2021 20:02:30 +0200 Subject: [PATCH 412/764] CHANGELOG.md 1.1.0 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ec913ca1..3b5736e17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 1.1.0 + +- **[Breaking]** We now use TypeScript's JSX transformer instead of maintaining our own. As a result, `React.createElement` now requires a self parameter, so remove `@noSelf`, `this: void` if necessary. +- **[Breaking(-ish)]** Due to limitations in 5.1, try/catch can no longer be used in async or generator functions when targetting Lua 5.1. This was already broken but now tstl will explicitly give an error if you try. +- Added support for the `switch` statement in all versions! (Before they were not supported in 5.1 and universal). +- Added support for `string.prototype.replaceAll` and improved `string.prototype.replace` implementation. +- Added `noResolvePaths` tsconfig option to disable module resolution for environment-provided modules. +- Implemented support for void expressions, i.e `void(0)` or `void(ignoreThisReturnValue())`. +- Upgraded TypeScript to 4.4.4 and made it a peer dependency to hopefully avoid plugin issues due to mismatching TypeScript versions. +- The `$vararg` language extension can be used to access CLI arguments, now also in bundles. +- Fixed a bug regarding `baseUrl` and relative imports. +- Fixed `sourceMapTraceback: true` not working correctly for bundles. +- Fixed an issue regarding hoisting in switch case clauses. +- Added missing function context validation cases for object literals. +- Fixed a problem where awaiting rejected promises in try/catch would give the wrong result. +- Fixed an issue where chained `.then` calls on already-resolved or already-rejected promises would cause some callbacks to not fire while they should. +- Fixed source file paths in source maps being absolute, they are now relative again. + ## 1.0.0 - **[Breaking]** `/* @tupleReturn */` has been removed and will no longer have any effect. You will get an error if you try ot use it or if you use declarations that use it. From 4b7c1d49ccbc174476cb54f0c9df089b060348f6 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 26 Oct 2021 20:10:54 +0200 Subject: [PATCH 413/764] 1.1.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e885ae74e..0dc5e4961 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.0.1", + "version": "1.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.0.1", + "version": "1.1.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 0fa2592ff..46327be32 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.0.1", + "version": "1.1.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 31dda3b136e04b5b8afd7a321fc8c03a8fb8adc2 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Nov 2021 18:20:09 +0100 Subject: [PATCH 414/764] Add noResolvePaths to tsconfig accepted options (#1154) --- src/cli/parse.ts | 16 +++++++++++++++- test/cli/parse.spec.ts | 7 +++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/cli/parse.ts b/src/cli/parse.ts index b7ed906e3..37e809eb6 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -18,7 +18,7 @@ interface CommandLineOptionOfEnum extends CommandLineOptionBase { } interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { - type: "boolean" | "string" | "object"; + type: "boolean" | "string" | "object" | "array"; } type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; @@ -78,6 +78,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "Provide verbose output useful for diagnosing problems.", type: "boolean", }, + { + name: "noResolvePaths", + description: "An array of paths that tstl should not resolve and keep as-is.", + type: "array", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { @@ -199,7 +204,16 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { return { value }; } + case "array": { + if (!Array.isArray(value)) { + return { + value: undefined, + error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, option.type), + }; + } + return { value }; + } case "enum": { if (typeof value !== "string") { return { diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index f157c9a21..17f68daf1 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -235,6 +235,13 @@ describe("tsconfig", () => { ["luaBundle", "foo", { luaBundle: "foo" }], ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], + + ["noImplicitSelf", true, { noImplicitSelf: true }], + + ["tstlVerbose", true, { tstlVerbose: true }], + + ["noResolvePaths", [], { noResolvePaths: [] }], + ["noResolvePaths", ["path1", "path2"], { noResolvePaths: ["path1", "path2"] }], ])("{ %p: %p }", (optionName, value, expected) => { const result = parseConfigFileContent({ tstl: { [optionName]: value } }); From f5b8c018c53d326a7d564af40717cdb8f7f923dc Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Nov 2021 18:20:25 +0100 Subject: [PATCH 415/764] Correctly export decorated classes (#1153) --- src/transformation/utils/export.ts | 11 ++-- src/transformation/visitors/class/index.ts | 14 ++++- src/transformation/visitors/modules/export.ts | 9 ++-- test/unit/classes/decorators.spec.ts | 53 +++++++++++++++++++ 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index 1edee936c..fafc26d86 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -10,10 +10,11 @@ export function hasDefaultExportModifier(node: ts.Node): boolean { return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); } -export const createDefaultExportIdentifier = (original: ts.Node): lua.Identifier => - lua.createIdentifier("default", original); +export function hasExportModifier(node: ts.Node): boolean { + return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword); +} -export const createDefaultExportStringLiteral = (original: ts.Node): lua.StringLiteral => +export const createDefaultExportStringLiteral = (original?: ts.Node): lua.StringLiteral => lua.createStringLiteral("default", original); export function getExportedSymbolDeclaration(symbol: ts.Symbol): ts.Declaration | undefined { @@ -142,3 +143,7 @@ export function createExportedIdentifier( return lua.createTableIndexExpression(exportTable, lua.createStringLiteral(identifier.text)); } + +export function createDefaultExportExpression(node: ts.Node): lua.AssignmentLeftHandSideExpression { + return lua.createTableIndexExpression(createExportsIdentifier(), createDefaultExportStringLiteral(node), node); +} diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 98d74f84a..2fb18a0cb 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -5,9 +5,10 @@ import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { annotationRemoved } from "../../utils/diagnostics"; import { - createDefaultExportIdentifier, + createDefaultExportExpression, createExportedIdentifier, hasDefaultExportModifier, + hasExportModifier, isSymbolExported, } from "../../utils/export"; import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; @@ -30,7 +31,7 @@ import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { - const left = createExportedIdentifier(context, createDefaultExportIdentifier(declaration)); + const left = createDefaultExportExpression(declaration); const right = transformClassAsExpression(declaration, context); return [lua.createAssignmentStatement(left, right, declaration)]; } @@ -220,6 +221,15 @@ function transformClassLikeDeclaration( ); const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); result.push(decoratingStatement); + + if (hasExportModifier(classDeclaration)) { + const exportExpression = hasDefaultExportModifier(classDeclaration) + ? createDefaultExportExpression(classDeclaration) + : createExportedIdentifier(context, className); + + const classAssignment = lua.createAssignmentStatement(exportExpression, localClassName); + result.push(classAssignment); + } } superInfo.pop(); diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 955f56866..07136f3e6 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { assert } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; import { - createDefaultExportIdentifier, + createDefaultExportExpression, createDefaultExportStringLiteral, createExportedIdentifier, } from "../../utils/export"; @@ -114,10 +114,9 @@ function transformExportSpecifier(context: TransformationContext, node: ts.Expor const exportedExpression = createShorthandIdentifier(context, exportedSymbol, exportedIdentifier); const isDefault = isDefaultExportSpecifier(node); - const identifierToExport = isDefault - ? createDefaultExportIdentifier(node) - : transformIdentifier(context, node.name); - const exportAssignmentLeftHandSide = createExportedIdentifier(context, identifierToExport); + const exportAssignmentLeftHandSide = isDefault + ? createDefaultExportExpression(node) + : createExportedIdentifier(context, transformIdentifier(context, node.name)); return lua.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); } diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index dadb73655..5b7b6e2ff 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -184,3 +184,56 @@ describe("Decorators /w descriptors", () => { } ); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 +test("exported class with decorator", () => { + util.testModule` + import { MyClass } from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export class MyClass { + foo() { + return "foo"; + } + }` + ) + .expectToEqual({ result: "overridden" }); +}); + +test("default exported class with decorator", () => { + util.testModule` + import MyClass from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export default class { + foo() { + return "foo"; + } + }` + ) + .expectToEqual({ result: "overridden" }); +}); From cb24c17911a28c83f0a00197c627df2ba2991e58 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 Nov 2021 18:20:40 +0100 Subject: [PATCH 416/764] Fix incorrect require searching pattern (#1151) --- src/transpilation/resolve.ts | 2 +- test/transpile/module-resolution.spec.ts | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index bfdf44b06..a3ac4f92a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -293,7 +293,7 @@ function isBuildModeLibrary(program: ts.Program) { function findRequiredPaths(code: string): string[] { // Find all require("") paths in a lua code string const paths: string[] = []; - const pattern = /(^|\s|;|=)require\("(.+)"\)/g; + const pattern = /(^|\s|;|=)require\("(.+?)"\)/g; // eslint-disable-next-line @typescript-eslint/ban-types let match: RegExpExecArray | null; while ((match = pattern.exec(code))) { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 75d025218..c363dbea1 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -503,3 +503,16 @@ test("includes lualib_bundle when external lua requests it", () => { foo: ["foo", "bar"], }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1146 +test("require matches correct pattern", () => { + util.testModule` + declare function require(this: void, module: string): any; + export const addResult = require("a").foo + require("b").foo; + export const callResult = require("c")("foo"); + ` + .addExtraFile("a.lua", "return { foo = 3 }") + .addExtraFile("b.lua", "return { foo = 5 }") + .addExtraFile("c.lua", "return function(self, a) return a end") + .expectToEqual({ addResult: 3 + 5, callResult: "foo" }); +}); From 3cc52f4c7d3e80ce310f2d652c792b9f0d3fcedc Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 2 Nov 2021 18:28:52 +0100 Subject: [PATCH 417/764] 1.1.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0dc5e4961..b3d3b5f40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.1.0", + "version": "1.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.1.0", + "version": "1.1.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 46327be32..1b47be298 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.1.0", + "version": "1.1.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 284a672844f4c3ea71656aab6993f7b134651d01 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 9 Nov 2021 11:42:18 -0800 Subject: [PATCH 418/764] Fix delete operator (#1160) * Fix delete operator * Fix delete test formatting * strict mode on object delete test --- src/LuaLib.ts | 2 +- src/lualib/Delete.ts | 10 +++----- test/unit/builtins/object.spec.ts | 39 ++++++++++++++++++++++++------- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 03483d2cc..03b3e4ef7 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -106,7 +106,7 @@ const luaLibDependencies: Partial> = { Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New], Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], DelegatedYield: [LuaLibFeature.StringAccess], - Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors], + Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors, LuaLibFeature.Error, LuaLibFeature.New], Error: [LuaLibFeature.Class, LuaLibFeature.ClassExtends, LuaLibFeature.New], FunctionBind: [LuaLibFeature.Unpack], Generator: [LuaLibFeature.Symbol], diff --git a/src/lualib/Delete.ts b/src/lualib/Delete.ts index 079dcb93d..8dfad76ad 100644 --- a/src/lualib/Delete.ts +++ b/src/lualib/Delete.ts @@ -3,17 +3,13 @@ function __TS__Delete(this: void, target: any, key: any): boolean { const descriptor = descriptors[key]; if (descriptor) { if (!descriptor.configurable) { - throw `Cannot delete property ${key} of ${target}.`; + throw new TypeError(`Cannot delete property ${key} of ${target}.`); } descriptors[key] = undefined; return true; } - if (target[key] !== undefined) { - target[key] = undefined; - return true; - } - - return false; + target[key] = undefined; + return true; } diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index fb0fe26ba..9cb5f8de3 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -222,11 +222,15 @@ describe("delete from object", () => { test("delete from object", () => { util.testFunction` const obj = { foo: "bar", bar: "baz" }; - delete obj["foo"]; - return obj; - ` - .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") - .expectToEqual({ bar: "baz" }); + return [delete obj["foo"], obj]; + `.expectToMatchJsResult(); + }); + + test("delete nonexistent property", () => { + util.testFunction` + const obj = {} as any + return [delete obj["foo"], obj]; + `.expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/993 @@ -234,10 +238,29 @@ describe("delete from object", () => { util.testFunction` const obj = { foo: "bar", bar: "baz" }; setmetatable(obj, {}); - delete obj["foo"]; - return obj; + return [delete obj["foo"], obj]; ` .setTsHeader("declare function setmetatable(this: void, table: T, metatable: any): T;") - .expectToEqual({ bar: "baz" }); + .expectToEqual([true, { bar: "baz" }]); + }); + + test("delete nonconfigurable own property", () => { + util.testFunction` + const obj = {} as any + Object.defineProperty(obj, "foo", { + configurable: false, + value: true + }) + try { + delete obj["foo"] + return "deleted" + } catch (e) { + return e instanceof TypeError + } + ` + .setOptions({ + strict: true, + }) + .expectToMatchJsResult(); }); }); From 8a6241ca63cb4369c966614e143f0bbd2d27ca9c Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 16 Nov 2021 08:12:38 -0800 Subject: [PATCH 419/764] Better print format (#1157) * Omit parenthesis based on operator precedence * Improve expression list printing * Add print format tests --- src/LuaPrinter.ts | 88 ++++++++++++++++--- .../__snapshots__/transformation.spec.ts.snap | 26 +++++- .../translation/transformation/printFormat.ts | 27 ++++++ .../__snapshots__/expressions.spec.ts.snap | 4 +- test/unit/__snapshots__/spread.spec.ts.snap | 12 +-- test/unit/__snapshots__/switch.spec.ts.snap | 14 +-- .../__snapshots__/console.spec.ts.snap | 56 +++--------- .../__snapshots__/multi.spec.ts.snap | 34 ++----- .../__snapshots__/range.spec.ts.snap | 18 +--- .../__snapshots__/table.spec.ts.snap | 40 ++++----- 10 files changed, 179 insertions(+), 140 deletions(-) create mode 100644 test/translation/transformation/printFormat.ts diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 4bfe53f5c..eb49932c8 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -120,6 +120,42 @@ export class LuaPrinter { [lua.SyntaxKind.BitwiseLeftShiftOperator]: "<<", [lua.SyntaxKind.BitwiseNotOperator]: "~", }; + private static operatorPrecedence: Record = { + [lua.SyntaxKind.OrOperator]: 1, + [lua.SyntaxKind.AndOperator]: 2, + + [lua.SyntaxKind.EqualityOperator]: 3, + [lua.SyntaxKind.InequalityOperator]: 3, + [lua.SyntaxKind.LessThanOperator]: 3, + [lua.SyntaxKind.LessEqualOperator]: 3, + [lua.SyntaxKind.GreaterThanOperator]: 3, + [lua.SyntaxKind.GreaterEqualOperator]: 3, + + [lua.SyntaxKind.BitwiseOrOperator]: 4, + [lua.SyntaxKind.BitwiseExclusiveOrOperator]: 5, + [lua.SyntaxKind.BitwiseAndOperator]: 6, + + [lua.SyntaxKind.BitwiseLeftShiftOperator]: 7, + [lua.SyntaxKind.BitwiseRightShiftOperator]: 7, + + [lua.SyntaxKind.ConcatOperator]: 8, + + [lua.SyntaxKind.AdditionOperator]: 9, + [lua.SyntaxKind.SubtractionOperator]: 9, + + [lua.SyntaxKind.MultiplicationOperator]: 10, + [lua.SyntaxKind.DivisionOperator]: 10, + [lua.SyntaxKind.FloorDivisionOperator]: 10, + [lua.SyntaxKind.ModuloOperator]: 10, + + [lua.SyntaxKind.NotOperator]: 11, + [lua.SyntaxKind.LengthOperator]: 11, + [lua.SyntaxKind.NegationOperator]: 11, + [lua.SyntaxKind.BitwiseNotOperator]: 11, + + [lua.SyntaxKind.PowerOperator]: 12, + }; + private static rightAssociativeOperators = new Set([lua.SyntaxKind.ConcatOperator, lua.SyntaxKind.PowerOperator]); private currentIndent = ""; private luaFile: string; @@ -676,34 +712,49 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printOperator(expression.operator)); - chunks.push(this.printExpressionInParenthesesIfNeeded(expression.operand)); + chunks.push( + this.printExpressionInParenthesesIfNeeded( + expression.operand, + LuaPrinter.operatorPrecedence[expression.operator] + ) + ); return this.createSourceNode(expression, chunks); } public printBinaryExpression(expression: lua.BinaryExpression): SourceNode { const chunks: SourceChunk[] = []; - - chunks.push(this.printExpressionInParenthesesIfNeeded(expression.left)); + const isRightAssociative = LuaPrinter.rightAssociativeOperators.has(expression.operator); + const precedence = LuaPrinter.operatorPrecedence[expression.operator]; + chunks.push( + this.printExpressionInParenthesesIfNeeded(expression.left, isRightAssociative ? precedence + 1 : precedence) + ); chunks.push(" ", this.printOperator(expression.operator), " "); - chunks.push(this.printExpressionInParenthesesIfNeeded(expression.right)); + chunks.push( + this.printExpressionInParenthesesIfNeeded( + expression.right, + isRightAssociative ? precedence : precedence + 1 + ) + ); return this.createSourceNode(expression, chunks); } - private printExpressionInParenthesesIfNeeded(expression: lua.Expression): SourceNode { - return this.needsParenthesis(expression) + private printExpressionInParenthesesIfNeeded(expression: lua.Expression, minPrecedenceToOmit?: number): SourceNode { + return this.needsParenthesis(expression, minPrecedenceToOmit) ? this.createSourceNode(expression, ["(", this.printExpression(expression), ")"]) : this.printExpression(expression); } - private needsParenthesis(expression: lua.Expression): boolean { - return ( - lua.isBinaryExpression(expression) || - lua.isFunctionExpression(expression) || - lua.isTableExpression(expression) || - (lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator) - ); + private needsParenthesis(expression: lua.Expression, minPrecedenceToOmit?: number): boolean { + if (lua.isBinaryExpression(expression) || lua.isUnaryExpression(expression)) { + return ( + minPrecedenceToOmit === undefined || + LuaPrinter.operatorPrecedence[expression.operator] < minPrecedenceToOmit + ); + } else { + return lua.isFunctionExpression(expression) || lua.isTableExpression(expression); + } } public printCallExpression(expression: lua.CallExpression): SourceNode { @@ -769,10 +820,19 @@ export class LuaPrinter { return intersperse(chunks, ", "); } + /** + * Returns true if the expression list (table field or parameters) should be printed on one line. + */ + protected isSimpleExpressionList(expressions: lua.Expression[]): boolean { + if (expressions.length <= 1) return true; + if (expressions.length > 4) return false; + return expressions.every(isSimpleExpression); + } + protected printExpressionList(expressions: lua.Expression[]): SourceChunk[] { const chunks: SourceChunk[] = []; - if (expressions.every(isSimpleExpression)) { + if (this.isSimpleExpressionList(expressions)) { chunks.push(...this.joinChunksWithComma(expressions.map(e => this.printExpression(e)))); } else { chunks.push("\n"); diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 7fd968b00..fb4594742 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -21,7 +21,7 @@ backQuoteInTemplateString = \\"\` \` \`\\" escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. ((\\"Level 1: \\\\n\\\\t\\\\t \\" .. ((\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\")) .. \\" \\\\n --\\")) .. \\" \\\\n --\\"" +nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. (\\"Level 1: \\\\n\\\\t\\\\t \\" .. (\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\"" `; exports[`Transformation (exportStatement) 1`] = ` @@ -230,6 +230,30 @@ return ____exports" exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; +exports[`Transformation (printFormat) 1`] = ` +"stringConcat = ((\\"a\\" .. \\"b\\" .. \\"c\\") .. \\"d\\") .. \\"e\\" +numbers = 2 * 2 + 3 + 4 * (5 + 6) ~= 7 +function func(...) +end +func(function() + local b = \\"A function\\" +end) +func(func()) +array = {func()} +array2 = { + func(), + func() +} +object = {a = 1, b = 2, c = 3} +bigObject = { + a = 1, + b = 2, + c = 3, + d = \\"value1\\", + e = \\"value2\\" +}" +`; + exports[`Transformation (returnDefault) 1`] = ` "function myFunc(self) return diff --git a/test/translation/transformation/printFormat.ts b/test/translation/transformation/printFormat.ts new file mode 100644 index 000000000..3374952c5 --- /dev/null +++ b/test/translation/transformation/printFormat.ts @@ -0,0 +1,27 @@ +const stringConcat = "a" + ("b" + "c") + "d" + "e"; +const numbers = 2 * 2 + 3 + 4 * (5 + 6) !== 7; + +function func(this: void, ...args: any) {} + +func(() => { + const b = "A function"; +}); + +func(func()); + +const array = [func()]; +const array2 = [func(), func()]; + +const object = { + a: 1, + b: 2, + c: 3, +}; + +const bigObject = { + a: 1, + b: 2, + c: 3, + d: "value1", + e: "value2", +}; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 03bb46230..cfd0e53cb 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -14,13 +14,13 @@ return ____exports" exports[`Binary expressions ordering parentheses ("1*(3+4*2)") 1`] = ` "local ____exports = {} -____exports.__result = 1 * (3 + (4 * 2)) +____exports.__result = 1 * (3 + 4 * 2) return ____exports" `; exports[`Binary expressions ordering parentheses ("1*30+4") 1`] = ` "local ____exports = {} -____exports.__result = (1 * 30) + 4 +____exports.__result = 1 * 30 + 4 return ____exports" `; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index 0b49fd80a..d27ea931d 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -90,9 +90,7 @@ function ____exports.__main(self) end return test( nil, - { - fn = function(____, arg) return arg end - }, + {fn = function(____, arg) return arg end}, \\"foobar\\" ) end @@ -108,11 +106,9 @@ function ____exports.__main(self) end local function test(self, ...) do - pcall( - function() - error(\\"foobar\\", 0) - end - ) + pcall(function() + error(\\"foobar\\", 0) + end) do return pick(nil, ...) end diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index 1349374bb..45ba87e16 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -50,14 +50,14 @@ function ____exports.__main(self) result = hoisted(nil) break end - ____cond3 = ____cond3 or (____switch3 == 2) + ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then result = \\"2\\" end if ____cond3 then result = \\"default\\" end - ____cond3 = ____cond3 or (____switch3 == 3) + ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then result = \\"3\\" break @@ -88,14 +88,14 @@ function ____exports.__main(self) result = hoisted(nil) break end - ____cond3 = ____cond3 or (____switch3 == 2) + ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then result = \\"2\\" end if ____cond3 then result = \\"default\\" end - ____cond3 = ____cond3 or (____switch3 == 3) + ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then result = \\"3\\" break @@ -118,19 +118,19 @@ function ____exports.__main(self) local out = {} repeat local ____switch3 = 0 - local ____cond3 = ((____switch3 == 0) or (____switch3 == 1)) or (____switch3 == 2) + local ____cond3 = ____switch3 == 0 or ____switch3 == 1 or ____switch3 == 2 if ____cond3 then __TS__ArrayPush(out, \\"0,1,2\\") break end - ____cond3 = ____cond3 or (____switch3 == 3) + ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then do __TS__ArrayPush(out, \\"3\\") break end end - ____cond3 = ____cond3 or (____switch3 == 4) + ____cond3 = ____cond3 or ____switch3 == 4 if ____cond3 then break end diff --git a/test/unit/builtins/__snapshots__/console.spec.ts.snap b/test/unit/builtins/__snapshots__/console.spec.ts.snap index f06d99dae..2af4f0446 100644 --- a/test/unit/builtins/__snapshots__/console.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/console.spec.ts.snap @@ -57,9 +57,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %%s\\", \\"there\\") - ) + print(string.format(\\"Hello %%s\\", \\"there\\")) end return ____exports" `; @@ -67,9 +65,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %s\\", \\"there\\") - ) + print(string.format(\\"Hello %s\\", \\"there\\")) end return ____exports" `; @@ -101,9 +97,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %%s\\", \\"there\\") - ) + print(string.format(\\"Hello %%s\\", \\"there\\")) end return ____exports" `; @@ -111,9 +105,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %s\\", \\"there\\") - ) + print(string.format(\\"Hello %s\\", \\"there\\")) end return ____exports" `; @@ -145,9 +137,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %%s\\", \\"there\\") - ) + print(string.format(\\"Hello %%s\\", \\"there\\")) end return ____exports" `; @@ -155,9 +145,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %s\\", \\"there\\") - ) + print(string.format(\\"Hello %s\\", \\"there\\")) end return ____exports" `; @@ -181,9 +169,7 @@ return ____exports" exports[`console.trace ("console.trace()") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - debug.traceback() - ) + print(debug.traceback()) end return ____exports" `; @@ -191,11 +177,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - debug.traceback( - string.format(\\"Hello %%s\\", \\"there\\") - ) - ) + print(debug.traceback(string.format(\\"Hello %%s\\", \\"there\\"))) end return ____exports" `; @@ -203,11 +185,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - debug.traceback( - string.format(\\"Hello %s\\", \\"there\\") - ) - ) + print(debug.traceback(string.format(\\"Hello %s\\", \\"there\\"))) end return ____exports" `; @@ -215,9 +193,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - debug.traceback(\\"Hello\\", \\"there\\") - ) + print(debug.traceback(\\"Hello\\", \\"there\\")) end return ____exports" `; @@ -225,9 +201,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"message\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - debug.traceback(\\"message\\") - ) + print(debug.traceback(\\"message\\")) end return ____exports" `; @@ -243,9 +217,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %%s\\", \\"there\\") - ) + print(string.format(\\"Hello %%s\\", \\"there\\")) end return ____exports" `; @@ -253,9 +225,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print( - string.format(\\"Hello %s\\", \\"there\\") - ) + print(string.format(\\"Hello %s\\", \\"there\\")) end return ____exports" `; diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index 36b928202..f9911b514 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -20,9 +20,7 @@ function ____exports.__main(self) local function multi(self, ...) return ... end - return ({ - multi(nil) - }).forEach + return ({multi(nil)}).forEach end return ____exports" `; @@ -42,9 +40,7 @@ exports[`invalid $multi call ($multi): diagnostics 1`] = `"main.ts(2,9): error T exports[`invalid $multi call (([a] = $multi(1)) => {}): code 1`] = ` "local function ____(____, ____bindingPattern0) if ____bindingPattern0 == nil then - ____bindingPattern0 = { - ____(_G, 1) - } + ____bindingPattern0 = {____(_G, 1)} end local a = ____bindingPattern0[1] end" @@ -65,21 +61,11 @@ end" exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const {} = $multi();): code 1`] = ` -"local ____ = { - { - ____(_G) - } -}" -`; +exports[`invalid $multi call (const {} = $multi();): code 1`] = `"local ____ = {{____(_G)}}"`; exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const a = $multi();): code 1`] = ` -"a = { - ____(_G) -}" -`; +exports[`invalid $multi call (const a = $multi();): code 1`] = `"a = {____(_G)}"`; exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts(2,19): error TSTL: The $multi function must be called in a return statement."`; @@ -180,9 +166,7 @@ local function multi(self, ...) return ... end local a -local ____ = { - ____(nil) -} +local ____ = {____(nil)} a = ____[1] ____exports.a = a ____exports.a = a @@ -198,9 +182,7 @@ local function multi(self, ...) end local a do - local ____ = { - ____(nil, 1, 2) - } + local ____ = {____(nil, 1, 2)} a = ____[1] ____exports.a = a while false do @@ -238,9 +220,7 @@ local function multi(self, ...) end local a if (function() - local ____ = { - ____(nil, 1) - } + local ____ = {____(nil, 1)} a = ____[1] ____exports.a = a return ____ diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap index f066c1260..c1f369cb6 100644 --- a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -36,11 +36,7 @@ exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` "require(\\"lualib_bundle\\"); local ____exports = {} function ____exports.__main(self) - local y = { - __TS__Spread( - ____(nil, 1, 10) - ) - } + local y = {__TS__Spread(____(nil, 1, 10))} end return ____exports" `; @@ -50,9 +46,7 @@ exports[`$range invalid use ("const y = [...$range(1, 10)];"): diagnostics 1`] = exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - for i in pairs( - ____(nil, 1, 10, 2) - ) do + for i in pairs(____(nil, 1, 10, 2)) do end end return ____exports" @@ -63,9 +57,7 @@ exports[`$range invalid use ("for (const i in $range(1, 10, 2)) {}"): diagnostic exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - for ____, i in ipairs( - ____(nil, 1, 10, 2) - ) do + for ____, i in ipairs(____(nil, 1, 10, 2)) do end end return ____exports" @@ -77,9 +69,7 @@ exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] "require(\\"lualib_bundle\\"); local ____exports = {} function ____exports.__main(self) - for ____, i in __TS__Iterator( - ____(nil, 1, 10, 2) - ) do + for ____, i in __TS__Iterator(____(nil, 1, 10, 2)) do end end return ____exports" diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 5deed95c3..7a3387f5e 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -47,23 +47,19 @@ return ____exports" exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` -"foo = { - (function() - ({}).foo = nil - return nil - end)() -}" +"foo = {(function() + ({}).foo = nil + return nil +end)()}" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` -"foo = tostring( - (function() - ({}).foo = nil - return nil - end)() -)" +"foo = tostring((function() + ({}).foo = nil + return nil +end)())" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; @@ -90,23 +86,19 @@ exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("dec exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` -"foo = { - (function() - ({}).foo = 3 - return nil - end)() -}" +"foo = {(function() + ({}).foo = 3 + return nil +end)()}" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` -"foo = tostring( - (function() - ({}).foo = 3 - return nil - end)() -)" +"foo = tostring((function() + ({}).foo = 3 + return nil +end)())" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; From 028e3f51b6b8f74f13c4c00c38855c90335fa922 Mon Sep 17 00:00:00 2001 From: Alex DiCarlo Date: Fri, 19 Nov 2021 10:55:08 -0800 Subject: [PATCH 420/764] Fix __TS__AsyncAwaiter error handling (#1168) * Fix __TS__AsyncAwaiter error handling * Add tests --- src/lualib/Await.ts | 2 +- test/unit/builtins/async-await.spec.ts | 58 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index 0bbfdd09f..4b825c71a 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -30,7 +30,7 @@ function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { if (success) { step(resultOrError, errorOrErrorHandler); } else { - reject(resultOrError); + reject(errorOrErrorHandler); } } function rejected(handler: ErrorHandler | undefined) { diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index c08514236..aba6b15eb 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -384,6 +384,64 @@ test("async function can forward varargs", () => { .expectToEqual(["resolved", "A", "B", "C"]); }); +test.each(["async function abc() {", "const abc = async () => {"])( + "can throw error after await in async function (%p)", + functionHeader => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving first promise", data)); + + ${functionHeader} + await promise; + log("run abc"); + throw "test throw"; + } + + const awaitingPromise = abc(); + awaitingPromise.catch(error => log("caught error", error)); + + resolve("resolved data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolving first promise", "resolved data", "run abc", "caught error", "test throw"]); + } +); + +test.each(["async function abc() {", "const abc = async () => {"])( + "can throw object after await in async function (%p)", + functionHeader => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(data => log("resolving first promise", data)); + + ${functionHeader} + await promise; + log("run abc"); + throw new Error("test throw"); + } + + const awaitingPromise = abc(); + awaitingPromise.catch(error => log("caught error", error)); + + resolve("resolved data"); + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual([ + "resolving first promise", + "resolved data", + "run abc", + "caught error", + { + message: "test throw", + name: "Error", + stack: expect.stringContaining("stack traceback"), + }, + ]); + } +); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1105 describe("try/catch in async function", () => { util.testEachVersion( From d8e6546af1fc5f42950ead3e5e50f61d53add2ea Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sat, 20 Nov 2021 10:14:03 -0700 Subject: [PATCH 421/764] Preceding Statements (#1116) * working on preceding statements implementation * fixed issues from tests and started adding new tests (which don't pass yet) * fixed issues with short-circuit compound operator expressions * execution order tests * fixes for remaining broken tests * switch test (currently broken) * refactor to expression list transformation * more refactoring and fixes for expression lists * refactored object literals a bit * refactorings, including removal of old iife stuff * snapshot updates * cleanup, fixes, and added some original nodes for source maps * comment update * fixed ifelse statements * more things to fix * working on fixes to assignments and creating more tests (most of which are broken) * more fixes. more broken things. * lots of fixes to call expressions and lots of new broken tests * more execution order fixes, more tests * working on fixes for destructuring exec order * additional object destructuring test * fixes for object destructuring * fixed switch statements * refactored expression list handling - removed optimization that broke certain situations - optimized out extra temp in common unary operator cases - removed duplicate functionality between transformOrderedExpressions and transformExpressionList * optimized out temps in many situations * fixed execution order of computed property names in object literals * a little refactoring * removed bad optimization and refactored call stuff a bit * added SparseArray lib functions to handle complex expression lists and fixed/refactored a few more things * addPrecedingStatements takes a single argument now * a little cleanup * fix for indirect property assignments * refactoring to expression-lists * fixes and refactors to tests * improvements to temp variable naming * treating temps like consts and more temp name adjustments * snapshot update * a couple of small refactorings * refactoring based on comments & suggestions * change void expressions to use preceding statements * better comments and variable names for preceding statement handling of loop conditions * addressed feedback * reverted change that didn't seem necessary * updated transformBinaryOperation to handle preceding statements * reverted switch handling to using lua expressions instead of manufactured ts expressions and handled preceding statements manually * constified compound assignment code * renamed createShortCircuitBinaryExpression * Merge from master Co-authored-by: Tom --- src/LuaAST.ts | 12 + src/LuaLib.ts | 3 + src/lualib/SparseArrayNew.ts | 9 + src/lualib/SparseArrayPush.ts | 8 + src/lualib/SparseArraySpread.ts | 4 + src/transformation/builtins/array.ts | 5 +- src/transformation/builtins/function.ts | 5 +- src/transformation/builtins/string.ts | 5 +- src/transformation/context/context.ts | 108 ++- src/transformation/utils/lua-ast.ts | 43 +- .../utils/preceding-statements.ts | 11 + src/transformation/utils/scope.ts | 7 + src/transformation/utils/transform.ts | 22 - src/transformation/utils/typescript/index.ts | 17 + src/transformation/visitors/access.ts | 36 +- .../visitors/binary-expression/assignments.ts | 163 +++-- .../visitors/binary-expression/compound.ts | 242 ++++--- .../destructuring-assignments.ts | 161 +++-- .../visitors/binary-expression/index.ts | 145 +++- src/transformation/visitors/call.ts | 235 ++++--- src/transformation/visitors/class/index.ts | 17 +- src/transformation/visitors/class/new.ts | 13 +- src/transformation/visitors/conditional.ts | 63 +- .../visitors/expression-list.ts | 192 ++++++ src/transformation/visitors/function.ts | 20 +- src/transformation/visitors/literal.ts | 96 ++- src/transformation/visitors/loops/do-while.ts | 69 +- src/transformation/visitors/loops/for.ts | 43 +- src/transformation/visitors/loops/utils.ts | 12 +- src/transformation/visitors/sourceFile.ts | 7 +- src/transformation/visitors/switch.ts | 98 ++- src/transformation/visitors/template.ts | 10 +- src/transformation/visitors/typeof.ts | 11 +- .../visitors/variable-declaration.ts | 18 +- src/transformation/visitors/void.ts | 21 +- .../__snapshots__/transformation.spec.ts.snap | 4 +- .../__snapshots__/expressions.spec.ts.snap | 180 ++--- .../__snapshots__/deprecated.spec.ts.snap | 10 +- .../__snapshots__/classes.spec.ts.snap | 6 +- .../__snapshots__/iterable.spec.ts.snap | 16 +- .../__snapshots__/multi.spec.ts.snap | 20 +- .../__snapshots__/table.spec.ts.snap | 58 +- test/unit/precedingStatements.spec.ts | 625 ++++++++++++++++++ 43 files changed, 2121 insertions(+), 729 deletions(-) create mode 100644 src/lualib/SparseArrayNew.ts create mode 100644 src/lualib/SparseArrayPush.ts create mode 100644 src/lualib/SparseArraySpread.ts create mode 100644 src/transformation/utils/preceding-statements.ts delete mode 100644 src/transformation/utils/transform.ts create mode 100644 src/transformation/visitors/expression-list.ts create mode 100644 test/unit/precedingStatements.spec.ts diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 1ac86d3f5..ee5c9d329 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -566,6 +566,18 @@ export function createStringLiteral(value: string, tsOriginal?: ts.Node): String return expression; } +export function isLiteral( + node: Node +): node is NilLiteral | DotsLiteral | BooleanLiteral | NumericLiteral | StringLiteral { + return ( + isNilLiteral(node) || + isDotsLiteral(node) || + isBooleanLiteral(node) || + isNumericLiteral(node) || + isStringLiteral(node) + ); +} + export enum FunctionExpressionFlags { None = 1 << 0, Inline = 1 << 1, // Keep function body on same line diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 03b3e4ef7..f22ff28e1 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -70,6 +70,9 @@ export enum LuaLibFeature { PromiseRace = "PromiseRace", Set = "Set", SetDescriptor = "SetDescriptor", + SparseArrayNew = "SparseArrayNew", + SparseArrayPush = "SparseArrayPush", + SparseArraySpread = "SparseArraySpread", WeakMap = "WeakMap", WeakSet = "WeakSet", SourceMapTraceBack = "SourceMapTraceBack", diff --git a/src/lualib/SparseArrayNew.ts b/src/lualib/SparseArrayNew.ts new file mode 100644 index 000000000..2370871ca --- /dev/null +++ b/src/lualib/SparseArrayNew.ts @@ -0,0 +1,9 @@ +type __TS__SparseArray = T[] & { sparseLength: number }; + +function __TS__SparseArrayNew(this: void, ...args: T[]): __TS__SparseArray { + const sparseArray = [...args] as __TS__SparseArray; + // select("#", ...) counts the number of args passed, including nils. + // Note that we're depending on vararg optimization to occur here. + sparseArray.sparseLength = select("#", ...args); + return sparseArray; +} diff --git a/src/lualib/SparseArrayPush.ts b/src/lualib/SparseArrayPush.ts new file mode 100644 index 000000000..30704620f --- /dev/null +++ b/src/lualib/SparseArrayPush.ts @@ -0,0 +1,8 @@ +function __TS__SparseArrayPush(this: void, sparseArray: __TS__SparseArray, ...args: T[]): void { + const argsLen = select("#", ...args); + const listLen = sparseArray.sparseLength; + for (const i of $range(1, argsLen)) { + sparseArray[listLen + i - 1] = args[i - 1]; + } + sparseArray.sparseLength = listLen + argsLen; +} diff --git a/src/lualib/SparseArraySpread.ts b/src/lualib/SparseArraySpread.ts new file mode 100644 index 000000000..e365f19bc --- /dev/null +++ b/src/lualib/SparseArraySpread.ts @@ -0,0 +1,4 @@ +function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { + const _unpack = unpack ?? table.unpack; + return _unpack(sparseArray, 1, sparseArray.sparseLength); +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index d8bd4dd3b..7bbd4cf98 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; import { isStringType, isNumberType } from "../utils/typescript"; export function transformArrayConstructorCall( @@ -29,8 +29,7 @@ export function transformArrayPrototypeCall( ): lua.CallExpression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - const caller = context.transformExpression(expression.expression); + const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); const expressionName = expression.name.text; switch (expressionName) { diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index f6cb8a6a0..aefe2a13e 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -6,7 +6,7 @@ import { unsupportedForTarget, unsupportedProperty, unsupportedSelfFunctionConve import { ContextType, getFunctionContextType } from "../utils/function-context"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { PropertyCallExpression, transformCallAndArguments } from "../visitors/call"; export function transformFunctionPrototypeCall( context: TransformationContext, @@ -19,8 +19,7 @@ export function transformFunctionPrototypeCall( } const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - const caller = context.transformExpression(expression.expression); + const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); const expressionName = expression.name.text; switch (expressionName) { case "apply": diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 952d18c7e..c71f855fc 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -4,7 +4,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { addToNumericExpression, createNaN, getNumberLiteralValue } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lua.Expression[]): lua.CallExpression { const stringIdentifier = lua.createIdentifier("string"); @@ -21,8 +21,7 @@ export function transformStringPrototypeCall( ): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); - const params = transformArguments(context, node.arguments, signature); - const caller = context.transformExpression(expression.expression); + const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); const expressionName = expression.name.text; switch (expressionName) { diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 4dbcf9e10..30f274c03 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -1,11 +1,14 @@ import * as ts from "typescript"; import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; -import { castArray } from "../../utils"; +import { assert, castArray } from "../../utils"; import { unsupportedNodeKind } from "../utils/diagnostics"; import { unwrapVisitorResult } from "../utils/lua-ast"; +import { createSafeName } from "../utils/safe-names"; import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; +export const tempSymbolId = -1 as lua.SymbolId; + export interface AllAccessorDeclarations { firstAccessor: ts.AccessorDeclaration; secondAccessor: ts.AccessorDeclaration | undefined; @@ -29,6 +32,7 @@ export class TransformationContext { public readonly diagnostics: ts.Diagnostic[] = []; public readonly checker: DiagnosticsProducingTypeChecker = this.program.getDiagnosticsProducingTypeChecker(); public readonly resolver: EmitResolver; + public readonly precedingStatementsStack: lua.Statement[][] = []; public readonly options: CompilerOptions = this.program.getCompilerOptions(); public readonly luaTarget = this.options.luaTarget ?? LuaTarget.Universal; @@ -46,6 +50,7 @@ export class TransformationContext { } private currentNodeVisitors: Array> = []; + private nextTempId = 0; public transformNode(node: ts.Node): lua.Node[]; /** @internal */ @@ -104,10 +109,107 @@ export class TransformationContext { } public transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { - return castArray(node).flatMap(n => this.transformNode(n) as lua.Statement[]); + return castArray(node).flatMap(n => { + this.pushPrecedingStatements(); + const statements = this.transformNode(n) as lua.Statement[]; + statements.unshift(...this.popPrecedingStatements()); + return statements; + }); } public superTransformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { - return castArray(node).flatMap(n => this.superTransformNode(n) as lua.Statement[]); + return castArray(node).flatMap(n => { + this.pushPrecedingStatements(); + const statements = this.superTransformNode(n) as lua.Statement[]; + statements.unshift(...this.popPrecedingStatements()); + return statements; + }); + } + + public pushPrecedingStatements() { + this.precedingStatementsStack.push([]); + } + + public popPrecedingStatements() { + const precedingStatements = this.precedingStatementsStack.pop(); + assert(precedingStatements); + return precedingStatements; + } + + public addPrecedingStatements(statements: lua.Statement | lua.Statement[]) { + const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1]; + assert(precedingStatements); + if (!Array.isArray(statements)) { + statements = [statements]; + } + precedingStatements.push(...statements); + } + + public prependPrecedingStatements(statements: lua.Statement | lua.Statement[]) { + const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1]; + assert(precedingStatements); + if (!Array.isArray(statements)) { + statements = [statements]; + } + precedingStatements.unshift(...statements); + } + + public createTempName(prefix = "temp") { + prefix = prefix.replace(/^_*/, ""); // Strip leading underscores because createSafeName will add them again + return createSafeName(`${prefix}_${this.nextTempId++}`); + } + + private getTempNameForLuaExpression(expression: lua.Expression): string | undefined { + if (lua.isStringLiteral(expression)) { + return expression.value; + } else if (lua.isNumericLiteral(expression)) { + return `_${expression.value.toString()}`; + } else if (lua.isIdentifier(expression)) { + return expression.text; + } else if (lua.isCallExpression(expression)) { + const name = this.getTempNameForLuaExpression(expression.expression); + if (name) { + return `${name}_result`; + } + } else if (lua.isTableIndexExpression(expression)) { + const tableName = this.getTempNameForLuaExpression(expression.table); + const indexName = this.getTempNameForLuaExpression(expression.index); + if (tableName || indexName) { + return `${tableName ?? "table"}_${indexName ?? "index"}`; + } + } + } + + public createTempNameForLuaExpression(expression: lua.Expression) { + const name = this.getTempNameForLuaExpression(expression); + const identifier = lua.createIdentifier(this.createTempName(name), undefined, tempSymbolId); + lua.setNodePosition(identifier, lua.getOriginalPos(expression)); + return identifier; + } + + private getTempNameForNode(node: ts.Node): string | undefined { + if (ts.isStringLiteral(node) || ts.isIdentifier(node) || ts.isMemberName(node)) { + return node.text; + } else if (ts.isNumericLiteral(node)) { + return `_${node.text}`; + } else if (ts.isCallExpression(node)) { + const name = this.getTempNameForNode(node.expression); + if (name) { + return `${name}_result`; + } + } else if (ts.isElementAccessExpression(node) || ts.isPropertyAccessExpression(node)) { + const tableName = this.getTempNameForNode(node.expression); + const indexName = ts.isElementAccessExpression(node) + ? this.getTempNameForNode(node.argumentExpression) + : node.name.text; + if (tableName || indexName) { + return `${tableName ?? "table"}_${indexName ?? "index"}`; + } + } + } + + public createTempNameForNode(node: ts.Node) { + const name = this.getTempNameForNode(node); + return lua.createIdentifier(this.createTempName(name), node, tempSymbolId); } } diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 091cd73f4..0670c51fc 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -4,7 +4,7 @@ import * as lua from "../../LuaAST"; import { assert, castArray } from "../../utils"; import { TransformationContext } from "../context"; import { createExportedIdentifier, getIdentifierExportScope } from "./export"; -import { peekScope, ScopeType, Scope } from "./scope"; +import { peekScope, ScopeType, Scope, addScopeVariableDeclaration } from "./scope"; import { transformLuaLibFunction } from "./lualib"; import { LuaLibFeature } from "../../LuaLib"; @@ -62,19 +62,6 @@ export function getNumberLiteralValue(expression?: lua.Expression) { return undefined; } -// Prefer use of transformToImmediatelyInvokedFunctionExpression to maintain correct scope. If you use this directly, -// ensure you push/pop a function scope appropriately to avoid incorrect vararg optimization. -export function createImmediatelyInvokedFunctionExpression( - statements: lua.Statement[], - result: lua.Expression | lua.Expression[], - tsOriginal?: ts.Node -): lua.CallExpression { - const body = [...statements, lua.createReturnStatement(castArray(result))]; - const flags = statements.length === 0 ? lua.FunctionExpressionFlags.Inline : lua.FunctionExpressionFlags.None; - const iife = lua.createFunctionExpression(lua.createBlock(body), undefined, undefined, flags); - return lua.createCallExpression(iife, [], tsOriginal); -} - export function createUnpackCall( context: TransformationContext, expression: lua.Expression, @@ -119,12 +106,7 @@ export function createHoistableVariableDeclarationStatement( if (identifier.symbolId !== undefined) { const scope = peekScope(context); assert(scope.type !== ScopeType.Switch); - - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } - - scope.variableDeclarations.push(declaration); + addScopeVariableDeclaration(scope, declaration); } return declaration; @@ -176,22 +158,25 @@ export function createLocalOrExportedOrGlobalDeclaration( if (context.isModule || !isTopLevelVariable) { if (!isFunctionDeclaration && hasMultipleReferences(scope, lhs)) { - // Split declaration and assignment of identifiers that reference themselves in their declaration - declaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); + // Split declaration and assignment of identifiers that reference themselves in their declaration. + // Put declaration above preceding statements in case the identifier is referenced in those. + const precedingDeclaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); + context.prependPrecedingStatements(precedingDeclaration); if (rhs) { assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } + + if (!isFunctionDeclaration) { + // Remember local variable declarations for hoisting later + addScopeVariableDeclaration(scope, precedingDeclaration); + } } else { declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); - } - if (!isFunctionDeclaration) { - // Remember local variable declarations for hoisting later - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; + if (!isFunctionDeclaration) { + // Remember local variable declarations for hoisting later + addScopeVariableDeclaration(scope, declaration); } - - scope.variableDeclarations.push(declaration); } } else if (rhs) { // global diff --git a/src/transformation/utils/preceding-statements.ts b/src/transformation/utils/preceding-statements.ts new file mode 100644 index 000000000..c64d0b90a --- /dev/null +++ b/src/transformation/utils/preceding-statements.ts @@ -0,0 +1,11 @@ +import * as lua from "../../LuaAST"; +import { TransformationContext } from "../context"; + +export function transformInPrecedingStatementScope< + TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] +>(context: TransformationContext, transformer: () => TReturn): [lua.Statement[], TReturn] { + context.pushPrecedingStatements(); + const statementOrStatements = transformer(); + const precedingStatements = context.popPrecedingStatements(); + return [precedingStatements, statementOrStatements]; +} diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index bed90da76..3a4558b4d 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -98,6 +98,13 @@ export function popScope(context: TransformationContext): Scope { return scope; } +export function addScopeVariableDeclaration(scope: Scope, declaration: lua.VariableDeclarationStatement) { + if (!scope.variableDeclarations) { + scope.variableDeclarations = []; + } + scope.variableDeclarations.push(declaration); +} + function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Node) { return symbol?.declarations?.some( d => ts.isFunctionDeclaration(d) && findFirstNodeAbove(d, (n): n is ts.Node => n === scopeNode) diff --git a/src/transformation/utils/transform.ts b/src/transformation/utils/transform.ts deleted file mode 100644 index 215a018d5..000000000 --- a/src/transformation/utils/transform.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../LuaAST"; -import { castArray } from "../../utils"; -import { TransformationContext } from "../context"; -import { createImmediatelyInvokedFunctionExpression } from "./lua-ast"; -import { ScopeType, pushScope, popScope } from "./scope"; - -export interface ImmediatelyInvokedFunctionParameters { - statements: lua.Statement | lua.Statement[]; - result: lua.Expression | lua.Expression[]; -} - -export function transformToImmediatelyInvokedFunctionExpression( - context: TransformationContext, - transformFunction: () => ImmediatelyInvokedFunctionParameters, - tsOriginal?: ts.Node -): lua.CallExpression { - pushScope(context, ScopeType.Function); - const { statements, result } = transformFunction(); - popScope(context); - return createImmediatelyInvokedFunctionExpression(castArray(statements), result, tsOriginal); -} diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 6d7bfa68c..1e2ffba44 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -92,3 +92,20 @@ export function getFunctionTypeForCall(context: TransformationContext, node: ts. } return context.checker.getTypeFromTypeNode(typeDeclaration.type); } + +export function isConstIdentifier(context: TransformationContext, node: ts.Node) { + let identifier = node; + if (ts.isComputedPropertyName(identifier)) { + identifier = identifier.expression; + } + if (!ts.isIdentifier(identifier)) { + return false; + } + const symbol = context.checker.getSymbolAtLocation(identifier); + if (!symbol || !symbol.declarations) { + return false; + } + return symbol.declarations.some( + d => ts.isVariableDeclarationList(d.parent) && (d.parent.flags & ts.NodeFlags.Const) !== 0 + ); +} diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 389bbde5f..a3ec68c46 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -8,39 +8,45 @@ import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; +import { transformOrderedExpressions } from "./expression-list"; import { isMultiReturnCall, returnsMultiType } from "./language-extensions/multi"; -export function transformElementAccessArgument( +function addOneToArrayAccessArgument( context: TransformationContext, - node: ts.ElementAccessExpression + node: ts.ElementAccessExpression, + index: lua.Expression ): lua.Expression { - const index = context.transformExpression(node.argumentExpression); - const type = context.checker.getTypeAtLocation(node.expression); const argumentType = context.checker.getTypeAtLocation(node.argumentExpression); if (isArrayType(context, type) && isNumberType(context, argumentType)) { return addToNumericExpression(index, 1); } - return index; } +export function transformElementAccessArgument( + context: TransformationContext, + node: ts.ElementAccessExpression +): lua.Expression { + const index = context.transformExpression(node.argumentExpression); + return addOneToArrayAccessArgument(context, node, index); +} + export const transformElementAccessExpression: FunctionVisitor = (node, context) => { const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return constEnumValue; } - const table = context.transformExpression(node.expression); + const [table, accessExpression] = transformOrderedExpressions(context, [node.expression, node.argumentExpression]); const type = context.checker.getTypeAtLocation(node.expression); const argumentType = context.checker.getTypeAtLocation(node.argumentExpression); if (isStringType(context, type) && isNumberType(context, argumentType)) { - const index = context.transformExpression(node.argumentExpression); - return transformLuaLibFunction(context, LuaLibFeature.StringAccess, node, table, index); + return transformLuaLibFunction(context, LuaLibFeature.StringAccess, node, table, accessExpression); } - const accessExpression = transformElementAccessArgument(context, node); + const updatedAccessExpression = addOneToArrayAccessArgument(context, node, accessExpression); if (isMultiReturnCall(context, node.expression)) { const accessType = context.checker.getTypeAtLocation(node.argumentExpression); @@ -53,16 +59,22 @@ export const transformElementAccessExpression: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index b934ca2e0..aec1ee96c 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -7,20 +7,33 @@ import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } f import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; -import { transformElementAccessArgument } from "../access"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; -import { popScope, pushScope, ScopeType } from "../../utils/scope"; -import { - ImmediatelyInvokedFunctionParameters, - transformToImmediatelyInvokedFunctionExpression, -} from "../../utils/transform"; import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; +import { transformElementAccessArgument } from "../access"; +import { moveToPrecedingTemp, transformExpressionList } from "../expression-list"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; export function transformAssignmentLeftHandSideExpression( context: TransformationContext, - node: ts.Expression + node: ts.Expression, + rightHasPrecedingStatements?: boolean ): lua.AssignmentLeftHandSideExpression { + // Access expressions need the components of the left side cached in temps before the right side's preceding statements + if (rightHasPrecedingStatements && (ts.isElementAccessExpression(node) || ts.isPropertyAccessExpression(node))) { + let table = context.transformExpression(node.expression); + table = moveToPrecedingTemp(context, table, node.expression); + + let index: lua.Expression; + if (ts.isElementAccessExpression(node)) { + index = transformElementAccessArgument(context, node); + index = moveToPrecedingTemp(context, index, node.argumentExpression); + } else { + index = lua.createStringLiteral(node.name.text, node.name); + } + return lua.createTableIndexExpression(table, index, node); + } + const symbol = context.checker.getSymbolAtLocation(node); const left = context.transformExpression(node); @@ -34,6 +47,7 @@ export function transformAssignment( // TODO: Change type to ts.LeftHandSideExpression? lhs: ts.Expression, right: lua.Expression, + rightHasPrecedingStatements?: boolean, parent?: ts.Expression ): lua.Statement[] { if (ts.isOptionalChain(lhs)) { @@ -55,13 +69,14 @@ export function transformAssignment( return [arrayLengthAssignment]; } - const symbol = ts.isShorthandPropertyAssignment(lhs.parent) - ? context.checker.getShorthandAssignmentValueSymbol(lhs.parent) - : context.checker.getSymbolAtLocation(lhs); + const symbol = + lhs.parent && ts.isShorthandPropertyAssignment(lhs.parent) + ? context.checker.getShorthandAssignmentValueSymbol(lhs.parent) + : context.checker.getSymbolAtLocation(lhs); const dependentSymbols = symbol ? getDependenciesOfSymbol(context, symbol) : []; - const left = transformAssignmentLeftHandSideExpression(context, lhs); + const left = transformAssignmentLeftHandSideExpression(context, lhs, rightHasPrecedingStatements); const rootAssignment = lua.createAssignmentStatement(left, right, lhs.parent); @@ -75,20 +90,36 @@ export function transformAssignment( ]; } +export function transformAssignmentWithRightPrecedingStatements( + context: TransformationContext, + lhs: ts.Expression, + right: lua.Expression, + rightPrecedingStatements: lua.Statement[], + parent?: ts.Expression +): lua.Statement[] { + return [ + ...rightPrecedingStatements, + ...transformAssignment(context, lhs, right, rightPrecedingStatements.length > 0, parent), + ]; +} + function transformDestructuredAssignmentExpression( context: TransformationContext, expression: ts.DestructuringAssignment -): ImmediatelyInvokedFunctionParameters { - const rootIdentifier = lua.createAnonymousIdentifier(expression.left); +) { + const rootIdentifier = context.createTempNameForNode(expression.right); - let right = context.transformExpression(expression.right); + let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.right) + ); + context.addPrecedingStatements(rightPrecedingStatements); if (isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } const statements = [ lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier), + ...transformDestructuringAssignment(context, expression, rootIdentifier, rightPrecedingStatements.length > 0), ]; return { statements, result: rootIdentifier }; @@ -115,56 +146,36 @@ export function transformAssignmentExpression( } if (isDestructuringAssignment(expression)) { - return transformToImmediatelyInvokedFunctionExpression( - context, - () => transformDestructuredAssignmentExpression(context, expression), - expression - ); + const { statements, result } = transformDestructuredAssignmentExpression(context, expression); + context.addPrecedingStatements(statements); + return result; } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { - // Left is property/element access: cache result while maintaining order of evaluation - // (function(o, i, v) o[i] = v; return v end)(${objExpression}, ${indexExpression}, ${right}) - const objParameter = lua.createIdentifier("o"); - const indexParameter = lua.createIdentifier("i"); - const valueParameter = lua.createIdentifier("v"); - const indexStatement = lua.createTableIndexExpression(objParameter, indexParameter); - const statements: lua.Statement[] = [ - lua.createAssignmentStatement(indexStatement, valueParameter), - lua.createReturnStatement([valueParameter]), - ]; - const iife = lua.createFunctionExpression(lua.createBlock(statements), [ - objParameter, - indexParameter, - valueParameter, - ]); - pushScope(context, ScopeType.Function); - const objExpression = context.transformExpression(expression.left.expression); - let indexExpression: lua.Expression; - if (ts.isPropertyAccessExpression(expression.left)) { - // Property access - indexExpression = lua.createStringLiteral(expression.left.name.text); - } else { - // Element access - indexExpression = transformElementAccessArgument(context, expression.left); - } + const tempVar = context.createTempNameForNode(expression.right); + const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.right) + ); - const args = [objExpression, indexExpression, context.transformExpression(expression.right)]; - popScope(context); - return lua.createCallExpression(iife, args, expression); - } else { - return transformToImmediatelyInvokedFunctionExpression( + const left = transformAssignmentLeftHandSideExpression( context, - () => { - // Simple assignment - // (function() ${left} = ${right}; return ${left} end)() - const left = context.transformExpression(expression.left); - const right = context.transformExpression(expression.right); - const statements = transformAssignment(context, expression.left, right); - return { statements, result: left }; - }, - expression + expression.left, + precedingStatements.length > 0 ); + + context.addPrecedingStatements([ + ...precedingStatements, + lua.createVariableDeclarationStatement(tempVar, right, expression.right), + lua.createAssignmentStatement(left, lua.cloneIdentifier(tempVar), expression.left), + ]); + return lua.cloneIdentifier(tempVar); + } else { + // Simple assignment + // ${left} = ${right}; return ${left} + const left = context.transformExpression(expression.left); + const right = context.transformExpression(expression.right); + context.addPrecedingStatements(transformAssignment(context, expression.left, right)); + return left; } } @@ -179,7 +190,9 @@ const canBeTransformedToLuaAssignmentStatement = ( } if (ts.isPropertyAccessExpression(element) || ts.isElementAccessExpression(element)) { - return true; + // Lua's execution order for multi-assignments is not the same as JS's, so we should always + // break these down when the left side may have side effects. + return false; } if (ts.isIdentifier(element)) { @@ -203,12 +216,15 @@ export function transformAssignmentStatement( if (isDestructuringAssignment(expression)) { if (canBeTransformedToLuaAssignmentStatement(context, expression)) { const rightType = context.checker.getTypeAtLocation(expression.right); - let right: lua.Expression | lua.Expression[] = context.transformExpression(expression.right); + let right: lua.Expression | lua.Expression[]; if (ts.isArrayLiteralExpression(expression.right)) { - right = expression.right.elements.map(e => context.transformExpression(e)); - } else if (!isMultiReturnCall(context, expression.right) && isArrayType(context, rightType)) { - right = createUnpackCall(context, right, expression.right); + right = transformExpressionList(context, expression.right.elements); + } else { + right = context.transformExpression(expression.right); + if (!isMultiReturnCall(context, expression.right) && isArrayType(context, rightType)) { + right = createUnpackCall(context, right, expression.right); + } } const left = expression.left.elements.map(e => transformAssignmentLeftHandSideExpression(context, e)); @@ -216,17 +232,28 @@ export function transformAssignmentStatement( return [lua.createAssignmentStatement(left, right, expression)]; } - let right = context.transformExpression(expression.right); + let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.right) + ); + context.addPrecedingStatements(rightPrecedingStatements); if (isMultiReturnCall(context, expression.right)) { right = wrapInTable(right); } - const rootIdentifier = lua.createAnonymousIdentifier(expression.left); + const rootIdentifier = context.createTempNameForNode(expression.left); return [ lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier), + ...transformDestructuringAssignment( + context, + expression, + rootIdentifier, + rightPrecedingStatements.length > 0 + ), ]; } else { - return transformAssignment(context, expression.left, context.transformExpression(expression.right)); + const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.right) + ); + return transformAssignmentWithRightPrecedingStatements(context, expression.left, right, precedingStatements); } } diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index febd7681e..76947ede9 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -2,38 +2,23 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { - ImmediatelyInvokedFunctionParameters, - transformToImmediatelyInvokedFunctionExpression, -} from "../../utils/transform"; -import { isArrayType, isExpressionWithEvaluationEffect } from "../../utils/typescript"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { transformBinaryOperation } from "../binary-expression"; -import { transformAssignment } from "./assignments"; +import { transformAssignmentWithRightPrecedingStatements } from "./assignments"; -// If expression is property/element access with possible effects from being evaluated, returns separated object and index expressions. -export function parseAccessExpressionWithEvaluationEffects( - context: TransformationContext, - node: ts.Expression -): [ts.Expression, ts.Expression] | [] { - if ( - ts.isElementAccessExpression(node) && - (isExpressionWithEvaluationEffect(node.expression) || isExpressionWithEvaluationEffect(node.argumentExpression)) - ) { - const type = context.checker.getTypeAtLocation(node.expression); - if (isArrayType(context, type)) { - // Offset arrays by one - const oneLit = ts.factory.createNumericLiteral("1"); - const exp = ts.factory.createParenthesizedExpression(node.argumentExpression); - const addExp = ts.factory.createBinaryExpression(exp, ts.SyntaxKind.PlusToken, oneLit); - return [node.expression, addExp]; - } else { - return [node.expression, node.argumentExpression]; - } - } else if (ts.isPropertyAccessExpression(node) && isExpressionWithEvaluationEffect(node.expression)) { - return [node.expression, ts.factory.createStringLiteral(node.name.text)]; - } +function isLuaExpressionWithSideEffect(expression: lua.Expression) { + return !(lua.isLiteral(expression) || lua.isIdentifier(expression)); +} - return []; +function shouldCacheTableIndexExpressions( + expression: lua.TableIndexExpression, + rightPrecedingStatements: lua.Statement[] +) { + return ( + isLuaExpressionWithSideEffect(expression.table) || + isLuaExpressionWithSideEffect(expression.index) || + rightPrecedingStatements.length > 0 + ); } // TODO: `as const` doesn't work on enum members @@ -85,74 +70,136 @@ export function transformCompoundAssignment( rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -): ImmediatelyInvokedFunctionParameters { +) { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - const right = context.transformExpression(rhs); + const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(rhs) + ); - const [objExpression, indexExpression] = parseAccessExpressionWithEvaluationEffects(context, lhs); - if (objExpression && indexExpression) { + if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __obj, __index = ${objExpression}, ${indexExpression}; - const obj = lua.createIdentifier("____obj"); - const index = lua.createIdentifier("____index"); - const objAndIndexDeclaration = lua.createVariableDeclarationStatement( - [obj, index], - [context.transformExpression(objExpression), context.transformExpression(indexExpression)] - ); + const obj = context.createTempNameForLuaExpression(left.table); + const index = context.createTempNameForLuaExpression(left.index); + + const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [left.table, left.index]); const accessExpression = lua.createTableIndexExpression(obj, index); - const tmp = lua.createIdentifier("____tmp"); - let tmpDeclaration: lua.VariableDeclarationStatement; - let assignStatement: lua.AssignmentStatement; + const tmp = context.createTempNameForLuaExpression(left); if (isPostfix) { // local ____tmp = ____obj[____index]; // ____obj[____index] = ____tmp ${replacementOperator} ${right}; - tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); - const operatorExpression = transformBinaryOperation(context, tmp, right, operator, expression); - assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); + // return ____tmp + const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + tmp, + right, + rightPrecedingStatements, + operator, + expression + ); + const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); + return { + statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + result: tmp, + }; } else { // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; - const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, expression); - tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); - assignStatement = lua.createAssignmentStatement(accessExpression, tmp); + // return ____tmp + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + accessExpression, + right, + rightPrecedingStatements, + operator, + expression + ); + const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); + const assignStatement = lua.createAssignmentStatement(accessExpression, tmp); + return { + statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + result: tmp, + }; } - // return ____tmp - return { statements: [objAndIndexDeclaration, tmpDeclaration, assignStatement], result: tmp }; } else if (isPostfix) { // Postfix expressions need to cache original value in temp // local ____tmp = ${left}; // ${left} = ____tmp ${replacementOperator} ${right}; // return ____tmp - const tmpIdentifier = lua.createIdentifier("____tmp"); + const tmpIdentifier = context.createTempNameForLuaExpression(left); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); - const operatorExpression = transformBinaryOperation(context, tmpIdentifier, right, operator, expression); - const assignStatements = transformAssignment(context, lhs, operatorExpression); - return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + tmpIdentifier, + right, + rightPrecedingStatements, + operator, + expression + ); + const assignStatements = transformAssignmentWithRightPrecedingStatements( + context, + lhs, + operatorExpression, + rightPrecedingStatements + ); + return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier }; } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { // Simple property/element access expressions need to cache in temp to avoid double-evaluation // local ____tmp = ${left} ${replacementOperator} ${right}; // ${left} = ____tmp; // return ____tmp - const tmpIdentifier = lua.createIdentifier("____tmp"); - const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); + const tmpIdentifier = context.createTempNameForLuaExpression(left); + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + left, + right, + rightPrecedingStatements, + operator, + expression + ); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); - const assignStatements = transformAssignment(context, lhs, tmpIdentifier); if (isSetterSkippingCompoundAssignmentOperator(operator)) { const statements = [ tmpDeclaration, - ...transformSetterSkippingCompoundAssignment(context, tmpIdentifier, operator, rhs), + ...transformSetterSkippingCompoundAssignment(tmpIdentifier, operator, right, precedingStatements), ]; return { statements, result: tmpIdentifier }; } + const assignStatements = transformAssignmentWithRightPrecedingStatements( + context, + lhs, + tmpIdentifier, + precedingStatements + ); return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { + if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) { + return { + statements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements), + result: left, + }; + } + // Simple expressions - // ${left} = ${right}; return ${right} - const operatorExpression = transformBinaryOperation(context, left, right, operator, expression); - const statements = transformAssignment(context, lhs, operatorExpression); + // ${left} = ${left} ${operator} ${right} + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + left, + right, + rightPrecedingStatements, + operator, + expression + ); + const statements = transformAssignmentWithRightPrecedingStatements( + context, + lhs, + operatorExpression, + precedingStatements + ); return { statements, result: left }; } } @@ -165,12 +212,10 @@ export function transformCompoundAssignmentExpression( rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -): lua.CallExpression { - return transformToImmediatelyInvokedFunctionExpression( - context, - () => transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix), - expression - ); +): lua.Expression { + const { statements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix); + context.addPrecedingStatements(statements); + return result; } export function transformCompoundAssignmentStatement( @@ -181,41 +226,66 @@ export function transformCompoundAssignmentStatement( operator: CompoundAssignmentToken ): lua.Statement[] { const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - const right = context.transformExpression(rhs); + let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(rhs) + ); - const [objExpression, indexExpression] = parseAccessExpressionWithEvaluationEffects(context, lhs); - if (objExpression && indexExpression) { + if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __obj, __index = ${objExpression}, ${indexExpression}; // ____obj[____index] = ____obj[____index] ${replacementOperator} ${right}; - const obj = lua.createIdentifier("____obj"); - const index = lua.createIdentifier("____index"); - const objAndIndexDeclaration = lua.createVariableDeclarationStatement( - [obj, index], - [context.transformExpression(objExpression), context.transformExpression(indexExpression)] - ); + const obj = context.createTempNameForLuaExpression(left.table); + const index = context.createTempNameForLuaExpression(left.index); + + const objAndIndexDeclaration = lua.createVariableDeclarationStatement([obj, index], [left.table, left.index]); const accessExpression = lua.createTableIndexExpression(obj, index); if (isSetterSkippingCompoundAssignmentOperator(operator)) { return [ objAndIndexDeclaration, - ...transformSetterSkippingCompoundAssignment(context, accessExpression, operator, rhs, node), + ...transformSetterSkippingCompoundAssignment( + accessExpression, + operator, + right, + rightPrecedingStatements, + node + ), ]; } - const operatorExpression = transformBinaryOperation(context, accessExpression, right, operator, node); + let operatorExpression: lua.Expression; + [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + context, + accessExpression, + right, + rightPrecedingStatements, + operator, + node + ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); - return [objAndIndexDeclaration, assignStatement]; + return [objAndIndexDeclaration, ...rightPrecedingStatements, assignStatement]; } else { if (isSetterSkippingCompoundAssignmentOperator(operator)) { - const luaLhs = context.transformExpression(lhs) as lua.AssignmentLeftHandSideExpression; - return transformSetterSkippingCompoundAssignment(context, luaLhs, operator, rhs, node); + return transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements, node); } // Simple statements // ${left} = ${left} ${replacementOperator} ${right} - const operatorExpression = transformBinaryOperation(context, left, right, operator, node); - return transformAssignment(context, lhs, operatorExpression); + let operatorExpression: lua.Expression; + [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + context, + left, + right, + rightPrecedingStatements, + operator, + node + ); + return transformAssignmentWithRightPrecedingStatements( + context, + lhs, + operatorExpression, + rightPrecedingStatements + ); } } @@ -237,10 +307,10 @@ function isSetterSkippingCompoundAssignmentOperator( } function transformSetterSkippingCompoundAssignment( - context: TransformationContext, lhs: lua.AssignmentLeftHandSideExpression, operator: SetterSkippingCompoundAssignmentOperator, - rhs: ts.Expression, + right: lua.Expression, + rightPrecedingStatements: lua.Statement[], node?: ts.Node ): lua.Statement[] { // These assignments have the form 'if x then y = z', figure out what condition x is first. @@ -260,7 +330,7 @@ function transformSetterSkippingCompoundAssignment( return [ lua.createIfStatement( condition, - lua.createBlock([lua.createAssignmentStatement(lhs, context.transformExpression(rhs))]), + lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(lhs, right, node)]), undefined, node ), diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index 567de4e6f..d3d0086c0 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -1,9 +1,12 @@ import * as ts from "typescript"; +import { transformBinaryOperation } from "."; import * as lua from "../../../LuaAST"; -import { assertNever } from "../../../utils"; +import { assertNever, cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { isArrayType, isAssignmentPattern } from "../../utils/typescript"; +import { moveToPrecedingTemp } from "../expression-list"; import { transformPropertyName } from "../literal"; import { transformAssignment, @@ -36,28 +39,31 @@ export function isArrayLength( export function transformDestructuringAssignment( context: TransformationContext, node: ts.DestructuringAssignment, - root: lua.Expression + root: lua.Expression, + rightHasPrecedingStatements: boolean ): lua.Statement[] { - return transformAssignmentPattern(context, node.left, root); + return transformAssignmentPattern(context, node.left, root, rightHasPrecedingStatements); } export function transformAssignmentPattern( context: TransformationContext, node: ts.AssignmentPattern, - root: lua.Expression + root: lua.Expression, + rightHasPrecedingStatements: boolean ): lua.Statement[] { switch (node.kind) { case ts.SyntaxKind.ObjectLiteralExpression: - return transformObjectLiteralAssignmentPattern(context, node, root); + return transformObjectLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements); case ts.SyntaxKind.ArrayLiteralExpression: - return transformArrayLiteralAssignmentPattern(context, node, root); + return transformArrayLiteralAssignmentPattern(context, node, root, rightHasPrecedingStatements); } } function transformArrayLiteralAssignmentPattern( context: TransformationContext, node: ts.ArrayLiteralExpression, - root: lua.Expression + root: lua.Expression, + rightHasPrecedingStatements: boolean ): lua.Statement[] { return node.elements.flatMap((element, index) => { const indexedRoot = lua.createTableIndexExpression(root, lua.createNumericLiteral(index + 1), element); @@ -67,16 +73,18 @@ function transformArrayLiteralAssignmentPattern( return transformObjectLiteralAssignmentPattern( context, element as ts.ObjectLiteralExpression, - indexedRoot + indexedRoot, + rightHasPrecedingStatements ); case ts.SyntaxKind.ArrayLiteralExpression: return transformArrayLiteralAssignmentPattern( context, element as ts.ArrayLiteralExpression, - indexedRoot + indexedRoot, + rightHasPrecedingStatements ); case ts.SyntaxKind.BinaryExpression: - const assignedVariable = lua.createIdentifier("____bindingAssignmentValue"); + const assignedVariable = context.createTempNameForLuaExpression(indexedRoot); const assignedVariableDeclaration = lua.createVariableDeclarationStatement( assignedVariable, @@ -89,12 +97,19 @@ function transformArrayLiteralAssignmentPattern( lua.SyntaxKind.EqualityOperator ); - const defaultAssignmentStatements = transformAssignment( + const [defaultPrecedingStatements, defaultAssignmentStatements] = transformInPrecedingStatementScope( context, - (element as ts.BinaryExpression).left, - context.transformExpression((element as ts.BinaryExpression).right) + () => + transformAssignment( + context, + (element as ts.BinaryExpression).left, + context.transformExpression((element as ts.BinaryExpression).right) + ) ); + // Keep preceding statements inside if block + defaultAssignmentStatements.unshift(...defaultPrecedingStatements); + const elseAssignmentStatements = transformAssignment( context, (element as ts.BinaryExpression).left, @@ -111,7 +126,10 @@ function transformArrayLiteralAssignmentPattern( case ts.SyntaxKind.Identifier: case ts.SyntaxKind.PropertyAccessExpression: case ts.SyntaxKind.ElementAccessExpression: - return transformAssignment(context, element, indexedRoot); + const [precedingStatements, statements] = transformInPrecedingStatementScope(context, () => + transformAssignment(context, element, indexedRoot, rightHasPrecedingStatements) + ); + return [...precedingStatements, ...statements]; // Keep preceding statements in order case ts.SyntaxKind.SpreadElement: if (index !== node.elements.length - 1) { // TypeScript error @@ -126,7 +144,15 @@ function transformArrayLiteralAssignmentPattern( lua.createNumericLiteral(index) ); - return transformAssignment(context, (element as ts.SpreadElement).expression, restElements); + const [spreadPrecedingStatements, spreadStatements] = transformInPrecedingStatementScope(context, () => + transformAssignment( + context, + (element as ts.SpreadElement).expression, + restElements, + rightHasPrecedingStatements + ) + ); + return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order case ts.SyntaxKind.OmittedExpression: return []; default: @@ -139,7 +165,8 @@ function transformArrayLiteralAssignmentPattern( function transformObjectLiteralAssignmentPattern( context: TransformationContext, node: ts.ObjectLiteralExpression, - root: lua.Expression + root: lua.Expression, + rightHasPrecedingStatements: boolean ): lua.Statement[] { const result: lua.Statement[] = []; @@ -149,7 +176,7 @@ function transformObjectLiteralAssignmentPattern( result.push(...transformShorthandPropertyAssignment(context, property, root)); break; case ts.SyntaxKind.PropertyAssignment: - result.push(...transformPropertyAssignment(context, property, root)); + result.push(...transformPropertyAssignment(context, property, root, rightHasPrecedingStatements)); break; case ts.SyntaxKind.SpreadAssignment: result.push(...transformSpreadAssignment(context, property, root, node.properties)); @@ -207,7 +234,8 @@ function transformShorthandPropertyAssignment( function transformPropertyAssignment( context: TransformationContext, node: ts.PropertyAssignment, - root: lua.Expression + root: lua.Expression, + rightHasPrecedingStatements: boolean ): lua.Statement[] { const result: lua.Statement[] = []; @@ -216,38 +244,95 @@ function transformPropertyAssignment( const newRootAccess = lua.createTableIndexExpression(root, propertyAccessString); if (ts.isObjectLiteralExpression(node.initializer)) { - return transformObjectLiteralAssignmentPattern(context, node.initializer, newRootAccess); + return transformObjectLiteralAssignmentPattern( + context, + node.initializer, + newRootAccess, + rightHasPrecedingStatements + ); } if (ts.isArrayLiteralExpression(node.initializer)) { - return transformArrayLiteralAssignmentPattern(context, node.initializer, newRootAccess); + return transformArrayLiteralAssignmentPattern( + context, + node.initializer, + newRootAccess, + rightHasPrecedingStatements + ); } } - const leftExpression = ts.isBinaryExpression(node.initializer) ? node.initializer.left : node.initializer; - const variableToExtract = transformPropertyName(context, node.name); - const extractingExpression = lua.createTableIndexExpression(root, variableToExtract); + context.pushPrecedingStatements(); - const destructureAssignmentStatements = transformAssignment(context, leftExpression, extractingExpression); - - result.push(...destructureAssignmentStatements); + let variableToExtract = transformPropertyName(context, node.name); + // Must be evaluated before left's preceding statements + variableToExtract = moveToPrecedingTemp(context, variableToExtract, node.name); + const extractingExpression = lua.createTableIndexExpression(root, variableToExtract); + let destructureAssignmentStatements: lua.Statement[]; if (ts.isBinaryExpression(node.initializer)) { - const assignmentLeftHandSide = context.transformExpression(node.initializer.left); - - const nilCondition = lua.createBinaryExpression( - assignmentLeftHandSide, - lua.createNilLiteral(), - lua.SyntaxKind.EqualityOperator - ); - - const ifBlock = lua.createBlock( - transformAssignmentStatement(context, node.initializer as ts.AssignmentExpression) + if ( + ts.isPropertyAccessExpression(node.initializer.left) || + ts.isElementAccessExpression(node.initializer.left) + ) { + // Access expressions need their table and index expressions cached to preserve execution order + const left = cast(context.transformExpression(node.initializer.left), lua.isTableIndexExpression); + + const rightExpression = node.initializer.right; + const [defaultPrecedingStatements, defaultExpression] = transformInPrecedingStatementScope(context, () => + context.transformExpression(rightExpression) + ); + + const tableTemp = context.createTempNameForLuaExpression(left.table); + const indexTemp = context.createTempNameForLuaExpression(left.index); + + const tempsDeclaration = lua.createVariableDeclarationStatement( + [tableTemp, indexTemp], + [left.table, left.index] + ); + + // obj[index] = extractingExpression ?? defaultExpression + const [rightPrecedingStatements, rhs] = transformBinaryOperation( + context, + extractingExpression, + defaultExpression, + defaultPrecedingStatements, + ts.SyntaxKind.QuestionQuestionToken, + node.initializer + ); + const assignStatement = lua.createAssignmentStatement( + lua.createTableIndexExpression(tableTemp, indexTemp), + rhs + ); + + destructureAssignmentStatements = [tempsDeclaration, ...rightPrecedingStatements, assignStatement]; + } else { + const assignmentLeftHandSide = context.transformExpression(node.initializer.left); + + const nilCondition = lua.createBinaryExpression( + assignmentLeftHandSide, + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator + ); + + const ifBlock = lua.createBlock( + transformAssignmentStatement(context, node.initializer as ts.AssignmentExpression) + ); + + destructureAssignmentStatements = [lua.createIfStatement(nilCondition, ifBlock, undefined, node)]; + } + } else { + destructureAssignmentStatements = transformAssignment( + context, + node.initializer, + extractingExpression, + rightHasPrecedingStatements ); - - result.push(lua.createIfStatement(nilCondition, ifBlock, undefined, node)); } + result.push(...context.popPrecedingStatements()); + result.push(...destructureAssignmentStatements); + return result; } diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 93ea66018..df4ef6434 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -14,7 +14,18 @@ import { unwrapCompoundAssignmentToken, } from "./compound"; import { assert } from "../../../utils"; -import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; +import { transformOrderedExpressions } from "../expression-list"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; + +type ShortCircuitOperator = + | ts.SyntaxKind.AmpersandAmpersandToken + | ts.SyntaxKind.BarBarToken + | ts.SyntaxKind.QuestionQuestionToken; + +const isShortCircuitOperator = (value: unknown): value is ShortCircuitOperator => + value === ts.SyntaxKind.AmpersandAmpersandToken || + value === ts.SyntaxKind.BarBarToken || + value === ts.SyntaxKind.QuestionQuestionToken; type SimpleOperator = | ts.AdditiveOperatorOrHigher @@ -41,7 +52,7 @@ const simpleOperatorsToLua: Record = { [ts.SyntaxKind.ExclamationEqualsEqualsToken]: lua.SyntaxKind.InequalityOperator, }; -export function transformBinaryOperation( +function transformBinaryOperationWithNoPrecedingStatements( context: TransformationContext, left: lua.Expression, right: lua.Expression, @@ -76,6 +87,100 @@ export function transformBinaryOperation( return lua.createBinaryExpression(left, right, luaOperator, node); } +export function createShortCircuitBinaryExpressionPrecedingStatements( + context: TransformationContext, + lhs: lua.Expression, + rhs: lua.Expression, + rightPrecedingStatements: lua.Statement[], + operator: ShortCircuitOperator, + node?: ts.BinaryExpression +): [lua.Statement[], lua.Expression] { + const conditionIdentifier = context.createTempNameForLuaExpression(lhs); + const assignmentStatement = lua.createVariableDeclarationStatement(conditionIdentifier, lhs, node?.left); + + let condition: lua.Expression; + switch (operator) { + case ts.SyntaxKind.BarBarToken: + condition = lua.createUnaryExpression( + lua.cloneIdentifier(conditionIdentifier), + lua.SyntaxKind.NotOperator, + node + ); + break; + case ts.SyntaxKind.AmpersandAmpersandToken: + condition = lua.cloneIdentifier(conditionIdentifier); + break; + case ts.SyntaxKind.QuestionQuestionToken: + condition = lua.createBinaryExpression( + lua.cloneIdentifier(conditionIdentifier), + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator, + node + ); + break; + } + + const ifStatement = lua.createIfStatement( + condition, + lua.createBlock([...rightPrecedingStatements, lua.createAssignmentStatement(conditionIdentifier, rhs)]), + undefined, + node?.left + ); + return [[assignmentStatement, ifStatement], conditionIdentifier]; +} + +function transformShortCircuitBinaryExpression( + context: TransformationContext, + node: ts.BinaryExpression, + operator: ShortCircuitOperator +): [lua.Statement[], lua.Expression] { + const lhs = context.transformExpression(node.left); + const [rightPrecedingStatements, rhs] = transformInPrecedingStatementScope(context, () => + context.transformExpression(node.right) + ); + if (rightPrecedingStatements.length > 0) { + return createShortCircuitBinaryExpressionPrecedingStatements( + context, + lhs, + rhs, + rightPrecedingStatements, + operator, + node + ); + } else { + return [ + rightPrecedingStatements, + transformBinaryOperationWithNoPrecedingStatements(context, lhs, rhs, operator, node), + ]; + } +} + +export function transformBinaryOperation( + context: TransformationContext, + left: lua.Expression, + right: lua.Expression, + rightPrecedingStatements: lua.Statement[], + operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, + node: ts.Node +): [lua.Statement[], lua.Expression] { + if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) { + assert(ts.isBinaryExpression(node)); + return createShortCircuitBinaryExpressionPrecedingStatements( + context, + left, + right, + rightPrecedingStatements, + operator, + node + ); + } + + return [ + rightPrecedingStatements, + transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node), + ]; +} + export const transformBinaryExpression: FunctionVisitor = (node, context) => { const operator = node.operatorToken.kind; @@ -118,25 +223,31 @@ export const transformBinaryExpression: FunctionVisitor = ( } case ts.SyntaxKind.CommaToken: { - return transformToImmediatelyInvokedFunctionExpression( - context, - () => ({ - statements: context.transformStatements(ts.factory.createExpressionStatement(node.left)), - result: context.transformExpression(node.right), - }), - node + const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left)); + const [precedingStatements, result] = transformInPrecedingStatementScope(context, () => + context.transformExpression(node.right) ); + statements.push(...precedingStatements); + context.addPrecedingStatements(statements); + return result; } - default: - return transformBinaryOperation( - context, - context.transformExpression(node.left), - context.transformExpression(node.right), - operator, - node - ); + case ts.SyntaxKind.QuestionQuestionToken: + case ts.SyntaxKind.AmpersandAmpersandToken: + case ts.SyntaxKind.BarBarToken: { + const [precedingStatements, result] = transformShortCircuitBinaryExpression(context, node, operator); + context.addPrecedingStatements(precedingStatements); + return result; + } } + + let [precedingStatements, [lhs, rhs]] = transformInPrecedingStatementScope(context, () => + transformOrderedExpressions(context, [node.left, node.right]) + ); + let result: lua.Expression; + [precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node); + context.addPrecedingStatements(precedingStatements); + return result; }; export function transformBinaryExpressionStatement( diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 22adb9a45..a863789ae 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -5,7 +5,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; -import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; @@ -23,124 +23,107 @@ import { transformTableSetExpression, } from "./language-extensions/table"; import { annotationRemoved, invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; -import { - ImmediatelyInvokedFunctionParameters, - transformToImmediatelyInvokedFunctionExpression, -} from "../utils/transform"; +import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; -function getExpressionsBeforeAndAfterFirstSpread( - expressions: readonly ts.Expression[] -): [readonly ts.Expression[], readonly ts.Expression[]] { - // [a, b, ...c, d, ...e] --> [a, b] and [...c, d, ...e] - const index = expressions.findIndex(ts.isSpreadElement); - const hasSpreadElement = index !== -1; - const before = hasSpreadElement ? expressions.slice(0, index) : expressions; - const after = hasSpreadElement ? expressions.slice(index) : []; - return [before, after]; -} - -function transformSpreadableExpressionsIntoArrayConcatArguments( +export function validateArguments( context: TransformationContext, - expressions: readonly ts.Expression[] | ts.NodeArray -): lua.Expression[] { - // [...array, a, b, ...tuple()] --> [ [...array], [a, b], [...tuple()] ] - // chunk non-spread arguments together so they don't concat - const chunks: ts.Expression[][] = []; - for (const [index, expression] of expressions.entries()) { - if (ts.isSpreadElement(expression)) { - chunks.push([expression]); - const next = expressions[index + 1]; - if (next && !ts.isSpreadElement(next)) { - chunks.push([]); - } - } else { - let lastChunk = chunks[chunks.length - 1]; - if (!lastChunk) { - lastChunk = []; - chunks.push(lastChunk); - } - lastChunk.push(expression); + params: readonly ts.Expression[], + signature?: ts.Signature +) { + if (!signature || signature.parameters.length < params.length) { + return; + } + for (const [index, param] of params.entries()) { + const signatureParameter = signature.parameters[index]; + const paramType = context.checker.getTypeAtLocation(param); + if (signatureParameter.valueDeclaration !== undefined) { + const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + validateAssignment(context, param, paramType, signatureType, signatureParameter.name); } } - - return chunks.map(chunk => wrapInTable(...chunk.map(expression => context.transformExpression(expression)))); } -export function flattenSpreadExpressions( +export function transformArguments( context: TransformationContext, - expressions: readonly ts.Expression[] + params: readonly ts.Expression[], + signature?: ts.Signature, + callContext?: ts.Expression ): lua.Expression[] { - const [preSpreadExpressions, postSpreadExpressions] = getExpressionsBeforeAndAfterFirstSpread(expressions); - const transformedPreSpreadExpressions = preSpreadExpressions.map(a => context.transformExpression(a)); + validateArguments(context, params, signature); + return transformExpressionList(context, callContext ? [callContext, ...params] : params); +} - // Nothing special required - if (postSpreadExpressions.length === 0) { - return transformedPreSpreadExpressions; +function transformCallWithArguments( + context: TransformationContext, + callExpression: ts.Expression, + transformedArguments: lua.Expression[], + argPrecedingStatements: lua.Statement[], + callContext?: ts.Expression +): [lua.Expression, lua.Expression[]] { + let call = context.transformExpression(callExpression); + + let transformedContext: lua.Expression | undefined; + if (callContext) { + transformedContext = context.transformExpression(callContext); } - // Only one spread element at the end? Will work as expected - if (postSpreadExpressions.length === 1) { - return [...transformedPreSpreadExpressions, context.transformExpression(postSpreadExpressions[0])]; + if (argPrecedingStatements.length > 0) { + if (transformedContext) { + transformedContext = moveToPrecedingTemp(context, transformedContext, callContext); + } + call = moveToPrecedingTemp(context, call, callExpression); + context.addPrecedingStatements(argPrecedingStatements); } - // Use Array.concat and unpack the result of that as the last Expression - const concatArguments = transformSpreadableExpressionsIntoArrayConcatArguments(context, postSpreadExpressions); - const lastExpression = createUnpackCall( - context, - transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, undefined, ...concatArguments) - ); + if (transformedContext) { + transformedArguments.unshift(transformedContext); + } - return [...transformedPreSpreadExpressions, lastExpression]; + return [call, transformedArguments]; } -export function transformArguments( +export function transformCallAndArguments( context: TransformationContext, + callExpression: ts.Expression, params: readonly ts.Expression[], signature?: ts.Signature, callContext?: ts.Expression -): lua.Expression[] { - const parameters = flattenSpreadExpressions(context, params); - - // Add context as first param if present - if (callContext) { - parameters.unshift(context.transformExpression(callContext)); - } - - if (signature && signature.parameters.length >= params.length) { - for (const [index, param] of params.entries()) { - const signatureParameter = signature.parameters[index]; - const paramType = context.checker.getTypeAtLocation(param); - if (signatureParameter.valueDeclaration !== undefined) { - const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); - validateAssignment(context, param, paramType, signatureType, signatureParameter.name); - } - } - } - - return parameters; +): [lua.Expression, lua.Expression[]] { + const [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => + transformArguments(context, params, signature, callContext) + ); + return transformCallWithArguments(context, callExpression, transformedArguments, argPrecedingStatements); } function transformElementAccessCall( context: TransformationContext, left: ts.PropertyAccessExpression | ts.ElementAccessExpression, - args: ts.Expression[] | ts.NodeArray, - signature?: ts.Signature -): ImmediatelyInvokedFunctionParameters { - const transformedArguments = transformArguments(context, args, signature, ts.factory.createIdentifier("____self")); - + transformedArguments: lua.Expression[], + argPrecedingStatements: lua.Statement[] +) { // Cache left-side if it has effects - // (function() local ____self = context; return ____self[argument](parameters); end)() + // local ____self = context; return ____self[argument](parameters); + const selfIdentifier = lua.createIdentifier(context.createTempName("self")); + const callContext = context.transformExpression(left.expression); + const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); + context.addPrecedingStatements(selfAssignment); + const argument = ts.isElementAccessExpression(left) ? transformElementAccessArgument(context, left) : lua.createStringLiteral(left.name.text); - const selfIdentifier = lua.createIdentifier("____self"); - const callContext = context.transformExpression(left.expression); - const selfAssignment = lua.createVariableDeclarationStatement(selfIdentifier, callContext); - const index = lua.createTableIndexExpression(selfIdentifier, argument); - const callExpression = lua.createCallExpression(index, transformedArguments); - return { statements: selfAssignment, result: callExpression }; + + let index: lua.Expression = lua.createTableIndexExpression(selfIdentifier, argument); + + if (argPrecedingStatements.length > 0) { + // Cache index in temp if args had preceding statements + index = moveToPrecedingTemp(context, index); + context.addPrecedingStatements(argPrecedingStatements); + } + + return lua.createCallExpression(index, [selfIdentifier, ...transformedArguments]); } export function transformContextualCallExpression( @@ -150,10 +133,19 @@ export function transformContextualCallExpression( signature?: ts.Signature ): lua.CallExpression | lua.MethodCallExpression { const left = ts.isCallExpression(node) ? node.expression : node.tag; - if (ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && isValidLuaIdentifier(left.name.text)) { + + let [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => + transformArguments(context, args, signature) + ); + + if ( + ts.isPropertyAccessExpression(left) && + ts.isIdentifier(left.name) && + isValidLuaIdentifier(left.name.text) && + argPrecedingStatements.length === 0 + ) { // table:name() const table = context.transformExpression(left.expression); - if (ts.isOptionalChain(node)) { return transformLuaLibFunction( context, @@ -162,33 +154,40 @@ export function transformContextualCallExpression( table, lua.createStringLiteral(left.name.text, left.name), lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call - ...transformArguments(context, args, signature) + ...transformedArguments ); } else { return lua.createMethodCallExpression( table, lua.createIdentifier(left.name.text, left.name), - transformArguments(context, args, signature), + transformedArguments, node ); } } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { - return transformToImmediatelyInvokedFunctionExpression( + return transformElementAccessCall(context, left, transformedArguments, argPrecedingStatements); + } else { + let expression: lua.Expression; + [expression, transformedArguments] = transformCallWithArguments( context, - () => transformElementAccessCall(context, left, args, signature), - node + left, + transformedArguments, + argPrecedingStatements, + left.expression ); - } else { - const callContext = context.transformExpression(left.expression); - const expression = context.transformExpression(left); - const transformedArguments = transformArguments(context, args, signature); - return lua.createCallExpression(expression, [callContext, ...transformedArguments]); + return lua.createCallExpression(expression, transformedArguments, node); } } else if (ts.isIdentifier(left)) { const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); - const transformedArguments = transformArguments(context, args, signature, callContext); - const expression = context.transformExpression(left); + let expression: lua.Expression; + [expression, transformedArguments] = transformCallWithArguments( + context, + left, + transformedArguments, + argPrecedingStatements, + callContext + ); return lua.createCallExpression(expression, transformedArguments, node); } else { throw new Error(`Unsupported LeftHandSideExpression kind: ${ts.SyntaxKind[left.kind]}`); @@ -213,8 +212,7 @@ function transformPropertyCall( return transformContextualCallExpression(context, node, node.arguments, signature); } else { // table.name() - const callPath = context.transformExpression(node.expression); - const parameters = transformArguments(context, node.arguments, signature); + const [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); if (ts.isOptionalChain(node)) { return transformLuaLibFunction(context, LuaLibFeature.OptionalFunctionCall, node, callPath, ...parameters); @@ -235,8 +233,7 @@ function transformElementCall( return transformContextualCallExpression(context, node, node.arguments, signature); } else { // No context - const expression = context.transformExpression(node.expression); - const parameters = transformArguments(context, node.arguments, signature); + const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); return lua.createCallExpression(expression, parameters); } } @@ -260,11 +257,8 @@ export const transformCallExpression: FunctionVisitor = (node if (isTableDeleteCall(context, node)) { context.diagnostics.push(invalidTableDeleteExpression(node)); - return transformToImmediatelyInvokedFunctionExpression( - context, - () => ({ statements: transformTableDeleteExpression(context, node), result: lua.createNilLiteral() }), - node - ); + context.addPrecedingStatements(transformTableDeleteExpression(context, node)); + return lua.createNilLiteral(); } if (isTableGetCall(context, node)) { @@ -277,11 +271,8 @@ export const transformCallExpression: FunctionVisitor = (node if (isTableSetCall(context, node)) { context.diagnostics.push(invalidTableSetExpression(node)); - return transformToImmediatelyInvokedFunctionExpression( - context, - () => ({ statements: transformTableSetExpression(context, node), result: lua.createNilLiteral() }), - node - ); + context.addPrecedingStatements(transformTableSetExpression(context, node)); + return lua.createNilLiteral(); } if (ts.isPropertyAccessExpression(node.expression)) { @@ -316,15 +307,21 @@ export const transformCallExpression: FunctionVisitor = (node ); } - const callPath = context.transformExpression(node.expression); const signatureDeclaration = signature?.getDeclaration(); + let callPath: lua.Expression; let parameters: lua.Expression[] = []; if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { - parameters = transformArguments(context, node.arguments, signature); + [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); } else { const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); - parameters = transformArguments(context, node.arguments, signature, callContext); + [callPath, parameters] = transformCallAndArguments( + context, + node.expression, + node.arguments, + signature, + callContext + ); } const callExpression = lua.createCallExpression(callPath, parameters, node); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 2fb18a0cb..0ea562fa4 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -11,9 +11,8 @@ import { hasExportModifier, isSymbolExported, } from "../../utils/export"; -import { createSelfIdentifier, unwrapVisitorResult } from "../../utils/lua-ast"; +import { createSelfIdentifier } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; -import { transformToImmediatelyInvokedFunctionExpression } from "../../utils/transform"; import { transformIdentifier } from "../identifier"; import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; @@ -46,14 +45,9 @@ export function transformClassAsExpression( expression: ts.ClassLikeDeclaration, context: TransformationContext ): lua.Expression { - return transformToImmediatelyInvokedFunctionExpression( - context, - () => { - const { statements, name } = transformClassLikeDeclaration(expression, context); - return { statements: unwrapVisitorResult(statements), result: name }; - }, - expression - ); + const { statements, name } = transformClassLikeDeclaration(expression, context); + context.addPrecedingStatements(statements); + return name; } const classSuperInfos = new WeakMap(); @@ -73,8 +67,7 @@ function transformClassLikeDeclaration( } else if (classDeclaration.name !== undefined) { className = transformIdentifier(context, classDeclaration.name); } else { - // TypeScript error - className = lua.createAnonymousIdentifier(); + className = lua.createIdentifier(context.createTempName("class"), classDeclaration); } const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 97e1c3407..f7433e7b5 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -4,7 +4,7 @@ import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { transformArguments } from "../call"; +import { transformArguments, transformCallAndArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; const builtinErrorTypeNames = new Set([ @@ -61,14 +61,15 @@ export const transformNewExpression: FunctionVisitor = (node, } const signature = context.checker.getResolvedSignature(node); - const params = node.arguments - ? transformArguments(context, node.arguments, signature) - : [lua.createBooleanLiteral(true)]; + const [name, params] = transformCallAndArguments( + context, + node.expression, + node.arguments ?? [ts.factory.createTrue()], + signature + ); checkForLuaLibType(context, type); - const name = context.transformExpression(node.expression); - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 2fab7494c..f83837a2d 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; @@ -27,32 +28,34 @@ function canBeFalsy(context: TransformationContext, type: ts.Type): boolean { } } -function wrapInFunctionCall(expression: lua.Expression): lua.FunctionExpression { - const returnStatement = lua.createReturnStatement([expression]); - - return lua.createFunctionExpression( - lua.createBlock([returnStatement]), - undefined, - undefined, - lua.FunctionExpressionFlags.Inline - ); -} - function transformProtectedConditionalExpression( context: TransformationContext, expression: ts.ConditionalExpression -): lua.CallExpression { +): lua.Expression { + const tempVar = context.createTempNameForNode(expression.condition); + const condition = context.transformExpression(expression.condition); - const val1 = context.transformExpression(expression.whenTrue); - const val2 = context.transformExpression(expression.whenFalse); - const val1Function = wrapInFunctionCall(val1); - const val2Function = wrapInFunctionCall(val2); + const [trueStatements, val1] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.whenTrue) + ); + trueStatements.push(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), val1, expression.whenTrue)); - // (condition and (() => v1) or (() => v2))() - const conditionAnd = lua.createBinaryExpression(condition, val1Function, lua.SyntaxKind.AndOperator); - const orExpression = lua.createBinaryExpression(conditionAnd, val2Function, lua.SyntaxKind.OrOperator); - return lua.createCallExpression(orExpression, [], expression); + const [falseStatements, val2] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.whenFalse) + ); + falseStatements.push(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), val2, expression.whenFalse)); + + context.addPrecedingStatements([ + lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition), + lua.createIfStatement( + condition, + lua.createBlock(trueStatements, expression.whenTrue), + lua.createBlock(falseStatements, expression.whenFalse), + expression + ), + ]); + return lua.cloneIdentifier(tempVar); } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { @@ -78,8 +81,24 @@ export function transformIfStatement(statement: ts.IfStatement, context: Transfo if (statement.elseStatement) { if (ts.isIfStatement(statement.elseStatement)) { - const elseStatement = transformIfStatement(statement.elseStatement, context); - return lua.createIfStatement(condition, ifBlock, elseStatement); + const tsElseStatement = statement.elseStatement; + const [precedingStatements, elseStatement] = transformInPrecedingStatementScope(context, () => + transformIfStatement(tsElseStatement, context) + ); + // If else-if condition generates preceding statements, we can't use elseif, we have to break it down: + // if conditionA then + // ... + // else + // conditionB's preceding statements + // if conditionB then + // end + // end + if (precedingStatements.length > 0) { + const elseBlock = lua.createBlock([...precedingStatements, elseStatement]); + return lua.createIfStatement(condition, ifBlock, elseBlock); + } else { + return lua.createIfStatement(condition, ifBlock, elseStatement); + } } else { pushScope(context, ScopeType.Conditional); const elseStatements = performHoisting( diff --git a/src/transformation/visitors/expression-list.ts b/src/transformation/visitors/expression-list.ts new file mode 100644 index 000000000..01213ce4d --- /dev/null +++ b/src/transformation/visitors/expression-list.ts @@ -0,0 +1,192 @@ +import assert = require("assert"); +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext, tempSymbolId } from "../context"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { isConstIdentifier } from "../utils/typescript"; + +function shouldMoveToTemp(context: TransformationContext, expression: lua.Expression, tsOriginal?: ts.Node) { + return ( + !lua.isLiteral(expression) && + !(lua.isIdentifier(expression) && expression.symbolId === tempSymbolId) && // Treat generated temps as consts + !(tsOriginal && isConstIdentifier(context, tsOriginal)) + ); +} + +// Cache an expression in a preceding statement and return the temp identifier +export function moveToPrecedingTemp( + context: TransformationContext, + expression: lua.Expression, + tsOriginal?: ts.Node +): lua.Expression { + if (!shouldMoveToTemp(context, expression, tsOriginal)) { + return expression; + } + const tempIdentifier = context.createTempNameForLuaExpression(expression); + const tempDeclaration = lua.createVariableDeclarationStatement(tempIdentifier, expression, tsOriginal); + context.addPrecedingStatements(tempDeclaration); + return lua.cloneIdentifier(tempIdentifier, tsOriginal); +} + +function transformExpressions( + context: TransformationContext, + expressions: readonly ts.Expression[] +): { + transformedExpressions: lua.Expression[]; + precedingStatements: lua.Statement[][]; + lastPrecedingStatementsIndex: number; +} { + const precedingStatements: lua.Statement[][] = []; + const transformedExpressions: lua.Expression[] = []; + let lastPrecedingStatementsIndex = -1; + for (let i = 0; i < expressions.length; ++i) { + const [expressionPrecedingStatements, expression] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expressions[i]) + ); + transformedExpressions.push(expression); + if (expressionPrecedingStatements.length > 0) { + lastPrecedingStatementsIndex = i; + } + precedingStatements.push(expressionPrecedingStatements); + } + return { transformedExpressions, precedingStatements, lastPrecedingStatementsIndex }; +} + +function transformExpressionsUsingTemps( + context: TransformationContext, + expressions: readonly ts.Expression[], + transformedExpressions: lua.Expression[], + precedingStatements: lua.Statement[][], + lastPrecedingStatementsIndex: number +) { + for (let i = 0; i < transformedExpressions.length; ++i) { + context.addPrecedingStatements(precedingStatements[i]); + if (i < lastPrecedingStatementsIndex) { + transformedExpressions[i] = moveToPrecedingTemp(context, transformedExpressions[i], expressions[i]); + } + } + return transformedExpressions; +} + +function pushToSparseArray( + context: TransformationContext, + arrayIdentifier: lua.Identifier | undefined, + expressions: lua.Expression[] +) { + if (!arrayIdentifier) { + arrayIdentifier = lua.createIdentifier(context.createTempName("array")); + const libCall = transformLuaLibFunction(context, LuaLibFeature.SparseArrayNew, undefined, ...expressions); + const declaration = lua.createVariableDeclarationStatement(arrayIdentifier, libCall); + context.addPrecedingStatements(declaration); + } else { + const libCall = transformLuaLibFunction( + context, + LuaLibFeature.SparseArrayPush, + undefined, + arrayIdentifier, + ...expressions + ); + context.addPrecedingStatements(lua.createExpressionStatement(libCall)); + } + return arrayIdentifier; +} + +function transformExpressionsUsingSparseArray( + context: TransformationContext, + expressions: readonly ts.Expression[], + transformedExpressions: lua.Expression[], + precedingStatements: lua.Statement[][] +) { + let arrayIdentifier: lua.Identifier | undefined; + + let expressionBatch: lua.Expression[] = []; + for (let i = 0; i < expressions.length; ++i) { + // Expressions with preceding statements should always be at the start of a batch + if (precedingStatements[i].length > 0 && expressionBatch.length > 0) { + arrayIdentifier = pushToSparseArray(context, arrayIdentifier, expressionBatch); + expressionBatch = []; + } + + context.addPrecedingStatements(precedingStatements[i]); + expressionBatch.push(transformedExpressions[i]); + + // Spread expressions should always be at the end of a batch + if (ts.isSpreadElement(expressions[i])) { + arrayIdentifier = pushToSparseArray(context, arrayIdentifier, expressionBatch); + expressionBatch = []; + } + } + + if (expressionBatch.length > 0) { + arrayIdentifier = pushToSparseArray(context, arrayIdentifier, expressionBatch); + } + + assert(arrayIdentifier); + return [transformLuaLibFunction(context, LuaLibFeature.SparseArraySpread, undefined, arrayIdentifier)]; +} + +function countNeededTemps( + context: TransformationContext, + expressions: readonly ts.Expression[], + transformedExpressions: lua.Expression[], + lastPrecedingStatementsIndex: number +) { + if (lastPrecedingStatementsIndex < 0) { + return 0; + } + return transformedExpressions + .slice(0, lastPrecedingStatementsIndex) + .filter((e, i) => shouldMoveToTemp(context, e, expressions[i])).length; +} + +// Transforms a list of expressions while flattening spreads and maintaining execution order +export function transformExpressionList( + context: TransformationContext, + expressions: readonly ts.Expression[] +): lua.Expression[] { + const { transformedExpressions, precedingStatements, lastPrecedingStatementsIndex } = transformExpressions( + context, + expressions + ); + + // If more than this number of temps are required to preserve execution order, we'll fall back to using the + // sparse array lib functions instead to prevent excessive locals. + const maxTemps = 2; + + // Use sparse array lib if there are spreads before the last expression + // or if too many temps are needed to preserve order + const lastSpread = expressions.findIndex(e => ts.isSpreadElement(e)); + if ( + (lastSpread >= 0 && lastSpread < expressions.length - 1) || + countNeededTemps(context, expressions, transformedExpressions, lastPrecedingStatementsIndex) > maxTemps + ) { + return transformExpressionsUsingSparseArray(context, expressions, transformedExpressions, precedingStatements); + } else { + return transformExpressionsUsingTemps( + context, + expressions, + transformedExpressions, + precedingStatements, + lastPrecedingStatementsIndex + ); + } +} + +// Transforms a series of expressions while maintaining execution order +export function transformOrderedExpressions( + context: TransformationContext, + expressions: readonly ts.Expression[] +): lua.Expression[] { + const { transformedExpressions, precedingStatements, lastPrecedingStatementsIndex } = transformExpressions( + context, + expressions + ); + return transformExpressionsUsingTemps( + context, + expressions, + transformedExpressions, + precedingStatements, + lastPrecedingStatementsIndex + ); +} diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 166a1b87a..dd749d202 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -8,12 +8,12 @@ import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../u import { ContextType, getFunctionContextType } from "../utils/function-context"; import { createExportsIdentifier, - createImmediatelyInvokedFunctionExpression, createLocalOrExportedOrGlobalDeclaration, createSelfIdentifier, wrapInTable, } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; import { isAsyncFunction, wrapInAsyncAwaiter } from "./async-await"; import { transformIdentifier } from "./identifier"; @@ -53,8 +53,10 @@ function isRestParameterReferenced(identifier: lua.Identifier, scope: Scope): bo export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { - const returnStatement = transformExpressionBodyToReturnStatement(context, body); - return [returnStatement]; + const [precedingStatements, returnStatement] = transformInPrecedingStatementScope(context, () => + transformExpressionBodyToReturnStatement(context, body) + ); + return [...precedingStatements, returnStatement]; } const bodyStatements = performHoisting(context, context.transformStatements(body.statements)); @@ -242,17 +244,13 @@ export function transformFunctionLikeDeclaration( nodes.some(n => context.checker.getSymbolAtLocation(n)?.valueDeclaration === symbol.valueDeclaration) ); - // Only wrap if the name is actually referenced inside the function + // Only handle if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); - // We cannot use transformToImmediatelyInvokedFunctionExpression() here because we need to transpile - // the function first to determine if it's self-referencing. Fortunately, this does not cause issues - // with var-arg optimization because the IIFE is just wrapping another function which will already push - // another scope. - return createImmediatelyInvokedFunctionExpression( - [lua.createVariableDeclarationStatement(nameIdentifier, functionExpression)], - lua.cloneIdentifier(nameIdentifier) + context.addPrecedingStatements( + lua.createVariableDeclarationStatement(nameIdentifier, functionExpression) ); + return lua.cloneIdentifier(nameIdentifier); } } } diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index c0e9a6256..32576a815 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -9,7 +9,7 @@ import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from ".. import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; -import { flattenSpreadExpressions } from "./call"; +import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { findMultiAssignmentViolations } from "./language-extensions/multi"; // TODO: Move to object-literal.ts? @@ -69,15 +69,33 @@ const transformObjectLiteralExpression: FunctionVisitor 0) { + lastPrecedingStatementsIndex = i; + } + + // Transform value and cache preceding statements + context.pushPrecedingStatements(); + if (ts.isPropertyAssignment(element)) { const expression = context.transformExpression(element.initializer); properties.push(lua.createTableFieldExpression(expression, name, element)); + initializers.push(element.initializer); } else if (ts.isShorthandPropertyAssignment(element)) { const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); if (valueSymbol) { @@ -86,18 +104,12 @@ const transformObjectLiteralExpression: FunctionVisitor __TS__ObjectAssign({x = 0}, {y = 2}, {y = 1, z = 2}) - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); - tableExpressions.push(tableExpression); - properties = []; - } - const type = context.checker.getTypeAtLocation(element.expression); let tableExpression: lua.Expression; if (isArrayType(context, type)) { @@ -111,26 +123,74 @@ const transformObjectLiteralExpression: FunctionVisitor 0) { + lastPrecedingStatementsIndex = i; + } + } + + // Expressions referenced before others that produced preceding statements need to be cached in temps + if (lastPrecedingStatementsIndex >= 0) { + for (let i = 0; i < properties.length; ++i) { + const property = properties[i]; + + // Bubble up key's preceding statements + context.addPrecedingStatements(keyPrecedingStatements[i]); + + // Cache computed property name in temp if before the last expression that generated preceding statements + if (i <= lastPrecedingStatementsIndex && lua.isTableFieldExpression(property) && property.key) { + property.key = moveToPrecedingTemp(context, property.key, expression.properties[i].name); + } + + // Bubble up value's preceding statements + context.addPrecedingStatements(valuePrecedingStatements[i]); + + // Cache property value in temp if before the last expression that generated preceding statements + if (i < lastPrecedingStatementsIndex) { + if (lua.isTableFieldExpression(property)) { + property.value = moveToPrecedingTemp(context, property.value, initializers[i]); + } else { + properties[i] = moveToPrecedingTemp(context, property, initializers[i]); + } + } + } + } + + // Sort into field expressions and tables to pass into __TS__ObjectAssign + let fields: lua.TableFieldExpression[] = []; + const tableExpressions: lua.Expression[] = []; + for (const property of properties) { + if (lua.isTableFieldExpression(property)) { + fields.push(property); + } else { + if (fields.length > 0) { + tableExpressions.push(lua.createTableExpression(fields)); + } + tableExpressions.push(property); + fields = []; + } } if (tableExpressions.length === 0) { - return lua.createTableExpression(properties, expression); + return lua.createTableExpression(fields, expression); } else { - if (properties.length > 0) { - const tableExpression = lua.createTableExpression(properties, expression); + if (fields.length > 0) { + const tableExpression = lua.createTableExpression(fields, expression); tableExpressions.push(tableExpression); } if (tableExpressions[0].kind !== lua.SyntaxKind.TableExpression) { tableExpressions.unshift(lua.createTableExpression(undefined, expression)); } - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...tableExpressions); } }; @@ -139,7 +199,7 @@ const transformArrayLiteralExpression: FunctionVisitor ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e ); - const values = flattenSpreadExpressions(context, filteredElements).map(e => lua.createTableFieldExpression(e)); + const values = transformExpressionList(context, filteredElements).map(e => lua.createTableFieldExpression(e)); return lua.createTableExpression(values, expression); }; diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index 0fafc710a..77f172007 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -1,23 +1,68 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; -import { transformLoopBody } from "./utils"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { invertCondition, transformLoopBody } from "./utils"; -export const transformWhileStatement: FunctionVisitor = (statement, context) => - lua.createWhileStatement( - lua.createBlock(transformLoopBody(context, statement)), - context.transformExpression(statement.expression), - statement +export const transformWhileStatement: FunctionVisitor = (statement, context) => { + const body = transformLoopBody(context, statement); + + let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => + context.transformExpression(statement.expression) ); + // If condition has preceding statements, ensure they are executed every iteration by using the form: + // + // while true do + // condition's preceding statements + // if not condition then + // break + // end + // ... + // end + if (conditionPrecedingStatements.length > 0) { + conditionPrecedingStatements.push( + lua.createIfStatement( + invertCondition(condition), + lua.createBlock([lua.createBreakStatement()]), + undefined, + statement.expression + ) + ); + body.unshift(...conditionPrecedingStatements); + condition = lua.createBooleanLiteral(true); + } + + return lua.createWhileStatement(lua.createBlock(body), condition, statement); +}; + export const transformDoStatement: FunctionVisitor = (statement, context) => { const body = lua.createDoStatement(transformLoopBody(context, statement)); - let condition = context.transformExpression(statement.expression); - if (lua.isUnaryExpression(condition) && condition.operator === lua.SyntaxKind.NotOperator) { - condition = condition.operand; - } else { - condition = lua.createUnaryExpression(condition, lua.SyntaxKind.NotOperator); + + let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => + invertCondition(context.transformExpression(statement.expression)) + ); + + // If condition has preceding statements, ensure they are executed every iteration by using the form: + // + // repeat + // ... + // condition's preceding statements + // if condition then + // break + // end + // end + if (conditionPrecedingStatements.length > 0) { + conditionPrecedingStatements.push( + lua.createIfStatement( + condition, + lua.createBlock([lua.createBreakStatement()]), + undefined, + statement.expression + ) + ); + condition = lua.createBooleanLiteral(false); } - return lua.createRepeatStatement(lua.createBlock([body]), condition, statement); + return lua.createRepeatStatement(lua.createBlock([body, ...conditionPrecedingStatements]), condition, statement); }; diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 98864082e..3fbbb6353 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -1,8 +1,9 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { checkVariableDeclarationList, transformVariableDeclaration } from "../variable-declaration"; -import { transformLoopBody } from "./utils"; +import { invertCondition, transformLoopBody } from "./utils"; export const transformForStatement: FunctionVisitor = (statement, context) => { const result: lua.Statement[] = []; @@ -17,19 +18,47 @@ export const transformForStatement: FunctionVisitor = (statemen } } - const condition = statement.condition - ? context.transformExpression(statement.condition) - : lua.createBooleanLiteral(true); - - // Add body const body: lua.Statement[] = transformLoopBody(context, statement); + let condition: lua.Expression; + if (statement.condition) { + let conditionPrecedingStatements: lua.Statement[]; + const tsCondition = statement.condition; + [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => + context.transformExpression(tsCondition) + ); + + // If condition has preceding statements, ensure they are executed every iteration by using the form: + // + // while true do + // condition's preceding statements + // if not condition then + // break + // end + // ... + // end + if (conditionPrecedingStatements.length > 0) { + conditionPrecedingStatements.push( + lua.createIfStatement( + invertCondition(condition), + lua.createBlock([lua.createBreakStatement()]), + undefined, + statement.condition + ) + ); + body.unshift(...conditionPrecedingStatements); + condition = lua.createBooleanLiteral(true); + } + } else { + condition = lua.createBooleanLiteral(true); + } + if (statement.incrementor) { body.push(...context.transformStatements(ts.factory.createExpressionStatement(statement.incrementor))); } // while (condition) do ... end - result.push(lua.createWhileStatement(lua.createBlock(body), condition)); + result.push(lua.createWhileStatement(lua.createBlock(body), condition, statement)); return lua.createDoStatement(result, statement); }; diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index a7402b653..ec3548baa 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -64,10 +64,20 @@ export function transformForInitializer( block.statements.unshift( ...(isAssignmentPattern(initializer) - ? transformAssignmentPattern(context, initializer, valueVariable) + ? transformAssignmentPattern(context, initializer, valueVariable, false) : transformAssignment(context, initializer, valueVariable)) ); } return valueVariable; } + +export function invertCondition(expression: lua.Expression) { + if (lua.isUnaryExpression(expression) && expression.operator === lua.SyntaxKind.NotOperator) { + return expression.operand; + } else { + const notExpression = lua.createUnaryExpression(expression, lua.SyntaxKind.NotOperator); + lua.setNodePosition(notExpression, lua.getOriginalPos(expression)); + return notExpression; + } +} diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 41561c67f..903ec0a11 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -4,6 +4,7 @@ import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; import { createExportsIdentifier } from "../utils/lua-ast"; import { getUsedLuaLibFeatures } from "../utils/lualib"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; @@ -13,7 +14,11 @@ export const transformSourceFileNode: FunctionVisitor = (node, co const [statement] = node.statements; if (statement) { assert(ts.isExpressionStatement(statement)); - statements.push(lua.createReturnStatement([context.transformExpression(statement.expression)])); + const [precedingStatements, expression] = transformInPrecedingStatementScope(context, () => + context.transformExpression(statement.expression) + ); + statements.push(...precedingStatements); + statements.push(lua.createReturnStatement([expression])); } else { const errorCall = lua.createCallExpression(lua.createIdentifier("error"), [ lua.createStringLiteral("Unexpected end of JSON input"), diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index ae01ff10d..e14df3002 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -1,7 +1,9 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { popScope, pushScope, ScopeType, separateHoistedStatements } from "../utils/scope"; +import { createShortCircuitBinaryExpressionPrecedingStatements } from "./binary-expression"; const containsBreakOrReturn = (nodes: Iterable): boolean => { for (const s of nodes) { @@ -17,31 +19,48 @@ const containsBreakOrReturn = (nodes: Iterable): boolean => { return false; }; +const createOrExpression = ( + context: TransformationContext, + left: lua.Expression, + right: lua.Expression, + rightPrecedingStatements: lua.Statement[] +): [lua.Statement[], lua.Expression] => { + if (rightPrecedingStatements.length > 0) { + return createShortCircuitBinaryExpressionPrecedingStatements( + context, + left, + right, + rightPrecedingStatements, + ts.SyntaxKind.BarBarToken + ); + } else { + return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)]; + } +}; + const coalesceCondition = ( condition: lua.Expression | undefined, + conditionPrecedingStatements: lua.Statement[], switchVariable: lua.Identifier, expression: ts.Expression, context: TransformationContext -): lua.Expression => { +): [lua.Statement[], lua.Expression] => { + const [precedingStatements, transformedExpression] = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression) + ); + // Coalesce skipped statements + const comparison = lua.createBinaryExpression( + switchVariable, + transformedExpression, + lua.SyntaxKind.EqualityOperator + ); if (condition) { - return lua.createBinaryExpression( - condition, - lua.createBinaryExpression( - switchVariable, - context.transformExpression(expression), - lua.SyntaxKind.EqualityOperator - ), - lua.SyntaxKind.OrOperator - ); + return createOrExpression(context, condition, comparison, precedingStatements); } // Next condition - return lua.createBinaryExpression( - switchVariable, - context.transformExpression(expression), - lua.SyntaxKind.EqualityOperator - ); + return [[...conditionPrecedingStatements, ...precedingStatements], comparison]; }; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { @@ -76,6 +95,7 @@ export const transformSwitchStatement: FunctionVisitor = (st let defaultTransformed = false; let isInitialCondition = true; let condition: lua.Expression | undefined = undefined; + let conditionPrecedingStatements: lua.Statement[] = []; for (let i = 0; i < clauses.length; i++) { const clause = clauses[i]; const previousClause: ts.CaseOrDefaultClause | undefined = clauses[i - 1]; @@ -88,25 +108,41 @@ export const transformSwitchStatement: FunctionVisitor = (st // Compute the condition for the if statement if (!ts.isDefaultClause(clause)) { - condition = coalesceCondition(condition, switchVariable, clause.expression, context); + [conditionPrecedingStatements, condition] = coalesceCondition( + condition, + conditionPrecedingStatements, + switchVariable, + clause.expression, + context + ); // Skip empty clauses unless final clause (i.e side-effects) if (i !== clauses.length - 1 && clause.statements.length === 0) continue; // Declare or assign condition variable - statements.push( - isInitialCondition - ? lua.createVariableDeclarationStatement(conditionVariable, condition) - : lua.createAssignmentStatement( - conditionVariable, - lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator) - ) - ); + if (isInitialCondition) { + statements.push( + ...conditionPrecedingStatements, + lua.createVariableDeclarationStatement(conditionVariable, condition) + ); + } else { + [conditionPrecedingStatements, condition] = createOrExpression( + context, + conditionVariable, + condition, + conditionPrecedingStatements + ); + statements.push( + ...conditionPrecedingStatements, + lua.createAssignmentStatement(conditionVariable, condition) + ); + } isInitialCondition = false; } else { // If the default is proceeded by empty clauses and will be emitted we may need to initialize the condition if (isInitialCondition) { statements.push( + ...conditionPrecedingStatements, lua.createVariableDeclarationStatement( conditionVariable, condition ?? lua.createBooleanLiteral(false) @@ -115,6 +151,7 @@ export const transformSwitchStatement: FunctionVisitor = (st // Clear condition ot ensure it is not evaluated twice condition = undefined; + conditionPrecedingStatements = []; isInitialCondition = false; } @@ -122,11 +159,15 @@ export const transformSwitchStatement: FunctionVisitor = (st if (i === clauses.length - 1) { // Evaluate the final condition that we may be skipping if (condition) { + [conditionPrecedingStatements, condition] = createOrExpression( + context, + conditionVariable, + condition, + conditionPrecedingStatements + ); statements.push( - lua.createAssignmentStatement( - conditionVariable, - lua.createBinaryExpression(conditionVariable, condition, lua.SyntaxKind.OrOperator) - ) + ...conditionPrecedingStatements, + lua.createAssignmentStatement(conditionVariable, condition) ); } continue; @@ -155,6 +196,7 @@ export const transformSwitchStatement: FunctionVisitor = (st // Clear condition for next clause condition = undefined; + conditionPrecedingStatements = []; } // If no conditions above match, we need to create the final default case code-path, diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 9f9a19b33..5f949adb1 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -5,6 +5,7 @@ import { ContextType, getDeclarationContextType } from "../utils/function-contex import { wrapInToStringForConcat } from "../utils/lua-ast"; import { isStringType } from "../utils/typescript/types"; import { transformArguments, transformContextualCallExpression } from "./call"; +import { transformOrderedExpressions } from "./expression-list"; // TODO: Source positions function getRawLiteral(node: ts.LiteralLikeNode): string { @@ -24,8 +25,13 @@ export const transformTemplateExpression: FunctionVisitor parts.push(lua.createStringLiteral(head, node.head)); } - for (const span of node.templateSpans) { - const expression = context.transformExpression(span.expression); + const transformedExpressions = transformOrderedExpressions( + context, + node.templateSpans.map(s => s.expression) + ); + for (let i = 0; i < node.templateSpans.length; ++i) { + const span = node.templateSpans[i]; + const expression = transformedExpressions[i]; const spanType = context.checker.getTypeAtLocation(span.expression); if (isStringType(context, spanType)) { parts.push(expression); diff --git a/src/transformation/visitors/typeof.ts b/src/transformation/visitors/typeof.ts index 60eef310c..aaa094491 100644 --- a/src/transformation/visitors/typeof.ts +++ b/src/transformation/visitors/typeof.ts @@ -47,5 +47,14 @@ export function transformTypeOfBinaryExpression( const innerExpression = context.transformExpression(typeOfExpression.expression); const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression); - return transformBinaryOperation(context, typeCall, comparedExpression, operator, node); + const [precedingStatements, result] = transformBinaryOperation( + context, + typeCall, + comparedExpression, + [], + operator, + node + ); + context.addPrecedingStatements(precedingStatements); + return result; } diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 4782fd157..2c5588dd8 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -7,6 +7,7 @@ import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; @@ -63,7 +64,11 @@ export function transformBindingPattern( // The identifier of the new variable const variableName = transformIdentifier(context, element.name); // The field to extract - const propertyName = transformPropertyName(context, element.propertyName ?? element.name); + const elementName = element.propertyName ?? element.name; + const [precedingStatements, propertyName] = transformInPrecedingStatementScope(context, () => + transformPropertyName(context, elementName) + ); + result.push(...precedingStatements); // Keep property's preceding statements in order let expression: lua.Expression; if (element.dotDotDotToken) { @@ -123,11 +128,16 @@ export function transformBindingPattern( result.push(...createLocalOrExportedOrGlobalDeclaration(context, variableName, expression)); if (element.initializer) { const identifier = addExportToIdentifier(context, variableName); + const tsInitializer = element.initializer; + const [initializerPrecedingStatements, initializer] = transformInPrecedingStatementScope(context, () => + context.transformExpression(tsInitializer) + ); result.push( lua.createIfStatement( lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), lua.createBlock([ - lua.createAssignmentStatement(identifier, context.transformExpression(element.initializer)), + ...initializerPrecedingStatements, + lua.createAssignmentStatement(identifier, initializer), ]) ) ); @@ -155,13 +165,15 @@ export function transformBindingVariableDeclaration( table = transformIdentifier(context, initializer); } else { // Contain the expression in a temporary variable - table = lua.createAnonymousIdentifier(); if (initializer) { + table = context.createTempNameForNode(initializer); let expression = context.transformExpression(initializer); if (isMultiReturnCall(context, initializer)) { expression = wrapInTable(expression); } statements.push(lua.createVariableDeclarationStatement(table, expression)); + } else { + table = lua.createAnonymousIdentifier(); } } statements.push(...transformBindingPattern(context, bindingPattern, table)); diff --git a/src/transformation/visitors/void.ts b/src/transformation/visitors/void.ts index 569198a93..9d6af960b 100644 --- a/src/transformation/visitors/void.ts +++ b/src/transformation/visitors/void.ts @@ -2,26 +2,21 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { FunctionVisitor } from "../context/visitors"; -import { createImmediatelyInvokedFunctionExpression } from "../utils/lua-ast"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void export const transformVoidExpression: FunctionVisitor = (node, context) => { // If content is a literal it is safe to replace the entire expression with nil - if (ts.isLiteralExpression(node.expression)) { - return lua.createNilLiteral(node); - } - - // (function() local ____ = end)() - return createImmediatelyInvokedFunctionExpression( - [ + if (!ts.isLiteralExpression(node.expression)) { + // local ____ = + context.addPrecedingStatements( lua.createVariableDeclarationStatement( lua.createAnonymousIdentifier(), context.transformExpression(node.expression) - ), - ], - [], - node - ); + ) + ); + } + + return lua.createNilLiteral(node); }; export const transformVoidExpressionStatement = (node: ts.VoidExpression, context: TransformationContext) => diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index fb4594742..9671f656c 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -4,8 +4,8 @@ exports[`Transformation (blockScopeVariables) 1`] = ` "do local a = 1 local b = 1 - local ____ = {c = 1} - local c = ____.c + local ____temp_0 = {c = 1} + local c = ____temp_0.c end" `; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index cfd0e53cb..91bc2306b 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -46,10 +46,8 @@ exports[`Bitop [5.1] ("~a"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitw exports[`Bitop [5.1] ("a&=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.band(a, b) - return a -end)() +a = bit.band(a, b) +____exports.__result = a return ____exports" `; @@ -65,10 +63,8 @@ exports[`Bitop [5.1] ("a&b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bit exports[`Bitop [5.1] ("a<<=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.lshift(a, b) - return a -end)() +a = bit.lshift(a, b) +____exports.__result = a return ____exports" `; @@ -84,10 +80,8 @@ exports[`Bitop [5.1] ("a<>=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.arshift(a, b) - return a -end)() +a = bit.arshift(a, b) +____exports.__result = a return ____exports" `; @@ -95,10 +89,8 @@ exports[`Bitop [5.1] ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: B exports[`Bitop [5.1] ("a>>>=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.rshift(a, b) - return a -end)() +a = bit.rshift(a, b) +____exports.__result = a return ____exports" `; @@ -122,10 +114,8 @@ exports[`Bitop [5.1] ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bi exports[`Bitop [5.1] ("a^=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.bxor(a, b) - return a -end)() +a = bit.bxor(a, b) +____exports.__result = a return ____exports" `; @@ -141,10 +131,8 @@ exports[`Bitop [5.1] ("a^b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bit exports[`Bitop [5.1] ("a|=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.bor(a, b) - return a -end)() +a = bit.bor(a, b) +____exports.__result = a return ____exports" `; @@ -166,10 +154,8 @@ return ____exports" exports[`Bitop [5.2] ("a&=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.band(a, b) - return a -end)() +a = bit32.band(a, b) +____exports.__result = a return ____exports" `; @@ -181,10 +167,8 @@ return ____exports" exports[`Bitop [5.2] ("a<<=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.lshift(a, b) - return a -end)() +a = bit32.lshift(a, b) +____exports.__result = a return ____exports" `; @@ -196,19 +180,15 @@ return ____exports" exports[`Bitop [5.2] ("a>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.arshift(a, b) - return a -end)() +a = bit32.arshift(a, b) +____exports.__result = a return ____exports" `; exports[`Bitop [5.2] ("a>>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.rshift(a, b) - return a -end)() +a = bit32.rshift(a, b) +____exports.__result = a return ____exports" `; @@ -226,10 +206,8 @@ return ____exports" exports[`Bitop [5.2] ("a^=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.bxor(a, b) - return a -end)() +a = bit32.bxor(a, b) +____exports.__result = a return ____exports" `; @@ -241,10 +219,8 @@ return ____exports" exports[`Bitop [5.2] ("a|=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit32.bor(a, b) - return a -end)() +a = bit32.bor(a, b) +____exports.__result = a return ____exports" `; @@ -262,10 +238,8 @@ return ____exports" exports[`Bitop [5.3] ("a&=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a & b - return a -end)() +a = a & b +____exports.__result = a return ____exports" `; @@ -277,10 +251,8 @@ return ____exports" exports[`Bitop [5.3] ("a<<=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a << b - return a -end)() +a = a << b +____exports.__result = a return ____exports" `; @@ -292,10 +264,8 @@ return ____exports" exports[`Bitop [5.3] ("a>>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a >> b - return a -end)() +a = a >> b +____exports.__result = a return ____exports" `; @@ -307,10 +277,8 @@ return ____exports" exports[`Bitop [5.3] ("a^=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a ~ b - return a -end)() +a = a ~ b +____exports.__result = a return ____exports" `; @@ -322,10 +290,8 @@ return ____exports" exports[`Bitop [5.3] ("a|=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a | b - return a -end)() +a = a | b +____exports.__result = a return ____exports" `; @@ -343,10 +309,8 @@ return ____exports" exports[`Bitop [5.4] ("a&=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a & b - return a -end)() +a = a & b +____exports.__result = a return ____exports" `; @@ -358,10 +322,8 @@ return ____exports" exports[`Bitop [5.4] ("a<<=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a << b - return a -end)() +a = a << b +____exports.__result = a return ____exports" `; @@ -373,10 +335,8 @@ return ____exports" exports[`Bitop [5.4] ("a>>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a >> b - return a -end)() +a = a >> b +____exports.__result = a return ____exports" `; @@ -388,10 +348,8 @@ return ____exports" exports[`Bitop [5.4] ("a^=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a ~ b - return a -end)() +a = a ~ b +____exports.__result = a return ____exports" `; @@ -403,10 +361,8 @@ return ____exports" exports[`Bitop [5.4] ("a|=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a | b - return a -end)() +a = a | b +____exports.__result = a return ____exports" `; @@ -424,10 +380,8 @@ return ____exports" exports[`Bitop [JIT] ("a&=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.band(a, b) - return a -end)() +a = bit.band(a, b) +____exports.__result = a return ____exports" `; @@ -439,10 +393,8 @@ return ____exports" exports[`Bitop [JIT] ("a<<=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.lshift(a, b) - return a -end)() +a = bit.lshift(a, b) +____exports.__result = a return ____exports" `; @@ -454,19 +406,15 @@ return ____exports" exports[`Bitop [JIT] ("a>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.arshift(a, b) - return a -end)() +a = bit.arshift(a, b) +____exports.__result = a return ____exports" `; exports[`Bitop [JIT] ("a>>>=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.rshift(a, b) - return a -end)() +a = bit.rshift(a, b) +____exports.__result = a return ____exports" `; @@ -484,10 +432,8 @@ return ____exports" exports[`Bitop [JIT] ("a^=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.bxor(a, b) - return a -end)() +a = bit.bxor(a, b) +____exports.__result = a return ____exports" `; @@ -499,10 +445,8 @@ return ____exports" exports[`Bitop [JIT] ("a|=b") 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = bit.bor(a, b) - return a -end)() +a = bit.bor(a, b) +____exports.__result = a return ____exports" `; @@ -618,10 +562,8 @@ return ____exports" exports[`Unsupported bitop 5.3 ("a>>=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a >> b - return a -end)() +a = a >> b +____exports.__result = a return ____exports" `; @@ -637,10 +579,8 @@ exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): erro exports[`Unsupported bitop 5.4 ("a>>=b"): code 1`] = ` "local ____exports = {} -____exports.__result = (function() - a = a >> b - return a -end)() +a = a >> b +____exports.__result = a return ____exports" `; diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 6dacea3ad..a962a4a30 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -65,11 +65,11 @@ function ____exports.__main(self) local arr = {\\"a\\", \\"b\\", \\"c\\"} local function luaIter(self) local i = 0 - return function() return arr[(function() - local ____tmp = i - i = ____tmp + 1 - return ____tmp - end)() + 1] end + return function() + local ____i_0 = i + i = ____i_0 + 1 + return arr[____i_0 + 1] + end end local result = \\"\\" return result diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap index a900582b5..6336a53a3 100644 --- a/test/unit/classes/__snapshots__/classes.spec.ts.snap +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -2,9 +2,9 @@ exports[`missing declaration name: code 1`] = ` "require(\\"lualib_bundle\\"); -____ = __TS__Class() -____.name = \\"\\" -function ____.prototype.____constructor(self) +____class_0 = __TS__Class() +____class_0.name = \\"\\" +function ____class_0.prototype.____constructor(self) end" `; diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap index 1f76110a4..d866c5e31 100644 --- a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -7,11 +7,9 @@ function ____exports.__main(self) local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} local i = 0 return function() - local strs = strsArray[(function() - local ____tmp = i - i = ____tmp + 1 - return ____tmp - end)() + 1] + local ____i_0 = i + i = ____i_0 + 1 + local strs = strsArray[____i_0 + 1] if strs then return table.unpack(strs) end @@ -32,11 +30,9 @@ function ____exports.__main(self) local strsArray = {{\\"a1\\", \\"a2\\"}, {\\"b1\\", \\"b2\\"}, {\\"c1\\", \\"c2\\"}} local i = 0 return function() - local strs = strsArray[(function() - local ____tmp = i - i = ____tmp + 1 - return ____tmp - end)() + 1] + local ____i_0 = i + i = ____i_0 + 1 + local strs = strsArray[____i_0 + 1] if strs then return table.unpack(strs) end diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index f9911b514..6bd3922eb 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -61,7 +61,7 @@ end" exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const {} = $multi();): code 1`] = `"local ____ = {{____(_G)}}"`; +exports[`invalid $multi call (const {} = $multi();): code 1`] = `"local _____24multi_result_0 = {{____(_G)}}"`; exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; @@ -166,8 +166,8 @@ local function multi(self, ...) return ... end local a -local ____ = {____(nil)} -a = ____[1] +local ____temp_0 = {____(nil)} +a = ____temp_0[1] ____exports.a = a ____exports.a = a return ____exports" @@ -182,8 +182,8 @@ local function multi(self, ...) end local a do - local ____ = {____(nil, 1, 2)} - a = ____[1] + local ____temp_0 = {____(nil, 1, 2)} + a = ____temp_0[1] ____exports.a = a while false do local ____ = 1 @@ -219,12 +219,10 @@ local function multi(self, ...) return ... end local a -if (function() - local ____ = {____(nil, 1)} - a = ____[1] - ____exports.a = a - return ____ -end)() then +local _____24multi_result_0 = {____(nil, 1)} +a = _____24multi_result_0[1] +____exports.a = a +if _____24multi_result_0 then a = a + 1 ____exports.a = a end diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 7a3387f5e..211b69e6b 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -47,79 +47,61 @@ return ____exports" exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` -"foo = {(function() - ({}).foo = nil - return nil -end)()}" +"({}).foo = nil +foo = {nil}" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` -"foo = tostring((function() - ({}).foo = nil - return nil -end)())" +"({}).foo = nil +foo = tostring(nil)" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): code 1`] = ` -"foo = (function() - ({}).foo = nil - return nil -end)()" +"({}).foo = nil +foo = nil" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): code 1`] = ` -"foo( - _G, - (function() - ({}).foo = nil - return nil - end)() -)" +"local ____foo_1 = foo +local ____G_0 = _G; +({}).foo = nil +____foo_1(____G_0, nil)" `; exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` -"foo = {(function() - ({}).foo = 3 - return nil -end)()}" +"({}).foo = 3 +foo = {nil}" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` -"foo = tostring((function() - ({}).foo = 3 - return nil -end)())" +"({}).foo = 3 +foo = tostring(nil)" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): code 1`] = ` -"foo = (function() - ({}).foo = 3 - return nil -end)()" +"({}).foo = 3 +foo = nil" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): code 1`] = ` -"foo( - _G, - (function() - ({}).foo = 3 - return nil - end)() -)" +"local ____foo_1 = foo +local ____G_0 = _G; +({}).foo = 3 +____foo_1(____G_0, nil)" `; exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts new file mode 100644 index 000000000..6ff6b4706 --- /dev/null +++ b/test/unit/precedingStatements.spec.ts @@ -0,0 +1,625 @@ +import * as util from "../util"; + +const shortCircuitTests: Array<{ operator: string; testValue: unknown }> = [ + { operator: "&&", testValue: true }, + { operator: "&&", testValue: false }, + { operator: "&&", testValue: null }, + { operator: "&&=", testValue: true }, + { operator: "&&=", testValue: false }, + { operator: "&&=", testValue: null }, + { operator: "||", testValue: true }, + { operator: "||", testValue: false }, + { operator: "||", testValue: null }, + { operator: "||=", testValue: true }, + { operator: "||=", testValue: false }, + { operator: "||=", testValue: null }, + { operator: "??", testValue: true }, + { operator: "??", testValue: false }, + { operator: "??", testValue: null }, + { operator: "??=", testValue: true }, + { operator: "??=", testValue: false }, + { operator: "??=", testValue: null }, +]; + +test.each(shortCircuitTests)("short circuit operator (%p)", ({ operator, testValue }) => { + util.testFunction` + let x: unknown = ${testValue}; + let y = 1; + const z = x ${operator} y++; + return {x, y, z}; + `.expectToMatchJsResult(); +}); + +test.each(shortCircuitTests)("short circuit operator on property (%p)", ({ operator, testValue }) => { + util.testFunction` + let x: { foo: unknown } = { foo: ${testValue} }; + let y = 1; + const z = x.foo ${operator} y++; + return {x: x.foo, y, z}; + `.expectToMatchJsResult(); +}); + +test.each([true, false])("ternary operator (%p)", condition => { + util.testFunction` + let a = 0, b = 0; + let condition: boolean = ${condition}; + const c = condition ? a++ : b++; + return [a, b, c]; + `.expectToMatchJsResult(); +}); + +describe("execution order", () => { + const sequenceTests = [ + "i++, i", + "i, i++, i, i++", + "...a", + "i, ...a", + "...a, i", + "i, ...a, i++, i, ...a", + "i, ...a, i++, i, ...a, i", + "...[1, i++, 2]", + "...[1, i++, 2], i++", + "i, ...[1, i++, 2]", + "i, ...[1, i++, 2], i", + "i, ...[1, i++, 2], i++", + "i, ...[1, i++, 2], i++, ...[3, i++, 4]", + "i, ...a, i++, ...[1, i++, 2], i, i++, ...a", + "i, inc(), i++", + "i, ...[1, i++, inc(), 2], i++", + "i, ...'foo', i++", + "i, ...([1, i++, 2] as any), i++", + ]; + + test.each(sequenceTests)("array literal ([%p])", sequence => { + util.testFunction` + const a = [7, 8, 9]; + let i = 0; + function inc() { ++i; return i; } + return [${sequence}]; + `.expectToMatchJsResult(); + }); + + test.each(sequenceTests)("function arguments (foo(%p))", sequence => { + util.testFunction` + const a = [7, 8, 9]; + let i = 0; + function inc() { ++i; return i; } + function foo(...args: unknown[]) { return args; } + return foo(${sequence}); + `.expectToMatchJsResult(); + }); + + test.each([ + "{a: i, b: i++}", + "{a: i, b: i++, c: i}", + "{a: i, ...{b: i++}, c: i}", + "{a: i, ...o, b: i++}", + "{a: i, ...[i], b: i++}", + "{a: i, ...[i++], b: i++}", + "{a: i, ...o, b: i++, ...[i], ...{c: i++}, d: i++}", + ])("object literal (%p)", literal => { + util.testFunction` + const o = {a: "A", b: "B", c: "C"}; + let i = 0; + const literal = ${literal}; + const result: Record = {}; + (Object.keys(result) as Array).forEach( + key => { result[key.toString()] = literal[key]; } + ); + return result; + `.expectToMatchJsResult(); + }); + + test("object literal with computed property names", () => { + util.testFunction` + let i = "A"; + const o = {[i += "B"]: i += "C", [i += "D"]: i += "E"}; + return [i, o]; + `.expectToMatchJsResult(); + }); + + test("comma operator", () => { + util.testFunction` + let a = 0, b = 0, c = 0; + const d = (a++, b += a, c += b); + return [a, b, c, d]; + `.expectToMatchJsResult(); + }); + + test("template expression", () => { + util.testFunction` + let i = 0; + return \`\${i}, \${i++}, \${i}\`; + `.expectToMatchJsResult(); + }); + + test("tagged template literal", () => { + util.testFunction` + let i = 0; + + function func(strings: TemplateStringsArray, ...expressions: any[]) { + const x = i > 0 ? "a" : "b"; + return { strings: [x, ...strings], raw: strings.raw, expressions }; + } + + return func\`hello \${i} \${i++}\`; + `.expectToMatchJsResult(); + }); + + test("binary operators", () => { + util.testFunction` + let i = 0; + return i + i++; + `.expectToMatchJsResult(); + }); + + test("index expression", () => { + util.testFunction` + let i = 0; + const a = [["A1", "A2"], ["B1", "B2"]]; + const result = a[i][i++]; + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("void expression", () => { + util.testFunction` + function foo(x: number, y: number, z: number | undefined) { + return z; + } + let i = 0; + const result = foo(i, i++, void(i++)); + return {result, i}; + `.expectToMatchJsResult(); + }); +}); + +describe("assignment execution order", () => { + test("index assignment statement", () => { + util.testFunction` + let i = 0; + const a = [4, 5]; + a[i] = i++; + return [a, i]; + `.expectToMatchJsResult(); + }); + + test("index assignment expression", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + const result = a[i] = i++; + return [result, a, i]; + `.expectToMatchJsResult(); + }); + + test("indirect index assignment statement", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + const b = [7, 6]; + function foo(x: number) { return (x > 0) ? b : a; } + foo(i)[i] = i++; + return [a, b, i]; + `.expectToMatchJsResult(); + }); + + test("indirect index assignment expression", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + const b = [7, 6]; + function foo(x: number) { return (x > 0) ? b : a; } + const result = foo(i)[i] = i++; + return [result, a, b, i]; + `.expectToMatchJsResult(); + }); + + test("indirect property assignment statement", () => { + util.testFunction` + const a = {value: 10}; + const b = {value: 11}; + let i = 0; + function foo(x: number) { return (x > 0) ? b : a; } + foo(i).value = i++; + return [a, b, i]; + `.expectToMatchJsResult(); + }); + + test("indirect property assignment expression", () => { + util.testFunction` + const a = {value: 10}; + const b = {value: 11}; + let i = 0; + function foo(x: number) { return (x > 0) ? b : a; } + const result = foo(i).value = i++; + return [result, a, b, i]; + `.expectToMatchJsResult(); + }); + + test("compound index assignment statement", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + a[i] += i++; + return [a, i]; + `.expectToMatchJsResult(); + }); + + test("compound index assignment expression", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + const result = a[i] += i++; + return [result, a, i]; + `.expectToMatchJsResult(); + }); + + test("compound indirect index assignment statement", () => { + util.testFunction` + let i = 0; + const a = [9, 8]; + const b = [7, 6]; + function foo(x: number) { return (x > 0) ? b : a; } + foo(i)[i] += i++; + return [a, b, i]; + `.expectToMatchJsResult(); + }); + + test("compound indirect index assignment expression", () => { + util.testFunction` + let i = 1; + const a = [9, 8]; + const b = [7, 6]; + function foo(x: number) { return (x > 0) ? b : a; } + const result = foo(i)[i] += i++; + return [result, a, b, i]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment statement", () => { + util.testFunction` + const a = [10, 9, 8, 7, 6, 5]; + let i = 0; + [a[i], a[i++]] = [i++, i++]; + return [a, i]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment expression", () => { + util.testFunction` + const a = [10, 9, 8, 7, 6, 5]; + let i = 0; + const result = [a[i], a[i++]] = [i++, i++]; + return [a, i, result]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment statement with default", () => { + util.testFunction` + const a = [10, 9, 8, 7, 6, 5]; + let i = 0; + [a[i] = i++, a[i++]] = [i++, i++]; + return [a, i]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment expression with default", () => { + util.testFunction` + const a = [10, 9, 8, 7, 6, 5]; + let i = 0; + const result = [a[i] = i++, a[i++]] = [i++, i++]; + return [a, i, result]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment statement with spread", () => { + util.testFunction` + let i = 0; + let a: number[][] = [[9, 9, 9], [9, 9, 9], [9, 9, 9]]; + [a[0][i], ...a[i++]] = [i++, i++]; + return [a, i]; + `.expectToMatchJsResult(); + }); + + test("array destructuring assignment expression with spread", () => { + util.testFunction` + let i = 0; + let a: number[][] = [[9, 9, 9], [9, 9, 9], [9, 9, 9]]; + const result = [a[0][i], ...a[i++]] = [i++, i++]; + return [a, i, result]; + `.expectToMatchJsResult(); + }); + + test("object destructuring assignment statement", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDEFG: "success", result: ""}; + function c(x: string) { s = x + "C"; return o; } + function g(x: string) { s = x + "G"; return o; } + function e(x: string) { s = x + "E"; return s; } + ({ [e(s += "D")]: g(s += "F").result } = c(s += "B")); + return [s, o]; + `.expectToMatchJsResult(); + }); + + test("object destructuring assignment statement with default", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDEFGHIJ: "success", result: ""}; + function c(x: string) { s = x + "C"; return o; } + function g(x: string) { s = x + "G"; return o; } + function i(x: string) { s = x + "I"; return o; } + function e(x: string): any { s = x + "E"; return undefined; } + ({ [e(s += "D")]: g(s += "F").result = i(s += "H")[s += "J"] } = c(s += "B")); + return [o, s]; + `.expectToMatchJsResult(); + }); + + test("object destructuring assignment expression", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDEFG: "success", result: ""}; + function c(x: string) { s = x + "C"; return o; } + function g(x: string) { s = x + "G"; return o; } + function e(x: string) { s = x + "E"; return s; } + const result = ({ [e(s += "D")]: g(s += "F").result } = c(s += "B")); + return [s, o, result]; + `.expectToMatchJsResult(); + }); + + test("object destructuring assignment expression with default", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDEFGHIJ: "success", result: ""}; + function c(x: string) { s = x + "C"; return o; } + function g(x: string) { s = x + "G"; return o; } + function i(x: string) { s = x + "I"; return o; } + function e(x: string): any { s = x + "E"; return undefined; } + const result = ({ [e(s += "D")]: g(s += "F").result = i(s += "H")[s += "J"] } = c(s += "B")); + return [o, s, result]; + `.expectToMatchJsResult(); + }); + + test("object destructuring declaration", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDE: "success"}; + function c(x: string) { s = x + "C"; return o; } + function e(x: string) { s = x + "E"; return s; } + const { [e(s += "D")]: result } = c(s += "B"); + return [result, s]; + `.expectToMatchJsResult(); + }); + + test("object destructuring declaration with default", () => { + util.testFunction` + let s = "A"; + const o: Record = {ABCDEFGH: "success"}; + function c(x: string) { s = x + "C"; return o; } + function g(x: string) { s = x + "G"; return o; } + function e(x: string): any { s = x + "E"; return undefined; } + const { [e(s += "D")]: result = g(s += "F")[s += "H"]} = c(s += "B"); + return [result, s]; + `.expectToMatchJsResult(); + }); + + test("call expression", () => { + util.testFunction` + let i = 1; + function a(x: number) { return x * 10; } + function b(x: number) { return x * 100; } + function foo(x: number) { return (x > 0) ? b : a; } + const result = foo(i)(i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("call expression (function modified)", () => { + util.testFunction` + let i = 1; + let foo = (x: null, y: number) => { return y; }; + function changeFoo() { + foo = (x: null, y: number) => { return y * 10; }; + return null; + } + const result = foo(changeFoo(), i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("method call expression (method modified)", () => { + util.testFunction` + let i = 1; + let o = { + val: 3, + foo(x: null, y: number) { return y + this.val; } + }; + function changeFoo(this: void) { + o.foo = function(x: null, y: number) { return (y + this.val) * 10; }; + return null; + } + const result = o.foo(changeFoo(), i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("method element access call expression (method modified)", () => { + util.testFunction` + let i = 1; + let o = { + val: 3, + foo(x: null, y: number) { return y + this.val; } + }; + function changeFoo(this: void) { + o.foo = function(x: null, y: number) { return (y + this.val) * 10; }; + return null; + } + function getFoo() { return "foo" as const; } + function getO() { return o; } + const result = getO()[getFoo()](changeFoo(), i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("method call expression (object modified)", () => { + util.testFunction` + let i = 1; + let o = { + val: 3, + foo(x: null, y: number) { return y + this.val; } + }; + function changeO(this: void) { + o = { + val: 5, + foo: function(x: null, y: number) { return (y + this.val) * 10; } + }; + return null; + } + const result = o.foo(changeO(), i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("method element access call expression (object modified)", () => { + util.testFunction` + let i = 1; + let o = { + val: 3, + foo(x: null, y: number) { return y + this.val; } + }; + function changeO(this: void) { + o = { + val: 5, + foo: function(x: null, y: number) { return (y + this.val) * 10; } + }; + return null; + } + function getFoo() { return "foo" as const; } + function getO() { return o; } + const result = getO()[getFoo()](changeO(), i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("array method call", () => { + util.testFunction` + let a = [7]; + let b = [9]; + function foo(x: number) { return (x > 0) ? b : a; } + let i = 0; + foo(i).push(i, i++, i); + return [a, b, i]; + `.expectToMatchJsResult(); + }); + + test("function method call", () => { + util.testFunction` + let o = {val: 3}; + let a = function(x: number) { return this.val + x; }; + let b = function(x: number) { return (this.val + x) * 10; }; + function foo(x: number) { return (x > 0) ? b : a; } + let i = 0; + const result = foo(i).call(o, i++); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("string method call", () => { + util.testFunction` + function foo(x: number) { return (x > 0) ? "foo" : "bar"; } + let i = 0; + const result = foo(i).substr(++i); + return [result, i]; + `.expectToMatchJsResult(); + }); + + test("new call", () => { + util.testFunction` + class A { public val = 3; constructor(x: number) { this.val += x; } }; + class B { public val = 5; constructor(x: number) { this.val += (x * 10); } }; + function foo(x: number) { return (x > 0) ? B : A; } + let i = 0; + const result = new (foo(i))(i++).val; + return [result, i]; + `.expectToMatchJsResult(); + }); +}); + +describe("loop expressions", () => { + test("while loop", () => { + util.testFunction` + let i = 0, j = 0; + while (i++ < 5) { + ++j; + if (j >= 10) { + break; + } + } + return [i, j]; + `.expectToMatchJsResult(); + }); + + test("for loop", () => { + util.testFunction` + let j = 0; + for (let i = 0; i++ < 5;) { + ++j; + if (j >= 10) { + break; + } + } + return j; + `.expectToMatchJsResult(); + }); + + test("do while loop", () => { + util.testFunction` + let i = 0, j = 0; + do { + ++j; + if (j >= 10) { + break; + } + } while (i++ < 5); + return [i, j]; + `.expectToMatchJsResult(); + }); + + test("do while loop scoping", () => { + util.testFunction` + let x = 0; + let result = 0; + do { + let x = -10; + ++result; + } while (x++ >= 0 && result < 2); + return result; + `.expectToMatchJsResult(); + }); +}); + +test("switch", () => { + util.testFunction` + let i = 0; + let x = 0; + let result = ""; + switch (x) { + case i++: + result = "test"; + break; + case i++: + } + return [i, result]; + `.expectToMatchJsResult(); +}); + +test("else if", () => { + util.testFunction` + let i = 0; + if (i++ === 0) { + } else if (i++ === 1) { + } + return i; + `.expectToMatchJsResult(); +}); From f624a6e50329777a9521e85ebde3378554dd3d35 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 21 Nov 2021 14:13:54 +0100 Subject: [PATCH 422/764] Update TS to 4.5.x (#1169) --- package-lock.json | 389 ++++++++++++++++-- package.json | 8 +- src/transformation/visitors/modules/export.ts | 2 +- 3 files changed, 350 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3d3b5f40..5e9167c3b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,8 +22,8 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^4.31.0", - "@typescript-eslint/parser": "^4.31.0", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", "eslint": "^7.32.0", "eslint-plugin-import": "^2.24.2", "eslint-plugin-jest": "^24.4.0", @@ -36,13 +36,13 @@ "prettier": "^2.3.2", "ts-jest": "^27.0.7", "ts-node": "^10.3.0", - "typescript": "~4.4.4" + "typescript": "~4.5.2" }, "engines": { "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.4.4" + "typescript": "~4.5.2" } }, "node_modules/@babel/code-frame": { @@ -1382,30 +1382,30 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", + "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", + "@typescript-eslint/experimental-utils": "5.4.0", + "@typescript-eslint/scope-manager": "5.4.0", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", - "regexpp": "^3.1.0", + "regexpp": "^3.2.0", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1413,6 +1413,113 @@ } } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", + "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/typescript-estree": "5.4.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", + "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", + "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", + "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", + "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@typescript-eslint/experimental-utils": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", @@ -1438,25 +1545,82 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", + "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" + "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/typescript-estree": "5.4.0", + "debug": "^4.3.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", + "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", + "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", + "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" }, "peerDependenciesMeta": { "typescript": { @@ -1464,6 +1628,32 @@ } } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", + "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.4.0", + "eslint-visitor-keys": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", @@ -6440,11 +6630,10 @@ } }, "node_modules/typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -7847,19 +8036,82 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", + "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", + "@typescript-eslint/experimental-utils": "5.4.0", + "@typescript-eslint/scope-manager": "5.4.0", + "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", - "regexpp": "^3.1.0", + "regexpp": "^3.2.0", "semver": "^7.3.5", "tsutils": "^3.21.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", + "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/typescript-estree": "5.4.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", + "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0" + } + }, + "@typescript-eslint/types": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", + "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", + "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", + "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + } } }, "@typescript-eslint/experimental-utils": { @@ -7877,15 +8129,64 @@ } }, "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", + "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" + "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/typescript-estree": "5.4.0", + "debug": "^4.3.2" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", + "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0" + } + }, + "@typescript-eslint/types": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", + "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", + "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/visitor-keys": "5.4.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", + "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.4.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "eslint-visitor-keys": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", + "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "dev": true + } } }, "@typescript-eslint/scope-manager": { @@ -11615,9 +11916,9 @@ } }, "typescript": { - "version": "4.4.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", - "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", + "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", "dev": true }, "typescript-to-lua": { diff --git a/package.json b/package.json index 1b47be298..432768356 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.4.4" + "typescript": "~4.5.2" }, "dependencies": { "enhanced-resolve": "^5.8.2", @@ -55,8 +55,8 @@ "@types/jest": "^25.1.3", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^4.31.0", - "@typescript-eslint/parser": "^4.31.0", + "@typescript-eslint/eslint-plugin": "^5.4.0", + "@typescript-eslint/parser": "^5.4.0", "eslint": "^7.32.0", "eslint-plugin-import": "^2.24.2", "eslint-plugin-jest": "^24.4.0", @@ -69,6 +69,6 @@ "prettier": "^2.3.2", "ts-jest": "^27.0.7", "ts-node": "^10.3.0", - "typescript": "~4.4.4" + "typescript": "~4.5.2" } } diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 07136f3e6..219e99eee 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -132,7 +132,7 @@ function transformExportSpecifiersFrom( false, undefined, ts.factory.createNamedImports( - exportSpecifiers.map(s => ts.factory.createImportSpecifier(s.propertyName, s.name)) + exportSpecifiers.map(s => ts.factory.createImportSpecifier(statement.isTypeOnly, s.propertyName, s.name)) ) ); From 88d472ad1dc49364249ae6105cd00c7571d20672 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 21 Nov 2021 05:20:16 -0800 Subject: [PATCH 423/764] Nullish coalescing with preceding statements (#1172) * Nullish coalescing with preceding statements * Add test for #1165 --- .../visitors/binary-expression/index.ts | 46 ++++++------------- test/unit/nullishCoalescing.spec.ts | 14 ++++++ 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index df4ef6434..330f51e7d 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -65,7 +65,7 @@ function transformBinaryOperationWithNoPrecedingStatements( if (operator === ts.SyntaxKind.QuestionQuestionToken) { assert(ts.isBinaryExpression(node)); - return transformNullishCoalescingExpression(context, node, left, right); + return transformNullishCoalescingOperationNoPrecedingStatements(context, node, left, right); } let luaOperator = simpleOperatorsToLua[operator]; @@ -138,21 +138,7 @@ function transformShortCircuitBinaryExpression( const [rightPrecedingStatements, rhs] = transformInPrecedingStatementScope(context, () => context.transformExpression(node.right) ); - if (rightPrecedingStatements.length > 0) { - return createShortCircuitBinaryExpressionPrecedingStatements( - context, - lhs, - rhs, - rightPrecedingStatements, - operator, - node - ); - } else { - return [ - rightPrecedingStatements, - transformBinaryOperationWithNoPrecedingStatements(context, lhs, rhs, operator, node), - ]; - } + return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node); } export function transformBinaryOperation( @@ -274,7 +260,7 @@ export function transformBinaryExpressionStatement( } } -function transformNullishCoalescingExpression( +function transformNullishCoalescingOperationNoPrecedingStatements( context: TransformationContext, node: ts.BinaryExpression, transformedLeft: lua.Expression, @@ -287,23 +273,17 @@ function transformNullishCoalescingExpression( (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Boolean)) !== 0 || (type.flags & ts.TypeFlags.BooleanLiteral & ts.TypeFlags.PossiblyFalsy) !== 0; if (typeCanSatisfy(context, lhsType, typeCanBeFalse)) { - // lhs can be false, transform to IIFE - const lhsIdentifier = lua.createIdentifier("____lhs"); - const nilComparison = lua.createBinaryExpression( - lua.cloneIdentifier(lhsIdentifier), - lua.createNilLiteral(), - lua.SyntaxKind.EqualityOperator - ); - // if ____ == nil then return rhs else return ____ end - const ifStatement = lua.createIfStatement( - nilComparison, - lua.createBlock([lua.createReturnStatement([transformedRight])]), - lua.createBlock([lua.createReturnStatement([lua.cloneIdentifier(lhsIdentifier)])]) - ); - // (function(lhs') if lhs' == nil then return rhs else return lhs' end)(lhs) - return lua.createCallExpression(lua.createFunctionExpression(lua.createBlock([ifStatement]), [lhsIdentifier]), [ + // reuse logic from case with preceding statements + const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements( + context, transformedLeft, - ]); + transformedRight, + [], + ts.SyntaxKind.QuestionQuestionToken, + node + ); + context.addPrecedingStatements(precedingStatements); + return result; } else { // lhs or rhs return lua.createBinaryExpression(transformedLeft, transformedRight, lua.SyntaxKind.OrOperator, node); diff --git a/test/unit/nullishCoalescing.spec.ts b/test/unit/nullishCoalescing.spec.ts index 67dbc1cec..309e43732 100644 --- a/test/unit/nullishCoalescing.spec.ts +++ b/test/unit/nullishCoalescing.spec.ts @@ -40,3 +40,17 @@ test("nullish-coalescing operator with side effect rhs", () => { return [i, undefined ?? incI(), i]; `.expectToMatchJsResult(); }); + +test("nullish-coalescing operator with vararg", () => { + util.testFunction` + + function foo(...args: any[]){ + return args + } + function bar(...args: any[]) { + let x: boolean | undefined = false + const y = x ?? foo(...args) + } + return bar(1, 2) + `.expectToMatchJsResult(); +}); From 7dc3e92e300b79b0606e6fe414e09cc40f017927 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 21 Nov 2021 14:21:56 +0100 Subject: [PATCH 424/764] Destructuring crash (#1170) * Update TS to 4.5.x * Fix crash when destructing nested array patterns * Made test deterministic * Fixed test again --- src/transformation/visitors/variable-declaration.ts | 12 ++++++++---- test/unit/loops.spec.ts | 12 ++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 2c5588dd8..a7e4a36ca 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -21,10 +21,14 @@ export function transformArrayBindingElement( } else if (ts.isIdentifier(name)) { return transformIdentifier(context, name); } else if (ts.isBindingElement(name)) { - // TODO: It should always be true when called from `transformVariableDeclaration`, - // but could be false from `transformForOfLuaIteratorStatement`. - assert(ts.isIdentifier(name.name)); - return transformIdentifier(context, name.name); + if (ts.isIdentifier(name.name)) { + return transformIdentifier(context, name.name); + } else { + // ts.isBindingPattern(name.name) + const tempName = context.createTempNameForNode(name.name); + context.addPrecedingStatements(transformBindingPattern(context, name.name, tempName)); + return tempName; + } } else { assertNever(name); } diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index cdb0c3e71..f5f288dd2 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -279,6 +279,18 @@ test("forof destructing", () => { `.expectToMatchJsResult(); }); +test("forof nested destructing", () => { + util.testFunction` + const obj = { a: [3], b: [5] }; + let result = 0; + + for(const [k, [v]] of Object.entries(obj)){ + result += v; + } + return result; + `.expectToMatchJsResult(); +}); + test("forof destructing with existing variables", () => { const input = [ [1, 2], From 25dd8c83d309a6f0f697d39d51e6f810a78b17f3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 23 Nov 2021 13:36:13 +0100 Subject: [PATCH 425/764] Make printer slightly easier to use, add better printer example as test (#1173) --- src/LuaPrinter.ts | 8 ++++---- test/transpile/plugins/plugins.spec.ts | 25 ++++++++++++++++++++++++- test/transpile/plugins/printer.ts | 22 +++++++++++++++++----- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index eb49932c8..542b55e10 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -158,9 +158,9 @@ export class LuaPrinter { private static rightAssociativeOperators = new Set([lua.SyntaxKind.ConcatOperator, lua.SyntaxKind.PowerOperator]); private currentIndent = ""; - private luaFile: string; - private relativeSourcePath: string; - private options: CompilerOptions; + protected luaFile: string; + protected relativeSourcePath: string; + protected options: CompilerOptions; public static readonly sourceMapTracebackPlaceholder = "{#SourceMapTraceback}"; @@ -226,7 +226,7 @@ export class LuaPrinter { return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } - private printFile(file: lua.File): SourceNode { + protected printFile(file: lua.File): SourceNode { let header = file.trivia; if (!this.options.noHeader) { diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index eaaee3dca..457d7d2d9 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -4,7 +4,30 @@ import * as util from "../../util"; test("printer", () => { util.testModule`` .setOptions({ luaPlugins: [{ name: path.join(__dirname, "printer.ts") }] }) - .tap(builder => expect(builder.getMainLuaCodeChunk()).toMatch("Plugin")); + .tap(builder => expect(builder.getMainLuaCodeChunk()).toMatch("-- Custom printer plugin:")); +}); + +test("printer in bundle", () => { + const { transpiledFiles } = util.testBundle` + import "./otherfile"; + + const foo = "foo"; + ` + .addExtraFile( + "otherfile.ts", + ` + const bar = "bar"; + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "printer.ts") }] }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + const lua = transpiledFiles[0].lua!; + + expect(lua).toContain("-- Custom printer plugin: main.lua"); + expect(lua).toContain("-- Custom printer plugin: otherfile.lua"); }); test("visitor", () => { diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts index 7ae55ca01..47627e5b5 100644 --- a/test/transpile/plugins/printer.ts +++ b/test/transpile/plugins/printer.ts @@ -1,11 +1,23 @@ +import { SourceNode } from "source-map"; import * as tstl from "../../../src"; +class CustomPrinter extends tstl.LuaPrinter { + /* Override printFile */ + protected printFile(file: tstl.File): SourceNode { + const originalResult = super.printFile(file); + // Add header comment at the top of the file + return this.createSourceNode(file, [`-- Custom printer plugin: ${this.luaFile}\n`, originalResult]); + } + + /* Override printBoolean */ + public printBooleanLiteral(expression: tstl.BooleanLiteral): SourceNode { + // Print any boolean as 'true' + return this.createSourceNode(expression, "true"); + } +} + const plugin: tstl.Plugin = { - printer(program, emitHost, fileName, ...args) { - const result = new tstl.LuaPrinter(emitHost, program, fileName).print(...args); - result.code = `-- Plugin\n${result.code}`; - return result; - }, + printer: (program, emitHost, fileName, file) => new CustomPrinter(emitHost, program, fileName).print(file), }; // eslint-disable-next-line import/no-default-export From 63a683c3f8467124bbe980a624f79184310a5636 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 28 Nov 2021 10:51:55 -0800 Subject: [PATCH 426/764] Optional chaining using preceding statements (#1171) * Optional chaining with preceding statements * Add more tests and fixes for optional chaining * Optional delete * Fix captureThisArg of optional chain * Use createTempNameForNode and more clarifying names in code * Remove optional chaining LuaLib * Clarify variable names: * Changes from PR feedback * Update comments * Handle non-null chains * Fix test formatting * Handle context in transformOptionalChain always * Clarify callContext determination --- src/LuaLib.ts | 3 - src/lualib/OptionalChainAccess.ts | 10 - src/lualib/OptionalFunctionCall.ts | 10 - src/lualib/OptionalMethodCall.ts | 17 -- src/transformation/builtins/index.ts | 30 ++- src/transformation/builtins/object.ts | 5 +- src/transformation/utils/diagnostics.ts | 8 + src/transformation/visitors/access.ts | 113 ++++++---- src/transformation/visitors/call.ts | 134 +++++------ src/transformation/visitors/delete.ts | 5 + .../visitors/expression-list.ts | 5 +- src/transformation/visitors/identifier.ts | 5 + .../visitors/optional-chaining.ts | 209 ++++++++++++++++++ src/transpilation/transformers.ts | 4 +- src/typescript-internal.d.ts | 3 + .../optionalChaining.spec.ts.snap | 60 +++++ test/unit/optionalChaining.spec.ts | 180 ++++++++++++++- 17 files changed, 629 insertions(+), 172 deletions(-) delete mode 100644 src/lualib/OptionalChainAccess.ts delete mode 100644 src/lualib/OptionalFunctionCall.ts delete mode 100644 src/lualib/OptionalMethodCall.ts create mode 100644 src/transformation/visitors/optional-chaining.ts create mode 100644 test/unit/__snapshots__/optionalChaining.spec.ts.snap diff --git a/src/LuaLib.ts b/src/LuaLib.ts index f22ff28e1..226bbe15c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -58,9 +58,6 @@ export enum LuaLibFeature { ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", - OptionalChainAccess = "OptionalChainAccess", - OptionalFunctionCall = "OptionalFunctionCall", - OptionalMethodCall = "OptionalMethodCall", ParseFloat = "ParseFloat", ParseInt = "ParseInt", Promise = "Promise", diff --git a/src/lualib/OptionalChainAccess.ts b/src/lualib/OptionalChainAccess.ts deleted file mode 100644 index 7924aa282..000000000 --- a/src/lualib/OptionalChainAccess.ts +++ /dev/null @@ -1,10 +0,0 @@ -function __TS__OptionalChainAccess( - this: void, - table: Record, - key: TKey -): TReturn | undefined { - if (table) { - return table[key]; - } - return undefined; -} diff --git a/src/lualib/OptionalFunctionCall.ts b/src/lualib/OptionalFunctionCall.ts deleted file mode 100644 index 85b52a047..000000000 --- a/src/lualib/OptionalFunctionCall.ts +++ /dev/null @@ -1,10 +0,0 @@ -function __TS__OptionalFunctionCall( - this: void, - f: (this: void, ...args: [...TArgs]) => TReturn, - ...args: [...TArgs] -): TReturn | undefined { - if (f) { - return f(...args); - } - return undefined; -} diff --git a/src/lualib/OptionalMethodCall.ts b/src/lualib/OptionalMethodCall.ts deleted file mode 100644 index 5549a1c36..000000000 --- a/src/lualib/OptionalMethodCall.ts +++ /dev/null @@ -1,17 +0,0 @@ -function __TS__OptionalMethodCall( - this: void, - table: Record TReturn>, - methodName: string, - isMethodOptional: boolean, - ...args: [...TArgs] -): TReturn | undefined { - if (table) { - const method = table[methodName]; - if (method) { - return method.call(table, ...args); - } else if (!isMethodOptional) { - throw `${methodName} is not a function`; - } - } - return undefined; -} diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 53473b420..5795b7619 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -25,6 +25,7 @@ import { transformObjectConstructorCall, transformObjectPrototypeCall } from "./ import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; +import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; export function transformBuiltinPropertyAccessExpression( context: TransformationContext, @@ -56,7 +57,8 @@ export function transformBuiltinPropertyAccessExpression( export function transformBuiltinCallExpression( context: TransformationContext, - node: ts.CallExpression + node: ts.CallExpression, + isOptionalCall: boolean ): lua.Expression | undefined { const expressionType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, expressionType, undefined)) { @@ -68,55 +70,75 @@ export function transformBuiltinCallExpression( } } - if (!ts.isPropertyAccessExpression(node.expression)) { + const expression = ts.getOriginalNode(node.expression); + if (!ts.isPropertyAccessExpression(expression)) { return; } assume(node); + const isOptionalAccess = expression.questionDotToken; + const unsupportedOptionalCall = () => { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + }; + // If the function being called is of type owner.func, get the type of owner - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + const ownerType = context.checker.getTypeAtLocation(expression.expression); if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); switch (symbol?.name) { case "ArrayConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformArrayConstructorCall(context, node); case "Console": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformConsoleCall(context, node); case "Math": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformMathCall(context, node); case "StringConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformStringConstructorCall(context, node); case "ObjectConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformObjectConstructorCall(context, node); case "SymbolConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformSymbolConstructorCall(context, node); case "NumberConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformNumberConstructorCall(context, node); case "PromiseConstructor": + if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); return transformPromiseConstructorCall(context, node); } } if (isStringType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + if (isOptionalCall) return unsupportedOptionalCall(); return transformStringPrototypeCall(context, node); } if (isNumberType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + if (isOptionalCall) return unsupportedOptionalCall(); return transformNumberPrototypeCall(context, node); } if (isArrayType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + if (isOptionalCall) return unsupportedOptionalCall(); return transformArrayPrototypeCall(context, node); } if (isFunctionType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + if (isOptionalCall) return unsupportedOptionalCall(); return transformFunctionPrototypeCall(context, node); } - const objectResult = transformObjectPrototypeCall(context, node); + const objectResult = transformObjectPrototypeCall(context, node, expression); if (objectResult) { + if (isOptionalCall) return unsupportedOptionalCall(); return objectResult; } } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 2db793f91..4b806eb32 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -1,4 +1,5 @@ import * as lua from "../../LuaAST"; +import * as ts from "typescript"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; @@ -36,9 +37,9 @@ export function transformObjectConstructorCall( export function transformObjectPrototypeCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + expression: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const name = expression.name.text; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index d6d151de9..ca8ae0320 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -151,3 +151,11 @@ export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( export const awaitMustBeInAsyncFunction = createErrorDiagnosticFactory( "Await can only be used inside async functions." ); + +export const unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory( + "Optional calls are not supported for builtin or language extension functions." +); + +export const unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactory( + "Optional calls are not supported on enums marked with @compileMembersOnly." +); diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index a3ec68c46..b09db7801 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,13 +3,23 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationRemoved, invalidMultiReturnAccess } from "../utils/diagnostics"; +import { + annotationRemoved, + invalidMultiReturnAccess, + unsupportedOptionalCompileMembersOnly, +} from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { transformOrderedExpressions } from "./expression-list"; import { isMultiReturnCall, returnsMultiType } from "./language-extensions/multi"; +import { + transformOptionalChainWithCapture, + ExpressionWithThisValue, + isOptionalContinuation, + captureThisValue, +} from "./optional-chaining"; function addOneToArrayAccessArgument( context: TransformationContext, @@ -32,10 +42,20 @@ export function transformElementAccessArgument( return addOneToArrayAccessArgument(context, node, index); } -export const transformElementAccessExpression: FunctionVisitor = (node, context) => { +export const transformElementAccessExpression: FunctionVisitor = (node, context) => + transformElementAccessExpressionWithCapture(context, node, undefined).expression; +export function transformElementAccessExpressionWithCapture( + context: TransformationContext, + node: ts.ElementAccessExpression, + thisValueCapture: lua.Identifier | undefined +): ExpressionWithThisValue { const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { - return constEnumValue; + return { expression: constEnumValue }; + } + + if (ts.isOptionalChain(node)) { + return transformOptionalChainWithCapture(context, node, thisValueCapture); } const [table, accessExpression] = transformOrderedExpressions(context, [node.expression, node.argumentExpression]); @@ -43,7 +63,10 @@ export const transformElementAccessExpression: FunctionVisitor = (node, context) => { +export const transformPropertyAccessExpression: FunctionVisitor = (node, context) => + transformPropertyAccessExpressionWithCapture(context, node, undefined).expression; +export function transformPropertyAccessExpressionWithCapture( + context: TransformationContext, + node: ts.PropertyAccessExpression, + thisValueCapture: lua.Identifier | undefined +): ExpressionWithThisValue { const property = node.name.text; const type = context.checker.getTypeAtLocation(node.expression); + const isOptionalLeft = isOptionalContinuation(node.expression); const annotations = getTypeAnnotations(type); @@ -89,49 +115,54 @@ export const transformPropertyAccessExpression: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index a863789ae..c10c08e28 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -6,7 +6,6 @@ import { AnnotationKind, getTypeAnnotations, isTupleReturnCall } from "../utils/ import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInTable } from "../utils/lua-ast"; -import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; @@ -22,9 +21,15 @@ import { transformTableHasExpression, transformTableSetExpression, } from "./language-extensions/table"; -import { annotationRemoved, invalidTableDeleteExpression, invalidTableSetExpression } from "../utils/diagnostics"; +import { + annotationRemoved, + invalidTableDeleteExpression, + invalidTableSetExpression, + unsupportedBuiltinOptionalCall, +} from "../utils/diagnostics"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformOptionalChain, getOptionalContinuationData } from "./optional-chaining"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -131,7 +136,10 @@ export function transformContextualCallExpression( node: ts.CallExpression | ts.TaggedTemplateExpression, args: ts.Expression[] | ts.NodeArray, signature?: ts.Signature -): lua.CallExpression | lua.MethodCallExpression { +): lua.Expression { + if (ts.isOptionalChain(node)) { + return transformOptionalChain(context, node); + } const left = ts.isCallExpression(node) ? node.expression : node.tag; let [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => @@ -146,24 +154,12 @@ export function transformContextualCallExpression( ) { // table:name() const table = context.transformExpression(left.expression); - if (ts.isOptionalChain(node)) { - return transformLuaLibFunction( - context, - LuaLibFeature.OptionalMethodCall, - node, - table, - lua.createStringLiteral(left.name.text, left.name), - lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call - ...transformedArguments - ); - } else { - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformedArguments, - node - ); - } + return lua.createMethodCallExpression( + table, + lua.createIdentifier(left.name.text, left.name), + transformedArguments, + node + ); } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { return transformElementAccessCall(context, left, transformedArguments, argPrecedingStatements); @@ -194,10 +190,7 @@ export function transformContextualCallExpression( } } -function transformPropertyCall( - context: TransformationContext, - node: PropertyCallExpression -): lua.CallExpression | lua.MethodCallExpression { +function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { const signature = context.checker.getResolvedSignature(node); if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { @@ -214,18 +207,11 @@ function transformPropertyCall( // table.name() const [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); - if (ts.isOptionalChain(node)) { - return transformLuaLibFunction(context, LuaLibFeature.OptionalFunctionCall, node, callPath, ...parameters); - } else { - return lua.createCallExpression(callPath, parameters, node); - } + return lua.createCallExpression(callPath, parameters, node); } } -function transformElementCall( - context: TransformationContext, - node: ts.CallExpression -): lua.CallExpression | lua.MethodCallExpression { +function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { const signature = context.checker.getResolvedSignature(node); const signatureDeclaration = signature?.getDeclaration(); if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { @@ -239,11 +225,20 @@ function transformElementCall( } export const transformCallExpression: FunctionVisitor = (node, context) => { + if (ts.isOptionalChain(node)) { + return transformOptionalChain(context, node); + } + + const optionalContinuation = ts.isIdentifier(node.expression) + ? getOptionalContinuationData(node.expression) + : undefined; const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); - const wrapResultInOptional = ts.isOptionalChain(node); - const builtinResult = transformBuiltinCallExpression(context, node); + const builtinResult = transformBuiltinCallExpression(context, node, optionalContinuation !== undefined); if (builtinResult) { + if (optionalContinuation) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + } return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; } @@ -252,6 +247,10 @@ export const transformCallExpression: FunctionVisitor = (node } if (isOperatorMapping(context, node)) { + if (optionalContinuation) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + } return transformOperatorMappingExpression(context, node); } @@ -262,10 +261,18 @@ export const transformCallExpression: FunctionVisitor = (node } if (isTableGetCall(context, node)) { + if (optionalContinuation) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + } return transformTableGetExpression(context, node); } if (isTableHasCall(context, node)) { + if (optionalContinuation) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + } return transformTableHasExpression(context, node); } @@ -283,13 +290,12 @@ export const transformCallExpression: FunctionVisitor = (node } const result = transformPropertyCall(context, node as PropertyCallExpression); - // transformPropertyCall already wraps optional so no need to do so here return wrapResultInTable ? wrapInTable(result) : result; } if (ts.isElementAccessExpression(node.expression)) { const result = transformElementCall(context, node); - return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, result, node); + return wrapResultInTable ? wrapInTable(result) : result; } const signature = context.checker.getResolvedSignature(node); @@ -310,11 +316,15 @@ export const transformCallExpression: FunctionVisitor = (node const signatureDeclaration = signature?.getDeclaration(); let callPath: lua.Expression; - let parameters: lua.Expression[] = []; - if (signatureDeclaration && getDeclarationContextType(context, signatureDeclaration) === ContextType.Void) { + let parameters: lua.Expression[]; + const isContextualCall = + !signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; + if (!isContextualCall) { [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); } else { - const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); + // if is optionalContinuation, context will be handled by transformOptionalChain. + const useGlobalContext = !context.isStrict && optionalContinuation === undefined; + const callContext = useGlobalContext ? ts.factory.createIdentifier("_G") : ts.factory.createNull(); [callPath, parameters] = transformCallAndArguments( context, node.expression, @@ -325,42 +335,8 @@ export const transformCallExpression: FunctionVisitor = (node } const callExpression = lua.createCallExpression(callPath, parameters, node); - return wrapIfRequired(context, wrapResultInTable, wrapResultInOptional, callExpression, node); -}; - -function wrapIfRequired( - context: TransformationContext, - shouldWrapInTable: boolean, - shouldWrapOptional: boolean, - call: lua.CallExpression | lua.MethodCallExpression, - node: ts.CallExpression -): lua.Expression { - const wrappedOptional = shouldWrapOptional ? wrapOptionalCall(context, call, node) : call; - return shouldWrapInTable ? wrapInTable(wrappedOptional) : wrappedOptional; -} - -function wrapOptionalCall( - context: TransformationContext, - call: lua.CallExpression | lua.MethodCallExpression, - node: ts.CallExpression -): lua.CallExpression { - if (lua.isMethodCallExpression(call)) { - return transformLuaLibFunction( - context, - LuaLibFeature.OptionalMethodCall, - node, - call.prefixExpression, - lua.createStringLiteral(call.name.text), - lua.createBooleanLiteral(node.questionDotToken !== undefined), // Require method is present if no ?.() call - ...call.params - ); - } else { - return transformLuaLibFunction( - context, - LuaLibFeature.OptionalFunctionCall, - node, - call.expression, - ...call.params - ); + if (optionalContinuation && isContextualCall) { + optionalContinuation.contextualCall = callExpression; } -} + return wrapResultInTable ? wrapInTable(callExpression) : callExpression; +}; diff --git a/src/transformation/visitors/delete.ts b/src/transformation/visitors/delete.ts index 39bbf1d57..efa879c2e 100644 --- a/src/transformation/visitors/delete.ts +++ b/src/transformation/visitors/delete.ts @@ -5,8 +5,13 @@ import { transformLuaLibFunction, LuaLibFeature } from "../utils/lualib"; import { unsupportedProperty } from "../utils/diagnostics"; import { isArrayType, isNumberType } from "../utils/typescript"; import { addToNumericExpression } from "../utils/lua-ast"; +import { transformOptionalDeleteExpression } from "./optional-chaining"; export const transformDeleteExpression: FunctionVisitor = (node, context) => { + if (ts.isOptionalChain(node.expression)) { + return transformOptionalDeleteExpression(context, node, node.expression); + } + let ownerExpression: lua.Expression | undefined; let propertyExpression: lua.Expression | undefined; diff --git a/src/transformation/visitors/expression-list.ts b/src/transformation/visitors/expression-list.ts index 01213ce4d..67019dcf1 100644 --- a/src/transformation/visitors/expression-list.ts +++ b/src/transformation/visitors/expression-list.ts @@ -5,12 +5,13 @@ import { TransformationContext, tempSymbolId } from "../context"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { isConstIdentifier } from "../utils/typescript"; +import { isOptionalContinuation } from "./optional-chaining"; -function shouldMoveToTemp(context: TransformationContext, expression: lua.Expression, tsOriginal?: ts.Node) { +export function shouldMoveToTemp(context: TransformationContext, expression: lua.Expression, tsOriginal?: ts.Node) { return ( !lua.isLiteral(expression) && !(lua.isIdentifier(expression) && expression.symbolId === tempSymbolId) && // Treat generated temps as consts - !(tsOriginal && isConstIdentifier(context, tsOriginal)) + !(tsOriginal && (isConstIdentifier(context, tsOriginal) || isOptionalContinuation(tsOriginal))) ); } diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 3d39b16a4..86684a9c8 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -21,8 +21,13 @@ import { isOperatorMapping } from "./language-extensions/operators"; import { isRangeFunctionNode } from "./language-extensions/range"; import { isTableExtensionIdentifier } from "./language-extensions/table"; import { isVarargConstantNode } from "./language-extensions/vararg"; +import { isOptionalContinuation } from "./optional-chaining"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { + if (isOptionalContinuation(identifier)) { + return lua.createIdentifier(identifier.text); + } + if (isMultiFunctionNode(context, identifier)) { context.diagnostics.push(invalidMultiFunctionUse(identifier)); return lua.createAnonymousIdentifier(identifier); diff --git a/src/transformation/visitors/optional-chaining.ts b/src/transformation/visitors/optional-chaining.ts new file mode 100644 index 000000000..7c6d457eb --- /dev/null +++ b/src/transformation/visitors/optional-chaining.ts @@ -0,0 +1,209 @@ +import * as ts from "typescript"; +import * as lua from "../../LuaAST"; +import { TransformationContext, tempSymbolId } from "../context"; +import { assert, assertNever } from "../../utils"; +import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformPropertyAccessExpressionWithCapture, transformElementAccessExpressionWithCapture } from "./access"; +import { shouldMoveToTemp } from "./expression-list"; + +type NormalOptionalChain = ts.PropertyAccessChain | ts.ElementAccessChain | ts.CallChain; + +function skipNonNullChains(chain: ts.OptionalChain): NormalOptionalChain { + while (ts.isNonNullChain(chain)) { + chain = chain.expression as ts.OptionalChain; + } + return chain; +} + +function flattenChain(chain: ts.OptionalChain) { + chain = skipNonNullChains(chain); + const links: NormalOptionalChain[] = [chain]; + while (!chain.questionDotToken && !ts.isTaggedTemplateExpression(chain)) { + const nextLink: ts.Expression = chain.expression; + assert(ts.isOptionalChain(nextLink)); + chain = skipNonNullChains(nextLink); + links.unshift(chain); + } + return { expression: chain.expression, chain: links }; +} + +export interface ExpressionWithThisValue { + expression: lua.Expression; + thisValue?: lua.Expression; +} + +function transformExpressionWithThisValueCapture( + context: TransformationContext, + node: ts.Expression, + thisValueCapture: lua.Identifier +): ExpressionWithThisValue { + if (ts.isParenthesizedExpression(node)) { + return transformExpressionWithThisValueCapture(context, node.expression, thisValueCapture); + } + if (ts.isPropertyAccessExpression(node)) { + return transformPropertyAccessExpressionWithCapture(context, node, thisValueCapture); + } + if (ts.isElementAccessExpression(node)) { + return transformElementAccessExpressionWithCapture(context, node, thisValueCapture); + } + return { expression: context.transformExpression(node) }; +} + +// returns thisValueCapture exactly if a temp variable was used. +export function captureThisValue( + context: TransformationContext, + expression: lua.Expression, + thisValueCapture: lua.Identifier, + tsOriginal: ts.Node +): lua.Expression { + if (!shouldMoveToTemp(context, expression, tsOriginal) && !isOptionalContinuation(tsOriginal)) { + return expression; + } + const tempAssignment = lua.createAssignmentStatement(thisValueCapture, expression, tsOriginal); + context.addPrecedingStatements(tempAssignment); + return thisValueCapture; +} + +export interface OptionalContinuation { + contextualCall?: lua.CallExpression; +} + +const optionalContinuations = new WeakMap(); + +// should be translated verbatim to lua +function createOptionalContinuationIdentifier(text: string, tsOriginal: ts.Expression): ts.Identifier { + const identifier = ts.factory.createIdentifier(text); + ts.setOriginalNode(identifier, tsOriginal); + optionalContinuations.set(identifier, {}); + return identifier; +} +export function isOptionalContinuation(node: ts.Node): boolean { + return ts.isIdentifier(node) && optionalContinuations.has(node); +} +export function getOptionalContinuationData(identifier: ts.Identifier): OptionalContinuation | undefined { + return optionalContinuations.get(identifier); +} + +export function transformOptionalChain(context: TransformationContext, node: ts.OptionalChain): lua.Expression { + return transformOptionalChainWithCapture(context, node, undefined).expression; +} + +export function transformOptionalChainWithCapture( + context: TransformationContext, + node: ts.OptionalChain, + thisValueCapture: lua.Identifier | undefined, + isDelete?: ts.DeleteExpression +): ExpressionWithThisValue { + const luaTemp = context.createTempNameForNode(node); + + const { expression: tsLeftExpression, chain } = flattenChain(node); + + // build temp.b.c.d + const tsTemp = createOptionalContinuationIdentifier(luaTemp.text, tsLeftExpression); + let tsRightExpression: ts.Expression = tsTemp; + for (const link of chain) { + if (ts.isPropertyAccessExpression(link)) { + tsRightExpression = ts.factory.createPropertyAccessExpression(tsRightExpression, link.name); + } else if (ts.isElementAccessExpression(link)) { + tsRightExpression = ts.factory.createElementAccessExpression(tsRightExpression, link.argumentExpression); + } else if (ts.isCallExpression(link)) { + tsRightExpression = ts.factory.createCallExpression(tsRightExpression, undefined, link.arguments); + } else { + assertNever(link); + } + ts.setOriginalNode(tsRightExpression, link); + } + if (isDelete) { + tsRightExpression = ts.factory.createDeleteExpression(tsRightExpression); + ts.setOriginalNode(tsRightExpression, isDelete); + } + + // transform right expression first to check if thisValue capture is needed + // capture and return thisValue if requested from outside + let returnThisValue: lua.Expression | undefined; + const [rightPrecedingStatements, rightAssignment] = transformInPrecedingStatementScope(context, () => { + let result: lua.Expression; + if (thisValueCapture) { + ({ expression: result, thisValue: returnThisValue } = transformExpressionWithThisValueCapture( + context, + tsRightExpression, + thisValueCapture + )); + } else { + result = context.transformExpression(tsRightExpression); + } + return lua.createAssignmentStatement(luaTemp, result); + }); + + // transform left expression, handle thisValue if needed by rightExpression + const thisValueCaptureName = context.createTempName("this"); + const leftThisValueTemp = lua.createIdentifier(thisValueCaptureName, undefined, tempSymbolId); + let capturedThisValue: lua.Expression | undefined; + + const rightContextualCall = getOptionalContinuationData(tsTemp)?.contextualCall; + const [leftPrecedingStatements, leftExpression] = transformInPrecedingStatementScope(context, () => { + let result: lua.Expression; + if (rightContextualCall) { + ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture( + context, + tsLeftExpression, + leftThisValueTemp + )); + } else { + result = context.transformExpression(tsLeftExpression); + } + return result; + }); + // handle context + if (rightContextualCall) { + if (capturedThisValue) { + rightContextualCall.params[0] = capturedThisValue; + if (capturedThisValue === leftThisValueTemp) { + context.addPrecedingStatements(lua.createVariableDeclarationStatement(leftThisValueTemp)); + } + } else { + if (context.isStrict) { + rightContextualCall.params[0] = lua.createNilLiteral(); + } else { + const identifier = lua.createIdentifier("_G"); + if (rightPrecedingStatements.length === 0) { + rightContextualCall.params[0] = identifier; + } else { + const tempContext = context.createTempNameForLuaExpression(identifier); + rightPrecedingStatements.unshift(lua.createVariableDeclarationStatement(tempContext, identifier)); + rightContextualCall.params[0] = tempContext; + } + } + } + } + + // + // local temp = + // if temp ~= nil then + // + // temp = temp.b.c.d + // end + // return temp + + context.addPrecedingStatements([ + ...leftPrecedingStatements, + lua.createVariableDeclarationStatement(luaTemp, leftExpression), + lua.createIfStatement( + lua.createBinaryExpression(luaTemp, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), + lua.createBlock([...rightPrecedingStatements, rightAssignment]) + ), + ]); + return { + expression: luaTemp, + thisValue: returnThisValue, + }; +} + +export function transformOptionalDeleteExpression( + context: TransformationContext, + node: ts.DeleteExpression, + innerExpression: ts.OptionalChain +) { + transformOptionalChainWithCapture(context, innerExpression, undefined, node); + return lua.createBooleanLiteral(true, node); +} diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index ac81f6d68..b06131e8c 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -57,7 +57,7 @@ export const noImplicitSelfTransformer: ts.TransformerFactory = context => sourceFile => { // Remove parenthesis expressions before transforming to Lua, so transpiler is not hindered by extra ParenthesizedExpression nodes function unwrapParentheses(node: ts.Expression) { - while (ts.isParenthesizedExpression(node)) { + while (ts.isParenthesizedExpression(node) && !ts.isOptionalChain(node.expression)) { node = node.expression; } return node; @@ -73,6 +73,8 @@ export const stripParenthesisExpressionsTransformer: ts.TransformerFactory SourceFile; + + function skipParentheses(node: Expression): Expression; + function skipParentheses(node: Node): Node; } diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap new file mode 100644 index 000000000..9a0adc0b2 --- /dev/null +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -0,0 +1,60 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Unsupported optional chains Builtin global method: code 1`] = ` +"require(\\"lualib_bundle\\"); +local ____Number_result_0 = Number +if ____Number_result_0 ~= nil then + ____Number_result_0 = __TS__Number(\\"3\\") +end +local ____ = ____Number_result_0" +`; + +exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; + +exports[`Unsupported optional chains Builtin global property: code 1`] = ` +"local ____console_log_result_0 = console +if ____console_log_result_0 ~= nil then + ____console_log_result_0 = nil +end +local ____ = ____console_log_result_0" +`; + +exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; + +exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` +"local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach +if ____table_forEach_result_0 ~= nil then + ____table_forEach_result_0 = nil +end +local ____ = ____table_forEach_result_0" +`; + +exports[`Unsupported optional chains Builtin prototype method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; + +exports[`Unsupported optional chains Compile members only: code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local A = 0 + local B = 2 + local C = 3 + local D = \\"D\\" + local ____TestEnum_B_0 = TestEnum + if ____TestEnum_B_0 ~= nil then + ____TestEnum_B_0 = B + end + local ____ = ____TestEnum_B_0 +end +return ____exports" +`; + +exports[`Unsupported optional chains Compile members only: diagnostics 1`] = `"main.ts(10,17): error TSTL: Optional calls are not supported on enums marked with @compileMembersOnly."`; + +exports[`Unsupported optional chains Language extensions: code 1`] = ` +"local ____table_has_result_0 = ({}).has +if ____table_has_result_0 ~= nil then + ____table_has_result_0 = nil +end +local ____ = ____table_has_result_0" +`; + +exports[`Unsupported optional chains Language extensions: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 9763a91c6..234bff14c 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,5 +1,6 @@ import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; +import { ScriptTarget } from "typescript"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` @@ -71,8 +72,9 @@ test("optional element function calls", () => { `.expectToMatchJsResult(); }); -test("optional element access method calls", () => { - util.testFunction` +describe("optional access method calls", () => { + test("element access call", () => { + util.testFunction` const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { value: "foobar", foo(prefix: string) { return prefix + this.value; } @@ -81,6 +83,39 @@ test("optional element access method calls", () => { const barKey = "bar"; return obj[barKey]?.("bar?") ?? obj[fooKey]?.("foo?"); `.expectToMatchJsResult(); + }); + + test("optional access call", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + return obj.foo?.("bar?") ?? obj.bar?.("foo?"); + `.expectToMatchJsResult(); + }); + + test("nested optional element access call", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + const fooKey = "foo"; + const barKey = "bar"; + return obj?.[barKey]?.("bar?") ?? obj?.[fooKey]?.("foo?"); + `.expectToMatchJsResult(); + }); + + test("nested optional property access call", () => { + util.testFunction` + const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { + value: "foobar", + foo(prefix: string) { return prefix + this.value; } + } + return obj?.foo?.("bar?") ?? obj?.bar?.("foo?"); + `.expectToMatchJsResult(); + }); }); test("no side effects", () => { @@ -173,6 +208,145 @@ describe("optional chaining function calls", () => { util.testFunction` const obj: any = {}; obj?.foo(); - `.expectToEqual(new util.ExecutionError("foo is not a function")); + `.expectToEqual(new util.ExecutionError("attempt to call a nil value (method 'foo')")); + }); + + describe("builtins", () => { + test.each([ + ["undefined", undefined], + ["{foo: 0}", true], + ])("LuaTable: %p", (expr, value) => { + util.testFunction` + const table: LuaTable = ${expr} as any + const bar = table?.has("foo") + return bar + ` + .withLanguageExtensions() + .expectToEqual(value); + }); + + test.each(["undefined", "foo"])("Function call: %p", e => { + util.testFunction` + const result = [] + function foo(this: unknown, arg: unknown) { + return [this, arg] + } + const bar = ${e} as typeof foo | undefined + return bar?.call(1, 2) + `.expectToMatchJsResult(); + }); + + test.each([undefined, "[1, 2, 3, 4]"])("Array: %p", expr => { + util.testFunction` + const value: any[] | undefined = ${expr} + return value?.map(x=>x+1) + `.expectToMatchJsResult(); + }); + }); + + test.each([true, false])("Default call context, strict %s", strict => { + util.testFunction` + function func(this: unknown, arg: unknown) { + return [this === globalThis ? "_G" : this === undefined ? "nil" : "neither", arg]; + } + let i = 0 + const result = func?.(i++); + ` + .setOptions({ + alwaysStrict: strict, + target: ScriptTarget.ES5, + }) + .expectToMatchJsResult(); + }); +}); + +describe("Unsupported optional chains", () => { + test("Language extensions", () => { + util.testModule` + new LuaTable().has?.(3) + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(); + }); + + test("Builtin prototype method", () => { + util.testModule` + [1,2,3,4].forEach?.(()=>{}) + `.expectDiagnosticsToMatchSnapshot(); + }); + + test("Builtin global method", () => { + util.testModule` + Number?.("3") + `.expectDiagnosticsToMatchSnapshot(); + }); + + test("Builtin global property", () => { + util.testModule` + console?.log("3") + ` + .setOptions({ + lib: ["lib.esnext.d.ts", "lib.dom.d.ts"], + }) + .expectDiagnosticsToMatchSnapshot(); + }); + + test("Compile members only", () => { + util.testFunction` + /** @compileMembersOnly */ + enum TestEnum { + A = 0, + B = 2, + C, + D = "D", + } + + TestEnum?.B + `.expectDiagnosticsToMatchSnapshot(); + }); +}); + +describe("optional delete", () => { + test("successful", () => { + util.testFunction` + const table = { + bar: 3 + } + return [delete table?.bar, table] + `.expectToMatchJsResult(); + }); + + test("unsuccessful", () => { + util.testFunction` + const table : { + bar?: number + } = {} + return [delete table?.bar, table] + `.expectToMatchJsResult(); + }); + + test("delete on undefined", () => { + util.testFunction` + const table : { + bar: number + } | undefined = undefined + return [delete table?.bar, table ?? "nil"] + `.expectToMatchJsResult(); + }); +}); + +describe("Non-null chain", () => { + test("Single non-null chain", () => { + util.testFunction` + const foo = {a: { b: 3} } + return foo?.a!.b + `.expectToMatchJsResult(); + }); + + test("Many non-null chains", () => { + util.testFunction` + const foo = {a: { b: 3} } + return foo?.a!!!.b!!! + `.expectToMatchJsResult(); }); }); From 9d9baa7f03b5ebc209dad08b821be017abdf2e53 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 28 Nov 2021 21:36:25 +0100 Subject: [PATCH 427/764] Resolve plugin ts-node relative to tstl instead of relative to tsconfig.json (#1175) --- src/transpilation/utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 9ac888a9e..0bf8075d2 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -35,6 +35,8 @@ export interface EmitFile extends BaseFile { export const getConfigDirectory = (options: ts.CompilerOptions) => options.configFilePath ? path.dirname(options.configFilePath) : process.cwd(); +const getTstlDirectory = () => path.dirname(__dirname); + export function resolvePlugin( kind: string, optionName: string, @@ -59,7 +61,7 @@ export function resolvePlugin( const hasNoRequireHook = require.extensions[".ts"] === undefined; if (hasNoRequireHook && (resolved.endsWith(".ts") || resolved.endsWith(".tsx"))) { try { - const tsNodePath = resolve.sync("ts-node", { basedir }); + const tsNodePath = resolve.sync("ts-node", { basedir: getTstlDirectory() }); const tsNode: typeof import("ts-node") = require(tsNodePath); tsNode.register({ transpileOnly: true }); } catch (err) { From b4fb9e308da4d5db2a79f70ef49202faaf6a7658 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 28 Nov 2021 21:43:22 +0100 Subject: [PATCH 428/764] CHANGELOG 1.2.0 --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b5736e17..7c8e0af4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 1.2.0 + +- Upgraded to TypeScript 4.5.x. +- Improved general output formatting. +- Added support for more complicated (nested) destructuring patterns, also fixing an exception they caused before. +- Fixed incorrect interactions between standard library functionality and optional chaining, e.g. `myArray?.forEach()`. +- Fixed rejected promises sometimes not getting the correct rejection reason. +- Fixed some `delete` behavior that was different in Lua compared to JS. +- Fixed a bug causing exported classes to lose their decorators. +- Fixed plugins checking for ts-node from the wrong location (tsconfig directory), plugins will now check for ts-node relative to the tstl directory. + +Under the hood: + +- We can now transform using preceding statements, allowing all kinds of optimizations and improvements to output Lua. +- Updated various language constructs to use preceding statements instead of inline immediately-invoked functions. + ## 1.1.0 - **[Breaking]** We now use TypeScript's JSX transformer instead of maintaining our own. As a result, `React.createElement` now requires a self parameter, so remove `@noSelf`, `this: void` if necessary. From ed3e785b85e48d3f495a309b3e0381031c511f82 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 28 Nov 2021 21:54:08 +0100 Subject: [PATCH 429/764] 1.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5e9167c3b..6b8944608 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.1.1", + "version": "1.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.1.1", + "version": "1.2.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 432768356..3df16477f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.1.1", + "version": "1.2.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 1f3a505488c3ba87bfc5345a31249c831bb68627 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 2 Dec 2021 14:19:53 -0700 Subject: [PATCH 430/764] fixes to binding destructuriing in loops and functions (#1182) Co-authored-by: Tom --- src/transformation/utils/scope.ts | 1 + src/transformation/visitors/function.ts | 6 +++++- src/transformation/visitors/loops/utils.ts | 10 +++++++++- test/unit/destructuring.spec.ts | 11 +++++++++++ test/unit/loops.spec.ts | 21 +++++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 3a4558b4d..ad1ddfe6a 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -14,6 +14,7 @@ export enum ScopeType { Block = 1 << 5, Try = 1 << 6, Catch = 1 << 7, + LoopInitializer = 1 << 8, } interface FunctionDefinitionInfo { diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index dd749d202..e16bf8401 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -85,7 +85,11 @@ export function transformFunctionBodyHeader( } // Binding pattern - bindingPatternDeclarations.push(...transformBindingPattern(context, declaration.name, identifier)); + const name = declaration.name; + const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + transformBindingPattern(context, name, identifier) + ); + bindingPatternDeclarations.push(...precedingStatements, ...bindings); } else if (declaration.initializer !== undefined) { // Default parameter headerStatements.push( diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index ec3548baa..3c5887281 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { performHoisting, popScope, pushScope, ScopeType } from "../../utils/scope"; import { isAssignmentPattern } from "../../utils/typescript"; import { transformAssignment } from "../binary-expression/assignments"; @@ -49,14 +50,20 @@ export function transformForInitializer( ): lua.Identifier { const valueVariable = lua.createIdentifier("____value"); + pushScope(context, ScopeType.LoopInitializer); + if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable const binding = getVariableDeclarationBinding(context, initializer); if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { - block.statements.unshift(...transformBindingPattern(context, binding, valueVariable)); + const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + transformBindingPattern(context, binding, valueVariable) + ); + block.statements.unshift(...precedingStatements, ...bindings); } else { // Single variable declared in for loop + popScope(context); return transformIdentifier(context, binding); } } else { @@ -69,6 +76,7 @@ export function transformForInitializer( ); } + popScope(context); return valueVariable; } diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 2ec12c7d1..d8fe47973 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -53,6 +53,17 @@ test("in function parameter creates local variables", () => { expect(code).toContain("local b ="); }); +test("in function parameter creates local variables in correct scope", () => { + util.testFunction` + let x = 7; + function foo([x]: [number]) { + x *= 2; + } + foo([1]); + return x; + `.expectToMatchJsResult(); +}); + test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { util.testFunction` let ${allBindings}; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index f5f288dd2..427af9d06 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -279,6 +279,27 @@ test("forof destructing", () => { `.expectToMatchJsResult(); }); +test("forof destructing scope", () => { + util.testFunction` + let x = 7; + for (let [x] of [[1], [2], [3]]) { + x *= 2; + } + return x; + `.expectToMatchJsResult(); +}); + +// This catches the case where x is falsely seen as globally scoped and the 'local' is stripped out +test("forof destructing scope (global)", () => { + util.testModule` + let x = 7; + for (let [x] of [[1], [2], [3]]) { + x *= 2; + } + if (x !== 7) throw x; + `.expectNoExecutionError(); +}); + test("forof nested destructing", () => { util.testFunction` const obj = { a: [3], b: [5] }; From c955a638f22e09f8323c729e34e90a3bab56f78a Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Thu, 2 Dec 2021 15:04:47 -0700 Subject: [PATCH 431/764] implemented support for properties on functions (#1180) Co-authored-by: Tom --- src/LuaLib.ts | 2 +- src/transformation/builtins/function.ts | 7 +- src/transformation/builtins/index.ts | 4 +- .../utils/language-extensions.ts | 6 + src/transformation/utils/lua-ast.ts | 10 +- src/transformation/utils/typescript/types.ts | 5 +- src/transformation/visitors/function.ts | 59 +++++- .../visitors/variable-declaration.ts | 14 +- .../unit/functions/functionProperties.spec.ts | 175 ++++++++++++++++++ 9 files changed, 264 insertions(+), 18 deletions(-) create mode 100644 test/unit/functions/functionProperties.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 226bbe15c..dd58b8e65 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -103,7 +103,7 @@ const luaLibDependencies: Partial> = { ArrayConcat: [LuaLibFeature.ArrayIsArray], ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], - Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New], + Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise], Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], DelegatedYield: [LuaLibFeature.StringAccess], Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors, LuaLibFeature.Error, LuaLibFeature.New], diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index aefe2a13e..3dfae1428 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -32,7 +32,7 @@ export function transformFunctionPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.FunctionBind, node, caller, ...params); case "call": return lua.createCallExpression(caller, params, node); - default: + case "toString": context.diagnostics.push(unsupportedProperty(expression.name, "function", expressionName)); } } @@ -60,7 +60,10 @@ export function transformFunctionProperty( ? lua.createBinaryExpression(nparams, lua.createNumericLiteral(1), lua.SyntaxKind.SubtractionOperator) : nparams; - default: + case "arguments": + case "caller": + case "displayName": + case "name": context.diagnostics.push(unsupportedProperty(node.name, "function", node.name.text)); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 5795b7619..a067ecde3 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -41,7 +41,7 @@ export function transformBuiltinPropertyAccessExpression( return transformArrayProperty(context, node); } - if (isFunctionType(context, ownerType)) { + if (isFunctionType(ownerType)) { return transformFunctionProperty(context, node); } @@ -131,7 +131,7 @@ export function transformBuiltinCallExpression( return transformArrayPrototypeCall(context, node); } - if (isFunctionType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + if (isFunctionType(ownerType) && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); return transformFunctionPrototypeCall(context, node); } diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 3861cbf57..698dfc021 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -118,6 +118,12 @@ export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): bo return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; } +export function getExtensionKinds(type: ts.Type): ExtensionKind[] { + return (Object.keys(extensionKindToTypeBrand) as Array).filter( + e => type.getProperty(extensionKindToTypeBrand[e]) !== undefined + ); +} + export function isExtensionValue( context: TransformationContext, symbol: ts.Symbol, diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 0670c51fc..9508479ce 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -157,7 +157,9 @@ export function createLocalOrExportedOrGlobalDeclaration( const isTopLevelVariable = scope.type === ScopeType.File; if (context.isModule || !isTopLevelVariable) { - if (!isFunctionDeclaration && hasMultipleReferences(scope, lhs)) { + const isLuaFunctionExpression = rhs && !Array.isArray(rhs) && lua.isFunctionExpression(rhs); + const isSafeRecursiveFunctionDeclaration = isFunctionDeclaration && isLuaFunctionExpression; + if (!isSafeRecursiveFunctionDeclaration && hasMultipleReferences(scope, lhs)) { // Split declaration and assignment of identifiers that reference themselves in their declaration. // Put declaration above preceding statements in case the identifier is referenced in those. const precedingDeclaration = lua.createVariableDeclarationStatement(lhs, undefined, tsOriginal); @@ -166,10 +168,8 @@ export function createLocalOrExportedOrGlobalDeclaration( assignment = lua.createAssignmentStatement(lhs, rhs, tsOriginal); } - if (!isFunctionDeclaration) { - // Remember local variable declarations for hoisting later - addScopeVariableDeclaration(scope, precedingDeclaration); - } + // Remember local variable declarations for hoisting later + addScopeVariableDeclaration(scope, precedingDeclaration); } else { declaration = lua.createVariableDeclarationStatement(lhs, rhs, tsOriginal); diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 2c6e69dcb..74e41db39 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -107,7 +107,6 @@ export function isArrayType(context: TransformationContext, type: ts.Type): bool return forTypeOrAnySupertype(context, type, t => isExplicitArrayType(context, t)); } -export function isFunctionType(context: TransformationContext, type: ts.Type): boolean { - const typeNode = context.checker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.InTypeAlias); - return typeNode !== undefined && ts.isFunctionTypeNode(typeNode); +export function isFunctionType(type: ts.Type): boolean { + return type.getCallSignatures().length > 0; } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index e16bf8401..12fab7d6e 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -6,6 +6,7 @@ import { AnnotationKind, getNodeAnnotations } from "../utils/annotations"; import { annotationRemoved } from "../utils/diagnostics"; import { createDefaultExportStringLiteral, hasDefaultExportModifier } from "../utils/export"; import { ContextType, getFunctionContextType } from "../utils/function-context"; +import { getExtensionKinds } from "../utils/language-extensions"; import { createExportsIdentifier, createLocalOrExportedOrGlobalDeclaration, @@ -15,6 +16,7 @@ import { import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { peekScope, performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; +import { isFunctionType } from "../utils/typescript"; import { isAsyncFunction, wrapInAsyncAwaiter } from "./async-await"; import { transformIdentifier } from "./identifier"; import { transformExpressionBodyToReturnStatement } from "./return"; @@ -51,6 +53,42 @@ function isRestParameterReferenced(identifier: lua.Identifier, scope: Scope): bo return references !== undefined && references.length > 0; } +export function createCallableTable(functionExpression: lua.Expression): lua.Expression { + // __call metamethod receives the table as the first argument, so we need to add a dummy parameter + if (lua.isFunctionExpression(functionExpression)) { + functionExpression.params?.unshift(lua.createAnonymousIdentifier()); + } else { + // functionExpression may have been replaced (lib functions, etc...), + // so we create a forwarding function to eat the extra argument + functionExpression = lua.createFunctionExpression( + lua.createBlock([ + lua.createReturnStatement([lua.createCallExpression(functionExpression, [lua.createDotsLiteral()])]), + ]), + [lua.createAnonymousIdentifier()], + lua.createDotsLiteral(), + lua.FunctionExpressionFlags.Inline + ); + } + return lua.createCallExpression(lua.createIdentifier("setmetatable"), [ + lua.createTableExpression(), + lua.createTableExpression([ + lua.createTableFieldExpression(functionExpression, lua.createStringLiteral("__call")), + ]), + ]); +} + +export function isFunctionTypeWithProperties(functionType: ts.Type) { + if (functionType.isUnion()) { + return functionType.types.some(isFunctionTypeWithProperties); + } else { + return ( + isFunctionType(functionType) && + functionType.getProperties().length > 0 && + getExtensionKinds(functionType).length === 0 // ignore TSTL extension functions like $range + ); + } +} + export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { const [precedingStatements, returnStatement] = transformInPrecedingStatementScope(context, () => @@ -251,9 +289,16 @@ export function transformFunctionLikeDeclaration( // Only handle if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); - context.addPrecedingStatements( - lua.createVariableDeclarationStatement(nameIdentifier, functionExpression) - ); + if (isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))) { + context.addPrecedingStatements([ + lua.createVariableDeclarationStatement(nameIdentifier), + lua.createAssignmentStatement(nameIdentifier, createCallableTable(functionExpression)), + ]); + } else { + context.addPrecedingStatements( + lua.createVariableDeclarationStatement(nameIdentifier, functionExpression) + ); + } return lua.cloneIdentifier(nameIdentifier); } } @@ -295,7 +340,13 @@ export const transformFunctionDeclaration: FunctionVisitor = (expression, context) => { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index a7e4a36ca..e7e604404 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -8,6 +8,7 @@ import { addExportToIdentifier } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { createCallableTable, isFunctionTypeWithProperties } from "./function"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; @@ -257,7 +258,18 @@ export function transformVariableDeclaration( // Find variable identifier const identifierName = transformIdentifier(context, statement.name); const value = statement.initializer && context.transformExpression(statement.initializer); - return createLocalOrExportedOrGlobalDeclaration(context, identifierName, value, statement); + + // Wrap functions being assigned to a type that contains additional properties in a callable table + // This catches 'const foo = function() {}; foo.bar = "FOOBAR";' + const wrappedValue = + value && + // Skip named function expressions because they will have been wrapped already + !(statement.initializer && ts.isFunctionExpression(statement.initializer) && statement.initializer.name) && + isFunctionTypeWithProperties(context.checker.getTypeAtLocation(statement.name)) + ? createCallableTable(value) + : value; + + return createLocalOrExportedOrGlobalDeclaration(context, identifierName, wrappedValue, statement); } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { return transformBindingVariableDeclaration(context, statement.name, statement.initializer); } else { diff --git a/test/unit/functions/functionProperties.spec.ts b/test/unit/functions/functionProperties.spec.ts new file mode 100644 index 000000000..85cdf9e31 --- /dev/null +++ b/test/unit/functions/functionProperties.spec.ts @@ -0,0 +1,175 @@ +import * as util from "../../util"; + +test("property on function", () => { + util.testFunction` + function foo(s: string) { return s; } + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("property on void function", () => { + util.testFunction` + function foo(this: void, s: string) { return s; } + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("property on recursively referenced function", () => { + util.testFunction` + function foo(s: string) { return s + foo.bar; } + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("property on hoisted function", () => { + util.testFunction` + foo.bar = "bar"; + function foo(s: string) { return s; } + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("function merged with namespace", () => { + util.testModule` + function foo(s: string) { return s; } + namespace foo { + export let bar = "bar"; + } + export const result = foo("foo") + foo.bar; + ` + .setReturnExport("result") + .expectToEqual("foobar"); +}); + +test("function with property assigned to variable", () => { + util.testFunction` + const foo = function(s: string) { return s; }; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("void function with property assigned to variable", () => { + util.testFunction` + const foo = function(this: void, s: string) { return s; }; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("recursively referenced function with property assigned to variable", () => { + util.testFunction` + const foo = function(s: string) { return s + foo.bar; }; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("named recursively referenced function with property assigned to variable", () => { + util.testFunction` + const foo = function baz(s: string) { return s + foo.bar + baz.bar; }; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("arrow function with property assigned to variable", () => { + util.testFunction` + const foo: { (s: string): string; bar: string; } = s => s; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("void arrow function with property assigned to variable", () => { + util.testFunction` + const foo: { (this: void, s: string): string; bar: string; } = s => s; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("recursively referenced arrow function with property assigned to variable", () => { + util.testFunction` + const foo: { (s: string): string; bar: string; } = s => s + foo.bar; + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + +test("property on generator function", () => { + util.testFunction` + function *foo(s: string) { yield s; } + foo.bar = "bar"; + for (const s of foo("foo")) { + return s + foo.bar; + } + `.expectToMatchJsResult(); +}); + +test("generator function assigned to variable", () => { + util.testFunction` + const foo = function *(s: string) { yield s; } + foo.bar = "bar"; + for (const s of foo("foo")) { + return s + foo.bar; + } + `.expectToMatchJsResult(); +}); + +test("property on async function", () => { + util.testFunction` + let result = ""; + async function foo(s: string) { result = s + foo.bar; } + foo.bar = "bar"; + void foo("foo"); + return result; + `.expectToMatchJsResult(); +}); + +test("async function with property assigned to variable", () => { + util.testFunction` + let result = ""; + const foo = async function(s: string) { result = s + foo.bar; } + foo.bar = "bar"; + void foo("foo"); + return result; + `.expectToMatchJsResult(); +}); + +test("async arrow function with property assigned to variable", () => { + util.testFunction` + let result = ""; + const foo: { (s: string): Promise; bar: string; } = async s => { result = s + foo.bar; }; + foo.bar = "bar"; + void foo("foo"); + return result; + `.expectToMatchJsResult(); +}); + +test("call function with property using call method", () => { + util.testFunction` + function foo(s: string) { return this + s; } + foo.baz = "baz"; + return foo.call("foo", "bar") + foo.baz; + `.expectToMatchJsResult(); +}); + +test("call function with property using apply method", () => { + util.testFunction` + function foo(s: string) { return this + s; } + foo.baz = "baz"; + return foo.apply("foo", ["bar"]) + foo.baz; + `.expectToMatchJsResult(); +}); + +test("call function with property using bind method", () => { + util.testFunction` + function foo(s: string) { return this + s; } + foo.baz = "baz"; + return foo.bind("foo", "bar")() + foo.baz; + `.expectToMatchJsResult(); +}); From 3eae0a292ff7e425107a707433a0e27a703b62db Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Mon, 6 Dec 2021 10:36:24 -0700 Subject: [PATCH 432/764] added LuaPairsIterable extension (#1176) Co-authored-by: Tom --- language-extensions/index.d.ts | 12 +- src/transformation/utils/diagnostics.ts | 4 + .../utils/language-extensions.ts | 2 + .../language-extensions/pairsIterable.ts | 63 +++++++++ src/transformation/visitors/loops/for-of.ts | 3 + .../__snapshots__/pairsIterable.spec.ts.snap | 26 ++++ .../language-extensions/pairsIterable.spec.ts | 120 ++++++++++++++++++ test/unit/language-extensions/table.spec.ts | 16 +++ 8 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 src/transformation/visitors/language-extensions/pairsIterable.ts create mode 100644 test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap create mode 100644 test/unit/language-extensions/pairsIterable.spec.ts diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 30eb70009..8c30e1a8d 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -78,6 +78,16 @@ declare type LuaIterable = Iterable & LuaIterator & LuaExtension<"__luaIterableBrand">; +/** + * Represents an object that can be iterated with pairs() + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TKey The type of the key returned each iteration. + * @param TValue The type of the value returned each iteration. + */ +declare type LuaPairsIterable = Iterable<[TKey, TValue]> & + LuaExtension<"__luaPairsIterableBrand">; + /** * Calls to functions with this type are translated to `left + right`. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -535,7 +545,7 @@ declare type LuaTableDeleteMethod = ((key: TKey) => bool * @param TKey The type of the keys used to access the table. * @param TValue The type of the values stored in the table. */ -declare interface LuaTable { +declare interface LuaTable extends LuaPairsIterable { length: LuaLengthMethod; get: LuaTableGetMethod; set: LuaTableSetMethod; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index ca8ae0320..af5138fd6 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -72,6 +72,10 @@ export const invalidMultiIterableWithoutDestructuring = createErrorDiagnosticFac "LuaIterable with a LuaMultiReturn return value type must be destructured." ); +export const invalidPairsIterableWithoutDestructuring = createErrorDiagnosticFactory( + "LuaPairsIterable type must be destructured in a for...of statement." +); + export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( "Accessors in object literal are not supported." ); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 698dfc021..a98844c7b 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -7,6 +7,7 @@ export enum ExtensionKind { RangeFunction = "RangeFunction", VarargConstant = "VarargConstant", IterableType = "IterableType", + PairsIterableType = "PairsIterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -66,6 +67,7 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", [ExtensionKind.IterableType]: "__luaIterableBrand", + [ExtensionKind.PairsIterableType]: "__luaPairsIterableBrand", [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", diff --git a/src/transformation/visitors/language-extensions/pairsIterable.ts b/src/transformation/visitors/language-extensions/pairsIterable.ts new file mode 100644 index 000000000..0874952cf --- /dev/null +++ b/src/transformation/visitors/language-extensions/pairsIterable.ts @@ -0,0 +1,63 @@ +import * as ts from "typescript"; +import * as lua from "../../../LuaAST"; +import { cast } from "../../../utils"; +import { TransformationContext } from "../../context"; +import { invalidPairsIterableWithoutDestructuring } from "../../utils/diagnostics"; +import * as extensions from "../../utils/language-extensions"; +import { getVariableDeclarationBinding } from "../loops/utils"; +import { transformArrayBindingElement } from "../variable-declaration"; + +function isPairsIterableType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.PairsIterableType); +} + +export function isPairsIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { + const type = context.checker.getTypeAtLocation(expression); + return isPairsIterableType(type); +} + +export function transformForOfPairsIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ + context.transformExpression(statement.expression), + ]); + + let identifiers: lua.Identifier[] = []; + + if (ts.isVariableDeclarationList(statement.initializer)) { + // Variables declared in for loop + // for key, value in iterable do + const binding = getVariableDeclarationBinding(context, statement.initializer); + if (ts.isArrayBindingPattern(binding)) { + identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); + } else { + context.diagnostics.push(invalidPairsIterableWithoutDestructuring(binding)); + } + } else if (ts.isArrayLiteralExpression(statement.initializer)) { + // Variables NOT declared in for loop - catch iterator values in temps and assign + // for ____key, ____value in iterable do + // key, value = ____key, ____value + identifiers = statement.initializer.elements.map(e => context.createTempNameForNode(e)); + if (identifiers.length > 0) { + block.statements.unshift( + lua.createAssignmentStatement( + statement.initializer.elements.map(e => + cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) + ), + identifiers + ) + ); + } + } else { + context.diagnostics.push(invalidPairsIterableWithoutDestructuring(statement.initializer)); + } + + if (identifiers.length === 0) { + identifiers.push(lua.createAnonymousIdentifier()); + } + + return lua.createForInStatement(block, identifiers, [pairsCall], statement); +} diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 64d2c211b..6380423f1 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -6,6 +6,7 @@ import { annotationRemoved } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType } from "../../utils/typescript"; import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; +import { isPairsIterableExpression, transformForOfPairsIterableStatement } from "../language-extensions/pairsIterable"; import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformForInitializer, transformLoopBody } from "./utils"; @@ -47,6 +48,8 @@ export const transformForOfStatement: FunctionVisitor = (node context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.ForRange)); } else if (isIterableExpression(context, node.expression)) { return transformForOfIterableStatement(context, node, body); + } else if (isPairsIterableExpression(context, node.expression)) { + return transformForOfPairsIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { diff --git a/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap new file mode 100644 index 000000000..b54b0de77 --- /dev/null +++ b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap @@ -0,0 +1,26 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIterable) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + for ____ in pairs(testIterable) do + end +end +return ____exports" +`; + +exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIterable) {}"): diagnostics 1`] = `"main.ts(5,20): error TSTL: LuaPairsIterable type must be destructured in a for...of statement."`; + +exports[`invalid LuaPairsIterable without destructuring ("let s; for (s of testIterable) {}"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + local s + for ____ in pairs(testIterable) do + end +end +return ____exports" +`; + +exports[`invalid LuaPairsIterable without destructuring ("let s; for (s of testIterable) {}"): diagnostics 1`] = `"main.ts(5,21): error TSTL: LuaPairsIterable type must be destructured in a for...of statement."`; diff --git a/test/unit/language-extensions/pairsIterable.spec.ts b/test/unit/language-extensions/pairsIterable.spec.ts new file mode 100644 index 000000000..3fd2e0d85 --- /dev/null +++ b/test/unit/language-extensions/pairsIterable.spec.ts @@ -0,0 +1,120 @@ +import * as util from "../../util"; +import { invalidPairsIterableWithoutDestructuring } from "../../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../../src"; + +const testIterable = ` +const testIterable = {a1: "a2", b1: "b2", c1: "c2"} as unknown as LuaPairsIterable; +`; + +const testResults = { + a1: "a2", + b1: "b2", + c1: "c2", +}; + +test("pairs iterable", () => { + util.testFunction` + ${testIterable} + const results: Record = {}; + for (const [k, v] of testIterable) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); +}); + +test("pairs iterable with external control variable", () => { + util.testFunction` + ${testIterable} + const results: Record = {}; + let k: string, v: string; + for ([k, v] of testIterable) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); +}); + +test("pairs iterable function forward", () => { + util.testFunction` + ${testIterable} + function forward() { return testIterable; } + const results: Record = {}; + for (const [k, v] of forward()) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); +}); + +test("pairs iterable function indirect forward", () => { + util.testFunction` + ${testIterable} + function forward() { const iter = testIterable; return iter; } + const results: Record = {}; + for (const [k, v] of forward()) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); +}); + +test("pairs iterable arrow function forward", () => { + util.testFunction` + ${testIterable} + const forward = () => testIterable; + const results: Record = {}; + for (const [k, v] of forward()) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual(testResults); +}); + +test("pairs iterable with __pairs metamethod", () => { + util.testFunction` + class PairsTest { + __pairs() { + const kvp = [ ["a1", "a2"], ["b1", "b2"], ["c1", "c2"] ]; + let i = 0; + return () => { + if (i < kvp.length) { + const [k, v] = kvp[i++]; + return $multi(k, v); + } + }; + } + } + const tester = new PairsTest() as PairsTest & LuaPairsIterable; + const results: Record = {}; + for (const [k, v] of tester) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .setOptions({ luaTarget: LuaTarget.Lua53 }) + .expectToEqual(testResults); +}); + +test.each(["for (const s of testIterable) {}", "let s; for (s of testIterable) {}"])( + "invalid LuaPairsIterable without destructuring (%p)", + statement => { + util.testFunction` + ${testIterable} + ${statement} + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidPairsIterableWithoutDestructuring.code]); + } +); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 0c652dca9..eeba4b921 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -325,4 +325,20 @@ describe("LuaTable extension interface", () => { util.testFunction(statement).withLanguageExtensions().expectToHaveNoDiagnostics(); } ); + + test("table pairs iterate", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + tbl.set("bar", 3); + tbl.set("baz", 5); + const results: Record = {}; + for (const [k, v] of tbl) { + results[k] = v; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ foo: 1, bar: 3, baz: 5 }); + }); }); From 2df70475acd06447348d7640f7362543f0313231 Mon Sep 17 00:00:00 2001 From: Tom <26638278+tomblind@users.noreply.github.com> Date: Sun, 12 Dec 2021 12:34:13 -0700 Subject: [PATCH 433/764] Support for unicode identifiers when targetting LuaJIT (#1187) implements #1117 Co-authored-by: Tom --- src/LuaPrinter.ts | 11 +- src/transformation/utils/safe-names.ts | 18 +- src/transformation/visitors/call.ts | 2 +- src/transformation/visitors/class/index.ts | 2 +- src/transformation/visitors/namespace.ts | 2 +- .../__snapshots__/identifiers.spec.ts.snap | 180 ++++++++++++++++++ test/unit/identifiers.spec.ts | 63 ++++++ 7 files changed, 266 insertions(+), 12 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 542b55e10..dc75b4a9b 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -5,7 +5,7 @@ import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; -import { isValidLuaIdentifier } from "./transformation/utils/safe-names"; +import { isValidLuaIdentifier, shouldAllowUnicode } from "./transformation/utils/safe-names"; import { EmitHost } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; @@ -34,7 +34,8 @@ export const tstlHeader = "--[[ Generated with https://github.com/TypeScriptToLu * `foo.bar` => passes (`function foo.bar()` is valid) * `getFoo().bar` => fails (`function getFoo().bar()` would be illegal) */ -const isValidLuaFunctionDeclarationName = (str: string) => /^[a-zA-Z0-9_.]+$/.test(str); +const isValidLuaFunctionDeclarationName = (str: string, options: CompilerOptions) => + (shouldAllowUnicode(options) ? /^[a-zA-Z0-9_\u00FF-\uFFFD.]+$/ : /^[a-zA-Z0-9_.]+$/).test(str); /** * Returns true if expression contains no function calls. @@ -439,7 +440,7 @@ export class LuaPrinter { ) { // Use `function foo()` instead of `foo = function()` const name = this.printExpression(statement.left[0]); - if (isValidLuaFunctionDeclarationName(name.toString())) { + if (isValidLuaFunctionDeclarationName(name.toString(), this.options)) { chunks.push(this.printFunctionDefinition(statement)); return this.createSourceNode(statement, chunks); } @@ -692,7 +693,7 @@ export class LuaPrinter { const value = this.printExpression(expression.value); if (expression.key) { - if (lua.isStringLiteral(expression.key) && isValidLuaIdentifier(expression.key.value)) { + if (lua.isStringLiteral(expression.key) && isValidLuaIdentifier(expression.key.value, this.options)) { chunks.push(expression.key.value, " = ", value); } else { chunks.push("[", this.printExpression(expression.key), "] = ", value); @@ -804,7 +805,7 @@ export class LuaPrinter { const chunks: SourceChunk[] = []; chunks.push(this.printExpressionInParenthesesIfNeeded(expression.table)); - if (lua.isStringLiteral(expression.index) && isValidLuaIdentifier(expression.index.value)) { + if (lua.isStringLiteral(expression.index) && isValidLuaIdentifier(expression.index.value, this.options)) { chunks.push(".", this.createSourceNode(expression.index, expression.index.value)); } else { chunks.push("[", this.printExpression(expression.index), "]"); diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index 877196ba4..638afdb91 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -1,10 +1,19 @@ import * as ts from "typescript"; +import { CompilerOptions, LuaTarget } from "../.."; import { TransformationContext } from "../context"; import { invalidAmbientIdentifierName } from "./diagnostics"; import { isSymbolExported } from "./export"; import { isAmbientNode } from "./typescript"; -export const isValidLuaIdentifier = (name: string) => !luaKeywords.has(name) && /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name); +export const shouldAllowUnicode = (options: CompilerOptions) => options.luaTarget === LuaTarget.LuaJIT; + +export const isValidLuaIdentifier = (name: string, options: CompilerOptions) => + !luaKeywords.has(name) && + (shouldAllowUnicode(options) + ? /^[a-zA-Z_\u007F-\uFFFD][a-zA-Z0-9_\u007F-\uFFFD]*$/ + : /^[a-zA-Z_][a-zA-Z0-9_]*$/ + ).test(name); + export const luaKeywords: ReadonlySet = new Set([ "and", "break", @@ -52,10 +61,11 @@ const luaBuiltins: ReadonlySet = new Set([ "unpack", ]); -export const isUnsafeName = (name: string) => !isValidLuaIdentifier(name) || luaBuiltins.has(name); +export const isUnsafeName = (name: string, options: CompilerOptions) => + !isValidLuaIdentifier(name, options) || luaBuiltins.has(name); function checkName(context: TransformationContext, name: string, node: ts.Node): boolean { - const isInvalid = !isValidLuaIdentifier(name); + const isInvalid = !isValidLuaIdentifier(name, context.options); if (isInvalid) { // Empty identifier is a TypeScript error @@ -80,7 +90,7 @@ export function hasUnsafeSymbolName( } // only unsafe when non-ambient and not exported - return isUnsafeName(symbol.name) && !isAmbient && !isSymbolExported(context, symbol); + return isUnsafeName(symbol.name, context.options) && !isAmbient && !isSymbolExported(context, symbol); } export function hasUnsafeIdentifierName( diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index c10c08e28..3f04d857e 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -149,7 +149,7 @@ export function transformContextualCallExpression( if ( ts.isPropertyAccessExpression(left) && ts.isIdentifier(left.name) && - isValidLuaIdentifier(left.name.text) && + isValidLuaIdentifier(left.name.text, context.options) && argPrecedingStatements.length === 0 ) { // table:name() diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 0ea562fa4..f43b349e5 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -99,7 +99,7 @@ function transformClassLikeDeclaration( const result: lua.Statement[] = []; let localClassName: lua.Identifier; - if (isUnsafeName(className.text)) { + if (isUnsafeName(className.text, context.options)) { localClassName = lua.createIdentifier( createSafeName(className.text), undefined, diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index d41aefd75..3f41d81b1 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -18,7 +18,7 @@ export function createModuleLocalNameIdentifier( declaration: ts.ModuleDeclaration ): lua.Identifier { const moduleSymbol = context.checker.getSymbolAtLocation(declaration.name); - if (moduleSymbol !== undefined && isUnsafeName(moduleSymbol.name)) { + if (moduleSymbol !== undefined && isUnsafeName(moduleSymbol.name, context.options)) { return lua.createIdentifier( createSafeName(declaration.name.text), declaration.name, diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index d955068e5..8af819bc0 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -247,3 +247,183 @@ exports[`undeclared identifier must be a valid lua identifier (object literal sh exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {foo = \\"foobar\\"} + local _̀ः٠‿ = ____temp_0.foo + return _̀ः٠‿ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {foo = \\"foobar\\"} + local ɥɣɎɌͼƛಠ = ____temp_0.foo + return ɥɣɎɌͼƛಠ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {foo = \\"foobar\\"} + local 𝛼𝛽𝚫 = ____temp_0.foo + return 𝛼𝛽𝚫 +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {_̀ः٠‿ = \\"foobar\\"} + local _̀ः٠‿ = ____temp_0._̀ः٠‿ + return _̀ः٠‿ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + local ɥɣɎɌͼƛಠ = ____temp_0.ɥɣɎɌͼƛಠ + return ɥɣɎɌͼƛಠ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ____temp_0 = {𝛼𝛽𝚫 = \\"foobar\\"} + local 𝛼𝛽𝚫 = ____temp_0.𝛼𝛽𝚫 + return 𝛼𝛽𝚫 +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) function ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function _̀ः٠‿(self, arg) + return \\"foo\\" .. arg + end + return _̀ः٠‿(nil, \\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) function ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function ɥɣɎɌͼƛಠ(self, arg) + return \\"foo\\" .. arg + end + return ɥɣɎɌͼƛಠ(nil, \\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) function ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function 𝛼𝛽𝚫(self, arg) + return \\"foo\\" .. arg + end + return 𝛼𝛽𝚫(nil, \\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) identifier name ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local _̀ः٠‿ = \\"foobar\\" + return _̀ः٠‿ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) identifier name ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local ɥɣɎɌͼƛಠ = \\"foobar\\" + return ɥɣɎɌͼƛಠ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) identifier name ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local 𝛼𝛽𝚫 = \\"foobar\\" + return 𝛼𝛽𝚫 +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) method ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local foo = {_̀ः٠‿ = function(self, arg) + return \\"foo\\" .. arg + end} + return foo:_̀ः٠‿(\\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) method ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local foo = {ɥɣɎɌͼƛಠ = function(self, arg) + return \\"foo\\" .. arg + end} + return foo:ɥɣɎɌͼƛಠ(\\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) method ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local foo = {𝛼𝛽𝚫 = function(self, arg) + return \\"foo\\" .. arg + end} + return foo:𝛼𝛽𝚫(\\"bar\\") +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) property name ("_̀ः٠‿") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = {_̀ः٠‿ = \\"foobar\\"} + return x._̀ः٠‿ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) property name ("ɥɣɎɌͼƛಠ") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + return x.ɥɣɎɌͼƛಠ +end +return ____exports" +`; + +exports[`unicode identifiers in supporting environments (luajit) property name ("𝛼𝛽𝚫") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local x = {𝛼𝛽𝚫 = \\"foobar\\"} + return x.𝛼𝛽𝚫 +end +return ____exports" +`; diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 9f72ad671..7c0722938 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -1,3 +1,4 @@ +import { LuaTarget } from "../../src"; import { invalidAmbientIdentifierName } from "../../src/transformation/utils/diagnostics"; import { luaKeywords } from "../../src/transformation/utils/safe-names"; import * as util from "../util"; @@ -222,6 +223,68 @@ test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua nam .expectToMatchJsResult(); }); +describe("unicode identifiers in supporting environments (luajit)", () => { + const unicodeNames = ["𝛼𝛽𝚫", "ɥɣɎɌͼƛಠ", "_̀ः٠‿"]; + + test.each(unicodeNames)("identifier name (%p)", name => { + util.testFunction` + const ${name} = "foobar"; + return ${name}; + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); + + test.each(unicodeNames)("property name (%p)", name => { + util.testFunction` + const x = { ${name}: "foobar" }; + return x.${name}; + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); + + test.each(unicodeNames)("destructuring property name (%p)", name => { + util.testFunction` + const { foo: ${name} } = { foo: "foobar" }; + return ${name}; + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); + + test.each(unicodeNames)("destructuring shorthand (%p)", name => { + util.testFunction` + const { ${name} } = { ${name}: "foobar" }; + return ${name}; + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); + + test.each(unicodeNames)("function (%p)", name => { + util.testFunction` + function ${name}(arg: string) { + return "foo" + arg; + } + return ${name}("bar"); + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); + + test.each(unicodeNames)("method (%p)", name => { + util.testFunction` + const foo = { + ${name}(arg: string) { return "foo" + arg; } + }; + return foo.${name}("bar"); + ` + .setOptions({ luaTarget: LuaTarget.LuaJIT }) + .expectLuaToMatchSnapshot(); + }); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { util.testFunction` From 976ed2f8a435bba55381f12c05bb5b352d3ded06 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Mon, 20 Dec 2021 13:07:34 -0800 Subject: [PATCH 434/764] Fix assignment to undefined globals in try catch with no return (#1192) --- src/transformation/visitors/errors.ts | 31 ++++++++++++++++----------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 2b58428b2..1dc4995e4 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -44,31 +44,38 @@ export const transformTryStatement: FunctionVisitor = (statemen const catchParameter = statement.catchClause.variableDeclaration ? transformIdentifier(context, statement.catchClause.variableDeclaration.name as ts.Identifier) : undefined; - const catchParameters = () => (catchParameter ? [lua.cloneIdentifier(catchParameter)] : []); - + const catchFunction = lua.createFunctionExpression( + catchBlock, + catchParameter ? [lua.cloneIdentifier(catchParameter)] : [] + ); const catchIdentifier = lua.createIdentifier("____catch"); - const catchFunction = lua.createFunctionExpression(catchBlock, catchParameters()); result.push(lua.createVariableDeclarationStatement(catchIdentifier, catchFunction)); + const hasReturn = tryScope.functionReturned ?? catchScope.functionReturned; + const tryReturnIdentifiers = [tryResultIdentifier]; // ____try - if (returnedIdentifier) { - tryReturnIdentifiers.push(returnedIdentifier); // ____returned or catch variable - if (tryScope.functionReturned || catchScope.functionReturned) { + if (hasReturn || statement.catchClause.variableDeclaration) { + tryReturnIdentifiers.push(returnedIdentifier); // ____returned + if (hasReturn) { tryReturnIdentifiers.push(returnValueIdentifier); // ____returnValue returnCondition = lua.cloneIdentifier(returnedIdentifier); } } result.push(lua.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); - // Wrap catch in function if try or catch has return - const catchCall = lua.createCallExpression(catchIdentifier, [lua.cloneIdentifier(returnedIdentifier)]); - const catchAssign = lua.createAssignmentStatement( - [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], - catchCall + const catchCall = lua.createCallExpression( + catchIdentifier, + statement.catchClause.variableDeclaration ? [lua.cloneIdentifier(returnedIdentifier)] : [] ); + const catchCallStatement = hasReturn + ? lua.createAssignmentStatement( + [lua.cloneIdentifier(returnedIdentifier), lua.cloneIdentifier(returnValueIdentifier)], + catchCall + ) + : lua.createExpressionStatement(catchCall); const notTryCondition = lua.createUnaryExpression(tryResultIdentifier, lua.SyntaxKind.NotOperator); - result.push(lua.createIfStatement(notTryCondition, lua.createBlock([catchAssign]))); + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([catchCallStatement]))); } else if (tryScope.functionReturned) { // try with return, but no catch // returnedIdentifier = lua.createIdentifier("____returned"); From 2429e267de93be229aa83ac6508dec75e5a6e4c2 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 21 Dec 2021 13:18:58 -0800 Subject: [PATCH 435/764] Fix nullish coalescing and conditionals when using generics (#1191) * Fix nullish coalescing and conditionals when using generics * Clarify strictNullChecks option in test case --- src/transformation/utils/typescript/types.ts | 52 +++++++++++++++---- .../visitors/binary-expression/index.ts | 7 +-- src/transformation/visitors/conditional.ts | 24 +-------- test/unit/conditionals.spec.ts | 13 +++++ test/unit/nullishCoalescing.spec.ts | 11 +++- 5 files changed, 69 insertions(+), 38 deletions(-) diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 74e41db39..cb1af0824 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -2,15 +2,7 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; export function isTypeWithFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { - const predicate = (type: ts.Type) => { - if (type.symbol) { - const baseConstraint = context.checker.getBaseConstraintOfType(type); - if (baseConstraint && baseConstraint !== type) { - return isTypeWithFlags(context, baseConstraint, flags); - } - } - return (type.flags & flags) !== 0; - }; + const predicate = (type: ts.Type) => (type.flags & flags) !== 0; return typeAlwaysSatisfies(context, type, predicate); } @@ -20,6 +12,11 @@ export function typeAlwaysSatisfies( type: ts.Type, predicate: (type: ts.Type) => boolean ): boolean { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint) { + type = baseConstraint; + } + if (predicate(type)) { return true; } @@ -40,6 +37,14 @@ export function typeCanSatisfy( type: ts.Type, predicate: (type: ts.Type) => boolean ): boolean { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (!baseConstraint) { + // type parameter with no constraint can be anything, assume it might satisfy predicate + if (type.isTypeParameter()) return true; + } else { + type = baseConstraint; + } + if (predicate(type)) { return true; } @@ -110,3 +115,32 @@ export function isArrayType(context: TransformationContext, type: ts.Type): bool export function isFunctionType(type: ts.Type): boolean { return type.getCallSignatures().length > 0; } + +export function canBeFalsy(context: TransformationContext, type: ts.Type): boolean { + const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; + const falsyFlags = + ts.TypeFlags.Boolean | + ts.TypeFlags.BooleanLiteral | + ts.TypeFlags.Never | + ts.TypeFlags.Void | + ts.TypeFlags.Unknown | + ts.TypeFlags.Any | + ts.TypeFlags.Undefined | + ts.TypeFlags.Null; + return typeCanSatisfy( + context, + type, + type => (type.flags & falsyFlags) !== 0 || (!strictNullChecks && !type.isLiteral()) + ); +} + +export function canBeFalsyWhenNotNull(context: TransformationContext, type: ts.Type): boolean { + const falsyFlags = + ts.TypeFlags.Boolean | + ts.TypeFlags.BooleanLiteral | + ts.TypeFlags.Never | + ts.TypeFlags.Void | + ts.TypeFlags.Unknown | + ts.TypeFlags.Any; + return typeCanSatisfy(context, type, type => (type.flags & falsyFlags) !== 0); +} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 330f51e7d..ba292d126 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { wrapInToStringForConcat } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; -import { isStandardLibraryType, isStringType, typeCanSatisfy } from "../../utils/typescript"; +import { canBeFalsyWhenNotNull, isStandardLibraryType, isStringType } from "../../utils/typescript"; import { transformTypeOfBinaryExpression } from "../typeof"; import { transformAssignmentExpression, transformAssignmentStatement } from "./assignments"; import { BitOperator, isBitOperator, transformBinaryBitOperation } from "./bit"; @@ -269,10 +269,7 @@ function transformNullishCoalescingOperationNoPrecedingStatements( const lhsType = context.checker.getTypeAtLocation(node.left); // Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'. - const typeCanBeFalse = (type: ts.Type) => - (type.flags & (ts.TypeFlags.Any | ts.TypeFlags.Unknown | ts.TypeFlags.Boolean)) !== 0 || - (type.flags & ts.TypeFlags.BooleanLiteral & ts.TypeFlags.PossiblyFalsy) !== 0; - if (typeCanSatisfy(context, lhsType, typeCanBeFalse)) { + if (canBeFalsyWhenNotNull(context, lhsType)) { // reuse logic from case with preceding statements const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements( context, diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index f83837a2d..518f658e5 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -4,29 +4,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; - -function canBeFalsy(context: TransformationContext, type: ts.Type): boolean { - const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; - - const falsyFlags = - ts.TypeFlags.Boolean | - ts.TypeFlags.BooleanLiteral | - ts.TypeFlags.Undefined | - ts.TypeFlags.Null | - ts.TypeFlags.Never | - ts.TypeFlags.Void | - ts.TypeFlags.Any; - - if (type.flags & falsyFlags) { - return true; - } else if (!strictNullChecks && !type.isLiteral()) { - return true; - } else if (type.isUnion()) { - return type.types.some(subType => canBeFalsy(context, subType)); - } else { - return false; - } -} +import { canBeFalsy } from "../utils/typescript"; function transformProtectedConditionalExpression( context: TransformationContext, diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index c9717d0c0..738ecacc1 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -99,3 +99,16 @@ test.each(["true", "false", "a < 4", "a == 8"])("Ternary Conditional Delayed (%p return delay(); `.expectToMatchJsResult(); }); + +test.each([false, true, null])("Ternary conditional with generic whenTrue branch (%p)", trueVal => { + util.testFunction` + function ternary(a: boolean, b: B, c: C) { + return a ? b : c + } + return ternary(true, ${trueVal}, "wasFalse") + ` + .setOptions({ + strictNullChecks: true, + }) + .expectToMatchJsResult(); +}); diff --git a/test/unit/nullishCoalescing.spec.ts b/test/unit/nullishCoalescing.spec.ts index 309e43732..3728f2815 100644 --- a/test/unit/nullishCoalescing.spec.ts +++ b/test/unit/nullishCoalescing.spec.ts @@ -43,7 +43,7 @@ test("nullish-coalescing operator with side effect rhs", () => { test("nullish-coalescing operator with vararg", () => { util.testFunction` - + function foo(...args: any[]){ return args } @@ -54,3 +54,12 @@ test("nullish-coalescing operator with vararg", () => { return bar(1, 2) `.expectToMatchJsResult(); }); + +test.each([true, false, null])("nullish-coalescing with generic lhs (%p)", lhs => { + util.testFunction` + function coalesce(a: A, b: B) { + return a ?? b + } + return coalesce(${lhs}, "wasNull") + `.expectToMatchJsResult(); +}); From c8d8c73d137604832537b1efd303690853cebe06 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 21 Dec 2021 13:19:26 -0800 Subject: [PATCH 436/764] Fix optimized vararg spread with casts (#1193) Also fixes for other outer expressions. --- src/transformation/visitors/spread.ts | 22 ++++++++++++++------- src/typescript-internal.d.ts | 12 ++++++++--- test/unit/__snapshots__/spread.spec.ts.snap | 15 ++++++++++++++ test/unit/spread.spec.ts | 12 +++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index f8ebdc79d..455f25fbf 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -16,8 +16,15 @@ import { isMultiReturnCall } from "./language-extensions/multi"; import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; +function skipOuterExpressionParents(node: ts.Node) { + while (ts.isOuterExpression(node)) { + node = node.parent; + } + return node; +} + export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { - if (!ts.isSpreadElement(identifier.parent)) { + if (!ts.isSpreadElement(skipOuterExpressionParents(identifier.parent))) { return false; } @@ -63,20 +70,21 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: // TODO: Currently it's also used as an array member export const transformSpreadElement: FunctionVisitor = (node, context) => { - if (ts.isIdentifier(node.expression)) { - if (isVarargType(context, node.expression)) { + const tsInnerExpression = ts.skipOuterExpressions(node.expression); + if (ts.isIdentifier(tsInnerExpression)) { + if (isVarargType(context, tsInnerExpression)) { context.diagnostics.push(annotationRemoved(node, AnnotationKind.Vararg)); } - const symbol = context.checker.getSymbolAtLocation(node.expression); - if (symbol && isOptimizedVarArgSpread(context, symbol, node.expression)) { + const symbol = context.checker.getSymbolAtLocation(tsInnerExpression); + if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) { return lua.createDotsLiteral(node); } } const innerExpression = context.transformExpression(node.expression); - if (isMultiReturnCall(context, node.expression)) return innerExpression; + if (isMultiReturnCall(context, tsInnerExpression)) return innerExpression; - const type = context.checker.getTypeAtLocation(node.expression); + const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts if (isArrayType(context, type)) { return createUnpackCall(context, innerExpression, node); } diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index a10bf1fc2..1a73ebb82 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -1,5 +1,4 @@ import { DiagnosticsProducingTypeChecker } from "./transformation/context"; - export {}; declare module "typescript" { @@ -31,6 +30,13 @@ declare module "typescript" { function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; - function skipParentheses(node: Expression): Expression; - function skipParentheses(node: Node): Node; + export type OuterExpression = + | ParenthesizedExpression + | TypeAssertion + | AsExpression + | NonNullExpression + | PartiallyEmittedExpression; + + function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; + export function isOuterExpression(node: Node, kinds?: OuterExpressionKinds): node is OuterExpression; } diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index d27ea931d..e0ef21233 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -17,6 +17,21 @@ end return ____exports" `; +exports[`vararg spread optimization With cast 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function pick(self, ...) + local args = {...} + return args[2] + end + local function test(self, ...) + return pick(nil, ...) + end + return test(nil, \\"a\\", \\"b\\", \\"c\\") +end +return ____exports" +`; + exports[`vararg spread optimization basic use 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 6b29d0cae..c3fe72b07 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -265,6 +265,18 @@ describe("vararg spread optimization", () => { .expectLuaToMatchSnapshot() .expectToMatchJsResult(); }); + + test("With cast", () => { + util.testFunction` + function pick(...args: any[]) { return args[1]; } + function testany>(...args: Parameters) { + return pick(...(args as any[])); + } + return test<(...args: string[])=>void>("a", "b", "c"); + ` + .expectLuaToMatchSnapshot() + .expectToMatchJsResult(); + }); }); describe("vararg spread de-optimization", () => { From 4bd18722e048b95fd058eb3295df56ece359ab46 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 21 Dec 2021 22:46:00 +0100 Subject: [PATCH 437/764] Correctly handle resolving promises with other promises (#1190) * Correctly handle resolving promises with other promises * Additional test --- src/lualib/Promise.ts | 8 ++++ test/unit/builtins/async-await.spec.ts | 57 ++++++++++++++++++++++++ test/unit/builtins/promise.spec.ts | 60 ++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index 76f119c38..de21de94a 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -128,6 +128,14 @@ class __TS__Promise implements Promise { } private resolve(data: T): void { + if (data instanceof __TS__Promise) { + data.then( + v => this.resolve(v), + err => this.reject(err) + ); + return; + } + // Resolve this promise, if it is still pending. This function is passed to the constructor function. if (this.state === __TS__PromiseState.Pending) { this.state = __TS__PromiseState.Fulfilled; diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index aba6b15eb..2440bd76f 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -384,6 +384,63 @@ test("async function can forward varargs", () => { .expectToEqual(["resolved", "A", "B", "C"]); }); +test("async function adopts pending promise", () => { + util.testFunction` + let resolve: (v: string) => void = () => {}; + async function receive(): Promise { + return new Promise(res => { + resolve = res; + }); + } + + receive().then(v => { + log(v); + }); + + resolve("delayed resolve"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["delayed resolve"]); +}); + +test("async function adopts resolved promise", () => { + util.testFunction` + async function receive(): Promise { + return new Promise(resolve => { + resolve("resolved!"); + }); + } + + receive().then(v => { + log(v); + }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["resolved!"]); +}); + +test("async function adopts rejected promise", () => { + util.testFunction` + async function receive(): Promise { + return new Promise((_, reject) => { + reject("rejected"); + }); + } + + receive().catch(err => { + log(err); + }); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["rejected"]); +}); + test.each(["async function abc() {", "const abc = async () => {"])( "can throw error after await in async function (%p)", functionHeader => { diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index 60e30dcf1..10a0c767a 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -751,6 +751,66 @@ test("catch after then catches rejected promise", () => { .expectToEqual(["catch", "test error"]); }); +test("promise unwraps resolved promise result", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(v => log(v)); + + resolve(Promise.resolve("result")); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["result"]); +}); + +test("resolving promise with rejected promise rejects the promise", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.catch(err => log(err)); + + resolve(Promise.reject("reject")); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["reject"]); +}); + +test("resolving promise with pending promise will keep pending until promise2 resolved", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.then(v => log("promise 1", v)); + + const { promise: promise2, resolve: resolve2 } = defer(); + promise2.then(v => log("promise 2", v)); + + resolve(promise2); + resolve2("result"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2", "result", "promise 1", "result"]); +}); + +test("resolving promise with pending promise will keep pending until promise2 rejects", () => { + util.testFunction` + const { promise, resolve } = defer(); + promise.catch(v => log("promise 1", v)); + + const { promise: promise2, reject: reject2 } = defer(); + promise2.catch(v => log("promise 2", v)); + + resolve(promise2); + reject2("rejection"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["promise 2", "rejection", "promise 1", "rejection"]); +}); + describe("Promise.all", () => { test("resolves once all arguments are resolved", () => { util.testFunction` From 120d91a578cb772d3d2fb0e2548838b70990ce63 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 22 Dec 2021 19:02:25 +0100 Subject: [PATCH 438/764] Async catch bug (#1195) * Correctly handle resolving promises with other promises * Additional test * Fix async functions not ending after returning from catch --- src/lualib/Await.ts | 10 +++++++--- test/unit/builtins/async-await.spec.ts | 21 +++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index 4b825c71a..a3139d88e 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -36,11 +36,15 @@ function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { function rejected(handler: ErrorHandler | undefined) { if (handler) { return (value: unknown) => { - const [success, valueOrError] = pcall(handler, value); + const [success, hasReturnedOrError, returnedValue] = pcall(handler, value); if (success) { - step(valueOrError, handler); + if (hasReturnedOrError) { + resolve(returnedValue); + } else { + step(hasReturnedOrError, handler); + } } else { - reject(valueOrError); + reject(hasReturnedOrError); } }; } else { diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 2440bd76f..21f8cd265 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -441,6 +441,27 @@ test("async function adopts rejected promise", () => { .expectToEqual(["rejected"]); }); +test("return in catch aborts async method", () => { + util.testFunction` + async function asyncFunc() { + try { + await Promise.reject("rejection"); + log("Should not be seen"); + } catch { + log("C"); + return "result"; + } + log("Should also not be seen"); + } + + asyncFunc().then(v => log("resolved", v)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["C", "resolved", "result"]); +}); + test.each(["async function abc() {", "const abc = async () => {"])( "can throw error after await in async function (%p)", functionHeader => { From c409d0179d406c5ec7c85725ba37a648264f1743 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 22 Dec 2021 20:10:24 +0100 Subject: [PATCH 439/764] CHANGELOG.md 1.3.0 --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c8e0af4d..b31d78040 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.3.0 + +- Added `LuaPairsIterable` language extension to mark objects as iterable with Lua's `pairs`. +- Added support for properties on functions. +- Unicode is no longer escaped and used as-is for `"luaTarget": "JIT"`. +- Fixed some bugs related to destructuring in loops and function parameters. +- Fixed incorrect global being generated for some `try` statements. +- Fixed some incorrect behavior for `??` and `? :` when generic types were involved. +- Added missing `...` optimization in cases where casts or parentheses are used. +- Fixed a bug for `Promise` when resolving with another Promise. This also fixes some unexpected behavior with `async` which is built with Promises. +- Fixed `async` functions not aborting after returning from a `catch` block. + ## 1.2.0 - Upgraded to TypeScript 4.5.x. From 55a307689674198a636181985a5a723cc2ca75a0 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 22 Dec 2021 20:27:03 +0100 Subject: [PATCH 440/764] 1.3.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6b8944608..8c8dbe206 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.2.0", + "version": "1.3.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.2.0", + "version": "1.3.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 3df16477f..e4c25750a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.2.0", + "version": "1.3.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 3dc393e717ab20f6e02dc90c964945dbac4a5851 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 4 Jan 2022 12:12:38 -0800 Subject: [PATCH 441/764] Improve expression statement handling and language extensions calls (#1201) * Improve expression statement handling and language extensions calls as expression. * Changes from PR feedback * Add more test cases --- src/transformation/builtins/index.ts | 13 +- src/transformation/utils/diagnostics.ts | 8 - src/transformation/visitors/call.ts | 69 +------- .../visitors/expression-statement.ts | 51 +++--- src/transformation/visitors/identifier.ts | 4 +- .../visitors/language-extensions/index.ts | 20 +++ .../visitors/language-extensions/operators.ts | 13 +- .../visitors/language-extensions/table.ts | 155 ++++++++++-------- src/transformation/visitors/void.ts | 23 +-- .../optionalChaining.spec.ts.snap | 15 +- .../__snapshots__/table.spec.ts.snap | 60 ------- test/unit/language-extensions/table.spec.ts | 67 +++++--- 12 files changed, 209 insertions(+), 289 deletions(-) create mode 100644 src/transformation/visitors/language-extensions/index.ts diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index a067ecde3..b56486425 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -60,12 +60,17 @@ export function transformBuiltinCallExpression( node: ts.CallExpression, isOptionalCall: boolean ): lua.Expression | undefined { + const unsupportedOptionalCall = () => { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + }; const expressionType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, expressionType, undefined)) { // TODO: checkForLuaLibType(context, expressionType); const result = transformGlobalCall(context, node); if (result) { + if (isOptionalCall) return unsupportedOptionalCall(); return result; } } @@ -75,14 +80,8 @@ export function transformBuiltinCallExpression( return; } - assume(node); - const isOptionalAccess = expression.questionDotToken; - const unsupportedOptionalCall = () => { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - }; - + assume(node); // If the function being called is of type owner.func, get the type of owner const ownerType = context.checker.getTypeAtLocation(expression.expression); diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index af5138fd6..65df1bcb4 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -128,14 +128,6 @@ export const invalidTableExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); -export const invalidTableDeleteExpression = createErrorDiagnosticFactory( - "Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." -); - -export const invalidTableSetExpression = createErrorDiagnosticFactory( - "Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement." -); - export const annotationRemoved = createErrorDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' has been removed and will no longer have any effect.` + diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 3f04d857e..b59b3889e 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -10,26 +10,11 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { isMultiReturnCall, shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; -import { isOperatorMapping, transformOperatorMappingExpression } from "./language-extensions/operators"; -import { - isTableDeleteCall, - isTableGetCall, - isTableHasCall, - isTableSetCall, - transformTableDeleteExpression, - transformTableGetExpression, - transformTableHasExpression, - transformTableSetExpression, -} from "./language-extensions/table"; -import { - annotationRemoved, - invalidTableDeleteExpression, - invalidTableSetExpression, - unsupportedBuiltinOptionalCall, -} from "../utils/diagnostics"; +import { annotationRemoved } from "../utils/diagnostics"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; -import { transformOptionalChain, getOptionalContinuationData } from "./optional-chaining"; +import { getOptionalContinuationData, transformOptionalChain } from "./optional-chaining"; +import { transformLanguageExtensionCallExpression } from "./language-extensions"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -234,52 +219,16 @@ export const transformCallExpression: FunctionVisitor = (node : undefined; const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); - const builtinResult = transformBuiltinCallExpression(context, node, optionalContinuation !== undefined); - if (builtinResult) { - if (optionalContinuation) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - } - return wrapResultInTable ? wrapInTable(builtinResult) : builtinResult; - } - if (isTupleReturnCall(context, node)) { context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); } - if (isOperatorMapping(context, node)) { - if (optionalContinuation) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - } - return transformOperatorMappingExpression(context, node); - } - - if (isTableDeleteCall(context, node)) { - context.diagnostics.push(invalidTableDeleteExpression(node)); - context.addPrecedingStatements(transformTableDeleteExpression(context, node)); - return lua.createNilLiteral(); - } - - if (isTableGetCall(context, node)) { - if (optionalContinuation) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - } - return transformTableGetExpression(context, node); - } - - if (isTableHasCall(context, node)) { - if (optionalContinuation) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - } - return transformTableHasExpression(context, node); - } - - if (isTableSetCall(context, node)) { - context.diagnostics.push(invalidTableSetExpression(node)); - context.addPrecedingStatements(transformTableSetExpression(context, node)); - return lua.createNilLiteral(); + const builtinOrExtensionResult = + transformBuiltinCallExpression(context, node, optionalContinuation !== undefined) ?? + transformLanguageExtensionCallExpression(context, node, optionalContinuation !== undefined); + if (builtinOrExtensionResult) { + // unsupportedOptionalCall diagnostic already present + return wrapResultInTable ? wrapInTable(builtinOrExtensionResult) : builtinOrExtensionResult; } if (ts.isPropertyAccessExpression(node.expression)) { diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index 2f64ec9d8..ebc0b1600 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -1,31 +1,10 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; +import { FunctionVisitor, tempSymbolId, TransformationContext } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; -import { - isTableDeleteCall, - isTableSetCall, - transformTableDeleteExpression, - transformTableSetExpression, -} from "./language-extensions/table"; import { transformUnaryExpressionStatement } from "./unary-expression"; -import { transformVoidExpressionStatement } from "./void"; export const transformExpressionStatement: FunctionVisitor = (node, context) => { - const expression = node.expression; - - if (ts.isCallExpression(expression) && isTableDeleteCall(context, expression)) { - return transformTableDeleteExpression(context, expression); - } - - if (ts.isCallExpression(expression) && isTableSetCall(context, expression)) { - return transformTableSetExpression(context, expression); - } - - if (ts.isVoidExpression(expression)) { - return transformVoidExpressionStatement(expression, context); - } - const unaryExpressionResult = transformUnaryExpressionStatement(context, node); if (unaryExpressionResult) { return unaryExpressionResult; @@ -36,9 +15,27 @@ export const transformExpressionStatement: FunctionVisitor([ [extensions.ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], @@ -82,10 +82,15 @@ export function isOperatorMapping(context: TransformationContext, node: ts.CallE export function transformOperatorMappingExpression( context: TransformationContext, - node: ts.CallExpression -): lua.Expression { + node: ts.CallExpression, + isOptionalCall: boolean +): lua.Expression | undefined { const extensionKind = getOperatorMapExtensionKindForCall(context, node); - assert(extensionKind); + if (!extensionKind) return undefined; + if (isOptionalCall) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + } const isBefore53 = context.luaTarget === LuaTarget.Lua51 || diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index 695bcd3b1..ee3e3f2db 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -3,26 +3,21 @@ import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import * as extensions from "../../utils/language-extensions"; import { getFunctionTypeForCall } from "../../utils/typescript"; -import { assert } from "../../../utils"; +import { transformExpressionList } from "../expression-list"; +import { unsupportedBuiltinOptionalCall } from "../../utils/diagnostics"; -const tableDeleteExtensions = [ +const tableCallExtensions = [ extensions.ExtensionKind.TableDeleteType, extensions.ExtensionKind.TableDeleteMethodType, + extensions.ExtensionKind.TableGetType, + extensions.ExtensionKind.TableGetMethodType, + extensions.ExtensionKind.TableHasType, + extensions.ExtensionKind.TableHasMethodType, + extensions.ExtensionKind.TableSetType, + extensions.ExtensionKind.TableSetMethodType, ]; -const tableGetExtensions = [extensions.ExtensionKind.TableGetType, extensions.ExtensionKind.TableGetMethodType]; - -const tableHasExtensions = [extensions.ExtensionKind.TableHasType, extensions.ExtensionKind.TableHasMethodType]; - -const tableSetExtensions = [extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType]; - -const tableExtensions = [ - extensions.ExtensionKind.TableNewType, - ...tableDeleteExtensions, - ...tableGetExtensions, - ...tableHasExtensions, - ...tableSetExtensions, -]; +const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableCallExtensions]; function getTableExtensionKindForCall( context: TransformationContext, @@ -38,34 +33,60 @@ export function isTableExtensionIdentifier(context: TransformationContext, node: return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); } -export function isTableDeleteCall(context: TransformationContext, node: ts.CallExpression) { - return getTableExtensionKindForCall(context, node, tableDeleteExtensions) !== undefined; +export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { + const type = context.checker.getTypeAtLocation(node.expression); + return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); } -export function isTableGetCall(context: TransformationContext, node: ts.CallExpression) { - return getTableExtensionKindForCall(context, node, tableGetExtensions) !== undefined; -} +export function transformTableExtensionCall( + context: TransformationContext, + node: ts.CallExpression, + isOptionalCall: boolean +): lua.Expression | undefined { + const extensionType = getTableExtensionKindForCall(context, node, tableCallExtensions); + if (!extensionType) return; + if (isOptionalCall) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + return lua.createNilLiteral(); + } -export function isTableHasCall(context: TransformationContext, node: ts.CallExpression) { - return getTableExtensionKindForCall(context, node, tableHasExtensions) !== undefined; -} + if ( + extensionType === extensions.ExtensionKind.TableDeleteType || + extensionType === extensions.ExtensionKind.TableDeleteMethodType + ) { + return transformTableDeleteExpression(context, node, extensionType); + } -export function isTableSetCall(context: TransformationContext, node: ts.CallExpression) { - return getTableExtensionKindForCall(context, node, tableSetExtensions) !== undefined; -} + if ( + extensionType === extensions.ExtensionKind.TableGetType || + extensionType === extensions.ExtensionKind.TableGetMethodType + ) { + return transformTableGetExpression(context, node, extensionType); + } -export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { - const type = context.checker.getTypeAtLocation(node.expression); - return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); -} + if ( + extensionType === extensions.ExtensionKind.TableHasType || + extensionType === extensions.ExtensionKind.TableHasMethodType + ) { + return transformTableHasExpression(context, node, extensionType); + } -export function transformTableDeleteExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { - const extensionKind = getTableExtensionKindForCall(context, node, tableDeleteExtensions); - assert(extensionKind); + if ( + extensionType === extensions.ExtensionKind.TableSetType || + extensionType === extensions.ExtensionKind.TableSetMethodType + ) { + return transformTableSetExpression(context, node, extensionType); + } +} +function transformTableDeleteExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: extensions.ExtensionKind +): lua.Expression { const args = node.arguments.slice(); if ( - args.length === 1 && + extensionKind === extensions.ExtensionKind.TableDeleteMethodType && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { // In case of method (no table argument), push method owner to front of args list @@ -73,41 +94,44 @@ export function transformTableDeleteExpression(context: TransformationContext, n } // arg0[arg1] = nil - return lua.createAssignmentStatement( - lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), - lua.createNilLiteral(), - node + const [table, accessExpression] = transformExpressionList(context, args); + context.addPrecedingStatements( + lua.createAssignmentStatement( + lua.createTableIndexExpression(table, accessExpression), + lua.createNilLiteral(), + node + ) ); + return lua.createBooleanLiteral(true); } -export function transformTableGetExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { - const extensionKind = getTableExtensionKindForCall(context, node, tableGetExtensions); - assert(extensionKind); - +function transformTableGetExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: extensions.ExtensionKind +): lua.Expression { const args = node.arguments.slice(); if ( - args.length === 1 && + extensionKind === extensions.ExtensionKind.TableGetMethodType && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } + const [table, accessExpression] = transformExpressionList(context, args); // arg0[arg1] - return lua.createTableIndexExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - node - ); + return lua.createTableIndexExpression(table, accessExpression, node); } -export function transformTableHasExpression(context: TransformationContext, node: ts.CallExpression): lua.Expression { - const extensionKind = getTableExtensionKindForCall(context, node, tableHasExtensions); - assert(extensionKind); - +function transformTableHasExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: extensions.ExtensionKind +): lua.Expression { const args = node.arguments.slice(); if ( - args.length === 1 && + extensionKind === extensions.ExtensionKind.TableHasMethodType && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { // In case of method (no table argument), push method owner to front of args list @@ -115,10 +139,8 @@ export function transformTableHasExpression(context: TransformationContext, node } // arg0[arg1] - const tableIndexExpression = lua.createTableIndexExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]) - ); + const [table, accessExpression] = transformExpressionList(context, args); + const tableIndexExpression = lua.createTableIndexExpression(table, accessExpression); // arg0[arg1] ~= nil return lua.createBinaryExpression( @@ -129,13 +151,14 @@ export function transformTableHasExpression(context: TransformationContext, node ); } -export function transformTableSetExpression(context: TransformationContext, node: ts.CallExpression): lua.Statement { - const extensionKind = getTableExtensionKindForCall(context, node, tableSetExtensions); - assert(extensionKind); - +function transformTableSetExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: extensions.ExtensionKind +): lua.Expression { const args = node.arguments.slice(); if ( - args.length === 2 && + extensionKind === extensions.ExtensionKind.TableSetMethodType && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { // In case of method (no table argument), push method owner to front of args list @@ -143,9 +166,9 @@ export function transformTableSetExpression(context: TransformationContext, node } // arg0[arg1] = arg2 - return lua.createAssignmentStatement( - lua.createTableIndexExpression(context.transformExpression(args[0]), context.transformExpression(args[1])), - context.transformExpression(args[2]), - node + const [table, accessExpression, value] = transformExpressionList(context, args); + context.addPrecedingStatements( + lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), value, node) ); + return lua.createNilLiteral(); } diff --git a/src/transformation/visitors/void.ts b/src/transformation/visitors/void.ts index 9d6af960b..ab5286db5 100644 --- a/src/transformation/visitors/void.ts +++ b/src/transformation/visitors/void.ts @@ -1,28 +1,15 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { TransformationContext } from "../context"; -import { FunctionVisitor } from "../context/visitors"; +import { FunctionVisitor } from "../context"; +import { transformExpressionToStatement } from "./expression-statement"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void export const transformVoidExpression: FunctionVisitor = (node, context) => { // If content is a literal it is safe to replace the entire expression with nil if (!ts.isLiteralExpression(node.expression)) { - // local ____ = - context.addPrecedingStatements( - lua.createVariableDeclarationStatement( - lua.createAnonymousIdentifier(), - context.transformExpression(node.expression) - ) - ); + const statements = transformExpressionToStatement(context, node.expression); + if (statements) context.addPrecedingStatements(statements); } - return lua.createNilLiteral(node); + return lua.createNilLiteral(); }; - -export const transformVoidExpressionStatement = (node: ts.VoidExpression, context: TransformationContext) => - // In case of a void expression statement we can omit the IIFE - lua.createVariableDeclarationStatement( - lua.createAnonymousIdentifier(), - context.transformExpression(node.expression), - node - ); diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 9a0adc0b2..46ac47aa8 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -4,9 +4,8 @@ exports[`Unsupported optional chains Builtin global method: code 1`] = ` "require(\\"lualib_bundle\\"); local ____Number_result_0 = Number if ____Number_result_0 ~= nil then - ____Number_result_0 = __TS__Number(\\"3\\") -end -local ____ = ____Number_result_0" + ____Number_result_0 = nil +end" `; exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; @@ -15,8 +14,7 @@ exports[`Unsupported optional chains Builtin global property: code 1`] = ` "local ____console_log_result_0 = console if ____console_log_result_0 ~= nil then ____console_log_result_0 = nil -end -local ____ = ____console_log_result_0" +end" `; exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; @@ -25,8 +23,7 @@ exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` "local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach if ____table_forEach_result_0 ~= nil then ____table_forEach_result_0 = nil -end -local ____ = ____table_forEach_result_0" +end" `; exports[`Unsupported optional chains Builtin prototype method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; @@ -42,7 +39,6 @@ function ____exports.__main(self) if ____TestEnum_B_0 ~= nil then ____TestEnum_B_0 = B end - local ____ = ____TestEnum_B_0 end return ____exports" `; @@ -53,8 +49,7 @@ exports[`Unsupported optional chains Language extensions: code 1`] = ` "local ____table_has_result_0 = ({}).has if ____table_has_result_0 ~= nil then ____table_has_result_0 = nil -end -local ____ = ____table_has_result_0" +end" `; exports[`Unsupported optional chains Language extensions: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 211b69e6b..831d1ec54 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -46,66 +46,6 @@ return ____exports" exports[`LuaTable extension interface LuaTable in strict mode does not accept key type that could be nil ("unknown"): diagnostics 1`] = `"main.ts(1,38): error TS2344: Type 'unknown' does not satisfy the constraint 'AnyNotNil'."`; -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): code 1`] = ` -"({}).foo = nil -foo = {nil}" -`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = [tableDelete({}, \\"foo\\")];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): code 1`] = ` -"({}).foo = nil -foo = tostring(nil)" -`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = \`\${tableDelete({}, \\"foo\\")}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): code 1`] = ` -"({}).foo = nil -foo = nil" -`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("const foo = tableDelete({}, \\"foo\\");"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): code 1`] = ` -"local ____foo_1 = foo -local ____G_0 = _G; -({}).foo = nil -____foo_1(____G_0, nil)" -`; - -exports[`LuaTableDelete extension LuaTableDelete invalid use as expression ("declare function foo(arg: any): void; foo(tableDelete({}, \\"foo\\"));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table delete extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): code 1`] = ` -"({}).foo = 3 -foo = {nil}" -`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = [setTable({}, \\"foo\\", 3)];"): diagnostics 1`] = `"main.ts(3,26): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): code 1`] = ` -"({}).foo = 3 -foo = tostring(nil)" -`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = \`\${setTable({}, \\"foo\\", 3)}\`;"): diagnostics 1`] = `"main.ts(3,28): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): code 1`] = ` -"({}).foo = 3 -foo = nil" -`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("const foo = setTable({}, \\"foo\\", 3);"): diagnostics 1`] = `"main.ts(3,25): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): code 1`] = ` -"local ____foo_1 = foo -local ____G_0 = _G; -({}).foo = 3 -____foo_1(____G_0, nil)" -`; - -exports[`LuaTableGet & LuaTableSet extensions LuaTableSet invalid use as expression ("declare function foo(arg: any): void; foo(setTable({}, \\"foo\\", 3));"): diagnostics 1`] = `"main.ts(3,55): error TSTL: Table set extension can only be called as a stand-alone statement. It cannot be used as an expression in another statement."`; - exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): code 1`] = `"foo = getTable(_G, 1, 2)"`; exports[`LuaTableGet & LuaTableSet extensions invalid use ("const foo = (getTable as any)(1, 2);"): diagnostics 1`] = `"main.ts(3,26): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index eeba4b921..baf05b0c0 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -1,9 +1,5 @@ import * as util from "../../util"; -import { - invalidTableDeleteExpression, - invalidTableExtensionUse, - invalidTableSetExpression, -} from "../../../src/transformation/utils/diagnostics"; +import { invalidTableExtensionUse } from "../../../src/transformation/utils/diagnostics"; describe("LuaTableGet & LuaTableSet extensions", () => { test("stand-alone function", () => { @@ -20,6 +16,24 @@ describe("LuaTableGet & LuaTableSet extensions", () => { .expectToEqual(3); }); + test("stand-alone function with preceding statements", () => { + util.testModule` + declare const setTable: LuaTableSet<{}, string, string>; + const values: any[] = [] + const tbl: any = {}; + const get = (value: any) => { + values.push(value) + return value + } + let x = "a" + setTable(tbl, x += "b", x += "c") + export const result = tbl.ab + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual("abc"); + }); + test("namespace function", () => { util.testModule` declare namespace Table { @@ -66,20 +80,6 @@ describe("LuaTableGet & LuaTableSet extensions", () => { .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); }); - - test.each([ - 'const foo = setTable({}, "foo", 3);', - 'const foo = `${setTable({}, "foo", 3)}`;', - 'declare function foo(arg: any): void; foo(setTable({}, "foo", 3));', - 'const foo = [setTable({}, "foo", 3)];', - ])("LuaTableSet invalid use as expression (%p)", expression => { - util.testModule` - declare const setTable: LuaTableSet<{}, string, number>; - ${expression} - ` - .withLanguageExtensions() - .expectDiagnosticsToMatchSnapshot([invalidTableSetExpression.code]); - }); }); describe("LuaTableHas extension", () => { @@ -213,17 +213,30 @@ describe("LuaTableDelete extension", () => { }); test.each([ - 'const foo = tableDelete({}, "foo");', - 'const foo = `${tableDelete({}, "foo")}`;', - 'declare function foo(arg: any): void; foo(tableDelete({}, "foo"));', - 'const foo = [tableDelete({}, "foo")];', - ])("LuaTableDelete invalid use as expression (%p)", expression => { + ["LuaTableDelete<{}, string>", 'func({}, "foo")', true], + ["LuaTableDelete<{}, string>", '"truthy" && func({}, "foo")', true], + ["LuaTableSet<{}, string, number>", 'func({}, "foo", 3)', undefined], + ])("Table functions used as expression", (funcType, expression, value) => { util.testModule` - declare const tableDelete: LuaTableDelete<{}, string>; - ${expression} + declare const func: ${funcType} + export const result = ${expression} ` .withLanguageExtensions() - .expectDiagnosticsToMatchSnapshot([invalidTableDeleteExpression.code]); + .setReturnExport("result") + .expectToEqual(value); + }); + + test.each([ + ["LuaTableDeleteMethod", 'tbl.func("foo")', true], + ["LuaTableSetMethod", 'tbl.func("foo", 3)', undefined], + ])("Table methods used as expression", (funcType, expression, value) => { + util.testModule` + const tbl = {} as { func: ${funcType} } + export const result = ${expression} + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(value); }); }); From 32257709c90ab11f20d40b132111deb827971608 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 4 Jan 2022 12:26:40 -0800 Subject: [PATCH 442/764] Fix function with properties assigned to variable declaration (#1202) --- src/transformation/visitors/function.ts | 7 +++-- .../visitors/variable-declaration.ts | 18 ++++++++----- .../unit/functions/functionProperties.spec.ts | 27 +++++++++++++++++++ 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 12fab7d6e..9ced7089f 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -277,8 +277,9 @@ export function transformFunctionLikeDeclaration( const [functionExpression, functionScope] = transformFunctionToExpression(context, node); + const isNamedFunctionExpression = ts.isFunctionExpression(node) && node.name; // Handle named function expressions which reference themselves - if (ts.isFunctionExpression(node) && node.name && functionScope.referencedSymbols) { + if (isNamedFunctionExpression && functionScope.referencedSymbols) { const symbol = context.checker.getSymbolAtLocation(node.name); if (symbol) { // TODO: Not using symbol ids because of https://github.com/microsoft/TypeScript/issues/37131 @@ -304,7 +305,9 @@ export function transformFunctionLikeDeclaration( } } - return functionExpression; + return isNamedFunctionExpression && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node)) + ? createCallableTable(functionExpression) + : functionExpression; } export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index e7e604404..9fd0f1f42 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -261,13 +261,7 @@ export function transformVariableDeclaration( // Wrap functions being assigned to a type that contains additional properties in a callable table // This catches 'const foo = function() {}; foo.bar = "FOOBAR";' - const wrappedValue = - value && - // Skip named function expressions because they will have been wrapped already - !(statement.initializer && ts.isFunctionExpression(statement.initializer) && statement.initializer.name) && - isFunctionTypeWithProperties(context.checker.getTypeAtLocation(statement.name)) - ? createCallableTable(value) - : value; + const wrappedValue = value && shouldWrapInitializerInCallableTable() ? createCallableTable(value) : value; return createLocalOrExportedOrGlobalDeclaration(context, identifierName, wrappedValue, statement); } else if (ts.isArrayBindingPattern(statement.name) || ts.isObjectBindingPattern(statement.name)) { @@ -275,6 +269,16 @@ export function transformVariableDeclaration( } else { return assertNever(statement.name); } + + function shouldWrapInitializerInCallableTable() { + assert(statement.initializer); + const initializer = ts.skipOuterExpressions(statement.initializer); + // do not wrap if not a function expression + if (!ts.isFunctionExpression(initializer) && !ts.isArrowFunction(initializer)) return false; + // Skip named function expressions because they will have been wrapped already + if (ts.isFunctionExpression(initializer) && initializer.name) return false; + return isFunctionTypeWithProperties(context.checker.getTypeAtLocation(statement.name)); + } } export function checkVariableDeclarationList(context: TransformationContext, node: ts.VariableDeclarationList): void { diff --git a/test/unit/functions/functionProperties.spec.ts b/test/unit/functions/functionProperties.spec.ts index 85cdf9e31..16b61ab46 100644 --- a/test/unit/functions/functionProperties.spec.ts +++ b/test/unit/functions/functionProperties.spec.ts @@ -60,6 +60,14 @@ test("void function with property assigned to variable", () => { `.expectToMatchJsResult(); }); +test("named function with property assigned to variable", () => { + util.testFunction` + const foo = function baz(s: string) { return s; } + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); + test("recursively referenced function with property assigned to variable", () => { util.testFunction` const foo = function(s: string) { return s + foo.bar; }; @@ -173,3 +181,22 @@ test("call function with property using bind method", () => { return foo.bind("foo", "bar")() + foo.baz; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1196 +test("Does not wrap simple variable declaration", () => { + util.testFunction` + function foo(s: string) { return s; } + foo.bar = "bar"; + const foo2 = foo; + return foo2("foo") + foo2.bar; + `.expectToMatchJsResult(); +}); + +test("Wraps function in inner expression", () => { + util.testFunction` + type Foo = { (s: string): string; bar: string; } + const foo = (s => s)! as Foo + foo.bar = "bar"; + return foo("foo") + foo.bar; + `.expectToMatchJsResult(); +}); From 2dd99575442bc560701be2d337e490136d9cc326 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 4 Jan 2022 21:36:51 +0100 Subject: [PATCH 443/764] 1.3.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c8dbe206..9c59f7aca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.3.0", + "version": "1.3.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.3.0", + "version": "1.3.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index e4c25750a..72beeb786 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.3.0", + "version": "1.3.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 78d7cf7bfa2853465e499503587e0c679330e9ba Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 13 Jan 2022 09:15:11 +0100 Subject: [PATCH 444/764] Added Math.sign (#1206) * Added Math.sign Also improved math tests a bit. * Update test/unit/builtins/math.spec.ts Co-authored-by: Perry van Wesel Co-authored-by: Perry van Wesel --- src/LuaLib.ts | 1 + src/lualib/MathSign.ts | 9 +++ src/transformation/builtins/math.ts | 4 + .../builtins/__snapshots__/math.spec.ts.snap | 81 ------------------- test/unit/builtins/math.spec.ts | 69 +++++++++++++--- 5 files changed, 72 insertions(+), 92 deletions(-) create mode 100644 src/lualib/MathSign.ts delete mode 100644 test/unit/builtins/__snapshots__/math.spec.ts.snap diff --git a/src/LuaLib.ts b/src/LuaLib.ts index dd58b8e65..e4321d181 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -44,6 +44,7 @@ export enum LuaLibFeature { Iterator = "Iterator", Map = "Map", MathAtan2 = "MathAtan2", + MathSign = "MathSign", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", diff --git a/src/lualib/MathSign.ts b/src/lualib/MathSign.ts new file mode 100644 index 000000000..e94614c83 --- /dev/null +++ b/src/lualib/MathSign.ts @@ -0,0 +1,9 @@ +function __TS__MathSign(this: void, val: number) { + if (val > 0) { + return 1; + } else if (val < 0) { + return -1; + } + + return 0; +} diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index af742214f..73e616851 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -78,6 +78,10 @@ export function transformMathCall( return lua.createCallExpression(lua.createTableIndexExpression(math, floor), [add], node); } + case "sign": { + return transformLuaLibFunction(context, LuaLibFeature.MathSign, node, ...params); + } + case "abs": case "acos": case "asin": diff --git a/test/unit/builtins/__snapshots__/math.spec.ts.snap b/test/unit/builtins/__snapshots__/math.spec.ts.snap deleted file mode 100644 index cb324c9c9..000000000 --- a/test/unit/builtins/__snapshots__/math.spec.ts.snap +++ /dev/null @@ -1,81 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Math.PI 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local ____ = math.pi -end -return ____exports" -`; - -exports[`Math.cos() 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.cos() -end -return ____exports" -`; - -exports[`Math.log1p(3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.log(1 + 3) -end -return ____exports" -`; - -exports[`Math.log2(3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local ____ = math.log(3) / 0.6931471805599453 -end -return ____exports" -`; - -exports[`Math.log10(3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local ____ = math.log(3) / 2.302585092994046 -end -return ____exports" -`; - -exports[`Math.min() 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.min() -end -return ____exports" -`; - -exports[`Math.round(3.3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.floor(3.3 + 0.5) -end -return ____exports" -`; - -exports[`Math.sin() 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - math.sin() -end -return ____exports" -`; - -exports[`const x = Math.log2(3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local x = math.log(3) / 0.6931471805599453 -end -return ____exports" -`; - -exports[`const x = Math.log10(3) 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local x = math.log(3) / 2.302585092994046 -end -return ____exports" -`; diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index dd928c68d..2682847be 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -1,28 +1,75 @@ import * as tstl from "../../../src"; import * as util from "../../util"; +// These test are kept to a minimum, +// because we just want to confirm translation is correct +// and not test Lua's built in math functions. +// Differences in math implementations between JS & Lua cause inaccuracies +// therefore test input numbers are "carefully" selected to always match accuratly. +// Lualib implementations are tested separately. test.each([ - "Math.cos()", - "Math.sin()", - "Math.min()", - "Math.log2(3)", - "Math.log10(3)", - "const x = Math.log2(3)", - "const x = Math.log10(3)", - "Math.log1p(3)", - "Math.round(3.3)", + // log + "Math.log(42)", + "Math.log10(10)", + "Math.log2(42)", + "Math.log1p(42)", + // round + "Math.round(0.1)", + "Math.round(0.9)", + "Math.round(0.5)", + // abs + "Math.abs(-42)", + "Math.abs(42)", + // trigometric + "Math.acos(0.42)", + "Math.asin(0.42)", + "Math.atan(0.42)", + "Math.cos(42)", + "Math.sin(42)", + "Math.tan(42)", "Math.PI", + // ceil & floor + "Math.ceil(42.42)", + "Math.floor(42.42)", + // exp + "Math.exp(42)", + // max & min + "Math.max(-42, 42)", + "Math.max(42, -42)", + "Math.max(42, 42)", + "Math.max(-42, -42)", + "Math.min(42, -42)", + "Math.min(-42, 42)", + "Math.min(42, 42)", + "Math.min(-42, -42)", + // pow + "Math.pow(4.2, 4.2)", + "Math.pow(4.2, -4.2)", + "Math.pow(-4.2, -4.2)", + // random + // "Math.random()", + // sqrt + "Math.sqrt(2)", + "Math.sqrt(-2)", ])("%s", code => { - // TODO: Remove? - util.testFunction(code).disableSemanticCheck().expectLuaToMatchSnapshot(); + util.testExpression(code).expectToMatchJsResult(); }); +// Hard to test properly +util.testExpression("Math.random()").expectNoExecutionError(); + test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s", constant => { util.testExpression`Math.${constant}`.tap(builder => { expect(builder.getLuaExecutionResult()).toBeCloseTo(builder.getJsExecutionResult()); }); }); +// LuaLib MathSign +test.each(["Math.sign(-42)", "Math.sign(42)", "Math.sign(-4.2)", "Math.sign(4.2)", "Math.sign(0)"])("%s", code => { + util.testExpression(code).expectToMatchJsResult(); +}); + +// LuaLib Atan2 const expectMathAtan2: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan2("); const expectMathAtan: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toContain("math.atan("); const expectLualibMathAtan2: util.TapCallback = builder => From 61bfff3eea55c83c8610e2f2745dd1eeb1efb257 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 13 Jan 2022 22:01:28 +0100 Subject: [PATCH 445/764] Put preceding statements for class fields in the constructor instead of file scope (#1209) --- .../visitors/class/members/constructor.ts | 6 +++++- test/unit/precedingStatements.spec.ts | 12 ++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 11766d2a8..3dfd6a26d 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; @@ -43,7 +44,9 @@ export function transformConstructorDeclaration( // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - const classInstanceFields = transformClassInstanceFields(context, instanceFields); + const [fieldsPrecedingStatements, classInstanceFields] = transformInPrecedingStatementScope(context, () => + transformClassInstanceFields(context, instanceFields) + ); // If there are field initializers and the first statement is a super call, // move super call between default assignments and initializers @@ -78,6 +81,7 @@ export function transformConstructorDeclaration( // else { TypeScript error: A parameter property may not be declared using a binding pattern } } + bodyWithFieldInitializers.push(...fieldsPrecedingStatements); bodyWithFieldInitializers.push(...classInstanceFields); bodyWithFieldInitializers.push(...body); diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts index 6ff6b4706..79769e519 100644 --- a/test/unit/precedingStatements.spec.ts +++ b/test/unit/precedingStatements.spec.ts @@ -623,3 +623,15 @@ test("else if", () => { return i; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1208 +test("class member initializers", () => { + util.testFunction` + class MyClass { + myField = false ?? true; + constructor(public foo: number = 0 ?? 5) {} + } + const inst = new MyClass(); + return [inst.myField, inst.foo]; + `.expectToMatchJsResult(); +}); From 7abca43f0c236fbc81f9913e4770d83fc1d9a121 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 14 Jan 2022 10:22:59 +0100 Subject: [PATCH 446/764] Use power operator instead of math.pow (#1210) * Use power operator instead of math.pow in lua 5.3 and later * Always use ^ instead of math.pow --- src/transformation/builtins/math.ts | 6 +++++- test/unit/builtins/math.spec.ts | 19 +++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 73e616851..e215e215d 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -70,6 +70,11 @@ export function transformMathCall( return lua.createCallExpression(lua.createTableIndexExpression(math, log), [add], node); } + case "pow": { + // Translate to base ^ power + return lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.PowerOperator, node); + } + // math.floor(x + 0.5) case "round": { const floor = lua.createStringLiteral("floor"); @@ -93,7 +98,6 @@ export function transformMathCall( case "log": case "max": case "min": - case "pow": case "random": case "sin": case "sqrt": diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 2682847be..9e191e1e2 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -84,11 +84,14 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), }); -util.testEachVersion("Math.atan2(4, 5)", () => util.testExpression`Math.atan2(4, 5)`, { - [tstl.LuaTarget.Universal]: builder => builder.expectToMatchJsResult(), - [tstl.LuaTarget.LuaJIT]: false, - [tstl.LuaTarget.Lua51]: builder => builder.expectToMatchJsResult(), - [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), - [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), - [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), -}); +util.testEachVersion( + "Math.atan2(4, 5)", + () => util.testExpression`Math.atan2(4, 5)`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); + +util.testEachVersion( + "Math.pow(3, 5)", + () => util.testExpression`Math.pow(3, 5)`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); From 3f76d2c743f6c8740ff3cb99cb9b2bcfa6e69208 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 14 Jan 2022 18:42:10 +0100 Subject: [PATCH 447/764] 1.3.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c59f7aca..b82974336 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.3.1", + "version": "1.3.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.3.1", + "version": "1.3.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 72beeb786..6c50daf7a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.3.1", + "version": "1.3.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f23ea3e3ae96754c022d02a50c1f3912104f722d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 16 Jan 2022 17:50:22 +0100 Subject: [PATCH 448/764] Correctly place class member preceding instances in the constructor always (#1211) --- .../visitors/class/members/constructor.ts | 6 +----- .../visitors/class/members/fields.ts | 21 ++++++++++++------- test/unit/precedingStatements.spec.ts | 11 ++++++++++ 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 3dfd6a26d..11766d2a8 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements"; import { popScope, pushScope, ScopeType } from "../../../utils/scope"; import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; @@ -44,9 +43,7 @@ export function transformConstructorDeclaration( // Check for field declarations in constructor const constructorFieldsDeclarations = statement.parameters.filter(p => p.modifiers !== undefined); - const [fieldsPrecedingStatements, classInstanceFields] = transformInPrecedingStatementScope(context, () => - transformClassInstanceFields(context, instanceFields) - ); + const classInstanceFields = transformClassInstanceFields(context, instanceFields); // If there are field initializers and the first statement is a super call, // move super call between default assignments and initializers @@ -81,7 +78,6 @@ export function transformConstructorDeclaration( // else { TypeScript error: A parameter property may not be declared using a binding pattern } } - bodyWithFieldInitializers.push(...fieldsPrecedingStatements); bodyWithFieldInitializers.push(...classInstanceFields); bodyWithFieldInitializers.push(...body); diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 980c6f851..49edacdb3 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; +import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements"; import { transformPropertyName } from "../../literal"; import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; import { transformMemberExpressionOwnerName } from "./method"; @@ -30,18 +31,22 @@ export function transformClassInstanceFields( const statements: lua.Statement[] = []; for (const f of instanceFields) { - // Get identifier - const fieldName = transformPropertyName(context, f.name); + const [precedingStatements, statement] = transformInPrecedingStatementScope(context, () => { + // Get identifier + const fieldName = transformPropertyName(context, f.name); - const value = f.initializer ? context.transformExpression(f.initializer) : undefined; + const value = f.initializer ? context.transformExpression(f.initializer) : undefined; - // self[fieldName] - const selfIndex = lua.createTableIndexExpression(createSelfIdentifier(), fieldName); + // self[fieldName] + const selfIndex = lua.createTableIndexExpression(createSelfIdentifier(), fieldName); - // self[fieldName] = value - const assignClassField = lua.createAssignmentStatement(selfIndex, value, f); + // self[fieldName] = value + const assignClassField = lua.createAssignmentStatement(selfIndex, value, f); - statements.push(assignClassField); + return assignClassField; + }); + + statements.push(...precedingStatements, statement); } return statements; diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts index 79769e519..f27d26494 100644 --- a/test/unit/precedingStatements.spec.ts +++ b/test/unit/precedingStatements.spec.ts @@ -635,3 +635,14 @@ test("class member initializers", () => { return [inst.myField, inst.foo]; `.expectToMatchJsResult(); }); + +test("class member initializers in extended class", () => { + util.testFunction` + class A {} + class MyClass extends A { + myField = false ?? true; + } + const inst = new MyClass(); + return inst.myField; + `.expectToMatchJsResult(); +}); From f64a7aabf3af706581e6536f7589d549245ffd17 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 16 Jan 2022 19:49:14 +0100 Subject: [PATCH 449/764] 1.3.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b82974336..af4759386 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.3.2", + "version": "1.3.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.3.2", + "version": "1.3.3", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 6c50daf7a..0db3f1280 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.3.2", + "version": "1.3.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 88a947859dbdff48bc06fd15fa8ca04b2c9a0eca Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 1 Mar 2022 23:23:30 +0100 Subject: [PATCH 450/764] Fix module resolution exploding (#1220) * Fix module resolution exploding * updated snapshot --- src/transpilation/resolve.ts | 4 ++-- test/transpile/__snapshots__/project.spec.ts.snap | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index a3ac4f92a..8643f6c86 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -161,7 +161,7 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext dependencies.push(...resolvedDependency.resolvedFiles); diagnostics.push(...resolvedDependency.diagnostics); } - return { resolvedFiles: dependencies, diagnostics }; + return { resolvedFiles: deduplicateResolvedFiles(dependencies), diagnostics }; } function resolveDependency( @@ -174,7 +174,7 @@ function resolveDependency( const fileDirectory = path.dirname(requiringFile.fileName); if (options.tstlVerbose) { - console.log(`Resolving "${dependency}" from ${normalizeSlashes(fileDirectory)}`); + console.log(`Resolving "${dependency}" from ${normalizeSlashes(requiringFile.fileName)}`); } // Check if the import is relative diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index 1effba209..ce03539da 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -11,7 +11,7 @@ Array [ "Constructing emit plan", "Resolving dependencies for /test/transpile/project/otherFile.ts", "Resolving dependencies for /test/transpile/project/index.ts", - "Resolving \\"./otherFile\\" from /test/transpile/project", + "Resolving \\"./otherFile\\" from /test/transpile/project/index.ts", "Resolved ./otherFile to /test/transpile/project/otherFile.ts", "Emitting output", "Emitting /test/transpile/project/otherFile.lua", From a434ab2e27c67e53826328106b3e4dfc0023e2fa Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 2 Mar 2022 00:08:48 +0100 Subject: [PATCH 451/764] 1.3.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index af4759386..b9591e6fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.3.3", + "version": "1.3.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.3.3", + "version": "1.3.4", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 0db3f1280..469f639c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.3.3", + "version": "1.3.4", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9954426ab659d1928dd9ddb44b38d378778e3c8c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 5 Mar 2022 17:28:30 +0100 Subject: [PATCH 452/764] Upgrade TypeScript to 4.6 (#1222) * Upgrade TypeScript to 4.6 * Upgrade pipeline node.js * Fix prettyformat error --- .eslintrc.js | 2 - .github/workflows/ci.yml | 6 +- .github/workflows/release.yml | 2 +- package-lock.json | 1996 +++++++--------------- package.json | 18 +- test/transpile/bundle.spec.ts | 4 +- test/transpile/module-resolution.spec.ts | 2 +- test/util.ts | 2 +- 8 files changed, 602 insertions(+), 1430 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 27bc25da8..370240c0b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -74,10 +74,8 @@ module.exports = { "jest/expect-expect": "off", "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], "jest/no-disabled-tests": "error", - "jest/no-expect-resolves": "error", "jest/no-identical-title": "off", "jest/no-test-return-statement": "error", - "jest/no-truthy-falsy": "error", "jest/prefer-spy-on": "error", "jest/prefer-todo": "error", "jest/valid-title": "error", diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4c778f21f..f8cfb0d49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,6 +13,8 @@ jobs: steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 + with: + node-version: 16.14.0 - run: npm ci - run: npm run lint env: @@ -30,7 +32,7 @@ jobs: - name: Use Node.js 15.14.0 uses: actions/setup-node@v1 with: - node-version: 15.14.0 + node-version: 16.14.0 - run: npm ci - run: npm run build - run: npx jest --maxWorkers 2 --coverage @@ -60,7 +62,7 @@ jobs: - name: Use Node.js 12.13.1 uses: actions/setup-node@v1 with: - node-version: 12.13.1 + node-version: 16.14.0 # NPM - name: NPM master run: npm ci && npm run build diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e6e9f26fd..22e242d03 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,7 +14,7 @@ jobs: - name: Use Node.js 12.13.1 uses: actions/setup-node@v1 with: - node-version: 12.13.1 + node-version: 16.14.0 registry-url: "https://registry.npmjs.org" - run: npm ci - run: npm run build diff --git a/package-lock.json b/package-lock.json index b9591e6fa..bc83442d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,14 +19,14 @@ "devDependencies": { "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", - "@types/jest": "^25.1.3", + "@types/jest": "^27.4.1", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", - "eslint": "^7.32.0", - "eslint-plugin-import": "^2.24.2", - "eslint-plugin-jest": "^24.4.0", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", + "eslint": "^8.10.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-jest": "^26.1.1", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^27.3.0", @@ -34,24 +34,15 @@ "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^27.0.7", + "ts-jest": "^27.1.3", "ts-node": "^10.3.0", - "typescript": "~4.5.2" + "typescript": "~4.6.2" }, "engines": { "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.5.2" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.10.4" + "typescript": "~4.6.2" } }, "node_modules/@babel/compat-data": { @@ -713,25 +704,31 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", "dev": true, "dependencies": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", + "debug": "^4.3.2", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/@eslint/eslintrc/node_modules/ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -741,13 +738,25 @@ "node": ">= 4" } }, + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" }, @@ -756,9 +765,9 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -1312,13 +1321,13 @@ } }, "node_modules/@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", "dev": true, "dependencies": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "node_modules/@types/json-schema": { @@ -1382,13 +1391,14 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz", + "integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/type-utils": "5.13.0", + "@typescript-eslint/utils": "5.13.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -1413,18 +1423,14 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", - "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1432,20 +1438,13 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" - }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1454,11 +1453,15 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.13.0", + "eslint-visitor-keys": "^3.0.0" + }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1467,19 +1470,25 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz", + "integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/typescript-estree": "5.13.0", + "debug": "^4.3.2" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1488,20 +1497,23 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.4.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1511,49 +1523,32 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", + "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "debug": "^4.3.2" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1562,23 +1557,20 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/types": "5.13.0", + "eslint-visitor-keys": "^3.0.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1588,31 +1580,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz", + "integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", + "@typescript-eslint/utils": "5.13.0", "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { @@ -1622,20 +1606,27 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "*" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "node_modules/@typescript-eslint/utils": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.13.0.tgz", + "integrity": "sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.4.0", - "eslint-visitor-keys": "^3.0.0" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/typescript-estree": "5.13.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1643,63 +1634,57 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", "dev": true, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", + "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", "semver": "^7.3.5", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -1711,23 +1696,32 @@ } } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "@typescript-eslint/types": "5.13.0", + "eslint-visitor-keys": "^3.0.0" }, "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/abab": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", @@ -1802,15 +1796,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1935,15 +1920,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2442,15 +2418,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -2532,18 +2499,6 @@ "node": ">=10.13.0" } }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, "node_modules/es-abstract": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", @@ -2709,49 +2664,44 @@ } }, "node_modules/eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", "dev": true, "dependencies": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.2.0", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", + "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -2759,7 +2709,7 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -2785,14 +2735,13 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", "dev": true, "dependencies": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "engines": { "node": ">=4" @@ -2808,9 +2757,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", - "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -2818,14 +2767,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.0", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", - "is-core-module": "^2.7.0", + "is-core-module": "^2.8.0", "is-glob": "^4.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "engines": { "node": ">=4" @@ -2862,23 +2811,26 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz", + "integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==", "dev": true, "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" + "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" }, "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">= 4", - "eslint": ">=5" + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "peerDependenciesMeta": { "@typescript-eslint/eslint-plugin": { "optional": true + }, + "jest": { + "optional": true } } }, @@ -2922,60 +2874,109 @@ "node": ">=10" } }, - "node_modules/eslint/node_modules/eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "node_modules/eslint/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^1.1.0" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, "node_modules/eslint/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" } }, + "node_modules/eslint/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "dependencies": { - "acorn": "^7.4.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree/node_modules/acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { - "node": ">=4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/esprima": { @@ -3389,9 +3390,9 @@ } }, "node_modules/globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -4120,39 +4121,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-cli": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", @@ -4227,18 +4195,6 @@ } } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-config/node_modules/jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", @@ -4248,55 +4204,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-config/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-diff/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jest-docblock": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", @@ -4325,18 +4232,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-each/node_modules/jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", @@ -4346,27 +4241,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-environment-jsdom": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", @@ -4402,15 +4276,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, "node_modules/jest-haste-map": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", @@ -4466,39 +4331,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-jasmine2/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-jasmine2/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-leak-detector": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", @@ -4512,18 +4344,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", @@ -4533,27 +4353,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-matcher-utils": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", @@ -4569,18 +4368,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-matcher-utils/node_modules/diff-sequences": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", @@ -4614,27 +4401,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-message-util": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", @@ -4667,39 +4433,6 @@ "node": ">=6.9.0" } }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-mock": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", @@ -4892,18 +4625,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-snapshot/node_modules/diff-sequences": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", @@ -4937,27 +4658,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-util": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", @@ -4992,18 +4692,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -5025,27 +4713,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, "node_modules/jest-watcher": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", @@ -5268,12 +4935,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "node_modules/lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -5286,12 +4947,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -5710,18 +5365,6 @@ "node": ">= 6" } }, - "node_modules/pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "dependencies": { - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5744,74 +5387,29 @@ } }, "node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": ">= 8.3" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/pretty-format/node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, "engines": { - "node": ">= 8.3" - } - }, - "node_modules/pretty-format/node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/pretty-format/node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/pretty-format/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "node": ">=10" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/prompts": { @@ -5863,9 +5461,9 @@ ] }, "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "node_modules/regexpp": { @@ -5889,15 +5487,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -6092,23 +5681,6 @@ "node": ">=8" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "node_modules/source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -6289,45 +5861,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "node_modules/table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/table/node_modules/ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -6432,9 +5965,9 @@ } }, "node_modules/ts-jest": { - "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", "dev": true, "dependencies": { "bs-logger": "0.x", @@ -6456,6 +5989,7 @@ "@babel/core": ">=7.0.0-beta.0 <8", "@types/jest": "^27.0.0", "babel-jest": ">=27.0.0 <28", + "esbuild": "~0.14.0", "jest": "^27.0.0", "typescript": ">=3.8 <5.0" }, @@ -6468,6 +6002,9 @@ }, "babel-jest": { "optional": true + }, + "esbuild": { + "optional": true } } }, @@ -6534,9 +6071,9 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz", + "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", @@ -6630,9 +6167,9 @@ } }, "node_modules/typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6955,15 +6492,6 @@ } }, "dependencies": { - "@babel/code-frame": { - "version": "7.12.11", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", - "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "@babel/compat-data": { "version": "7.15.0", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", @@ -7466,45 +6994,60 @@ } }, "@eslint/eslintrc": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz", - "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", + "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", "dev": true, "requires": { "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", + "debug": "^4.3.2", + "espree": "^9.3.1", "globals": "^13.9.0", "ignore": "^4.0.6", "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "minimatch": "^3.0.4", "strip-json-comments": "^3.1.1" }, "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, "@humanwhocodes/config-array": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", - "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.0", + "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", "minimatch": "^3.0.4" } }, "@humanwhocodes/object-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz", - "integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -7966,13 +7509,13 @@ } }, "@types/jest": { - "version": "25.2.3", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-25.2.3.tgz", - "integrity": "sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw==", + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", "dev": true, "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, "@types/json-schema": { @@ -8036,13 +7579,14 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.4.0.tgz", - "integrity": "sha512-9/yPSBlwzsetCsGEn9j24D8vGQgJkOTr4oMLas/w886ZtzKIs1iyoqFrwsX2fqYEeUwsdBpC21gcjRGo57u0eg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz", + "integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "5.4.0", - "@typescript-eslint/scope-manager": "5.4.0", + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/type-utils": "5.13.0", + "@typescript-eslint/utils": "5.13.0", "debug": "^4.3.2", "functional-red-black-tree": "^1.0.1", "ignore": "^5.1.8", @@ -8051,119 +7595,76 @@ "tsutils": "^3.21.0" }, "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.4.0.tgz", - "integrity": "sha512-Nz2JDIQUdmIGd6p33A+naQmwfkU5KVTLb/5lTk+tLVTDacZKoGQisj8UCxk7onJcrgjIvr8xWqkYI+DbI3TfXg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, "@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" } }, "@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", "dev": true }, - "@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, "@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/types": "5.13.0", "eslint-visitor-keys": "^3.0.0" } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true } } }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } - }, "@typescript-eslint/parser": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.4.0.tgz", - "integrity": "sha512-JoB41EmxiYpaEsRwpZEYAJ9XQURPFer8hpkIW9GiaspVLX8oqbqNM8P4EP8HOZg96yaALiLEVWllA2E8vwsIKw==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz", + "integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.4.0", - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/typescript-estree": "5.4.0", + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/typescript-estree": "5.13.0", "debug": "^4.3.2" }, "dependencies": { "@typescript-eslint/scope-manager": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.4.0.tgz", - "integrity": "sha512-pRxFjYwoi8R+n+sibjgF9iUiAELU9ihPBtHzocyW8v8D8G8KeQvXTsW7+CBYIyTYsmhtNk50QPGLE3vrvhM5KA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0" + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" } }, "@typescript-eslint/types": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.4.0.tgz", - "integrity": "sha512-GjXNpmn+n1LvnttarX+sPD6+S7giO+9LxDIGlRl4wK3a7qMWALOHYuVSZpPTfEIklYjaWuMtfKdeByx0AcaThA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.4.0.tgz", - "integrity": "sha512-nhlNoBdhKuwiLMx6GrybPT3SFILm5Gij2YBdPEPFlYNFAXUJWX6QRgvi/lwVoadaQEFsizohs6aFRMqsXI2ewA==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", + "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", - "@typescript-eslint/visitor-keys": "5.4.0", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0", "debug": "^4.3.2", "globby": "^11.0.4", "is-glob": "^4.0.3", @@ -8172,62 +7673,95 @@ } }, "@typescript-eslint/visitor-keys": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.4.0.tgz", - "integrity": "sha512-PVbax7MeE7tdLfW5SA0fs8NGVVr+buMPrcj+CWYWPXsZCH8qZ1THufDzbXm1xrZ2b2PA1iENJ0sRq5fuUtvsJg==", + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.4.0", + "@typescript-eslint/types": "5.13.0", "eslint-visitor-keys": "^3.0.0" } }, "eslint-visitor-keys": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.1.0.tgz", - "integrity": "sha512-yWJFpu4DtjsWKkt5GeNBBuZMlNcYVs6vRCLoCVEJrTjaSB6LC98gFipNK/erM2Heg/E8mIK+hXG/pJMLK+eRZA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true } } }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } - }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "@typescript-eslint/type-utils": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz", + "integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", + "@typescript-eslint/utils": "5.13.0", + "debug": "^4.3.2", "tsutils": "^3.21.0" } }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "@typescript-eslint/utils": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.13.0.tgz", + "integrity": "sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ==", "dev": true, "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.13.0", + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/typescript-estree": "5.13.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", + "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0" + } + }, + "@typescript-eslint/types": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", + "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", + "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.13.0", + "@typescript-eslint/visitor-keys": "5.13.0", + "debug": "^4.3.2", + "globby": "^11.0.4", + "is-glob": "^4.0.3", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", + "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.13.0", + "eslint-visitor-keys": "^3.0.0" + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + } } }, "abab": { @@ -8286,12 +7820,6 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -8379,12 +7907,6 @@ "es-abstract": "^1.19.0" } }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -8780,12 +8302,6 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", - "dev": true - }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8848,15 +8364,6 @@ "tapable": "^2.2.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "requires": { - "ansi-colors": "^4.1.1" - } - }, "es-abstract": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", @@ -8976,75 +8483,99 @@ } }, "eslint": { - "version": "7.32.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz", - "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", + "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", "dev": true, "requires": { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.3", - "@humanwhocodes/config-array": "^0.5.0", + "@eslint/eslintrc": "^1.2.0", + "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", - "debug": "^4.0.1", + "debug": "^4.3.2", "doctrine": "^3.0.0", - "enquirer": "^2.3.5", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.1", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.3.1", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.1.2", + "glob-parent": "^6.0.1", "globals": "^13.6.0", - "ignore": "^4.0.6", + "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", + "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "progress": "^2.0.0", - "regexpp": "^3.1.0", - "semver": "^7.2.1", - "strip-ansi": "^6.0.0", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "table": "^6.0.9", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { - "eslint-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", - "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "requires": { - "eslint-visitor-keys": "^1.1.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true - } + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" } }, "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } } } }, @@ -9070,14 +8601,13 @@ } }, "eslint-module-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.1.tgz", - "integrity": "sha512-fjoetBXQZq2tSTWZ9yWVl2KuFrTZZH3V+9iD1V1RfpDgxzJR+mPd/KZmMiA8gbPqdBzpNiEHOuT7IYEWxrH0zQ==", + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", "dev": true, "requires": { "debug": "^3.2.7", - "find-up": "^2.1.0", - "pkg-dir": "^2.0.0" + "find-up": "^2.1.0" }, "dependencies": { "debug": { @@ -9092,9 +8622,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.2.tgz", - "integrity": "sha512-qCwQr9TYfoBHOFcVGKY9C9unq05uOxxdklmBXLVvcwo68y5Hta6/GzCZEMx2zQiu0woKNEER0LE7ZgaOfBU14g==", + "version": "2.25.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", + "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -9102,14 +8632,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.0", + "eslint-module-utils": "^2.7.2", "has": "^1.0.3", - "is-core-module": "^2.7.0", + "is-core-module": "^2.8.0", "is-glob": "^4.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.5", "resolve": "^1.20.0", - "tsconfig-paths": "^3.11.0" + "tsconfig-paths": "^3.12.0" }, "dependencies": { "debug": { @@ -9139,12 +8669,12 @@ } }, "eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "version": "26.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz", + "integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "^4.0.1" + "@typescript-eslint/utils": "^5.10.0" } }, "eslint-scope": { @@ -9173,20 +8703,26 @@ "dev": true }, "espree": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", - "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", + "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", "dev": true, "requires": { - "acorn": "^7.4.0", + "acorn": "^8.7.0", "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^1.3.0" + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { + "acorn": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", + "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "dev": true + }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true } } @@ -9501,9 +9037,9 @@ } }, "globals": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.11.0.tgz", - "integrity": "sha512-08/xrJ7wQjK9kkkRoI3OFUBbLx4f+6x3SGwcPvQ0QH6goFDrOU2oyAWrmh3dJezu65buo+HBMzAMQy6rovVC3g==", + "version": "13.12.1", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", + "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -10018,32 +9554,6 @@ "slash": "^3.0.0", "stack-utils": "^2.0.3", "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } } }, "jest-cli": { @@ -10095,59 +9605,11 @@ "pretty-format": "^27.3.0" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } - } - }, - "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } } } }, @@ -10173,35 +9635,11 @@ "pretty-format": "^27.3.0" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10234,12 +9672,6 @@ "jest-util": "^27.3.0" } }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, "jest-haste-map": { "version": "27.3.0", "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", @@ -10285,32 +9717,6 @@ "jest-util": "^27.3.0", "pretty-format": "^27.3.0", "throat": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - } } }, "jest-leak-detector": { @@ -10323,35 +9729,11 @@ "pretty-format": "^27.3.0" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "jest-get-type": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10367,12 +9749,6 @@ "pretty-format": "^27.3.0" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "diff-sequences": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", @@ -10396,24 +9772,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10442,30 +9800,6 @@ "requires": { "@babel/highlight": "^7.14.5" } - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10627,12 +9961,6 @@ "semver": "^7.3.2" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "diff-sequences": { "version": "27.0.6", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", @@ -10656,24 +9984,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10705,12 +10015,6 @@ "pretty-format": "^27.3.0" }, "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", @@ -10722,24 +10026,6 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", "dev": true - }, - "pretty-format": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.0.tgz", - "integrity": "sha512-Nkdd0xmxZdjCe6GoJomHnrLcCYGYzZKI/fRnUX0sCwDai2mmCHJfC9Ecx33lYgaxAFS/pJCAqhfxmWlm1wNVag==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - } - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true } } }, @@ -10913,12 +10199,6 @@ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -10931,12 +10211,6 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", - "dev": true - }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -11258,15 +10532,6 @@ "node-modules-regexp": "^1.0.0" } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -11280,66 +10545,24 @@ "dev": true }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "dependencies": { - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true } } }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, "prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -11369,9 +10592,9 @@ "dev": true }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, "regexpp": { @@ -11386,12 +10609,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -11528,17 +10745,6 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, "source-map": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", @@ -11678,40 +10884,6 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, - "table": { - "version": "6.7.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz", - "integrity": "sha512-UFZK67uvyNivLeQbVtkiUs8Uuuxv24aSL4/Vil2PJVtMgU8Lx0CYkP12uCGa3kjyQzOSgV1+z9Wkb82fCGsO0g==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.clonedeep": "^4.5.0", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "ajv": { - "version": "8.6.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.6.3.tgz", - "integrity": "sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } - } - }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -11792,9 +10964,9 @@ } }, "ts-jest": { - "version": "27.0.7", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.7.tgz", - "integrity": "sha512-O41shibMqzdafpuP+CkrOL7ykbmLh+FqQrXEmV9CydQ5JBk0Sj0uAEF5TNNe94fZWKm3yYvWa/IbyV4Yg1zK2Q==", + "version": "27.1.3", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", + "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", "dev": true, "requires": { "bs-logger": "0.x", @@ -11842,9 +11014,9 @@ } }, "tsconfig-paths": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.11.0.tgz", - "integrity": "sha512-7ecdYDnIdmv639mmDwslG6KQg1Z9STTz1j7Gcz0xa+nshh/gKDAHcPxRbWOsA3SPp0tXP2leTcY9Kw+NAkfZzA==", + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz", + "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==", "dev": true, "requires": { "@types/json5": "^0.0.29", @@ -11916,9 +11088,9 @@ } }, "typescript": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz", - "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw==", + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", + "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", "dev": true }, "typescript-to-lua": { diff --git a/package.json b/package.json index 469f639c7..320b3d17b 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.5.2" + "typescript": "~4.6.2" }, "dependencies": { "enhanced-resolve": "^5.8.2", @@ -52,14 +52,14 @@ "devDependencies": { "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", - "@types/jest": "^25.1.3", + "@types/jest": "^27.4.1", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.4.0", - "@typescript-eslint/parser": "^5.4.0", - "eslint": "^7.32.0", - "eslint-plugin-import": "^2.24.2", - "eslint-plugin-jest": "^24.4.0", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", + "eslint": "^8.10.0", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-jest": "^26.1.1", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^27.3.0", @@ -67,8 +67,8 @@ "lua-types": "2.10.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^27.0.7", + "ts-jest": "^27.1.3", "ts-node": "^10.3.0", - "typescript": "~4.5.2" + "typescript": "~4.6.2" } } diff --git a/test/transpile/bundle.spec.ts b/test/transpile/bundle.spec.ts index 95ab76a96..3834bbb2f 100644 --- a/test/transpile/bundle.spec.ts +++ b/test/transpile/bundle.spec.ts @@ -52,7 +52,7 @@ describe("bundle with source maps", () => { // See https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1109 test('the result file should not contain "{#SourceMapTraceback}" macro-string', () => { const { lua } = transpileResult.transpiledFiles[0]; - expect(lua).not.toBeUndefined(); + expect(lua).toBeDefined(); expect(lua!).not.toContain("{#SourceMapTraceback}"); }); @@ -126,7 +126,7 @@ describe("bundle with source maps", () => { const typescriptPosition = lineAndColumnOf(code[currentFile], typeScriptPattern); expect(mappedLine.line).toEqual(typescriptPosition.line); - expect(mappedLine.file).toEqual(`${currentFile}.ts`); + expect(mappedLine.file).toBe(`${currentFile}.ts`); } }); }); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index c363dbea1..b60c83e91 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -49,7 +49,7 @@ describe("basic module resolution", () => { test("can resolve package depencency with a dependency on another package", () => { // Declarations in the node_modules directory - expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDependencyResult).toEqual( + expect(projectWithNodeModules.getLuaExecutionResult().moduleWithDependencyResult).toBe( "Calling dependency: foo from lua module with decls" ); }); diff --git a/test/util.ts b/test/util.ts index 7d5ea6b95..0f053d9a0 100644 --- a/test/util.ts +++ b/test/util.ts @@ -310,7 +310,7 @@ export abstract class TestBuilder { const luaCode = transpiledFiles .filter(f => includeLualib || f.outPath !== "lualib_bundle.lua") .map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); - const value = prettyFormat(this.getLuaExecutionResult()).replace(/^/gm, " "); + const value = prettyFormat.format(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); return this; } From 5d66aa40d40675293e459d8663f67b8d5b488e81 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 10 Mar 2022 22:52:09 +0100 Subject: [PATCH 453/764] Error when using null or undefined in array literal (#1223) * Error when using null or undefined in array literal * Fix prettier --- src/transformation/utils/diagnostics.ts | 4 +++ src/transformation/visitors/literal.ts | 34 ++++++++++++++++++++++++- test/unit/builtins/array.spec.ts | 26 +++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 65df1bcb4..25442cdfa 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -155,3 +155,7 @@ export const unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory( export const unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactory( "Optional calls are not supported on enums marked with @compileMembersOnly." ); + +export const undefinedInArrayLiteral = createErrorDiagnosticFactory( + "Array literals may not contain undefined or null." +); diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 32576a815..e33af39e6 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,7 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { invalidMultiFunctionUse, unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; +import { + invalidMultiFunctionUse, + undefinedInArrayLiteral, + unsupportedAccessorInObjectLiteral, +} from "../utils/diagnostics"; import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; @@ -196,6 +200,9 @@ const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { + // Disallow using undefined/null in array literals + checkForUndefinedOrNullInArrayLiteral(expression, context); + const filteredElements = expression.elements.map(e => ts.isOmittedExpression(e) ? ts.factory.createIdentifier("undefined") : e ); @@ -204,6 +211,31 @@ const transformArrayLiteralExpression: FunctionVisitor= 0; lastNonUndefinedIndex--) { + if (!isUndefinedOrNull(array.elements[lastNonUndefinedIndex])) { + break; + } + } + + // Add diagnostics for non-trailing nil elements in array literal + for (let i = 0; i < array.elements.length; i++) { + if (i < lastNonUndefinedIndex && isUndefinedOrNull(array.elements[i])) { + context.diagnostics.push(undefinedInArrayLiteral(array.elements[i])); + } + } +} + +function isUndefinedOrNull(node: ts.Node) { + return ( + node.kind === ts.SyntaxKind.UndefinedKeyword || + node.kind === ts.SyntaxKind.NullKeyword || + (ts.isIdentifier(node) && node.text === "undefined") + ); +} + export const literalVisitors: Visitors = { [ts.SyntaxKind.NullKeyword]: node => lua.createNilLiteral(node), [ts.SyntaxKind.TrueKeyword]: node => lua.createBooleanLiteral(true, node), diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 037ebe2a7..aae630b78 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -1,3 +1,4 @@ +import { undefinedInArrayLiteral } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("omitted expression", () => { @@ -674,3 +675,28 @@ test("Array.isArray returns true for empty objects", () => { test("array.prototype.concat issue #738", () => { util.testExpression`([] as any[]).concat(13, 323, {x: 3}, [2, 3])`.expectToMatchJsResult(); }); + +test.each(["[1, undefined, 3]", "[1, null, 3]", "[1, undefined, 2, null]"])( + "not allowed to use null or undefined in array literals (%p)", + literal => { + util.testExpression(literal).expectToHaveDiagnostics([undefinedInArrayLiteral.code]); + } +); + +test("not allowed to use null or undefined in array literals ([undefined, null, 1])", () => { + util.testExpression`[undefined, null, 1]`.expectToHaveDiagnostics([ + undefinedInArrayLiteral.code, + undefinedInArrayLiteral.code, + ]); +}); + +test.each([ + "[]", + "[1, 2, undefined]", + "[1, 2, null]", + "[1, undefined, undefined, null]", + "[undefined]", + "[undefined, null]", +])("trailing undefined or null are allowed in array literal (%p)", literal => { + util.testExpression(literal).expectToHaveNoDiagnostics(); +}); From 26ac507e6fd925c9707013747f911a6d85ca9157 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Mar 2022 12:06:52 +0100 Subject: [PATCH 454/764] Function apply without arguments should not lead to exception (#1228) --- src/transformation/builtins/function.ts | 7 ++----- test/unit/functions/functions.spec.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index 3dfae1428..161660461 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -23,11 +23,8 @@ export function transformFunctionPrototypeCall( const expressionName = expression.name.text; switch (expressionName) { case "apply": - return lua.createCallExpression( - caller, - [params[0], createUnpackCall(context, params[1], node.arguments[1])], - node - ); + const nonContextArgs = params.length > 1 ? [createUnpackCall(context, params[1], node.arguments[1])] : []; + return lua.createCallExpression(caller, [params[0], ...nonContextArgs], node); case "bind": return transformLuaLibFunction(context, LuaLibFeature.FunctionBind, node, caller, ...params); case "call": diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 2d9d8f1e3..b5fc4bdfd 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -173,6 +173,14 @@ test("Function apply", () => { `.expectToMatchJsResult(); }); +// Fix #1226: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1226 +test("function apply without arguments should not lead to exception", () => { + util.testFunction` + const f = function (this: number) { return this + 3; } + return f.apply(4); + `.expectToMatchJsResult(); +}); + test("Function call", () => { util.testFunction` const abc = function (this: { a: number }, a: string) { return this.a + a; } From 3bae760d0b50ffa455d3c458f168915576bed202 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 13 Mar 2022 17:43:38 +0100 Subject: [PATCH 455/764] Allow configuring output file extension in config (#1229) --- src/CompilerOptions.ts | 1 + src/cli/parse.ts | 5 +++++ src/transpilation/transpiler.ts | 7 +++++-- test/cli/parse.spec.ts | 3 +++ test/transpile/paths.spec.ts | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 952de19ef..af9a9a75a 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -23,6 +23,7 @@ export interface LuaPluginImport { export type CompilerOptions = OmitIndexSignature & { buildMode?: BuildMode; + extension?: string; luaBundle?: string; luaBundleEntry?: string; luaTarget?: LuaTarget; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 37e809eb6..1a20880c9 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -30,6 +30,11 @@ export const optionDeclarations: CommandLineOption[] = [ type: "enum", choices: Object.values(BuildMode), }, + { + name: "extension", + description: 'File extension for the resulting Lua files. Defaults to ".lua"', + type: "string", + }, { name: "luaBundle", description: "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index e30410f73..22491ac7a 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -127,8 +127,11 @@ export function getEmitPathRelativeToOutDir(fileName: string, program: ts.Progra emitPathSplits[0] = "lua_modules"; } - // Make extension lua - emitPathSplits[emitPathSplits.length - 1] = trimExtension(emitPathSplits[emitPathSplits.length - 1]) + ".lua"; + // Set extension + const extension = ((program.getCompilerOptions() as CompilerOptions).extension ?? "lua").trim(); + const trimmedExtension = extension.startsWith(".") ? extension.substring(1) : extension; + emitPathSplits[emitPathSplits.length - 1] = + trimExtension(emitPathSplits[emitPathSplits.length - 1]) + "." + trimmedExtension; return path.join(...emitPathSplits); } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 17f68daf1..f40cf960c 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -123,6 +123,9 @@ describe("command line", () => { ["luaBundle", "foo", { luaBundle: "foo" }], ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], + + ["extension", ".lua", { extension: ".lua" }], + ["extension", "scar", { extension: "scar" }], ])("--%s %s", (optionName, value, expected) => { const result = tstl.parseCommandLine([`--${optionName}`, value]); diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts index 33d4f6258..0917307b8 100644 --- a/test/transpile/paths.spec.ts +++ b/test/transpile/paths.spec.ts @@ -113,6 +113,38 @@ describe("getEmitPath", () => { expect(fileNames).toHaveLength(1); expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.lua")); }); + + test.each([".scar", "scar"])("uses config extension (%p)", extension => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("main.ts") + .addExtraFile("dir/extra.ts", "") + .setOptions({ extension }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toContain("main.scar"); + expect(fileNames).toContain(path.join("dir", "extra.scar")); + }); + + test("bundle with different extension", () => { + const { transpiledFiles } = util.testModule`` + .setMainFileName("src/main.ts") + .addExtraFile("src/extra.ts", "") + .setOptions({ + configFilePath, + rootDir: "src", + outDir: "out1", + luaBundle: "out2/bundle.scar", + luaBundleEntry: "src/main.ts", + }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + const fileNames = transpiledFiles.map(f => f.outPath); + expect(fileNames).toHaveLength(1); + expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.scar")); + }); }); function normalize(path: string) { From 191c20b1faff969ab6af050ddbfa4e5d08d4587d Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 17 Mar 2022 12:44:47 -0700 Subject: [PATCH 456/764] Fix preceding statements with ternary operator (#1234) Fixes #1231 --- src/transformation/visitors/conditional.ts | 48 ++++++++++++++-------- test/unit/conditionals.spec.ts | 26 ++++++++++++ 2 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 518f658e5..566dc9f75 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -6,28 +6,30 @@ import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope" import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; +type EvaluatedExpression = [precedingStatemens: lua.Statement[], value: lua.Expression]; + function transformProtectedConditionalExpression( context: TransformationContext, - expression: ts.ConditionalExpression + expression: ts.ConditionalExpression, + condition: EvaluatedExpression, + whenTrue: EvaluatedExpression, + whenFalse: EvaluatedExpression ): lua.Expression { const tempVar = context.createTempNameForNode(expression.condition); - const condition = context.transformExpression(expression.condition); - - const [trueStatements, val1] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expression.whenTrue) + const trueStatements = whenTrue[0].concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue[1], expression.whenTrue) ); - trueStatements.push(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), val1, expression.whenTrue)); - const [falseStatements, val2] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expression.whenFalse) + const falseStatements = whenFalse[0].concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse[1], expression.whenFalse) ); - falseStatements.push(lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), val2, expression.whenFalse)); context.addPrecedingStatements([ lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition), + ...condition[0], lua.createIfStatement( - condition, + condition[1], lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression @@ -37,17 +39,27 @@ function transformProtectedConditionalExpression( } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { - if (canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue))) { - return transformProtectedConditionalExpression(context, expression); + const condition = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.condition) + ); + const whenTrue = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.whenTrue) + ); + const whenFalse = transformInPrecedingStatementScope(context, () => + context.transformExpression(expression.whenFalse) + ); + if ( + whenTrue[0].length > 0 || + whenFalse[0].length > 0 || + canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue)) + ) { + return transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse); } - const condition = context.transformExpression(expression.condition); - const val1 = context.transformExpression(expression.whenTrue); - const val2 = context.transformExpression(expression.whenFalse); - // condition and v1 or v2 - const conditionAnd = lua.createBinaryExpression(condition, val1, lua.SyntaxKind.AndOperator); - return lua.createBinaryExpression(conditionAnd, val2, lua.SyntaxKind.OrOperator, expression); + context.addPrecedingStatements(condition[0]); + const conditionAnd = lua.createBinaryExpression(condition[1], whenTrue[1], lua.SyntaxKind.AndOperator); + return lua.createBinaryExpression(conditionAnd, whenFalse[1], lua.SyntaxKind.OrOperator, expression); }; export function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): lua.IfStatement { diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 738ecacc1..a1a234cf6 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -112,3 +112,29 @@ test.each([false, true, null])("Ternary conditional with generic whenTrue branch }) .expectToMatchJsResult(); }); + +test.each([false, true])("Ternary conditional with preceding statements in true branch (%p)", trueVal => { + // language=TypeScript + util.testFunction` + let i = 0; + const result = ${trueVal} ? i += 1 : i; + return { result, i }; + ` + .setOptions({ + strictNullChecks: true, + }) + .expectToMatchJsResult(); +}); + +test.each([false, true])("Ternary conditional with preceding statements in false branch (%p)", trueVal => { + // language=TypeScript + util.testFunction` + let i = 0; + const result = ${trueVal} ? i : i += 2; + return { result, i }; + ` + .setOptions({ + strictNullChecks: true, + }) + .expectToMatchJsResult(); +}); From 3b41774172f4c799d6227cdc6fc49dc304f2aaa9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 17 Mar 2022 20:52:46 +0100 Subject: [PATCH 457/764] Fix prototype call check for nullable types (#1230) * Fix prototype call check for nullable types * Added extra test covering more types --- src/transformation/builtins/index.ts | 21 ++++++++++++--- src/transformation/utils/typescript/types.ts | 15 +++++++++++ test/unit/builtins/array.spec.ts | 12 +++++++++ test/unit/builtins/numbers.spec.ts | 12 +++++++++ test/unit/builtins/string.spec.ts | 27 ++++++++++++++++++++ test/unit/functions/functions.spec.ts | 12 +++++++++ 6 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index b56486425..94c5cb44f 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -9,6 +9,7 @@ import { hasStandardLibrarySignature, isArrayType, isFunctionType, + isNullableType, isNumberType, isStandardLibraryType, isStringType, @@ -115,22 +116,34 @@ export function transformBuiltinCallExpression( } } - if (isStringType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + const isStringFunction = + isStringType(context, ownerType) || + (expression.questionDotToken && isNullableType(context, ownerType, isStringType)); + if (isStringFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); return transformStringPrototypeCall(context, node); } - if (isNumberType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + const isNumberFunction = + isNumberType(context, ownerType) || + (expression.questionDotToken && isNullableType(context, ownerType, isNumberType)); + if (isNumberFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); return transformNumberPrototypeCall(context, node); } - if (isArrayType(context, ownerType) && hasStandardLibrarySignature(context, node)) { + const isArrayFunction = + isArrayType(context, ownerType) || + (expression.questionDotToken && isNullableType(context, ownerType, isArrayType)); + if (isArrayFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); return transformArrayPrototypeCall(context, node); } - if (isFunctionType(ownerType) && hasStandardLibrarySignature(context, node)) { + const isFunctionFunction = + isFunctionType(ownerType) || + (expression.questionDotToken && isNullableType(context, ownerType, (_, t) => isFunctionType(t))); + if (isFunctionFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); return transformFunctionPrototypeCall(context, node); } diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index cb1af0824..4be744f7e 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -60,6 +60,10 @@ export function typeCanSatisfy( return false; } +export function isNullishType(context: TransformationContext, type: ts.Type): boolean { + return isTypeWithFlags(context, type, ts.TypeFlags.Undefined | ts.TypeFlags.Null | ts.TypeFlags.VoidLike); +} + export function isStringType(context: TransformationContext, type: ts.Type): boolean { return isTypeWithFlags(context, type, ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral); } @@ -68,6 +72,17 @@ export function isNumberType(context: TransformationContext, type: ts.Type): boo return isTypeWithFlags(context, type, ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral); } +export function isNullableType( + context: TransformationContext, + type: ts.Type, + isType: (c: TransformationContext, t: ts.Type) => boolean +): boolean { + return ( + typeCanSatisfy(context, type, t => isType(context, t)) && + typeAlwaysSatisfies(context, type, t => isType(context, t) || isNullishType(context, t)) + ); +} + function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { if (type.symbol) { const baseConstraint = context.checker.getBaseConstraintOfType(type); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index aae630b78..eaeddf08e 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -700,3 +700,15 @@ test.each([ ])("trailing undefined or null are allowed in array literal (%p)", literal => { util.testExpression(literal).expectToHaveNoDiagnostics(); }); + +// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 +test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", value => { + util.testFunction` + function find(arr?: number[]) { + return arr?.indexOf(2); + } + return find(${value}); + ` + .setOptions({ strictNullChecks: true }) + .expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index ad9ae0c79..ab7e332a9 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -143,3 +143,15 @@ test.each([ ])("parseInt with base and trailing text (%p)", ({ numberString, base }) => { util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); }); + +// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 +test.each(["42", "undefined"])("prototype call on nullable number (%p)", value => { + util.testFunction` + function toString(n?: number) { + return n?.toString(); + } + return toString(${value}); + ` + .setOptions({ strictNullChecks: true }) + .expectToMatchJsResult(); +}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 70d7e2463..9bb7fbebf 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -367,3 +367,30 @@ test("string intersected method", () => { return ({ abc: () => "a" } as Vector).abc(); `.expectToMatchJsResult(); }); + +// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 +test.each(['"foo"', "undefined"])("prototype call on nullable string (%p)", value => { + util.testFunction` + function toUpper(str?: string) { + return str?.toUpperCase(); + } + return toUpper(${value}); + ` + .setOptions({ strictNullChecks: true }) + .expectToMatchJsResult(); +}); + +// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 +test.each(["string | undefined", "string | null", "null | string", "null | undefined | string"])( + "prototype call on nullable string type (%p)", + type => { + util.testFunction` + function toUpper(str: ${type}) { + return str?.toUpperCase(); + } + return toUpper("foo"); + ` + .setOptions({ strictNullChecks: true }) + .expectToMatchJsResult(); + } +); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index b5fc4bdfd..c5a488460 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -181,6 +181,18 @@ test("function apply without arguments should not lead to exception", () => { `.expectToMatchJsResult(); }); +// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 +test.each(["() => 4", "undefined"])("prototype call on nullable function (%p)", value => { + util.testFunction` + function call(f?: () => number) { + return f?.apply(3); + } + return call(${value}); + ` + .setOptions({ strictNullChecks: true }) + .expectToMatchJsResult(); +}); + test("Function call", () => { util.testFunction` const abc = function (this: { a: number }, a: string) { return this.a + a; } From fbb00d28107ae2a92bffc1f1a2c9df262b6fc97c Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 17 Mar 2022 20:57:11 +0100 Subject: [PATCH 458/764] Lualib modules using a plugin to generate lualib (#1227) * generate lualib with plugins * Copy over new lualib code * Lualib modules via plugin (#1224) * fix lualib-build * Finish lualib modules via plugin implementation * Include build-lualib.ts * Clean up lualib plugin with new plugin hooks * Fix mistake * Use plugin afterPrint results array to create bundle * Bundle lualib in correct order * Added tests for new plugin hooks * fix prettier * Remove lualibimport always option * updated snapshots * Remove obsolete error log * Use tstl CLI to build-lualib * Fix using tstl CLI to build lualib (#1233) Co-authored-by: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> --- build-lualib.js | 17 -- package.json | 3 +- src/CompilerOptions.ts | 1 - src/LuaLib.ts | 140 +++++++------- src/LuaPrinter.ts | 21 +-- src/index.ts | 1 + src/lualib-build/plugin.ts | 173 ++++++++++++++++++ src/lualib-build/util.ts | 47 +++++ src/lualib/ArrayConcat.ts | 2 +- src/lualib/ArrayEntries.ts | 2 +- src/lualib/ArrayEvery.ts | 2 +- src/lualib/ArrayFilter.ts | 2 +- src/lualib/ArrayFind.ts | 2 +- src/lualib/ArrayFindIndex.ts | 2 +- src/lualib/ArrayFlat.ts | 2 +- src/lualib/ArrayFlatMap.ts | 2 +- src/lualib/ArrayForEach.ts | 2 +- src/lualib/ArrayIncludes.ts | 2 +- src/lualib/ArrayIndexOf.ts | 2 +- src/lualib/ArrayIsArray.ts | 2 +- src/lualib/ArrayJoin.ts | 2 +- src/lualib/ArrayMap.ts | 6 +- src/lualib/ArrayPush.ts | 2 +- src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArrayReverse.ts | 2 +- src/lualib/ArraySetLength.ts | 2 +- src/lualib/ArrayShift.ts | 2 +- src/lualib/ArraySlice.ts | 2 +- src/lualib/ArraySome.ts | 2 +- src/lualib/ArraySort.ts | 2 +- src/lualib/ArraySplice.ts | 2 +- src/lualib/ArrayToObject.ts | 2 +- src/lualib/ArrayUnshift.ts | 2 +- src/lualib/Await.ts | 6 +- src/lualib/Class.ts | 2 +- src/lualib/ClassExtends.ts | 2 +- src/lualib/CloneDescriptor.ts | 2 +- src/lualib/Decorate.ts | 11 +- src/lualib/DecorateParam.ts | 4 +- src/lualib/Decorator.d.ts | 5 + src/lualib/DelegatedYield.ts | 4 +- src/lualib/Delete.ts | 4 +- src/lualib/Error.ts | 26 ++- src/lualib/FunctionBind.ts | 2 +- src/lualib/Generator.ts | 16 +- src/lualib/GeneratorIterator.d.ts | 5 + src/lualib/InstanceOf.ts | 2 +- src/lualib/InstanceOfObject.ts | 2 +- src/lualib/Iterator.ts | 16 +- src/lualib/Map.ts | 4 +- src/lualib/MathAtan2.ts | 2 +- src/lualib/MathSign.ts | 2 +- src/lualib/New.ts | 2 +- src/lualib/Number.ts | 2 +- src/lualib/NumberIsFinite.ts | 2 +- src/lualib/NumberIsNaN.ts | 2 +- src/lualib/NumberToString.ts | 8 +- src/lualib/ObjectAssign.ts | 2 +- src/lualib/ObjectDefineProperty.ts | 9 +- src/lualib/ObjectEntries.ts | 2 +- src/lualib/ObjectFromEntries.ts | 2 +- src/lualib/ObjectGetOwnPropertyDescriptor.ts | 6 +- src/lualib/ObjectGetOwnPropertyDescriptors.ts | 5 +- src/lualib/ObjectKeys.ts | 2 +- src/lualib/ObjectRest.ts | 2 +- src/lualib/ObjectValues.ts | 2 +- src/lualib/ParseFloat.ts | 2 +- src/lualib/ParseInt.ts | 8 +- src/lualib/Promise.ts | 39 ++-- src/lualib/PromiseAll.ts | 8 +- src/lualib/PromiseAllSettled.ts | 8 +- src/lualib/PromiseAny.ts | 8 +- src/lualib/PromiseRace.ts | 8 +- src/lualib/Set.ts | 4 +- src/lualib/SetDescriptor.ts | 18 +- src/lualib/SourceMapTraceBack.ts | 9 +- src/lualib/SparseArray.d.ts | 1 + src/lualib/SparseArrayNew.ts | 4 +- src/lualib/SparseArrayPush.ts | 4 +- src/lualib/SparseArraySpread.ts | 4 +- src/lualib/Spread.ts | 2 +- src/lualib/StringAccess.ts | 2 +- src/lualib/StringCharAt.ts | 2 +- src/lualib/StringCharCodeAt.ts | 2 +- src/lualib/StringConcat.ts | 2 +- src/lualib/StringEndsWith.ts | 2 +- src/lualib/StringIncludes.ts | 2 +- src/lualib/StringPadEnd.ts | 2 +- src/lualib/StringPadStart.ts | 2 +- src/lualib/StringReplace.ts | 2 +- src/lualib/StringReplaceAll.ts | 2 +- src/lualib/StringSlice.ts | 2 +- src/lualib/StringSplit.ts | 2 +- src/lualib/StringStartsWith.ts | 2 +- src/lualib/StringSubstr.ts | 2 +- src/lualib/StringSubstring.ts | 2 +- src/lualib/StringTrim.ts | 2 +- src/lualib/StringTrimEnd.ts | 2 +- src/lualib/StringTrimStart.ts | 2 +- src/lualib/Symbol.ts | 8 +- src/lualib/SymbolRegistry.ts | 17 +- src/lualib/TypeOf.ts | 2 +- src/lualib/Unpack.ts | 2 +- src/lualib/WeakMap.ts | 4 +- src/lualib/WeakSet.ts | 4 +- src/lualib/tsconfig.json | 3 +- src/transformation/builtins/index.ts | 63 +++++-- src/transformation/visitors/class/index.ts | 7 +- src/transformation/visitors/class/new.ts | 46 +---- src/transformation/visitors/identifier.ts | 9 +- src/transformation/visitors/modules/import.ts | 16 +- src/transpilation/bundle.ts | 2 +- src/transpilation/plugins.ts | 18 +- src/transpilation/transpile.ts | 14 ++ test/cli/parse.spec.ts | 2 - .../__snapshots__/transformation.spec.ts.snap | 9 +- .../__snapshots__/directories.spec.ts.snap | 4 - test/transpile/directories.spec.ts | 2 +- test/transpile/lualib.spec.ts | 41 +++-- test/transpile/module-resolution.spec.ts | 3 +- test/transpile/plugins/afterPrint.ts | 22 +++ test/transpile/plugins/beforeTransform.ts | 15 ++ test/transpile/plugins/plugins.spec.ts | 34 +++- .../__snapshots__/expressions.spec.ts.snap | 12 +- .../optionalChaining.spec.ts.snap | 3 +- test/unit/__snapshots__/switch.spec.ts.snap | 9 +- .../customConstructor.spec.ts.snap | 4 +- .../__snapshots__/deprecated.spec.ts.snap | 15 +- test/unit/builtins/loading.spec.ts | 7 - test/unit/builtins/set.spec.ts | 7 + .../__snapshots__/classes.spec.ts.snap | 3 +- .../__snapshots__/decorators.spec.ts.snap | 4 +- .../__snapshots__/range.spec.ts.snap | 6 +- test/unit/printer/sourcemaps.spec.ts | 2 +- 135 files changed, 800 insertions(+), 406 deletions(-) delete mode 100644 build-lualib.js create mode 100644 src/lualib-build/plugin.ts create mode 100644 src/lualib-build/util.ts create mode 100644 src/lualib/Decorator.d.ts create mode 100644 src/lualib/GeneratorIterator.d.ts create mode 100644 src/lualib/SparseArray.d.ts create mode 100644 test/transpile/plugins/afterPrint.ts create mode 100644 test/transpile/plugins/beforeTransform.ts diff --git a/build-lualib.js b/build-lualib.js deleted file mode 100644 index 41ece7e32..000000000 --- a/build-lualib.js +++ /dev/null @@ -1,17 +0,0 @@ -require("ts-node/register/transpile-only"); -const fs = require("fs"); -const path = require("path"); -const ts = require("typescript"); -const tstl = require("./src"); -const { loadLuaLibFeatures } = require("./src/LuaLib"); - -const configFileName = path.resolve(__dirname, "src/lualib/tsconfig.json"); -const { diagnostics } = tstl.transpileProject(configFileName); -diagnostics.forEach(tstl.createDiagnosticReporter(true)); - -const bundlePath = path.join(__dirname, "dist/lualib/lualib_bundle.lua"); -if (fs.existsSync(bundlePath)) { - fs.unlinkSync(bundlePath); -} - -fs.writeFileSync(bundlePath, loadLuaLibFeatures(Object.values(tstl.LuaLibFeature), ts.sys)); diff --git a/package.json b/package.json index 320b3d17b..ae73f35b6 100644 --- a/package.json +++ b/package.json @@ -18,13 +18,14 @@ "dist/**/*.js", "dist/**/*.lua", "dist/**/*.ts", + "dist/lualib/*.json", "language-extensions/**/*.ts" ], "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc && npm run build-lualib", - "build-lualib": "node build-lualib.js", + "build-lualib": "node dist/tstl.js -p src/lualib/tsconfig.json", "pretest": "npm run lint && npm run check:language-extensions && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index af9a9a75a..1e1ba8c72 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -40,7 +40,6 @@ export type CompilerOptions = OmitIndexSignature & { export enum LuaLibImportKind { None = "none", - Always = "always", Inline = "inline", Require = "require", } diff --git a/src/LuaLib.ts b/src/LuaLib.ts index e4321d181..e5df8927a 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,5 +1,6 @@ import * as path from "path"; import { EmitHost } from "./transpilation"; +import * as lua from "./LuaAST"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -99,81 +100,54 @@ export enum LuaLibFeature { Unpack = "Unpack", } -/* eslint-disable @typescript-eslint/naming-convention */ -const luaLibDependencies: Partial> = { - ArrayConcat: [LuaLibFeature.ArrayIsArray], - ArrayFlat: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], - ArrayFlatMap: [LuaLibFeature.ArrayConcat, LuaLibFeature.ArrayIsArray], - Await: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise], - Decorate: [LuaLibFeature.ObjectGetOwnPropertyDescriptor, LuaLibFeature.SetDescriptor, LuaLibFeature.ObjectAssign], - DelegatedYield: [LuaLibFeature.StringAccess], - Delete: [LuaLibFeature.ObjectGetOwnPropertyDescriptors, LuaLibFeature.Error, LuaLibFeature.New], - Error: [LuaLibFeature.Class, LuaLibFeature.ClassExtends, LuaLibFeature.New], - FunctionBind: [LuaLibFeature.Unpack], - Generator: [LuaLibFeature.Symbol], - InstanceOf: [LuaLibFeature.Symbol], - Iterator: [LuaLibFeature.Symbol], - NumberToString: [LuaLibFeature.StringAccess], - ObjectDefineProperty: [LuaLibFeature.CloneDescriptor, LuaLibFeature.SetDescriptor], - ObjectFromEntries: [LuaLibFeature.Iterator, LuaLibFeature.Symbol], - Promise: [ - LuaLibFeature.ArrayPush, - LuaLibFeature.Class, - LuaLibFeature.FunctionBind, - LuaLibFeature.InstanceOf, - LuaLibFeature.New, - ], - PromiseAll: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], - PromiseAllSettled: [LuaLibFeature.InstanceOf, LuaLibFeature.New, LuaLibFeature.Promise, LuaLibFeature.Iterator], - PromiseAny: [ - LuaLibFeature.ArrayPush, - LuaLibFeature.InstanceOf, - LuaLibFeature.New, - LuaLibFeature.Promise, - LuaLibFeature.Iterator, - ], - PromiseRace: [ - LuaLibFeature.ArrayPush, - LuaLibFeature.InstanceOf, - LuaLibFeature.New, - LuaLibFeature.Promise, - LuaLibFeature.Iterator, - ], - ParseFloat: [LuaLibFeature.StringAccess], - ParseInt: [LuaLibFeature.StringSubstr, LuaLibFeature.StringSubstring], - SetDescriptor: [LuaLibFeature.CloneDescriptor], - Spread: [LuaLibFeature.Iterator, LuaLibFeature.StringAccess, LuaLibFeature.Unpack], - StringSplit: [LuaLibFeature.StringSubstring, LuaLibFeature.StringAccess], - SymbolRegistry: [LuaLibFeature.Symbol], - - Map: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], - WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol, LuaLibFeature.Class], -}; -/* eslint-enable @typescript-eslint/naming-convention */ - -export function loadLuaLibFeatures(features: Iterable, emitHost: EmitHost): string { - let result = ""; +export interface LuaLibFeatureInfo { + dependencies?: LuaLibFeature[]; + exports: string[]; +} +export type LuaLibModulesInfo = Record; + +export const luaLibModulesInfoFileName = "lualib_module_info.json"; +let luaLibModulesInfo: LuaLibModulesInfo | undefined; +export function getLuaLibModulesInfo(emitHost: EmitHost): LuaLibModulesInfo { + if (luaLibModulesInfo === undefined) { + const lualibPath = path.resolve(__dirname, `../dist/lualib/${luaLibModulesInfoFileName}`); + const result = emitHost.readFile(lualibPath); + if (result !== undefined) { + luaLibModulesInfo = JSON.parse(result) as LuaLibModulesInfo; + } else { + throw new Error(`Could not load lualib dependencies from '${lualibPath}'`); + } + } + return luaLibModulesInfo; +} +export function readLuaLibFeature(feature: LuaLibFeature, emitHost: EmitHost): string { + const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); + const luaLibFeature = emitHost.readFile(featurePath); + if (luaLibFeature === undefined) { + throw new Error(`Could not load lualib feature from '${featurePath}'`); + } + return luaLibFeature; +} + +export function resolveRecursiveLualibFeatures( + features: Iterable, + emitHost: EmitHost, + luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModulesInfo(emitHost) +): LuaLibFeature[] { const loadedFeatures = new Set(); + const result: LuaLibFeature[] = []; function load(feature: LuaLibFeature): void { if (loadedFeatures.has(feature)) return; loadedFeatures.add(feature); - const dependencies = luaLibDependencies[feature]; + const dependencies = luaLibModulesInfo[feature]?.dependencies; if (dependencies) { dependencies.forEach(load); } - const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - const luaLibFeature = emitHost.readFile(featurePath); - if (luaLibFeature !== undefined) { - result += luaLibFeature + "\n"; - } else { - throw new Error(`Could not load lualib feature from '${featurePath}'`); - } + result.push(feature); } for (const feature of features) { @@ -183,6 +157,44 @@ export function loadLuaLibFeatures(features: Iterable, emitHost: return result; } +export function loadInlineLualibFeatures(features: Iterable, emitHost: EmitHost): string { + let result = ""; + + for (const feature of resolveRecursiveLualibFeatures(features, emitHost)) { + const luaLibFeature = readLuaLibFeature(feature, emitHost); + result += luaLibFeature + "\n"; + } + + return result; +} + +export function loadImportedLualibFeatures(features: Iterable, emitHost: EmitHost): lua.Statement[] { + const luaLibModuleInfo = getLuaLibModulesInfo(emitHost); + + const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports); + + const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [ + lua.createStringLiteral("lualib_bundle"), + ]); + if (imports.length === 0) { + return []; + } + + const luaLibId = lua.createIdentifier("____lualib"); + const importStatement = lua.createVariableDeclarationStatement(luaLibId, requireCall); + const statements: lua.Statement[] = [importStatement]; + // local = ____luaLib. + for (const item of imports) { + statements.push( + lua.createVariableDeclarationStatement( + lua.createIdentifier(item), + lua.createTableIndexExpression(luaLibId, lua.createStringLiteral(item)) + ) + ); + } + return statements; +} + let luaLibBundleContent: string; export function getLuaLibBundle(emitHost: EmitHost): string { if (luaLibBundleContent === undefined) { diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index dc75b4a9b..cc8a6fa46 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,12 +1,11 @@ import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; -import { getEmitPath } from "."; import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; import * as lua from "./LuaAST"; -import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib"; +import { loadInlineLualibFeatures, LuaLibFeature, loadImportedLualibFeatures } from "./LuaLib"; import { isValidLuaIdentifier, shouldAllowUnicode } from "./transformation/utils/safe-names"; -import { EmitHost } from "./transpilation"; +import { EmitHost, getEmitPath } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; // https://www.lua.org/pil/2.4.html @@ -233,18 +232,18 @@ export class LuaPrinter { if (!this.options.noHeader) { header += tstlHeader; } + let statements = file.statements; const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; - if ( - luaLibImport === LuaLibImportKind.Always || - (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) - ) { - // Require lualib bundle - header += 'require("lualib_bundle");\n'; + if (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) { + // Import lualib features + const importStatements = loadImportedLualibFeatures(file.luaLibFeatures, this.emitHost); + + statements = importStatements.concat(statements); } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features header += "-- Lua Library inline imports\n"; - header += loadLuaLibFeatures(file.luaLibFeatures, this.emitHost); + header += loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost); } if (this.options.sourceMapTraceback && !isBundleEnabled(this.options)) { @@ -253,7 +252,7 @@ export class LuaPrinter { header += `${LuaPrinter.sourceMapTracebackPlaceholder}\n`; } - return this.concatNodes(header, ...this.printStatementArray(file.statements)); + return this.concatNodes(header, ...this.printStatementArray(statements)); } protected pushIndent(): void { diff --git a/src/index.ts b/src/index.ts index 3d060a994..0b994c7f6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,3 +8,4 @@ export { LuaLibFeature } from "./LuaLib"; export * from "./LuaPrinter"; export * from "./transformation/context"; export * from "./transpilation"; +export { ProcessedFile } from "./transpilation/utils"; diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts new file mode 100644 index 000000000..a14c8917a --- /dev/null +++ b/src/lualib-build/plugin.ts @@ -0,0 +1,173 @@ +import { SourceNode } from "source-map"; +import * as ts from "typescript"; +import * as tstl from ".."; +import * as path from "path"; +import { getUsedLuaLibFeatures } from "../transformation/utils/lualib"; +import { LuaLibFeature, LuaLibModulesInfo, luaLibModulesInfoFileName, resolveRecursiveLualibFeatures } from "../LuaLib"; +import { EmitHost, ProcessedFile } from "../transpilation/utils"; +import { + isExportAlias, + isExportAssignment, + isExportsReturn, + isExportTableDeclaration, + isImport, + isRequire, +} from "./util"; +import { createDiagnosticFactoryWithCode } from "../utils"; + +export const lualibDiagnostic = createDiagnosticFactoryWithCode(200000, (message: string, file?: ts.SourceFile) => ({ + messageText: message, + file, + start: file && 0, + length: file && 0, +})); + +class LuaLibPlugin implements tstl.Plugin { + // Plugin members + public visitors = { + [ts.SyntaxKind.SourceFile]: this.lualibFileVisitor.bind(this), + }; + + public printer: tstl.Printer = (program, emitHost, fileName, file) => + new LuaLibPrinter(emitHost, program, fileName).print(file); + + public afterPrint(program: ts.Program, options: tstl.CompilerOptions, emitHost: EmitHost, result: ProcessedFile[]) { + void options; + + // Write lualib dependency json + const { result: luaLibModuleInfo, diagnostics } = this.createLuaLibModulesInfo(); + const emitBOM = options.emitBOM ?? false; + emitHost.writeFile( + path.join(tstl.getEmitOutDir(program), luaLibModulesInfoFileName), + JSON.stringify(luaLibModuleInfo, null, 2), + emitBOM + ); + + // Create map of result files keyed by their 'lualib name' + const exportedLualibFeatures = new Map(result.map(f => [path.basename(f.fileName).split(".")[0], f.code])); + + // Figure out the order required in the bundle by recursively resolving all dependency features + const allFeatures = Object.values(LuaLibFeature) as LuaLibFeature[]; + const orderedFeatures = resolveRecursiveLualibFeatures(allFeatures, emitHost, luaLibModuleInfo); + + // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results + let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLibFeature[f])).join("\n"); + const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports); + lualibBundle += `\nreturn {\n${exports.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; + result.push({ fileName: "lualib_bundle.lua", code: lualibBundle }); + + return diagnostics; + } + + // Internals + protected featureExports: Map> = new Map(); + protected featureDependencies: Map> = new Map(); + + protected lualibFileVisitor(file: ts.SourceFile, context: tstl.TransformationContext): tstl.File { + const featureName = path.basename(file.fileName, ".ts") as tstl.LuaLibFeature; + if (!(featureName in tstl.LuaLibFeature)) { + context.diagnostics.push(lualibDiagnostic(`File is not a lualib feature: ${featureName}`, file)); + } + + // Transpile file as normal with tstl + const fileResult = context.superTransformNode(file)[0] as tstl.File; + + const usedFeatures = new Set(getUsedLuaLibFeatures(context)); + + // Get all imports in file + const importNames = new Set(); + const imports = file.statements.filter(ts.isImportDeclaration); + for (const { importClause, moduleSpecifier } of imports) { + if (importClause?.namedBindings && ts.isNamedImports(importClause.namedBindings)) { + for (const { name } of importClause.namedBindings.elements) { + importNames.add(name.text); + } + } + // track lualib imports + if (ts.isStringLiteral(moduleSpecifier)) { + const featureName = path.basename(moduleSpecifier.text, ".ts") as tstl.LuaLibFeature; + if (featureName in tstl.LuaLibFeature) { + usedFeatures.add(featureName); + } + } + } + + const filteredStatements = fileResult.statements + .filter( + s => !isExportTableDeclaration(s) && !isRequire(s) && !isImport(s, importNames) && !isExportsReturn(s) + ) + .map(statement => { + if (isExportAlias(statement)) { + const name = statement.left[0]; + const exportName = statement.right[0].index.value; + if (name.text === exportName) return undefined; // Remove "x = x" statements + return tstl.createAssignmentStatement(name, tstl.createIdentifier(exportName)); + } + return statement; + }) + .filter(statement => statement !== undefined) as tstl.Statement[]; + + const exportNames = filteredStatements.filter(isExportAssignment).map(s => s.left[0].index.value); + if (!filteredStatements.every(isExportAssignment)) { + // If there are local statements, wrap them in a do ... end with exports outside + const exports = tstl.createVariableDeclarationStatement(exportNames.map(k => tstl.createIdentifier(k))); + // transform export assignments to local assignments + const bodyStatements = filteredStatements.map(s => + isExportAssignment(s) + ? tstl.createAssignmentStatement(tstl.createIdentifier(s.left[0].index.value), s.right[0]) + : s + ); + + fileResult.statements = [exports, tstl.createDoStatement(bodyStatements)]; + } else { + // transform export assignments to local variable declarations + fileResult.statements = filteredStatements.map(s => + tstl.createVariableDeclarationStatement(tstl.createIdentifier(s.left[0].index.value), s.right[0]) + ); + } + + // Save dependency information + this.featureExports.set(featureName, new Set(exportNames)); + if (usedFeatures.size > 0) { + this.featureDependencies.set(featureName, usedFeatures); + } + + return fileResult; + } + + protected createLuaLibModulesInfo(): { result: LuaLibModulesInfo; diagnostics: ts.Diagnostic[] } { + const result: Partial = {}; + const diagnostics: ts.Diagnostic[] = []; + for (const feature of Object.values(tstl.LuaLibFeature)) { + const exports = this.featureExports.get(feature); + if (!exports) { + diagnostics.push(lualibDiagnostic(`Missing file for lualib feature: ${feature}`)); + continue; + } + const dependencies = this.featureDependencies.get(feature); + result[feature] = { + exports: Array.from(exports), + dependencies: dependencies ? Array.from(dependencies) : undefined, + }; + } + return { result: result as LuaLibModulesInfo, diagnostics }; + } +} + +class LuaLibPrinter extends tstl.LuaPrinter { + // Strip all exports during print + public printTableIndexExpression(expression: tstl.TableIndexExpression): SourceNode { + if ( + tstl.isIdentifier(expression.table) && + expression.table.text === "____exports" && + tstl.isStringLiteral(expression.index) + ) { + return super.printExpression(tstl.createIdentifier(expression.index.value)); + } + return super.printTableIndexExpression(expression); + } +} + +const pluginInstance = new LuaLibPlugin(); +// eslint-disable-next-line import/no-default-export +export default pluginInstance; diff --git a/src/lualib-build/util.ts b/src/lualib-build/util.ts new file mode 100644 index 000000000..c8ea1e3a8 --- /dev/null +++ b/src/lualib-build/util.ts @@ -0,0 +1,47 @@ +import * as tstl from ".."; + +export function isExportTableDeclaration(node: tstl.Node): node is tstl.VariableDeclarationStatement & { left: [] } { + return tstl.isVariableDeclarationStatement(node) && isExportTable(node.left[0]); +} + +export function isExportTable(node: tstl.Node): node is tstl.Identifier { + return tstl.isIdentifier(node) && node.text === "____exports"; +} + +export type ExportTableIndex = tstl.TableIndexExpression & { index: tstl.StringLiteral }; +export function isExportTableIndex(node: tstl.Node): node is ExportTableIndex { + return tstl.isTableIndexExpression(node) && isExportTable(node.table) && tstl.isStringLiteral(node.index); +} + +export function isExportAlias( + node: tstl.Node +): node is tstl.VariableDeclarationStatement & { right: [ExportTableIndex] } { + return tstl.isVariableDeclarationStatement(node) && node.right !== undefined && isExportTableIndex(node.right[0]); +} + +export type ExportAssignment = tstl.AssignmentStatement & { left: [ExportTableIndex] }; +export function isExportAssignment(node: tstl.Node): node is ExportAssignment { + return tstl.isAssignmentStatement(node) && isExportTableIndex(node.left[0]); +} + +export function isRequire(node: tstl.Node) { + return ( + tstl.isVariableDeclarationStatement(node) && + node.right && + tstl.isCallExpression(node.right[0]) && + tstl.isIdentifier(node.right[0].expression) && + node.right[0].expression.text === "require" + ); +} + +export function isImport(node: tstl.Node, importNames: Set) { + return tstl.isVariableDeclarationStatement(node) && importNames.has(node.left[0].text); +} + +export function isExportsReturn(node: tstl.Node) { + return ( + tstl.isReturnStatement(node) && + tstl.isIdentifier(node.expressions[0]) && + node.expressions[0].text === "____exports" + ); +} diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index 30da83514..56f3d1b5f 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -1,4 +1,4 @@ -function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { +export function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { const out: any[] = []; for (const val of arr1) { out[out.length] = val; diff --git a/src/lualib/ArrayEntries.ts b/src/lualib/ArrayEntries.ts index 7d12f1347..6cdef13a3 100644 --- a/src/lualib/ArrayEntries.ts +++ b/src/lualib/ArrayEntries.ts @@ -1,5 +1,5 @@ // https://262.ecma-international.org/10.0/#sec-array.prototype.entries -function __TS__ArrayEntries(this: void, array: T[]): IterableIterator<[number, T]> { +export function __TS__ArrayEntries(this: void, array: T[]): IterableIterator<[number, T]> { let key = 0; return { [Symbol.iterator](): IterableIterator<[number, T]> { diff --git a/src/lualib/ArrayEvery.ts b/src/lualib/ArrayEvery.ts index 011dd9abe..43dd312ea 100644 --- a/src/lualib/ArrayEvery.ts +++ b/src/lualib/ArrayEvery.ts @@ -1,4 +1,4 @@ -function __TS__ArrayEvery( +export function __TS__ArrayEvery( this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean diff --git a/src/lualib/ArrayFilter.ts b/src/lualib/ArrayFilter.ts index 3d88ddffa..0559a02d6 100644 --- a/src/lualib/ArrayFilter.ts +++ b/src/lualib/ArrayFilter.ts @@ -1,4 +1,4 @@ -function __TS__ArrayFilter( +export function __TS__ArrayFilter( this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean diff --git a/src/lualib/ArrayFind.ts b/src/lualib/ArrayFind.ts index 608bd3ef6..a9a0efc70 100644 --- a/src/lualib/ArrayFind.ts +++ b/src/lualib/ArrayFind.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.find -function __TS__ArrayFind( +export function __TS__ArrayFind( this: void, arr: T[], predicate: (value: T, index: number, obj: T[]) => unknown diff --git a/src/lualib/ArrayFindIndex.ts b/src/lualib/ArrayFindIndex.ts index 53d83cb39..945fed18d 100644 --- a/src/lualib/ArrayFindIndex.ts +++ b/src/lualib/ArrayFindIndex.ts @@ -1,4 +1,4 @@ -function __TS__ArrayFindIndex( +export function __TS__ArrayFindIndex( this: void, arr: T[], callbackFn: (element: T, index?: number, array?: T[]) => boolean diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index 2bed314cb..b98861aeb 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,4 +1,4 @@ -function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { +export function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { let result: any[] = []; for (const value of array) { if (depth > 0 && Array.isArray(value)) { diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index c31af9046..29f92c1f5 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -1,4 +1,4 @@ -function __TS__ArrayFlatMap( +export function __TS__ArrayFlatMap( this: void, array: T[], callback: (value: T, index: number, array: T[]) => U | readonly U[] diff --git a/src/lualib/ArrayForEach.ts b/src/lualib/ArrayForEach.ts index 96ac4a806..37a610433 100644 --- a/src/lualib/ArrayForEach.ts +++ b/src/lualib/ArrayForEach.ts @@ -1,4 +1,4 @@ -function __TS__ArrayForEach( +export function __TS__ArrayForEach( this: void, arr: T[], callbackFn: (value: T, index?: number, array?: any[]) => any diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts index b012f87bf..88e788a15 100644 --- a/src/lualib/ArrayIncludes.ts +++ b/src/lualib/ArrayIncludes.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.includes -function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boolean { +export function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = 0): boolean { const len = this.length; let k = fromIndex; diff --git a/src/lualib/ArrayIndexOf.ts b/src/lualib/ArrayIndexOf.ts index e91a1a5dc..1631caf76 100644 --- a/src/lualib/ArrayIndexOf.ts +++ b/src/lualib/ArrayIndexOf.ts @@ -1,4 +1,4 @@ -function __TS__ArrayIndexOf(this: void, arr: T[], searchElement: T, fromIndex?: number): number { +export function __TS__ArrayIndexOf(this: void, arr: T[], searchElement: T, fromIndex?: number): number { const len = arr.length; if (len === 0) { return -1; diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts index 417ae6e6e..7d2ec3112 100644 --- a/src/lualib/ArrayIsArray.ts +++ b/src/lualib/ArrayIsArray.ts @@ -1,6 +1,6 @@ declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; -function __TS__ArrayIsArray(this: void, value: any): value is any[] { +export function __TS__ArrayIsArray(this: void, value: any): value is any[] { // Workaround to determine if value is an array or not (fails in case of objects without keys) // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); diff --git a/src/lualib/ArrayJoin.ts b/src/lualib/ArrayJoin.ts index 33e220181..7400b886e 100644 --- a/src/lualib/ArrayJoin.ts +++ b/src/lualib/ArrayJoin.ts @@ -1,4 +1,4 @@ -function __TS__ArrayJoin(this: unknown[], separator = ",") { +export function __TS__ArrayJoin(this: unknown[], separator = ",") { let result = ""; for (const [index, value] of ipairs(this)) { if (index > 1) result += separator; diff --git a/src/lualib/ArrayMap.ts b/src/lualib/ArrayMap.ts index 04ee22a48..7e9c868fa 100644 --- a/src/lualib/ArrayMap.ts +++ b/src/lualib/ArrayMap.ts @@ -1,4 +1,8 @@ -function __TS__ArrayMap(this: void, arr: T[], callbackfn: (value: T, index?: number, array?: T[]) => U): U[] { +export function __TS__ArrayMap( + this: void, + arr: T[], + callbackfn: (value: T, index?: number, array?: T[]) => U +): U[] { const newArray: U[] = []; for (let i = 0; i < arr.length; i++) { newArray[i] = callbackfn(arr[i], i, arr); diff --git a/src/lualib/ArrayPush.ts b/src/lualib/ArrayPush.ts index f09005e44..39d4f241e 100644 --- a/src/lualib/ArrayPush.ts +++ b/src/lualib/ArrayPush.ts @@ -1,4 +1,4 @@ -function __TS__ArrayPush(this: void, arr: T[], ...items: T[]): number { +export function __TS__ArrayPush(this: void, arr: T[], ...items: T[]): number { for (const item of items) { arr[arr.length] = item; } diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 5ac7bd856..737128cd0 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduce( +export function __TS__ArrayReduce( this: void, arr: TElement[], callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 26258b862..91099946a 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce -function __TS__ArrayReduceRight( +export function __TS__ArrayReduceRight( this: void, arr: TElement[], callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, diff --git a/src/lualib/ArrayReverse.ts b/src/lualib/ArrayReverse.ts index b4a97a2c1..e644355d9 100644 --- a/src/lualib/ArrayReverse.ts +++ b/src/lualib/ArrayReverse.ts @@ -1,4 +1,4 @@ -function __TS__ArrayReverse(this: void, arr: any[]): any[] { +export function __TS__ArrayReverse(this: void, arr: any[]): any[] { let i = 0; let j = arr.length - 1; while (i < j) { diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index e1bd8ea03..6fde3254d 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -1,4 +1,4 @@ -function __TS__ArraySetLength(this: void, arr: T[], length: number): number { +export function __TS__ArraySetLength(this: void, arr: T[], length: number): number { if ( length < 0 || length !== length || // NaN diff --git a/src/lualib/ArrayShift.ts b/src/lualib/ArrayShift.ts index e39d9616b..799463d9d 100644 --- a/src/lualib/ArrayShift.ts +++ b/src/lualib/ArrayShift.ts @@ -1,3 +1,3 @@ -function __TS__ArrayShift(this: void, arr: T[]): T { +export function __TS__ArrayShift(this: void, arr: T[]): T { return table.remove(arr, 1); } diff --git a/src/lualib/ArraySlice.ts b/src/lualib/ArraySlice.ts index d38d96006..e9797c43f 100644 --- a/src/lualib/ArraySlice.ts +++ b/src/lualib/ArraySlice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.slice -function __TS__ArraySlice(this: void, list: T[], first: number, last: number): T[] { +export function __TS__ArraySlice(this: void, list: T[], first: number, last: number): T[] { const len = list.length; const relativeStart = first || 0; diff --git a/src/lualib/ArraySome.ts b/src/lualib/ArraySome.ts index 9122b1bbc..1c4725d4c 100644 --- a/src/lualib/ArraySome.ts +++ b/src/lualib/ArraySome.ts @@ -1,4 +1,4 @@ -function __TS__ArraySome( +export function __TS__ArraySome( this: void, arr: T[], callbackfn: (value: T, index?: number, array?: any[]) => boolean diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts index 1855c3bb5..034344f76 100644 --- a/src/lualib/ArraySort.ts +++ b/src/lualib/ArraySort.ts @@ -1,4 +1,4 @@ -function __TS__ArraySort(this: void, arr: T[], compareFn?: (a: T, b: T) => number): T[] { +export function __TS__ArraySort(this: void, arr: T[], compareFn?: (a: T, b: T) => number): T[] { if (compareFn !== undefined) { table.sort(arr, (a, b) => compareFn(a, b) < 0); } else { diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index d4a122181..273525ed0 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,5 +1,5 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { +export function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { const len = list.length; const actualArgumentCount = select("#", ...args); diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts index 460a77250..e3ed41f78 100644 --- a/src/lualib/ArrayToObject.ts +++ b/src/lualib/ArrayToObject.ts @@ -1,4 +1,4 @@ -function __TS__ArrayToObject(this: void, array: T[]): Record { +export function __TS__ArrayToObject(this: void, array: T[]): Record { const object: Record = {}; for (let i = 0; i < array.length; i += 1) { object[i] = array[i]; diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts index 95dc15b8f..c3dd6bdb4 100644 --- a/src/lualib/ArrayUnshift.ts +++ b/src/lualib/ArrayUnshift.ts @@ -1,4 +1,4 @@ -function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { +export function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { for (let i = items.length - 1; i >= 0; --i) { table.insert(arr, 1, items[i]); } diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index a3139d88e..acb9607e4 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -14,10 +14,12 @@ // }; // +import { __TS__Promise } from "./Promise"; + type ErrorHandler = (this: void, error: unknown) => unknown; // eslint-disable-next-line @typescript-eslint/promise-function-async -function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { +export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { return new Promise((resolve, reject) => { const asyncCoroutine = coroutine.create(generator); @@ -70,6 +72,6 @@ function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { }); } -function __TS__Await(this: void, errorHandler: ErrorHandler, thing: unknown) { +export function __TS__Await(this: void, errorHandler: ErrorHandler, thing: unknown) { return coroutine.yield(errorHandler, thing); } diff --git a/src/lualib/Class.ts b/src/lualib/Class.ts index d5d7af93d..bdcd7ce4f 100644 --- a/src/lualib/Class.ts +++ b/src/lualib/Class.ts @@ -1,4 +1,4 @@ -function __TS__Class(): LuaClass { +export function __TS__Class(): LuaClass { const c: LuaClass = { prototype: {} }; c.prototype.__index = c.prototype; c.prototype.constructor = c; diff --git a/src/lualib/ClassExtends.ts b/src/lualib/ClassExtends.ts index 0df851629..6075868d7 100644 --- a/src/lualib/ClassExtends.ts +++ b/src/lualib/ClassExtends.ts @@ -1,4 +1,4 @@ -function __TS__ClassExtends(this: void, target: LuaClass, base: LuaClass): void { +export function __TS__ClassExtends(this: void, target: LuaClass, base: LuaClass): void { target.____super = base; // Set base class as a metatable, because descriptors use `getmetatable` to get extended prototype diff --git a/src/lualib/CloneDescriptor.ts b/src/lualib/CloneDescriptor.ts index d74292bab..2afe76914 100644 --- a/src/lualib/CloneDescriptor.ts +++ b/src/lualib/CloneDescriptor.ts @@ -1,4 +1,4 @@ -function __TS__CloneDescriptor( +export function __TS__CloneDescriptor( this: void, { enumerable, configurable, get, set, writable, value }: PropertyDescriptor ): PropertyDescriptor { diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 816721da7..50510f12c 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,12 +1,11 @@ /** * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 */ -type Decorator = ( - target: TTarget, - key?: TKey, - descriptor?: PropertyDescriptor -) => TTarget; -function __TS__Decorate( +import { __TS__ObjectGetOwnPropertyDescriptor } from "./ObjectGetOwnPropertyDescriptor"; +import { __TS__SetDescriptor } from "./SetDescriptor"; +import { Decorator } from "./Decorator"; + +export function __TS__Decorate( this: void, decorators: Array>, target: TTarget, diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index 4e11f3e54..f6c405015 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -1,9 +1,11 @@ +import { Decorator } from "./Decorator"; + type ParamDecorator = ( target: TTarget, key: TKey, index: number ) => TTarget; -function __TS__DecorateParam( +export function __TS__DecorateParam( this: void, paramIndex: number, decorator: ParamDecorator diff --git a/src/lualib/Decorator.d.ts b/src/lualib/Decorator.d.ts new file mode 100644 index 000000000..338b11b3f --- /dev/null +++ b/src/lualib/Decorator.d.ts @@ -0,0 +1,5 @@ +export type Decorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; diff --git a/src/lualib/DelegatedYield.ts b/src/lualib/DelegatedYield.ts index ab47d02d8..827dd6326 100644 --- a/src/lualib/DelegatedYield.ts +++ b/src/lualib/DelegatedYield.ts @@ -1,4 +1,6 @@ -function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { +import { GeneratorIterator } from "./GeneratorIterator"; + +export function __TS__DelegatedYield(this: void, iterable: string | GeneratorIterator | Iterable | readonly T[]) { if (typeof iterable === "string") { for (const index of $range(0, iterable.length - 1)) { coroutine.yield(iterable[index]); diff --git a/src/lualib/Delete.ts b/src/lualib/Delete.ts index 8dfad76ad..07499f44f 100644 --- a/src/lualib/Delete.ts +++ b/src/lualib/Delete.ts @@ -1,4 +1,6 @@ -function __TS__Delete(this: void, target: any, key: any): boolean { +import { __TS__ObjectGetOwnPropertyDescriptors } from "./ObjectGetOwnPropertyDescriptors"; + +export function __TS__Delete(this: void, target: any, key: any): boolean { const descriptors = __TS__ObjectGetOwnPropertyDescriptors(target); const descriptor = descriptors[key]; if (descriptor) { diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index 197ff816b..2ebb2aaaa 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -3,7 +3,7 @@ interface ErrorType { new (...args: any[]): Error; } -function __TS__GetErrorStack(constructor: () => any): string { +function getErrorStack(constructor: () => any): string { let level = 1; while (true) { const info = debug.getinfo(level, "f"); @@ -20,7 +20,7 @@ function __TS__GetErrorStack(constructor: () => any): string { return debug.traceback(undefined, level); } -function __TS__WrapErrorToString(getDescription: (this: T) => string): (this: T) => string { +function wrapErrorToString(getDescription: (this: T) => string): (this: T) => string { return function (this: Error): string { const description = getDescription.call(this); const caller = debug.getinfo(3, "f"); @@ -32,24 +32,24 @@ function __TS__WrapErrorToString(getDescription: (this: T) => s }; } -function __TS__InitErrorClass(Type: ErrorType, name: string): any { +function initErrorClass(Type: ErrorType, name: string): any { Type.name = name; return setmetatable(Type, { __call: (_self: any, message: string) => new Type(message), }); } -Error = __TS__InitErrorClass( +export const Error: ErrorConstructor = initErrorClass( class implements Error { public name = "Error"; public stack: string; constructor(public message = "") { - this.stack = __TS__GetErrorStack((this.constructor as any).new); + this.stack = getErrorStack((this.constructor as any).new); const metatable = getmetatable(this); if (!metatable.__errorToStringPatched) { metatable.__errorToStringPatched = true; - metatable.__tostring = __TS__WrapErrorToString(metatable.__tostring); + metatable.__tostring = wrapErrorToString(metatable.__tostring); } } @@ -60,11 +60,17 @@ Error = __TS__InitErrorClass( "Error" ); -for (const errorName of ["RangeError", "ReferenceError", "SyntaxError", "TypeError", "URIError"]) { - globalThis[errorName] = __TS__InitErrorClass( +function createErrorClass(name: string) { + return initErrorClass( class extends Error { - public name = errorName; + public name = name; }, - errorName + name ); } + +export const RangeError = createErrorClass("RangeError"); +export const ReferenceError = createErrorClass("ReferenceError"); +export const SyntaxError = createErrorClass("SyntaxError"); +export const TypeError = createErrorClass("TypeError"); +export const URIError = createErrorClass("URIError"); diff --git a/src/lualib/FunctionBind.ts b/src/lualib/FunctionBind.ts index e12fbe37c..a6cb2fac5 100644 --- a/src/lualib/FunctionBind.ts +++ b/src/lualib/FunctionBind.ts @@ -1,4 +1,4 @@ -function __TS__FunctionBind( +export function __TS__FunctionBind( this: void, fn: (this: void, ...argArray: any[]) => any, thisArg: any, diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index 1e18f2e25..0122602a2 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -1,14 +1,10 @@ -interface GeneratorIterator { - ____coroutine: LuaThread; - [Symbol.iterator](): GeneratorIterator; - next: typeof __TS__GeneratorNext; -} +import { GeneratorIterator } from "./GeneratorIterator"; -function __TS__GeneratorIterator(this: GeneratorIterator) { +function generatorIterator(this: GeneratorIterator) { return this; } -function __TS__GeneratorNext(this: GeneratorIterator, ...args: any[]) { +function generatorNext(this: GeneratorIterator, ...args: any[]) { const co = this.____coroutine; if (coroutine.status(co) === "dead") return { done: true }; @@ -18,14 +14,14 @@ function __TS__GeneratorNext(this: GeneratorIterator, ...args: any[]) { return { value, done: coroutine.status(co) === "dead" }; } -function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { +export function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { return function (this: void, ...args: any[]): GeneratorIterator { const argsLength = select("#", ...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil ____coroutine: coroutine.create(() => fn(...(unpack ?? table.unpack)(args, 1, argsLength))), - [Symbol.iterator]: __TS__GeneratorIterator, - next: __TS__GeneratorNext, + [Symbol.iterator]: generatorIterator, + next: generatorNext, }; }; } diff --git a/src/lualib/GeneratorIterator.d.ts b/src/lualib/GeneratorIterator.d.ts new file mode 100644 index 000000000..2509046b5 --- /dev/null +++ b/src/lualib/GeneratorIterator.d.ts @@ -0,0 +1,5 @@ +export interface GeneratorIterator { + ____coroutine: LuaThread; + [Symbol.iterator](): GeneratorIterator; + next: typeof generatorNext; +} diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index a4d80c881..a469cc35f 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -1,4 +1,4 @@ -function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: LuaClass): boolean { +export function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: LuaClass): boolean { if (typeof classTbl !== "object") { throw "Right-hand side of 'instanceof' is not an object"; } diff --git a/src/lualib/InstanceOfObject.ts b/src/lualib/InstanceOfObject.ts index 681e243c5..28e32150e 100644 --- a/src/lualib/InstanceOfObject.ts +++ b/src/lualib/InstanceOfObject.ts @@ -1,4 +1,4 @@ -function __TS__InstanceOfObject(this: void, value: unknown): boolean { +export function __TS__InstanceOfObject(this: void, value: unknown): boolean { const valueType = type(value); return valueType === "table" || valueType === "function"; } diff --git a/src/lualib/Iterator.ts b/src/lualib/Iterator.ts index 29da08683..6991ea888 100644 --- a/src/lualib/Iterator.ts +++ b/src/lualib/Iterator.ts @@ -1,4 +1,6 @@ -function __TS__IteratorGeneratorStep(this: GeneratorIterator): LuaMultiReturn<[true, any] | []> { +import { GeneratorIterator } from "./GeneratorIterator"; + +function iteratorGeneratorStep(this: GeneratorIterator): LuaMultiReturn<[true, any] | []> { const co = this.____coroutine; const [status, value] = coroutine.resume(co); @@ -8,29 +10,29 @@ function __TS__IteratorGeneratorStep(this: GeneratorIterator): LuaMultiReturn<[t return $multi(true, value); } -function __TS__IteratorIteratorStep(this: Iterator): LuaMultiReturn<[true, T] | []> { +function iteratorIteratorStep(this: Iterator): LuaMultiReturn<[true, T] | []> { const result = this.next(); if (result.done) return $multi(); return $multi(true, result.value); } -function __TS__IteratorStringStep(this: string, index: number): LuaMultiReturn<[number, string] | []> { +function iteratorStringStep(this: string, index: number): LuaMultiReturn<[number, string] | []> { index += 1; if (index > this.length) return $multi(); return $multi(index, string.sub(this, index, index)); } -function __TS__Iterator( +export function __TS__Iterator( this: void, iterable: string | GeneratorIterator | Iterable | readonly T[] ): LuaMultiReturn<[(...args: any[]) => [any, any] | [], ...any[]]> | LuaIterable> { if (typeof iterable === "string") { - return $multi(__TS__IteratorStringStep, iterable, 0); + return $multi(iteratorStringStep, iterable, 0); } else if ("____coroutine" in iterable) { - return $multi(__TS__IteratorGeneratorStep, iterable); + return $multi(iteratorGeneratorStep, iterable); } else if (iterable[Symbol.iterator]) { const iterator = iterable[Symbol.iterator](); - return $multi(__TS__IteratorIteratorStep, iterator); + return $multi(iteratorIteratorStep, iterator); } else { return ipairs(iterable as readonly T[]); } diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index e442b6132..fb1382fc3 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -1,4 +1,4 @@ -Map = class Map { +export class Map { public static [Symbol.species] = Map; public [Symbol.toStringTag] = "Map"; @@ -156,4 +156,4 @@ Map = class Map { }, }; } -}; +} diff --git a/src/lualib/MathAtan2.ts b/src/lualib/MathAtan2.ts index fdf322664..185cfe678 100644 --- a/src/lualib/MathAtan2.ts +++ b/src/lualib/MathAtan2.ts @@ -1 +1 @@ -const __TS__MathAtan2 = math.atan2 || math.atan; +export const __TS__MathAtan2 = math.atan2 || math.atan; diff --git a/src/lualib/MathSign.ts b/src/lualib/MathSign.ts index e94614c83..f3be69e8d 100644 --- a/src/lualib/MathSign.ts +++ b/src/lualib/MathSign.ts @@ -1,4 +1,4 @@ -function __TS__MathSign(this: void, val: number) { +export function __TS__MathSign(this: void, val: number) { if (val > 0) { return 1; } else if (val < 0) { diff --git a/src/lualib/New.ts b/src/lualib/New.ts index 8b33ec837..b54890917 100644 --- a/src/lualib/New.ts +++ b/src/lualib/New.ts @@ -1,4 +1,4 @@ -function __TS__New(this: void, target: LuaClass, ...args: any[]): any { +export function __TS__New(this: void, target: LuaClass, ...args: any[]): any { const instance: any = setmetatable({}, target.prototype); instance.____constructor(...args); return instance; diff --git a/src/lualib/Number.ts b/src/lualib/Number.ts index 0b19a1600..b258b48f6 100644 --- a/src/lualib/Number.ts +++ b/src/lualib/Number.ts @@ -1,4 +1,4 @@ -function __TS__Number(this: void, value: unknown): number { +export function __TS__Number(this: void, value: unknown): number { const valueType = type(value); if (valueType === "number") { return value as number; diff --git a/src/lualib/NumberIsFinite.ts b/src/lualib/NumberIsFinite.ts index 98df30790..f225b8c5c 100644 --- a/src/lualib/NumberIsFinite.ts +++ b/src/lualib/NumberIsFinite.ts @@ -1,3 +1,3 @@ -function __TS__NumberIsFinite(this: void, value: unknown): boolean { +export function __TS__NumberIsFinite(this: void, value: unknown): boolean { return typeof value === "number" && value === value && value !== Infinity && value !== -Infinity; } diff --git a/src/lualib/NumberIsNaN.ts b/src/lualib/NumberIsNaN.ts index b040f5e5b..e57631cc1 100644 --- a/src/lualib/NumberIsNaN.ts +++ b/src/lualib/NumberIsNaN.ts @@ -1,3 +1,3 @@ -function __TS__NumberIsNaN(this: void, value: unknown): boolean { +export function __TS__NumberIsNaN(this: void, value: unknown): boolean { return value !== value; } diff --git a/src/lualib/NumberToString.ts b/src/lualib/NumberToString.ts index 52da58d7c..1e1a1ad03 100644 --- a/src/lualib/NumberToString.ts +++ b/src/lualib/NumberToString.ts @@ -1,7 +1,7 @@ -const ____radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; +const radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tostring -function __TS__NumberToString(this: number, radix?: number): string { +export function __TS__NumberToString(this: number, radix?: number): string { if (radix === undefined || radix === 10 || this === Infinity || this === -Infinity || this !== this) { return this.toString(); } @@ -20,7 +20,7 @@ function __TS__NumberToString(this: number, radix?: number): string { result = string.format("%x", integer); } else { do { - result = ____radixChars[integer % radix] + result; + result = radixChars[integer % radix] + result; integer = Math.floor(integer / radix); } while (integer !== 0); } @@ -33,7 +33,7 @@ function __TS__NumberToString(this: number, radix?: number): string { fraction *= radix; delta *= radix; const digit = Math.floor(fraction); - result += ____radixChars[digit]; + result += radixChars[digit]; fraction -= digit; // TODO: Round to even } while (fraction >= delta); diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index bcf521c07..a351c030a 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,6 +1,6 @@ // https://tc39.github.io/ecma262/#sec-object.assign // eslint-disable-next-line @typescript-eslint/ban-types -function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { +export function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { if (to === undefined) { return to; } diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index f37b36c2a..6b275bfa0 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,7 +1,14 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty // eslint-disable-next-line @typescript-eslint/ban-types -function __TS__ObjectDefineProperty(this: void, target: T, key: any, desc: PropertyDescriptor): T { +import { __TS__SetDescriptor } from "./SetDescriptor"; + +export function __TS__ObjectDefineProperty( + this: void, + target: T, + key: any, + desc: PropertyDescriptor +): T { const luaKey = typeof key === "number" ? key + 1 : key; const value = rawget(target, luaKey); diff --git a/src/lualib/ObjectEntries.ts b/src/lualib/ObjectEntries.ts index f491bd039..3059fbecf 100644 --- a/src/lualib/ObjectEntries.ts +++ b/src/lualib/ObjectEntries.ts @@ -1,4 +1,4 @@ -function __TS__ObjectEntries(this: void, obj: any): Array { +export function __TS__ObjectEntries(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = [key, obj[key]]; diff --git a/src/lualib/ObjectFromEntries.ts b/src/lualib/ObjectFromEntries.ts index efdf7dd90..88c224cf7 100644 --- a/src/lualib/ObjectFromEntries.ts +++ b/src/lualib/ObjectFromEntries.ts @@ -1,4 +1,4 @@ -function __TS__ObjectFromEntries( +export function __TS__ObjectFromEntries( this: void, entries: ReadonlyArray<[string, T]> | Iterable<[string, T]> ): Record { diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts index 84dab33df..1f7e660bf 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptor.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -1,4 +1,8 @@ -function __TS__ObjectGetOwnPropertyDescriptor(this: void, object: any, key: any): PropertyDescriptor | undefined { +export function __TS__ObjectGetOwnPropertyDescriptor( + this: void, + object: any, + key: any +): PropertyDescriptor | undefined { const metatable = getmetatable(object); if (!metatable) return; if (!rawget(metatable, "_descriptors")) return; diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts index 04aee8b51..41d92ddfc 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptors.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -1,4 +1,7 @@ -function __TS__ObjectGetOwnPropertyDescriptors(this: void, object: any): Record { +export function __TS__ObjectGetOwnPropertyDescriptors( + this: void, + object: any +): Record { const metatable = getmetatable(object); if (!metatable) return {}; return rawget(metatable, "_descriptors") || {}; diff --git a/src/lualib/ObjectKeys.ts b/src/lualib/ObjectKeys.ts index 8163a620a..d07f6c8d6 100644 --- a/src/lualib/ObjectKeys.ts +++ b/src/lualib/ObjectKeys.ts @@ -1,4 +1,4 @@ -function __TS__ObjectKeys(this: void, obj: any): Array { +export function __TS__ObjectKeys(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = key; diff --git a/src/lualib/ObjectRest.ts b/src/lualib/ObjectRest.ts index 7da14b2fb..276135ce5 100644 --- a/src/lualib/ObjectRest.ts +++ b/src/lualib/ObjectRest.ts @@ -1,4 +1,4 @@ -function __TS__ObjectRest( +export function __TS__ObjectRest( this: void, target: Record, usedProperties: Partial> diff --git a/src/lualib/ObjectValues.ts b/src/lualib/ObjectValues.ts index e850f6a31..02ab400cb 100644 --- a/src/lualib/ObjectValues.ts +++ b/src/lualib/ObjectValues.ts @@ -1,4 +1,4 @@ -function __TS__ObjectValues(this: void, obj: any): Array { +export function __TS__ObjectValues(this: void, obj: any): Array { const result = []; for (const key in obj) { result[result.length] = obj[key]; diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts index 0c6d04d65..94ca97429 100644 --- a/src/lualib/ParseFloat.ts +++ b/src/lualib/ParseFloat.ts @@ -1,4 +1,4 @@ -function __TS__ParseFloat(this: void, numberString: string): number { +export function __TS__ParseFloat(this: void, numberString: string): number { // Check if string is infinity const [infinityMatch] = string.match(numberString, "^%s*(-?Infinity)"); if (infinityMatch) { diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index cb1d851f4..208d84e44 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -1,6 +1,6 @@ -const __TS__parseInt_base_pattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; +const parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; -function __TS__ParseInt(this: void, numberString: string, base?: number): number { +export function __TS__ParseInt(this: void, numberString: string, base?: number): number { // Check which base to use if none specified if (base === undefined) { base = 10; @@ -20,9 +20,7 @@ function __TS__ParseInt(this: void, numberString: string, base?: number): number // Calculate string match pattern to use const allowedDigits = - base <= 10 - ? __TS__parseInt_base_pattern.substring(0, base) - : __TS__parseInt_base_pattern.substr(0, 10 + 2 * (base - 10)); + base <= 10 ? parseIntBasePattern.substring(0, base) : parseIntBasePattern.substr(0, 10 + 2 * (base - 10)); const pattern = `^%s*(-?[${allowedDigits}]*)`; // Try to parse with Lua tonumber diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index de21de94a..99f144c0e 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -3,7 +3,7 @@ // Promises implemented based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise // and https://promisesaplus.com/ -enum __TS__PromiseState { +export const enum PromiseState { Pending, Fulfilled, Rejected, @@ -12,7 +12,7 @@ enum __TS__PromiseState { type FulfillCallback = (value: TData) => TResult | PromiseLike; type RejectCallback = (reason: any) => TResult | PromiseLike; -function __TS__PromiseDeferred() { +function promiseDeferred() { let resolve: FulfillCallback; let reject: RejectCallback; const promise = new Promise((res, rej) => { @@ -23,12 +23,12 @@ function __TS__PromiseDeferred() { return { promise, resolve, reject }; } -function __TS__IsPromiseLike(thing: unknown): thing is PromiseLike { +function isPromiseLike(thing: unknown): thing is PromiseLike { return thing instanceof __TS__Promise; } -class __TS__Promise implements Promise { - public state = __TS__PromiseState.Pending; +export class __TS__Promise implements Promise { + public state = PromiseState.Pending; public value?: T; public rejectionReason?: any; @@ -42,7 +42,7 @@ class __TS__Promise implements Promise { public static resolve(this: void, data: TData): Promise { // Create and return a promise instance that is already resolved const promise = new __TS__Promise(() => {}); - promise.state = __TS__PromiseState.Fulfilled; + promise.state = PromiseState.Fulfilled; promise.value = data; return promise; } @@ -51,7 +51,7 @@ class __TS__Promise implements Promise { public static reject(this: void, reason: any): Promise { // Create and return a promise instance that is already rejected const promise = new __TS__Promise(() => {}); - promise.state = __TS__PromiseState.Rejected; + promise.state = PromiseState.Rejected; promise.rejectionReason = reason; return promise; } @@ -70,10 +70,10 @@ class __TS__Promise implements Promise { onFulfilled?: FulfillCallback, onRejected?: RejectCallback ): Promise { - const { promise, resolve, reject } = __TS__PromiseDeferred(); + const { promise, resolve, reject } = promiseDeferred(); - const isFulfilled = this.state === __TS__PromiseState.Fulfilled; - const isRejected = this.state === __TS__PromiseState.Rejected; + const isFulfilled = this.state === PromiseState.Fulfilled; + const isRejected = this.state === PromiseState.Rejected; if (onFulfilled) { const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); @@ -110,16 +110,18 @@ class __TS__Promise implements Promise { return promise as Promise; } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch public catch(onRejected?: (reason: any) => TResult | PromiseLike): Promise { return this.then(undefined, onRejected); } + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally public finally(onFinally?: () => void): Promise { if (onFinally) { this.finallyCallbacks.push(onFinally); - if (this.state !== __TS__PromiseState.Pending) { + if (this.state !== PromiseState.Pending) { // If promise already resolved or rejected, immediately fire finally callback onFinally(); } @@ -137,8 +139,8 @@ class __TS__Promise implements Promise { } // Resolve this promise, if it is still pending. This function is passed to the constructor function. - if (this.state === __TS__PromiseState.Pending) { - this.state = __TS__PromiseState.Fulfilled; + if (this.state === PromiseState.Pending) { + this.state = PromiseState.Fulfilled; this.value = data; for (const callback of this.fulfilledCallbacks) { @@ -152,8 +154,8 @@ class __TS__Promise implements Promise { private reject(reason: any): void { // Reject this promise, if it is still pending. This function is passed to the constructor function. - if (this.state === __TS__PromiseState.Pending) { - this.state = __TS__PromiseState.Rejected; + if (this.state === PromiseState.Pending) { + this.state = PromiseState.Rejected; this.rejectionReason = reason; for (const callback of this.rejectedCallbacks) { @@ -179,18 +181,19 @@ class __TS__Promise implements Promise { } }; } + private handleCallbackData( data: TResult | PromiseLike, resolve: FulfillCallback, reject: RejectCallback ) { - if (__TS__IsPromiseLike(data)) { + if (isPromiseLike(data)) { const nextpromise = data as __TS__Promise; - if (nextpromise.state === __TS__PromiseState.Fulfilled) { + if (nextpromise.state === PromiseState.Fulfilled) { // If a handler function returns an already fulfilled promise, // the promise returned by then gets fulfilled with that promise's value resolve(nextpromise.value); - } else if (nextpromise.state === __TS__PromiseState.Rejected) { + } else if (nextpromise.state === PromiseState.Rejected) { // If a handler function returns an already rejected promise, // the promise returned by then gets fulfilled with that promise's value reject(nextpromise.rejectionReason); diff --git a/src/lualib/PromiseAll.ts b/src/lualib/PromiseAll.ts index e0d940977..c9263b645 100644 --- a/src/lualib/PromiseAll.ts +++ b/src/lualib/PromiseAll.ts @@ -1,6 +1,8 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all +import { __TS__Promise, PromiseState } from "./Promise"; + // eslint-disable-next-line @typescript-eslint/promise-function-async -function __TS__PromiseAll(this: void, iterable: Iterable>): Promise { +export function __TS__PromiseAll(this: void, iterable: Iterable>): Promise { const results: T[] = []; const toResolve = new LuaTable>(); @@ -9,10 +11,10 @@ function __TS__PromiseAll(this: void, iterable: Iterable>) let i = 0; for (const item of iterable) { if (item instanceof __TS__Promise) { - if (item.state === __TS__PromiseState.Fulfilled) { + if (item.state === PromiseState.Fulfilled) { // If value is a resolved promise, add its value to our results array results[i] = item.value; - } else if (item.state === __TS__PromiseState.Rejected) { + } else if (item.state === PromiseState.Rejected) { // If value is a rejected promise, return a rejected promise with the rejection reason return Promise.reject(item.rejectionReason); } else { diff --git a/src/lualib/PromiseAllSettled.ts b/src/lualib/PromiseAllSettled.ts index 165e226f4..4bcd13123 100644 --- a/src/lualib/PromiseAllSettled.ts +++ b/src/lualib/PromiseAllSettled.ts @@ -1,6 +1,8 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled +import { __TS__Promise, PromiseState } from "./Promise"; + // eslint-disable-next-line @typescript-eslint/promise-function-async -function __TS__PromiseAllSettled( +export function __TS__PromiseAllSettled( this: void, iterable: Iterable ): Promise ? U : T>>> { @@ -12,10 +14,10 @@ function __TS__PromiseAllSettled( let i = 0; for (const item of iterable) { if (item instanceof __TS__Promise) { - if (item.state === __TS__PromiseState.Fulfilled) { + if (item.state === PromiseState.Fulfilled) { // If value is a resolved promise, add a fulfilled PromiseSettledResult results[i] = { status: "fulfilled", value: item.value }; - } else if (item.state === __TS__PromiseState.Rejected) { + } else if (item.state === PromiseState.Rejected) { // If value is a rejected promise, add a rejected PromiseSettledResult results[i] = { status: "rejected", reason: item.rejectionReason }; } else { diff --git a/src/lualib/PromiseAny.ts b/src/lualib/PromiseAny.ts index eb70bf12f..17c77f273 100644 --- a/src/lualib/PromiseAny.ts +++ b/src/lualib/PromiseAny.ts @@ -1,15 +1,17 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any +import { __TS__Promise, PromiseState } from "./Promise"; + // eslint-disable-next-line @typescript-eslint/promise-function-async -function __TS__PromiseAny(this: void, iterable: Iterable>): Promise { +export function __TS__PromiseAny(this: void, iterable: Iterable>): Promise { const rejections: string[] = []; const pending: Array> = []; for (const item of iterable) { if (item instanceof __TS__Promise) { - if (item.state === __TS__PromiseState.Fulfilled) { + if (item.state === PromiseState.Fulfilled) { // If value is a resolved promise, return a new resolved promise with its value return Promise.resolve(item.value); - } else if (item.state === __TS__PromiseState.Rejected) { + } else if (item.state === PromiseState.Rejected) { // If value is a rejected promise, add its value to our list of rejections rejections.push(item.rejectionReason); } else { diff --git a/src/lualib/PromiseRace.ts b/src/lualib/PromiseRace.ts index 3b3a1fb7b..238aaf33b 100644 --- a/src/lualib/PromiseRace.ts +++ b/src/lualib/PromiseRace.ts @@ -1,14 +1,16 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race +import { PromiseState, __TS__Promise } from "./Promise"; + // eslint-disable-next-line @typescript-eslint/promise-function-async -function __TS__PromiseRace(this: void, iterable: Iterable>): Promise { +export function __TS__PromiseRace(this: void, iterable: Iterable>): Promise { const pending: Array> = []; for (const item of iterable) { if (item instanceof __TS__Promise) { - if (item.state === __TS__PromiseState.Fulfilled) { + if (item.state === PromiseState.Fulfilled) { // If value is a fulfilled promise, return a resolved promise with its value return Promise.resolve(item.value); - } else if (item.state === __TS__PromiseState.Rejected) { + } else if (item.state === PromiseState.Rejected) { // If value is a rejected promise, return rejected promise with its value return Promise.reject(item.rejectionReason); } else { diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index 71a8265ff..e4ac5e1cb 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -1,4 +1,4 @@ -Set = class Set { +export class Set { public static [Symbol.species] = Set; public [Symbol.toStringTag] = "Set"; @@ -145,4 +145,4 @@ Set = class Set { }, }; } -}; +} diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 5659848d5..11c435162 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -1,4 +1,6 @@ -function ____descriptorIndex(this: any, key: string): void { +import { __TS__CloneDescriptor } from "./CloneDescriptor"; + +function descriptorIndex(this: any, key: string): void { const value = rawget(this, key); if (value !== null) { return value; @@ -27,7 +29,7 @@ function ____descriptorIndex(this: any, key: string): void { } } -function ____descriptorNewindex(this: any, key: string, value: any): void { +function descriptorNewIndex(this: any, key: string, value: any): void { let metatable = getmetatable(this); while (metatable) { const descriptors = rawget(metatable, "_descriptors"); @@ -54,7 +56,13 @@ function ____descriptorNewindex(this: any, key: string, value: any): void { } // It's also used directly in class transform to add descriptors to the prototype -function __TS__SetDescriptor(this: void, target: any, key: any, desc: PropertyDescriptor, isPrototype = false): void { +export function __TS__SetDescriptor( + this: void, + target: any, + key: any, + desc: PropertyDescriptor, + isPrototype = false +): void { let metatable = isPrototype ? target : getmetatable(target); if (!metatable) { metatable = {}; @@ -67,6 +75,6 @@ function __TS__SetDescriptor(this: void, target: any, key: any, desc: PropertyDe if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; const descriptor = __TS__CloneDescriptor(desc); metatable._descriptors[key] = descriptor; - metatable.__index = ____descriptorIndex; - metatable.__newindex = ____descriptorNewindex; + metatable.__index = descriptorIndex; + metatable.__newindex = descriptorNewIndex; } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 542a8c483..f33a0dcd4 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -7,18 +7,19 @@ interface SourceMap { declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); -function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { +export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; globalThis.__TS__sourcemap[fileName] = sourceMap; if (globalThis.__TS__originalTraceback === undefined) { - globalThis.__TS__originalTraceback = debug.traceback; + const originalTraceback = debug.traceback; + globalThis.__TS__originalTraceback = originalTraceback; debug.traceback = ((thread, message, level) => { let trace: string; if (thread === undefined && message === undefined && level === undefined) { - trace = globalThis.__TS__originalTraceback(); + trace = originalTraceback(); } else { - trace = globalThis.__TS__originalTraceback(thread, message, level); + trace = originalTraceback(thread, message, level); } if (typeof trace !== "string") { diff --git a/src/lualib/SparseArray.d.ts b/src/lualib/SparseArray.d.ts new file mode 100644 index 000000000..768d93d7f --- /dev/null +++ b/src/lualib/SparseArray.d.ts @@ -0,0 +1 @@ +export type __TS__SparseArray = T[] & { sparseLength: number }; diff --git a/src/lualib/SparseArrayNew.ts b/src/lualib/SparseArrayNew.ts index 2370871ca..07bfae13e 100644 --- a/src/lualib/SparseArrayNew.ts +++ b/src/lualib/SparseArrayNew.ts @@ -1,6 +1,6 @@ -type __TS__SparseArray = T[] & { sparseLength: number }; +import { __TS__SparseArray } from "./SparseArray"; -function __TS__SparseArrayNew(this: void, ...args: T[]): __TS__SparseArray { +export function __TS__SparseArrayNew(this: void, ...args: T[]): __TS__SparseArray { const sparseArray = [...args] as __TS__SparseArray; // select("#", ...) counts the number of args passed, including nils. // Note that we're depending on vararg optimization to occur here. diff --git a/src/lualib/SparseArrayPush.ts b/src/lualib/SparseArrayPush.ts index 30704620f..8a089a192 100644 --- a/src/lualib/SparseArrayPush.ts +++ b/src/lualib/SparseArrayPush.ts @@ -1,4 +1,6 @@ -function __TS__SparseArrayPush(this: void, sparseArray: __TS__SparseArray, ...args: T[]): void { +import { __TS__SparseArray } from "./SparseArray"; + +export function __TS__SparseArrayPush(this: void, sparseArray: __TS__SparseArray, ...args: T[]): void { const argsLen = select("#", ...args); const listLen = sparseArray.sparseLength; for (const i of $range(1, argsLen)) { diff --git a/src/lualib/SparseArraySpread.ts b/src/lualib/SparseArraySpread.ts index e365f19bc..99871cb89 100644 --- a/src/lualib/SparseArraySpread.ts +++ b/src/lualib/SparseArraySpread.ts @@ -1,4 +1,6 @@ -function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { +import { __TS__SparseArray } from "./SparseArray"; + +export function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { const _unpack = unpack ?? table.unpack; return _unpack(sparseArray, 1, sparseArray.sparseLength); } diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 6bc3bf628..46ec8d5ae 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,4 +1,4 @@ -function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { +export function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { const arr = []; if (typeof iterable === "string") { // eslint-disable-next-line @typescript-eslint/prefer-for-of diff --git a/src/lualib/StringAccess.ts b/src/lualib/StringAccess.ts index 8695fd4e7..c273506c2 100644 --- a/src/lualib/StringAccess.ts +++ b/src/lualib/StringAccess.ts @@ -1,4 +1,4 @@ -function __TS__StringAccess(this: string, index: number) { +export function __TS__StringAccess(this: string, index: number) { if (index >= 0 && index < this.length) { return string.sub(this, index + 1, index + 1); } diff --git a/src/lualib/StringCharAt.ts b/src/lualib/StringCharAt.ts index 3c0e5161f..d76e94654 100644 --- a/src/lualib/StringCharAt.ts +++ b/src/lualib/StringCharAt.ts @@ -1,4 +1,4 @@ -function __TS__StringCharAt(this: string, pos: number): string { +export function __TS__StringCharAt(this: string, pos: number): string { if (pos !== pos) pos = 0; if (pos < 0) return ""; return string.sub(this, pos + 1, pos + 1); diff --git a/src/lualib/StringCharCodeAt.ts b/src/lualib/StringCharCodeAt.ts index 0044cc6cf..a3c722b9d 100644 --- a/src/lualib/StringCharCodeAt.ts +++ b/src/lualib/StringCharCodeAt.ts @@ -1,4 +1,4 @@ -function __TS__StringCharCodeAt(this: string, index: number): number { +export function __TS__StringCharCodeAt(this: string, index: number): number { if (index !== index) index = 0; if (index < 0) return NaN; return string.byte(this, index + 1) ?? NaN; diff --git a/src/lualib/StringConcat.ts b/src/lualib/StringConcat.ts index 657ae5c24..473040f31 100644 --- a/src/lualib/StringConcat.ts +++ b/src/lualib/StringConcat.ts @@ -1,4 +1,4 @@ -function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { +export function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { let out = str1; for (const arg of args) { out += arg; diff --git a/src/lualib/StringEndsWith.ts b/src/lualib/StringEndsWith.ts index b519a77eb..ea7d9020e 100644 --- a/src/lualib/StringEndsWith.ts +++ b/src/lualib/StringEndsWith.ts @@ -1,4 +1,4 @@ -function __TS__StringEndsWith(this: string, searchString: string, endPosition?: number): boolean { +export function __TS__StringEndsWith(this: string, searchString: string, endPosition?: number): boolean { if (endPosition === undefined || endPosition > this.length) { endPosition = this.length; } diff --git a/src/lualib/StringIncludes.ts b/src/lualib/StringIncludes.ts index 7508a2a42..3d896c8fa 100644 --- a/src/lualib/StringIncludes.ts +++ b/src/lualib/StringIncludes.ts @@ -1,4 +1,4 @@ -function __TS__StringIncludes(this: string, searchString: string, position?: number): boolean { +export function __TS__StringIncludes(this: string, searchString: string, position?: number): boolean { // http://lua-users.org/wiki/StringLibraryTutorial if (!position) { position = 1; diff --git a/src/lualib/StringPadEnd.ts b/src/lualib/StringPadEnd.ts index 24c8d48da..1f1c30e2e 100644 --- a/src/lualib/StringPadEnd.ts +++ b/src/lualib/StringPadEnd.ts @@ -1,4 +1,4 @@ -function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): string { +export function __TS__StringPadEnd(this: string, maxLength: number, fillString = " "): string { if (maxLength !== maxLength) maxLength = 0; if (maxLength === -Infinity || maxLength === Infinity) { throw "Invalid string length"; diff --git a/src/lualib/StringPadStart.ts b/src/lualib/StringPadStart.ts index 0e73f06fc..a6cb8e601 100644 --- a/src/lualib/StringPadStart.ts +++ b/src/lualib/StringPadStart.ts @@ -1,4 +1,4 @@ -function __TS__StringPadStart(this: string, maxLength: number, fillString = " "): string { +export function __TS__StringPadStart(this: string, maxLength: number, fillString = " "): string { if (maxLength !== maxLength) maxLength = 0; if (maxLength === -Infinity || maxLength === Infinity) { throw "Invalid string length"; diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index ab96d5329..f7de1da7a 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -1,4 +1,4 @@ -function __TS__StringReplace( +export function __TS__StringReplace( this: void, source: string, searchValue: string, diff --git a/src/lualib/StringReplaceAll.ts b/src/lualib/StringReplaceAll.ts index e288a1497..6911f92d7 100644 --- a/src/lualib/StringReplaceAll.ts +++ b/src/lualib/StringReplaceAll.ts @@ -1,4 +1,4 @@ -function __TS__StringReplaceAll( +export function __TS__StringReplaceAll( this: void, source: string, searchValue: string, diff --git a/src/lualib/StringSlice.ts b/src/lualib/StringSlice.ts index 42355d9e1..307d86894 100644 --- a/src/lualib/StringSlice.ts +++ b/src/lualib/StringSlice.ts @@ -1,4 +1,4 @@ -function __TS__StringSlice(this: string, start?: number, end?: number): string { +export function __TS__StringSlice(this: string, start?: number, end?: number): string { if (start === undefined || start !== start) start = 0; if (end !== end) end = 0; diff --git a/src/lualib/StringSplit.ts b/src/lualib/StringSplit.ts index 734dac38c..cf2b6ae9d 100644 --- a/src/lualib/StringSplit.ts +++ b/src/lualib/StringSplit.ts @@ -1,4 +1,4 @@ -function __TS__StringSplit(this: void, source: string, separator?: string, limit?: number): string[] { +export function __TS__StringSplit(this: void, source: string, separator?: string, limit?: number): string[] { if (limit === undefined) { limit = 4294967295; } diff --git a/src/lualib/StringStartsWith.ts b/src/lualib/StringStartsWith.ts index 8de8fa8ec..82f542143 100644 --- a/src/lualib/StringStartsWith.ts +++ b/src/lualib/StringStartsWith.ts @@ -1,4 +1,4 @@ -function __TS__StringStartsWith(this: string, searchString: string, position?: number): boolean { +export function __TS__StringStartsWith(this: string, searchString: string, position?: number): boolean { if (position === undefined || position < 0) { position = 0; } diff --git a/src/lualib/StringSubstr.ts b/src/lualib/StringSubstr.ts index e14c3c4a5..1940daf4d 100644 --- a/src/lualib/StringSubstr.ts +++ b/src/lualib/StringSubstr.ts @@ -1,4 +1,4 @@ -function __TS__StringSubstr(this: string, from: number, length?: number): string { +export function __TS__StringSubstr(this: string, from: number, length?: number): string { if (from !== from) from = 0; if (length !== undefined) { diff --git a/src/lualib/StringSubstring.ts b/src/lualib/StringSubstring.ts index df8210555..f3480081a 100644 --- a/src/lualib/StringSubstring.ts +++ b/src/lualib/StringSubstring.ts @@ -1,4 +1,4 @@ -function __TS__StringSubstring(this: string, start: number, end?: number): string { +export function __TS__StringSubstring(this: string, start: number, end?: number): string { if (end !== end) end = 0; if (end !== undefined && start > end) { diff --git a/src/lualib/StringTrim.ts b/src/lualib/StringTrim.ts index 8a231118a..f1d71d712 100644 --- a/src/lualib/StringTrim.ts +++ b/src/lualib/StringTrim.ts @@ -1,4 +1,4 @@ -function __TS__StringTrim(this: string): string { +export function __TS__StringTrim(this: string): string { // http://lua-users.org/wiki/StringTrim const [result] = string.gsub(this, "^[%s\xA0\uFEFF]*(.-)[%s\xA0\uFEFF]*$", "%1"); return result; diff --git a/src/lualib/StringTrimEnd.ts b/src/lualib/StringTrimEnd.ts index c45238235..711c91538 100644 --- a/src/lualib/StringTrimEnd.ts +++ b/src/lualib/StringTrimEnd.ts @@ -1,4 +1,4 @@ -function __TS__StringTrimEnd(this: string): string { +export function __TS__StringTrimEnd(this: string): string { // http://lua-users.org/wiki/StringTrim const [result] = string.gsub(this, "[%s\xA0\uFEFF]*$", ""); return result; diff --git a/src/lualib/StringTrimStart.ts b/src/lualib/StringTrimStart.ts index 47e6e8a66..258ea4f8b 100644 --- a/src/lualib/StringTrimStart.ts +++ b/src/lualib/StringTrimStart.ts @@ -1,4 +1,4 @@ -function __TS__StringTrimStart(this: string): string { +export function __TS__StringTrimStart(this: string): string { // http://lua-users.org/wiki/StringTrim const [result] = string.gsub(this, "^[%s\xA0\uFEFF]*", ""); return result; diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 67a1fd71b..d06eec37e 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,14 +1,14 @@ -const ____symbolMetatable = { +const symbolMetatable = { __tostring(this: symbol): string { return `Symbol(${this.description || ""})`; }, }; -function __TS__Symbol(this: void, description?: string | number): symbol { - return setmetatable({ description }, ____symbolMetatable) as unknown as symbol; +export function __TS__Symbol(this: void, description?: string | number): symbol { + return setmetatable({ description }, symbolMetatable) as unknown as symbol; } -Symbol = { +export const Symbol = { iterator: __TS__Symbol("Symbol.iterator"), hasInstance: __TS__Symbol("Symbol.hasInstance"), diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index 460edcc86..d8e68e3dd 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -1,15 +1,16 @@ -const ____symbolRegistry: Record = {}; +import { __TS__Symbol } from "./Symbol"; -function __TS__SymbolRegistryFor(this: void, key: string): symbol { - if (!____symbolRegistry[key]) { - ____symbolRegistry[key] = __TS__Symbol(key); +const symbolRegistry: Record = {}; +export function __TS__SymbolRegistryFor(this: void, key: string): symbol { + if (!symbolRegistry[key]) { + symbolRegistry[key] = __TS__Symbol(key); } - return ____symbolRegistry[key]; + return symbolRegistry[key]; } -function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string { - for (const key in ____symbolRegistry) { - if (____symbolRegistry[key] === sym) return key; +export function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string { + for (const key in symbolRegistry) { + if (symbolRegistry[key] === sym) return key; } } diff --git a/src/lualib/TypeOf.ts b/src/lualib/TypeOf.ts index 158062cd4..5afbbde04 100644 --- a/src/lualib/TypeOf.ts +++ b/src/lualib/TypeOf.ts @@ -1,4 +1,4 @@ -function __TS__TypeOf(this: void, value: unknown): string { +export function __TS__TypeOf(this: void, value: unknown): string { const luaType = type(value); if (luaType === "table") { return "object"; diff --git a/src/lualib/Unpack.ts b/src/lualib/Unpack.ts index 99aedf253..f138f2d7d 100644 --- a/src/lualib/Unpack.ts +++ b/src/lualib/Unpack.ts @@ -1 +1 @@ -const __TS__Unpack = table.unpack || unpack; +export const __TS__Unpack = table.unpack || unpack; diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index 7b7df1e99..e5f333293 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -WeakMap = class WeakMap { +export class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; @@ -46,4 +46,4 @@ WeakMap = class WeakMap { this.items.set(key, value); return this; } -}; +} diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index 670b3c695..0873861ab 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -WeakSet = class WeakSet { +export class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; @@ -40,4 +40,4 @@ WeakSet = class WeakSet { public has(value: T): boolean { return this.items.get(value) === true; } -}; +} diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index 5897dbad9..8acde4cca 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -11,6 +11,7 @@ }, "tstl": { "luaLibImport": "none", - "noHeader": true + "noHeader": true, + "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 94c5cb44f..c462bbe19 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -15,7 +15,6 @@ import { isStringType, } from "../utils/typescript"; import { PropertyCallExpression } from "../visitors/call"; -import { checkForLuaLibType } from "../visitors/class/new"; import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; @@ -34,6 +33,15 @@ export function transformBuiltinPropertyAccessExpression( ): lua.Expression | undefined { const ownerType = context.checker.getTypeAtLocation(node.expression); + if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { + switch (node.expression.text) { + case "Math": + return transformMathProperty(context, node); + case "Symbol": + importLuaLibFeature(context, LuaLibFeature.Symbol); + } + } + if (isStringType(context, ownerType)) { return transformStringProperty(context, node); } @@ -45,15 +53,6 @@ export function transformBuiltinPropertyAccessExpression( if (isFunctionType(ownerType)) { return transformFunctionProperty(context, node); } - - if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { - switch (node.expression.text) { - case "Math": - return transformMathProperty(context, node); - case "Symbol": - importLuaLibFeature(context, LuaLibFeature.Symbol); - } - } } export function transformBuiltinCallExpression( @@ -67,7 +66,6 @@ export function transformBuiltinCallExpression( }; const expressionType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, expressionType, undefined)) { - // TODO: checkForLuaLibType(context, expressionType); const result = transformGlobalCall(context, node); if (result) { @@ -172,3 +170,46 @@ export function transformBuiltinIdentifierExpression( return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node), "globalThis"); } } + +const builtinErrorTypeNames = new Set([ + "Error", + "ErrorConstructor", + "RangeError", + "RangeErrorConstructor", + "ReferenceError", + "ReferenceErrorConstructor", + "SyntaxError", + "SyntaxErrorConstructor", + "TypeError", + "TypeErrorConstructor", + "URIError", + "URIErrorConstructor", +]); + +export function checkForLuaLibType(context: TransformationContext, type: ts.Type): void { + if (!type.symbol) return; + + const name = context.checker.getFullyQualifiedName(type.symbol); + switch (name) { + case "Map": + case "MapConstructor": + importLuaLibFeature(context, LuaLibFeature.Map); + return; + case "Set": + case "SetConstructor": + importLuaLibFeature(context, LuaLibFeature.Set); + return; + case "WeakMap": + case "WeakMapConstructor": + importLuaLibFeature(context, LuaLibFeature.WeakMap); + return; + case "WeakSet": + case "WeakSetConstructor": + importLuaLibFeature(context, LuaLibFeature.WeakSet); + return; + } + + if (builtinErrorTypeNames.has(name)) { + importLuaLibFeature(context, LuaLibFeature.Error); + } +} diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index f43b349e5..5257c2db6 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -23,9 +23,8 @@ import { transformStaticPropertyDeclaration, } from "./members/fields"; import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; -import { checkForLuaLibType } from "./new"; -import { createClassSetup } from "./setup"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; +import { createClassSetup } from "./setup"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead @@ -86,10 +85,6 @@ function transformClassLikeDeclaration( const superInfo = getOrUpdate(classSuperInfos, context, () => []); superInfo.push({ className, extendedTypeNode }); - if (extendedType) { - checkForLuaLibType(context, extendedType); - } - // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index f7433e7b5..13a4a57a9 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -1,52 +1,12 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { FunctionVisitor, TransformationContext } from "../../context"; +import { FunctionVisitor } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; -import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; -const builtinErrorTypeNames = new Set([ - "Error", - "ErrorConstructor", - "RangeError", - "RangeErrorConstructor", - "ReferenceError", - "ReferenceErrorConstructor", - "SyntaxError", - "SyntaxErrorConstructor", - "TypeError", - "TypeErrorConstructor", - "URIError", - "URIErrorConstructor", -]); - -// TODO: Do it in identifier? -export function checkForLuaLibType(context: TransformationContext, type: ts.Type): void { - if (!type.symbol) return; - - const name = context.checker.getFullyQualifiedName(type.symbol); - switch (name) { - case "Map": - importLuaLibFeature(context, LuaLibFeature.Map); - return; - case "Set": - importLuaLibFeature(context, LuaLibFeature.Set); - return; - case "WeakMap": - importLuaLibFeature(context, LuaLibFeature.WeakMap); - return; - case "WeakSet": - importLuaLibFeature(context, LuaLibFeature.WeakSet); - return; - } - - if (builtinErrorTypeNames.has(name)) { - importLuaLibFeature(context, LuaLibFeature.Error); - } -} - export const transformNewExpression: FunctionVisitor = (node, context) => { const type = context.checker.getTypeAtLocation(node); @@ -68,8 +28,6 @@ export const transformNewExpression: FunctionVisitor = (node, signature ); - checkForLuaLibType(context, type); - const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 46c3a8904..6a73bfeb6 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { transformBuiltinIdentifierExpression } from "../builtins"; -import { createPromiseIdentifier, isPromiseClass } from "../builtins/promise"; +import { transformBuiltinIdentifierExpression, checkForLuaLibType } from "../builtins"; +import { isPromiseClass, createPromiseIdentifier } from "../builtins/promise"; import { FunctionVisitor, tempSymbolId, TransformationContext } from "../context"; import { AnnotationKind, isForRangeType } from "../utils/annotations"; import { @@ -22,6 +22,7 @@ import { isRangeFunctionNode } from "./language-extensions/range"; import { isTableExtensionIdentifier } from "./language-extensions/table"; import { isVarargConstantNode } from "./language-extensions/vararg"; import { isOptionalContinuation } from "./optional-chaining"; +import { isStandardLibraryType } from "../utils/typescript"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { if (isOptionalContinuation(identifier)) { @@ -59,6 +60,10 @@ export function transformIdentifier(context: TransformationContext, identifier: importLuaLibFeature(context, LuaLibFeature.Promise); return createPromiseIdentifier(identifier); } + const type = context.checker.getTypeAtLocation(identifier); + if (isStandardLibraryType(context, type, undefined)) { + checkForLuaLibType(context, type); + } const text = hasUnsafeIdentifierName(context, identifier) ? createSafeName(identifier.text) : identifier.text; diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index d8daba8c9..a9a53f4e4 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -72,12 +72,8 @@ export const transformImportDeclaration: FunctionVisitor = if (statement.importClause === undefined) { result.push(lua.createExpressionStatement(requireCall)); - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; - } + scope.importStatements.push(...result); + return undefined; } const importPath = ts.isStringLiteral(statement.moduleSpecifier) @@ -144,12 +140,8 @@ export const transformImportDeclaration: FunctionVisitor = result.unshift(lua.createVariableDeclarationStatement(importUniqueName, requireCall, statement)); } - if (scope.importStatements) { - scope.importStatements.push(...result); - return undefined; - } else { - return result; - } + scope.importStatements.push(...result); + return undefined; }; export const transformExternalModuleReference: FunctionVisitor = (node, context) => diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 45fe6d409..0c039ad4f 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -104,7 +104,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const footers: string[] = []; if (options.sourceMapTraceback) { // Generates SourceMapTraceback for the entire file - footers.push('require("lualib_bundle")\n'); + footers.push('local __TS__SourceMapTraceBack = require("lualib_bundle").__TS__SourceMapTraceBack\n'); footers.push(`${sourceMapTracebackBundlePlaceholder}\n`); } diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 0311efbbd..8b4070591 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -1,8 +1,9 @@ import * as ts from "typescript"; +import { EmitHost } from ".."; import { CompilerOptions } from "../CompilerOptions"; import { Printer } from "../LuaPrinter"; import { Visitors } from "../transformation/context"; -import { getConfigDirectory, resolvePlugin } from "./utils"; +import { getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils"; export interface Plugin { /** @@ -18,6 +19,21 @@ export interface Plugin { * At most one custom printer can be provided across all plugins. */ printer?: Printer; + + /** + * This function is called before transpilation of the TypeScript program starts. + */ + beforeTransform?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost) => ts.Diagnostic[] | void; + + /** + * This function is called after TypeScriptToLua has translated the input program to Lua. + */ + afterPrint?: ( + program: ts.Program, + options: CompilerOptions, + emitHost: EmitHost, + result: ProcessedFile[] + ) => ts.Diagnostic[] | void; } export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], customPlugins: Plugin[]): Plugin[] { diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index fc645147f..bf226992f 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -66,6 +66,13 @@ export function getProgramTranspileResult( console.log(`Successfully loaded ${plugins.length} plugins`); } + for (const plugin of plugins) { + if (plugin.beforeTransform) { + const pluginDiagnostics = plugin.beforeTransform(program, options, emitHost) ?? []; + diagnostics.push(...pluginDiagnostics); + } + } + const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); const processSourceFile = (sourceFile: ts.SourceFile) => { @@ -129,5 +136,12 @@ export function getProgramTranspileResult( transpiledFiles = []; } + for (const plugin of plugins) { + if (plugin.afterPrint) { + const pluginDiagnostics = plugin.afterPrint(program, options, emitHost, transpiledFiles) ?? []; + diagnostics.push(...pluginDiagnostics); + } + } + return { diagnostics, transpiledFiles }; } diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index f40cf960c..921af9c45 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -111,7 +111,6 @@ describe("command line", () => { ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], - ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], @@ -225,7 +224,6 @@ describe("tsconfig", () => { ["buildMode", "library", { buildMode: tstl.BuildMode.Library }], ["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }], - ["luaLibImport", "always", { luaLibImport: tstl.LuaLibImportKind.Always }], ["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }], ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 9671f656c..32f48994b 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -58,7 +58,8 @@ return ____exports" `; exports[`Transformation (methodRestArguments) 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class MyClass = __TS__Class() MyClass.name = \\"MyClass\\" function MyClass.prototype.____constructor(self) @@ -74,7 +75,8 @@ return ____exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass @@ -85,7 +87,8 @@ return ____exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index eaf179a6c..a76619460 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -3,7 +3,6 @@ exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` Array [ "directories/basic/src/lib/file.lua", - "directories/basic/src/lualib_bundle.lua", "directories/basic/src/main.lua", ] `; @@ -11,7 +10,6 @@ Array [ exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 2`] = ` Array [ "directories/basic/out/lib/file.lua", - "directories/basic/out/lualib_bundle.lua", "directories/basic/out/main.lua", ] `; @@ -19,7 +17,6 @@ Array [ exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 3`] = ` Array [ "directories/basic/src/lib/file.lua", - "directories/basic/src/lualib_bundle.lua", "directories/basic/src/main.lua", ] `; @@ -27,7 +24,6 @@ Array [ exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 4`] = ` Array [ "directories/basic/out/lib/file.lua", - "directories/basic/out/lualib_bundle.lua", "directories/basic/out/main.lua", ] `; diff --git a/test/transpile/directories.spec.ts b/test/transpile/directories.spec.ts index 1c0bba994..9572c1e0d 100644 --- a/test/transpile/directories.spec.ts +++ b/test/transpile/directories.spec.ts @@ -19,7 +19,7 @@ test.each([ const config = { compilerOptions: { ...compilerOptions, types: [], skipLibCheck: true }, - tstl: { luaTarget: tstl.LuaTarget.LuaJIT, luaLibImport: tstl.LuaLibImportKind.Always }, + tstl: { luaTarget: tstl.LuaTarget.LuaJIT }, }; const { fileNames, options } = tstl.updateParsedConfigFile( diff --git a/test/transpile/lualib.spec.ts b/test/transpile/lualib.spec.ts index 0af391c46..b35ab996b 100644 --- a/test/transpile/lualib.spec.ts +++ b/test/transpile/lualib.spec.ts @@ -1,26 +1,31 @@ import * as ts from "typescript"; import { LuaLibFeature } from "../../src"; -import { loadLuaLibFeatures } from "../../src/LuaLib"; +import { readLuaLibFeature } from "../../src/LuaLib"; +import * as util from "../util"; -test.each(Object.entries(LuaLibFeature))("Lualib feature has correct dependencies (%p)", (_, feature) => { - const lualibCode = loadLuaLibFeatures([feature], ts.sys); +test.each(Object.entries(LuaLibFeature))("Lualib does not use ____exports (%p)", (_, feature) => { + const lualibCode = readLuaLibFeature(feature, ts.sys); - // Find all used lualib features - const luaLibReferences = lualibCode.match(/__TS__[a-zA-Z_]+\(/g); - - // For every reference lualib function, check if its definition is also included - const missingReferences = []; + const exportsOccurrences = lualibCode.match(/____exports/g); + expect(exportsOccurrences).toBeNull(); +}); - if (luaLibReferences !== null) { - for (const reference of luaLibReferences) { - if ( - !lualibCode.includes(`function ${reference}`) && - !lualibCode.includes(`${reference.substring(0, reference.length - 1)} =`) - ) { - missingReferences.push(reference); +test("Lualib bundle does not assign globals", () => { + // language=TypeScript + util.testModule` + declare const _G: LuaTable; + declare const require: (this: void, module: string) => any; + const globalKeys = new LuaTable(); + for (const [key] of _G) { + globalKeys[key] = true; + } + require("lualib_bundle"); + for (const [key] of _G) { + if (!globalKeys[key]) { + error("Global was assigned: " + key); } } - } - - expect(missingReferences).toHaveLength(0); + ` + .withLanguageExtensions() + .expectNoExecutionError(); }); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index b60c83e91..83836f6b7 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -490,7 +490,8 @@ test("includes lualib_bundle when external lua requests it", () => { .addExtraFile( "lualibuser.lua", ` - require("lualib_bundle") + local ____lualib = require("lualib_bundle") + local __TS__ArrayPush = ____lualib.__TS__ArrayPush local result = {} __TS__ArrayPush(result, "foo") diff --git a/test/transpile/plugins/afterPrint.ts b/test/transpile/plugins/afterPrint.ts new file mode 100644 index 000000000..5d0d3e78d --- /dev/null +++ b/test/transpile/plugins/afterPrint.ts @@ -0,0 +1,22 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + afterPrint( + program: ts.Program, + options: tstl.CompilerOptions, + emitHost: tstl.EmitHost, + result: tstl.ProcessedFile[] + ) { + void program; + void options; + void emitHost; + + for (const file of result) { + file.code = "-- Commented added by afterPrint plugin\n" + file.code; + } + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/beforeTransform.ts b/test/transpile/plugins/beforeTransform.ts new file mode 100644 index 000000000..947358fa2 --- /dev/null +++ b/test/transpile/plugins/beforeTransform.ts @@ -0,0 +1,15 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + beforeTransform(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost) { + void program; + void emitHost; + + // Modify settings + options.outDir = "plugin/beforeTransform/outdir"; + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 457d7d2d9..614e2f1ca 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -78,8 +78,40 @@ test.each(["namespace", "module"])("%s with TS transformer plugin", moduleOrName return false; } } - ` + ` ) .setOptions({ plugins: [{ transform: path.join(__dirname, "transformer-plugin.ts") }] }) .expectNoExecutionError(); }); + +test("beforeTransform plugin", () => { + const { transpiledFiles } = util.testModule` + console.log("Hello, World!"); + ` + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeTransform.ts") }] }) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(1); + // Expect emitted to output path set by the plugin + expect(transpiledFiles[0].outPath).toContain(path.join("plugin", "beforeTransform", "outdir")); +}); + +test("afterPrint plugin", () => { + const { transpiledFiles } = util.testModule` + console.log("Hello, World!"); + ` + .addExtraFile( + "extrafile.ts", + ` + console.log("Hello, Mars!"); + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "afterPrint.ts") }] }) + .getLuaResult(); + + expect(transpiledFiles).toHaveLength(2); + for (const f of transpiledFiles) { + // Expect plugin inserted extra lua at start of file + expect(f.lua).toContain("-- Commented added by afterPrint plugin"); + } +}); diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 91bc2306b..5f58cde14 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -503,7 +503,8 @@ return ____exports" `; exports[`Unary expressions basic ("delete tbl.test") 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) __TS__Delete(tbl, \\"test\\") @@ -512,7 +513,8 @@ return ____exports" `; exports[`Unary expressions basic ("delete tbl['test']") 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) __TS__Delete(tbl, \\"test\\") @@ -537,7 +539,8 @@ return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl.test") 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) local a = __TS__Delete(tbl, \\"test\\") @@ -546,7 +549,8 @@ return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl['test']") 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) local a = __TS__Delete(tbl, \\"test\\") diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 46ac47aa8..3d67bf838 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Unsupported optional chains Builtin global method: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Number = ____lualib.__TS__Number local ____Number_result_0 = Number if ____Number_result_0 ~= nil then ____Number_result_0 = nil diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index 45ba87e16..a640878c4 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`switch empty fallthrough to default (0) 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayPush = ____lualib.__TS__ArrayPush local ____exports = {} function ____exports.__main(self) local out = {} @@ -18,7 +19,8 @@ return ____exports" `; exports[`switch empty fallthrough to default (1) 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayPush = ____lualib.__TS__ArrayPush local ____exports = {} function ____exports.__main(self) local out = {} @@ -111,7 +113,8 @@ return ____exports" `; exports[`switch produces optimal output 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayPush = ____lualib.__TS__ArrayPush local ____exports = {} function ____exports.__main(self) local x = 0 diff --git a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap index c283485bf..ffd43b2b6 100644 --- a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`IncorrectUsage: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New local ____exports = {} function ____exports.__main(self) local Point2D = __TS__Class() diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index a962a4a30..32c01be9e 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -11,7 +11,8 @@ return ____exports" exports[`LuaTable deprecation warning property access set: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; exports[`LuaTable removed warning constructor: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__New = ____lualib.__TS__New ____table = __TS__New(Table)" `; @@ -38,14 +39,18 @@ return ____exports" exports[`LuaTable removed warning property access length: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; exports[`extension removed: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local __TS__ClassExtends = ____lualib.__TS__ClassExtends B = __TS__Class() B.name = \\"B\\" __TS__ClassExtends(B, A)" `; exports[`extension removed: code 2`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local __TS__ClassExtends = ____lualib.__TS__ClassExtends B = __TS__Class() B.name = \\"B\\" __TS__ClassExtends(B, A)" @@ -90,7 +95,9 @@ end" exports[`phantom removed: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@phantom' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; exports[`pureAbstract removed: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local __TS__ClassExtends = ____lualib.__TS__ClassExtends ClassB = __TS__Class() ClassB.name = \\"ClassB\\" __TS__ClassExtends(ClassB, ClassA)" diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index fa213d03f..a5da97772 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -16,13 +16,6 @@ describe("luaLibImport", () => { .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); - - test("always", () => { - util.testModule`` - .setOptions({ luaLibImport: tstl.LuaLibImportKind.Always }) - .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) - .expectToEqual(undefined); - }); }); test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index 8f81edfe8..93e23e98e 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -194,3 +194,10 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM `.expectToMatchJsResult(); }); }); + +test("instanceof Set without creating set", () => { + util.testFunction` + const myset = 3 as any; + return myset instanceof Set; + `.expectToMatchJsResult(); +}); diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap index 6336a53a3..7822867f5 100644 --- a/test/unit/classes/__snapshots__/classes.spec.ts.snap +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`missing declaration name: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class ____class_0 = __TS__Class() ____class_0.name = \\"\\" function ____class_0.prototype.____constructor(self) diff --git a/test/unit/classes/__snapshots__/decorators.spec.ts.snap b/test/unit/classes/__snapshots__/decorators.spec.ts.snap index cbc983bd5..cef76f35e 100644 --- a/test/unit/classes/__snapshots__/decorators.spec.ts.snap +++ b/test/unit/classes/__snapshots__/decorators.spec.ts.snap @@ -1,7 +1,9 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Throws error if decorator function has void context: code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Class = ____lualib.__TS__Class +local __TS__Decorate = ____lualib.__TS__Decorate local ____exports = {} function ____exports.__main(self) local function decorator(constructor) diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap index c1f369cb6..64273b8fe 100644 --- a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -33,7 +33,8 @@ return ____exports" exports[`$range invalid use ("const x = $range(1, 10);"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $range can only be used in a for...of loop."`; exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Spread = ____lualib.__TS__Spread local ____exports = {} function ____exports.__main(self) local y = {__TS__Spread(____(nil, 1, 10))} @@ -66,7 +67,8 @@ return ____exports" exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] = ` -"require(\\"lualib_bundle\\"); +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__Iterator = ____lualib.__TS__Iterator local ____exports = {} function ____exports.__main(self) for ____, i in __TS__Iterator(____(nil, 1, 10, 2)) do diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index fdc21a13a..b625f1f5f 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -88,7 +88,7 @@ test.each([ assertPatterns: [ { luaPattern: "Bar = __TS__Class()", typeScriptPattern: "class Bar" }, { luaPattern: "Bar.name =", typeScriptPattern: "class Bar" }, - { luaPattern: "__TS__ClassExtends", typeScriptPattern: "extends" }, + { luaPattern: "__TS__ClassExtends(", typeScriptPattern: "extends" }, // find use of function, not import { luaPattern: "Foo", typeScriptPattern: "Foo" }, { luaPattern: "function Bar.prototype.____constructor", typeScriptPattern: "constructor" }, ], From cd260bc0e939e418cf0f3f49a6c891af65596333 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 17 Mar 2022 21:24:01 +0100 Subject: [PATCH 459/764] CHANGELOG.md 1.4.0 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b31d78040..8929e86d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## 1.4.0 + +- Upgraded to TypeScript 4.6 +- Added two event hooks to TSTL plugins: `beforeTransform` and `afterPrint` + - These allow you to run plugin code at specific points in the transpilation process. +- Lualib polyfills are now modules required into locals, instead of global functions + - This change also removes the `"always"` option for the `"lualibImport"` tsconfig key. +- Added support for `Math.sign` +- Switched to `^` instead of `math.pow`, the latter was deprecated in 5.3 +- Added an error when using `null` or `undefined` in tuples, as that is undefined behavior in the Lua spec and causes unexpected behavior +- Added tsconfig setting `extension`, allowing to specify a different output file extension +- Fixed multiple issues with optional chaining and lualib/language extensions +- Fixed issue assigning function with properties to variable declarations +- Fixed multiple issues with preceding statements in class constructors +- Fixed external code module resolution exploding into a stack overflow in complicated module hierarchies +- Fixed a `function.apply(context)` breaking the transpiler if called with only one parameter +- Fixed preceding statements in ternary conditionals (`x ? y : z`) leading to incorrect code + ## 1.3.0 - Added `LuaPairsIterable` language extension to mark objects as iterable with Lua's `pairs`. From baa826d422faa87fbb03c0c558b800a2e5fb08e2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 17 Mar 2022 21:37:29 +0100 Subject: [PATCH 460/764] 1.4.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bc83442d1..a6384b0d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.3.4", + "version": "1.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.3.4", + "version": "1.4.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index ae73f35b6..bfedfab5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.3.4", + "version": "1.4.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f742949ca83751df8b3238e3340f5b5414acbfec Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 20 Mar 2022 03:37:57 -0700 Subject: [PATCH 461/764] Implement Array.from and Array.of (#1240) --- src/LuaLib.ts | 1 + src/lualib/ArrayFrom.ts | 36 ++++++++++++++++++++++++++++ src/lualib/tsconfig.json | 3 ++- src/transformation/builtins/array.ts | 7 +++++- test/unit/builtins/array.spec.ts | 14 +++++++++++ 5 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/lualib/ArrayFrom.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index e5df8927a..b9beddab9 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -10,6 +10,7 @@ export enum LuaLibFeature { ArrayForEach = "ArrayForEach", ArrayFind = "ArrayFind", ArrayFindIndex = "ArrayFindIndex", + ArrayFrom = "ArrayFrom", ArrayIncludes = "ArrayIncludes", ArrayIndexOf = "ArrayIndexOf", ArrayIsArray = "ArrayIsArray", diff --git a/src/lualib/ArrayFrom.ts b/src/lualib/ArrayFrom.ts new file mode 100644 index 000000000..fda55580f --- /dev/null +++ b/src/lualib/ArrayFrom.ts @@ -0,0 +1,36 @@ +/** @noSelfInFile */ + +import { __TS__Iterator } from "./Iterator"; + +function arrayLikeStep(this: ArrayLike, index: number): LuaMultiReturn<[number, unknown] | []> { + index += 1; + if (index > this.length) return $multi(); + return $multi(index, this[index]); +} + +const arrayLikeIterator: ( + this: void, + arr: ArrayLike | Iterable +) => LuaIterable> = (arr => { + if (typeof arr.length === "number") return $multi(arrayLikeStep, arr, 0); + return __TS__Iterator(arr); +}) as any; + +export function __TS__ArrayFrom( + this: void, + arrayLike: ArrayLike | Iterable, + mapFn?: (this: unknown, element: unknown, index: number) => unknown, + thisArg?: unknown +): unknown[] { + const result = []; + if (mapFn === undefined) { + for (const [, v] of arrayLikeIterator(arrayLike)) { + result.push(v); + } + } else { + for (const [i, v] of arrayLikeIterator(arrayLike)) { + result.push(mapFn.call(thisArg, v, i - 1)); + } + } + return result; +} diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index 8acde4cca..246e46b90 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -13,5 +13,6 @@ "luaLibImport": "none", "noHeader": true, "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] - } + }, + "include": [".", "../../language-extensions/index.d.ts"] } diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 7bbd4cf98..3242cd57a 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -5,19 +5,24 @@ import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; import { isStringType, isNumberType } from "../utils/typescript"; +import { wrapInTable } from "../utils/lua-ast"; export function transformArrayConstructorCall( context: TransformationContext, node: PropertyCallExpression -): lua.CallExpression | undefined { +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); const expressionName = expression.name.text; switch (expressionName) { + case "from": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFrom, node, ...params); case "isArray": return transformLuaLibFunction(context, LuaLibFeature.ArrayIsArray, node, ...params); + case "of": + return wrapInTable(...params); default: context.diagnostics.push(unsupportedProperty(expression.name, "Array", expressionName)); } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index eaeddf08e..98b749e3b 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -671,6 +671,20 @@ test("Array.isArray returns true for empty objects", () => { util.testExpression`Array.isArray({})`.expectToEqual(true); }); +test.each([ + "[1, 2, 3]", + "(new Set([1, 2, 3])).values()", + "[1, 2, 3], value => value * 2", + "{ length: 3 }, (_, index) => index + 1", +])("Array.from(%p)", valueString => { + util.testExpression`Array.from(${valueString})`.expectToMatchJsResult(); +}); + +// Array.of +test.each(["1, 2, 3", "", "...[1, 2, 3], 4, 5, 6"])("Array.of(%p)", valueString => { + util.testExpression`Array.of(${valueString})`.expectToMatchJsResult(); +}); + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/738 test("array.prototype.concat issue #738", () => { util.testExpression`([] as any[]).concat(13, 323, {x: 3}, [2, 3])`.expectToMatchJsResult(); From 304c203c8014810fe0163583424345da8028dc9d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 20 Mar 2022 14:04:58 +0100 Subject: [PATCH 462/764] Fix sourcemap traceback being in the wrong place (#1238) --- src/LuaPrinter.ts | 20 ++++++++++---------- test/unit/printer/sourcemaps.spec.ts | 9 +++++++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index cc8a6fa46..851131a42 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -227,32 +227,32 @@ export class LuaPrinter { } protected printFile(file: lua.File): SourceNode { - let header = file.trivia; + let sourceChunks: SourceChunk[] = [file.trivia]; if (!this.options.noHeader) { - header += tstlHeader; + sourceChunks.push(tstlHeader); } - let statements = file.statements; const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) { // Import lualib features - const importStatements = loadImportedLualibFeatures(file.luaLibFeatures, this.emitHost); - - statements = importStatements.concat(statements); + sourceChunks = this.printStatementArray(loadImportedLualibFeatures(file.luaLibFeatures, this.emitHost)); } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features - header += "-- Lua Library inline imports\n"; - header += loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost); + sourceChunks.push("-- Lua Library inline imports\n"); + sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost)); } if (this.options.sourceMapTraceback && !isBundleEnabled(this.options)) { // In bundle mode the traceback is being generated for the entire file in getBundleResult // Otherwise, traceback is being generated locally - header += `${LuaPrinter.sourceMapTracebackPlaceholder}\n`; + sourceChunks.push(`${LuaPrinter.sourceMapTracebackPlaceholder}\n`); } - return this.concatNodes(header, ...this.printStatementArray(statements)); + // Print reest of the statements in file + sourceChunks.push(...this.printStatementArray(file.statements)); + + return this.concatNodes(...sourceChunks); } protected pushIndent(): void { diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index b625f1f5f..9ea7a920c 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -284,6 +284,15 @@ test("sourceMapTraceback saves sourcemap in _G", () => { }); test("sourceMapTraceback gives traceback", () => { + const builder = util.testFunction` + return (debug.traceback as (this: void)=>string)(); + `.setOptions({ sourceMapTraceback: true }); + + const traceback = builder.getLuaExecutionResult(); + expect(traceback).toEqual(expect.any(String)); +}); + +test("inline sourceMapTraceback gives traceback", () => { const builder = util.testFunction` return (debug.traceback as (this: void)=>string)(); `.setOptions({ sourceMapTraceback: true, luaLibImport: tstl.LuaLibImportKind.Inline }); From 1cdd6b070c5834aa4e238b9a36c121c2ca685d60 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 20 Mar 2022 14:06:43 +0100 Subject: [PATCH 463/764] Added BeforeEmit plugin hook (#1239) * Added BeforeEmit plugin hook * Updated verbose log snapshot --- src/index.ts | 2 +- src/transpilation/plugins.ts | 23 +++++++-- src/transpilation/transpile.ts | 10 +--- src/transpilation/transpiler.ts | 31 +++++++----- src/transpilation/utils.ts | 1 - .../__snapshots__/project.spec.ts.snap | 2 +- test/transpile/plugins/afterPrint.ts | 2 +- test/transpile/plugins/beforeEmit.ts | 17 +++++++ test/transpile/plugins/plugins.spec.ts | 47 ++++++++++++++++++- 9 files changed, 107 insertions(+), 28 deletions(-) create mode 100644 test/transpile/plugins/beforeEmit.ts diff --git a/src/index.ts b/src/index.ts index 0b994c7f6..2d2e3de54 100644 --- a/src/index.ts +++ b/src/index.ts @@ -8,4 +8,4 @@ export { LuaLibFeature } from "./LuaLib"; export * from "./LuaPrinter"; export * from "./transformation/context"; export * from "./transpilation"; -export { ProcessedFile } from "./transpilation/utils"; +export { EmitHost, EmitFile, ProcessedFile } from "./transpilation/utils"; diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 8b4070591..f425c5488 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -3,7 +3,7 @@ import { EmitHost } from ".."; import { CompilerOptions } from "../CompilerOptions"; import { Printer } from "../LuaPrinter"; import { Visitors } from "../transformation/context"; -import { getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils"; +import { EmitFile, getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils"; export interface Plugin { /** @@ -26,7 +26,7 @@ export interface Plugin { beforeTransform?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost) => ts.Diagnostic[] | void; /** - * This function is called after TypeScriptToLua has translated the input program to Lua. + * This function is called after translating the input program to Lua, but before resolving dependencies or bundling. */ afterPrint?: ( program: ts.Program, @@ -34,9 +34,20 @@ export interface Plugin { emitHost: EmitHost, result: ProcessedFile[] ) => ts.Diagnostic[] | void; + + /** + * This function is called after translating the input program to Lua, after resolving dependencies and after bundling. + */ + beforeEmit?: ( + program: ts.Program, + options: CompilerOptions, + emitHost: EmitHost, + result: EmitFile[] + ) => ts.Diagnostic[] | void; } -export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], customPlugins: Plugin[]): Plugin[] { +export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } { + const diagnostics: ts.Diagnostic[] = []; const pluginsFromOptions: Plugin[] = []; const options = program.getCompilerOptions() as CompilerOptions; @@ -58,5 +69,9 @@ export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], cu pluginsFromOptions.push(plugin); } - return [...customPlugins, ...pluginsFromOptions]; + if (options.tstlVerbose) { + console.log(`Loaded ${pluginsFromOptions.length} plugins`); + } + + return { diagnostics, plugins: pluginsFromOptions }; } diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index bf226992f..c693fa35a 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -4,7 +4,7 @@ import { CompilerOptions, validateOptions } from "../CompilerOptions"; import { createPrinter } from "../LuaPrinter"; import { createVisitorMap, transformSourceFile } from "../transformation"; import { isNonNull } from "../utils"; -import { getPlugins, Plugin } from "./plugins"; +import { Plugin } from "./plugins"; import { getTransformers } from "./transformers"; import { EmitHost, ProcessedFile } from "./utils"; @@ -23,7 +23,7 @@ export interface TranspileResult { export function getProgramTranspileResult( emitHost: EmitHost, writeFileResult: ts.WriteFileCallback, - { program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins: customPlugins = [] }: TranspileOptions + { program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins = [] }: TranspileOptions ): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions; @@ -60,12 +60,6 @@ export function getProgramTranspileResult( } } - const plugins = getPlugins(program, diagnostics, customPlugins); - - if (options.tstlVerbose) { - console.log(`Successfully loaded ${plugins.length} plugins`); - } - for (const plugin of plugins) { if (plugin.beforeTransform) { const pluginDiagnostics = plugin.beforeTransform(program, options, emitHost) ?? []; diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 22491ac7a..f16b6614e 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -4,6 +4,7 @@ import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; +import { getPlugins } from "./plugins"; import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; import { EmitFile, EmitHost, ProcessedFile } from "./utils"; @@ -29,23 +30,31 @@ export class Transpiler { public emit(emitOptions: EmitOptions): EmitResult { const { program, writeFile = this.emitHost.writeFile } = emitOptions; - const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose; - const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( - this.emitHost, - writeFile, - emitOptions - ); + const options = program.getCompilerOptions() as CompilerOptions; + + const { diagnostics: getPluginsDiagnostics, plugins } = getPlugins(program); + + const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(this.emitHost, writeFile, { + ...emitOptions, + plugins, + }); const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); - if (verbose) { + if (options.tstlVerbose) { console.log("Emitting output"); } - const options = program.getCompilerOptions(); + for (const plugin of plugins) { + if (plugin.beforeEmit) { + const beforeEmitPluginDiagnostics = plugin.beforeEmit(program, options, this.emitHost, emitPlan) ?? []; + diagnostics.push(...beforeEmitPluginDiagnostics); + } + } + const emitBOM = options.emitBOM ?? false; for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) { - if (verbose) { + if (options.tstlVerbose) { console.log(`Emitting ${normalizeSlashes(outputPath)}`); } @@ -55,11 +64,11 @@ export class Transpiler { } } - if (verbose) { + if (options.tstlVerbose) { console.log("Emit finished!"); } - return { diagnostics, emitSkipped: emitPlan.length === 0 }; + return { diagnostics: getPluginsDiagnostics.concat(diagnostics), emitSkipped: emitPlan.length === 0 }; } protected getEmitPlan( diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index 0bf8075d2..cef3af310 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -24,7 +24,6 @@ interface BaseFile { export interface ProcessedFile extends BaseFile { fileName: string; luaAst?: lua.File; - /** @internal */ sourceMapNode?: SourceNode; } diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index ce03539da..c2f66a1e7 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -2,8 +2,8 @@ exports[`should give verbose output 1`] = ` Array [ + "Loaded 0 plugins", "Parsing project settings", - "Successfully loaded 0 plugins", "Transforming /test/transpile/project/otherFile.ts", "Printing /test/transpile/project/otherFile.ts", "Transforming /test/transpile/project/index.ts", diff --git a/test/transpile/plugins/afterPrint.ts b/test/transpile/plugins/afterPrint.ts index 5d0d3e78d..1c2529361 100644 --- a/test/transpile/plugins/afterPrint.ts +++ b/test/transpile/plugins/afterPrint.ts @@ -13,7 +13,7 @@ const plugin: tstl.Plugin = { void emitHost; for (const file of result) { - file.code = "-- Commented added by afterPrint plugin\n" + file.code; + file.code = "-- Comment added by afterPrint plugin\n" + file.code; } }, }; diff --git a/test/transpile/plugins/beforeEmit.ts b/test/transpile/plugins/beforeEmit.ts new file mode 100644 index 000000000..973024ba4 --- /dev/null +++ b/test/transpile/plugins/beforeEmit.ts @@ -0,0 +1,17 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + beforeEmit(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost, result: tstl.EmitFile[]) { + void program; + void options; + void emitHost; + + for (const file of result) { + file.code = "-- Comment added by beforeEmit plugin\n" + file.code; + } + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 614e2f1ca..3fc4b63cf 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -112,6 +112,51 @@ test("afterPrint plugin", () => { expect(transpiledFiles).toHaveLength(2); for (const f of transpiledFiles) { // Expect plugin inserted extra lua at start of file - expect(f.lua).toContain("-- Commented added by afterPrint plugin"); + expect(f.lua).toContain("-- Comment added by afterPrint plugin"); + } +}); + +test("beforeEmit plugin", () => { + const { transpiledFiles } = util.testModule` + console.log("Hello, World!"); + [].push(1,2,3); // Use lualib code + ` + .addExtraFile( + "extrafile.ts", + ` + console.log("Hello, Mars!"); + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] }) + .getLuaResult(); + + // 2 input files + 1 lualib_bundle + expect(transpiledFiles).toHaveLength(3); + expect(transpiledFiles.find(f => f.outPath.endsWith("lualib_bundle.lua"))).toBeDefined(); + for (const f of transpiledFiles) { + // Expect plugin inserted extra lua at start of all files including lualib bundle + expect(f.lua).toContain("-- Comment added by beforeEmit plugin"); + } +}); + +test("beforeEmit plugin bundle", () => { + const { transpiledFiles } = util.testBundle` + console.log("Hello, World!"); + [].push(1,2,3); // Use lualib code + ` + .addExtraFile( + "extrafile.ts", + ` + console.log("Hello, Mars!"); + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] }) + .getLuaResult(); + + // 1 lua bundle output + expect(transpiledFiles).toHaveLength(1); + for (const f of transpiledFiles) { + // Expect bundle to be affected by plugin + expect(f.lua).toContain("-- Comment added by beforeEmit plugin"); } }); From b42bba554041ddc5aabc31695a706816d50d8d23 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 20 Mar 2022 14:29:35 +0100 Subject: [PATCH 464/764] 1.4.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a6384b0d1..bf5da97e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.4.0", + "version": "1.4.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.4.0", + "version": "1.4.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index bfedfab5f..4a15ce0d3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.4.0", + "version": "1.4.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From eaa63717c0f0f029ea3d3ef74178930dd2ac9fe3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 21 Mar 2022 21:10:40 +0100 Subject: [PATCH 465/764] Resolve node_modules symlinks as node_modules paths (#1241) --- src/transpilation/resolve.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 8643f6c86..d786c79cf 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -14,6 +14,7 @@ const resolver = resolve.ResolverFactory.createResolver({ enforceExtension: true, // Resolved file must be a lua file fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, useSyncFileSystemCalls: true, + symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) }); interface ResolutionResult { From 444306326753a3ec2a964a137bd6f830ddfa12b1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 21 Mar 2022 22:12:00 +0100 Subject: [PATCH 466/764] 1.4.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bf5da97e8..422ce67e9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.4.1", + "version": "1.4.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.4.1", + "version": "1.4.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 4a15ce0d3..a90161b5d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.4.1", + "version": "1.4.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 39480bb781a983401d6e8e99f8e3fa4c600170fd Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sat, 2 Apr 2022 22:18:02 +1000 Subject: [PATCH 467/764] Add new option to bypass 5.1 try/catch in async/await precaution (#1247) * Add new option to bypass 5.1 try/catch in async/await precaution * Fix diagnostic tests * Remove unused import --- src/CompilerOptions.ts | 11 ++++++++--- src/cli/parse.ts | 5 +++++ src/transformation/utils/diagnostics.ts | 15 +++++++++++++-- src/transformation/visitors/errors.ts | 17 ++++++++++++++--- test/unit/builtins/async-await.spec.ts | 12 ++++++++---- 5 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 1e1ba8c72..d5023bf3f 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -21,7 +21,7 @@ export interface LuaPluginImport { [option: string]: any; } -export type CompilerOptions = OmitIndexSignature & { +export interface TypeScriptToLuaOptions { buildMode?: BuildMode; extension?: string; luaBundle?: string; @@ -35,8 +35,13 @@ export type CompilerOptions = OmitIndexSignature & { plugins?: Array; sourceMapTraceback?: boolean; tstlVerbose?: boolean; - [option: string]: any; -}; + lua51AllowTryCatchInAsyncAwait?: boolean; +} + +export type CompilerOptions = OmitIndexSignature & + TypeScriptToLuaOptions & { + [option: string]: any; + }; export enum LuaLibImportKind { None = "none", diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 1a20880c9..4d113610f 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -88,6 +88,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "An array of paths that tstl should not resolve and keep as-is.", type: "array", }, + { + name: "lua51AllowTryCatchInAsyncAwait", + description: "Always allow try/catch in async/await functions for Lua 5.1.", + type: "boolean", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 25442cdfa..d0ecbd1d1 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { LuaTarget } from "../../CompilerOptions"; +import { LuaTarget, TypeScriptToLuaOptions } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; @@ -84,12 +84,23 @@ export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); +type NonUniversalTarget = Exclude; + const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export const unsupportedForTarget = createErrorDiagnosticFactory( - (functionality: string, version: Exclude) => + (functionality: string, version: NonUniversalTarget) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); +export const unsupportedForTargetButOverrideAvailable = createErrorDiagnosticFactory( + (functionality: string, version: NonUniversalTarget, optionName: keyof TypeScriptToLuaOptions) => + `As a precaution, ${functionality} is/are not supported for target ${getLuaTargetName( + version + )} due to language features/limitations. ` + + `However "--${optionName}" can be used to bypass this precaution. ` + + "See https://typescripttolua.github.io/docs/configuration for more information." +); + export const unsupportedProperty = createErrorDiagnosticFactory( (parentName: string, property: string) => `${parentName}.${property} is unsupported.` ); diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 1dc4995e4..894ba3ad5 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import { LuaTarget } from "../.."; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { unsupportedForTarget } from "../utils/diagnostics"; +import { unsupportedForTarget, unsupportedForTargetButOverrideAvailable } from "../utils/diagnostics"; import { createUnpackCall } from "../utils/lua-ast"; import { ScopeType } from "../utils/scope"; import { isInAsyncFunction, isInGeneratorFunction } from "../utils/typescript"; @@ -14,8 +14,19 @@ import { createReturnStatement } from "./return"; export const transformTryStatement: FunctionVisitor = (statement, context) => { const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if (context.options.luaTarget === LuaTarget.Lua51 && isInAsyncFunction(statement)) { - context.diagnostics.push(unsupportedForTarget(statement, "try/catch inside async functions", LuaTarget.Lua51)); + if ( + context.options.luaTarget === LuaTarget.Lua51 && + isInAsyncFunction(statement) && + !context.options.lua51AllowTryCatchInAsyncAwait + ) { + context.diagnostics.push( + unsupportedForTargetButOverrideAvailable( + statement, + "try/catch inside async functions", + LuaTarget.Lua51, + "lua51AllowTryCatchInAsyncAwait" + ) + ); return tryBlock.statements; } diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 21f8cd265..10bf7601f 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -1,6 +1,7 @@ import { ModuleKind, ScriptTarget } from "typescript"; import { LuaTarget } from "../../../src"; -import { awaitMustBeInAsyncFunction, unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; +import { unsupportedForTargetButOverrideAvailable } from "../../../src/transformation/utils/diagnostics"; +import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const promiseTestLib = ` @@ -540,7 +541,8 @@ describe("try/catch in async function", () => { // Cannot execute LuaJIT with test runner { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: 4 })), - [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + [LuaTarget.Lua51]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } ); @@ -563,7 +565,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), - [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + [LuaTarget.Lua51]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } ); @@ -590,7 +593,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), - [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), + [LuaTarget.Lua51]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } ); }); From b5159f0f39045d0bd165bd1ca49b5d33a3ba2d62 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sat, 2 Apr 2022 11:45:05 -0700 Subject: [PATCH 468/764] Optimize lualib functions (#1217) * Add benchmarks * Optimize lualib functions * Introduce NodeFlags * Optimize array push array * Remove `debug()` from tests * PR feedback --- .../runtime_benchmarks/array_concat_array.ts | 9 +++ .../runtime_benchmarks/array_concat_spread.ts | 9 +++ .../src/runtime_benchmarks/array_every.ts | 7 ++ .../src/runtime_benchmarks/array_filter.ts | 7 ++ .../src/runtime_benchmarks/array_find.ts | 9 +++ .../src/runtime_benchmarks/array_findIndex.ts | 9 +++ .../src/runtime_benchmarks/array_flat.ts | 7 ++ .../src/runtime_benchmarks/array_flatMap.ts | 13 ++++ .../src/runtime_benchmarks/array_foreach.ts | 10 +++ .../src/runtime_benchmarks/array_includes.ts | 9 +++ .../src/runtime_benchmarks/array_indexOf.ts | 9 +++ .../src/runtime_benchmarks/array_join.ts | 8 ++ benchmark/src/runtime_benchmarks/array_map.ts | 7 ++ .../runtime_benchmarks/array_push_array.ts | 9 +++ .../{array_push.ts => array_push_multiple.ts} | 4 +- .../runtime_benchmarks/array_push_single.ts | 8 ++ .../runtime_benchmarks/array_push_vararg.ts | 12 +++ .../src/runtime_benchmarks/array_reduce.ts | 7 ++ .../runtime_benchmarks/array_reduceRight.ts | 7 ++ .../src/runtime_benchmarks/array_reverse.ts | 7 ++ .../src/runtime_benchmarks/array_slice.ts | 9 +++ .../src/runtime_benchmarks/array_some.ts | 7 ++ .../src/runtime_benchmarks/array_splice.ts | 9 +++ .../src/runtime_benchmarks/array_unshift.ts | 9 +++ .../src/runtime_benchmarks/string_concat.ts | 8 ++ .../src/runtime_benchmarks/string_replace.ts | 8 ++ .../runtime_benchmarks/string_replaceAll.ts | 8 ++ .../src/runtime_benchmarks/string_split.ts | 8 ++ src/LuaAST.ts | 30 +++++--- src/LuaLib.ts | 3 +- src/LuaPrinter.ts | 5 +- src/lualib/ArrayConcat.ts | 26 ++++--- src/lualib/ArrayEvery.ts | 10 +-- src/lualib/ArrayFilter.ts | 14 ++-- src/lualib/ArrayFind.ts | 15 ++-- src/lualib/ArrayFindIndex.ts | 12 +-- src/lualib/ArrayFlat.ts | 23 ++++-- src/lualib/ArrayFlatMap.ts | 23 +++--- src/lualib/ArrayForEach.ts | 10 +-- src/lualib/ArrayIncludes.ts | 4 +- src/lualib/ArrayIndexOf.ts | 28 +++---- src/lualib/ArrayIsArray.ts | 4 +- src/lualib/ArrayJoin.ts | 11 ++- src/lualib/ArrayMap.ts | 14 ++-- src/lualib/ArrayPush.ts | 10 ++- src/lualib/ArrayPushArray.ts | 8 ++ src/lualib/ArrayReduce.ts | 13 ++-- src/lualib/ArrayReduceRight.ts | 13 ++-- src/lualib/ArrayReverse.ts | 18 ++--- src/lualib/ArraySetLength.ts | 6 +- src/lualib/ArrayShift.ts | 3 - src/lualib/ArraySlice.ts | 47 ++++++------ src/lualib/ArraySome.ts | 10 +-- src/lualib/ArraySort.ts | 8 +- src/lualib/ArraySplice.ts | 74 +++++++++++-------- src/lualib/ArrayToObject.ts | 6 +- src/lualib/ArrayUnshift.ts | 14 +++- src/lualib/FunctionBind.ts | 7 +- src/lualib/ObjectAssign.ts | 13 ++-- src/lualib/ObjectEntries.ts | 4 +- src/lualib/ObjectKeys.ts | 4 +- src/lualib/ObjectValues.ts | 4 +- src/lualib/Spread.ts | 8 +- src/lualib/StringConcat.ts | 7 -- src/lualib/StringReplace.ts | 2 +- src/lualib/StringReplaceAll.ts | 19 ++--- src/lualib/StringSplit.ts | 36 ++++----- src/transformation/builtins/array.ts | 71 ++++++++++++++++-- src/transformation/builtins/string.ts | 8 +- src/transformation/utils/lua-ast.ts | 6 +- src/transformation/utils/typescript/index.ts | 8 ++ src/transformation/visitors/class/index.ts | 2 +- .../visitors/class/members/accessors.ts | 2 +- .../visitors/class/members/constructor.ts | 2 +- src/transformation/visitors/function.ts | 8 +- src/transformation/visitors/spread.ts | 11 +-- test/unit/__snapshots__/switch.spec.ts.snap | 32 +++----- test/unit/builtins/array.spec.ts | 21 +++++- test/unit/builtins/loading.spec.ts | 4 +- 79 files changed, 657 insertions(+), 317 deletions(-) create mode 100644 benchmark/src/runtime_benchmarks/array_concat_array.ts create mode 100644 benchmark/src/runtime_benchmarks/array_concat_spread.ts create mode 100644 benchmark/src/runtime_benchmarks/array_every.ts create mode 100644 benchmark/src/runtime_benchmarks/array_filter.ts create mode 100644 benchmark/src/runtime_benchmarks/array_find.ts create mode 100644 benchmark/src/runtime_benchmarks/array_findIndex.ts create mode 100644 benchmark/src/runtime_benchmarks/array_flat.ts create mode 100644 benchmark/src/runtime_benchmarks/array_flatMap.ts create mode 100644 benchmark/src/runtime_benchmarks/array_foreach.ts create mode 100644 benchmark/src/runtime_benchmarks/array_includes.ts create mode 100644 benchmark/src/runtime_benchmarks/array_indexOf.ts create mode 100644 benchmark/src/runtime_benchmarks/array_join.ts create mode 100644 benchmark/src/runtime_benchmarks/array_map.ts create mode 100644 benchmark/src/runtime_benchmarks/array_push_array.ts rename benchmark/src/runtime_benchmarks/{array_push.ts => array_push_multiple.ts} (68%) create mode 100644 benchmark/src/runtime_benchmarks/array_push_single.ts create mode 100644 benchmark/src/runtime_benchmarks/array_push_vararg.ts create mode 100644 benchmark/src/runtime_benchmarks/array_reduce.ts create mode 100644 benchmark/src/runtime_benchmarks/array_reduceRight.ts create mode 100644 benchmark/src/runtime_benchmarks/array_reverse.ts create mode 100644 benchmark/src/runtime_benchmarks/array_slice.ts create mode 100644 benchmark/src/runtime_benchmarks/array_some.ts create mode 100644 benchmark/src/runtime_benchmarks/array_splice.ts create mode 100644 benchmark/src/runtime_benchmarks/array_unshift.ts create mode 100644 benchmark/src/runtime_benchmarks/string_concat.ts create mode 100644 benchmark/src/runtime_benchmarks/string_replace.ts create mode 100644 benchmark/src/runtime_benchmarks/string_replaceAll.ts create mode 100644 benchmark/src/runtime_benchmarks/string_split.ts create mode 100644 src/lualib/ArrayPushArray.ts delete mode 100644 src/lualib/ArrayShift.ts delete mode 100644 src/lualib/StringConcat.ts diff --git a/benchmark/src/runtime_benchmarks/array_concat_array.ts b/benchmark/src/runtime_benchmarks/array_concat_array.ts new file mode 100644 index 000000000..9c9a7e83d --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_concat_array.ts @@ -0,0 +1,9 @@ +export default function arrayConcat(): number[] { + const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const n = 50000; + for (let i = 0; i < n; i++) { + arr1.concat(arr2); + } + return arr1; +} diff --git a/benchmark/src/runtime_benchmarks/array_concat_spread.ts b/benchmark/src/runtime_benchmarks/array_concat_spread.ts new file mode 100644 index 000000000..a04eff958 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_concat_spread.ts @@ -0,0 +1,9 @@ +export default function arrayConcat(): number[] { + const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; + const n = 50000; + for (let i = 0; i < n; i++) { + arr1.concat(...arr2); + } + return arr1; +} diff --git a/benchmark/src/runtime_benchmarks/array_every.ts b/benchmark/src/runtime_benchmarks/array_every.ts new file mode 100644 index 000000000..f5dbfc4e4 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_every.ts @@ -0,0 +1,7 @@ +export default function arrayEvery() { + const n = 200000; + const array = [1, 2, 3, 4, 5, 6, 7, 8, 7, 10]; + for (let i = 0; i < n; i++) { + array.every((item, index) => item > index); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_filter.ts b/benchmark/src/runtime_benchmarks/array_filter.ts new file mode 100644 index 000000000..127d2476d --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_filter.ts @@ -0,0 +1,7 @@ +export default function arrayFilter() { + const n = 100000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 7, 10]; + for (let i = 0; i < n; i++) { + array.filter((item, index) => item > index); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_find.ts b/benchmark/src/runtime_benchmarks/array_find.ts new file mode 100644 index 000000000..8a84ff4e5 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_find.ts @@ -0,0 +1,9 @@ +export default function arrayFind() { + const n = 50000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 10; j++) { + array.find(value => value === j); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_findIndex.ts b/benchmark/src/runtime_benchmarks/array_findIndex.ts new file mode 100644 index 000000000..c058a99df --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_findIndex.ts @@ -0,0 +1,9 @@ +export default function arrayFindIndex() { + const n = 50000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 10; j++) { + array.findIndex(value => value === j); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_flat.ts b/benchmark/src/runtime_benchmarks/array_flat.ts new file mode 100644 index 000000000..36ace2d95 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_flat.ts @@ -0,0 +1,7 @@ +export default function arrayFlat() { + const n = 50000; + const array = [1, 2, [3, [4, 5], 6], 7, [8, 9], 10]; + for (let i = 0; i < n; i++) { + array.flat(2); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_flatMap.ts b/benchmark/src/runtime_benchmarks/array_flatMap.ts new file mode 100644 index 000000000..26c6490e5 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_flatMap.ts @@ -0,0 +1,13 @@ +export default function arrayFlatMap() { + const n = 50000; + const array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + array.flatMap((el, index) => { + if (index < 5) { + return [el, el + 1]; + } else { + return el + 2; + } + }); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_foreach.ts b/benchmark/src/runtime_benchmarks/array_foreach.ts new file mode 100644 index 000000000..8e14c8119 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_foreach.ts @@ -0,0 +1,10 @@ +export default function arrayForeach() { + const n = 200000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + array.forEach(value => { + let foo = value * 2; + foo = foo; + }); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_includes.ts b/benchmark/src/runtime_benchmarks/array_includes.ts new file mode 100644 index 000000000..828c167a3 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_includes.ts @@ -0,0 +1,9 @@ +export default function arrayIncludes() { + const n = 50000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 10; j++) { + array.includes(j); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_indexOf.ts b/benchmark/src/runtime_benchmarks/array_indexOf.ts new file mode 100644 index 000000000..333c67988 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_indexOf.ts @@ -0,0 +1,9 @@ +export default function arrayIndexOf() { + const n = 50000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 10; j++) { + array.indexOf(j); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_join.ts b/benchmark/src/runtime_benchmarks/array_join.ts new file mode 100644 index 000000000..5a9f5bae4 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_join.ts @@ -0,0 +1,8 @@ +const array = [1, 2, "3", 4, 3, "6", { foo: 3 }, 8, 9, 10]; + +export default function arrayJoin() { + const n = 3000; + for (let i = 0; i < n; i++) { + array.join("|"); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_map.ts b/benchmark/src/runtime_benchmarks/array_map.ts new file mode 100644 index 000000000..79d00d66a --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_map.ts @@ -0,0 +1,7 @@ +export default function arrayMap() { + const n = 100000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + array.map(value => value * 2); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_push_array.ts b/benchmark/src/runtime_benchmarks/array_push_array.ts new file mode 100644 index 000000000..fcc239a31 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_push_array.ts @@ -0,0 +1,9 @@ +export default function arrayPush(): number[] { + const n = 200000; + const numberList: number[] = []; + const numbers = [1, 2, 3]; + for (let i = 0; i < n; i++) { + numberList.push(...numbers); + } + return numberList; +} diff --git a/benchmark/src/runtime_benchmarks/array_push.ts b/benchmark/src/runtime_benchmarks/array_push_multiple.ts similarity index 68% rename from benchmark/src/runtime_benchmarks/array_push.ts rename to benchmark/src/runtime_benchmarks/array_push_multiple.ts index e0d2d0b87..dbef5460c 100644 --- a/benchmark/src/runtime_benchmarks/array_push.ts +++ b/benchmark/src/runtime_benchmarks/array_push_multiple.ts @@ -1,8 +1,8 @@ export default function arrayPush(): number[] { - const n = 1000000; + const n = 200000; const numberList: number[] = []; for (let i = 0; i < n; i++) { - numberList[numberList.length] = i * i; + numberList.push(i * i, i + 1); } return numberList; } diff --git a/benchmark/src/runtime_benchmarks/array_push_single.ts b/benchmark/src/runtime_benchmarks/array_push_single.ts new file mode 100644 index 000000000..f09bc21ec --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_push_single.ts @@ -0,0 +1,8 @@ +export default function arrayPush(): number[] { + const n = 500000; + const numberList: number[] = []; + for (let i = 0; i < n; i++) { + numberList.push(i * i); + } + return numberList; +} diff --git a/benchmark/src/runtime_benchmarks/array_push_vararg.ts b/benchmark/src/runtime_benchmarks/array_push_vararg.ts new file mode 100644 index 000000000..e780461ee --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_push_vararg.ts @@ -0,0 +1,12 @@ +export default function arrayPush(): number[] { + const n = 200000; + const numberList: number[] = []; + function pushArgs(...args: number[]): void { + numberList.push(...args); + } + + for (let i = 0; i < n; i++) { + pushArgs(3, 4); + } + return numberList; +} diff --git a/benchmark/src/runtime_benchmarks/array_reduce.ts b/benchmark/src/runtime_benchmarks/array_reduce.ts new file mode 100644 index 000000000..2d615e80f --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_reduce.ts @@ -0,0 +1,7 @@ +export default function arrayReduce() { + const n = 200000; + const array = [1, 2, 3, 4, 5, 6, 7, 8, 7, 10]; + for (let i = 0; i < n; i++) { + array.reduce((prev, cur, i) => prev + cur + i, 1); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_reduceRight.ts b/benchmark/src/runtime_benchmarks/array_reduceRight.ts new file mode 100644 index 000000000..9dd97d3d2 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_reduceRight.ts @@ -0,0 +1,7 @@ +export default function arrayReduce() { + const n = 200000; + const array = [1, 2, 3, 4, 5, 6, 7, 8, 7, 10]; + for (let i = 0; i < n; i++) { + array.reduceRight((prev, cur, i) => prev + cur + i, 1); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_reverse.ts b/benchmark/src/runtime_benchmarks/array_reverse.ts new file mode 100644 index 000000000..539d26138 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_reverse.ts @@ -0,0 +1,7 @@ +export default function arrayReverse(): void { + const n = 500000; + const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + numbers.reverse(); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_slice.ts b/benchmark/src/runtime_benchmarks/array_slice.ts new file mode 100644 index 000000000..5419cb0d9 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_slice.ts @@ -0,0 +1,9 @@ +export default function arraySlice() { + const n = 50000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 6; j++) { + array.slice(j, -j); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_some.ts b/benchmark/src/runtime_benchmarks/array_some.ts new file mode 100644 index 000000000..8add42a56 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_some.ts @@ -0,0 +1,7 @@ +export default function arraySome() { + const n = 200000; + const array = [1, 2, 3, 4, 5, 6, 7, 8, 7, 10]; + for (let i = 0; i < n; i++) { + array.some((item, index) => item < index); + } +} diff --git a/benchmark/src/runtime_benchmarks/array_splice.ts b/benchmark/src/runtime_benchmarks/array_splice.ts new file mode 100644 index 000000000..4620bad86 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_splice.ts @@ -0,0 +1,9 @@ +export default function arraySplice() { + const n = 20000; + const array = [1, 2, 3, 4, 3, 6, 7, 8, 9, 10]; + for (let i = 0; i < n; i++) { + for (let j = 0; j < 10; j++) { + array.splice(j, 2, 1, 2); + } + } +} diff --git a/benchmark/src/runtime_benchmarks/array_unshift.ts b/benchmark/src/runtime_benchmarks/array_unshift.ts new file mode 100644 index 000000000..b0f59a0b2 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/array_unshift.ts @@ -0,0 +1,9 @@ +export default function arrayUnshift(): number[] { + const n = 2000; + const numberList: number[] = []; + const numbers = [1, 2, 3]; + for (let i = 0; i < n; i++) { + numberList.unshift(...numbers); + } + return numberList; +} diff --git a/benchmark/src/runtime_benchmarks/string_concat.ts b/benchmark/src/runtime_benchmarks/string_concat.ts new file mode 100644 index 000000000..47d520e9a --- /dev/null +++ b/benchmark/src/runtime_benchmarks/string_concat.ts @@ -0,0 +1,8 @@ +export default function stringReplace() { + const str = "one"; + const n = 50000; + for (let i = 0; i < n; i++) { + str.concat("two", "three", "four", "five"); + } + return str; +} diff --git a/benchmark/src/runtime_benchmarks/string_replace.ts b/benchmark/src/runtime_benchmarks/string_replace.ts new file mode 100644 index 000000000..e7a00fc35 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/string_replace.ts @@ -0,0 +1,8 @@ +export default function stringReplace() { + const str = "Hello, World!"; + const n = 50000; + for (let i = 0; i < n; i++) { + str.replace("World", "Universe"); + } + return str; +} diff --git a/benchmark/src/runtime_benchmarks/string_replaceAll.ts b/benchmark/src/runtime_benchmarks/string_replaceAll.ts new file mode 100644 index 000000000..268bb3642 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/string_replaceAll.ts @@ -0,0 +1,8 @@ +export default function stringReplaceAll() { + const str = "hello, hello world!"; + const n = 50000; + for (let i = 0; i < n; i++) { + str.replaceAll("Hello", "Goodbye"); + } + return str; +} diff --git a/benchmark/src/runtime_benchmarks/string_split.ts b/benchmark/src/runtime_benchmarks/string_split.ts new file mode 100644 index 000000000..22f6c9bb1 --- /dev/null +++ b/benchmark/src/runtime_benchmarks/string_split.ts @@ -0,0 +1,8 @@ +export default function stringReplaceAll() { + const str = "This is a string"; + const n = 50000; + for (let i = 0; i < n; i++) { + str.split(" "); + } + return str; +} diff --git a/src/LuaAST.ts b/src/LuaAST.ts index ee5c9d329..472831451 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -125,6 +125,13 @@ export type Operator = UnaryOperator | BinaryOperator; export type SymbolId = number & { _symbolIdBrand: any }; +export enum NodeFlags { + None = 0, + Inline = 1 << 0, // Keep function body on same line + Declaration = 1 << 1, // Prefer declaration syntax `function foo()` over assignment syntax `foo = function()` + TableUnpackCall = 1 << 2, // This is a table.unpack call +} + export interface TextRange { line?: number; column?: number; @@ -132,18 +139,19 @@ export interface TextRange { export interface Node extends TextRange { kind: SyntaxKind; + flags: NodeFlags; } export function createNode(kind: SyntaxKind, tsOriginal?: ts.Node): Node { if (tsOriginal === undefined) { - return { kind }; + return { kind, flags: NodeFlags.None }; } const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { - return { kind, line: sourcePosition.line, column: sourcePosition.column }; + return { kind, line: sourcePosition.line, column: sourcePosition.column, flags: NodeFlags.None }; } else { - return { kind }; + return { kind, flags: NodeFlags.None }; } } @@ -190,6 +198,11 @@ export function getOriginalPos(node: Node): TextRange { return { line: node.line, column: node.column }; } +export function setNodeFlags(node: T, flags: NodeFlags): T { + node.flags = flags; + return node; +} + export interface File extends Node { kind: SyntaxKind.File; statements: Statement[]; @@ -578,18 +591,11 @@ export function isLiteral( ); } -export enum FunctionExpressionFlags { - None = 1 << 0, - Inline = 1 << 1, // Keep function body on same line - Declaration = 1 << 2, // Prefer declaration syntax `function foo()` over assignment syntax `foo = function()` -} - export interface FunctionExpression extends Expression { kind: SyntaxKind.FunctionExpression; params?: Identifier[]; dots?: DotsLiteral; body: Block; - flags: FunctionExpressionFlags; } export function isFunctionExpression(node: Node): node is FunctionExpression { @@ -600,7 +606,7 @@ export function createFunctionExpression( body: Block, params?: Identifier[], dots?: DotsLiteral, - flags = FunctionExpressionFlags.None, + flags = NodeFlags.None, tsOriginal?: ts.Node ): FunctionExpression { const expression = createNode(SyntaxKind.FunctionExpression, tsOriginal) as FunctionExpression; @@ -819,6 +825,6 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr expression.body.statements?.length === 1 && isReturnStatement(expression.body.statements[0]) && expression.body.statements[0].expressions !== undefined && - (expression.flags & FunctionExpressionFlags.Inline) !== 0 + (expression.flags & NodeFlags.Inline) !== 0 ); } diff --git a/src/LuaLib.ts b/src/LuaLib.ts index b9beddab9..60ffcf8c7 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -17,10 +17,10 @@ export enum LuaLibFeature { ArrayJoin = "ArrayJoin", ArrayMap = "ArrayMap", ArrayPush = "ArrayPush", + ArrayPushArray = "ArrayPushArray", ArrayReduce = "ArrayReduce", ArrayReduceRight = "ArrayReduceRight", ArrayReverse = "ArrayReverse", - ArrayShift = "ArrayShift", ArrayUnshift = "ArrayUnshift", ArraySort = "ArraySort", ArraySlice = "ArraySlice", @@ -80,7 +80,6 @@ export enum LuaLibFeature { StringAccess = "StringAccess", StringCharAt = "StringCharAt", StringCharCodeAt = "StringCharCodeAt", - StringConcat = "StringConcat", StringEndsWith = "StringEndsWith", StringIncludes = "StringIncludes", StringPadEnd = "StringPadEnd", diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 851131a42..ed6163dc0 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -433,10 +433,7 @@ export class LuaPrinter { chunks.push(this.indent()); - if ( - lua.isFunctionDefinition(statement) && - (statement.right[0].flags & lua.FunctionExpressionFlags.Declaration) !== 0 - ) { + if (lua.isFunctionDefinition(statement) && (statement.right[0].flags & lua.NodeFlags.Declaration) !== 0) { // Use `function foo()` instead of `foo = function()` const name = this.printExpression(statement.left[0]); if (isValidLuaFunctionDeclarationName(name.toString(), this.options)) { diff --git a/src/lualib/ArrayConcat.ts b/src/lualib/ArrayConcat.ts index 56f3d1b5f..caaafa369 100644 --- a/src/lualib/ArrayConcat.ts +++ b/src/lualib/ArrayConcat.ts @@ -1,18 +1,22 @@ -export function __TS__ArrayConcat(this: void, arr1: any[], ...args: any[]): any[] { - const out: any[] = []; - for (const val of arr1) { - out[out.length] = val; +export function __TS__ArrayConcat(this: T[], ...items: Array): T[] { + const result: T[] = []; + let len = 0; + for (const i of $range(1, this.length)) { + len++; + result[len - 1] = this[i - 1]; } - for (const arg of args) { - if (Array.isArray(arg)) { - const argAsArray = arg; - for (const val of argAsArray) { - out[out.length] = val; + for (const i of $range(1, items.length)) { + const item = items[i - 1]; + if (Array.isArray(item)) { + for (const j of $range(1, item.length)) { + len++; + result[len - 1] = item[j - 1]; } } else { - out[out.length] = arg; + len++; + result[len - 1] = item; } } - return out; + return result; } diff --git a/src/lualib/ArrayEvery.ts b/src/lualib/ArrayEvery.ts index 43dd312ea..d94efec54 100644 --- a/src/lualib/ArrayEvery.ts +++ b/src/lualib/ArrayEvery.ts @@ -1,10 +1,10 @@ export function __TS__ArrayEvery( - this: void, - arr: T[], - callbackfn: (value: T, index?: number, array?: any[]) => boolean + this: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean, + thisArg?: any ): boolean { - for (let i = 0; i < arr.length; i++) { - if (!callbackfn(arr[i], i, arr)) { + for (const i of $range(1, this.length)) { + if (!callbackfn.call(thisArg, this[i - 1], i - 1, this)) { return false; } } diff --git a/src/lualib/ArrayFilter.ts b/src/lualib/ArrayFilter.ts index 0559a02d6..5d63a0494 100644 --- a/src/lualib/ArrayFilter.ts +++ b/src/lualib/ArrayFilter.ts @@ -1,12 +1,14 @@ export function __TS__ArrayFilter( - this: void, - arr: T[], - callbackfn: (value: T, index?: number, array?: any[]) => boolean + this: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean, + thisArg?: any ): T[] { const result: T[] = []; - for (let i = 0; i < arr.length; i++) { - if (callbackfn(arr[i], i, arr)) { - result[result.length] = arr[i]; + let len = 0; + for (const i of $range(1, this.length)) { + if (callbackfn.call(thisArg, this[i - 1], i - 1, this)) { + len++; + result[len - 1] = this[i - 1]; } } return result; diff --git a/src/lualib/ArrayFind.ts b/src/lualib/ArrayFind.ts index a9a0efc70..3beb9c83b 100644 --- a/src/lualib/ArrayFind.ts +++ b/src/lualib/ArrayFind.ts @@ -1,17 +1,14 @@ // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.find export function __TS__ArrayFind( - this: void, - arr: T[], - predicate: (value: T, index: number, obj: T[]) => unknown + this: T[], + predicate: (value: T, index: number, obj: T[]) => unknown, + thisArg?: any ): T | undefined { - const len = arr.length; - let k = 0; - while (k < len) { - const elem = arr[k]; - if (predicate(elem, k, arr)) { + for (const i of $range(1, this.length)) { + const elem = this[i - 1]; + if (predicate.call(thisArg, elem, i - 1, this)) { return elem; } - k += 1; } return undefined; diff --git a/src/lualib/ArrayFindIndex.ts b/src/lualib/ArrayFindIndex.ts index 945fed18d..3741f3a0f 100644 --- a/src/lualib/ArrayFindIndex.ts +++ b/src/lualib/ArrayFindIndex.ts @@ -1,11 +1,11 @@ export function __TS__ArrayFindIndex( - this: void, - arr: T[], - callbackFn: (element: T, index?: number, array?: T[]) => boolean + this: T[], + callbackFn: (element: T, index?: number, array?: T[]) => boolean, + thisArg?: any ): number { - for (let i = 0, len = arr.length; i < len; i++) { - if (callbackFn(arr[i], i, arr)) { - return i; + for (const i of $range(1, this.length)) { + if (callbackFn.call(thisArg, this[i - 1], i - 1, this)) { + return i - 1; } } return -1; diff --git a/src/lualib/ArrayFlat.ts b/src/lualib/ArrayFlat.ts index b98861aeb..3e15b455b 100644 --- a/src/lualib/ArrayFlat.ts +++ b/src/lualib/ArrayFlat.ts @@ -1,10 +1,23 @@ -export function __TS__ArrayFlat(this: void, array: any[], depth = 1): any[] { - let result: any[] = []; - for (const value of array) { +export function __TS__ArrayFlat(this: any[], depth = 1): any[] { + const result: any[] = []; + let len = 0; + for (const i of $range(1, this.length)) { + const value = this[i - 1]; if (depth > 0 && Array.isArray(value)) { - result = result.concat(__TS__ArrayFlat(value, depth - 1)); + let toAdd: any[]; + if (depth === 1) { + toAdd = value; + } else { + toAdd = value.flat(depth - 1); + } + for (const j of $range(1, toAdd.length)) { + const val = toAdd[j - 1]; + len++; + result[len - 1] = val; + } } else { - result[result.length] = value; + len++; + result[len - 1] = value; } } diff --git a/src/lualib/ArrayFlatMap.ts b/src/lualib/ArrayFlatMap.ts index 29f92c1f5..fa68fce8f 100644 --- a/src/lualib/ArrayFlatMap.ts +++ b/src/lualib/ArrayFlatMap.ts @@ -1,15 +1,20 @@ export function __TS__ArrayFlatMap( - this: void, - array: T[], - callback: (value: T, index: number, array: T[]) => U | readonly U[] + this: T[], + callback: (value: T, index: number, array: T[]) => U | readonly U[], + thisArg?: any ): U[] { - let result: U[] = []; - for (let i = 0; i < array.length; i++) { - const value = callback(array[i], i, array); - if (type(value) === "table" && Array.isArray(value)) { - result = result.concat(value); + const result: U[] = []; + let len = 0; + for (const i of $range(1, this.length)) { + const value = callback.call(thisArg, this[i - 1], i - 1, this); + if (Array.isArray(value)) { + for (const j of $range(1, value.length)) { + len++; + result[len - 1] = value[j - 1]; + } } else { - result[result.length] = value as U; + len++; + result[len - 1] = value as U; } } diff --git a/src/lualib/ArrayForEach.ts b/src/lualib/ArrayForEach.ts index 37a610433..caf4ec53e 100644 --- a/src/lualib/ArrayForEach.ts +++ b/src/lualib/ArrayForEach.ts @@ -1,9 +1,9 @@ export function __TS__ArrayForEach( - this: void, - arr: T[], - callbackFn: (value: T, index?: number, array?: any[]) => any + this: T[], + callbackFn: (value: T, index?: number, array?: any[]) => any, + thisArg?: any ): void { - for (let i = 0; i < arr.length; i++) { - callbackFn(arr[i], i, arr); + for (const i of $range(1, this.length)) { + callbackFn.call(thisArg, this[i - 1], i - 1, this); } } diff --git a/src/lualib/ArrayIncludes.ts b/src/lualib/ArrayIncludes.ts index 88e788a15..b3fd871f6 100644 --- a/src/lualib/ArrayIncludes.ts +++ b/src/lualib/ArrayIncludes.ts @@ -11,8 +11,8 @@ export function __TS__ArrayIncludes(this: T[], searchElement: T, fromIndex = k = 0; } - for (const i of $range(k, len)) { - if (this[i] === searchElement) { + for (const i of $range(k + 1, len)) { + if (this[i - 1] === searchElement) { return true; } } diff --git a/src/lualib/ArrayIndexOf.ts b/src/lualib/ArrayIndexOf.ts index 1631caf76..0a3ebc1f9 100644 --- a/src/lualib/ArrayIndexOf.ts +++ b/src/lualib/ArrayIndexOf.ts @@ -1,31 +1,23 @@ -export function __TS__ArrayIndexOf(this: void, arr: T[], searchElement: T, fromIndex?: number): number { - const len = arr.length; +export function __TS__ArrayIndexOf(this: T[], searchElement: T, fromIndex = 0): number { + const len = this.length; if (len === 0) { return -1; } - let n = 0; - if (fromIndex) { - n = fromIndex; - } - - if (n >= len) { + if (fromIndex >= len) { return -1; } - let k: number; - if (n >= 0) { - k = n; - } else { - k = len + n; - if (k < 0) { - k = 0; + if (fromIndex < 0) { + fromIndex = len + fromIndex; + if (fromIndex < 0) { + fromIndex = 0; } } - for (let i = k; i < len; i++) { - if (arr[i] === searchElement) { - return i; + for (const i of $range(fromIndex + 1, len)) { + if (this[i - 1] === searchElement) { + return i - 1; } } diff --git a/src/lualib/ArrayIsArray.ts b/src/lualib/ArrayIsArray.ts index 7d2ec3112..61fca760b 100644 --- a/src/lualib/ArrayIsArray.ts +++ b/src/lualib/ArrayIsArray.ts @@ -1,7 +1,7 @@ -declare type NextEmptyCheck = (this: void, table: any, index: undefined) => unknown | undefined; +declare type NextEmptyCheck = (this: void, table: any, index?: undefined) => unknown | undefined; export function __TS__ArrayIsArray(this: void, value: any): value is any[] { // Workaround to determine if value is an array or not (fails in case of objects without keys) // See discussion in: https://github.com/TypeScriptToLua/TypeScriptToLua/pull/737 - return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value, undefined) === undefined); + return type(value) === "table" && (1 in value || (next as NextEmptyCheck)(value) === undefined); } diff --git a/src/lualib/ArrayJoin.ts b/src/lualib/ArrayJoin.ts index 7400b886e..0f0b11c9f 100644 --- a/src/lualib/ArrayJoin.ts +++ b/src/lualib/ArrayJoin.ts @@ -1,8 +1,7 @@ -export function __TS__ArrayJoin(this: unknown[], separator = ",") { - let result = ""; - for (const [index, value] of ipairs(this)) { - if (index > 1) result += separator; - result += value.toString(); +export function __TS__ArrayJoin(this: any[], separator = ",") { + const parts: string[] = []; + for (const i of $range(1, this.length)) { + parts[i - 1] = this[i - 1].toString(); } - return result; + return table.concat(parts, separator); } diff --git a/src/lualib/ArrayMap.ts b/src/lualib/ArrayMap.ts index 7e9c868fa..2caf84028 100644 --- a/src/lualib/ArrayMap.ts +++ b/src/lualib/ArrayMap.ts @@ -1,11 +1,11 @@ export function __TS__ArrayMap( - this: void, - arr: T[], - callbackfn: (value: T, index?: number, array?: T[]) => U + this: T[], + callbackfn: (value: T, index?: number, array?: T[]) => U, + thisArg?: any ): U[] { - const newArray: U[] = []; - for (let i = 0; i < arr.length; i++) { - newArray[i] = callbackfn(arr[i], i, arr); + const result: U[] = []; + for (const i of $range(1, this.length)) { + result[i - 1] = callbackfn.call(thisArg, this[i - 1], i - 1, this); } - return newArray; + return result; } diff --git a/src/lualib/ArrayPush.ts b/src/lualib/ArrayPush.ts index 39d4f241e..9f181d1f2 100644 --- a/src/lualib/ArrayPush.ts +++ b/src/lualib/ArrayPush.ts @@ -1,6 +1,8 @@ -export function __TS__ArrayPush(this: void, arr: T[], ...items: T[]): number { - for (const item of items) { - arr[arr.length] = item; +export function __TS__ArrayPush(this: T[], ...items: T[]): number { + let len = this.length; + for (const i of $range(1, items.length)) { + len++; + this[len - 1] = items[i - 1]; } - return arr.length; + return len; } diff --git a/src/lualib/ArrayPushArray.ts b/src/lualib/ArrayPushArray.ts new file mode 100644 index 000000000..8ea9b6916 --- /dev/null +++ b/src/lualib/ArrayPushArray.ts @@ -0,0 +1,8 @@ +export function __TS__ArrayPushArray(this: T[], items: T[]): number { + let len = this.length; + for (const i of $range(1, items.length)) { + len++; + this[len - 1] = items[i - 1]; + } + return len; +} diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index 737128cd0..eb26a9731 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,27 +1,26 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduce( - this: void, - arr: TElement[], + this: TElement[], callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, ...initial: TAccumulator[] ): TAccumulator { - const len = arr.length; + const len = this.length; let k = 0; let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - [accumulator] = select(1, ...initial); + [accumulator] = [...initial]; } else if (len > 0) { - accumulator = arr[0] as unknown as TAccumulator; + accumulator = this[0] as unknown as TAccumulator; k = 1; } else { throw "Reduce of empty array with no initial value"; } - for (const i of $range(k, len - 1)) { - accumulator = callbackFn(accumulator, arr[i], i, arr); + for (const i of $range(k + 1, len)) { + accumulator = callbackFn(accumulator, this[i - 1], i - 1, this); } return accumulator; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 91099946a..e32e87e79 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,27 +1,26 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduceRight( - this: void, - arr: TElement[], + this: TElement[], callbackFn: (accumulator: TAccumulator, currentValue: TElement, index: number, array: TElement[]) => TAccumulator, ...initial: TAccumulator[] ): TAccumulator { - const len = arr.length; + const len = this.length; let k = len - 1; let accumulator: TAccumulator = undefined; // Check if initial value is present in function call if (select("#", ...initial) !== 0) { - [accumulator] = select(1, ...initial); + [accumulator] = [...initial]; } else if (len > 0) { - accumulator = arr[k] as unknown as TAccumulator; + accumulator = this[k] as unknown as TAccumulator; k -= 1; } else { throw "Reduce of empty array with no initial value"; } - for (const i of $range(k, 0, -1)) { - accumulator = callbackFn(accumulator, arr[i], i, arr); + for (const i of $range(k + 1, 1, -1)) { + accumulator = callbackFn(accumulator, this[i - 1], i - 1, this); } return accumulator; diff --git a/src/lualib/ArrayReverse.ts b/src/lualib/ArrayReverse.ts index e644355d9..96403753b 100644 --- a/src/lualib/ArrayReverse.ts +++ b/src/lualib/ArrayReverse.ts @@ -1,12 +1,12 @@ -export function __TS__ArrayReverse(this: void, arr: any[]): any[] { - let i = 0; - let j = arr.length - 1; +export function __TS__ArrayReverse(this: any[]): any[] { + let i = 1; + let j = this.length; while (i < j) { - const temp = arr[j]; - arr[j] = arr[i]; - arr[i] = temp; - i += 1; - j -= 1; + const temp = this[j - 1]; + this[j - 1] = this[i - 1]; + this[i - 1] = temp; + i++; + j--; } - return arr; + return this; } diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 6fde3254d..4ec78715d 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -1,4 +1,4 @@ -export function __TS__ArraySetLength(this: void, arr: T[], length: number): number { +export function __TS__ArraySetLength(this: T[], length: number): number { if ( length < 0 || length !== length || // NaN @@ -8,8 +8,8 @@ export function __TS__ArraySetLength(this: void, arr: T[], length: number): n // non-integer throw `invalid array length: ${length}`; } - for (let i = arr.length - 1; i >= length; --i) { - arr[i] = undefined; + for (const i of $range(length + 1, this.length)) { + this[i - 1] = undefined; } return length; } diff --git a/src/lualib/ArrayShift.ts b/src/lualib/ArrayShift.ts deleted file mode 100644 index 799463d9d..000000000 --- a/src/lualib/ArrayShift.ts +++ /dev/null @@ -1,3 +0,0 @@ -export function __TS__ArrayShift(this: void, arr: T[]): T { - return table.remove(arr, 1); -} diff --git a/src/lualib/ArraySlice.ts b/src/lualib/ArraySlice.ts index e9797c43f..e8c357e7f 100644 --- a/src/lualib/ArraySlice.ts +++ b/src/lualib/ArraySlice.ts @@ -1,34 +1,39 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.slice -export function __TS__ArraySlice(this: void, list: T[], first: number, last: number): T[] { - const len = list.length; +export function __TS__ArraySlice(this: T[], first?: number, last?: number): T[] { + const len = this.length; - const relativeStart = first || 0; - - let k: number; - if (relativeStart < 0) { - k = Math.max(len + relativeStart, 0); + first = first ?? 0; + if (first < 0) { + first = len + first; + if (first < 0) { + first = 0; + } } else { - k = Math.min(relativeStart, len); - } - - let relativeEnd = last; - if (last === undefined) { - relativeEnd = len; + if (first > len) { + first = len; + } } - let final: number; - if (relativeEnd < 0) { - final = Math.max(len + relativeEnd, 0); + last = last ?? len; + if (last < 0) { + last = len + last; + if (last < 0) { + last = 0; + } } else { - final = Math.min(relativeEnd, len); + if (last > len) { + last = len; + } } const out = []; - let n = 0; - while (k < final) { - out[n] = list[k]; - k++; + first++; + last++; + let n = 1; + while (first < last) { + out[n - 1] = this[first - 1]; + first++; n++; } return out; diff --git a/src/lualib/ArraySome.ts b/src/lualib/ArraySome.ts index 1c4725d4c..33ffe69ab 100644 --- a/src/lualib/ArraySome.ts +++ b/src/lualib/ArraySome.ts @@ -1,10 +1,10 @@ export function __TS__ArraySome( - this: void, - arr: T[], - callbackfn: (value: T, index?: number, array?: any[]) => boolean + this: T[], + callbackfn: (value: T, index?: number, array?: any[]) => boolean, + thisArg?: any ): boolean { - for (let i = 0; i < arr.length; i++) { - if (callbackfn(arr[i], i, arr)) { + for (const i of $range(1, this.length)) { + if (callbackfn.call(thisArg, this[i - 1], i - 1, this)) { return true; } } diff --git a/src/lualib/ArraySort.ts b/src/lualib/ArraySort.ts index 034344f76..2a6495511 100644 --- a/src/lualib/ArraySort.ts +++ b/src/lualib/ArraySort.ts @@ -1,8 +1,8 @@ -export function __TS__ArraySort(this: void, arr: T[], compareFn?: (a: T, b: T) => number): T[] { +export function __TS__ArraySort(this: T[], compareFn?: (a: T, b: T) => number): T[] { if (compareFn !== undefined) { - table.sort(arr, (a, b) => compareFn(a, b) < 0); + table.sort(this, (a, b) => compareFn(a, b) < 0); } else { - table.sort(arr); + table.sort(this); } - return arr; + return this; } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 273525ed0..dc69e16fb 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,20 +1,24 @@ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice -export function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { - const len = list.length; +export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { + const len = this.length; const actualArgumentCount = select("#", ...args); - const start = select(1, ...args)[0] as unknown as number; - const deleteCount = select(2, ...args)[0] as unknown as number; - - let actualStart: number; + let start = args[0] as number; + const deleteCount = args[1] as number; if (start < 0) { - actualStart = Math.max(len + start, 0); - } else { - actualStart = Math.min(start, len); + start = len + start; + if (start < 0) { + start = 0; + } + } else if (start > len) { + start = len; } - const itemCount = Math.max(actualArgumentCount - 2, 0); + let itemCount = actualArgumentCount - 2; + if (itemCount < 0) { + itemCount = 0; + } let actualDeleteCount: number; @@ -23,56 +27,62 @@ export function __TS__ArraySplice(this: void, list: T[], ...args: T[]): T[] { actualDeleteCount = 0; } else if (actualArgumentCount === 1) { // ECMA-spec line 6: if number of actual arguments is 1 - actualDeleteCount = len - actualStart; + actualDeleteCount = len - start; } else { - actualDeleteCount = Math.min(Math.max(deleteCount || 0, 0), len - actualStart); + actualDeleteCount = deleteCount ?? 0; + if (actualDeleteCount < 0) { + actualDeleteCount = 0; + } + if (actualDeleteCount > len - start) { + actualDeleteCount = len - start; + } } const out: T[] = []; - for (let k = 0; k < actualDeleteCount; k++) { - const from = actualStart + k; + for (const k of $range(1, actualDeleteCount)) { + const from = start + k; - if (list[from]) { - out[k] = list[from]; + if (this[from - 1] !== undefined) { + out[k - 1] = this[from - 1]; } } if (itemCount < actualDeleteCount) { - for (let k = actualStart; k < len - actualDeleteCount; k++) { + for (const k of $range(start + 1, len - actualDeleteCount)) { const from = k + actualDeleteCount; const to = k + itemCount; - if (list[from]) { - list[to] = list[from]; + if (this[from - 1]) { + this[to - 1] = this[from - 1]; } else { - list[to] = undefined; + this[to - 1] = undefined; } } - for (let k = len; k > len - actualDeleteCount + itemCount; k--) { - list[k - 1] = undefined; + for (const k of $range(len - actualDeleteCount + itemCount + 1, len)) { + this[k - 1] = undefined; } } else if (itemCount > actualDeleteCount) { - for (let k = len - actualDeleteCount; k > actualStart; k--) { - const from = k + actualDeleteCount - 1; - const to = k + itemCount - 1; + for (const k of $range(len - actualDeleteCount, start + 1, -1)) { + const from = k + actualDeleteCount; + const to = k + itemCount; - if (list[from]) { - list[to] = list[from]; + if (this[from - 1]) { + this[to - 1] = this[from - 1]; } else { - list[to] = undefined; + this[to - 1] = undefined; } } } - let j = actualStart; + let j = start + 1; for (const i of $range(3, actualArgumentCount)) { - list[j] = select(i, ...args)[0]; + this[j - 1] = args[i - 1]; j++; } - for (let k = list.length - 1; k >= len - actualDeleteCount + itemCount; k--) { - list[k] = undefined; + for (const k of $range(this.length, len - actualDeleteCount + itemCount + 1, -1)) { + this[k - 1] = undefined; } return out; diff --git a/src/lualib/ArrayToObject.ts b/src/lualib/ArrayToObject.ts index e3ed41f78..1f9e9778a 100644 --- a/src/lualib/ArrayToObject.ts +++ b/src/lualib/ArrayToObject.ts @@ -1,7 +1,7 @@ -export function __TS__ArrayToObject(this: void, array: T[]): Record { +export function __TS__ArrayToObject(this: T[]): Record { const object: Record = {}; - for (let i = 0; i < array.length; i += 1) { - object[i] = array[i]; + for (const i of $range(1, this.length)) { + object[i - 1] = this[i - 1]; } return object; } diff --git a/src/lualib/ArrayUnshift.ts b/src/lualib/ArrayUnshift.ts index c3dd6bdb4..6c628c625 100644 --- a/src/lualib/ArrayUnshift.ts +++ b/src/lualib/ArrayUnshift.ts @@ -1,6 +1,12 @@ -export function __TS__ArrayUnshift(this: void, arr: T[], ...items: T[]): number { - for (let i = items.length - 1; i >= 0; --i) { - table.insert(arr, 1, items[i]); +export function __TS__ArrayUnshift(this: T[], ...items: T[]): number { + const numItemsToInsert = items.length; + if (numItemsToInsert === 0) return this.length; + + for (const i of $range(this.length, 1, -1)) { + this[i + numItemsToInsert - 1] = this[i - 1]; } - return arr.length; + for (const i of $range(1, numItemsToInsert)) { + this[i - 1] = items[i - 1]; + } + return this.length; } diff --git a/src/lualib/FunctionBind.ts b/src/lualib/FunctionBind.ts index a6cb2fac5..f36e9f6e5 100644 --- a/src/lualib/FunctionBind.ts +++ b/src/lualib/FunctionBind.ts @@ -1,13 +1,10 @@ export function __TS__FunctionBind( this: void, fn: (this: void, ...argArray: any[]) => any, - thisArg: any, ...boundArgs: any[] ): (...args: any[]) => any { return (...args: any[]) => { - for (let i = 0; i < boundArgs.length; ++i) { - table.insert(args, i + 1, boundArgs[i]); - } - return fn(thisArg, ...args); + args.unshift(...boundArgs); + return fn(...args); }; } diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index a351c030a..4fd4aff0d 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,15 +1,12 @@ // https://tc39.github.io/ecma262/#sec-object.assign // eslint-disable-next-line @typescript-eslint/ban-types -export function __TS__ObjectAssign(this: void, to: T, ...sources: object[]): T { - if (to === undefined) { - return to; - } - - for (const source of sources) { +export function __TS__ObjectAssign(this: void, target: T, ...sources: T[]): T { + for (const i of $range(1, sources.length)) { + const source = sources[i - 1]; for (const key in source) { - to[key] = source[key]; + target[key] = source[key]; } } - return to; + return target; } diff --git a/src/lualib/ObjectEntries.ts b/src/lualib/ObjectEntries.ts index 3059fbecf..5daeee1e0 100644 --- a/src/lualib/ObjectEntries.ts +++ b/src/lualib/ObjectEntries.ts @@ -1,7 +1,9 @@ export function __TS__ObjectEntries(this: void, obj: any): Array { const result = []; + let len = 0; for (const key in obj) { - result[result.length] = [key, obj[key]]; + len++; + result[len - 1] = [key, obj[key]]; } return result; } diff --git a/src/lualib/ObjectKeys.ts b/src/lualib/ObjectKeys.ts index d07f6c8d6..c7a0c0208 100644 --- a/src/lualib/ObjectKeys.ts +++ b/src/lualib/ObjectKeys.ts @@ -1,7 +1,9 @@ export function __TS__ObjectKeys(this: void, obj: any): Array { const result = []; + let len = 0; for (const key in obj) { - result[result.length] = key; + len++; + result[len - 1] = key; } return result; } diff --git a/src/lualib/ObjectValues.ts b/src/lualib/ObjectValues.ts index 02ab400cb..925a61ab3 100644 --- a/src/lualib/ObjectValues.ts +++ b/src/lualib/ObjectValues.ts @@ -1,7 +1,9 @@ export function __TS__ObjectValues(this: void, obj: any): Array { const result = []; + let len = 0; for (const key in obj) { - result[result.length] = obj[key]; + len++; + result[len - 1] = obj[key]; } return result; } diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 46ec8d5ae..ffe745b6d 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -2,12 +2,14 @@ export function __TS__Spread(this: void, iterable: string | Iterable): Lua const arr = []; if (typeof iterable === "string") { // eslint-disable-next-line @typescript-eslint/prefer-for-of - for (let i = 0; i < iterable.length; i += 1) { - arr[arr.length] = iterable[i]; + for (const i of $range(0, iterable.length - 1)) { + arr[i] = iterable[i]; } } else { + let len = 0; for (const item of iterable) { - arr[arr.length] = item; + len++; + arr[len - 1] = item; } } return $multi(...arr); diff --git a/src/lualib/StringConcat.ts b/src/lualib/StringConcat.ts deleted file mode 100644 index 473040f31..000000000 --- a/src/lualib/StringConcat.ts +++ /dev/null @@ -1,7 +0,0 @@ -export function __TS__StringConcat(this: void, str1: string, ...args: string[]): string { - let out = str1; - for (const arg of args) { - out += arg; - } - return out; -} diff --git a/src/lualib/StringReplace.ts b/src/lualib/StringReplace.ts index f7de1da7a..9a2da017b 100644 --- a/src/lualib/StringReplace.ts +++ b/src/lualib/StringReplace.ts @@ -1,3 +1,4 @@ +const sub = string.sub; export function __TS__StringReplace( this: void, source: string, @@ -8,7 +9,6 @@ export function __TS__StringReplace( if (!startPos) { return source; } - const sub = string.sub; const before = sub(source, 1, startPos - 1); const replacement = typeof replaceValue === "string" ? replaceValue : replaceValue(searchValue, startPos - 1, source); diff --git a/src/lualib/StringReplaceAll.ts b/src/lualib/StringReplaceAll.ts index 6911f92d7..c110512e9 100644 --- a/src/lualib/StringReplaceAll.ts +++ b/src/lualib/StringReplaceAll.ts @@ -1,35 +1,36 @@ +const sub = string.sub; +const find = string.find; export function __TS__StringReplaceAll( this: void, source: string, searchValue: string, replaceValue: string | ((match: string, offset: number, string: string) => string) ): string { - let replacer: (match: string, offset: number, string: string) => string; if (typeof replaceValue === "string") { - replacer = () => replaceValue; - } else { - replacer = replaceValue; + const concat = table.concat(source.split(searchValue), replaceValue); + if (searchValue.length === 0) { + return replaceValue + concat + replaceValue; + } + return concat; } const parts: string[] = []; let partsIndex = 1; - const sub = string.sub; if (searchValue.length === 0) { - parts[0] = replacer("", 0, source); + parts[0] = replaceValue("", 0, source); partsIndex = 2; for (const i of $range(1, source.length)) { parts[partsIndex - 1] = sub(source, i, i); - parts[partsIndex] = replacer("", i, source); + parts[partsIndex] = replaceValue("", i, source); partsIndex += 2; } } else { - const find = string.find; let currentPos = 1; while (true) { const [startPos, endPos] = find(source, searchValue, currentPos, true); if (!startPos) break; parts[partsIndex - 1] = sub(source, currentPos, startPos - 1); - parts[partsIndex] = replacer(searchValue, startPos - 1, source); + parts[partsIndex] = replaceValue(searchValue, startPos - 1, source); partsIndex += 2; currentPos = endPos + 1; diff --git a/src/lualib/StringSplit.ts b/src/lualib/StringSplit.ts index cf2b6ae9d..1d2dd6610 100644 --- a/src/lualib/StringSplit.ts +++ b/src/lualib/StringSplit.ts @@ -1,3 +1,5 @@ +const sub = string.sub; +const find = string.find; export function __TS__StringSplit(this: void, source: string, separator?: string, limit?: number): string[] { if (limit === undefined) { limit = 4294967295; @@ -7,30 +9,28 @@ export function __TS__StringSplit(this: void, source: string, separator?: string return []; } - const out = []; - let index = 0; - let count = 0; + const result = []; + let resultIndex = 1; if (separator === undefined || separator === "") { - while (index < source.length - 1 && count < limit) { - out[count] = source[index]; - count++; - index++; + for (const i of $range(1, source.length)) { + result[resultIndex - 1] = sub(source, i, i); + resultIndex++; } } else { - const separatorLength = separator.length; - let nextIndex = source.indexOf(separator); - while (nextIndex >= 0 && count < limit) { - out[count] = source.substring(index, nextIndex); - count++; - index = nextIndex + separatorLength; - nextIndex = source.indexOf(separator, index); + let currentPos = 1; + while (resultIndex <= limit) { + const [startPos, endPos] = find(source, separator, currentPos, true); + if (!startPos) break; + result[resultIndex - 1] = sub(source, currentPos, startPos - 1); + resultIndex++; + currentPos = endPos + 1; } - } - if (count < limit) { - out[count] = source.substring(index); + if (resultIndex <= limit) { + result[resultIndex - 1] = sub(source, currentPos); + } } - return out; + return result; } diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 3242cd57a..9567c45ae 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -4,8 +4,9 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; -import { isStringType, isNumberType } from "../utils/typescript"; -import { wrapInTable } from "../utils/lua-ast"; +import { isStringType, isNumberType, findFirstNonOuterParent } from "../utils/typescript"; +import { moveToPrecedingTemp } from "../visitors/expression-list"; +import { isUnpackCall, wrapInTable } from "../utils/lua-ast"; export function transformArrayConstructorCall( context: TransformationContext, @@ -28,10 +29,47 @@ export function transformArrayConstructorCall( } } +/** + * Optimized single element Array.push + * + * array[#array+1] = el + * return (#array + 1) + */ +function transformSingleElementArrayPush( + context: TransformationContext, + node: PropertyCallExpression, + caller: lua.Expression, + param: lua.Expression +): lua.Expression { + const expressionIsUsed = !ts.isExpressionStatement(findFirstNonOuterParent(node)); + + const arrayIdentifier = lua.isIdentifier(caller) ? caller : moveToPrecedingTemp(context, caller); + + // #array + 1 + let lengthExpression: lua.Expression = lua.createBinaryExpression( + lua.createUnaryExpression(arrayIdentifier, lua.SyntaxKind.LengthOperator), + lua.createNumericLiteral(1), + lua.SyntaxKind.AdditionOperator + ); + + if (expressionIsUsed) { + // store length in a temp + lengthExpression = moveToPrecedingTemp(context, lengthExpression); + } + + const pushStatement = lua.createAssignmentStatement( + lua.createTableIndexExpression(arrayIdentifier, lengthExpression), + param, + node + ); + context.addPrecedingStatements(pushStatement); + return expressionIsUsed ? lengthExpression : lua.createNilLiteral(); +} + export function transformArrayPrototypeCall( context: TransformationContext, node: PropertyCallExpression -): lua.CallExpression | undefined { +): lua.Expression | undefined { const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); @@ -43,11 +81,31 @@ export function transformArrayPrototypeCall( case "entries": return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); case "push": + if (node.arguments.length === 1) { + const param = params[0]; + if (isUnpackCall(param)) { + return transformLuaLibFunction( + context, + LuaLibFeature.ArrayPushArray, + node, + caller, + (param as lua.CallExpression).params[0] + ); + } + if (!lua.isDotsLiteral(param)) { + return transformSingleElementArrayPush(context, node, caller, param); + } + } + return transformLuaLibFunction(context, LuaLibFeature.ArrayPush, node, caller, ...params); case "reverse": return transformLuaLibFunction(context, LuaLibFeature.ArrayReverse, node, caller); case "shift": - return transformLuaLibFunction(context, LuaLibFeature.ArrayShift, node, caller); + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("remove")), + [caller, lua.createNumericLiteral(1)], + node + ); case "unshift": return transformLuaLibFunction(context, LuaLibFeature.ArrayUnshift, node, caller, ...params); case "sort": @@ -89,11 +147,14 @@ export function transformArrayPrototypeCall( const elementType = context.checker.getElementTypeOfArrayType(callerType); if (elementType && (isStringType(context, elementType) || isNumberType(context, elementType))) { const defaultSeparatorLiteral = lua.createStringLiteral(","); + const param = params[0]; const parameters = [ caller, node.arguments.length === 0 ? defaultSeparatorLiteral - : lua.createBinaryExpression(params[0], defaultSeparatorLiteral, lua.SyntaxKind.OrOperator), + : lua.isStringLiteral(param) + ? param + : lua.createBinaryExpression(param, defaultSeparatorLiteral, lua.SyntaxKind.OrOperator), ]; return lua.createCallExpression( diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index c71f855fc..d151d8d47 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; -import { addToNumericExpression, createNaN, getNumberLiteralValue } from "../utils/lua-ast"; +import { addToNumericExpression, createNaN, getNumberLiteralValue, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; @@ -30,7 +30,11 @@ export function transformStringPrototypeCall( case "replaceAll": return transformLuaLibFunction(context, LuaLibFeature.StringReplaceAll, node, caller, ...params); case "concat": - return transformLuaLibFunction(context, LuaLibFeature.StringConcat, node, caller, ...params); + return lua.createCallExpression( + lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("concat")), + [wrapInTable(caller, ...params)], + node + ); case "indexOf": { const stringExpression = createStringCall( diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 9508479ce..b894dba63 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -76,7 +76,11 @@ export function createUnpackCall( ? lua.createIdentifier("unpack") : lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("unpack")); - return lua.createCallExpression(unpack, [expression], tsOriginal); + return lua.setNodeFlags(lua.createCallExpression(unpack, [expression], tsOriginal), lua.NodeFlags.TableUnpackCall); +} + +export function isUnpackCall(node: lua.Node): boolean { + return lua.isCallExpression(node) && (node.flags & lua.NodeFlags.TableUnpackCall) !== 0; } export function wrapInTable(...expressions: lua.Expression[]): lua.TableExpression { diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 1e2ffba44..f9c60f583 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -24,6 +24,14 @@ export function findFirstNodeAbove(node: ts.Node, callback: ( } } +export function findFirstNonOuterParent(node: ts.Node): ts.Node { + let current = node.parent; + while (ts.isOuterExpression(current)) { + current = current.parent; + } + return current; +} + export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { const originalSourceFile = ts.getParseTreeNode(sourceFile) ?? sourceFile; const declarations = (symbol.getDeclarations() ?? []).filter(d => d.getSourceFile() === originalSourceFile); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 5257c2db6..80b5f7536 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -155,7 +155,7 @@ function transformClassLikeDeclaration( lua.createBlock(constructorBody), [createSelfIdentifier()], lua.createDotsLiteral(), - lua.FunctionExpressionFlags.Declaration + lua.NodeFlags.Declaration ); result.push( lua.createAssignmentStatement(createConstructorName(localClassName), constructorFunction, classDeclaration) diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index f774b9645..fe34a3d8a 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -11,7 +11,7 @@ import { createPrototypeName } from "./constructor"; function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; - return lua.createFunctionExpression(lua.createBlock(body), params, dot, lua.FunctionExpressionFlags.Declaration); + return lua.createFunctionExpression(lua.createBlock(body), params, dot, lua.NodeFlags.Declaration); } export function transformAccessorDeclarations( diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 11766d2a8..22ab14feb 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -90,7 +90,7 @@ export function transformConstructorDeclaration( return lua.createAssignmentStatement( createConstructorName(className), - lua.createFunctionExpression(block, params, dotsLiteral, lua.FunctionExpressionFlags.Declaration), + lua.createFunctionExpression(block, params, dotsLiteral, lua.NodeFlags.Declaration), constructorWasGenerated ? classDeclaration : statement ); } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 9ced7089f..0b432ae84 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -66,7 +66,7 @@ export function createCallableTable(functionExpression: lua.Expression): lua.Exp ]), [lua.createAnonymousIdentifier()], lua.createDotsLiteral(), - lua.FunctionExpressionFlags.Inline + lua.NodeFlags.Inline ); } return lua.createCallExpression(lua.createIdentifier("setmetatable"), [ @@ -231,10 +231,10 @@ export function transformFunctionToExpression( } } - let flags = lua.FunctionExpressionFlags.None; - if (!ts.isBlock(node.body)) flags |= lua.FunctionExpressionFlags.Inline; + let flags = lua.NodeFlags.None; + if (!ts.isBlock(node.body)) flags |= lua.NodeFlags.Inline; if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node)) { - flags |= lua.FunctionExpressionFlags.Declaration; + flags |= lua.NodeFlags.Declaration; } const [paramNames, dotsLiteral, spreadIdentifier] = transformParameters(context, node.parameters, functionContext); diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 455f25fbf..1cfbe18ea 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -11,20 +11,13 @@ import { isFunctionScopeWithDefinition, ScopeType, } from "../utils/scope"; -import { isArrayType } from "../utils/typescript"; +import { isArrayType, findFirstNonOuterParent } from "../utils/typescript"; import { isMultiReturnCall } from "./language-extensions/multi"; import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; -function skipOuterExpressionParents(node: ts.Node) { - while (ts.isOuterExpression(node)) { - node = node.parent; - } - return node; -} - export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { - if (!ts.isSpreadElement(skipOuterExpressionParents(identifier.parent))) { + if (!ts.isSpreadElement(findFirstNonOuterParent(identifier))) { return false; } diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index a640878c4..ef5504938 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -1,16 +1,14 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`switch empty fallthrough to default (0) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__ArrayPush = ____lualib.__TS__ArrayPush -local ____exports = {} +"local ____exports = {} function ____exports.__main(self) local out = {} repeat local ____switch3 = 0 local ____cond3 = ____switch3 == 1 do - __TS__ArrayPush(out, \\"default\\") + out[#out + 1] = \\"default\\" end until true return out @@ -19,16 +17,14 @@ return ____exports" `; exports[`switch empty fallthrough to default (1) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__ArrayPush = ____lualib.__TS__ArrayPush -local ____exports = {} +"local ____exports = {} function ____exports.__main(self) local out = {} repeat local ____switch3 = 1 local ____cond3 = ____switch3 == 1 do - __TS__ArrayPush(out, \\"default\\") + out[#out + 1] = \\"default\\" end until true return out @@ -113,9 +109,7 @@ return ____exports" `; exports[`switch produces optimal output 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__ArrayPush = ____lualib.__TS__ArrayPush -local ____exports = {} +"local ____exports = {} function ____exports.__main(self) local x = 0 local out = {} @@ -123,13 +117,13 @@ function ____exports.__main(self) local ____switch3 = 0 local ____cond3 = ____switch3 == 0 or ____switch3 == 1 or ____switch3 == 2 if ____cond3 then - __TS__ArrayPush(out, \\"0,1,2\\") + out[#out + 1] = \\"0,1,2\\" break end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then do - __TS__ArrayPush(out, \\"3\\") + out[#out + 1] = \\"3\\" break end end @@ -139,20 +133,14 @@ function ____exports.__main(self) end do x = x + 1 - __TS__ArrayPush( - out, - \\"default = \\" .. tostring(x) - ) + out[#out + 1] = \\"default = \\" .. tostring(x) do - __TS__ArrayPush(out, \\"3\\") + out[#out + 1] = \\"3\\" break end end until true - __TS__ArrayPush( - out, - tostring(x) - ) + out[#out + 1] = tostring(x) return out end return ____exports" diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 98b749e3b..b86a07fa1 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -472,10 +472,27 @@ test.each([ util.testExpression`${util.formatCode(array)}.indexOf(${util.formatCode(...args)})`.expectToMatchJsResult(); }); -test.each([{ args: [1] }, { args: [1, 2, 3] }])("array.push (%p)", ({ args }) => { +test.each([ + { args: "1" }, + { args: "1, 2, 3" }, + { args: "...[1, 2, 3]" }, + { args: "1, 2, ...[3, 4]" }, + { args: "1, 2, ...[3, 4], 5" }, +])("array.push (%p)", ({ args }) => { + util.testFunction` + const array = [0]; + const value = array.push(${args}); + return { array, value }; + `.expectToMatchJsResult(); +}); + +test("array.push(...)", () => { util.testFunction` const array = [0]; - const value = array.push(${util.formatCode(...args)}); + function push(...args: any[]) { + return array.push(...args); + } + const value = push(1, 2, 3); return { array, value }; `.expectToMatchJsResult(); }); diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index a5da97772..ac76de5a1 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -4,14 +4,14 @@ import * as util from "../../util"; describe("luaLibImport", () => { test("inline", () => { - util.testExpression`[0].push(1)` + util.testExpression`[0].indexOf(1)` .setOptions({ luaLibImport: tstl.LuaLibImportKind.Inline }) .tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); test("require", () => { - util.testExpression`[0].push(1)` + util.testExpression`[0].indexOf(1)` .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToMatchJsResult(); From 87cb4dc005ddf1c9a0435e9ce397807199013dba Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Mon, 4 Apr 2022 18:41:59 +0200 Subject: [PATCH 469/764] Fix benchmark results being logged as undefined (#1249) * Correctly output memory benchmarks and runtime benchmarks into CI log * Improved markdown formatting --- .github/scripts/create_benchmark_check.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/scripts/create_benchmark_check.js b/.github/scripts/create_benchmark_check.js index e1d303e06..4d9ac86cc 100644 --- a/.github/scripts/create_benchmark_check.js +++ b/.github/scripts/create_benchmark_check.js @@ -16,7 +16,13 @@ module.exports = ({ github, context, core }) => { const summary = `[Open visualizer](https://typescripttolua.github.io/benchviz?d=${compressed.toString("base64")})\n` + - `### Lua5.3\n${benchmarkInfoLua.comparison.summary}\n### LuaJIT\n${benchmarkInfoJIT.comparison.summary}`; + `### Lua5.3 +${benchmarkInfoLua.comparison.memory.summary} +${benchmarkInfoLua.comparison.runtime.summary} +--- +### LuaJIT +${benchmarkInfoJIT.comparison.memory.summary} +${benchmarkInfoJIT.comparison.runtime.summary}`; return summary; }; From 570c51092709449e1b936036ecb104584df627d5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 10 Apr 2022 19:32:19 +0200 Subject: [PATCH 470/764] Support for import expressions (#1254) * Support for import expressions * update package-lock and jest timeout --- package-lock.json | 12 ++++++------ src/transformation/builtins/promise.ts | 2 +- src/transformation/visitors/call.ts | 5 +++++ src/transformation/visitors/modules/import.ts | 9 +++++++++ test/cli/run.ts | 2 +- test/unit/modules/modules.spec.ts | 11 +++++++++++ 6 files changed, 33 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 422ce67e9..164ef86fa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5084,9 +5084,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "node_modules/ms": { @@ -10320,9 +10320,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, "ms": { diff --git a/src/transformation/builtins/promise.ts b/src/transformation/builtins/promise.ts index cd30aa718..11d80d45c 100644 --- a/src/transformation/builtins/promise.ts +++ b/src/transformation/builtins/promise.ts @@ -44,7 +44,7 @@ export function transformPromiseConstructorCall( } } -function createStaticPromiseFunctionAccessor(functionName: string, node: ts.Node) { +export function createStaticPromiseFunctionAccessor(functionName: string, node: ts.Node) { return lua.createTableIndexExpression( lua.createIdentifier("__TS__Promise"), lua.createStringLiteral(functionName), diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index b59b3889e..58eb29eab 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -15,6 +15,7 @@ import { moveToPrecedingTemp, transformExpressionList } from "./expression-list" import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { getOptionalContinuationData, transformOptionalChain } from "./optional-chaining"; import { transformLanguageExtensionCallExpression } from "./language-extensions"; +import { transformImportExpression } from "./modules/import"; export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; @@ -210,6 +211,10 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre } export const transformCallExpression: FunctionVisitor = (node, context) => { + if (node.expression.kind === ts.SyntaxKind.ImportKeyword) { + return transformImportExpression(node, context); + } + if (ts.isOptionalChain(node)) { return transformOptionalChain(context, node); } diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index a9a53f4e4..7a320d558 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -1,10 +1,12 @@ import * as path from "path"; import * as ts from "typescript"; import * as lua from "../../../LuaAST"; +import { createStaticPromiseFunctionAccessor } from "../../builtins/promise"; import { FunctionVisitor, TransformationContext } from "../../context"; import { AnnotationKind, getSymbolAnnotations } from "../../utils/annotations"; import { createDefaultExportStringLiteral } from "../../utils/export"; import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast"; +import { importLuaLibFeature, LuaLibFeature } from "../../utils/lualib"; import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; import { transformIdentifier } from "../identifier"; @@ -161,3 +163,10 @@ export const transformImportEqualsDeclaration: FunctionVisitor = (node, context) => { + importLuaLibFeature(context, LuaLibFeature.Promise); + + const importPath = node.arguments.map(a => context.transformExpression(a)); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", node), importPath, node); +}; diff --git a/test/cli/run.ts b/test/cli/run.ts index cee7e19b2..652e03095 100644 --- a/test/cli/run.ts +++ b/test/cli/run.ts @@ -1,7 +1,7 @@ import { ChildProcess, fork } from "child_process"; import * as path from "path"; -jest.setTimeout(20000); +jest.setTimeout(30000); const cliPath = path.join(__dirname, "../../src/tstl.ts"); diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index ffdc36ce9..73f7c5be1 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -280,3 +280,14 @@ test("namespace export with unsafe Lua name", () => { .addExtraFile("module.ts", moduleFile) .expectToMatchJsResult(); }); + +test("import expression", () => { + util.testModule` + let result; + import("./module").then(m => { result = m.foo(); }); + export { result }; + ` + .addExtraFile("module.ts", 'export function foo() { return "foo"; }') + .setOptions({ module: ts.ModuleKind.ESNext }) + .expectToMatchJsResult(); +}); From 288ab8cd1c7e1736578db0b31fd23f62c0ccfce6 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 10 Apr 2022 19:47:25 +0200 Subject: [PATCH 471/764] 1.4.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 164ef86fa..d864867d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.4.2", + "version": "1.4.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.4.2", + "version": "1.4.3", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index a90161b5d..ceb273174 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.4.2", + "version": "1.4.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From ffcca572bfd1067cd07e5ce6e8e15b3eaa4b4282 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 20 Apr 2022 20:39:54 +0200 Subject: [PATCH 472/764] Fix exception trying to push single element to optional chain array (#1257) --- src/transformation/utils/typescript/index.ts | 4 ++-- test/unit/builtins/array.spec.ts | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index f9c60f583..5f603f98e 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -25,9 +25,9 @@ export function findFirstNodeAbove(node: ts.Node, callback: ( } export function findFirstNonOuterParent(node: ts.Node): ts.Node { - let current = node.parent; + let current = ts.getOriginalNode(node).parent; while (ts.isOuterExpression(current)) { - current = current.parent; + current = ts.getOriginalNode(current).parent; } return current; } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index b86a07fa1..6c73c1588 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -497,6 +497,15 @@ test("array.push(...)", () => { `.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256 +test.each(["[1, 2, 3]", "undefined"])("array push on optional array", value => { + util.testFunction` + const arr = ${value} as number[] | undefined; + arr?.push(4); + return arr + `.expectToMatchJsResult(); +}); + test.each([ { array: [1, 2, 3], expected: [3, 2] }, { array: [1, 2, 3, null], expected: [3, 2] }, From 080163ac742c7a790b426d7907a5a310a8158242 Mon Sep 17 00:00:00 2001 From: Gengxin Wang <793493083@qq.com> Date: Sun, 24 Apr 2022 22:54:47 +0800 Subject: [PATCH 473/764] fix: debug.traceback of loadstring get unknown file #1259 (#1260) * fix: debug.traceback of loadstring get unknown file #1259 * fix the linter errors * add a test: loadstring sourceMapTraceback gives traceback * better test for loadstring sourceMapTraceback gives traceback --- src/lualib/SourceMapTraceBack.ts | 20 +++++++++++++++++--- test/unit/printer/sourcemaps.spec.ts | 22 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index f33a0dcd4..fe1714f1f 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -43,9 +43,23 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap let [result] = string.gsub(trace, "(%S+)%.lua:(%d+)", (file, line) => replacer(`${file}.lua`, `${file}.ts`, line) ); - [result] = string.gsub(result, '(%[string "[^"]+"%]):(%d+)', (file, line) => - replacer(file, "unknown", line) - ); + + const stringReplacer = (file: string, line: string) => { + const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; + if (fileSourceMap && fileSourceMap[line]) { + const chunkName = string.match(file, '%[string "([^"]+)"%]')[0]; + const [sourceName] = string.gsub(chunkName, ".lua$", ".ts"); + const data = fileSourceMap[line]; + if (typeof data === "number") { + return `${sourceName}:${data}`; + } + + return `${data.file}:${data.line}`; + } + + return `${file}:${line}`; + }; + [result] = string.gsub(result, '(%[string "[^"]+"%]):(%d+)', (file, line) => stringReplacer(file, line)); return result; }) as typeof debug.traceback; diff --git a/test/unit/printer/sourcemaps.spec.ts b/test/unit/printer/sourcemaps.spec.ts index 9ea7a920c..478f482d6 100644 --- a/test/unit/printer/sourcemaps.spec.ts +++ b/test/unit/printer/sourcemaps.spec.ts @@ -1,5 +1,6 @@ import { SourceMapConsumer } from "source-map"; import * as tstl from "../../../src"; +import { LuaTarget, transpileString } from "../../../src"; import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; import { lineAndColumnOf } from "./utils"; @@ -326,3 +327,24 @@ test("Inline sourcemaps", () => { const inlineSourceMap = Buffer.from(inlineSourceMapMatch, "base64").toString(); expect(inlineSourceMap).toBe(file.luaSourceMap); }); + +test("loadstring sourceMapTraceback gives traceback", () => { + const loadStrCode = transpileString( + `function bar() { + const trace = (debug.traceback as (this: void)=>string)(); + return trace; + } + return bar();`, + { sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 } + ).file?.lua; + + const builder = util.testModule` + const luaCode = \`${loadStrCode}\`; + return loadstring(luaCode, "foo.lua")(); + ` + .setTsHeader("declare function loadstring(this: void, string: string, chunkname: string): () => unknown") + .setOptions({ sourceMapTraceback: true, luaTarget: LuaTarget.Lua51 }); + + const traceback = builder.getLuaExecutionResult(); + expect(traceback).toContain("foo.ts"); +}); From 5756807aa6cccbd8ffd1044832c1ad3d66604544 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 5 May 2022 20:26:59 +0200 Subject: [PATCH 474/764] 1.4.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d864867d2..486db8945 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.4.3", + "version": "1.4.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.4.3", + "version": "1.4.4", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index ceb273174..3c9e19d90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.4.3", + "version": "1.4.4", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 43d31d080b0f6c3a67d8844c38c402873696b0ec Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sat, 28 May 2022 12:20:20 -0400 Subject: [PATCH 475/764] noImplicitGlobalVariables compiler option (#1269) * adding option + test * adding noImplicitGlobalVariables option * Update noImplicitGlobalVariables.spec.ts * prettier fix * fix tests --- src/CompilerOptions.ts | 1 + src/cli/parse.ts | 6 ++++ src/transformation/utils/lua-ast.ts | 4 ++- .../noImplicitGlobalVariables.spec.ts | 30 +++++++++++++++++++ 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/unit/functions/noImplicitGlobalVariables.spec.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index d5023bf3f..5c9700097 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -29,6 +29,7 @@ export interface TypeScriptToLuaOptions { luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; luaPlugins?: LuaPluginImport[]; + noImplicitGlobalVariables?: boolean; noImplicitSelf?: boolean; noHeader?: boolean; noResolvePaths?: string[]; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 4d113610f..fbb104459 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -58,6 +58,12 @@ export const optionDeclarations: CommandLineOption[] = [ type: "enum", choices: Object.values(LuaTarget), }, + { + name: "noImplicitGlobalVariables", + description: + 'Specify to prevent implicitly turning "normal" variants into global variables in the transpiled output.', + type: "boolean", + }, { name: "noImplicitSelf", description: 'If "this" is implicitly considered an any type, do not generate a self parameter.', diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index b894dba63..e2a3d2a9e 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -137,6 +137,8 @@ export function createLocalOrExportedOrGlobalDeclaration( let declaration: lua.VariableDeclarationStatement | undefined; let assignment: lua.AssignmentStatement | undefined; + const noImplicitGlobalVariables = context.options.noImplicitGlobalVariables === true; + const isFunctionDeclaration = tsOriginal !== undefined && ts.isFunctionDeclaration(tsOriginal); const identifiers = castArray(lhs); @@ -160,7 +162,7 @@ export function createLocalOrExportedOrGlobalDeclaration( const scope = peekScope(context); const isTopLevelVariable = scope.type === ScopeType.File; - if (context.isModule || !isTopLevelVariable) { + if (context.isModule || !isTopLevelVariable || noImplicitGlobalVariables) { const isLuaFunctionExpression = rhs && !Array.isArray(rhs) && lua.isFunctionExpression(rhs); const isSafeRecursiveFunctionDeclaration = isFunctionDeclaration && isLuaFunctionExpression; if (!isSafeRecursiveFunctionDeclaration && hasMultipleReferences(scope, lhs)) { diff --git a/test/unit/functions/noImplicitGlobalVariables.spec.ts b/test/unit/functions/noImplicitGlobalVariables.spec.ts new file mode 100644 index 000000000..00bd6195a --- /dev/null +++ b/test/unit/functions/noImplicitGlobalVariables.spec.ts @@ -0,0 +1,30 @@ +import * as util from "../../util"; + +test("normal TSTL creates global variables", () => { + const builder = util.testModule` + function foo() {} + const bar = 123; + `.expectToHaveNoDiagnostics(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).not.toContain("local"); +}); + +test("noImplicitGlobalVariables does not create any global variables", () => { + const builder = util.testModule` + function foo() {} + const bar = 123; + ` + .setOptions({ noImplicitGlobalVariables: true }) + .expectToHaveNoDiagnostics(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("local function foo("); + expect(lua).toContain("local bar ="); +}); From 0924b37a73f255c333f5a4fb8567bd1a93f6645e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 29 May 2022 20:26:53 +0200 Subject: [PATCH 476/764] Fix async try (#1278) * Initial prototype * this works * Kinda works but not really * Actually it does work but test was wrong * finalize solution --- src/lualib/Await.ts | 48 ++---- src/transformation/visitors/async-await.ts | 29 ++-- src/transformation/visitors/errors.ts | 96 ++++++++--- src/transformation/visitors/function.ts | 2 +- src/transformation/visitors/return.ts | 9 +- test/unit/builtins/async-await.spec.ts | 187 +++++++++++++++++++++ 6 files changed, 299 insertions(+), 72 deletions(-) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index acb9607e4..7093a617f 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -16,11 +16,10 @@ import { __TS__Promise } from "./Promise"; -type ErrorHandler = (this: void, error: unknown) => unknown; - // eslint-disable-next-line @typescript-eslint/promise-function-async export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { return new Promise((resolve, reject) => { + let resolved = false; const asyncCoroutine = coroutine.create(generator); // eslint-disable-next-line @typescript-eslint/promise-function-async @@ -28,50 +27,33 @@ export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) return value instanceof __TS__Promise ? value : Promise.resolve(value); } function fulfilled(value: unknown) { - const [success, errorOrErrorHandler, resultOrError] = coroutine.resume(asyncCoroutine, value); + const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); if (success) { - step(resultOrError, errorOrErrorHandler); - } else { - reject(errorOrErrorHandler); - } - } - function rejected(handler: ErrorHandler | undefined) { - if (handler) { - return (value: unknown) => { - const [success, hasReturnedOrError, returnedValue] = pcall(handler, value); - if (success) { - if (hasReturnedOrError) { - resolve(returnedValue); - } else { - step(hasReturnedOrError, handler); - } - } else { - reject(hasReturnedOrError); - } - }; + step(resultOrError); } else { - // If no catch clause, just reject - return value => { - reject(value); - }; + reject(resultOrError); } } - function step(result: unknown, errorHandler: ErrorHandler | undefined) { + function step(result: unknown) { + if (resolved) return; if (coroutine.status(asyncCoroutine) === "dead") { resolve(result); } else { - adopt(result).then(fulfilled, rejected(errorHandler)); + adopt(result).then(fulfilled, reject); } } - const [success, errorOrErrorHandler, resultOrError] = coroutine.resume(asyncCoroutine); + const [success, resultOrError] = coroutine.resume(asyncCoroutine, (v: unknown) => { + resolved = true; + adopt(v).then(resolve, reject); + }); if (success) { - step(resultOrError, errorOrErrorHandler); + step(resultOrError); } else { - reject(errorOrErrorHandler); + reject(resultOrError); } }); } -export function __TS__Await(this: void, errorHandler: ErrorHandler, thing: unknown) { - return coroutine.yield(errorHandler, thing); +export function __TS__Await(this: void, thing: unknown) { + return coroutine.yield(thing); } diff --git a/src/transformation/visitors/async-await.ts b/src/transformation/visitors/async-await.ts index 6b43d4c84..8063312c0 100644 --- a/src/transformation/visitors/async-await.ts +++ b/src/transformation/visitors/async-await.ts @@ -3,35 +3,32 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { awaitMustBeInAsyncFunction } from "../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { findFirstNodeAbove } from "../utils/typescript"; +import { isInAsyncFunction } from "../utils/typescript"; export const transformAwaitExpression: FunctionVisitor = (node, context) => { // Check if await is inside an async function, it is not allowed at top level or in non-async functions - const containingFunction = findFirstNodeAbove(node, ts.isFunctionLike); - if ( - containingFunction === undefined || - !containingFunction.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) - ) { + if (!isInAsyncFunction(node)) { context.diagnostics.push(awaitMustBeInAsyncFunction(node)); } const expression = context.transformExpression(node.expression); - const catchIdentifier = lua.createIdentifier("____catch"); - return transformLuaLibFunction(context, LuaLibFeature.Await, node, catchIdentifier, expression); + return transformLuaLibFunction(context, LuaLibFeature.Await, node, expression); }; export function isAsyncFunction(declaration: ts.FunctionLikeDeclaration): boolean { return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; } -export function wrapInAsyncAwaiter(context: TransformationContext, statements: lua.Statement[]): lua.Statement[] { +export function wrapInAsyncAwaiter( + context: TransformationContext, + statements: lua.Statement[], + includeResolveParameter = true +): lua.CallExpression { importLuaLibFeature(context, LuaLibFeature.Await); - return [ - lua.createReturnStatement([ - lua.createCallExpression(lua.createIdentifier("__TS__AsyncAwaiter"), [ - lua.createFunctionExpression(lua.createBlock(statements)), - ]), - ]), - ]; + const parameters = includeResolveParameter ? [lua.createIdentifier("____awaiter_resolve")] : []; + + return lua.createCallExpression(lua.createIdentifier("__TS__AsyncAwaiter"), [ + lua.createFunctionExpression(lua.createBlock(statements), parameters), + ]); } diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 894ba3ad5..783a340e5 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -1,24 +1,22 @@ import * as ts from "typescript"; -import { LuaTarget } from "../.."; +import { LuaLibFeature, LuaTarget } from "../.."; import * as lua from "../../LuaAST"; -import { FunctionVisitor } from "../context"; +import { FunctionVisitor, TransformationContext } from "../context"; import { unsupportedForTarget, unsupportedForTargetButOverrideAvailable } from "../utils/diagnostics"; import { createUnpackCall } from "../utils/lua-ast"; -import { ScopeType } from "../utils/scope"; +import { transformLuaLibFunction } from "../utils/lualib"; +import { Scope, ScopeType } from "../utils/scope"; import { isInAsyncFunction, isInGeneratorFunction } from "../utils/typescript"; +import { wrapInAsyncAwaiter } from "./async-await"; import { transformScopeBlock } from "./block"; import { transformIdentifier } from "./identifier"; import { isInMultiReturnFunction } from "./language-extensions/multi"; import { createReturnStatement } from "./return"; -export const transformTryStatement: FunctionVisitor = (statement, context) => { - const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); +const transformAsyncTry: FunctionVisitor = (statement, context) => { + const [tryBlock] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if ( - context.options.luaTarget === LuaTarget.Lua51 && - isInAsyncFunction(statement) && - !context.options.lua51AllowTryCatchInAsyncAwait - ) { + if (context.options.luaTarget === LuaTarget.Lua51 && !context.options.lua51AllowTryCatchInAsyncAwait) { context.diagnostics.push( unsupportedForTargetButOverrideAvailable( statement, @@ -30,6 +28,57 @@ export const transformTryStatement: FunctionVisitor = (statemen return tryBlock.statements; } + // __TS__AsyncAwaiter() + const awaiter = wrapInAsyncAwaiter(context, tryBlock.statements, false); + const awaiterIdentifier = lua.createIdentifier("____try"); + const awaiterDefinition = lua.createVariableDeclarationStatement(awaiterIdentifier, awaiter); + + // local ____try = __TS__AsyncAwaiter() + const result: lua.Statement[] = [awaiterDefinition]; + + if (statement.finallyBlock) { + const awaiterFinally = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("finally")); + const finallyFunction = lua.createFunctionExpression( + lua.createBlock(context.transformStatements(statement.finallyBlock.statements)) + ); + const finallyCall = lua.createCallExpression( + awaiterFinally, + [awaiterIdentifier, finallyFunction], + statement.finallyBlock + ); + // ____try.finally() + result.push(lua.createExpressionStatement(finallyCall)); + } + + if (statement.catchClause) { + // ____try.catch() + const [catchFunction] = transformCatchClause(context, statement.catchClause); + if (catchFunction.params) { + catchFunction.params.unshift(lua.createAnonymousIdentifier()); + } + + const awaiterCatch = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("catch")); + const catchCall = lua.createCallExpression(awaiterCatch, [awaiterIdentifier, catchFunction]); + + // await ____try.catch() + const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, catchCall); + result.push(lua.createExpressionStatement(promiseAwait, statement)); + } else { + // await ____try + const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, awaiterIdentifier); + result.push(lua.createExpressionStatement(promiseAwait, statement)); + } + + return result; +}; + +export const transformTryStatement: FunctionVisitor = (statement, context) => { + if (isInAsyncFunction(statement)) { + return transformAsyncTry(statement, context); + } + + const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); + if (context.options.luaTarget === LuaTarget.Lua51 && isInGeneratorFunction(statement)) { context.diagnostics.push( unsupportedForTarget(statement, "try/catch inside generator functions", LuaTarget.Lua51) @@ -50,15 +99,7 @@ export const transformTryStatement: FunctionVisitor = (statemen if (statement.catchClause && statement.catchClause.block.statements.length > 0) { // try with catch - const [catchBlock, catchScope] = transformScopeBlock(context, statement.catchClause.block, ScopeType.Catch); - - const catchParameter = statement.catchClause.variableDeclaration - ? transformIdentifier(context, statement.catchClause.variableDeclaration.name as ts.Identifier) - : undefined; - const catchFunction = lua.createFunctionExpression( - catchBlock, - catchParameter ? [lua.cloneIdentifier(catchParameter)] : [] - ); + const [catchFunction, catchScope] = transformCatchClause(context, statement.catchClause); const catchIdentifier = lua.createIdentifier("____catch"); result.push(lua.createVariableDeclarationStatement(catchIdentifier, catchFunction)); @@ -138,3 +179,20 @@ export const transformThrowStatement: FunctionVisitor = (stat statement ); }; + +function transformCatchClause( + context: TransformationContext, + catchClause: ts.CatchClause +): [lua.FunctionExpression, Scope] { + const [catchBlock, catchScope] = transformScopeBlock(context, catchClause.block, ScopeType.Catch); + + const catchParameter = catchClause.variableDeclaration + ? transformIdentifier(context, catchClause.variableDeclaration.name as ts.Identifier) + : undefined; + const catchFunction = lua.createFunctionExpression( + catchBlock, + catchParameter ? [lua.cloneIdentifier(catchParameter)] : [] + ); + + return [catchFunction, catchScope]; +} diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 0b432ae84..0dd67e25f 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -163,7 +163,7 @@ export function transformFunctionBody( scope.node = node; let bodyStatements = transformFunctionBodyContent(context, body); if (node && isAsyncFunction(node)) { - bodyStatements = wrapInAsyncAwaiter(context, bodyStatements); + bodyStatements = [lua.createReturnStatement([wrapInAsyncAwaiter(context, bodyStatements)])]; } const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); popScope(context); diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 1bd1bb0fe..ef2e36e51 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -85,12 +85,15 @@ export function createReturnStatement( ): lua.ReturnStatement { const results = [...values]; + if (isInAsyncFunction(node)) { + return lua.createReturnStatement([ + lua.createCallExpression(lua.createIdentifier("____awaiter_resolve"), [lua.createNilLiteral(), ...values]), + ]); + } + if (isInTryCatch(context)) { // Bubble up explicit return flag and check if we're inside a try/catch block results.unshift(lua.createBooleanLiteral(true)); - } else if (isInAsyncFunction(node)) { - // Add nil error handler in async function and not in try - results.unshift(lua.createNilLiteral()); } return lua.createReturnStatement(results, node); diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 10bf7601f..8b7e0b5cf 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -597,4 +597,191 @@ describe("try/catch in async function", () => { builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } ); + + test("try/finally in async function", () => { + util.testModule` + const foo = async () => { + throw "foo error"; + }; + + let finallyCalled = false; + + const run = async () => { + try { + await foo(); + } finally { + finallyCalled = true; + } + return 10; + }; + + let succeeded: any = false; + let rejected: any = false; + + run() + .then(_ => { succeeded = true }) + .catch(e => { rejected = e }); + + export const result = { finallyCalled, succeeded, rejected }; + `.expectToEqual({ + result: { + finallyCalled: true, + succeeded: false, + rejected: "foo error", + }, + }); + }); + + test("async function adopts pending promise in try", () => { + util.testFunction` + let resolve: (v: string) => void = () => {}; + async function receive(): Promise { + try + { + return new Promise(res => { + resolve = res; + }); + } + catch + { + } + } + + receive().then(v => { + log(v); + }); + + resolve("delayed resolve"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["delayed resolve"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1272 + test("Awaiting a rejected promise should halt function execution (#1272)", () => { + util.testModule` + const foo = async () => { + throw new Error('foo error'); + }; + + let halted = true; + let caught = ""; + + const run = async () => { + try { + await foo(); + halted = false; + } catch (err) { + caught = 'catch err: ' + err; + } + }; + + let succeeded: any = false; + let rejected: any = false; + + run() + .then(_ => { succeeded = true }, + e => { rejected = e }); + + export const result = { halted, caught, succeeded, rejected }; + `.expectToEqual({ + result: { + halted: true, + caught: "catch err: Error: foo error", + succeeded: true, + rejected: false, + }, + }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1272 + test("Awaiting a rejecting promise should halt function execution (#1272)", () => { + util.testModule` + let rej: (error: any) => void = () => {}; + const foo = () => new Promise((_, reject) => { + rej = reject; + }); + + let halted = true; + let caught = ""; + + const run = async () => { + try { + await foo(); + halted = false; + } catch (err) { + caught = 'catch err: ' + err; + } + }; + + let succeeded: any = false; + let rejected: any = false; + + run() + .then(_ => { succeeded = true }, + e => { rejected = e }); + + rej("rejection message"); + + export const result = { halted, caught, succeeded, rejected }; + `.expectToEqual({ + result: { + halted: true, + caught: "catch err: rejection message", + succeeded: true, + rejected: false, + }, + }); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1272 + test("Async try/catch complicated case (#1272)", () => { + util.testModule` + const foo = async () => { + throw new Error('foo error'); + }; + + let halted = true; + let caught = ""; + + const run = async () => { + try { + await foo(); // This throws + } catch (err) { + caught = 'catch err: ' + err; // This catches the async thrown error, function continues + } + try { + throw "throw 2"; // Another throw + } catch (err) { + try { + await foo(); + } catch (err2) { + return \`caught: \${err}, then: \${err2}\`; // Async function should exit here + } + } + halted = false; // This code should not be called + return 10; + }; + + let succeeded: any = false; + let rejected: any = false; + let value: any = undefined; + + run() + .then(v => { succeeded = true; value = v }, + e => { rejected = e }); + + export const result = { halted, caught, succeeded, rejected, value }; + `.expectToEqual({ + result: { + halted: true, + caught: "catch err: Error: foo error", + succeeded: true, + rejected: false, + value: "caught: throw 2, then: Error: foo error", + }, + }); + }); }); From da506ac352b06c4360a87fad64761fa2b3183fea Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Mon, 30 May 2022 14:58:56 -0400 Subject: [PATCH 477/764] Apply JSDoc Comments to Lua code (#1270) * todo * comment feature works * cleanup * fix: prettier * fix for tests * rename function * fix for removeComments config value * adding comment * adding snapshots * fix prettier * feat: jsdoc tag detection * typo * fix: tests --- src/transformation/utils/lua-ast.ts | 99 +++++++++++++++++++ test/unit/__snapshots__/comments.spec.ts.snap | 50 ++++++++++ .../optionalChaining.spec.ts.snap | 8 ++ .../customConstructor.spec.ts.snap | 2 + .../__snapshots__/deprecated.spec.ts.snap | 10 ++ test/unit/annotations/deprecated.spec.ts | 4 +- test/unit/comments.spec.ts | 95 ++++++++++++++++++ 7 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 test/unit/__snapshots__/comments.spec.ts.snap create mode 100644 test/unit/comments.spec.ts diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index e2a3d2a9e..31c101d13 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -204,6 +204,8 @@ export function createLocalOrExportedOrGlobalDeclaration( } } + setJSDocComments(context, tsOriginal, declaration, assignment); + if (declaration && assignment) { return [declaration, assignment]; } else if (declaration) { @@ -215,6 +217,103 @@ export function createLocalOrExportedOrGlobalDeclaration( } } +/** + * Apply JSDoc comments to the newly-created Lua statement, if present. + * https://stackoverflow.com/questions/47429792/is-it-possible-to-get-comments-as-nodes-in-the-ast-using-the-typescript-compiler + */ +function setJSDocComments( + context: TransformationContext, + tsOriginal: ts.Node | undefined, + declaration: lua.VariableDeclarationStatement | undefined, + assignment: lua.AssignmentStatement | undefined +) { + // Respect the vanilla TypeScript option of "removeComments": + // https://www.typescriptlang.org/tsconfig#removeComments + if (context.options.removeComments) { + return; + } + + const docCommentArray = getJSDocCommentFromTSNode(context, tsOriginal); + if (docCommentArray === undefined) { + return; + } + + if (declaration && assignment) { + declaration.leadingComments = docCommentArray; + } else if (declaration) { + declaration.leadingComments = docCommentArray; + } else if (assignment) { + assignment.leadingComments = docCommentArray; + } +} + +function getJSDocCommentFromTSNode( + context: TransformationContext, + tsOriginal: ts.Node | undefined +): string[] | undefined { + if (tsOriginal === undefined) { + return undefined; + } + + // The "name" property is only on a subset of node types; we want to be permissive and get the + // comments from as many nodes as possible. + const node = tsOriginal as any; + if (node.name === undefined) { + return undefined; + } + + const symbol = context.checker.getSymbolAtLocation(node.name); + if (symbol === undefined) { + return undefined; + } + + // The TypeScript compiler separates JSDoc comments into the "documentation comment" and the + // "tags". The former is conventionally at the top of the comment, and the bottom is + // conventionally at the bottom. We need to get both from the TypeScript API and then combine + // them into one block of text. + const docCommentArray = symbol.getDocumentationComment(context.checker); + const docCommentText = ts.displayPartsToString(docCommentArray).trim(); + + const jsDocTagInfoArray = symbol.getJsDocTags(context.checker); + const jsDocTagsTextLines = jsDocTagInfoArray.map(jsDocTagInfo => { + let text = "@" + jsDocTagInfo.name; + if (jsDocTagInfo.text !== undefined) { + const tagDescriptionTextArray = jsDocTagInfo.text + .filter(symbolDisplayPart => symbolDisplayPart.text.trim() !== "") + .map(symbolDisplayPart => symbolDisplayPart.text.trim()); + const tagDescriptionText = tagDescriptionTextArray.join(" "); + text += " " + tagDescriptionText; + } + return text; + }); + const jsDocTagsText = jsDocTagsTextLines.join("\n"); + + const combined = (docCommentText + "\n\n" + jsDocTagsText).trim(); + if (combined === "") { + return undefined; + } + + // By default, TSTL will display comments immediately next to the "--" characters. We can make + // the comments look better if we separate them by a space (similar to what Prettier does in + // JavaScript/TypeScript). + const linesWithoutSpace = combined.split("\n"); + const lines = linesWithoutSpace.map(line => ` ${line}`); + + // We want to JSDoc comments to map on to LDoc comments: + // https://stevedonovan.github.io/ldoc/manual/doc.md.html + // LDoc comments require that the first line starts with three hyphens. + // Thus, need to add a hyphen to the first line. + const firstLine = lines[0]; + if (firstLine.startsWith(" @")) { + lines.unshift("-"); + } else { + lines.shift(); + lines.unshift("-" + firstLine); + } + + return lines; +} + export const createNaN = (tsOriginal?: ts.Node) => lua.createBinaryExpression( lua.createNumericLiteral(0), diff --git a/test/unit/__snapshots__/comments.spec.ts.snap b/test/unit/__snapshots__/comments.spec.ts.snap new file mode 100644 index 000000000..23b89dcb7 --- /dev/null +++ b/test/unit/__snapshots__/comments.spec.ts.snap @@ -0,0 +1,50 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`JSDoc is copied on a function with tags: code 1`] = ` +"--- This is a function comment. +-- It has multiple lines. +-- +-- @param arg1 This is the first argument. +-- @param arg2 This is the second argument. +-- @returns A very powerful string. +function foo(self, arg1, arg2) + return \\"bar\\" +end" +`; + +exports[`JSDoc is copied on a function with tags: diagnostics 1`] = `""`; + +exports[`JSDoc is copied on a variable: code 1`] = ` +"--- This is a variable comment. +foo = 123" +`; + +exports[`JSDoc is copied on a variable: diagnostics 1`] = `""`; + +exports[`Multi-line JSDoc with one block is copied on a function: code 1`] = ` +"--- This is a function comment. +-- It has more than one line. +function foo(self) +end" +`; + +exports[`Multi-line JSDoc with one block is copied on a function: diagnostics 1`] = `""`; + +exports[`Multi-line JSDoc with two blocks is copied on a function: code 1`] = ` +"--- This is a function comment. +-- It has more than one line. +-- +-- It also has more than one block. +function foo(self) +end" +`; + +exports[`Multi-line JSDoc with two blocks is copied on a function: diagnostics 1`] = `""`; + +exports[`Single-line JSDoc is copied on a function: code 1`] = ` +"--- This is a function comment. +function foo(self) +end" +`; + +exports[`Single-line JSDoc is copied on a function: diagnostics 1`] = `""`; diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 3d67bf838..26fbcf046 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -32,9 +32,17 @@ exports[`Unsupported optional chains Builtin prototype method: diagnostics 1`] = exports[`Unsupported optional chains Compile members only: code 1`] = ` "local ____exports = {} function ____exports.__main(self) + --- + -- @compileMembersOnly local A = 0 + --- + -- @compileMembersOnly local B = 2 + --- + -- @compileMembersOnly local C = 3 + --- + -- @compileMembersOnly local D = \\"D\\" local ____TestEnum_B_0 = TestEnum if ____TestEnum_B_0 ~= nil then diff --git a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap index ffd43b2b6..ad79b2eaa 100644 --- a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap @@ -6,6 +6,8 @@ local __TS__Class = ____lualib.__TS__Class local __TS__New = ____lualib.__TS__New local ____exports = {} function ____exports.__main(self) + --- + -- @customConstructor local Point2D = __TS__Class() Point2D.name = \\"Point2D\\" function Point2D.prototype.____constructor(self) diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap index 32c01be9e..87d39ce95 100644 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap @@ -42,6 +42,8 @@ exports[`extension removed: code 1`] = ` "local ____lualib = require(\\"lualib_bundle\\") local __TS__Class = ____lualib.__TS__Class local __TS__ClassExtends = ____lualib.__TS__ClassExtends +--- +-- @extension B = __TS__Class() B.name = \\"B\\" __TS__ClassExtends(B, A)" @@ -51,6 +53,8 @@ exports[`extension removed: code 2`] = ` "local ____lualib = require(\\"lualib_bundle\\") local __TS__Class = ____lualib.__TS__Class local __TS__ClassExtends = ____lualib.__TS__ClassExtends +--- +-- @metaExtension B = __TS__Class() B.name = \\"B\\" __TS__ClassExtends(B, A)" @@ -108,6 +112,8 @@ exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@ exports[`tuplereturn lambda: code 1`] = ` "local ____exports = {} function ____exports.__main(self) + --- + -- @tupleReturn local function f() return {3, 4} end @@ -120,6 +126,8 @@ exports[`tuplereturn lambda: diagnostics 1`] = `"main.ts(2,39): error TSTL: '@tu exports[`tuplereturn removed on function declaration: code 1`] = ` "local ____exports = {} function ____exports.__main(self) + --- + -- @tupleReturn local function tuple(self) return {3, 5, 1} end @@ -132,6 +140,8 @@ exports[`tuplereturn removed on function declaration: diagnostics 1`] = `"main.t exports[`tuplereturn removed: code 1`] = ` "local ____exports = {} function ____exports.__main(self) + --- + -- @tupleReturn local function tuple(self) return {3, 5, 1} end diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts index f7f0ac9b1..091d681f2 100644 --- a/test/unit/annotations/deprecated.spec.ts +++ b/test/unit/annotations/deprecated.spec.ts @@ -4,14 +4,14 @@ import * as util from "../../util"; test.each(["extension", "metaExtension"])("extension removed", extensionType => { util.testModule` declare class A {} - /** @${extensionType} **/ + /** @${extensionType} */ class B extends A {} `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); }); test("phantom removed", () => { util.testModule` - /** @phantom **/ + /** @phantom */ namespace A { function nsMember() {} } diff --git a/test/unit/comments.spec.ts b/test/unit/comments.spec.ts new file mode 100644 index 000000000..58e648ad3 --- /dev/null +++ b/test/unit/comments.spec.ts @@ -0,0 +1,95 @@ +import * as util from "../util"; + +test("Single-line JSDoc is copied on a function", () => { + const builder = util.testModule` + /** This is a function comment. */ + function foo() {} + ` + .expectToHaveNoDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("This is a function comment."); +}); + +test("Multi-line JSDoc with one block is copied on a function", () => { + const builder = util.testModule` + /** + * This is a function comment. + * It has more than one line. + */ + function foo() {} + ` + .expectToHaveNoDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("It has more than one line."); +}); + +test("Multi-line JSDoc with two blocks is copied on a function", () => { + const builder = util.testModule` + /** + * This is a function comment. + * It has more than one line. + * + * It also has more than one block. + */ + function foo() {} + ` + .expectToHaveNoDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("It also has more than one block."); +}); + +test("JSDoc is copied on a function with tags", () => { + const builder = util.testModule` + /** + * This is a function comment. + * It has multiple lines. + * + * @param arg1 This is the first argument. + * @param arg2 This is the second argument. + * @returns A very powerful string. + */ + function foo(arg1: boolean, arg2: number): string { + return "bar"; + } + ` + .expectToHaveNoDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("This is the first argument."); + expect(lua).toContain("This is the second argument."); + expect(lua).toContain("A very powerful string."); +}); + +test("JSDoc is copied on a variable", () => { + const builder = util.testModule` + /** This is a variable comment. */ + const foo = 123; + ` + .expectToHaveNoDiagnostics() + .expectDiagnosticsToMatchSnapshot(); + + const transpiledFile = builder.getLuaResult().transpiledFiles[0]; + expect(transpiledFile).toBeDefined(); + const { lua } = transpiledFile; + expect(lua).toBeDefined(); + expect(lua).toContain("This is a variable comment."); +}); From 71fb85e4440c952d41e20be8227f3ceed290672f Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 31 May 2022 15:03:09 +0200 Subject: [PATCH 478/764] Fix methods with non-null operator not being detected as methods (#1280) * Fix methods with non-null operator not being detected as methods * Fix other occurrences of PropertyAccessCall --- src/transformation/builtins/array.ts | 24 ++++++------- src/transformation/builtins/console.ts | 20 +++++------ src/transformation/builtins/function.ts | 14 ++++---- src/transformation/builtins/index.ts | 46 ++++++++++++------------- src/transformation/builtins/math.ts | 10 +++--- src/transformation/builtins/number.ts | 27 ++++++++------- src/transformation/builtins/object.ts | 36 +++++++++---------- src/transformation/builtins/promise.ts | 14 ++++---- src/transformation/builtins/string.ts | 20 +++++------ src/transformation/builtins/symbol.ts | 17 ++++----- src/transformation/visitors/call.ts | 42 ++++++++++++++-------- test/unit/functions/functions.spec.ts | 8 +++++ 12 files changed, 149 insertions(+), 129 deletions(-) diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 9567c45ae..2ecf3336a 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -3,20 +3,20 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; +import { transformArguments, transformCallAndArguments } from "../visitors/call"; import { isStringType, isNumberType, findFirstNonOuterParent } from "../utils/typescript"; import { moveToPrecedingTemp } from "../visitors/expression-list"; import { isUnpackCall, wrapInTable } from "../utils/lua-ast"; export function transformArrayConstructorCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "from": return transformLuaLibFunction(context, LuaLibFeature.ArrayFrom, node, ...params); @@ -25,7 +25,7 @@ export function transformArrayConstructorCall( case "of": return wrapInTable(...params); default: - context.diagnostics.push(unsupportedProperty(expression.name, "Array", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Array", expressionName)); } } @@ -37,7 +37,7 @@ export function transformArrayConstructorCall( */ function transformSingleElementArrayPush( context: TransformationContext, - node: PropertyCallExpression, + node: ts.CallExpression, caller: lua.Expression, param: lua.Expression ): lua.Expression { @@ -68,13 +68,13 @@ function transformSingleElementArrayPush( export function transformArrayPrototypeCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); - const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); + const [caller, params] = transformCallAndArguments(context, calledMethod.expression, node.arguments, signature); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); @@ -143,7 +143,7 @@ export function transformArrayPrototypeCall( case "splice": return transformLuaLibFunction(context, LuaLibFeature.ArraySplice, node, caller, ...params); case "join": - const callerType = context.checker.getTypeAtLocation(expression.expression); + const callerType = context.checker.getTypeAtLocation(calledMethod.expression); const elementType = context.checker.getElementTypeOfArrayType(callerType); if (elementType && (isStringType(context, elementType) || isNumberType(context, elementType))) { const defaultSeparatorLiteral = lua.createStringLiteral(","); @@ -170,7 +170,7 @@ export function transformArrayPrototypeCall( case "flatMap": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); default: - context.diagnostics.push(unsupportedProperty(expression.name, "array", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "array", expressionName)); } } diff --git a/src/transformation/builtins/console.ts b/src/transformation/builtins/console.ts index af7ceb87e..a32f547da 100644 --- a/src/transformation/builtins/console.ts +++ b/src/transformation/builtins/console.ts @@ -2,25 +2,25 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; const isStringFormatTemplate = (node: ts.Expression) => ts.isStringLiteral(node) && node.text.includes("%"); export function transformConsoleCall( context: TransformationContext, - expression: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const method = expression.expression; - const methodName = method.name.text; - const signature = context.checker.getResolvedSignature(expression); - const parameters = transformArguments(context, expression.arguments, signature); + const methodName = calledMethod.name.text; + const signature = context.checker.getResolvedSignature(node); + const parameters = transformArguments(context, node.arguments, signature); switch (methodName) { case "error": case "info": case "log": case "warn": - if (expression.arguments.length > 0 && isStringFormatTemplate(expression.arguments[0])) { + if (node.arguments.length > 0 && isStringFormatTemplate(node.arguments[0])) { // print(string.format([arguments])) const stringFormatCall = lua.createCallExpression( lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), @@ -31,7 +31,7 @@ export function transformConsoleCall( // print([arguments]) return lua.createCallExpression(lua.createIdentifier("print"), parameters); case "assert": - if (expression.arguments.length > 1 && isStringFormatTemplate(expression.arguments[1])) { + if (node.arguments.length > 1 && isStringFormatTemplate(node.arguments[1])) { // assert([condition], string.format([arguments])) const stringFormatCall = lua.createCallExpression( lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), @@ -42,7 +42,7 @@ export function transformConsoleCall( // assert() return lua.createCallExpression(lua.createIdentifier("assert"), parameters); case "trace": - if (expression.arguments.length > 0 && isStringFormatTemplate(expression.arguments[0])) { + if (node.arguments.length > 0 && isStringFormatTemplate(node.arguments[0])) { // print(debug.traceback(string.format([arguments]))) const stringFormatCall = lua.createCallExpression( lua.createTableIndexExpression(lua.createIdentifier("string"), lua.createStringLiteral("format")), @@ -61,6 +61,6 @@ export function transformConsoleCall( ); return lua.createCallExpression(lua.createIdentifier("print"), [debugTracebackCall]); default: - context.diagnostics.push(unsupportedProperty(method.name, "console", methodName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "console", methodName)); } } diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index 161660461..ebf0a83ca 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -6,21 +6,21 @@ import { unsupportedForTarget, unsupportedProperty, unsupportedSelfFunctionConve import { ContextType, getFunctionContextType } from "../utils/function-context"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformCallAndArguments } from "../visitors/call"; +import { transformCallAndArguments } from "../visitors/call"; export function transformFunctionPrototypeCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.CallExpression | undefined { - const expression = node.expression; - const callerType = context.checker.getTypeAtLocation(expression.expression); + const callerType = context.checker.getTypeAtLocation(calledMethod.expression); if (getFunctionContextType(context, callerType) === ContextType.Void) { context.diagnostics.push(unsupportedSelfFunctionConversion(node)); } const signature = context.checker.getResolvedSignature(node); - const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); - const expressionName = expression.name.text; + const [caller, params] = transformCallAndArguments(context, calledMethod.expression, node.arguments, signature); + const expressionName = calledMethod.name.text; switch (expressionName) { case "apply": const nonContextArgs = params.length > 1 ? [createUnpackCall(context, params[1], node.arguments[1])] : []; @@ -30,7 +30,7 @@ export function transformFunctionPrototypeCall( case "call": return lua.createCallExpression(caller, params, node); case "toString": - context.diagnostics.push(unsupportedProperty(expression.name, "function", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "function", expressionName)); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index c462bbe19..bc3be66e6 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { assume } from "../../utils"; import { TransformationContext } from "../context"; import { createNaN } from "../utils/lua-ast"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; @@ -14,7 +13,7 @@ import { isStandardLibraryType, isStringType, } from "../utils/typescript"; -import { PropertyCallExpression } from "../visitors/call"; +import { getCalledExpression } from "../visitors/call"; import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; @@ -74,79 +73,78 @@ export function transformBuiltinCallExpression( } } - const expression = ts.getOriginalNode(node.expression); - if (!ts.isPropertyAccessExpression(expression)) { + const calledMethod = ts.getOriginalNode(getCalledExpression(node)); + if (!ts.isPropertyAccessExpression(calledMethod)) { return; } - const isOptionalAccess = expression.questionDotToken; - assume(node); + const isOptionalAccess = calledMethod.questionDotToken; // If the function being called is of type owner.func, get the type of owner - const ownerType = context.checker.getTypeAtLocation(expression.expression); + const ownerType = context.checker.getTypeAtLocation(calledMethod.expression); if (isStandardLibraryType(context, ownerType, undefined)) { const symbol = ownerType.getSymbol(); switch (symbol?.name) { case "ArrayConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformArrayConstructorCall(context, node); + return transformArrayConstructorCall(context, node, calledMethod); case "Console": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformConsoleCall(context, node); + return transformConsoleCall(context, node, calledMethod); case "Math": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformMathCall(context, node); + return transformMathCall(context, node, calledMethod); case "StringConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformStringConstructorCall(context, node); + return transformStringConstructorCall(context, node, calledMethod); case "ObjectConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformObjectConstructorCall(context, node); + return transformObjectConstructorCall(context, node, calledMethod); case "SymbolConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformSymbolConstructorCall(context, node); + return transformSymbolConstructorCall(context, node, calledMethod); case "NumberConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformNumberConstructorCall(context, node); + return transformNumberConstructorCall(context, node, calledMethod); case "PromiseConstructor": if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformPromiseConstructorCall(context, node); + return transformPromiseConstructorCall(context, node, calledMethod); } } const isStringFunction = isStringType(context, ownerType) || - (expression.questionDotToken && isNullableType(context, ownerType, isStringType)); + (calledMethod.questionDotToken && isNullableType(context, ownerType, isStringType)); if (isStringFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); - return transformStringPrototypeCall(context, node); + return transformStringPrototypeCall(context, node, calledMethod); } const isNumberFunction = isNumberType(context, ownerType) || - (expression.questionDotToken && isNullableType(context, ownerType, isNumberType)); + (calledMethod.questionDotToken && isNullableType(context, ownerType, isNumberType)); if (isNumberFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); - return transformNumberPrototypeCall(context, node); + return transformNumberPrototypeCall(context, node, calledMethod); } const isArrayFunction = isArrayType(context, ownerType) || - (expression.questionDotToken && isNullableType(context, ownerType, isArrayType)); + (calledMethod.questionDotToken && isNullableType(context, ownerType, isArrayType)); if (isArrayFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); - return transformArrayPrototypeCall(context, node); + return transformArrayPrototypeCall(context, node, calledMethod); } const isFunctionFunction = isFunctionType(ownerType) || - (expression.questionDotToken && isNullableType(context, ownerType, (_, t) => isFunctionType(t))); + (calledMethod.questionDotToken && isNullableType(context, ownerType, (_, t) => isFunctionType(t))); if (isFunctionFunction && hasStandardLibrarySignature(context, node)) { if (isOptionalCall) return unsupportedOptionalCall(); - return transformFunctionPrototypeCall(context, node); + return transformFunctionPrototypeCall(context, node, calledMethod); } - const objectResult = transformObjectPrototypeCall(context, node, expression); + const objectResult = transformObjectPrototypeCall(context, node, calledMethod); if (objectResult) { if (isOptionalCall) return unsupportedOptionalCall(); return objectResult; diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index e215e215d..630f33646 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -4,7 +4,7 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; export function transformMathProperty( context: TransformationContext, @@ -33,14 +33,14 @@ export function transformMathProperty( export function transformMathCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); const math = lua.createIdentifier("math"); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { // Lua 5.3: math.atan(y, x) // Otherwise: math.atan2(y, x) @@ -107,6 +107,6 @@ export function transformMathCall( } default: - context.diagnostics.push(unsupportedProperty(expression.name, "Math", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Math", expressionName)); } } diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index 227d82b23..3376c0db3 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -1,42 +1,43 @@ +import ts = require("typescript"); import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; export function transformNumberPrototypeCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); - const caller = context.transformExpression(expression.expression); + const caller = context.transformExpression(calledMethod.expression); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "toString": return params.length === 0 ? lua.createCallExpression(lua.createIdentifier("tostring"), [caller], node) : transformLuaLibFunction(context, LuaLibFeature.NumberToString, node, caller, ...params); default: - context.diagnostics.push(unsupportedProperty(expression.name, "number", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "number", expressionName)); } } export function transformNumberConstructorCall( context: TransformationContext, - expression: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.CallExpression | undefined { - const method = expression.expression; - const parameters = transformArguments(context, expression.arguments); - const methodName = method.name.text; + const parameters = transformArguments(context, node.arguments); + const methodName = calledMethod.name.text; switch (methodName) { case "isNaN": - return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, node, ...parameters); case "isFinite": - return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, expression, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, node, ...parameters); default: - context.diagnostics.push(unsupportedProperty(method.name, "Number", methodName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Number", methodName)); } } diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index 4b806eb32..c23341b97 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -3,56 +3,56 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; export function transformObjectConstructorCall( context: TransformationContext, - expression: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const method = expression.expression; - const args = transformArguments(context, expression.arguments); - const methodName = method.name.text; + const args = transformArguments(context, node.arguments); + const methodName = calledMethod.name.text; switch (methodName) { case "assign": - return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectAssign, node, ...args); case "defineProperty": - return transformLuaLibFunction(context, LuaLibFeature.ObjectDefineProperty, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectDefineProperty, node, ...args); case "entries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, node, ...args); case "fromEntries": - return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectFromEntries, node, ...args); case "getOwnPropertyDescriptor": - return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, node, ...args); case "getOwnPropertyDescriptors": - return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, node, ...args); case "keys": - return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, node, ...args); case "values": - return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, expression, ...args); + return transformLuaLibFunction(context, LuaLibFeature.ObjectValues, node, ...args); default: - context.diagnostics.push(unsupportedProperty(method.name, "Object", methodName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Object", methodName)); } } export function transformObjectPrototypeCall( context: TransformationContext, node: ts.CallExpression, - expression: ts.PropertyAccessExpression + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { const signature = context.checker.getResolvedSignature(node); - const name = expression.name.text; + const name = calledMethod.name.text; switch (name) { case "toString": const toStringIdentifier = lua.createIdentifier("tostring"); return lua.createCallExpression( toStringIdentifier, - [context.transformExpression(expression.expression)], + [context.transformExpression(calledMethod.expression)], node ); case "hasOwnProperty": - const expr = context.transformExpression(expression.expression); + const expr = context.transformExpression(calledMethod.expression); const parameters = transformArguments(context, node.arguments, signature); const rawGetIdentifier = lua.createIdentifier("rawget"); const rawGetCall = lua.createCallExpression(rawGetIdentifier, [expr, ...parameters]); diff --git a/src/transformation/builtins/promise.ts b/src/transformation/builtins/promise.ts index 11d80d45c..07a291d8b 100644 --- a/src/transformation/builtins/promise.ts +++ b/src/transformation/builtins/promise.ts @@ -4,7 +4,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isStandardLibraryType } from "../utils/typescript"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; export function isPromiseClass(context: TransformationContext, node: ts.Identifier) { const type = context.checker.getTypeAtLocation(node); @@ -17,13 +17,13 @@ export function createPromiseIdentifier(original: ts.Node) { export function transformPromiseConstructorCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "all": return transformLuaLibFunction(context, LuaLibFeature.PromiseAll, node, ...params); @@ -35,12 +35,12 @@ export function transformPromiseConstructorCall( return transformLuaLibFunction(context, LuaLibFeature.PromiseRace, node, ...params); case "resolve": importLuaLibFeature(context, LuaLibFeature.Promise); - return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", expression), params, node); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", calledMethod), params, node); case "reject": importLuaLibFeature(context, LuaLibFeature.Promise); - return lua.createCallExpression(createStaticPromiseFunctionAccessor("reject", expression), params, node); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("reject", calledMethod), params, node); default: - context.diagnostics.push(unsupportedProperty(expression.name, "Promise", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Promise", expressionName)); } } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index d151d8d47..95f35133f 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -4,7 +4,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { addToNumericExpression, createNaN, getNumberLiteralValue, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments, transformCallAndArguments } from "../visitors/call"; +import { transformArguments, transformCallAndArguments } from "../visitors/call"; function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lua.Expression[]): lua.CallExpression { const stringIdentifier = lua.createIdentifier("string"); @@ -17,13 +17,13 @@ function createStringCall(methodName: string, tsOriginal: ts.Node, ...params: lu export function transformStringPrototypeCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); - const [caller, params] = transformCallAndArguments(context, expression.expression, node.arguments, signature); + const [caller, params] = transformCallAndArguments(context, calledMethod.expression, node.arguments, signature); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "replace": return transformLuaLibFunction(context, LuaLibFeature.StringReplace, node, caller, ...params); @@ -146,19 +146,19 @@ export function transformStringPrototypeCall( case "padEnd": return transformLuaLibFunction(context, LuaLibFeature.StringPadEnd, node, caller, ...params); default: - context.diagnostics.push(unsupportedProperty(expression.name, "string", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "string", expressionName)); } } export function transformStringConstructorCall( context: TransformationContext, - node: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const expression = node.expression; const signature = context.checker.getResolvedSignature(node); const params = transformArguments(context, node.arguments, signature); - const expressionName = expression.name.text; + const expressionName = calledMethod.name.text; switch (expressionName) { case "fromCharCode": return lua.createCallExpression( @@ -168,7 +168,7 @@ export function transformStringConstructorCall( ); default: - context.diagnostics.push(unsupportedProperty(expression.name, "String", expressionName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "String", expressionName)); } } diff --git a/src/transformation/builtins/symbol.ts b/src/transformation/builtins/symbol.ts index 04329e059..4c5b7cbde 100644 --- a/src/transformation/builtins/symbol.ts +++ b/src/transformation/builtins/symbol.ts @@ -1,25 +1,26 @@ +import ts = require("typescript"); import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; -import { PropertyCallExpression, transformArguments } from "../visitors/call"; +import { transformArguments } from "../visitors/call"; export function transformSymbolConstructorCall( context: TransformationContext, - expression: PropertyCallExpression + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression ): lua.CallExpression | undefined { - const method = expression.expression; - const signature = context.checker.getResolvedSignature(expression); - const parameters = transformArguments(context, expression.arguments, signature); - const methodName = method.name.text; + const signature = context.checker.getResolvedSignature(node); + const parameters = transformArguments(context, node.arguments, signature); + const methodName = calledMethod.name.text; switch (methodName) { case "for": case "keyFor": importLuaLibFeature(context, LuaLibFeature.SymbolRegistry); const upperMethodName = methodName[0].toUpperCase() + methodName.slice(1); const functionIdentifier = lua.createIdentifier(`__TS__SymbolRegistry${upperMethodName}`); - return lua.createCallExpression(functionIdentifier, parameters, expression); + return lua.createCallExpression(functionIdentifier, parameters, node); default: - context.diagnostics.push(unsupportedProperty(method.name, "Symbol", methodName)); + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Symbol", methodName)); } } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 58eb29eab..eb1c1a549 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -17,8 +17,6 @@ import { getOptionalContinuationData, transformOptionalChain } from "./optional- import { transformLanguageExtensionCallExpression } from "./language-extensions"; import { transformImportExpression } from "./modules/import"; -export type PropertyCallExpression = ts.CallExpression & { expression: ts.PropertyAccessExpression }; - export function validateArguments( context: TransformationContext, params: readonly ts.Expression[], @@ -126,7 +124,7 @@ export function transformContextualCallExpression( if (ts.isOptionalChain(node)) { return transformOptionalChain(context, node); } - const left = ts.isCallExpression(node) ? node.expression : node.tag; + const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag; let [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => transformArguments(context, args, signature) @@ -176,10 +174,14 @@ export function transformContextualCallExpression( } } -function transformPropertyCall(context: TransformationContext, node: PropertyCallExpression): lua.Expression { +function transformPropertyCall( + context: TransformationContext, + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression +): lua.Expression { const signature = context.checker.getResolvedSignature(node); - if (node.expression.expression.kind === ts.SyntaxKind.SuperKeyword) { + if (calledMethod.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression(context.transformExpression(node.expression), parameters); @@ -211,7 +213,9 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre } export const transformCallExpression: FunctionVisitor = (node, context) => { - if (node.expression.kind === ts.SyntaxKind.ImportKeyword) { + const calledExpression = getCalledExpression(node); + + if (calledExpression.kind === ts.SyntaxKind.ImportKeyword) { return transformImportExpression(node, context); } @@ -219,8 +223,8 @@ export const transformCallExpression: FunctionVisitor = (node return transformOptionalChain(context, node); } - const optionalContinuation = ts.isIdentifier(node.expression) - ? getOptionalContinuationData(node.expression) + const optionalContinuation = ts.isIdentifier(calledExpression) + ? getOptionalContinuationData(calledExpression) : undefined; const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); @@ -236,18 +240,18 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResultInTable ? wrapInTable(builtinOrExtensionResult) : builtinOrExtensionResult; } - if (ts.isPropertyAccessExpression(node.expression)) { - const ownerType = context.checker.getTypeAtLocation(node.expression.expression); + if (ts.isPropertyAccessExpression(calledExpression)) { + const ownerType = context.checker.getTypeAtLocation(calledExpression.expression); const annotations = getTypeAnnotations(ownerType); if (annotations.has(AnnotationKind.LuaTable)) { context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); } - const result = transformPropertyCall(context, node as PropertyCallExpression); + const result = transformPropertyCall(context, node, calledExpression); return wrapResultInTable ? wrapInTable(result) : result; } - if (ts.isElementAccessExpression(node.expression)) { + if (ts.isElementAccessExpression(calledExpression)) { const result = transformElementCall(context, node); return wrapResultInTable ? wrapInTable(result) : result; } @@ -255,7 +259,7 @@ export const transformCallExpression: FunctionVisitor = (node const signature = context.checker.getResolvedSignature(node); // Handle super calls properly - if (node.expression.kind === ts.SyntaxKind.SuperKeyword) { + if (calledExpression.kind === ts.SyntaxKind.SuperKeyword) { const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); return lua.createCallExpression( @@ -274,14 +278,14 @@ export const transformCallExpression: FunctionVisitor = (node const isContextualCall = !signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; if (!isContextualCall) { - [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); + [callPath, parameters] = transformCallAndArguments(context, calledExpression, node.arguments, signature); } else { // if is optionalContinuation, context will be handled by transformOptionalChain. const useGlobalContext = !context.isStrict && optionalContinuation === undefined; const callContext = useGlobalContext ? ts.factory.createIdentifier("_G") : ts.factory.createNull(); [callPath, parameters] = transformCallAndArguments( context, - node.expression, + calledExpression, node.arguments, signature, callContext @@ -294,3 +298,11 @@ export const transformCallExpression: FunctionVisitor = (node } return wrapResultInTable ? wrapInTable(callExpression) : callExpression; }; + +export function getCalledExpression(node: ts.CallExpression): ts.Expression { + function unwrapExpression(expression: ts.Expression): ts.Expression { + expression = ts.skipOuterExpressions(expression); + return ts.isNonNullExpression(expression) ? unwrapExpression(expression.expression) : expression; + } + return unwrapExpression(node.expression); +} diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index c5a488460..6c8819f70 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -268,6 +268,14 @@ test("Object method declaration", () => { `.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1266 +test("Object method declaration used with non-null operator (#1266)", () => { + util.testFunction` + let o = { v: 4, m(i: number): number { return this.v * i; } }; + return o.m!(3); + `.expectToMatchJsResult(); +}); + test.each([ { args: ["bar"], expected: "foobar" }, { args: ["baz", "bar"], expected: "bazbar" }, From c7cf302ec7273441634d92104d9b61b309534297 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 1 Jun 2022 20:52:02 +0200 Subject: [PATCH 479/764] CHANGELOG.md 1.5.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8929e86d5..e92a7c2ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 1.5.0 + +- Added support for `Array.from` and `Array.of` +- Added support for `beforeEmit` hook to plugins that runs after tstl is totally done, but before emitting the result. + - For more info about plugin hooks, see: https://typescripttolua.github.io/docs/api/plugins +- Added support for import expressions (`import("./module").then(m => m.foo());`) +- Added tsconfig setting `lua51AllowTryCatchInAsyncAwait` to disable restrictions on try/catch in combination with async/await in 5.1 (default: false) +- Added tsconfig setting `noImplicitGlobalVariables` to disable tstl making variables global in non-module files. +- Various lualib optimizations +- JSDoc comments from input TS are now also part of output Lua as LDoc comments. + - Can be disabled with `removeComments` tsconfig setting. +- Rewrote how try/catch works in async functions, fixing many bugs. +- Fixed a bug where methods with non-null expressions (i.e. `obj.method!()`) would not pass the correct self parameter, causing runtime errors. +- Fixed a bug where symlinked node_modules (for example when using `npm link`) were not recognized as external dependencies by module resolution. +- Fixed a bug with sourcemap traceback leading to invalid lua +- Improved sourcemap traceback interaction with `loadstring` + ## 1.4.0 - Upgraded to TypeScript 4.6 From 0f32b4b485ac465cf9334dc675ad491974e6aab2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 1 Jun 2022 21:00:50 +0200 Subject: [PATCH 480/764] 1.5.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 486db8945..0413c7035 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.4.4", + "version": "1.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.4.4", + "version": "1.5.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 3c9e19d90..8ef801418 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.4.4", + "version": "1.5.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From b737d0c3db0025939398a70cf35b98df6cfe4c5d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 11 Jun 2022 20:06:35 +0200 Subject: [PATCH 481/764] Upgrade typescript to 4.7 (#1281) * Upgrade typescript to 4.7 * Also update eslint --- .eslintrc.js | 6 + package-lock.json | 849 ++++++++++---------------- package.json | 16 +- src/transformation/context/context.ts | 4 +- src/typescript-internal.d.ts | 2 - 5 files changed, 325 insertions(+), 552 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 370240c0b..5b8fe5f4a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -204,6 +204,12 @@ module.exports = { match: false, }, }, + { + /* Ignore properties that require quotes */ + selector: "objectLiteralProperty", + modifiers: ["requiresQuotes"], + format: null, + }, ], }, }, diff --git a/package-lock.json b/package-lock.json index 0413c7035..504ee8ced 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,14 +19,14 @@ "devDependencies": { "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", - "@types/jest": "^27.4.1", + "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", + "@typescript-eslint/eslint-plugin": "^5.27.0", + "@typescript-eslint/parser": "^5.27.0", + "eslint": "^8.17.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jest": "^26.4.6", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^27.3.0", @@ -36,13 +36,13 @@ "prettier": "^2.3.2", "ts-jest": "^27.1.3", "ts-node": "^10.3.0", - "typescript": "~4.6.2" + "typescript": "~4.7.3" }, "engines": { "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.6.2" + "typescript": "~4.7.3" } }, "node_modules/@babel/compat-data": { @@ -704,19 +704,19 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", - "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { @@ -729,15 +729,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/@eslint/eslintrc/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1321,9 +1312,9 @@ } }, "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, "dependencies": { "jest-matcher-utils": "^27.0.0", @@ -1339,7 +1330,7 @@ "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "node_modules/@types/minimatch": { @@ -1391,19 +1382,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz", - "integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", + "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/type-utils": "5.13.0", - "@typescript-eslint/utils": "5.13.0", - "debug": "^4.3.2", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/type-utils": "5.27.0", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -1423,72 +1414,16 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, "node_modules/@typescript-eslint/parser": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz", - "integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", + "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/typescript-estree": "5.13.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", + "debug": "^4.3.4" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1506,28 +1441,15 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", + "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1536,18 +1458,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", - "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", + "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" }, "engines": { @@ -1557,21 +1475,20 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "*" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", + "node_modules/@typescript-eslint/types": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", + "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" - }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -1580,23 +1497,18 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz", - "integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", + "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.13.0", - "debug": "^4.3.2", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "engines": { @@ -1606,9 +1518,6 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "*" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1616,15 +1525,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.13.0.tgz", - "integrity": "sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", + "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/typescript-estree": "5.13.0", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -1639,71 +1548,14 @@ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", - "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", + "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.27.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1713,7 +1565,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", @@ -2336,9 +2188,9 @@ } }, "node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2664,12 +2516,12 @@ } }, "node_modules/eslint": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", - "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.2.0", + "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -2680,14 +2532,14 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -2696,7 +2548,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -2757,9 +2609,9 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "dependencies": { "array-includes": "^3.1.4", @@ -2767,14 +2619,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { "node": ">=4" @@ -2811,15 +2663,15 @@ "dev": true }, "node_modules/eslint-plugin-jest": { - "version": "26.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz", - "integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==", + "version": "26.4.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", + "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { "@typescript-eslint/eslint-plugin": "^5.0.0", @@ -2923,15 +2775,6 @@ "node": ">=10.13.0" } }, - "node_modules/eslint/node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, "node_modules/eslint/node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -2945,13 +2788,13 @@ } }, "node_modules/espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2959,9 +2802,9 @@ } }, "node_modules/espree/node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -3129,9 +2972,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3141,7 +2984,7 @@ "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, "node_modules/fast-json-stable-stringify": { @@ -3390,9 +3233,9 @@ } }, "node_modules/globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3405,16 +3248,16 @@ } }, "node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" }, "engines": { @@ -3552,9 +3395,9 @@ } }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, "engines": { "node": ">= 4" @@ -3766,9 +3609,9 @@ } }, "node_modules/is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dependencies": { "has": "^1.0.3" }, @@ -5072,9 +4915,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { "brace-expansion": "^1.1.7" @@ -5488,12 +5331,16 @@ } }, "node_modules/resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5611,9 +5458,9 @@ } }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5855,6 +5702,17 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -6071,14 +5929,14 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz", - "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" } }, @@ -6167,9 +6025,9 @@ } }, "node_modules/typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6994,19 +6852,19 @@ } }, "@eslint/eslintrc": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz", - "integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { @@ -7016,12 +6874,6 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -7509,9 +7361,9 @@ } }, "@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, "requires": { "jest-matcher-utils": "^27.0.0", @@ -7527,7 +7379,7 @@ "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/minimatch": { @@ -7579,183 +7431,100 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.13.0.tgz", - "integrity": "sha512-vLktb2Uec81fxm/cfz2Hd6QaWOs8qdmVAZXLdOBX6JFJDhf6oDZpMzZ4/LZ6SFM/5DgDcxIMIvy3F+O9yZBuiQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", + "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/type-utils": "5.13.0", - "@typescript-eslint/utils": "5.13.0", - "debug": "^4.3.2", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/type-utils": "5.27.0", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - } - }, - "@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true - }, - "@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } } }, "@typescript-eslint/parser": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.13.0.tgz", - "integrity": "sha512-GdrU4GvBE29tm2RqWOM0P5QfCtgCyN4hXICj/X9ibKED16136l9ZpoJvCL5pSKtmJzA+NRDzQ312wWMejCVVfg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", + "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/typescript-estree": "5.13.0", - "debug": "^4.3.2" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - } - }, - "@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", - "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", + "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0" } }, "@typescript-eslint/type-utils": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.13.0.tgz", - "integrity": "sha512-/nz7qFizaBM1SuqAKb7GLkcNn2buRdDgZraXlkhz+vUGiN1NZ9LzkA595tHHeduAiS2MsHqMNhE2zNzGdw43Yg==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", + "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.13.0", - "debug": "^4.3.2", + "@typescript-eslint/utils": "5.27.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", + "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", + "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/visitor-keys": "5.27.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/utils": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.13.0.tgz", - "integrity": "sha512-+9oHlPWYNl6AwwoEt5TQryEHwiKRVjz7Vk6kaBeD3/kwHE5YqTGHtm/JZY8Bo9ITOeKutFaXnBlMgSATMJALUQ==", + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", + "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.13.0", - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/typescript-estree": "5.13.0", + "@typescript-eslint/scope-manager": "5.27.0", + "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/typescript-estree": "5.27.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.27.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", + "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.27.0", + "eslint-visitor-keys": "^3.3.0" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.13.0.tgz", - "integrity": "sha512-T4N8UvKYDSfVYdmJq7g2IPJYCRzwtp74KyDZytkR4OL3NRupvswvmJQJ4CX5tDSurW2cvCc1Ia1qM7d0jpa7IA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0" - } - }, - "@typescript-eslint/types": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.13.0.tgz", - "integrity": "sha512-LmE/KO6DUy0nFY/OoQU0XelnmDt+V8lPQhh8MOVa7Y5k2gGRd6U9Kp3wAjhB4OHg57tUO0nOnwYQhRRyEAyOyg==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.13.0.tgz", - "integrity": "sha512-Q9cQow0DeLjnp5DuEDjLZ6JIkwGx3oYZe+BfcNuw/POhtpcxMTy18Icl6BJqTSd+3ftsrfuVb7mNHRZf7xiaNA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "@typescript-eslint/visitor-keys": "5.13.0", - "debug": "^4.3.2", - "globby": "^11.0.4", - "is-glob": "^4.0.3", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.13.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.13.0.tgz", - "integrity": "sha512-HLKEAS/qA1V7d9EzcpLFykTePmOQqOFim8oCvhY3pZgQ8Hi38hYpHd9e5GN6nQBFQNecNhws5wkS9Y5XIO0s/g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.13.0", - "eslint-visitor-keys": "^3.0.0" - } - }, "eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", @@ -8243,9 +8012,9 @@ } }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -8483,12 +8252,12 @@ } }, "eslint": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz", - "integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", + "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.2.0", + "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -8499,14 +8268,14 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -8515,7 +8284,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -8562,12 +8331,6 @@ "is-glob": "^4.0.3" } }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, "js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -8622,9 +8385,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -8632,14 +8395,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { @@ -8669,9 +8432,9 @@ } }, "eslint-plugin-jest": { - "version": "26.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.1.tgz", - "integrity": "sha512-HRKOuPi5ADhza4ZBK5ufyNXy28bXXkib87w+pQqdvBhSTsamndh6sIAKPAUl8y0/n9jSWBdTPslrwtKWqkp8dA==", + "version": "26.4.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", + "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -8703,20 +8466,20 @@ "dev": true }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" }, "dependencies": { "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true }, "eslint-visitor-keys": { @@ -8837,9 +8600,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", - "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -9037,25 +8800,25 @@ } }, "globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, "globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", "slash": "^3.0.0" } }, @@ -9151,9 +8914,9 @@ } }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true }, "import-fresh": { @@ -9304,9 +9067,9 @@ } }, "is-core-module": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz", - "integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "requires": { "has": "^1.0.3" } @@ -10311,9 +10074,9 @@ "dev": true }, "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -10610,12 +10373,13 @@ "dev": true }, "resolve": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", - "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" } }, "resolve-cwd": { @@ -10693,9 +10457,9 @@ } }, "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10878,6 +10642,11 @@ "supports-color": "^7.0.0" } }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" + }, "symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", @@ -11014,14 +10783,14 @@ } }, "tsconfig-paths": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.13.0.tgz", - "integrity": "sha512-nWuffZppoaYK0vQ1SQmkSsQzJoHA4s6uzdb2waRpD806x9yfq153AdVsWz4je2qZcW+pENrMQXbGQ3sMCkXuhw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dev": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { @@ -11088,9 +10857,9 @@ } }, "typescript": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.2.tgz", - "integrity": "sha512-HM/hFigTBHZhLXshn9sN37H085+hQGeJHJ/X7LpBWLID/fbc2acUMfU+lGD98X81sKP+pFa9f0DZmCwB9GnbAg==", + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", "dev": true }, "typescript-to-lua": { diff --git a/package.json b/package.json index 8ef801418..084019243 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "node": ">=12.13.0" }, "peerDependencies": { - "typescript": "~4.6.2" + "typescript": "~4.7.3" }, "dependencies": { "enhanced-resolve": "^5.8.2", @@ -53,14 +53,14 @@ "devDependencies": { "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", - "@types/jest": "^27.4.1", + "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", + "@typescript-eslint/eslint-plugin": "^5.27.0", + "@typescript-eslint/parser": "^5.27.0", + "eslint": "^8.17.0", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jest": "^26.4.6", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^27.3.0", @@ -70,6 +70,6 @@ "prettier": "^2.3.2", "ts-jest": "^27.1.3", "ts-node": "^10.3.0", - "typescript": "~4.6.2" + "typescript": "~4.7.3" } } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 30f274c03..9a5af84c9 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -24,13 +24,13 @@ export interface EmitResolver { getAllAccessorDeclarations(declaration: ts.AccessorDeclaration): AllAccessorDeclarations; } -export interface DiagnosticsProducingTypeChecker extends ts.TypeChecker { +export interface TypeCheckerWithEmitResolver extends ts.TypeChecker { getEmitResolver(sourceFile?: ts.SourceFile, cancellationToken?: ts.CancellationToken): EmitResolver; } export class TransformationContext { public readonly diagnostics: ts.Diagnostic[] = []; - public readonly checker: DiagnosticsProducingTypeChecker = this.program.getDiagnosticsProducingTypeChecker(); + public readonly checker = this.program.getTypeChecker() as TypeCheckerWithEmitResolver; public readonly resolver: EmitResolver; public readonly precedingStatementsStack: lua.Statement[][] = []; diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 1a73ebb82..c1e644fff 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -1,4 +1,3 @@ -import { DiagnosticsProducingTypeChecker } from "./transformation/context"; export {}; declare module "typescript" { @@ -15,7 +14,6 @@ declare module "typescript" { interface Program { getCommonSourceDirectory(): string; - getDiagnosticsProducingTypeChecker(): DiagnosticsProducingTypeChecker; } interface CompilerOptions { From 1e81749fee23230916173a89eb0cf856310e82d6 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 11 Jun 2022 20:07:21 +0200 Subject: [PATCH 482/764] Include plugins from emitOptions in plugins list (#1288) --- src/transpilation/transpiler.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index f16b6614e..6314fdded 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -29,10 +29,11 @@ export class Transpiler { } public emit(emitOptions: EmitOptions): EmitResult { - const { program, writeFile = this.emitHost.writeFile } = emitOptions; + const { program, writeFile = this.emitHost.writeFile, plugins: optionsPlugins = [] } = emitOptions; const options = program.getCompilerOptions() as CompilerOptions; - const { diagnostics: getPluginsDiagnostics, plugins } = getPlugins(program); + const { diagnostics: getPluginsDiagnostics, plugins: configPlugins } = getPlugins(program); + const plugins = [...optionsPlugins, ...configPlugins]; const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(this.emitHost, writeFile, { ...emitOptions, From c47d3b3525cf9a662234dab8b95b36a0ccf30543 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Jun 2022 12:00:28 +0200 Subject: [PATCH 483/764] Fixed a bug where sometimes call expressions would get an incorrect context parameter (#1282) --- src/transformation/visitors/call.ts | 3 ++- test/unit/jsx.spec.ts | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index eb1c1a549..62554bd5b 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -288,7 +288,8 @@ export const transformCallExpression: FunctionVisitor = (node calledExpression, node.arguments, signature, - callContext + // Only pass context if noImplicitSelf is not configured + context.options.noImplicitSelf ? undefined : callContext ); } diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts index 37cdc14c5..03b00e95d 100644 --- a/test/unit/jsx.spec.ts +++ b/test/unit/jsx.spec.ts @@ -288,6 +288,18 @@ describe("jsx", () => { .addExtraFile("myJsx.ts", customJsxLib) .expectToMatchJsResult(); }); + test("custom JSX factory with noImplicitSelf", () => { + testJsx` + return c + ` + .setTsHeader( + `function createElement(tag: string | Function, props: { [key: string]: string | boolean }, ...children: any[]) { + return { tag, children }; + }` + ) + .setOptions({ jsxFactory: "createElement", noImplicitSelf: true }) + .expectToMatchJsResult(); + }); test("custom fragment factory", () => { testJsx` return <>c From 60f11ddb4ba6eaa7c86fb3db0bcd603a02b56962 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Jun 2022 14:59:48 +0200 Subject: [PATCH 484/764] Resolve the correct lualib_bundles for node_modules dependencies (#1283) * Resolve the correct lualib_bundles for node_modules dependencies * Unfocus test --- src/transpilation/resolve.ts | 4 ++-- test/transpile/module-resolution.spec.ts | 15 +++++++++++++-- .../dependency1-ts/index.ts | 5 +++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index d786c79cf..56b0354bd 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -138,8 +138,8 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext const diagnostics: ts.Diagnostic[] = []; for (const required of findRequiredPaths(file.code)) { - // Do no resolve lualib - if (required === "lualib_bundle") { + // Do no resolve lualib, unless it is included from node_modules + if (required === "lualib_bundle" && !isNodeModulesFile(file.fileName)) { dependencies.push({ fileName: "lualib_bundle", code: "" }); continue; } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 83836f6b7..dec970cf0 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -247,10 +247,21 @@ describe("module resolution project with dependencies built by tstl library mode }; test("can resolve lua dependencies", () => { - util.testProject(path.join(projectPath, "tsconfig.json")) + const transpileResult = util + .testProject(path.join(projectPath, "tsconfig.json")) .setMainFileName(path.join(projectPath, "main.ts")) .setOptions({ outDir: "tstl-out" }) - .expectToEqual(expectedResult); + .expectToEqual(expectedResult) + .getLuaResult(); + + // Assert lualib_bundle from node_module is include + const expectedLualibBundle = path.join("lua_modules", "dependency1", "lualib_bundle.lua"); + expect(transpileResult.transpiledFiles.some(f => f.outPath.endsWith(expectedLualibBundle))).toBe(true); + // Assert node_modules file requires the correct lualib_bundle + const requiringLuaFile = path.join("lua_modules", "dependency1", "index.lua"); + const lualibRequiringFile = transpileResult.transpiledFiles.find(f => f.outPath.endsWith(requiringLuaFile)); + expect(lualibRequiringFile).toBeDefined(); + expect(lualibRequiringFile?.lua).toContain('require("lua_modules.dependency1.lualib_bundle")'); }); test("can resolve dependencies and bundle", () => { diff --git a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts index fc1cdddec..03cff47c5 100644 --- a/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts +++ b/test/transpile/module-resolution/project-with-tstl-library-modules/dependency1-ts/index.ts @@ -3,3 +3,8 @@ import { dependency1OtherFileFunc } from "./d1otherfile"; export function dependency1IndexFunc() { return "function in dependency 1 index: " + dependency1OtherFileFunc(); } + +export function squares(nums: number[]) { + // Require lualib functionality + return nums.map(n => n * n); +} From b697e8e86a47adcea0e5c1e8daaadcc73f9967e8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Jun 2022 15:04:01 +0200 Subject: [PATCH 485/764] Fix compound assignment not assigning in expressions (#1287) --- .../visitors/binary-expression/compound.ts | 47 ++++++------------- test/unit/assignments.spec.ts | 15 +++++- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 76947ede9..44c492505 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -76,7 +76,7 @@ export function transformCompoundAssignment( context.transformExpression(rhs) ); - if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { + if (lua.isTableIndexExpression(left)) { // Complex property/element accesses need to cache object/index expressions to avoid repeating side-effects // local __obj, __index = ${objExpression}, ${indexExpression}; const obj = context.createTempNameForLuaExpression(left.table); @@ -105,6 +105,20 @@ export function transformCompoundAssignment( result: tmp, }; } else { + if (isSetterSkippingCompoundAssignmentOperator(operator)) { + return { + statements: [ + objAndIndexDeclaration, + ...transformSetterSkippingCompoundAssignment( + accessExpression, + operator, + right, + rightPrecedingStatements + ), + ], + result: left, + }; + } // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; // return ____tmp @@ -145,37 +159,6 @@ export function transformCompoundAssignment( rightPrecedingStatements ); return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier }; - } else if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { - // Simple property/element access expressions need to cache in temp to avoid double-evaluation - // local ____tmp = ${left} ${replacementOperator} ${right}; - // ${left} = ____tmp; - // return ____tmp - const tmpIdentifier = context.createTempNameForLuaExpression(left); - const [precedingStatements, operatorExpression] = transformBinaryOperation( - context, - left, - right, - rightPrecedingStatements, - operator, - expression - ); - const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, operatorExpression); - - if (isSetterSkippingCompoundAssignmentOperator(operator)) { - const statements = [ - tmpDeclaration, - ...transformSetterSkippingCompoundAssignment(tmpIdentifier, operator, right, precedingStatements), - ]; - return { statements, result: tmpIdentifier }; - } - - const assignStatements = transformAssignmentWithRightPrecedingStatements( - context, - lhs, - tmpIdentifier, - precedingStatements - ); - return { statements: [tmpDeclaration, ...assignStatements], result: tmpIdentifier }; } else { if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) { return { diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 71a7503e2..398f0513b 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -135,6 +135,17 @@ test.each([ `.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1277 +test("Compound assignment as expression (#1277)", () => { + util.testFunction` + let foo = { + bar: false as any + } + const result = foo.bar ||= true; + return { result, foo }; + `.expectToMatchJsResult(); +}); + test.each([ "++o.p", "o.p++", @@ -417,7 +428,7 @@ test.each([ * x.y ||= z is translated to x.y || (x.y = z). * x.y &&= z is translated to x.y && (x.y = z). * x.y ||= z is translated to x.y !== undefined && (x.y = z). - + Test if setter in Lua is called same nr of times as in JS. */ util.testModule` @@ -449,7 +460,7 @@ test.each([ * x.y ||= z is translated to x.y || (x.y = z). * x.y &&= z is translated to x.y && (x.y = z). * x.y ||= z is translated to x.y !== undefined && (x.y = z). - + Test if setter in Lua is called same nr of times as in JS. */ util.testModule` From 7a4388b0afddf38d6ac0925b6a6ee7cf224b16f9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Jun 2022 18:16:13 +0200 Subject: [PATCH 486/764] Fix noImplicitSelf failing due to file paths (#1289) * Fix noImplicitSelf not working depending on path separator * Fix test path --- src/transformation/utils/function-context.ts | 2 +- src/transpilation/index.ts | 13 +++++++--- .../functions/noImplicitSelfOption.spec.ts | 25 +++++++++++++++++++ test/util.ts | 11 +++----- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index b3e9ee2c5..3a74bce80 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -79,7 +79,7 @@ export function getDeclarationContextType( // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const options = program.getCompilerOptions() as CompilerOptions; - if (options.noImplicitSelf && program.getRootFileNames().includes(signatureDeclaration.getSourceFile().fileName)) { + if (options.noImplicitSelf && program.getSourceFile(signatureDeclaration.getSourceFile().fileName) !== undefined) { return ContextType.Void; } diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index 59e83233a..bce4e52c4 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -3,6 +3,7 @@ import * as path from "path"; import * as ts from "typescript"; import { parseConfigFileWithSystem } from "../cli/tsconfig"; import { CompilerOptions } from "../CompilerOptions"; +import { normalizeSlashes } from "../utils"; import { createEmitOutputCollector, TranspiledFile } from "./output-collector"; import { EmitResult, Transpiler } from "./transpiler"; @@ -44,8 +45,12 @@ const libCache: { [key: string]: ts.SourceFile } = {}; /** @internal */ export function createVirtualProgram(input: Record, options: CompilerOptions = {}): ts.Program { + const normalizedFiles: Record = {}; + for (const [path, file] of Object.entries(input)) { + normalizedFiles[normalizeSlashes(path)] = file; + } const compilerHost: ts.CompilerHost = { - fileExists: fileName => fileName in input || ts.sys.fileExists(fileName), + fileExists: fileName => fileName in normalizedFiles || ts.sys.fileExists(fileName), getCanonicalFileName: fileName => fileName, getCurrentDirectory: () => "", getDefaultLibFileName: ts.getDefaultLibFileName, @@ -55,8 +60,8 @@ export function createVirtualProgram(input: Record, options: Com writeFile() {}, getSourceFile(fileName) { - if (fileName in input) { - return ts.createSourceFile(fileName, input[fileName], ts.ScriptTarget.Latest, false); + if (fileName in normalizedFiles) { + return ts.createSourceFile(fileName, normalizedFiles[fileName], ts.ScriptTarget.Latest, false); } let filePath: string | undefined; @@ -80,7 +85,7 @@ export function createVirtualProgram(input: Record, options: Com }, }; - return ts.createProgram(Object.keys(input), options, compilerHost); + return ts.createProgram(Object.keys(normalizedFiles), options, compilerHost); } export interface TranspileVirtualProjectResult { diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index 2da1d9722..b68a1ebc9 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -1,3 +1,5 @@ +import * as path from "path"; +import { transpileFiles } from "../../../src"; import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; @@ -5,11 +7,34 @@ test("enables noSelfInFile behavior for functions", () => { util.testFunction` function fooBar() {} const test: (this: void) => void = fooBar; + fooBar(); ` .setOptions({ noImplicitSelf: true }) .expectToHaveNoDiagnostics(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1084 +test.each(["\\", "/"])("transpileFiles handles paths with noImplicitSelf and %s separator (#1084)", separator => { + const projectDir = `${path.dirname(path.dirname(__dirname))}${separator}transpile${separator}project`; + const emittedFiles: Record = {}; + const { diagnostics } = transpileFiles( + [ + `${projectDir}${separator}index.ts`, + `${projectDir}${separator}api.d.ts`, + `${projectDir}${separator}otherFile.ts`, + ], + { noImplicitSelf: true }, + (fileName, text) => (emittedFiles[fileName] = text) + ); + expect(diagnostics).toHaveLength(0); + expect(Object.keys(emittedFiles)).not.toHaveLength(0); + for (const fileContent of Object.values(emittedFiles)) { + expect(fileContent).toContain("getNumber()"); + expect(fileContent).not.toContain("getNumber(self)"); + expect(fileContent).not.toContain("getNumber(_G)"); + } +}); + test("enables noSelfInFile behavior for methods", () => { util.testFunction` class FooBar { diff --git a/test/util.ts b/test/util.ts index 0f053d9a0..995f6d9cf 100644 --- a/test/util.ts +++ b/test/util.ts @@ -172,14 +172,14 @@ export abstract class TestBuilder { protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { expect(this.hasProgram).toBe(false); - this.mainFileName = normalizeSlashes(mainFileName); + this.mainFileName = mainFileName; return this; } protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { expect(this.hasProgram).toBe(false); - this.extraFiles[fileName] = code; + this.extraFiles[fileName] = normalizeSlashes(code); return this; } @@ -206,10 +206,7 @@ export abstract class TestBuilder { Object.entries(this.extraFiles).filter(([fileName]) => !fileName.endsWith(".lua")) ); - return tstl.createVirtualProgram( - { ...nonLuaExtraFiles, [normalizeSlashes(this.mainFileName)]: this.getTsCode() }, - this.options - ); + return tstl.createVirtualProgram({ ...nonLuaExtraFiles, [this.mainFileName]: this.getTsCode() }, this.options); } private getEmitHost(): EmitHost { @@ -247,7 +244,7 @@ export abstract class TestBuilder { const mainFile = this.options.luaBundle ? transpiledFiles[0] : transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => normalizeSlashes(f.fileName) === this.mainFileName) + sourceFiles.some(f => f.fileName === normalizeSlashes(this.mainFileName)) ); expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); From d057bd0e445dad669790d249db514d348d2ea917 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 12 Jun 2022 20:04:18 +0200 Subject: [PATCH 487/764] CHANGELOG.md 1.6.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e92a7c2ef..1e786c078 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.6.0 + +- **[Breaking]** Upgraded TypeScript to 4.7 +- Fixed a bug where EmitOptions plugins were ignored +- Fixed a bug where sometimes function calls (like those to a custom jsx factory) would have a context argument even though `noImplicitSelf` was specified. +- Fixed a bug where sometimes `noImplicitSelf` was ignored because of incorrect file path separators. +- Fixed lualib_bundle files not correctly being included from node_module packages. +- Fixed compound assignment operators (e.g. ??= or ||=) not correctly updating the lhs if used as expression instead of statement. + ## 1.5.0 - Added support for `Array.from` and `Array.of` From b854f3f6d1e2b44e9dc6691a79e9ababf10226d2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 12 Jun 2022 20:18:45 +0200 Subject: [PATCH 488/764] 1.6.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 504ee8ced..ce30c8943 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.5.0", + "version": "1.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.5.0", + "version": "1.6.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 084019243..c5d1792be 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.5.0", + "version": "1.6.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d2accd722194bdbd54f13c8f2b1cc20fd4969813 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Fri, 24 Jun 2022 08:24:46 -0700 Subject: [PATCH 489/764] Fix #1295 (#1296) --- src/transformation/utils/function-context.ts | 11 +++++++++-- test/unit/functions/noImplicitSelfOption.spec.ts | 12 ++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 3a74bce80..896f7e373 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -79,8 +79,15 @@ export function getDeclarationContextType( // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const options = program.getCompilerOptions() as CompilerOptions; - if (options.noImplicitSelf && program.getSourceFile(signatureDeclaration.getSourceFile().fileName) !== undefined) { - return ContextType.Void; + if (options.noImplicitSelf) { + const sourceFile = program.getSourceFile(signatureDeclaration.getSourceFile().fileName); + if ( + sourceFile !== undefined && + !program.isSourceFileDefaultLibrary(sourceFile) && + !program.isSourceFileFromExternalLibrary(sourceFile) + ) { + return ContextType.Void; + } } // Walk up to find @noSelf or @noSelfInFile diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index b68a1ebc9..b2fbdd7d0 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -35,6 +35,18 @@ test.each(["\\", "/"])("transpileFiles handles paths with noImplicitSelf and %s } }); +test("noImplicitSelf does not affect functions in default libraries", () => { + util.testFunction` + const array = [1, 2, 3]; + const items = array.filter(x => x > 1); // array.filter is in external library + return items; + ` + .setOptions({ + noImplicitSelf: true, + }) + .expectToMatchJsResult(); +}); + test("enables noSelfInFile behavior for methods", () => { util.testFunction` class FooBar { From 3b75b04fe17cce215e274131e06e84f34d15aa91 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 24 Jun 2022 17:31:30 +0200 Subject: [PATCH 490/764] Revert resolving lualib_bundle from node_modules (#1293) --- src/transpilation/resolve.ts | 4 ++-- test/transpile/module-resolution.spec.ts | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 56b0354bd..4bff1528c 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -138,8 +138,8 @@ function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext const diagnostics: ts.Diagnostic[] = []; for (const required of findRequiredPaths(file.code)) { - // Do no resolve lualib, unless it is included from node_modules - if (required === "lualib_bundle" && !isNodeModulesFile(file.fileName)) { + // Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages + if (required === "lualib_bundle") { dependencies.push({ fileName: "lualib_bundle", code: "" }); continue; } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index dec970cf0..cd7869c70 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -254,14 +254,11 @@ describe("module resolution project with dependencies built by tstl library mode .expectToEqual(expectedResult) .getLuaResult(); - // Assert lualib_bundle from node_module is include - const expectedLualibBundle = path.join("lua_modules", "dependency1", "lualib_bundle.lua"); - expect(transpileResult.transpiledFiles.some(f => f.outPath.endsWith(expectedLualibBundle))).toBe(true); // Assert node_modules file requires the correct lualib_bundle const requiringLuaFile = path.join("lua_modules", "dependency1", "index.lua"); const lualibRequiringFile = transpileResult.transpiledFiles.find(f => f.outPath.endsWith(requiringLuaFile)); expect(lualibRequiringFile).toBeDefined(); - expect(lualibRequiringFile?.lua).toContain('require("lua_modules.dependency1.lualib_bundle")'); + expect(lualibRequiringFile?.lua).toContain('require("lualib_bundle")'); }); test("can resolve dependencies and bundle", () => { From 66bb36ecf195a7b65cfd7b983be1a7895e4aeb3c Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Fri, 24 Jun 2022 09:02:57 -0700 Subject: [PATCH 491/764] Reduce use of temp variables (#1291) * Reduce use of temp variables * Remove obsolete check * Add test cases for destructuring with no temps --- .../visitors/binary-expression/assignments.ts | 46 ++++++------------- .../visitors/expression-list.ts | 7 ++- .../visitors/variable-declaration.ts | 28 +++++------ .../__snapshots__/transformation.spec.ts.snap | 3 +- test/unit/destructuring.spec.ts | 44 ++++++++++++++++++ .../__snapshots__/multi.spec.ts.snap | 8 ++-- 6 files changed, 84 insertions(+), 52 deletions(-) diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index aec1ee96c..efd7180cb 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -107,8 +107,6 @@ function transformDestructuredAssignmentExpression( context: TransformationContext, expression: ts.DestructuringAssignment ) { - const rootIdentifier = context.createTempNameForNode(expression.right); - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); @@ -117,12 +115,15 @@ function transformDestructuredAssignmentExpression( right = wrapInTable(right); } - const statements = [ - lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment(context, expression, rootIdentifier, rightPrecedingStatements.length > 0), - ]; + const rightExpr = moveToPrecedingTemp(context, right, expression.right); + const statements = transformDestructuringAssignment( + context, + expression, + rightExpr, + rightPrecedingStatements.length > 0 + ); - return { statements, result: rootIdentifier }; + return { statements, result: rightExpr }; } export function transformAssignmentExpression( @@ -152,7 +153,6 @@ export function transformAssignmentExpression( } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { - const tempVar = context.createTempNameForNode(expression.right); const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); @@ -163,12 +163,10 @@ export function transformAssignmentExpression( precedingStatements.length > 0 ); - context.addPrecedingStatements([ - ...precedingStatements, - lua.createVariableDeclarationStatement(tempVar, right, expression.right), - lua.createAssignmentStatement(left, lua.cloneIdentifier(tempVar), expression.left), - ]); - return lua.cloneIdentifier(tempVar); + context.addPrecedingStatements(precedingStatements); + const rightExpr = moveToPrecedingTemp(context, right, expression.right); + context.addPrecedingStatements(lua.createAssignmentStatement(left, rightExpr, expression.left)); + return rightExpr; } else { // Simple assignment // ${left} = ${right}; return ${left} @@ -232,24 +230,8 @@ export function transformAssignmentStatement( return [lua.createAssignmentStatement(left, right, expression)]; } - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expression.right) - ); - context.addPrecedingStatements(rightPrecedingStatements); - if (isMultiReturnCall(context, expression.right)) { - right = wrapInTable(right); - } - - const rootIdentifier = context.createTempNameForNode(expression.left); - return [ - lua.createVariableDeclarationStatement(rootIdentifier, right), - ...transformDestructuringAssignment( - context, - expression, - rootIdentifier, - rightPrecedingStatements.length > 0 - ), - ]; + const { statements } = transformDestructuredAssignmentExpression(context, expression); + return statements; } else { const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) diff --git a/src/transformation/visitors/expression-list.ts b/src/transformation/visitors/expression-list.ts index 67019dcf1..475108922 100644 --- a/src/transformation/visitors/expression-list.ts +++ b/src/transformation/visitors/expression-list.ts @@ -11,7 +11,12 @@ export function shouldMoveToTemp(context: TransformationContext, expression: lua return ( !lua.isLiteral(expression) && !(lua.isIdentifier(expression) && expression.symbolId === tempSymbolId) && // Treat generated temps as consts - !(tsOriginal && (isConstIdentifier(context, tsOriginal) || isOptionalContinuation(tsOriginal))) + !( + tsOriginal && + (isConstIdentifier(context, tsOriginal) || + isOptionalContinuation(tsOriginal) || + tsOriginal.kind === ts.SyntaxKind.ThisKeyword) + ) ); } diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 9fd0f1f42..9cae749ce 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -12,6 +12,7 @@ import { createCallableTable, isFunctionTypeWithProperties } from "./function"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; +import { moveToPrecedingTemp } from "./expression-list"; export function transformArrayBindingElement( context: TransformationContext, @@ -38,7 +39,7 @@ export function transformArrayBindingElement( export function transformBindingPattern( context: TransformationContext, pattern: ts.BindingPattern, - table: lua.Identifier, + table: lua.Expression, propertyAccessStack: ts.PropertyName[] = [] ): lua.Statement[] { const result: lua.Statement[] = []; @@ -165,21 +166,20 @@ export function transformBindingVariableDeclaration( ts.isBindingElement(e) && (!ts.isIdentifier(e.name) || e.dotDotDotToken); if (ts.isObjectBindingPattern(bindingPattern) || bindingPattern.elements.some(isComplexBindingElement)) { - let table: lua.Identifier; - if (initializer !== undefined && ts.isIdentifier(initializer)) { - table = transformIdentifier(context, initializer); - } else { + let table: lua.Expression; + if (initializer) { // Contain the expression in a temporary variable - if (initializer) { - table = context.createTempNameForNode(initializer); - let expression = context.transformExpression(initializer); - if (isMultiReturnCall(context, initializer)) { - expression = wrapInTable(expression); - } - statements.push(lua.createVariableDeclarationStatement(table, expression)); - } else { - table = lua.createAnonymousIdentifier(); + let expression = context.transformExpression(initializer); + if (isMultiReturnCall(context, initializer)) { + expression = wrapInTable(expression); } + const [moveStatements, movedExpr] = transformInPrecedingStatementScope(context, () => + moveToPrecedingTemp(context, expression, initializer) + ); + statements.push(...moveStatements); + table = movedExpr; + } else { + table = lua.createAnonymousIdentifier(); } statements.push(...transformBindingPattern(context, bindingPattern, table)); return statements; diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 32f48994b..05bb647b8 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -269,7 +269,8 @@ value1 = obj.value1 value2 = obj.value2 obj2 = {value3 = 1, value4 = 2} value3 = obj2.value3 -value4 = obj2.value4 +local ____obj2_0 = obj2 +value4 = ____obj2_0.value4 function fun1(self) end fun2 = function() diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index d8fe47973..e44f8f0c3 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -74,6 +74,28 @@ test.each(testCases)("in variable declaration (%p)", ({ binding, value }) => { `.expectToMatchJsResult(); }); +test.each(testCases)("in variable declaration from const variable (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + { + const v: any = ${value}; + const ${binding} = v; + return { ${allBindings} }; + } + `.expectToMatchJsResult(); +}); + +test.each(testCases)("in variable declaration from this (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + function test(this: any) { + const ${binding} = this; + return { ${allBindings} }; + } + return test.call(${value}); + `.expectToMatchJsResult(); +}); + test.each(testCases)("in exported variable declaration (%p)", ({ binding, value }) => { util.testModule` export const ${binding} = ${value}; @@ -101,6 +123,28 @@ test.each(assignmentTestCases)("in assignment expression (%p)", ({ binding, valu `.expectToMatchJsResult(); }); +test.each(assignmentTestCases)("in assignment expression from const variable (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + const obj = { prop: false }; + const v: any = ${value}; + const expressionResult = (${binding} = v); + return { ${allBindings}, expressionResult }; + `.expectToMatchJsResult(); +}); + +test.each(assignmentTestCases)("in assignment expression from this (%p)", ({ binding, value }) => { + util.testFunction` + let ${allBindings}; + const obj = { prop: false }; + function test(this: any) { + const expressionResult = (${binding} = this); + return { ${allBindings}, obj, expressionResult }; + } + return test.call(${value}); + `.expectToMatchJsResult(); +}); + test.each(["[]", "{}"])("empty binding pattern", bindingPattern => { util.testFunction` let i = 1; diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index 6bd3922eb..98678b857 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -61,7 +61,7 @@ end" exports[`invalid $multi call (const [a = 0] = $multi()): diagnostics 1`] = `"main.ts(2,25): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (const {} = $multi();): code 1`] = `"local _____24multi_result_0 = {{____(_G)}}"`; +exports[`invalid $multi call (const {} = $multi();): code 1`] = `"local ____temp_0 = {{____(_G)}}"`; exports[`invalid $multi call (const {} = $multi();): diagnostics 1`] = `"main.ts(2,20): error TSTL: The $multi function must be called in a return statement."`; @@ -219,10 +219,10 @@ local function multi(self, ...) return ... end local a -local _____24multi_result_0 = {____(nil, 1)} -a = _____24multi_result_0[1] +local ____temp_0 = {____(nil, 1)} +a = ____temp_0[1] ____exports.a = a -if _____24multi_result_0 then +if ____temp_0 then a = a + 1 ____exports.a = a end From 70b61d9ab6db10e50b2f54d60d0d64831d835371 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Fri, 24 Jun 2022 11:38:48 -0700 Subject: [PATCH 492/764] Fix call context (#1294) * Add tests for #1292 * Fix #1292 * Always use noImplicitSelf for node without signature declaration --- src/transformation/visitors/call.ts | 16 ++++++++++------ test/unit/functions/noImplicitSelfOption.spec.ts | 14 ++++++++++++++ test/unit/functions/noSelfAnnotation.spec.ts | 11 +++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 62554bd5b..cfed13245 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -271,12 +271,9 @@ export const transformCallExpression: FunctionVisitor = (node ); } - const signatureDeclaration = signature?.getDeclaration(); - let callPath: lua.Expression; let parameters: lua.Expression[]; - const isContextualCall = - !signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void; + const isContextualCall = isContextualCallExpression(context, signature); if (!isContextualCall) { [callPath, parameters] = transformCallAndArguments(context, calledExpression, node.arguments, signature); } else { @@ -288,8 +285,7 @@ export const transformCallExpression: FunctionVisitor = (node calledExpression, node.arguments, signature, - // Only pass context if noImplicitSelf is not configured - context.options.noImplicitSelf ? undefined : callContext + callContext ); } @@ -300,6 +296,14 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResultInTable ? wrapInTable(callExpression) : callExpression; }; +function isContextualCallExpression(context: TransformationContext, signature: ts.Signature | undefined): boolean { + const declaration = signature?.getDeclaration(); + if (!declaration) { + return !context.options.noImplicitSelf; + } + return getDeclarationContextType(context, declaration) !== ContextType.Void; +} + export function getCalledExpression(node: ts.CallExpression): ts.Expression { function unwrapExpression(expression: ts.Expression): ts.Expression { expression = ts.skipOuterExpressions(expression); diff --git a/test/unit/functions/noImplicitSelfOption.spec.ts b/test/unit/functions/noImplicitSelfOption.spec.ts index b2fbdd7d0..ef788c922 100644 --- a/test/unit/functions/noImplicitSelfOption.spec.ts +++ b/test/unit/functions/noImplicitSelfOption.spec.ts @@ -79,3 +79,17 @@ test("generates declaration files with @noSelfInFile", () => { .ignoreDiagnostics([couldNotResolveRequire.code]) // no foo implementation in the project to create foo.lua .expectToHaveNoDiagnostics(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1292 +test("explicit this parameter respected over noImplicitSelf", () => { + util.testModule` + function foo(this: unknown, arg: any) { + return {self: this, arg}; + } + export const result = foo(1); + ` + .setOptions({ + noImplicitSelf: true, + }) + .expectToMatchJsResult(); +}); diff --git a/test/unit/functions/noSelfAnnotation.spec.ts b/test/unit/functions/noSelfAnnotation.spec.ts index ab77ec03e..1125f9cda 100644 --- a/test/unit/functions/noSelfAnnotation.spec.ts +++ b/test/unit/functions/noSelfAnnotation.spec.ts @@ -51,3 +51,14 @@ test("@noSelf on parent namespace declaration removes context argument", () => { MyNamespace.myMethod(); `.expectLuaToMatchSnapshot(); }); + +// additional coverage for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1292 +test("explicit this parameter respected over @noSelf", () => { + util.testModule` + /** @noSelfInFile */ + function foo(this: unknown, arg: any) { + return {self: this, arg}; + } + export const result = foo(1); + `.expectToMatchJsResult(); +}); From afbb749d5df7d80fa2ac5fd1c00ab743de007d2c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 24 Jun 2022 20:52:04 +0200 Subject: [PATCH 493/764] 1.6.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ce30c8943..69164bab1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.6.0", + "version": "1.6.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.6.0", + "version": "1.6.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index c5d1792be..5b1b71bda 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.6.0", + "version": "1.6.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9e9c3249e86eb730d99b70af75319faf87963eed Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 30 Jun 2022 21:19:05 +0200 Subject: [PATCH 494/764] Create FUNDING.yml --- .github/FUNDING.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 000000000..cd3dd9f16 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +# Sponsoring TypeScriptToLua helps us stay motivated and shows your appreciation for our work! +github: [Perryvw] From 288c1b70c2b2a95aaaef422ebebf25865aa221da Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 3 Jul 2022 19:21:57 +0200 Subject: [PATCH 495/764] Fix chained promise resolves not correctly passing value when then is empty (#1298) --- src/LuaPrinter.ts | 1 + src/lualib/Promise.ts | 5 ++++- test/unit/builtins/promise.spec.ts | 30 +++++++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index ed6163dc0..62fda173a 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -241,6 +241,7 @@ export class LuaPrinter { // Inline lualib features sourceChunks.push("-- Lua Library inline imports\n"); sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost)); + sourceChunks.push("-- End of Lua Library inline imports\n"); } if (this.options.sourceMapTraceback && !isBundleEnabled(this.options)) { diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index 99f144c0e..b55330713 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -85,7 +85,7 @@ export class __TS__Promise implements Promise { } } else { // We always want to resolve our child promise if this promise is resolved, even if we have no handler - this.fulfilledCallbacks.push(() => resolve(undefined)); + this.fulfilledCallbacks.push(v => resolve(v)); } if (onRejected) { @@ -96,6 +96,9 @@ export class __TS__Promise implements Promise { // If promise already rejected, immediately call callback internalCallback(this.rejectionReason); } + } else { + // We always want to reject our child promise if this promise is rejected, even if we have no handler + this.rejectedCallbacks.push(err => reject(err)); } if (isFulfilled) { diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index 10a0c767a..fa6f6cf0f 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -523,6 +523,34 @@ test("chained then throws", () => { ]); }); +test("empty then resolves", () => { + util.testFunction` + const { promise, resolve } = defer(); + + promise.then().then(v => { log("then2", v) }); + + resolve("mydata"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["then2", "mydata"]); +}); + +test("empty then rejects", () => { + util.testFunction` + const { promise, reject } = defer(); + + promise.then().catch(err => { log("catch", err) }); + + reject("my error"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch", "my error"]); +}); + test("catch on rejected promise immediately calls callback", () => { util.testFunction` Promise.reject("already rejected").catch(reason => { log(reason); }); @@ -592,7 +620,7 @@ describe("finally behaves same as then/catch", () => { log("final code"); }) .catch(reason => { - log("handling error", data); + log("handling error", reason); log("final code"); }); `; From 157c35be8cbea4448bffa90df1578d44d03b87f4 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 3 Jul 2022 20:45:33 +0200 Subject: [PATCH 496/764] 1.6.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 69164bab1..d3eed73bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.6.1", + "version": "1.6.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.6.1", + "version": "1.6.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 5b1b71bda..bb0119e2e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.6.1", + "version": "1.6.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 4d493542e805b395c6f19487ad1953ced4592776 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 8 Jul 2022 16:00:32 +0200 Subject: [PATCH 497/764] Get preEmit diagnostics from TypeScript before transforming (#1301) --- src/transpilation/index.ts | 12 ++++-------- src/tstl.ts | 7 +++---- test/unit/comments.spec.ts | 20 ++++++++++++++++++++ test/util.ts | 6 ++---- 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/transpilation/index.ts b/src/transpilation/index.ts index bce4e52c4..d4e890719 100644 --- a/src/transpilation/index.ts +++ b/src/transpilation/index.ts @@ -19,11 +19,9 @@ export function transpileFiles( writeFile?: ts.WriteFileCallback ): EmitResult { const program = ts.createProgram(rootNames, options); + const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); const { diagnostics: transpileDiagnostics, emitSkipped } = new Transpiler().emit({ program, writeFile }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...transpileDiagnostics, - ]); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics]); return { diagnostics: [...diagnostics], emitSkipped }; } @@ -98,12 +96,10 @@ export function transpileVirtualProject( options: CompilerOptions = {} ): TranspileVirtualProjectResult { const program = createVirtualProgram(files, options); + const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); const collector = createEmitOutputCollector(); const { diagnostics: transpileDiagnostics } = new Transpiler().emit({ program, writeFile: collector.writeFile }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...transpileDiagnostics, - ]); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics]); return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; } diff --git a/src/tstl.ts b/src/tstl.ts index d7b6d1df1..01a1d463b 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -102,12 +102,11 @@ function performCompilation( configFileParsingDiagnostics, }); + const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); + const { diagnostics: transpileDiagnostics, emitSkipped } = new tstl.Transpiler().emit({ program }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...transpileDiagnostics, - ]); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics]); diagnostics.forEach(reportDiagnostic); const exitCode = diff --git a/test/unit/comments.spec.ts b/test/unit/comments.spec.ts index 58e648ad3..2efb92b53 100644 --- a/test/unit/comments.spec.ts +++ b/test/unit/comments.spec.ts @@ -93,3 +93,23 @@ test("JSDoc is copied on a variable", () => { expect(lua).toBeDefined(); expect(lua).toContain("This is a variable comment."); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1299 +test("tsdoc comment does not cause a diagnostic (#1299)", () => { + util.testModule` + interface LuaBootstrap { + /** + * @remarks + * + * Links can point to a URL: {@link https://github.com/microsoft/tsdoc} + */ + on_init(f: (() => void) ): void + } + + const script : LuaBootstrap = { + on_init: (x) => x() + } + + script.on_init(() => {}) + `.expectToHaveNoDiagnostics(); +}); diff --git a/test/util.ts b/test/util.ts index 995f6d9cf..ffc6bac68 100644 --- a/test/util.ts +++ b/test/util.ts @@ -223,6 +223,7 @@ export abstract class TestBuilder { @memoize public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); + const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); const collector = createEmitOutputCollector(); const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({ program, @@ -230,10 +231,7 @@ export abstract class TestBuilder { writeFile: collector.writeFile, }); - const diagnostics = ts.sortAndDeduplicateDiagnostics([ - ...ts.getPreEmitDiagnostics(program), - ...transpileDiagnostics, - ]); + const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics]); return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; } From 33af9ea7c377f27ceb8bfd2a3efea92697666e0f Mon Sep 17 00:00:00 2001 From: hazzard993 Date: Sat, 9 Jul 2022 21:45:14 +1000 Subject: [PATCH 498/764] Support arrays in CLI arguments (#1300) * Support arrays in CLI arguments * Support arrays of objects in CLI via arrays of JSON * Do not split by comma if JSON is involved * Refine some tests, improve readability * Use an enum OptionSource --- src/cli/diagnostics.ts | 5 ++++ src/cli/parse.ts | 57 +++++++++++++++++++++++++++++++++--------- test/cli/parse.spec.ts | 14 +++++++++++ 3 files changed, 64 insertions(+), 12 deletions(-) diff --git a/src/cli/diagnostics.ts b/src/cli/diagnostics.ts index e386fa391..963713d2b 100644 --- a/src/cli/diagnostics.ts +++ b/src/cli/diagnostics.ts @@ -33,6 +33,11 @@ export const compilerOptionRequiresAValueOfType = createCommandLineError( (name: string, type: string) => `Compiler option '${name}' requires a value of type ${type}.` ); +export const compilerOptionCouldNotParseJson = createCommandLineError( + 5025, + (name: string, error: string) => `Compiler option '${name}' failed to parse the given JSON value: '${error}'.` +); + export const optionProjectCannotBeMixedWithSourceFilesOnACommandLine = createCommandLineError( 5042, () => "Option 'project' cannot be mixed with source files on a command line." diff --git a/src/cli/parse.ts b/src/cli/parse.ts index fbb104459..7c17a9177 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -18,7 +18,7 @@ interface CommandLineOptionOfEnum extends CommandLineOptionBase { } interface CommandLineOptionOfPrimitive extends CommandLineOptionBase { - type: "boolean" | "string" | "object" | "array"; + type: "boolean" | "string" | "json-array-of-objects" | "array"; } type CommandLineOption = CommandLineOptionOfEnum | CommandLineOptionOfPrimitive; @@ -82,7 +82,7 @@ export const optionDeclarations: CommandLineOption[] = [ { name: "luaPlugins", description: "List of TypeScriptToLua plugins.", - type: "object", + type: "json-array-of-objects", }, { name: "tstlVerbose", @@ -124,7 +124,7 @@ export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): continue; } - const { error, value } = readValue(option, rawValue); + const { error, value } = readValue(option, rawValue, OptionSource.TsConfig); if (error) parsedConfigFile.errors.push(error); if (parsedConfigFile.options[name] === undefined) parsedConfigFile.options[name] = value; } @@ -164,9 +164,9 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: if (error) parsedCommandLine.errors.push(error); parsedCommandLine.options[option.name] = value; if (consumed) { - i += 1; // Values of custom options are parsed as a file name, exclude them - parsedCommandLine.fileNames = parsedCommandLine.fileNames.filter(f => f !== value); + parsedCommandLine.fileNames = parsedCommandLine.fileNames.filter(f => f !== args[i + 1]); + i += 1; } } } @@ -196,7 +196,12 @@ function readCommandLineArgument(option: CommandLineOption, value: any): Command }; } - return { ...readValue(option, value), consumed: true }; + return { ...readValue(option, value, OptionSource.CommandLine), consumed: true }; +} + +enum OptionSource { + CommandLine, + TsConfig, } interface ReadValueResult { @@ -204,13 +209,12 @@ interface ReadValueResult { value: any; } -function readValue(option: CommandLineOption, value: unknown): ReadValueResult { +function readValue(option: CommandLineOption, value: unknown, source: OptionSource): ReadValueResult { if (value === null) return { value }; switch (option.type) { case "boolean": - case "string": - case "object": { + case "string": { if (typeof value !== option.type) { return { value: undefined, @@ -220,15 +224,44 @@ function readValue(option: CommandLineOption, value: unknown): ReadValueResult { return { value }; } - case "array": { - if (!Array.isArray(value)) { + case "array": + case "json-array-of-objects": { + const isInvalidNonCliValue = source === OptionSource.TsConfig && !Array.isArray(value); + const isInvalidCliValue = source === OptionSource.CommandLine && typeof value !== "string"; + + if (isInvalidNonCliValue || isInvalidCliValue) { return { value: undefined, error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, option.type), }; } - return { value }; + const shouldParseValue = source === OptionSource.CommandLine && typeof value === "string"; + if (!shouldParseValue) return { value }; + + if (option.type === "array") { + const array = value.split(","); + return { value: array }; + } + + try { + const objects = JSON.parse(value); + if (!Array.isArray(objects)) { + return { + value: undefined, + error: cliDiagnostics.compilerOptionRequiresAValueOfType(option.name, option.type), + }; + } + + return { value: objects }; + } catch (e) { + if (!(e instanceof SyntaxError)) throw e; + + return { + value: undefined, + error: cliDiagnostics.compilerOptionCouldNotParseJson(option.name, e.message), + }; + } } case "enum": { if (typeof value !== "string") { diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 921af9c45..2def0b45a 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -59,6 +59,14 @@ describe("command line", () => { }); }); + describe("array-of-objects options", () => { + test.each([["{"], ["{}"], ["0"], ["''"]])("should error on invalid value (%s)", value => { + const result = tstl.parseCommandLine(["--luaPlugins", value]); + + expect(result.errors).toHaveDiagnostics(); + }); + }); + describe("boolean options", () => { test.each([true, false])("should parse booleans (%p)", value => { const result = tstl.parseCommandLine(["--noHeader", value.toString()]); @@ -125,6 +133,12 @@ describe("command line", () => { ["extension", ".lua", { extension: ".lua" }], ["extension", "scar", { extension: "scar" }], + + ["luaPlugins", '[{ "name": "a" }]', { luaPlugins: [{ name: "a" }] }], + ["luaPlugins", '[{ "name": "a" },{ "name": "b" }]', { luaPlugins: [{ name: "a" }, { name: "b" }] }], + + ["noResolvePaths", "path1", { noResolvePaths: ["path1"] }], + ["noResolvePaths", "path1,path2", { noResolvePaths: ["path1", "path2"] }], ])("--%s %s", (optionName, value, expected) => { const result = tstl.parseCommandLine([`--${optionName}`, value]); From 8733992b05d7642ae2ed4f30bb9e4b65136294e7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 9 Jul 2022 13:54:47 +0200 Subject: [PATCH 499/764] 1.6.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d3eed73bc..e8b7cb5eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.6.2", + "version": "1.6.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.6.2", + "version": "1.6.3", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index bb0119e2e..f01b5790d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.6.2", + "version": "1.6.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 7ff29f0ce8b64f95b65e90a37781770272169f7d Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 14 Jul 2022 12:51:45 -0700 Subject: [PATCH 500/764] Add LuaMap and LuaSet language extensions (#1303) * Add LuaTableAdd language extension * Add definitions for LuaSet and LuaMap * Add LuaPairsKeyIterable language extension * Update test * Fix typos * Rename LuaTableAdd to LuaTableAddKey * Add more tests for LuaTableAddKey --- language-extensions/index.d.ts | 91 +++++++++++++++++ .../utils/language-extensions.ts | 6 ++ .../language-extensions/pairsIterable.ts | 23 ++++- .../visitors/language-extensions/table.ts | 35 +++++++ src/transformation/visitors/loops/for-of.ts | 9 +- .../language-extensions/pairsIterable.spec.ts | 99 +++++++++++++++++++ test/unit/language-extensions/table.spec.ts | 69 +++++++++++++ 7 files changed, 330 insertions(+), 2 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 8c30e1a8d..1085a57b7 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -88,6 +88,13 @@ declare type LuaIterable = Iterable & declare type LuaPairsIterable = Iterable<[TKey, TValue]> & LuaExtension<"__luaPairsIterableBrand">; +/** + * Represents an object that can be iterated with pairs(), where only the key value is used. + * + * @param TKey The type of the key returned each iteration. + */ +declare type LuaPairsKeyIterable = Iterable & LuaExtension<"__luaPairsKeyIterableBrand">; + /** * Calls to functions with this type are translated to `left + right`. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -500,6 +507,24 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & LuaExtension<"__luaTableSetMethodBrand">; +/** + * Calls to functions with this type are translated to `table[key] = true`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableAddKey = ((table: TTable, key: TKey) => void) & + LuaExtension<"__luaTableAddKeyBrand">; + +/** + * Calls to methods with this type are translated to `table[key] = true`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * @param TKey The type of the key to use to access the table. + */ +declare type LuaTableAddKeyMethod = ((key: TKey) => void) & + LuaExtension<"__luaTableAddKeyMethodBrand">; + /** * Calls to functions with this type are translated to `table[key] ~= nil`. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -574,3 +599,69 @@ declare type LuaTableConstructor = (new extends LuaPairsIterable { + get: LuaTableGetMethod; + set: LuaTableSetMethod; + has: LuaTableHasMethod; + delete: LuaTableDeleteMethod; +} + +/** + * A convenience type for working directly with a Lua table, used as a map. + * + * This differs from LuaTable in that the `get` method may return `nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * @param K The type of the keys used to access the table. + * @param V The type of the values stored in the table. + */ +declare const LuaMap: (new () => LuaMap) & + LuaExtension<"__luaTableNewBrand">; + +/** + * Readonly version of {@link LuaMap}. + * + * @param K The type of the keys used to access the table. + * @param V The type of the values stored in the table. + */ +declare interface LuaReadonlyMap extends LuaPairsIterable { + get: LuaTableGetMethod; + has: LuaTableHasMethod; +} + +/** + * A convenience type for working directly with a Lua table, used as a set. + * + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * @param T The type of the keys used to access the table. + */ +declare interface LuaSet extends LuaPairsKeyIterable { + add: LuaTableAddKeyMethod; + has: LuaTableHasMethod; + delete: LuaTableDeleteMethod; +} + +/** + * A convenience type for working directly with a Lua table, used as a set. + * + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * @param T The type of the keys used to access the table. + */ +declare const LuaSet: (new () => LuaSet) & LuaExtension<"__luaTableNewBrand">; + +/** + * Readonly version of {@link LuaSet}. + * + * @param T The type of the keys used to access the table. + */ +declare interface LuaReadonlySet extends LuaPairsKeyIterable { + has: LuaTableHasMethod; +} diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index a98844c7b..8b6b15859 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -8,6 +8,7 @@ export enum ExtensionKind { VarargConstant = "VarargConstant", IterableType = "IterableType", PairsIterableType = "PairsIterableType", + PairsKeyIterableType = "PairsKeyIterableType", AdditionOperatorType = "AdditionOperatorType", AdditionOperatorMethodType = "AdditionOperatorMethodType", SubtractionOperatorType = "SubtractionOperatorType", @@ -53,6 +54,8 @@ export enum ExtensionKind { TableHasMethodType = "TableHasMethodType", TableSetType = "TableSetType", TableSetMethodType = "TableSetMethodType", + TableAddType = "TableAddType", + TableAddMethodType = "TableAddMethodType", } const extensionKindToValueName: { [T in ExtensionKind]?: string } = { @@ -68,6 +71,7 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", [ExtensionKind.IterableType]: "__luaIterableBrand", [ExtensionKind.PairsIterableType]: "__luaPairsIterableBrand", + [ExtensionKind.PairsKeyIterableType]: "__luaPairsKeyIterableBrand", [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", @@ -113,6 +117,8 @@ const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { [ExtensionKind.TableHasMethodType]: "__luaTableHasMethodBrand", [ExtensionKind.TableSetType]: "__luaTableSetBrand", [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", + [ExtensionKind.TableAddType]: "__luaTableAddKeyBrand", + [ExtensionKind.TableAddMethodType]: "__luaTableAddKeyMethodBrand", }; export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { diff --git a/src/transformation/visitors/language-extensions/pairsIterable.ts b/src/transformation/visitors/language-extensions/pairsIterable.ts index 0874952cf..a688ded2f 100644 --- a/src/transformation/visitors/language-extensions/pairsIterable.ts +++ b/src/transformation/visitors/language-extensions/pairsIterable.ts @@ -4,7 +4,7 @@ import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { invalidPairsIterableWithoutDestructuring } from "../../utils/diagnostics"; import * as extensions from "../../utils/language-extensions"; -import { getVariableDeclarationBinding } from "../loops/utils"; +import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; import { transformArrayBindingElement } from "../variable-declaration"; function isPairsIterableType(type: ts.Type): boolean { @@ -16,6 +16,15 @@ export function isPairsIterableExpression(context: TransformationContext, expres return isPairsIterableType(type); } +function isPairsKeyIterableType(type: ts.Type): boolean { + return extensions.isExtensionType(type, extensions.ExtensionKind.PairsKeyIterableType); +} + +export function isPairsKeyIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { + const type = context.checker.getTypeAtLocation(expression); + return isPairsKeyIterableType(type); +} + export function transformForOfPairsIterableStatement( context: TransformationContext, statement: ts.ForOfStatement, @@ -61,3 +70,15 @@ export function transformForOfPairsIterableStatement( return lua.createForInStatement(block, identifiers, [pairsCall], statement); } + +export function transformForOfPairsKeyIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ + context.transformExpression(statement.expression), + ]); + const identifier = transformForInitializer(context, statement.initializer, block); + return lua.createForInStatement(block, [identifier], [pairsCall], statement); +} diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index ee3e3f2db..eedc42c8e 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -15,6 +15,8 @@ const tableCallExtensions = [ extensions.ExtensionKind.TableHasMethodType, extensions.ExtensionKind.TableSetType, extensions.ExtensionKind.TableSetMethodType, + extensions.ExtensionKind.TableAddType, + extensions.ExtensionKind.TableAddMethodType, ]; const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableCallExtensions]; @@ -77,6 +79,13 @@ export function transformTableExtensionCall( ) { return transformTableSetExpression(context, node, extensionType); } + + if ( + extensionType === extensions.ExtensionKind.TableAddType || + extensionType === extensions.ExtensionKind.TableAddMethodType + ) { + return transformTableAddExpression(context, node, extensionType); + } } function transformTableDeleteExpression( @@ -172,3 +181,29 @@ function transformTableSetExpression( ); return lua.createNilLiteral(); } + +function transformTableAddExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: extensions.ExtensionKind +): lua.Expression { + const args = node.arguments.slice(); + if ( + extensionKind === extensions.ExtensionKind.TableAddMethodType && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + // In case of method (no table argument), push method owner to front of args list + args.unshift(node.expression.expression); + } + + // arg0[arg1] = true + const [table, value] = transformExpressionList(context, args); + context.addPrecedingStatements( + lua.createAssignmentStatement( + lua.createTableIndexExpression(table, value), + lua.createBooleanLiteral(true), + node + ) + ); + return lua.createNilLiteral(); +} diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 6380423f1..70a64e643 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -6,7 +6,12 @@ import { annotationRemoved } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType } from "../../utils/typescript"; import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; -import { isPairsIterableExpression, transformForOfPairsIterableStatement } from "../language-extensions/pairsIterable"; +import { + isPairsIterableExpression, + transformForOfPairsIterableStatement, + isPairsKeyIterableExpression, + transformForOfPairsKeyIterableStatement, +} from "../language-extensions/pairsIterable"; import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformForInitializer, transformLoopBody } from "./utils"; @@ -50,6 +55,8 @@ export const transformForOfStatement: FunctionVisitor = (node return transformForOfIterableStatement(context, node, body); } else if (isPairsIterableExpression(context, node.expression)) { return transformForOfPairsIterableStatement(context, node, body); + } else if (isPairsKeyIterableExpression(context, node.expression)) { + return transformForOfPairsKeyIterableStatement(context, node, body); } else if (isLuaIteratorType(context, node.expression)) { context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { diff --git a/test/unit/language-extensions/pairsIterable.spec.ts b/test/unit/language-extensions/pairsIterable.spec.ts index 3fd2e0d85..51c7e0b4e 100644 --- a/test/unit/language-extensions/pairsIterable.spec.ts +++ b/test/unit/language-extensions/pairsIterable.spec.ts @@ -118,3 +118,102 @@ test.each(["for (const s of testIterable) {}", "let s; for (s of testIterable) { .expectDiagnosticsToMatchSnapshot([invalidPairsIterableWithoutDestructuring.code]); } ); + +const testKeyIterable = ` +const testKeyIterable = {a1: true, b1: true, c1: true} as unknown as LuaPairsKeyIterable; +`; + +test("pairs key iterable", () => { + util.testFunction` + ${testKeyIterable} + const results: Record = {}; + for (const k of testKeyIterable) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ a1: true, b1: true, c1: true }); +}); + +test("pairs key iterable with external control variable", () => { + util.testFunction` + ${testKeyIterable} + const results: Record = {}; + let k: string; + for (k of testKeyIterable) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ a1: true, b1: true, c1: true }); +}); + +test("pairs key iterable function forward", () => { + util.testFunction` + ${testKeyIterable} + function forward() { return testKeyIterable; } + const results: Record = {}; + for (const k of forward()) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ a1: true, b1: true, c1: true }); +}); + +test("pairs key iterable function indirect forward", () => { + util.testFunction` + ${testKeyIterable} + function forward() { const iter = testKeyIterable; return iter; } + const results: Record = {}; + for (const k of forward()) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ a1: true, b1: true, c1: true }); +}); + +test("pairs key iterable arrow function forward", () => { + util.testFunction` + ${testKeyIterable} + const forward = () => testKeyIterable; + const results: Record = {}; + for (const k of forward()) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .expectToEqual({ a1: true, b1: true, c1: true }); +}); + +test("pairs key iterable with __pairs metamethod", () => { + util.testFunction` + class PairsTest { + __pairs() { + const kvp = [ ["a1", true], ["b1", true], ["c1", true] ]; + let i = 0; + return () => { + if (i < kvp.length) { + const [k, v] = kvp[i++]; + return $multi(k, v); + } + }; + } + } + const tester = new PairsTest() as PairsTest & LuaPairsKeyIterable; + const results: Record = {}; + for (const k of tester) { + results[k] = true; + } + return results; + ` + .withLanguageExtensions() + .setOptions({ luaTarget: LuaTarget.Lua53 }) + .expectToEqual({ a1: true, b1: true, c1: true }); +}); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index baf05b0c0..f42ababa7 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -240,6 +240,65 @@ describe("LuaTableDelete extension", () => { }); }); +describe("LuaTableAddKey extension", () => { + test("LuaTableAddKey standalone function", () => { + util.testModule` + declare const tableAddKey: LuaTableAddKey<{}, string>; + export const table = { foo: "bar" }; + tableAddKey(table, "baz"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { foo: "bar", baz: true } }); + }); + + test("LuaTableAddKey namespace function", () => { + util.testModule` + declare namespace Table { + export const tableAddKey: LuaTableAddKey<{}, string>; + } + export const table = { foo: "bar" }; + Table.tableAddKey(table, "baz"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { foo: "bar", baz: true } }); + }); + + test("LuaTableAddKey method", () => { + util.testModule` + interface TableWithAddKey { + addKey: LuaTableAddKeyMethod; + } + export const table = {} as TableWithAddKey; + table.addKey("bar"); + ` + .withLanguageExtensions() + .expectToEqual({ table: { bar: true } }); + }); + + test.each([ + ["LuaTableAddKey<{}, string>", 'func({}, "foo")', undefined], + ["LuaTableAddKey<{}, string>", '"truthy" && func({}, "foo")', undefined], + ])("Table functions used as expression", (funcType, expression, value) => { + util.testModule` + declare const func: ${funcType} + export const result = ${expression} + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(value); + }); + + test("Method used as expression", () => { + util.testModule` + const tbl = {} as { func: LuaTableAddKeyMethod } + export const result = tbl.func("foo") + ` + .withLanguageExtensions() + .setReturnExport("result") + .expectToEqual(undefined); + }); +}); + describe("LuaTable extension interface", () => { test("untyped table", () => { util.testFunction` @@ -332,6 +391,16 @@ describe("LuaTable extension interface", () => { .expectToEqual({ baz: 5 }); }); + test("table add", () => { + util.testFunction` + const tbl = new LuaSet() + tbl.add("foo"); + return tbl + ` + .withLanguageExtensions() + .expectToEqual({ foo: true }); + }); + test.each(['new LuaTable().get("foo");', 'new LuaTable().set("foo", "bar");'])( "table immediate access (%p)", statement => { From d69f089e53e03cbfe573138a8e6b4fa05c1733db Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Sat, 16 Jul 2022 05:04:49 -0400 Subject: [PATCH 501/764] adding schema (#1302) * adding schema * prettier --- tsconfig-schema.json | 106 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 tsconfig-schema.json diff --git a/tsconfig-schema.json b/tsconfig-schema.json new file mode 100644 index 000000000..ca6f9be8c --- /dev/null +++ b/tsconfig-schema.json @@ -0,0 +1,106 @@ +{ + "title": "tsconfig.json with TSTL", + "description": "JSON schema for the TypeScript compiler's configuration file with TSTL", + "$schema": "http://json-schema.org/draft-07/schema", + "allOf": [ + { + "$ref": "https://json.schemastore.org/tsconfig" + } + ], + "properties": { + "tstl": { + "description": "TypeScriptToLua compiler options.", + "type": "object", + "definitions": { + "//": { + "reference": "https://typescripttolua.github.io/docs/configuration#custom-options" + } + }, + "properties": { + "buildMode": { + "description": "Use buildMode: \"library\" to build publishable library packages.", + "type": "string", + "default": "library", + "enum": ["default", "library"] + }, + "lua51AllowTryCatchInAsyncAwait": { + "description": "Disable the warning that try/catch is not allowed in async functions in Lua 5.1, in case you are using a patched 5.1 lua version that supports this.", + "type": "boolean", + "default": false + }, + "luaBundle": { + "description": "The name of the lua file to bundle output lua to. Requires luaBundleEntry.", + "type": "string" + }, + "luaBundleEntry": { + "description": "The entry *.ts file that will be executed when entering the luaBundle. Requires luaBundle.", + "type": "string" + }, + "luaLibImport": { + "description": "Specifies how js standard features missing in lua are imported.", + "type": "string", + "default": "require", + "enum": ["none", "always", "inline", "require"] + }, + "luaTarget": { + "description": "Specifies the Lua version you want to generate code for.", + "type": "string", + "default": "universal", + "enum": ["5.1", "5.2", "5.3", "JIT"] + }, + "noImplicitGlobalVariables": { + "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", + "type": "boolean", + "default": false + }, + "noImplicitSelf": { + "description": "If true, treats all project files as if they were prefixed with\n/** @noSelfInFile **/.", + "type": "boolean", + "default": false + }, + "noHeader": { + "description": "Specify if a header will be added to compiled files.", + "type": "boolean", + "default": false + }, + "noResolvePaths": { + "description": "An array of import paths that should not be resolved but copied verbatim to output lua.", + "type": "array" + }, + "sourceMapTraceback": { + "description": "Applies the source map to show source TS files and lines in error tracebacks.", + "default": false, + "type": "boolean" + }, + "tstlVerbose": { + "description": "Give verbose tstl output, helpful when diagnosing tstl issues.", + "type": "boolean", + "default": false + }, + "luaPlugins": { + "description": "List of TypeScriptToLua plugins.", + "type": "array", + "items": { + "description": "Describes TypeScriptToLua plugin", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "description": "Path to the JS file, that contains the plugin code", + "type": "string" + }, + "import": { + "type": "string" + } + } + } + } + }, + "dependencies": { + "luaBundle": ["luaBundleEntry"], + "luaBundleEntry": ["luaBundle"] + } + } + }, + "allowTrailingCommas": true +} From cfd1e365797ad17cf24a7e9f6740ebf2a228a434 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Mon, 18 Jul 2022 09:53:48 -0700 Subject: [PATCH 502/764] Significant performance improvements (#1308) * Add performance hooks * Ignore v8 profile logs * Optimize TransformationContext 2% performance improvement * Remove WeakMap 3-4% performance improvement * Change language extension declaration method * Significantly improve performance of language extensions >4x speedup!!! * Separate iterable language extensions * Unify language extension call transformers * Fix getExtensionsKindForType and error reporting for TableNew type * Cache function context * Fix crash on incorrect language extension use * Optimize and cleanup builtins 5% performance improvement * Optimize and cleanup annotations 3% performance improvement * Remove deprecated annotations 4-5% performance improvement * Optimize assignment-validation 5-6% performance improvement * Optimize language extensions again 2-3% performance improvement * Optimize getEmitPlan ~3% performance improvement in getEmitPlan (mostly IO) * Flatten visitor map * Ignore v8 cpu profiles * Fix prettier * PR feedback * Optimize isExplicitArrayType 6% transpilation time speedup typeToTypeNode is very slow * PR feedback * Revert changes to createReturnStatement * PR feedback --- .gitignore | 4 + language-extensions/index.d.ts | 146 ++++---- src/CompilerOptions.ts | 1 + src/cli/parse.ts | 5 + src/lualib-build/plugin.ts | 3 +- src/measure-performance.ts | 83 +++++ src/transformation/builtins/array.ts | 7 +- src/transformation/builtins/global.ts | 25 +- src/transformation/builtins/index.ts | 188 +++++----- src/transformation/builtins/object.ts | 5 +- src/transformation/builtins/promise.ts | 5 +- src/transformation/builtins/string.ts | 2 + src/transformation/context/context.ts | 119 +++++-- src/transformation/context/visitors.ts | 2 +- src/transformation/index.ts | 15 +- src/transformation/utils/annotations.ts | 146 +++----- .../utils/assignment-validation.ts | 65 ++-- src/transformation/utils/diagnostics.ts | 6 +- src/transformation/utils/function-context.ts | 124 +++---- .../utils/language-extensions.ts | 223 ++++++------ src/transformation/utils/lualib.ts | 8 +- src/transformation/utils/safe-names.ts | 9 +- src/transformation/utils/scope.ts | 37 +- src/transformation/utils/symbols.ts | 30 +- src/transformation/utils/typescript/index.ts | 2 +- src/transformation/utils/typescript/types.ts | 73 ++-- src/transformation/visitors/access.ts | 13 +- src/transformation/visitors/block.ts | 10 +- src/transformation/visitors/call.ts | 30 +- src/transformation/visitors/class/index.ts | 25 +- .../visitors/class/members/constructor.ts | 6 +- src/transformation/visitors/class/new.ts | 12 +- src/transformation/visitors/class/setup.ts | 7 +- src/transformation/visitors/class/utils.ts | 16 +- src/transformation/visitors/conditional.ts | 10 +- src/transformation/visitors/function.ts | 30 +- src/transformation/visitors/identifier.ts | 103 +++--- .../language-extensions/call-extension.ts | 34 ++ .../language-extensions/identifier.ts | 27 ++ .../visitors/language-extensions/index.ts | 20 -- .../visitors/language-extensions/iterable.ts | 68 ++-- .../visitors/language-extensions/multi.ts | 44 +-- .../visitors/language-extensions/operators.ts | 214 ++++++------ .../language-extensions/pairsIterable.ts | 84 ----- .../visitors/language-extensions/range.ts | 8 +- .../visitors/language-extensions/table.ts | 177 +++------- .../visitors/language-extensions/vararg.ts | 10 +- src/transformation/visitors/literal.ts | 39 +-- src/transformation/visitors/loops/for-of.ts | 39 +-- src/transformation/visitors/loops/utils.ts | 12 +- src/transformation/visitors/namespace.ts | 24 +- src/transformation/visitors/return.ts | 6 +- src/transformation/visitors/sourceFile.ts | 9 +- src/transformation/visitors/spread.ts | 5 - src/transformation/visitors/switch.ts | 6 +- .../visitors/variable-declaration.ts | 2 +- src/transpilation/plugins.ts | 4 + src/transpilation/resolve.ts | 320 ++++++++---------- src/transpilation/transpile.ts | 19 +- src/transpilation/transpiler.ts | 46 ++- src/tstl.ts | 28 +- src/typescript-internal.d.ts | 11 + .../optionalChaining.spec.ts.snap | 16 +- .../__snapshots__/deprecated.spec.ts.snap | 166 --------- test/unit/annotations/deprecated.spec.ts | 124 ------- test/unit/builtins/string.spec.ts | 4 + .../__snapshots__/multi.spec.ts.snap | 2 +- .../__snapshots__/operators.spec.ts.snap | 10 +- .../language-extensions/operators.spec.ts | 5 +- test/unit/language-extensions/table.spec.ts | 6 +- 70 files changed, 1374 insertions(+), 1810 deletions(-) create mode 100644 src/measure-performance.ts create mode 100644 src/transformation/visitors/language-extensions/call-extension.ts create mode 100644 src/transformation/visitors/language-extensions/identifier.ts delete mode 100644 src/transformation/visitors/language-extensions/index.ts delete mode 100644 src/transformation/visitors/language-extensions/pairsIterable.ts delete mode 100644 test/unit/annotations/__snapshots__/deprecated.spec.ts.snap delete mode 100644 test/unit/annotations/deprecated.spec.ts diff --git a/.gitignore b/.gitignore index c2bc56893..e9fe7f092 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ yarn.lock benchmark/data/* benchmark/dist/* + +# v8 cpu profiles +*-.log +*.cpuprofile diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 1085a57b7..c18e68690 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -3,12 +3,24 @@ type AnyTable = Record; type AnyNotNil = {}; /** - * Indicates a type is a language extension provided by TypescriptToLua. + * Indicates a type is a language extension provided by TypescriptToLua when used as a value or function call. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions * * @param TBrand A string used to uniquely identify the language extension type */ -declare type LuaExtension = { [T in TBrand]: { readonly __luaExtensionSymbol: unique symbol } }; +declare interface LuaExtension { + readonly __tstlExtension: TBrand; +} + +/** + * Indicates a type is a language extension provided by TypescriptToLua when used in a for-of loop. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TBrand A string used to uniquely identify the language extension type + */ +declare interface LuaIterationExtension { + readonly __tstlIterable: TBrand; +} /** * Returns multiple values from a function, by wrapping them in a LuaMultiReturn tuple. @@ -17,7 +29,7 @@ declare type LuaExtension = { [T in TBrand]: { readonly _ * @param T A tuple type with each element type representing a return value's type. * @param values Return values. */ -declare const $multi: ((...values: T) => LuaMultiReturn) & LuaExtension<"__luaMultiFunctionBrand">; +declare const $multi: ((...values: T) => LuaMultiReturn) & LuaExtension<"MultiFunction">; /** * Represents multiple return values as a tuple. @@ -25,7 +37,9 @@ declare const $multi: ((...values: T) => LuaMultiReturn) & L * * @param T A tuple type with each element type representing a return value's type. */ -declare type LuaMultiReturn = T & LuaExtension<"__luaMultiReturnBrand">; +declare type LuaMultiReturn = T & { + readonly __tstlMultiReturn: any; +}; /** * Creates a Lua-style numeric for loop (for i=start,limit,step) when used in for...of. Not valid in any other context. @@ -36,13 +50,13 @@ declare type LuaMultiReturn = T & LuaExtension<"__luaMultiRetur * @param step The amount to increment each iteration. */ declare const $range: ((start: number, limit: number, step?: number) => Iterable) & - LuaExtension<"__luaRangeFunctionBrand">; + LuaExtension<"RangeFunction">; /** * Transpiles to the global vararg (`...`) * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions */ -declare const $vararg: string[] & LuaExtension<"__luaVarargConstantBrand">; +declare const $vararg: string[] & LuaExtension<"VarargConstant">; /** * Represents a Lua-style iterator which is returned from a LuaIterable. @@ -76,7 +90,7 @@ declare type LuaIterator = TState extends undefined */ declare type LuaIterable = Iterable & LuaIterator & - LuaExtension<"__luaIterableBrand">; + LuaIterationExtension<"Iterable">; /** * Represents an object that can be iterated with pairs() @@ -86,14 +100,14 @@ declare type LuaIterable = Iterable & * @param TValue The type of the value returned each iteration. */ declare type LuaPairsIterable = Iterable<[TKey, TValue]> & - LuaExtension<"__luaPairsIterableBrand">; + LuaIterationExtension<"Pairs">; /** * Represents an object that can be iterated with pairs(), where only the key value is used. * * @param TKey The type of the key returned each iteration. */ -declare type LuaPairsKeyIterable = Iterable & LuaExtension<"__luaPairsKeyIterableBrand">; +declare type LuaPairsKeyIterable = Iterable & LuaIterationExtension<"PairsKey">; /** * Calls to functions with this type are translated to `left + right`. @@ -103,8 +117,7 @@ declare type LuaPairsKeyIterable = Iterable & LuaE * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaAdditionBrand">; +declare type LuaAddition = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"Addition">; /** * Calls to methods with this type are translated to `left + right`, where `left` is the object with the method. @@ -113,8 +126,7 @@ declare type LuaAddition = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaAdditionMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaAdditionMethodBrand">; +declare type LuaAdditionMethod = ((right: TRight) => TReturn) & LuaExtension<"AdditionMethod">; /** * Calls to functions with this type are translated to `left - right`. @@ -125,7 +137,7 @@ declare type LuaAdditionMethod = ((right: TRight) => TReturn) & * @param TReturn The resulting (return) type of the operation. */ declare type LuaSubtraction = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaSubtractionBrand">; + LuaExtension<"Subtraction">; /** * Calls to methods with this type are translated to `left - right`, where `left` is the object with the method. @@ -134,8 +146,7 @@ declare type LuaSubtraction = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaSubtractionMethodBrand">; +declare type LuaSubtractionMethod = ((right: TRight) => TReturn) & LuaExtension<"SubtractionMethod">; /** * Calls to functions with this type are translated to `left * right`. @@ -146,7 +157,7 @@ declare type LuaSubtractionMethod = ((right: TRight) => TReturn * @param TReturn The resulting (return) type of the operation. */ declare type LuaMultiplication = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaMultiplicationBrand">; + LuaExtension<"Multiplication">; /** * Calls to methods with this type are translated to `left * right`, where `left` is the object with the method. @@ -156,7 +167,7 @@ declare type LuaMultiplication = ((left: TLeft, right: T * @param TReturn The resulting (return) type of the operation. */ declare type LuaMultiplicationMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaMultiplicationMethodBrand">; + LuaExtension<"MultiplicationMethod">; /** * Calls to functions with this type are translated to `left / right`. @@ -166,8 +177,7 @@ declare type LuaMultiplicationMethod = ((right: TRight) => TRet * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaDivisionBrand">; +declare type LuaDivision = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"Division">; /** * Calls to methods with this type are translated to `left / right`, where `left` is the object with the method. @@ -176,8 +186,7 @@ declare type LuaDivision = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaDivisionMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaDivisionMethodBrand">; +declare type LuaDivisionMethod = ((right: TRight) => TReturn) & LuaExtension<"DivisionMethod">; /** * Calls to functions with this type are translated to `left % right`. @@ -187,8 +196,7 @@ declare type LuaDivisionMethod = ((right: TRight) => TReturn) & * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaModuloBrand">; +declare type LuaModulo = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"Modulo">; /** * Calls to methods with this type are translated to `left % right`, where `left` is the object with the method. @@ -197,7 +205,7 @@ declare type LuaModulo = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaModuloMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaModuloMethodBrand">; +declare type LuaModuloMethod = ((right: TRight) => TReturn) & LuaExtension<"ModuloMethod">; /** * Calls to functions with this type are translated to `left ^ right`. @@ -207,8 +215,7 @@ declare type LuaModuloMethod = ((right: TRight) => TReturn) & L * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaPowerBrand">; +declare type LuaPower = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"Power">; /** * Calls to methods with this type are translated to `left ^ right`, where `left` is the object with the method. @@ -217,7 +224,7 @@ declare type LuaPower = ((left: TLeft, right: TRight) => * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaPowerMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaPowerMethodBrand">; +declare type LuaPowerMethod = ((right: TRight) => TReturn) & LuaExtension<"PowerMethod">; /** * Calls to functions with this type are translated to `left // right`. @@ -228,7 +235,7 @@ declare type LuaPowerMethod = ((right: TRight) => TReturn) & Lu * @param TReturn The resulting (return) type of the operation. */ declare type LuaFloorDivision = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaFloorDivisionBrand">; + LuaExtension<"FloorDivision">; /** * Calls to methods with this type are translated to `left // right`, where `left` is the object with the method. @@ -238,7 +245,7 @@ declare type LuaFloorDivision = ((left: TLeft, right: TR * @param TReturn The resulting (return) type of the operation. */ declare type LuaFloorDivisionMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaFloorDivisionMethodBrand">; + LuaExtension<"FloorDivisionMethod">; /** * Calls to functions with this type are translated to `left & right`. @@ -249,7 +256,7 @@ declare type LuaFloorDivisionMethod = ((right: TRight) => TRetu * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseAnd = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseAndBrand">; + LuaExtension<"BitwiseAnd">; /** * Calls to methods with this type are translated to `left & right`, where `left` is the object with the method. @@ -258,8 +265,7 @@ declare type LuaBitwiseAnd = ((left: TLeft, right: TRigh * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseAndMethodBrand">; +declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) & LuaExtension<"BitwiseAndMethod">; /** * Calls to functions with this type are translated to `left | right`. @@ -270,7 +276,7 @@ declare type LuaBitwiseAndMethod = ((right: TRight) => TReturn) * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseOr = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseOrBrand">; + LuaExtension<"BitwiseOr">; /** * Calls to methods with this type are translated to `left | right`, where `left` is the object with the method. @@ -279,8 +285,7 @@ declare type LuaBitwiseOr = ((left: TLeft, right: TRight * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseOrMethodBrand">; +declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) & LuaExtension<"BitwiseOrMethod">; /** * Calls to functions with this type are translated to `left ~ right`. @@ -291,7 +296,7 @@ declare type LuaBitwiseOrMethod = ((right: TRight) => TReturn) * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseExclusiveOr = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseExclusiveOrBrand">; + LuaExtension<"BitwiseExclusiveOr">; /** * Calls to methods with this type are translated to `left ~ right`, where `left` is the object with the method. @@ -301,7 +306,7 @@ declare type LuaBitwiseExclusiveOr = ((left: TLeft, righ * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseExclusiveOrMethodBrand">; + LuaExtension<"BitwiseExclusiveOrMethod">; /** * Calls to functions with this type are translated to `left << right`. @@ -312,7 +317,7 @@ declare type LuaBitwiseExclusiveOrMethod = ((right: TRight) => * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseLeftShift = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseLeftShiftBrand">; + LuaExtension<"BitwiseLeftShift">; /** * Calls to methods with this type are translated to `left << right`, where `left` is the object with the method. @@ -322,7 +327,7 @@ declare type LuaBitwiseLeftShift = ((left: TLeft, right: * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseLeftShiftMethodBrand">; + LuaExtension<"BitwiseLeftShiftMethod">; /** * Calls to functions with this type are translated to `left >> right`. @@ -333,7 +338,7 @@ declare type LuaBitwiseLeftShiftMethod = ((right: TRight) => TR * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseRightShift = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseRightShiftBrand">; + LuaExtension<"BitwiseRightShift">; /** * Calls to methods with this type are translated to `left >> right`, where `left` is the object with the method. @@ -343,7 +348,7 @@ declare type LuaBitwiseRightShift = ((left: TLeft, right * @param TReturn The resulting (return) type of the operation. */ declare type LuaBitwiseRightShiftMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaBitwiseRightShiftMethodBrand">; + LuaExtension<"BitwiseRightShiftMethod">; /** * Calls to functions with this type are translated to `left .. right`. @@ -353,8 +358,7 @@ declare type LuaBitwiseRightShiftMethod = ((right: TRight) => T * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaConcatBrand">; +declare type LuaConcat = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"Concat">; /** * Calls to methods with this type are translated to `left .. right`, where `left` is the object with the method. @@ -363,7 +367,7 @@ declare type LuaConcat = ((left: TLeft, right: TRight) = * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaConcatMethod = ((right: TRight) => TReturn) & LuaExtension<"__luaConcatMethodBrand">; +declare type LuaConcatMethod = ((right: TRight) => TReturn) & LuaExtension<"ConcatMethod">; /** * Calls to functions with this type are translated to `left < right`. @@ -373,8 +377,7 @@ declare type LuaConcatMethod = ((right: TRight) => TReturn) & L * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaLessThanBrand">; +declare type LuaLessThan = ((left: TLeft, right: TRight) => TReturn) & LuaExtension<"LessThan">; /** * Calls to methods with this type are translated to `left < right`, where `left` is the object with the method. @@ -383,8 +386,7 @@ declare type LuaLessThan = ((left: TLeft, right: TRight) * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLessThanMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaLessThanMethodBrand">; +declare type LuaLessThanMethod = ((right: TRight) => TReturn) & LuaExtension<"LessThanMethod">; /** * Calls to functions with this type are translated to `left > right`. @@ -395,7 +397,7 @@ declare type LuaLessThanMethod = ((right: TRight) => TReturn) & * @param TReturn The resulting (return) type of the operation. */ declare type LuaGreaterThan = ((left: TLeft, right: TRight) => TReturn) & - LuaExtension<"__luaGreaterThanBrand">; + LuaExtension<"GreaterThan">; /** * Calls to methods with this type are translated to `left > right`, where `left` is the object with the method. @@ -404,8 +406,7 @@ declare type LuaGreaterThan = ((left: TLeft, right: TRig * @param TRight The type of the right-hand-side of the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & - LuaExtension<"__luaGreaterThanMethodBrand">; +declare type LuaGreaterThanMethod = ((right: TRight) => TReturn) & LuaExtension<"GreaterThanMethod">; /** * Calls to functions with this type are translated to `-operand`. @@ -414,7 +415,7 @@ declare type LuaGreaterThanMethod = ((right: TRight) => TReturn * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegation = ((operand: TOperand) => TReturn) & LuaExtension<"__luaNegationBrand">; +declare type LuaNegation = ((operand: TOperand) => TReturn) & LuaExtension<"Negation">; /** * Calls to method with this type are translated to `-operand`, where `operand` is the object with the method. @@ -422,7 +423,7 @@ declare type LuaNegation = ((operand: TOperand) => TReturn) & * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"__luaNegationMethodBrand">; +declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"NegationMethod">; /** * Calls to functions with this type are translated to `~operand`. @@ -431,7 +432,7 @@ declare type LuaNegationMethod = (() => TReturn) & LuaExtension<"__luaN * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & LuaExtension<"__luaBitwiseNotBrand">; +declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) & LuaExtension<"BitwiseNot">; /** * Calls to method with this type are translated to `~operand`, where `operand` is the object with the method. @@ -439,7 +440,7 @@ declare type LuaBitwiseNot = ((operand: TOperand) => TReturn) * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"__luaBitwiseNotMethodBrand">; +declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"BitwiseNotMethod">; /** * Calls to functions with this type are translated to `#operand`. @@ -448,7 +449,7 @@ declare type LuaBitwiseNotMethod = (() => TReturn) & LuaExtension<"__lu * @param TOperand The type of the value in the operation. * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLength = ((operand: TOperand) => TReturn) & LuaExtension<"__luaLengthBrand">; +declare type LuaLength = ((operand: TOperand) => TReturn) & LuaExtension<"Length">; /** * Calls to method with this type are translated to `#operand`, where `operand` is the object with the method. @@ -456,7 +457,7 @@ declare type LuaLength = ((operand: TOperand) => TReturn) & L * * @param TReturn The resulting (return) type of the operation. */ -declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"__luaLengthMethodBrand">; +declare type LuaLengthMethod = (() => TReturn) & LuaExtension<"LengthMethod">; /** * Calls to functions with this type are translated to `table[key]`. @@ -470,7 +471,7 @@ declare type LuaTableGet TValue) & - LuaExtension<"__luaTableGetBrand">; + LuaExtension<"TableGet">; /** * Calls to methods with this type are translated to `table[key]`, where `table` is the object with the method. @@ -480,7 +481,7 @@ declare type LuaTableGet = ((key: TKey) => TValue) & - LuaExtension<"__luaTableGetMethodBrand">; + LuaExtension<"TableGetMethod">; /** * Calls to functions with this type are translated to `table[key] = value`. @@ -495,7 +496,7 @@ declare type LuaTableSet void) & - LuaExtension<"__luaTableSetBrand">; + LuaExtension<"TableSet">; /** * Calls to methods with this type are translated to `table[key] = value`, where `table` is the object with the method. @@ -505,7 +506,7 @@ declare type LuaTableSet = ((key: TKey, value: TValue) => void) & - LuaExtension<"__luaTableSetMethodBrand">; + LuaExtension<"TableSetMethod">; /** * Calls to functions with this type are translated to `table[key] = true`. @@ -515,15 +516,14 @@ declare type LuaTableSetMethod = ((key: TKey, va * @param TKey The type of the key to use to access the table. */ declare type LuaTableAddKey = ((table: TTable, key: TKey) => void) & - LuaExtension<"__luaTableAddKeyBrand">; + LuaExtension<"TableAddKey">; /** * Calls to methods with this type are translated to `table[key] = true`, where `table` is the object with the method. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions * @param TKey The type of the key to use to access the table. */ -declare type LuaTableAddKeyMethod = ((key: TKey) => void) & - LuaExtension<"__luaTableAddKeyMethodBrand">; +declare type LuaTableAddKeyMethod = ((key: TKey) => void) & LuaExtension<"TableAddKeyMethod">; /** * Calls to functions with this type are translated to `table[key] ~= nil`. @@ -533,7 +533,7 @@ declare type LuaTableAddKeyMethod = ((key: TKey) => void * @param TKey The type of the key to use to access the table. */ declare type LuaTableHas = ((table: TTable, key: TKey) => boolean) & - LuaExtension<"__luaTableHasBrand">; + LuaExtension<"TableHas">; /** * Calls to methods with this type are translated to `table[key] ~= nil`, where `table` is the object with the method. @@ -541,8 +541,7 @@ declare type LuaTableHas = ((ta * * @param TKey The type of the key to use to access the table. */ -declare type LuaTableHasMethod = ((key: TKey) => boolean) & - LuaExtension<"__luaTableHasMethodBrand">; +declare type LuaTableHasMethod = ((key: TKey) => boolean) & LuaExtension<"TableHasMethod">; /** * Calls to functions with this type are translated to `table[key] = nil`. @@ -552,7 +551,7 @@ declare type LuaTableHasMethod = ((key: TKey) => boolean * @param TKey The type of the key to use to access the table. */ declare type LuaTableDelete = ((table: TTable, key: TKey) => boolean) & - LuaExtension<"__luaTableDeleteBrand">; + LuaExtension<"TableDelete">; /** * Calls to methods with this type are translated to `table[key] = nil`, where `table` is the object with the method. @@ -561,7 +560,7 @@ declare type LuaTableDelete = ( * @param TKey The type of the key to use to access the table. */ declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & - LuaExtension<"__luaTableDeleteMethodBrand">; + LuaExtension<"TableDeleteMethod">; /** * A convenience type for working directly with a Lua table. @@ -589,7 +588,7 @@ declare type LuaTableConstructor = (new ) & - LuaExtension<"__luaTableNewBrand">; + LuaExtension<"TableNew">; /** * A convenience type for working directly with a Lua table. @@ -623,8 +622,7 @@ declare interface LuaMap extends LuaPa * @param K The type of the keys used to access the table. * @param V The type of the values stored in the table. */ -declare const LuaMap: (new () => LuaMap) & - LuaExtension<"__luaTableNewBrand">; +declare const LuaMap: (new () => LuaMap) & LuaExtension<"TableNew">; /** * Readonly version of {@link LuaMap}. @@ -655,7 +653,7 @@ declare interface LuaSet extends LuaPairsKeyIte * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions * @param T The type of the keys used to access the table. */ -declare const LuaSet: (new () => LuaSet) & LuaExtension<"__luaTableNewBrand">; +declare const LuaSet: (new () => LuaSet) & LuaExtension<"TableNew">; /** * Readonly version of {@link LuaSet}. diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 5c9700097..b22ee031a 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -37,6 +37,7 @@ export interface TypeScriptToLuaOptions { sourceMapTraceback?: boolean; tstlVerbose?: boolean; lua51AllowTryCatchInAsyncAwait?: boolean; + measurePerformance?: boolean; } export type CompilerOptions = OmitIndexSignature & diff --git a/src/cli/parse.ts b/src/cli/parse.ts index 7c17a9177..a49510780 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -99,6 +99,11 @@ export const optionDeclarations: CommandLineOption[] = [ description: "Always allow try/catch in async/await functions for Lua 5.1.", type: "boolean", }, + { + name: "measurePerformance", + description: "Measure performance of the tstl compiler.", + type: "boolean", + }, ]; export function updateParsedConfigFile(parsedConfigFile: ts.ParsedCommandLine): ParsedCommandLine { diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index a14c8917a..76b7e5008 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -2,7 +2,6 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import * as tstl from ".."; import * as path from "path"; -import { getUsedLuaLibFeatures } from "../transformation/utils/lualib"; import { LuaLibFeature, LuaLibModulesInfo, luaLibModulesInfoFileName, resolveRecursiveLualibFeatures } from "../LuaLib"; import { EmitHost, ProcessedFile } from "../transpilation/utils"; import { @@ -72,7 +71,7 @@ class LuaLibPlugin implements tstl.Plugin { // Transpile file as normal with tstl const fileResult = context.superTransformNode(file)[0] as tstl.File; - const usedFeatures = new Set(getUsedLuaLibFeatures(context)); + const usedFeatures = new Set(context.usedLuaLibFeatures); // Get all imports in file const importNames = new Set(); diff --git a/src/measure-performance.ts b/src/measure-performance.ts new file mode 100644 index 000000000..1d66af7e8 --- /dev/null +++ b/src/measure-performance.ts @@ -0,0 +1,83 @@ +import { performance } from "perf_hooks"; + +// We use our own performance hooks implementation for easier use, but also call node's performance hooks, so it shows up in the profiler. + +let enabled = false; +const marks = new Map(); +const durations = new Map(); + +function timestamp() { + return performance.now(); +} + +/** + * Marks a performance event, with the given markName. + */ +function mark(markName: string) { + if (enabled) { + marks.set(markName, timestamp()); + performance.mark(markName); + } +} + +/** + * Adds a performance measurement with the specified name. + * + * @param measureName The name of the performance measurement. + * @param startMarkName The name of the starting mark + * @param endMarkName The name of the ending mark + */ +function measure(measureName: string, startMarkName: string, endMarkName: string) { + if (enabled) { + const end = marks.get(endMarkName) ?? timestamp(); + const start = marks.get(startMarkName) ?? performance.timeOrigin; + const previousDuration = durations.get(measureName) ?? 0; + durations.set(measureName, previousDuration + (end - start)); + performance.measure(measureName, startMarkName, endMarkName); + } +} + +/** + * Starts a performance measurement section. + * @param name name of the measurement + */ +export function startSection(name: string) { + mark("start " + name); +} + +/** + * Ends a performance measurement section. + * @param name name of the measurement + */ +export function endSection(name: string) { + mark("end " + name); + measure(name, "start " + name, "end " + name); +} + +export function isMeasurementEnabled() { + return enabled; +} + +export function enableMeasurement() { + if (!enabled) { + enabled = true; + } +} + +export function disableMeasurement() { + if (enabled) { + enabled = false; + marks.clear(); + durations.clear(); + } +} + +export function forEachMeasure(callback: (measureName: string, duration: number) => void) { + durations.forEach((duration, measureName) => callback(measureName, duration)); +} + +export function getTotalDuration() { + let total = 0; + forEachMeasure((_, duration) => (total += duration)); + return total; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 2ecf3336a..9eeca1a1c 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -4,7 +4,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../visitors/call"; -import { isStringType, isNumberType, findFirstNonOuterParent } from "../utils/typescript"; +import { findFirstNonOuterParent, typeAlwaysHasSomeOfFlags } from "../utils/typescript"; import { moveToPrecedingTemp } from "../visitors/expression-list"; import { isUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -145,7 +145,10 @@ export function transformArrayPrototypeCall( case "join": const callerType = context.checker.getTypeAtLocation(calledMethod.expression); const elementType = context.checker.getElementTypeOfArrayType(callerType); - if (elementType && (isStringType(context, elementType) || isNumberType(context, elementType))) { + if ( + elementType && + typeAlwaysHasSomeOfFlags(context, elementType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike) + ) { const defaultSeparatorLiteral = lua.createStringLiteral(","); const param = params[0]; const parameters = [ diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 79f359bbd..4d882b293 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -5,24 +5,27 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isNumberType } from "../utils/typescript"; import { transformArguments } from "../visitors/call"; -export function transformGlobalCall( +export function tryTransformBuiltinGlobalCall( context: TransformationContext, - node: ts.CallExpression + node: ts.CallExpression, + expressionType: ts.Type ): lua.Expression | undefined { - const signature = context.checker.getResolvedSignature(node); - const parameters = transformArguments(context, node.arguments, signature); - const expressionType = context.checker.getTypeAtLocation(node.expression); + function getParameters() { + const signature = context.checker.getResolvedSignature(node); + return transformArguments(context, node.arguments, signature); + } + const name = expressionType.symbol.name; switch (name) { case "SymbolConstructor": - return transformLuaLibFunction(context, LuaLibFeature.Symbol, node, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.Symbol, node, ...getParameters()); case "NumberConstructor": - return transformLuaLibFunction(context, LuaLibFeature.Number, node, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.Number, node, ...getParameters()); case "isNaN": case "isFinite": const numberParameters = isNumberType(context, expressionType) - ? parameters - : [transformLuaLibFunction(context, LuaLibFeature.Number, undefined, ...parameters)]; + ? getParameters() + : [transformLuaLibFunction(context, LuaLibFeature.Number, undefined, ...getParameters())]; return transformLuaLibFunction( context, @@ -31,8 +34,8 @@ export function transformGlobalCall( ...numberParameters ); case "parseFloat": - return transformLuaLibFunction(context, LuaLibFeature.ParseFloat, node, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ParseFloat, node, ...getParameters()); case "parseInt": - return transformLuaLibFunction(context, LuaLibFeature.ParseInt, node, ...parameters); + return transformLuaLibFunction(context, LuaLibFeature.ParseInt, node, ...getParameters()); } } diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index bc3be66e6..f7ed149b9 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -5,22 +5,20 @@ import { createNaN } from "../utils/lua-ast"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { getIdentifierSymbolId } from "../utils/symbols"; import { - hasStandardLibrarySignature, - isArrayType, - isFunctionType, - isNullableType, - isNumberType, isStandardLibraryType, + isStandardLibraryDeclaration, isStringType, + isArrayType, + isFunctionType, } from "../utils/typescript"; import { getCalledExpression } from "../visitors/call"; import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; -import { transformGlobalCall } from "./global"; +import { tryTransformBuiltinGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; -import { transformObjectConstructorCall, transformObjectPrototypeCall } from "./object"; +import { transformObjectConstructorCall, tryTransformObjectPrototypeCall } from "./object"; import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; @@ -33,10 +31,10 @@ export function transformBuiltinPropertyAccessExpression( const ownerType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { - switch (node.expression.text) { + switch (ownerType.symbol.name) { case "Math": return transformMathProperty(context, node); - case "Symbol": + case "SymbolConstructor": importLuaLibFeature(context, LuaLibFeature.Symbol); } } @@ -56,104 +54,105 @@ export function transformBuiltinPropertyAccessExpression( export function transformBuiltinCallExpression( context: TransformationContext, - node: ts.CallExpression, - isOptionalCall: boolean + node: ts.CallExpression ): lua.Expression | undefined { - const unsupportedOptionalCall = () => { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - }; const expressionType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, expressionType, undefined)) { checkForLuaLibType(context, expressionType); - const result = transformGlobalCall(context, node); - if (result) { - if (isOptionalCall) return unsupportedOptionalCall(); - return result; - } + const result = tryTransformBuiltinGlobalCall(context, node, expressionType); + if (result) return result; } const calledMethod = ts.getOriginalNode(getCalledExpression(node)); - if (!ts.isPropertyAccessExpression(calledMethod)) { - return; + if (ts.isPropertyAccessExpression(calledMethod)) { + const globalResult = tryTransformBuiltinGlobalMethodCall(context, node, calledMethod); + if (globalResult) return globalResult; + + const prototypeResult = tryTransformBuiltinPropertyCall(context, node, calledMethod); + if (prototypeResult) return prototypeResult; + + // object prototype call may work even without resolved signature/type (which the other builtin calls use) + // e.g. (foo as any).toString() + // prototype methods take precedence (e.g. number.toString(2)) + const objectResult = tryTransformObjectPrototypeCall(context, node, calledMethod); + if (objectResult) return objectResult; } +} - const isOptionalAccess = calledMethod.questionDotToken; - // If the function being called is of type owner.func, get the type of owner +function tryTransformBuiltinGlobalMethodCall( + context: TransformationContext, + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression +) { const ownerType = context.checker.getTypeAtLocation(calledMethod.expression); - - if (isStandardLibraryType(context, ownerType, undefined)) { - const symbol = ownerType.getSymbol(); - switch (symbol?.name) { - case "ArrayConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformArrayConstructorCall(context, node, calledMethod); - case "Console": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformConsoleCall(context, node, calledMethod); - case "Math": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformMathCall(context, node, calledMethod); - case "StringConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformStringConstructorCall(context, node, calledMethod); - case "ObjectConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformObjectConstructorCall(context, node, calledMethod); - case "SymbolConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformSymbolConstructorCall(context, node, calledMethod); - case "NumberConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformNumberConstructorCall(context, node, calledMethod); - case "PromiseConstructor": - if (isOptionalCall || isOptionalAccess) return unsupportedOptionalCall(); - return transformPromiseConstructorCall(context, node, calledMethod); - } - } - - const isStringFunction = - isStringType(context, ownerType) || - (calledMethod.questionDotToken && isNullableType(context, ownerType, isStringType)); - if (isStringFunction && hasStandardLibrarySignature(context, node)) { - if (isOptionalCall) return unsupportedOptionalCall(); - return transformStringPrototypeCall(context, node, calledMethod); - } - - const isNumberFunction = - isNumberType(context, ownerType) || - (calledMethod.questionDotToken && isNullableType(context, ownerType, isNumberType)); - if (isNumberFunction && hasStandardLibrarySignature(context, node)) { - if (isOptionalCall) return unsupportedOptionalCall(); - return transformNumberPrototypeCall(context, node, calledMethod); - } - - const isArrayFunction = - isArrayType(context, ownerType) || - (calledMethod.questionDotToken && isNullableType(context, ownerType, isArrayType)); - if (isArrayFunction && hasStandardLibrarySignature(context, node)) { - if (isOptionalCall) return unsupportedOptionalCall(); - return transformArrayPrototypeCall(context, node, calledMethod); + if (!isStandardLibraryType(context, ownerType, undefined)) return; + + const ownerSymbol = ownerType.symbol; + if (!ownerSymbol || ownerSymbol.parent) return; + + let result: lua.Expression | undefined; + switch (ownerSymbol.name) { + case "ArrayConstructor": + result = transformArrayConstructorCall(context, node, calledMethod); + break; + case "Console": + result = transformConsoleCall(context, node, calledMethod); + break; + case "Math": + result = transformMathCall(context, node, calledMethod); + break; + case "StringConstructor": + result = transformStringConstructorCall(context, node, calledMethod); + break; + case "ObjectConstructor": + result = transformObjectConstructorCall(context, node, calledMethod); + break; + case "SymbolConstructor": + result = transformSymbolConstructorCall(context, node, calledMethod); + break; + case "NumberConstructor": + result = transformNumberConstructorCall(context, node, calledMethod); + break; + case "PromiseConstructor": + result = transformPromiseConstructorCall(context, node, calledMethod); + break; } - - const isFunctionFunction = - isFunctionType(ownerType) || - (calledMethod.questionDotToken && isNullableType(context, ownerType, (_, t) => isFunctionType(t))); - if (isFunctionFunction && hasStandardLibrarySignature(context, node)) { - if (isOptionalCall) return unsupportedOptionalCall(); - return transformFunctionPrototypeCall(context, node, calledMethod); + if (result && calledMethod.questionDotToken) { + // e.g. console?.log() + context.diagnostics.push(unsupportedBuiltinOptionalCall(calledMethod)); } + return result; +} - const objectResult = transformObjectPrototypeCall(context, node, calledMethod); - if (objectResult) { - if (isOptionalCall) return unsupportedOptionalCall(); - return objectResult; +function tryTransformBuiltinPropertyCall( + context: TransformationContext, + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression +) { + const signatureDeclaration = context.checker.getResolvedSignature(node)?.declaration; + if (!signatureDeclaration || !isStandardLibraryDeclaration(context, signatureDeclaration)) return; + + const callSymbol = context.checker.getTypeAtLocation(signatureDeclaration).symbol; + const ownerSymbol = callSymbol.parent; + if (!ownerSymbol || ownerSymbol.parent) return; + + switch (ownerSymbol.name) { + case "String": + return transformStringPrototypeCall(context, node, calledMethod); + case "Number": + return transformNumberPrototypeCall(context, node, calledMethod); + case "Array": + case "ReadonlyArray": + return transformArrayPrototypeCall(context, node, calledMethod); + case "Function": + return transformFunctionPrototypeCall(context, node, calledMethod); } } export function transformBuiltinIdentifierExpression( context: TransformationContext, - node: ts.Identifier + node: ts.Identifier, + symbol: ts.Symbol | undefined ): lua.Expression | undefined { switch (node.text) { case "NaN": @@ -165,7 +164,7 @@ export function transformBuiltinIdentifierExpression( return lua.createTableIndexExpression(math, huge, node); case "globalThis": - return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node), "globalThis"); + return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node, symbol), "globalThis"); } } @@ -185,9 +184,10 @@ const builtinErrorTypeNames = new Set([ ]); export function checkForLuaLibType(context: TransformationContext, type: ts.Type): void { - if (!type.symbol) return; + const symbol = type.symbol; + if (!symbol || symbol.parent) return; + const name = symbol.name; - const name = context.checker.getFullyQualifiedName(type.symbol); switch (name) { case "Map": case "MapConstructor": @@ -205,6 +205,10 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type case "WeakSetConstructor": importLuaLibFeature(context, LuaLibFeature.WeakSet); return; + case "Promise": + case "PromiseConstructor": + importLuaLibFeature(context, LuaLibFeature.Promise); + return; } if (builtinErrorTypeNames.has(name)) { diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index c23341b97..cd386ce19 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -35,13 +35,11 @@ export function transformObjectConstructorCall( } } -export function transformObjectPrototypeCall( +export function tryTransformObjectPrototypeCall( context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression ): lua.Expression | undefined { - const signature = context.checker.getResolvedSignature(node); - const name = calledMethod.name.text; switch (name) { case "toString": @@ -53,6 +51,7 @@ export function transformObjectPrototypeCall( ); case "hasOwnProperty": const expr = context.transformExpression(calledMethod.expression); + const signature = context.checker.getResolvedSignature(node); const parameters = transformArguments(context, node.arguments, signature); const rawGetIdentifier = lua.createIdentifier("rawget"); const rawGetCall = lua.createCallExpression(rawGetIdentifier, [expr, ...parameters]); diff --git a/src/transformation/builtins/promise.ts b/src/transformation/builtins/promise.ts index 07a291d8b..19c7284e7 100644 --- a/src/transformation/builtins/promise.ts +++ b/src/transformation/builtins/promise.ts @@ -3,12 +3,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { importLuaLibFeature, LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { isStandardLibraryType } from "../utils/typescript"; import { transformArguments } from "../visitors/call"; +import { isStandardLibraryType } from "../utils/typescript"; export function isPromiseClass(context: TransformationContext, node: ts.Identifier) { + if (node.text !== "Promise") return false; const type = context.checker.getTypeAtLocation(node); - return isStandardLibraryType(context, type, undefined) && node.text === "Promise"; + return isStandardLibraryType(context, type, undefined); } export function createPromiseIdentifier(original: ts.Node) { diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 95f35133f..711f59230 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -145,6 +145,8 @@ export function transformStringPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.StringPadStart, node, caller, ...params); case "padEnd": return transformLuaLibFunction(context, LuaLibFeature.StringPadEnd, node, caller, ...params); + case "toString": + return; // will be handled by transformObjectPrototypeCall default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "string", expressionName)); } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 9a5af84c9..8fda0bc23 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -3,9 +3,13 @@ import { CompilerOptions, LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { assert, castArray } from "../../utils"; import { unsupportedNodeKind } from "../utils/diagnostics"; -import { unwrapVisitorResult } from "../utils/lua-ast"; +import { unwrapVisitorResult, OneToManyVisitorResult } from "../utils/lua-ast"; import { createSafeName } from "../utils/safe-names"; -import { ExpressionLikeNode, ObjectVisitor, StatementLikeNode, VisitorMap } from "./visitors"; +import { ExpressionLikeNode, StatementLikeNode, VisitorMap, FunctionVisitor } from "./visitors"; +import { SymbolInfo } from "../utils/symbols"; +import { LuaLibFeature } from "../../LuaLib"; +import { Scope, ScopeType } from "../utils/scope"; +import { ClassSuperInfo } from "../visitors/class"; export const tempSymbolId = -1 as lua.SymbolId; @@ -49,71 +53,82 @@ export class TransformationContext { this.resolver = this.checker.getEmitResolver(originalSourceFile); } - private currentNodeVisitors: Array> = []; + private currentNodeVisitors: ReadonlyArray> = []; + private currentNodeVisitorsIndex = 0; + private nextTempId = 0; - public transformNode(node: ts.Node): lua.Node[]; + public transformNode(node: ts.Node): lua.Node[] { + return unwrapVisitorResult(this.transformNodeRaw(node)); + } + /** @internal */ - // eslint-disable-next-line @typescript-eslint/unified-signatures - public transformNode(node: ts.Node, isExpression?: boolean): lua.Node[]; - public transformNode(node: ts.Node, isExpression?: boolean): lua.Node[] { + public transformNodeRaw(node: ts.Node, isExpression?: boolean) { // TODO: Move to visitors? if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { return []; } const nodeVisitors = this.visitorMap.get(node.kind); - if (!nodeVisitors || nodeVisitors.length === 0) { + if (!nodeVisitors) { this.diagnostics.push(unsupportedNodeKind(node, node.kind)); return isExpression ? [lua.createNilLiteral()] : []; } const previousNodeVisitors = this.currentNodeVisitors; - this.currentNodeVisitors = [...nodeVisitors]; + const previousNodeVisitorsIndex = this.currentNodeVisitorsIndex; + this.currentNodeVisitors = nodeVisitors; + this.currentNodeVisitorsIndex = nodeVisitors.length - 1; - const visitor = this.currentNodeVisitors.pop()!; - const result = unwrapVisitorResult(visitor.transform(node, this)); + const visitor = this.currentNodeVisitors[this.currentNodeVisitorsIndex]; + const result = visitor(node, this); this.currentNodeVisitors = previousNodeVisitors; + this.currentNodeVisitorsIndex = previousNodeVisitorsIndex; return result; } public superTransformNode(node: ts.Node): lua.Node[] { - if (this.currentNodeVisitors.length === 0) { + return unwrapVisitorResult(this.doSuperTransformNode(node)); + } + + private doSuperTransformNode(node: ts.Node): OneToManyVisitorResult { + if (--this.currentNodeVisitorsIndex < 0) { throw new Error(`There is no super transform for ${ts.SyntaxKind[node.kind]} visitor`); } - const visitor = this.currentNodeVisitors.pop()!; - return unwrapVisitorResult(visitor.transform(node, this)); + const visitor = this.currentNodeVisitors[this.currentNodeVisitorsIndex]; + return unwrapVisitorResult(visitor(node, this)); } public transformExpression(node: ExpressionLikeNode): lua.Expression { - const [result] = this.transformNode(node, true); + const result = this.transformNodeRaw(node, true); + return this.assertIsExpression(node, result); + } + private assertIsExpression(node: ExpressionLikeNode, result: OneToManyVisitorResult): lua.Expression { if (result === undefined) { throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`); } - + if (Array.isArray(result)) { + return result[0] as lua.Expression; + } return result as lua.Expression; } public superTransformExpression(node: ExpressionLikeNode): lua.Expression { - const [result] = this.superTransformNode(node); - - if (result === undefined) { - throw new Error(`Expression visitor for node type ${ts.SyntaxKind[node.kind]} did not return any result.`); - } - - return result as lua.Expression; + const result = this.doSuperTransformNode(node); + return this.assertIsExpression(node, result); } public transformStatements(node: StatementLikeNode | readonly StatementLikeNode[]): lua.Statement[] { return castArray(node).flatMap(n => { this.pushPrecedingStatements(); const statements = this.transformNode(n) as lua.Statement[]; - statements.unshift(...this.popPrecedingStatements()); - return statements; + const result = this.popPrecedingStatements(); + result.push(...statements); + return result; }); } @@ -121,8 +136,9 @@ export class TransformationContext { return castArray(node).flatMap(n => { this.pushPrecedingStatements(); const statements = this.superTransformNode(n) as lua.Statement[]; - statements.unshift(...this.popPrecedingStatements()); - return statements; + const result = this.popPrecedingStatements(); + result.push(...statements); + return result; }); } @@ -139,19 +155,21 @@ export class TransformationContext { public addPrecedingStatements(statements: lua.Statement | lua.Statement[]) { const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1]; assert(precedingStatements); - if (!Array.isArray(statements)) { - statements = [statements]; + if (Array.isArray(statements)) { + precedingStatements.push(...statements); + } else { + precedingStatements.push(statements); } - precedingStatements.push(...statements); } public prependPrecedingStatements(statements: lua.Statement | lua.Statement[]) { const precedingStatements = this.precedingStatementsStack[this.precedingStatementsStack.length - 1]; assert(precedingStatements); - if (!Array.isArray(statements)) { - statements = [statements]; + if (Array.isArray(statements)) { + precedingStatements.unshift(...statements); + } else { + precedingStatements.unshift(statements); } - precedingStatements.unshift(...statements); } public createTempName(prefix = "temp") { @@ -212,4 +230,39 @@ export class TransformationContext { const name = this.getTempNameForNode(node); return lua.createIdentifier(this.createTempName(name), node, tempSymbolId); } + + // other utils + + private lastSymbolId = 0; + public readonly symbolInfoMap = new Map(); + public readonly symbolIdMaps = new Map(); + + public nextSymbolId(): lua.SymbolId { + return ++this.lastSymbolId as lua.SymbolId; + } + + public readonly usedLuaLibFeatures = new Set(); + + public readonly scopeStack: Scope[] = []; + private lastScopeId = 0; + + public pushScope(type: ScopeType): Scope { + const scope = { type, id: ++this.lastScopeId }; + this.scopeStack.push(scope); + return scope; + } + + public popScope(): Scope { + const scope = this.scopeStack.pop(); + assert(scope); + return scope; + } + + // Static context -> namespace dictionary keeping the current namespace for each transformation context + // see visitors/namespace.ts + /** @internal */ + public currentNamespaces: ts.ModuleDeclaration | undefined; + + /** @internal */ + public classSuperInfos: ClassSuperInfo[] = []; } diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index df7cd7acb..fff7441e5 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -162,4 +162,4 @@ export interface ObjectVisitor { } export type Visitors = { [P in keyof NodesBySyntaxKind]?: Visitor }; -export type VisitorMap = Map>>; +export type VisitorMap = Map>>; diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 5b6fca647..4580a3b80 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -5,14 +5,14 @@ import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./co import { standardVisitors } from "./visitors"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { - const visitorMap: VisitorMap = new Map(); + const objectVisitorMap: Map>> = new Map(); for (const visitors of [standardVisitors, ...customVisitors]) { const priority = visitors === standardVisitors ? -Infinity : 0; for (const [syntaxKindKey, visitor] of Object.entries(visitors)) { if (!visitor) continue; const syntaxKind = Number(syntaxKindKey) as ts.SyntaxKind; - const nodeVisitors = getOrUpdate(visitorMap, syntaxKind, () => []); + const nodeVisitors = getOrUpdate(objectVisitorMap, syntaxKind, () => []); const objectVisitor: ObjectVisitor = typeof visitor === "function" ? { transform: visitor, priority } : visitor; @@ -20,11 +20,14 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { } } - for (const nodeVisitors of visitorMap.values()) { - nodeVisitors.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0)); + const result: VisitorMap = new Map(); + for (const [kind, nodeVisitors] of objectVisitorMap) { + result.set( + kind, + nodeVisitors.sort((a, b) => (a.priority ?? 0) - (b.priority ?? 0)).map(visitor => visitor.transform) + ); } - - return visitorMap; + return result; } export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 2b2309941..0f25d8769 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -1,153 +1,107 @@ import * as ts from "typescript"; -import { TransformationContext } from "../context"; export enum AnnotationKind { - Extension = "extension", - MetaExtension = "metaExtension", CustomConstructor = "customConstructor", CompileMembersOnly = "compileMembersOnly", NoResolution = "noResolution", - PureAbstract = "pureAbstract", - Phantom = "phantom", - TupleReturn = "tupleReturn", - LuaIterator = "luaIterator", - LuaTable = "luaTable", NoSelf = "noSelf", NoSelfInFile = "noSelfInFile", - Vararg = "vararg", - ForRange = "forRange", } +const annotationValues = new Map(Object.values(AnnotationKind).map(k => [k.toLowerCase(), k])); + export interface Annotation { kind: AnnotationKind; args: string[]; } -function createAnnotation(name: string, args: string[]): Annotation | undefined { - const kind = Object.values(AnnotationKind).find(k => k.toLowerCase() === name.toLowerCase()); - if (kind !== undefined) { - return { kind, args }; - } -} - export type AnnotationsMap = Map; function collectAnnotations(source: ts.Symbol | ts.Signature, annotationsMap: AnnotationsMap): void { for (const tag of source.getJsDocTags()) { - const annotation = createAnnotation(tag.name, tag.text?.map(p => p.text) ?? []); - if (annotation) { - annotationsMap.set(annotation.kind, annotation); - } + const tagName = annotationValues.get(tag.name.toLowerCase()); + if (!tagName) continue; + const annotation: Annotation = { + kind: tag.name as AnnotationKind, + args: tag.text?.map(p => p.text) ?? [], + }; + annotationsMap.set(tagName, annotation); } } +const symbolAnnotations = new WeakMap(); + export function getSymbolAnnotations(symbol: ts.Symbol): AnnotationsMap { + const known = symbolAnnotations.get(symbol); + if (known) return known; + const annotationsMap: AnnotationsMap = new Map(); collectAnnotations(symbol, annotationsMap); + + symbolAnnotations.set(symbol, annotationsMap); return annotationsMap; } export function getTypeAnnotations(type: ts.Type): AnnotationsMap { + // types are not frequently repeatedly polled for annotations, so it's not worth caching them const annotationsMap: AnnotationsMap = new Map(); - - if (type.symbol) collectAnnotations(type.symbol, annotationsMap); - if (type.aliasSymbol) collectAnnotations(type.aliasSymbol, annotationsMap); - + if (type.symbol) { + getSymbolAnnotations(type.symbol).forEach((value, key) => { + annotationsMap.set(key, value); + }); + } + if (type.aliasSymbol) { + getSymbolAnnotations(type.aliasSymbol).forEach((value, key) => { + annotationsMap.set(key, value); + }); + } return annotationsMap; } +const nodeAnnotations = new WeakMap(); export function getNodeAnnotations(node: ts.Node): AnnotationsMap { - const annotationsMap: AnnotationsMap = new Map(); + const known = nodeAnnotations.get(node); + if (known) return known; - for (const tag of ts.getJSDocTags(node)) { - const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); - if (annotation) { - annotationsMap.set(annotation.kind, annotation); - } - } + const annotationsMap: AnnotationsMap = new Map(); + collectAnnotationsFromTags(annotationsMap, ts.getAllJSDocTags(node, ts.isJSDocUnknownTag)); + nodeAnnotations.set(node, annotationsMap); return annotationsMap; } +function collectAnnotationsFromTags(annotationsMap: AnnotationsMap, tags: readonly ts.JSDocTag[]) { + for (const tag of tags) { + const tagName = annotationValues.get(tag.tagName.text.toLowerCase()); + if (!tagName) continue; + annotationsMap.set(tagName, { kind: tagName, args: getTagArgsFromComment(tag) }); + } +} + +const fileAnnotations = new WeakMap(); export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { + const known = fileAnnotations.get(sourceFile); + if (known) return known; + const annotationsMap: AnnotationsMap = new Map(); if (sourceFile.statements.length > 0) { // Manually collect jsDoc because `getJSDocTags` includes tags only from closest comment const jsDoc = sourceFile.statements[0].jsDoc; if (jsDoc) { - for (const tag of jsDoc.flatMap(x => x.tags ?? [])) { - const tagName = tag.tagName.text; - const annotation = createAnnotation(tagName, getTagArgsFromComment(tag)); - if (annotation) { - annotationsMap.set(annotation.kind, annotation); + for (const jsDocElement of jsDoc) { + if (jsDocElement.tags) { + collectAnnotationsFromTags(annotationsMap, jsDocElement.tags); } } } } + fileAnnotations.set(sourceFile, annotationsMap); return annotationsMap; } -export function getSignatureAnnotations(context: TransformationContext, signature: ts.Signature): AnnotationsMap { - const annotationsMap: AnnotationsMap = new Map(); - collectAnnotations(signature, annotationsMap); - - // Function properties on interfaces have the JSDoc tags on the parent PropertySignature - const declaration = signature.getDeclaration(); - if (declaration?.parent && ts.isPropertySignature(declaration.parent)) { - const symbol = context.checker.getSymbolAtLocation(declaration.parent.name); - if (symbol) { - collectAnnotations(symbol, annotationsMap); - } - } - - return annotationsMap; -} - -export function isTupleReturnCall(context: TransformationContext, node: ts.Node): boolean { - if (!ts.isCallExpression(node)) { - return false; - } - - const signature = context.checker.getResolvedSignature(node); - if (signature) { - if (getSignatureAnnotations(context, signature).has(AnnotationKind.TupleReturn)) { - return true; - } - - // Only check function type for directive if it is declared as an interface or type alias - const declaration = signature.getDeclaration(); - const isInterfaceOrAlias = - declaration?.parent && - ((ts.isInterfaceDeclaration(declaration.parent) && ts.isCallSignatureDeclaration(declaration)) || - ts.isTypeAliasDeclaration(declaration.parent)); - if (!isInterfaceOrAlias) { - return false; - } - } - - const type = context.checker.getTypeAtLocation(node.expression); - return getTypeAnnotations(type).has(AnnotationKind.TupleReturn); -} - -export function isLuaIteratorType(context: TransformationContext, node: ts.Node): boolean { - const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(type).has(AnnotationKind.LuaIterator); -} - -export function isVarargType(context: TransformationContext, node: ts.Node): boolean { - const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(type).has(AnnotationKind.Vararg); -} - -export function isForRangeType(context: TransformationContext, node: ts.Node): boolean { - const type = context.checker.getTypeAtLocation(node); - return getTypeAnnotations(type).has(AnnotationKind.ForRange); -} - -export function getTagArgsFromComment(tag: ts.JSDocTag): string[] { +function getTagArgsFromComment(tag: ts.JSDocTag): string[] { if (tag.comment) { if (typeof tag.comment === "string") { return tag.comment.split(" "); diff --git a/src/transformation/utils/assignment-validation.ts b/src/transformation/utils/assignment-validation.ts index 15279bca2..d0f42d90a 100644 --- a/src/transformation/utils/assignment-validation.ts +++ b/src/transformation/utils/assignment-validation.ts @@ -34,15 +34,10 @@ export function validateAssignment( validateFunctionAssignment(context, node, fromType, toType, toName); - const fromTypeNode = context.checker.typeToTypeNode(fromType, undefined, undefined); - const toTypeNode = context.checker.typeToTypeNode(toType, undefined, undefined); - if (!fromTypeNode || !toTypeNode) { - return; - } - + const checker = context.checker; if ( - (ts.isArrayTypeNode(toTypeNode) || ts.isTupleTypeNode(toTypeNode)) && - (ts.isArrayTypeNode(fromTypeNode) || ts.isTupleTypeNode(fromTypeNode)) + (checker.isTupleType(toType) || checker.isArrayType(toType)) && + (checker.isTupleType(fromType) || checker.isArrayType(fromType)) ) { // Recurse into arrays/tuples const fromTypeArguments = (fromType as ts.TypeReference).typeArguments; @@ -58,33 +53,39 @@ export function validateAssignment( } } - if ( - (toType.flags & ts.TypeFlags.Object) !== 0 && - (ts.isTypeLiteralNode(toTypeNode) || - ((toType as ts.ObjectType).objectFlags & ts.ObjectFlags.ClassOrInterface) !== 0) && - toType.symbol && - toType.symbol.members && - fromType.symbol && - fromType.symbol.members - ) { + const fromMembers = fromType.symbol?.members; + const toMembers = toType.symbol?.members; + + if (fromMembers && toMembers) { // Recurse into interfaces - toType.symbol.members.forEach((toMember, escapedMemberName) => { - if (fromType.symbol.members) { - const fromMember = fromType.symbol.members.get(escapedMemberName); + if (toMembers.size < fromMembers.size) { + toMembers.forEach((toMember, escapedMemberName) => { + const fromMember = fromMembers.get(escapedMemberName); if (fromMember) { - const toMemberType = context.checker.getTypeOfSymbolAtLocation(toMember, node); - const fromMemberType = context.checker.getTypeOfSymbolAtLocation(fromMember, node); - const memberName = ts.unescapeLeadingUnderscores(escapedMemberName); - validateAssignment( - context, - node, - fromMemberType, - toMemberType, - toName ? `${toName}.${memberName}` : memberName - ); + validateMember(toMember, fromMember, escapedMemberName); } - } - }); + }); + } else { + fromMembers.forEach((fromMember, escapedMemberName) => { + const toMember = toMembers.get(escapedMemberName); + if (toMember) { + validateMember(toMember, fromMember, escapedMemberName); + } + }); + } + } + + function validateMember(toMember: ts.Symbol, fromMember: ts.Symbol, escapedMemberName: ts.__String): void { + const toMemberType = context.checker.getTypeOfSymbolAtLocation(toMember, node); + const fromMemberType = context.checker.getTypeOfSymbolAtLocation(fromMember, node); + const memberName = ts.unescapeLeadingUnderscores(escapedMemberName); + validateAssignment( + context, + node, + fromMemberType, + toMemberType, + toName ? `${toName}.${memberName}` : memberName + ); } } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index d0ecbd1d1..6520694ed 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -131,11 +131,7 @@ export const invalidMultiReturnAccess = createErrorDiagnosticFactory( "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); -export const invalidOperatorMappingUse = createErrorDiagnosticFactory( - "This function must always be directly called and cannot be referred to." -); - -export const invalidTableExtensionUse = createErrorDiagnosticFactory( +export const invalidCallExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 896f7e373..41e70d40f 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -5,10 +5,10 @@ import { AnnotationKind, getFileAnnotations, getNodeAnnotations } from "./annota import { findFirstNodeAbove, getAllCallSignatures, inferAssignedType } from "./typescript"; export enum ContextType { - None, - Void, - NonVoid, - Mixed, + None = 0, + Void = 1 << 0, + NonVoid = 1 << 1, + Mixed = Void | NonVoid, } function hasNoSelfAncestor(declaration: ts.Declaration): boolean { @@ -29,15 +29,26 @@ function hasNoSelfAncestor(declaration: ts.Declaration): boolean { } function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined { - return signatureDeclaration.parameters.find( - param => ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword - ); + const param = signatureDeclaration.parameters[0]; + if (param && ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + return param; + } } +const signatureDeclarationContextTypes = new WeakMap(); + export function getDeclarationContextType( - { program }: TransformationContext, + context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration ): ContextType { + const known = signatureDeclarationContextTypes.get(signatureDeclaration); + if (known !== undefined) return known; + const contextType = computeDeclarationContextType(context, signatureDeclaration); + signatureDeclarationContextTypes.set(signatureDeclaration, contextType); + return contextType; +} + +function computeDeclarationContextType(context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration) { const thisParameter = getExplicitThisParameter(signatureDeclaration); if (thisParameter) { // Explicit 'this' @@ -66,11 +77,7 @@ export function getDeclarationContextType( ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) ); - if (scopeDeclaration === undefined) { - return ContextType.NonVoid; - } - - if (getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) { + if (scopeDeclaration !== undefined && getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) { return ContextType.Void; } @@ -78,6 +85,7 @@ export function getDeclarationContextType( } // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. + const program = context.program; const options = program.getCompilerOptions() as CompilerOptions; if (options.noImplicitSelf) { const sourceFile = program.getSourceFile(signatureDeclaration.getSourceFile().fileName); @@ -99,60 +107,55 @@ export function getDeclarationContextType( } function reduceContextTypes(contexts: ContextType[]): ContextType { - const reducer = (a: ContextType, b: ContextType) => { - if (a === ContextType.None) { - return b; - } else if (b === ContextType.None) { - return a; - } else if (a !== b) { - return ContextType.Mixed; - } else { - return a; - } - }; - - return contexts.reduce(reducer, ContextType.None); + let type = ContextType.None; + for (const context of contexts) { + type |= context; + if (type === ContextType.Mixed) break; + } + return type; } -function getSignatureDeclarations( - context: TransformationContext, - signatures: readonly ts.Signature[] -): ts.SignatureDeclaration[] { - return signatures.flatMap(signature => { - const signatureDeclaration = signature.getDeclaration(); - let inferredType: ts.Type | undefined; - if ( - ts.isMethodDeclaration(signatureDeclaration) && - ts.isObjectLiteralExpression(signatureDeclaration.parent) && - !getExplicitThisParameter(signatureDeclaration) - ) { - inferredType = context.checker.getContextualTypeForObjectLiteralElement(signatureDeclaration); - } else if ( - (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && - !getExplicitThisParameter(signatureDeclaration) - ) { - // Infer type of function expressions/arrow functions - inferredType = inferAssignedType(context, signatureDeclaration); - } +function getSignatureDeclarations(context: TransformationContext, signature: ts.Signature): ts.SignatureDeclaration[] { + const signatureDeclaration = signature.getDeclaration(); + let inferredType: ts.Type | undefined; + if ( + ts.isMethodDeclaration(signatureDeclaration) && + ts.isObjectLiteralExpression(signatureDeclaration.parent) && + !getExplicitThisParameter(signatureDeclaration) + ) { + inferredType = context.checker.getContextualTypeForObjectLiteralElement(signatureDeclaration); + } else if ( + (ts.isFunctionExpression(signatureDeclaration) || ts.isArrowFunction(signatureDeclaration)) && + !getExplicitThisParameter(signatureDeclaration) + ) { + // Infer type of function expressions/arrow functions + inferredType = inferAssignedType(context, signatureDeclaration); + } - if (inferredType) { - const inferredSignatures = getAllCallSignatures(inferredType); - if (inferredSignatures.length > 0) { - return inferredSignatures.map(s => s.getDeclaration()); - } + if (inferredType) { + const inferredSignatures = getAllCallSignatures(inferredType); + if (inferredSignatures.length > 0) { + return inferredSignatures.map(s => s.getDeclaration()); } + } - return signatureDeclaration; - }); + return [signatureDeclaration]; } +const typeContextTypes = new WeakMap(); + export function getFunctionContextType(context: TransformationContext, type: ts.Type): ContextType { - if (type.isTypeParameter()) { - type = type.getConstraint() ?? type; - } + const known = typeContextTypes.get(type); + if (known !== undefined) return known; + const contextType = computeFunctionContextType(context, type); + typeContextTypes.set(type, contextType); + return contextType; +} - if (type.isUnion()) { - return reduceContextTypes(type.types.map(t => getFunctionContextType(context, t))); +function computeFunctionContextType(context: TransformationContext, type: ts.Type): ContextType { + if (type.isTypeParameter()) { + const constraint = type.getConstraint(); + if (constraint) return getFunctionContextType(context, constraint); } const signatures = context.checker.getSignaturesOfType(type, ts.SignatureKind.Call); @@ -160,6 +163,7 @@ export function getFunctionContextType(context: TransformationContext, type: ts. return ContextType.None; } - const signatureDeclarations = getSignatureDeclarations(context, signatures); - return reduceContextTypes(signatureDeclarations.map(s => getDeclarationContextType(context, s))); + return reduceContextTypes( + signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getDeclarationContextType(context, s)) + ); } diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 8b6b15859..f5e446195 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -3,142 +3,111 @@ import { TransformationContext } from "../context"; export enum ExtensionKind { MultiFunction = "MultiFunction", - MultiType = "MultiType", RangeFunction = "RangeFunction", VarargConstant = "VarargConstant", - IterableType = "IterableType", - PairsIterableType = "PairsIterableType", - PairsKeyIterableType = "PairsKeyIterableType", - AdditionOperatorType = "AdditionOperatorType", - AdditionOperatorMethodType = "AdditionOperatorMethodType", - SubtractionOperatorType = "SubtractionOperatorType", - SubtractionOperatorMethodType = "SubtractionOperatorMethodType", - MultiplicationOperatorType = "MultiplicationOperatorType", - MultiplicationOperatorMethodType = "MultiplicationOperatorMethodType", - DivisionOperatorType = "DivisionOperatorType", - DivisionOperatorMethodType = "DivisionOperatorMethodType", - ModuloOperatorType = "ModuloOperatorType", - ModuloOperatorMethodType = "ModuloOperatorMethodType", - PowerOperatorType = "PowerOperatorType", - PowerOperatorMethodType = "PowerOperatorMethodType", - FloorDivisionOperatorType = "FloorDivisionOperatorType", - FloorDivisionOperatorMethodType = "FloorDivisionOperatorMethodType", - BitwiseAndOperatorType = "BitwiseAndOperatorType", - BitwiseAndOperatorMethodType = "BitwiseAndOperatorMethodType", - BitwiseOrOperatorType = "BitwiseOrOperatorType", - BitwiseOrOperatorMethodType = "BitwiseOrOperatorMethodType", - BitwiseExclusiveOrOperatorType = "BitwiseExclusiveOrOperatorType", - BitwiseExclusiveOrOperatorMethodType = "BitwiseExclusiveOrOperatorMethodType", - BitwiseLeftShiftOperatorType = "BitwiseLeftShiftOperatorType", - BitwiseLeftShiftOperatorMethodType = "BitwiseLeftShiftOperatorMethodType", - BitwiseRightShiftOperatorType = "BitwiseRightShiftOperatorType", - BitwiseRightShiftOperatorMethodType = "BitwiseRightShiftOperatorMethodType", - ConcatOperatorType = "ConcatOperatorType", - ConcatOperatorMethodType = "ConcatOperatorMethodType", - LessThanOperatorType = "LessThanOperatorType", - LessThanOperatorMethodType = "LessThanOperatorMethodType", - GreaterThanOperatorType = "GreaterThanOperatorType", - GreaterThanOperatorMethodType = "GreaterThanOperatorMethodType", - NegationOperatorType = "NegationOperatorType", - NegationOperatorMethodType = "NegationOperatorMethodType", - BitwiseNotOperatorType = "BitwiseNotOperatorType", - BitwiseNotOperatorMethodType = "BitwiseNotOperatorMethodType", - LengthOperatorType = "LengthOperatorType", - LengthOperatorMethodType = "LengthOperatorMethodType", - TableNewType = "TableNewType", - TableDeleteType = "TableDeleteType", - TableDeleteMethodType = "TableDeleteMethodType", - TableGetType = "TableGetType", - TableGetMethodType = "TableGetMethodType", - TableHasType = "TableHasType", - TableHasMethodType = "TableHasMethodType", - TableSetType = "TableSetType", - TableSetMethodType = "TableSetMethodType", - TableAddType = "TableAddType", - TableAddMethodType = "TableAddMethodType", + AdditionOperatorType = "Addition", + AdditionOperatorMethodType = "AdditionMethod", + SubtractionOperatorType = "Subtraction", + SubtractionOperatorMethodType = "SubtractionMethod", + MultiplicationOperatorType = "Multiplication", + MultiplicationOperatorMethodType = "MultiplicationMethod", + DivisionOperatorType = "Division", + DivisionOperatorMethodType = "DivisionMethod", + ModuloOperatorType = "Modulo", + ModuloOperatorMethodType = "ModuloMethod", + PowerOperatorType = "Power", + PowerOperatorMethodType = "PowerMethod", + FloorDivisionOperatorType = "FloorDivision", + FloorDivisionOperatorMethodType = "FloorDivisionMethod", + BitwiseAndOperatorType = "BitwiseAnd", + BitwiseAndOperatorMethodType = "BitwiseAndMethod", + BitwiseOrOperatorType = "BitwiseOr", + BitwiseOrOperatorMethodType = "BitwiseOrMethod", + BitwiseExclusiveOrOperatorType = "BitwiseExclusiveOr", + BitwiseExclusiveOrOperatorMethodType = "BitwiseExclusiveOrMethod", + BitwiseLeftShiftOperatorType = "BitwiseLeftShift", + BitwiseLeftShiftOperatorMethodType = "BitwiseLeftShiftMethod", + BitwiseRightShiftOperatorType = "BitwiseRightShift", + BitwiseRightShiftOperatorMethodType = "BitwiseRightShiftMethod", + ConcatOperatorType = "Concat", + ConcatOperatorMethodType = "ConcatMethod", + LessThanOperatorType = "LessThan", + LessThanOperatorMethodType = "LessThanMethod", + GreaterThanOperatorType = "GreaterThan", + GreaterThanOperatorMethodType = "GreaterThanMethod", + NegationOperatorType = "Negation", + NegationOperatorMethodType = "NegationMethod", + BitwiseNotOperatorType = "BitwiseNot", + BitwiseNotOperatorMethodType = "BitwiseNotMethod", + LengthOperatorType = "Length", + LengthOperatorMethodType = "LengthMethod", + TableNewType = "TableNew", + TableDeleteType = "TableDelete", + TableDeleteMethodType = "TableDeleteMethod", + TableGetType = "TableGet", + TableGetMethodType = "TableGetMethod", + TableHasType = "TableHas", + TableHasMethodType = "TableHasMethod", + TableSetType = "TableSet", + TableSetMethodType = "TableSetMethod", + TableAddKeyType = "TableAddKey", + TableAddKeyMethodType = "TableAddKeyMethod", } +const extensionValues: Set = new Set(Object.values(ExtensionKind)); -const extensionKindToValueName: { [T in ExtensionKind]?: string } = { - [ExtensionKind.MultiFunction]: "$multi", - [ExtensionKind.RangeFunction]: "$range", - [ExtensionKind.VarargConstant]: "$vararg", -}; +export function getExtensionKindForType(context: TransformationContext, type: ts.Type): ExtensionKind | undefined { + const value = getPropertyValue(context, type, "__tstlExtension"); + if (value && extensionValues.has(value)) { + return value as ExtensionKind; + } +} + +const excludedTypeFlags: ts.TypeFlags = + ((1 << 18) - 1) & // All flags from Any...Never + ts.TypeFlags.Index & + ts.TypeFlags.NonPrimitive; -const extensionKindToTypeBrand: { [T in ExtensionKind]: string } = { - [ExtensionKind.MultiFunction]: "__luaMultiFunctionBrand", - [ExtensionKind.MultiType]: "__luaMultiReturnBrand", - [ExtensionKind.RangeFunction]: "__luaRangeFunctionBrand", - [ExtensionKind.VarargConstant]: "__luaVarargConstantBrand", - [ExtensionKind.IterableType]: "__luaIterableBrand", - [ExtensionKind.PairsIterableType]: "__luaPairsIterableBrand", - [ExtensionKind.PairsKeyIterableType]: "__luaPairsKeyIterableBrand", - [ExtensionKind.AdditionOperatorType]: "__luaAdditionBrand", - [ExtensionKind.AdditionOperatorMethodType]: "__luaAdditionMethodBrand", - [ExtensionKind.SubtractionOperatorType]: "__luaSubtractionBrand", - [ExtensionKind.SubtractionOperatorMethodType]: "__luaSubtractionMethodBrand", - [ExtensionKind.MultiplicationOperatorType]: "__luaMultiplicationBrand", - [ExtensionKind.MultiplicationOperatorMethodType]: "__luaMultiplicationMethodBrand", - [ExtensionKind.DivisionOperatorType]: "__luaDivisionBrand", - [ExtensionKind.DivisionOperatorMethodType]: "__luaDivisionMethodBrand", - [ExtensionKind.ModuloOperatorType]: "__luaModuloBrand", - [ExtensionKind.ModuloOperatorMethodType]: "__luaModuloMethodBrand", - [ExtensionKind.PowerOperatorType]: "__luaPowerBrand", - [ExtensionKind.PowerOperatorMethodType]: "__luaPowerMethodBrand", - [ExtensionKind.FloorDivisionOperatorType]: "__luaFloorDivisionBrand", - [ExtensionKind.FloorDivisionOperatorMethodType]: "__luaFloorDivisionMethodBrand", - [ExtensionKind.BitwiseAndOperatorType]: "__luaBitwiseAndBrand", - [ExtensionKind.BitwiseAndOperatorMethodType]: "__luaBitwiseAndMethodBrand", - [ExtensionKind.BitwiseOrOperatorType]: "__luaBitwiseOrBrand", - [ExtensionKind.BitwiseOrOperatorMethodType]: "__luaBitwiseOrMethodBrand", - [ExtensionKind.BitwiseExclusiveOrOperatorType]: "__luaBitwiseExclusiveOrBrand", - [ExtensionKind.BitwiseExclusiveOrOperatorMethodType]: "__luaBitwiseExclusiveOrMethodBrand", - [ExtensionKind.BitwiseLeftShiftOperatorType]: "__luaBitwiseLeftShiftBrand", - [ExtensionKind.BitwiseLeftShiftOperatorMethodType]: "__luaBitwiseLeftShiftMethodBrand", - [ExtensionKind.BitwiseRightShiftOperatorType]: "__luaBitwiseRightShiftBrand", - [ExtensionKind.BitwiseRightShiftOperatorMethodType]: "__luaBitwiseRightShiftMethodBrand", - [ExtensionKind.ConcatOperatorType]: "__luaConcatBrand", - [ExtensionKind.ConcatOperatorMethodType]: "__luaConcatMethodBrand", - [ExtensionKind.LessThanOperatorType]: "__luaLessThanBrand", - [ExtensionKind.LessThanOperatorMethodType]: "__luaLessThanMethodBrand", - [ExtensionKind.GreaterThanOperatorType]: "__luaGreaterThanBrand", - [ExtensionKind.GreaterThanOperatorMethodType]: "__luaGreaterThanMethodBrand", - [ExtensionKind.NegationOperatorType]: "__luaNegationBrand", - [ExtensionKind.NegationOperatorMethodType]: "__luaNegationMethodBrand", - [ExtensionKind.BitwiseNotOperatorType]: "__luaBitwiseNotBrand", - [ExtensionKind.BitwiseNotOperatorMethodType]: "__luaBitwiseNotMethodBrand", - [ExtensionKind.LengthOperatorType]: "__luaLengthBrand", - [ExtensionKind.LengthOperatorMethodType]: "__luaLengthMethodBrand", - [ExtensionKind.TableNewType]: "__luaTableNewBrand", - [ExtensionKind.TableDeleteType]: "__luaTableDeleteBrand", - [ExtensionKind.TableDeleteMethodType]: "__luaTableDeleteMethodBrand", - [ExtensionKind.TableGetType]: "__luaTableGetBrand", - [ExtensionKind.TableGetMethodType]: "__luaTableGetMethodBrand", - [ExtensionKind.TableHasType]: "__luaTableHasBrand", - [ExtensionKind.TableHasMethodType]: "__luaTableHasMethodBrand", - [ExtensionKind.TableSetType]: "__luaTableSetBrand", - [ExtensionKind.TableSetMethodType]: "__luaTableSetMethodBrand", - [ExtensionKind.TableAddType]: "__luaTableAddKeyBrand", - [ExtensionKind.TableAddMethodType]: "__luaTableAddKeyMethodBrand", -}; +function getPropertyValue(context: TransformationContext, type: ts.Type, propertyName: string): string | undefined { + if (type.flags & excludedTypeFlags) return; + const property = type.getProperty(propertyName); + if (!property) return undefined; + const propertyType = context.checker.getTypeOfSymbolAtLocation(property, context.sourceFile); + if (propertyType.isStringLiteral()) return propertyType.value; +} -export function isExtensionType(type: ts.Type, extensionKind: ExtensionKind): boolean { - const typeBrand = extensionKindToTypeBrand[extensionKind]; - return typeBrand !== undefined && type.getProperty(typeBrand) !== undefined; +export function getExtensionKindForNode(context: TransformationContext, node: ts.Node): ExtensionKind | undefined { + const type = context.checker.getTypeAtLocation(node); + return getExtensionKindForType(context, type); } -export function getExtensionKinds(type: ts.Type): ExtensionKind[] { - return (Object.keys(extensionKindToTypeBrand) as Array).filter( - e => type.getProperty(extensionKindToTypeBrand[e]) !== undefined - ); +export function getExtensionKindForSymbol( + context: TransformationContext, + symbol: ts.Symbol +): ExtensionKind | undefined { + const type = context.checker.getTypeOfSymbolAtLocation(symbol, context.sourceFile); + return getExtensionKindForType(context, type); +} + +export enum IterableExtensionKind { + Iterable = "Iterable", + Pairs = "Pairs", + PairsKey = "PairsKey", +} + +export function getIterableExtensionTypeForType( + context: TransformationContext, + type: ts.Type +): IterableExtensionKind | undefined { + const value = getPropertyValue(context, type, "__tstlIterable"); + if (value && value in IterableExtensionKind) { + return value as IterableExtensionKind; + } } -export function isExtensionValue( +export function getIterableExtensionKindForNode( context: TransformationContext, - symbol: ts.Symbol, - extensionKind: ExtensionKind -): boolean { - return ( - symbol.getName() === extensionKindToValueName[extensionKind] && - symbol.declarations?.some(d => isExtensionType(context.checker.getTypeAtLocation(d), extensionKind)) === true - ); + node: ts.Node +): IterableExtensionKind | undefined { + const type = context.checker.getTypeAtLocation(node); + return getIterableExtensionTypeForType(context, type); } diff --git a/src/transformation/utils/lualib.ts b/src/transformation/utils/lualib.ts index 3c2d0ec1b..ee828d1b9 100644 --- a/src/transformation/utils/lualib.ts +++ b/src/transformation/utils/lualib.ts @@ -1,18 +1,12 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { LuaLibFeature } from "../../LuaLib"; -import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; export { LuaLibFeature }; -const luaLibFeatures = new WeakMap>(); -export function getUsedLuaLibFeatures(context: TransformationContext): Set { - return getOrUpdate(luaLibFeatures, context, () => new Set()); -} - export function importLuaLibFeature(context: TransformationContext, feature: LuaLibFeature): void { - getUsedLuaLibFeatures(context).add(feature); + context.usedLuaLibFeatures.add(feature); } export function transformLuaLibFunction( diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index 638afdb91..538d77a91 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -96,13 +96,10 @@ export function hasUnsafeSymbolName( export function hasUnsafeIdentifierName( context: TransformationContext, identifier: ts.Identifier, - checkSymbol = true + symbol: ts.Symbol | undefined ): boolean { - if (checkSymbol) { - const symbol = context.checker.getSymbolAtLocation(identifier); - if (symbol) { - return hasUnsafeSymbolName(context, symbol, identifier); - } + if (symbol) { + return hasUnsafeSymbolName(context, symbol, identifier); } return checkName(context, identifier.text, identifier); diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index ad1ddfe6a..9e89d3422 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -40,13 +40,8 @@ export interface HoistingResult { hoistedIdentifiers: lua.Identifier[]; } -const scopeStacks = new WeakMap(); -function getScopeStack(context: TransformationContext): Scope[] { - return getOrUpdate(scopeStacks, context, () => []); -} - export function* walkScopesUp(context: TransformationContext): IterableIterator { - const scopeStack = getScopeStack(context); + const scopeStack = context.scopeStack; for (let i = scopeStack.length - 1; i >= 0; --i) { const scope = scopeStack[i]; yield scope; @@ -58,7 +53,7 @@ export function markSymbolAsReferencedInCurrentScopes( symbolId: lua.SymbolId, identifier: ts.Identifier ): void { - for (const scope of getScopeStack(context)) { + for (const scope of context.scopeStack) { if (!scope.referencedSymbols) { scope.referencedSymbols = new Map(); } @@ -69,7 +64,7 @@ export function markSymbolAsReferencedInCurrentScopes( } export function peekScope(context: TransformationContext): Scope { - const scopeStack = getScopeStack(context); + const scopeStack = context.scopeStack; const scope = scopeStack[scopeStack.length - 1]; assert(scope); @@ -77,26 +72,12 @@ export function peekScope(context: TransformationContext): Scope { } export function findScope(context: TransformationContext, scopeTypes: ScopeType): Scope | undefined { - return [...getScopeStack(context)].reverse().find(s => scopeTypes & s.type); -} - -const scopeIdCounters = new WeakMap(); -export function pushScope(context: TransformationContext, scopeType: ScopeType): Scope { - const nextScopeId = (scopeIdCounters.get(context) ?? 0) + 1; - scopeIdCounters.set(context, nextScopeId); - - const scopeStack = getScopeStack(context); - const scope: Scope = { type: scopeType, id: nextScopeId }; - scopeStack.push(scope); - return scope; -} - -export function popScope(context: TransformationContext): Scope { - const scopeStack = getScopeStack(context); - const scope = scopeStack.pop(); - assert(scope); - - return scope; + for (let i = context.scopeStack.length - 1; i >= 0; --i) { + const scope = context.scopeStack[i]; + if (scopeTypes & scope.type) { + return scope; + } + } } export function addScopeVariableDeclaration(scope: Scope, declaration: lua.VariableDeclarationStatement) { diff --git a/src/transformation/utils/symbols.ts b/src/transformation/utils/symbols.ts index f800eea86..d79b68da8 100644 --- a/src/transformation/utils/symbols.ts +++ b/src/transformation/utils/symbols.ts @@ -1,31 +1,20 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { getOrUpdate } from "../../utils"; import { TransformationContext } from "../context"; import { isOptimizedVarArgSpread } from "../visitors/spread"; import { markSymbolAsReferencedInCurrentScopes } from "./scope"; -const symbolIdCounters = new WeakMap(); -function nextSymbolId(context: TransformationContext): lua.SymbolId { - const symbolId = (symbolIdCounters.get(context) ?? 0) + 1; - symbolIdCounters.set(context, symbolId); - return symbolId as lua.SymbolId; -} - export interface SymbolInfo { symbol: ts.Symbol; firstSeenAtPos: number; } -const symbolInfoMap = new WeakMap>(); -const symbolIdMaps = new WeakMap>(); - export function getSymbolInfo(context: TransformationContext, symbolId: lua.SymbolId): SymbolInfo | undefined { - return getOrUpdate(symbolInfoMap, context, () => new Map()).get(symbolId); + return context.symbolInfoMap.get(symbolId); } export function getSymbolIdOfSymbol(context: TransformationContext, symbol: ts.Symbol): lua.SymbolId | undefined { - return getOrUpdate(symbolIdMaps, context, () => new Map()).get(symbol); + return context.symbolIdMaps.get(symbol); } export function trackSymbolReference( @@ -33,16 +22,13 @@ export function trackSymbolReference( symbol: ts.Symbol, identifier: ts.Identifier ): lua.SymbolId | undefined { - const symbolIds = getOrUpdate(symbolIdMaps, context, () => new Map()); - // Track first time symbols are seen - let symbolId = symbolIds.get(symbol); + let symbolId = context.symbolIdMaps.get(symbol); if (symbolId === undefined) { - symbolId = nextSymbolId(context); + symbolId = context.nextSymbolId(); - symbolIds.set(symbol, symbolId); - const symbolInfo = getOrUpdate(symbolInfoMap, context, () => new Map()); - symbolInfo.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); + context.symbolIdMaps.set(symbol, symbolId); + context.symbolInfoMap.set(symbolId, { symbol, firstSeenAtPos: identifier.pos }); } // If isOptimizedVarArgSpread returns true, the identifier will not appear in the resulting Lua. @@ -56,9 +42,9 @@ export function trackSymbolReference( export function getIdentifierSymbolId( context: TransformationContext, - identifier: ts.Identifier + identifier: ts.Identifier, + symbol: ts.Symbol | undefined ): lua.SymbolId | undefined { - const symbol = context.checker.getSymbolAtLocation(identifier); if (symbol) { return trackSymbolReference(context, symbol, identifier); } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index 5f603f98e..cac697064 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -39,7 +39,7 @@ export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.Sour return declarations.length > 0 ? declarations.reduce((p, c) => (p.pos < c.pos ? p : c)) : undefined; } -function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { +export function isStandardLibraryDeclaration(context: TransformationContext, declaration: ts.Declaration): boolean { const parseTreeNode = ts.getParseTreeNode(declaration) ?? declaration; const sourceFile = parseTreeNode.getSourceFile(); if (!sourceFile) { diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 4be744f7e..d13a40b38 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -1,42 +1,28 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; -export function isTypeWithFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { - const predicate = (type: ts.Type) => (type.flags & flags) !== 0; - - return typeAlwaysSatisfies(context, type, predicate); -} - -export function typeAlwaysSatisfies( - context: TransformationContext, - type: ts.Type, - predicate: (type: ts.Type) => boolean -): boolean { +export function typeAlwaysHasSomeOfFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (baseConstraint) { type = baseConstraint; } - if (predicate(type)) { + if (type.flags & flags) { return true; } if (type.isUnion()) { - return type.types.every(t => typeAlwaysSatisfies(context, t, predicate)); + return type.types.every(t => typeAlwaysHasSomeOfFlags(context, t, flags)); } if (type.isIntersection()) { - return type.types.some(t => typeAlwaysSatisfies(context, t, predicate)); + return type.types.some(t => typeAlwaysHasSomeOfFlags(context, t, flags)); } return false; } -export function typeCanSatisfy( - context: TransformationContext, - type: ts.Type, - predicate: (type: ts.Type) => boolean -): boolean { +export function typeCanHaveSomeOfFlags(context: TransformationContext, type: ts.Type, flags: ts.TypeFlags): boolean { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (!baseConstraint) { // type parameter with no constraint can be anything, assume it might satisfy predicate @@ -45,45 +31,31 @@ export function typeCanSatisfy( type = baseConstraint; } - if (predicate(type)) { + if (type.flags & flags) { return true; } if (type.isUnion()) { - return type.types.some(t => typeCanSatisfy(context, t, predicate)); + return type.types.some(t => typeCanHaveSomeOfFlags(context, t, flags)); } if (type.isIntersection()) { - return type.types.some(t => typeCanSatisfy(context, t, predicate)); + return type.types.some(t => typeCanHaveSomeOfFlags(context, t, flags)); } return false; } -export function isNullishType(context: TransformationContext, type: ts.Type): boolean { - return isTypeWithFlags(context, type, ts.TypeFlags.Undefined | ts.TypeFlags.Null | ts.TypeFlags.VoidLike); -} - export function isStringType(context: TransformationContext, type: ts.Type): boolean { - return isTypeWithFlags(context, type, ts.TypeFlags.String | ts.TypeFlags.StringLike | ts.TypeFlags.StringLiteral); + return typeAlwaysHasSomeOfFlags(context, type, ts.TypeFlags.StringLike); } export function isNumberType(context: TransformationContext, type: ts.Type): boolean { - return isTypeWithFlags(context, type, ts.TypeFlags.Number | ts.TypeFlags.NumberLike | ts.TypeFlags.NumberLiteral); -} - -export function isNullableType( - context: TransformationContext, - type: ts.Type, - isType: (c: TransformationContext, t: ts.Type) => boolean -): boolean { - return ( - typeCanSatisfy(context, type, t => isType(context, t)) && - typeAlwaysSatisfies(context, type, t => isType(context, t) || isNullishType(context, t)) - ); + return typeAlwaysHasSomeOfFlags(context, type, ts.TypeFlags.NumberLike); } function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { + if (context.checker.isArrayType(type) || context.checker.isTupleType(type)) return true; if (type.symbol) { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (baseConstraint && baseConstraint !== type) { @@ -95,13 +67,7 @@ function isExplicitArrayType(context: TransformationContext, type: ts.Type): boo return type.types.some(t => isExplicitArrayType(context, t)); } - const flags = ts.NodeBuilderFlags.InTypeAlias | ts.NodeBuilderFlags.AllowEmptyTuple; - let typeNode = context.checker.typeToTypeNode(type, undefined, flags); - if (typeNode && ts.isTypeOperatorNode(typeNode) && typeNode.operator === ts.SyntaxKind.ReadonlyKeyword) { - typeNode = typeNode.type; - } - - return typeNode !== undefined && (ts.isArrayTypeNode(typeNode) || ts.isTupleTypeNode(typeNode)); + return false; } /** @@ -120,7 +86,9 @@ export function forTypeOrAnySupertype( type = context.checker.getDeclaredTypeOfSymbol(type.symbol); } - return (type.getBaseTypes() ?? []).some(superType => forTypeOrAnySupertype(context, superType, predicate)); + const baseTypes = type.getBaseTypes(); + if (!baseTypes) return false; + return baseTypes.some(superType => forTypeOrAnySupertype(context, superType, predicate)); } export function isArrayType(context: TransformationContext, type: ts.Type): boolean { @@ -133,6 +101,7 @@ export function isFunctionType(type: ts.Type): boolean { export function canBeFalsy(context: TransformationContext, type: ts.Type): boolean { const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; + if (!strictNullChecks && !type.isLiteral()) return true; const falsyFlags = ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral | @@ -142,14 +111,12 @@ export function canBeFalsy(context: TransformationContext, type: ts.Type): boole ts.TypeFlags.Any | ts.TypeFlags.Undefined | ts.TypeFlags.Null; - return typeCanSatisfy( - context, - type, - type => (type.flags & falsyFlags) !== 0 || (!strictNullChecks && !type.isLiteral()) - ); + return typeCanHaveSomeOfFlags(context, type, falsyFlags); } export function canBeFalsyWhenNotNull(context: TransformationContext, type: ts.Type): boolean { + const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; + if (!strictNullChecks && !type.isLiteral()) return true; const falsyFlags = ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral | @@ -157,5 +124,5 @@ export function canBeFalsyWhenNotNull(context: TransformationContext, type: ts.T ts.TypeFlags.Void | ts.TypeFlags.Unknown | ts.TypeFlags.Any; - return typeCanSatisfy(context, type, type => (type.flags & falsyFlags) !== 0); + return typeCanHaveSomeOfFlags(context, type, falsyFlags); } diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index b09db7801..f0eced595 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,11 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { - annotationRemoved, - invalidMultiReturnAccess, - unsupportedOptionalCompileMembersOnly, -} from "../utils/diagnostics"; +import { invalidMultiReturnAccess, unsupportedOptionalCompileMembersOnly } from "../utils/diagnostics"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; @@ -107,12 +103,6 @@ export function transformPropertyAccessExpressionWithCapture( const type = context.checker.getTypeAtLocation(node.expression); const isOptionalLeft = isOptionalContinuation(node.expression); - const annotations = getTypeAnnotations(type); - - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); - } - const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return { expression: constEnumValue }; @@ -127,6 +117,7 @@ export function transformPropertyAccessExpressionWithCapture( } // Do not output path for member only enums + const annotations = getTypeAnnotations(type); if (annotations.has(AnnotationKind.CompileMembersOnly)) { if (isOptionalLeft) { context.diagnostics.push(unsupportedOptionalCompileMembersOnly(node)); diff --git a/src/transformation/visitors/block.ts b/src/transformation/visitors/block.ts index c26cc1cea..c0a2ad3a8 100644 --- a/src/transformation/visitors/block.ts +++ b/src/transformation/visitors/block.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { performHoisting, popScope, pushScope, Scope, ScopeType } from "../utils/scope"; +import { performHoisting, Scope, ScopeType } from "../utils/scope"; export function transformBlockOrStatement(context: TransformationContext, statement: ts.Statement): lua.Statement[] { return context.transformStatements(ts.isBlock(statement) ? statement.statements : statement); @@ -12,15 +12,15 @@ export function transformScopeBlock( node: ts.Block, scopeType: ScopeType ): [lua.Block, Scope] { - pushScope(context, scopeType); + context.pushScope(scopeType); const statements = performHoisting(context, context.transformStatements(node.statements)); - const scope = popScope(context); + const scope = context.popScope(); return [lua.createBlock(statements, node), scope]; } export const transformBlock: FunctionVisitor = (node, context) => { - pushScope(context, ScopeType.Block); + context.pushScope(ScopeType.Block); const statements = performHoisting(context, context.transformStatements(node.statements)); - popScope(context); + context.popScope(); return lua.createDoStatement(statements, node); }; diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index cfed13245..6b2fc602f 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -2,7 +2,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations, isTupleReturnCall } from "../utils/annotations"; import { validateAssignment } from "../utils/assignment-validation"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInTable } from "../utils/lua-ast"; @@ -10,12 +9,12 @@ import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; import { transformElementAccessArgument } from "./access"; import { isMultiReturnCall, shouldMultiReturnCallBeWrapped } from "./language-extensions/multi"; -import { annotationRemoved } from "../utils/diagnostics"; +import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { getOptionalContinuationData, transformOptionalChain } from "./optional-chaining"; -import { transformLanguageExtensionCallExpression } from "./language-extensions"; import { transformImportExpression } from "./modules/import"; +import { transformLanguageExtensionCallExpression } from "./language-extensions/call-extension"; export function validateArguments( context: TransformationContext, @@ -27,9 +26,9 @@ export function validateArguments( } for (const [index, param] of params.entries()) { const signatureParameter = signature.parameters[index]; - const paramType = context.checker.getTypeAtLocation(param); if (signatureParameter.valueDeclaration !== undefined) { const signatureType = context.checker.getTypeAtLocation(signatureParameter.valueDeclaration); + const paramType = context.checker.getTypeAtLocation(param); validateAssignment(context, param, paramType, signatureType, signatureParameter.name); } } @@ -228,25 +227,16 @@ export const transformCallExpression: FunctionVisitor = (node : undefined; const wrapResultInTable = isMultiReturnCall(context, node) && shouldMultiReturnCallBeWrapped(context, node); - if (isTupleReturnCall(context, node)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); - } - const builtinOrExtensionResult = - transformBuiltinCallExpression(context, node, optionalContinuation !== undefined) ?? - transformLanguageExtensionCallExpression(context, node, optionalContinuation !== undefined); + transformBuiltinCallExpression(context, node) ?? transformLanguageExtensionCallExpression(context, node); if (builtinOrExtensionResult) { - // unsupportedOptionalCall diagnostic already present + if (optionalContinuation !== undefined) { + context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); + } return wrapResultInTable ? wrapInTable(builtinOrExtensionResult) : builtinOrExtensionResult; } if (ts.isPropertyAccessExpression(calledExpression)) { - const ownerType = context.checker.getTypeAtLocation(calledExpression.expression); - const annotations = getTypeAnnotations(ownerType); - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); - } - const result = transformPropertyCall(context, node, calledExpression); return wrapResultInTable ? wrapInTable(result) : result; } @@ -305,9 +295,5 @@ function isContextualCallExpression(context: TransformationContext, signature: t } export function getCalledExpression(node: ts.CallExpression): ts.Expression { - function unwrapExpression(expression: ts.Expression): ts.Expression { - expression = ts.skipOuterExpressions(expression); - return ts.isNonNullExpression(expression) ? unwrapExpression(expression.expression) : expression; - } - return unwrapExpression(node.expression); + return ts.skipOuterExpressions(node.expression); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 80b5f7536..3aee65a36 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -1,9 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { getOrUpdate } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationRemoved } from "../../utils/diagnostics"; import { createDefaultExportExpression, createExportedIdentifier, @@ -49,8 +46,8 @@ export function transformClassAsExpression( return name; } -const classSuperInfos = new WeakMap(); -interface ClassSuperInfo { +/** @internal */ +export interface ClassSuperInfo { className: lua.Identifier; extendedTypeNode?: ts.ExpressionWithTypeArguments; } @@ -69,21 +66,11 @@ function transformClassLikeDeclaration( className = lua.createIdentifier(context.createTempName("class"), classDeclaration); } - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(classDeclaration)); - - if (annotations.has(AnnotationKind.Extension)) { - context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.Extension)); - } - if (annotations.has(AnnotationKind.MetaExtension)) { - context.diagnostics.push(annotationRemoved(classDeclaration, AnnotationKind.MetaExtension)); - } - // Get type that is extended - const extendedTypeNode = getExtendedNode(context, classDeclaration); + const extendedTypeNode = getExtendedNode(classDeclaration); const extendedType = getExtendedType(context, classDeclaration); - const superInfo = getOrUpdate(classSuperInfos, context, () => []); - superInfo.push({ className, extendedTypeNode }); + context.classSuperInfos.push({ className, extendedTypeNode }); // Get all properties with value const properties = classDeclaration.members.filter(ts.isPropertyDeclaration).filter(member => member.initializer); @@ -220,13 +207,13 @@ function transformClassLikeDeclaration( } } - superInfo.pop(); + context.classSuperInfos.pop(); return { statements: result, name: className }; } export const transformSuperExpression: FunctionVisitor = (expression, context) => { - const superInfos = getOrUpdate(classSuperInfos, context, () => []); + const superInfos = context.classSuperInfos; const superInfo = superInfos[superInfos.length - 1]; if (!superInfo) return lua.createAnonymousIdentifier(expression); const { className, extendedTypeNode } = superInfo; diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 22ab14feb..73aad20a8 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../../LuaAST"; import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; -import { popScope, pushScope, ScopeType } from "../../../utils/scope"; +import { ScopeType } from "../../../utils/scope"; import { transformFunctionBodyContent, transformFunctionBodyHeader, transformParameters } from "../../function"; import { transformIdentifier } from "../../identifier"; import { transformClassInstanceFields } from "./fields"; @@ -28,7 +28,7 @@ export function transformConstructorDeclaration( } // Transform body - const scope = pushScope(context, ScopeType.Function); + const scope = context.pushScope(ScopeType.Function); const body = transformFunctionBodyContent(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( @@ -86,7 +86,7 @@ export function transformConstructorDeclaration( const constructorWasGenerated = statement.pos === -1; - popScope(context); + context.popScope(); return lua.createAssignmentStatement( createConstructorName(className), diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 13a4a57a9..9fcdc3c94 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,20 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount, annotationRemoved } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; export const transformNewExpression: FunctionVisitor = (node, context) => { - const type = context.checker.getTypeAtLocation(node); - - const annotations = getTypeAnnotations(type); - - if (annotations.has(AnnotationKind.LuaTable)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.LuaTable)); - } - if (isTableNewCall(context, node)) { return lua.createTableExpression(undefined, node); } @@ -28,6 +20,8 @@ export const transformNewExpression: FunctionVisitor = (node, signature ); + const type = context.checker.getTypeAtLocation(node); + const annotations = getTypeAnnotations(type); const customConstructorAnnotation = annotations.get(AnnotationKind.CustomConstructor); if (customConstructorAnnotation) { if (customConstructorAnnotation.args.length === 1) { diff --git a/src/transformation/visitors/class/setup.ts b/src/transformation/visitors/class/setup.ts index 151e68a77..ab6eeea92 100644 --- a/src/transformation/visitors/class/setup.ts +++ b/src/transformation/visitors/class/setup.ts @@ -55,13 +55,13 @@ export function createClassSetup( result.push( lua.createAssignmentStatement( lua.createTableIndexExpression(lua.cloneIdentifier(localClassName), lua.createStringLiteral("name")), - getReflectionClassName(context, statement, className), + getReflectionClassName(statement, className), statement ) ); if (extendsType) { - const extendedNode = getExtendedNode(context, statement); + const extendedNode = getExtendedNode(statement); assert(extendedNode); result.push( lua.createExpressionStatement( @@ -80,7 +80,6 @@ export function createClassSetup( } export function getReflectionClassName( - context: TransformationContext, declaration: ts.ClassLikeDeclarationBase, className: lua.Identifier ): lua.Expression { @@ -92,7 +91,7 @@ export function getReflectionClassName( return lua.createStringLiteral("default"); } - if (getExtendedNode(context, declaration)) { + if (getExtendedNode(declaration)) { return lua.createTableIndexExpression(className, lua.createStringLiteral("name")); } diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index aea06680a..8708a54fb 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,7 +1,5 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; -import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationRemoved } from "../../utils/diagnostics"; export function isStaticNode(node: ts.Node): boolean { return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); @@ -11,20 +9,10 @@ export function getExtendsClause(node: ts.ClassLikeDeclarationBase): ts.Heritage return (node.heritageClauses ?? []).find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); } -export function getExtendedNode( - context: TransformationContext, - node: ts.ClassLikeDeclarationBase -): ts.ExpressionWithTypeArguments | undefined { +export function getExtendedNode(node: ts.ClassLikeDeclarationBase): ts.ExpressionWithTypeArguments | undefined { const extendsClause = getExtendsClause(node); if (!extendsClause) return; - const superType = context.checker.getTypeAtLocation(extendsClause.types[0]); - const annotations = getTypeAnnotations(superType); - - if (annotations.has(AnnotationKind.PureAbstract)) { - context.diagnostics.push(annotationRemoved(extendsClause, AnnotationKind.PureAbstract)); - } - return extendsClause.types[0]; } @@ -32,6 +20,6 @@ export function getExtendedType( context: TransformationContext, node: ts.ClassLikeDeclarationBase ): ts.Type | undefined { - const extendedNode = getExtendedNode(context, node); + const extendedNode = getExtendedNode(node); return extendedNode && context.checker.getTypeAtLocation(extendedNode); } diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 566dc9f75..0c8434890 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; -import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { performHoisting, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; @@ -63,10 +63,10 @@ export const transformConditionalExpression: FunctionVisitor isFunctionTypeWithProperties(context, t)); } else { return ( isFunctionType(functionType) && functionType.getProperties().length > 0 && - getExtensionKinds(functionType).length === 0 // ignore TSTL extension functions like $range + getExtensionKindForType(context, functionType) === undefined // ignore TSTL extension functions like $range ); } } @@ -159,14 +157,14 @@ export function transformFunctionBody( spreadIdentifier?: lua.Identifier, node?: ts.FunctionLikeDeclaration ): [lua.Statement[], Scope] { - const scope = pushScope(context, ScopeType.Function); + const scope = context.pushScope(ScopeType.Function); scope.node = node; let bodyStatements = transformFunctionBodyContent(context, body); if (node && isAsyncFunction(node)) { bodyStatements = [lua.createReturnStatement([wrapInAsyncAwaiter(context, bodyStatements)])]; } const headerStatements = transformFunctionBodyHeader(context, scope, parameters, spreadIdentifier); - popScope(context); + context.popScope(); return [[...headerStatements, ...bodyStatements], scope]; } @@ -271,10 +269,6 @@ export function transformFunctionLikeDeclaration( return lua.createNilLiteral(); } - if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); - } - const [functionExpression, functionScope] = transformFunctionToExpression(context, node); const isNamedFunctionExpression = ts.isFunctionExpression(node) && node.name; @@ -290,7 +284,7 @@ export function transformFunctionLikeDeclaration( // Only handle if the name is actually referenced inside the function if (isReferenced) { const nameIdentifier = transformIdentifier(context, node.name); - if (isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node))) { + if (isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(node))) { context.addPrecedingStatements([ lua.createVariableDeclarationStatement(nameIdentifier), lua.createAssignmentStatement(nameIdentifier, createCallableTable(functionExpression)), @@ -305,16 +299,12 @@ export function transformFunctionLikeDeclaration( } } - return isNamedFunctionExpression && isFunctionTypeWithProperties(context.checker.getTypeAtLocation(node)) + return isNamedFunctionExpression && isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(node)) ? createCallableTable(functionExpression) : functionExpression; } export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { - if (getNodeAnnotations(node).has(AnnotationKind.TupleReturn)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.TupleReturn)); - } - // Don't transform functions without body (overload declarations) if (node.body === undefined) { return undefined; @@ -345,7 +335,7 @@ export const transformFunctionDeclaration: FunctionVisitor = (node, context) => { - const symbol = context.checker.getSymbolAtLocation(node); +export function transformIdentifierWithSymbol( + context: TransformationContext, + node: ts.Identifier, + symbol: ts.Symbol | undefined +): lua.Expression { if (symbol) { const exportScope = getSymbolExportScope(context, symbol); if (exportScope) { const name = symbol.name; - const text = hasUnsafeIdentifierName(context, node) ? createSafeName(name) : name; - const symbolId = getIdentifierSymbolId(context, node); + const text = hasUnsafeIdentifierName(context, node, symbol) ? createSafeName(name) : name; + const symbolId = getIdentifierSymbolId(context, node, symbol); const identifier = lua.createIdentifier(text, node, symbolId, name); return createExportedIdentifier(context, identifier, exportScope); } } - - if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { - return lua.createNilLiteral(); - } - - const builtinResult = transformBuiltinIdentifierExpression(context, node); + const builtinResult = transformBuiltinIdentifierExpression(context, node, symbol); if (builtinResult) { return builtinResult; } - return transformIdentifier(context, node); + return transformNonValueIdentifier(context, node, symbol); +} + +export const transformIdentifierExpression: FunctionVisitor = (node, context) => { + if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + return lua.createNilLiteral(node); + } + + const symbol = context.checker.getSymbolAtLocation(node); + return transformIdentifierWithSymbol(context, node, symbol); }; diff --git a/src/transformation/visitors/language-extensions/call-extension.ts b/src/transformation/visitors/language-extensions/call-extension.ts new file mode 100644 index 000000000..49c05b72e --- /dev/null +++ b/src/transformation/visitors/language-extensions/call-extension.ts @@ -0,0 +1,34 @@ +import { TransformationContext } from "../../context"; +import * as ts from "typescript"; +import { ExtensionKind, getExtensionKindForNode } from "../../utils/language-extensions"; +import * as lua from "../../../LuaAST"; +import { operatorExtensionTransformers } from "./operators"; +import { tableExtensionTransformers, tableNewExtensions } from "./table"; + +const allCallExtensionHandlers: LanguageExtensionCallTransformerMap = { + ...operatorExtensionTransformers, + ...tableExtensionTransformers, +}; +export const callExtensions = new Set(Object.keys(allCallExtensionHandlers) as ExtensionKind[]); +tableNewExtensions.forEach(kind => callExtensions.add(kind)); + +export type LanguageExtensionCallTransformer = ( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: ExtensionKind +) => lua.Expression; + +export type LanguageExtensionCallTransformerMap = { + [P in ExtensionKind]?: LanguageExtensionCallTransformer; +}; +export function transformLanguageExtensionCallExpression( + context: TransformationContext, + node: ts.CallExpression +): lua.Expression | undefined { + const extensionKind = getExtensionKindForNode(context, node.expression); + if (!extensionKind) return; + const transformer = allCallExtensionHandlers[extensionKind]; + if (transformer) { + return transformer(context, node, extensionKind); + } +} diff --git a/src/transformation/visitors/language-extensions/identifier.ts b/src/transformation/visitors/language-extensions/identifier.ts new file mode 100644 index 000000000..945126e6d --- /dev/null +++ b/src/transformation/visitors/language-extensions/identifier.ts @@ -0,0 +1,27 @@ +import * as ts from "typescript"; +import { ExtensionKind } from "../../utils/language-extensions"; +import { TransformationContext } from "../../context"; +import { invalidMultiFunctionUse, invalidRangeUse, invalidVarargUse } from "../../utils/diagnostics"; + +const extensionKindToValueName: { [T in ExtensionKind]?: string } = { + [ExtensionKind.MultiFunction]: "$multi", + [ExtensionKind.RangeFunction]: "$range", + [ExtensionKind.VarargConstant]: "$vararg", +}; +export function isIdentifierExtensionValue(symbol: ts.Symbol | undefined, extensionKind: ExtensionKind): boolean { + return symbol !== undefined && extensionKindToValueName[extensionKind] === symbol.name; +} + +export function reportInvalidExtensionValue( + context: TransformationContext, + identifier: ts.Identifier, + extensionKind: ExtensionKind +): void { + if (extensionKind === ExtensionKind.MultiFunction) { + context.diagnostics.push(invalidMultiFunctionUse(identifier)); + } else if (extensionKind === ExtensionKind.RangeFunction) { + context.diagnostics.push(invalidRangeUse(identifier)); + } else if (extensionKind === ExtensionKind.VarargConstant) { + context.diagnostics.push(invalidVarargUse(identifier)); + } +} diff --git a/src/transformation/visitors/language-extensions/index.ts b/src/transformation/visitors/language-extensions/index.ts deleted file mode 100644 index 93e14f447..000000000 --- a/src/transformation/visitors/language-extensions/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { TransformationContext } from "../../context"; -import * as ts from "typescript"; -import * as lua from "../../../LuaAST"; -import { transformOperatorMappingExpression } from "./operators"; -import { transformTableExtensionCall } from "./table"; - -export function transformLanguageExtensionCallExpression( - context: TransformationContext, - node: ts.CallExpression, - isOptionalCall: boolean -): lua.Expression | undefined { - const operatorMapping = transformOperatorMappingExpression(context, node, isOptionalCall); - if (operatorMapping) { - return operatorMapping; - } - const tableCall = transformTableExtensionCall(context, node, isOptionalCall); - if (tableCall) { - return tableCall; - } -} diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts index 769e15093..dc792df6d 100644 --- a/src/transformation/visitors/language-extensions/iterable.ts +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -1,34 +1,22 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import * as extensions from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; import { transformArrayBindingElement } from "../variable-declaration"; -import { invalidMultiIterableWithoutDestructuring } from "../../utils/diagnostics"; +import { + invalidMultiIterableWithoutDestructuring, + invalidPairsIterableWithoutDestructuring, +} from "../../utils/diagnostics"; import { cast } from "../../../utils"; import { isMultiReturnType } from "./multi"; -export function isIterableType(type: ts.Type): boolean { - return extensions.isExtensionType(type, extensions.ExtensionKind.IterableType); -} - -export function returnsIterableType(context: TransformationContext, node: ts.CallExpression): boolean { - const signature = context.checker.getResolvedSignature(node); - const type = signature?.getReturnType(); - return type ? isIterableType(type) : false; -} - -export function isIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { - const type = context.checker.getTypeAtLocation(expression); - return isIterableType(type); -} - function transformForOfMultiIterableStatement( context: TransformationContext, statement: ts.ForOfStatement, - block: lua.Block + block: lua.Block, + luaIterator: lua.Expression, + invalidMultiUseDiagnostic: (node: ts.Node) => ts.Diagnostic ): lua.Statement { - const luaIterator = context.transformExpression(statement.expression); let identifiers: lua.Identifier[] = []; if (ts.isVariableDeclarationList(statement.initializer)) { @@ -38,7 +26,7 @@ function transformForOfMultiIterableStatement( if (ts.isArrayBindingPattern(binding)) { identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); } else { - context.diagnostics.push(invalidMultiIterableWithoutDestructuring(binding)); + context.diagnostics.push(invalidMultiUseDiagnostic(binding)); } } else if (ts.isArrayLiteralExpression(statement.initializer)) { // Variables NOT declared in for loop - catch iterator values in temps and assign @@ -56,7 +44,7 @@ function transformForOfMultiIterableStatement( ); } } else { - context.diagnostics.push(invalidMultiIterableWithoutDestructuring(statement.initializer)); + context.diagnostics.push(invalidMultiUseDiagnostic(statement.initializer)); } if (identifiers.length === 0) { @@ -73,10 +61,46 @@ export function transformForOfIterableStatement( ): lua.Statement { const type = context.checker.getTypeAtLocation(statement.expression); if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { - return transformForOfMultiIterableStatement(context, statement, block); + const luaIterator = context.transformExpression(statement.expression); + return transformForOfMultiIterableStatement( + context, + statement, + block, + luaIterator, + invalidMultiIterableWithoutDestructuring + ); } const luaIterator = context.transformExpression(statement.expression); const identifier = transformForInitializer(context, statement.initializer, block); return lua.createForInStatement(block, [identifier], [luaIterator], statement); } + +export function transformForOfPairsIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ + context.transformExpression(statement.expression), + ]); + return transformForOfMultiIterableStatement( + context, + statement, + block, + pairsCall, + invalidPairsIterableWithoutDestructuring + ); +} + +export function transformForOfPairsKeyIterableStatement( + context: TransformationContext, + statement: ts.ForOfStatement, + block: lua.Block +): lua.Statement { + const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ + context.transformExpression(statement.expression), + ]); + const identifier = transformForInitializer(context, statement.initializer, block); + return lua.createForInStatement(block, [identifier], [pairsCall], statement); +} diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index caaae7470..5dd239deb 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -1,16 +1,20 @@ import * as ts from "typescript"; import * as extensions from "../../utils/language-extensions"; +import { + getExtensionKindForNode, + getIterableExtensionKindForNode, + IterableExtensionKind, +} from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; import { findFirstNodeAbove } from "../../utils/typescript"; -import { isIterableExpression } from "./iterable"; -import { invalidMultiFunctionUse } from "../../utils/diagnostics"; +const multiReturnExtensionName = "__tstlMultiReturn"; export function isMultiReturnType(type: ts.Type): boolean { - return extensions.isExtensionType(type, extensions.ExtensionKind.MultiType); + return type.getProperty(multiReturnExtensionName) !== undefined; } export function canBeMultiReturnType(type: ts.Type): boolean { - return isMultiReturnType(type) || (type.isUnion() && type.types.some(canBeMultiReturnType)); + return isMultiReturnType(type) || (type.isUnion() && type.types.some(t => canBeMultiReturnType(t))); } export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { @@ -28,8 +32,11 @@ export function isMultiReturnCall(context: TransformationContext, expression: ts } export function isMultiFunctionNode(context: TransformationContext, node: ts.Node): boolean { - const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.MultiFunction) : false; + return ( + ts.isIdentifier(node) && + node.text === "$multi" && + getExtensionKindForNode(context, node) === extensions.ExtensionKind.MultiFunction + ); } export function isInMultiReturnFunction(context: TransformationContext, node: ts.Node) { @@ -85,29 +92,12 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n } // LuaIterable in for...of - if (ts.isForOfStatement(node.parent) && isIterableExpression(context, node)) { + if ( + ts.isForOfStatement(node.parent) && + getIterableExtensionKindForNode(context, node) === IterableExtensionKind.Iterable + ) { return false; } return true; } - -export function findMultiAssignmentViolations( - context: TransformationContext, - node: ts.ObjectLiteralExpression -): ts.Node[] { - const result: ts.Node[] = []; - - for (const element of node.properties) { - if (!ts.isShorthandPropertyAssignment(element)) continue; - const valueSymbol = context.checker.getShorthandAssignmentValueSymbol(element); - if (valueSymbol) { - if (extensions.isExtensionValue(context, valueSymbol, extensions.ExtensionKind.MultiFunction)) { - context.diagnostics.push(invalidMultiFunctionUse(element)); - result.push(element); - } - } - } - - return result; -} diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index dce4f5017..2281712b8 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -1,97 +1,122 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import * as extensions from "../../utils/language-extensions"; import { assert } from "../../../utils"; -import { getFunctionTypeForCall } from "../../utils/typescript"; import { LuaTarget } from "../../../CompilerOptions"; -import { unsupportedBuiltinOptionalCall, unsupportedForTarget } from "../../utils/diagnostics"; +import { unsupportedForTarget } from "../../utils/diagnostics"; +import { ExtensionKind } from "../../utils/language-extensions"; +import { LanguageExtensionCallTransformerMap } from "./call-extension"; -const binaryOperatorMappings = new Map([ - [extensions.ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], - [extensions.ExtensionKind.AdditionOperatorMethodType, lua.SyntaxKind.AdditionOperator], - [extensions.ExtensionKind.SubtractionOperatorType, lua.SyntaxKind.SubtractionOperator], - [extensions.ExtensionKind.SubtractionOperatorMethodType, lua.SyntaxKind.SubtractionOperator], - [extensions.ExtensionKind.MultiplicationOperatorType, lua.SyntaxKind.MultiplicationOperator], - [extensions.ExtensionKind.MultiplicationOperatorMethodType, lua.SyntaxKind.MultiplicationOperator], - [extensions.ExtensionKind.DivisionOperatorType, lua.SyntaxKind.DivisionOperator], - [extensions.ExtensionKind.DivisionOperatorMethodType, lua.SyntaxKind.DivisionOperator], - [extensions.ExtensionKind.ModuloOperatorType, lua.SyntaxKind.ModuloOperator], - [extensions.ExtensionKind.ModuloOperatorMethodType, lua.SyntaxKind.ModuloOperator], - [extensions.ExtensionKind.PowerOperatorType, lua.SyntaxKind.PowerOperator], - [extensions.ExtensionKind.PowerOperatorMethodType, lua.SyntaxKind.PowerOperator], - [extensions.ExtensionKind.FloorDivisionOperatorType, lua.SyntaxKind.FloorDivisionOperator], - [extensions.ExtensionKind.FloorDivisionOperatorMethodType, lua.SyntaxKind.FloorDivisionOperator], - [extensions.ExtensionKind.BitwiseAndOperatorType, lua.SyntaxKind.BitwiseAndOperator], - [extensions.ExtensionKind.BitwiseAndOperatorMethodType, lua.SyntaxKind.BitwiseAndOperator], - [extensions.ExtensionKind.BitwiseOrOperatorType, lua.SyntaxKind.BitwiseOrOperator], - [extensions.ExtensionKind.BitwiseOrOperatorMethodType, lua.SyntaxKind.BitwiseOrOperator], - [extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, lua.SyntaxKind.BitwiseExclusiveOrOperator], - [extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, lua.SyntaxKind.BitwiseExclusiveOrOperator], - [extensions.ExtensionKind.BitwiseLeftShiftOperatorType, lua.SyntaxKind.BitwiseLeftShiftOperator], - [extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, lua.SyntaxKind.BitwiseLeftShiftOperator], - [extensions.ExtensionKind.BitwiseRightShiftOperatorType, lua.SyntaxKind.BitwiseRightShiftOperator], - [extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, lua.SyntaxKind.BitwiseRightShiftOperator], - [extensions.ExtensionKind.ConcatOperatorType, lua.SyntaxKind.ConcatOperator], - [extensions.ExtensionKind.ConcatOperatorMethodType, lua.SyntaxKind.ConcatOperator], - [extensions.ExtensionKind.LessThanOperatorType, lua.SyntaxKind.LessThanOperator], - [extensions.ExtensionKind.LessThanOperatorMethodType, lua.SyntaxKind.LessThanOperator], - [extensions.ExtensionKind.GreaterThanOperatorType, lua.SyntaxKind.GreaterThanOperator], - [extensions.ExtensionKind.GreaterThanOperatorMethodType, lua.SyntaxKind.GreaterThanOperator], +const binaryOperatorMappings = new Map([ + [ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], + [ExtensionKind.AdditionOperatorMethodType, lua.SyntaxKind.AdditionOperator], + [ExtensionKind.SubtractionOperatorType, lua.SyntaxKind.SubtractionOperator], + [ExtensionKind.SubtractionOperatorMethodType, lua.SyntaxKind.SubtractionOperator], + [ExtensionKind.MultiplicationOperatorType, lua.SyntaxKind.MultiplicationOperator], + [ExtensionKind.MultiplicationOperatorMethodType, lua.SyntaxKind.MultiplicationOperator], + [ExtensionKind.DivisionOperatorType, lua.SyntaxKind.DivisionOperator], + [ExtensionKind.DivisionOperatorMethodType, lua.SyntaxKind.DivisionOperator], + [ExtensionKind.ModuloOperatorType, lua.SyntaxKind.ModuloOperator], + [ExtensionKind.ModuloOperatorMethodType, lua.SyntaxKind.ModuloOperator], + [ExtensionKind.PowerOperatorType, lua.SyntaxKind.PowerOperator], + [ExtensionKind.PowerOperatorMethodType, lua.SyntaxKind.PowerOperator], + [ExtensionKind.FloorDivisionOperatorType, lua.SyntaxKind.FloorDivisionOperator], + [ExtensionKind.FloorDivisionOperatorMethodType, lua.SyntaxKind.FloorDivisionOperator], + [ExtensionKind.BitwiseAndOperatorType, lua.SyntaxKind.BitwiseAndOperator], + [ExtensionKind.BitwiseAndOperatorMethodType, lua.SyntaxKind.BitwiseAndOperator], + [ExtensionKind.BitwiseOrOperatorType, lua.SyntaxKind.BitwiseOrOperator], + [ExtensionKind.BitwiseOrOperatorMethodType, lua.SyntaxKind.BitwiseOrOperator], + [ExtensionKind.BitwiseExclusiveOrOperatorType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [ExtensionKind.BitwiseExclusiveOrOperatorMethodType, lua.SyntaxKind.BitwiseExclusiveOrOperator], + [ExtensionKind.BitwiseLeftShiftOperatorType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [ExtensionKind.BitwiseLeftShiftOperatorMethodType, lua.SyntaxKind.BitwiseLeftShiftOperator], + [ExtensionKind.BitwiseRightShiftOperatorType, lua.SyntaxKind.BitwiseRightShiftOperator], + [ExtensionKind.BitwiseRightShiftOperatorMethodType, lua.SyntaxKind.BitwiseRightShiftOperator], + [ExtensionKind.ConcatOperatorType, lua.SyntaxKind.ConcatOperator], + [ExtensionKind.ConcatOperatorMethodType, lua.SyntaxKind.ConcatOperator], + [ExtensionKind.LessThanOperatorType, lua.SyntaxKind.LessThanOperator], + [ExtensionKind.LessThanOperatorMethodType, lua.SyntaxKind.LessThanOperator], + [ExtensionKind.GreaterThanOperatorType, lua.SyntaxKind.GreaterThanOperator], + [ExtensionKind.GreaterThanOperatorMethodType, lua.SyntaxKind.GreaterThanOperator], ]); -const unaryOperatorMappings = new Map([ - [extensions.ExtensionKind.NegationOperatorType, lua.SyntaxKind.NegationOperator], - [extensions.ExtensionKind.NegationOperatorMethodType, lua.SyntaxKind.NegationOperator], - [extensions.ExtensionKind.BitwiseNotOperatorType, lua.SyntaxKind.BitwiseNotOperator], - [extensions.ExtensionKind.BitwiseNotOperatorMethodType, lua.SyntaxKind.BitwiseNotOperator], - [extensions.ExtensionKind.LengthOperatorType, lua.SyntaxKind.LengthOperator], - [extensions.ExtensionKind.LengthOperatorMethodType, lua.SyntaxKind.LengthOperator], +const unaryOperatorMappings = new Map([ + [ExtensionKind.NegationOperatorType, lua.SyntaxKind.NegationOperator], + [ExtensionKind.NegationOperatorMethodType, lua.SyntaxKind.NegationOperator], + [ExtensionKind.BitwiseNotOperatorType, lua.SyntaxKind.BitwiseNotOperator], + [ExtensionKind.BitwiseNotOperatorMethodType, lua.SyntaxKind.BitwiseNotOperator], + [ExtensionKind.LengthOperatorType, lua.SyntaxKind.LengthOperator], + [ExtensionKind.LengthOperatorMethodType, lua.SyntaxKind.LengthOperator], ]); -const operatorMapExtensions = [...binaryOperatorMappings.keys(), ...unaryOperatorMappings.keys()]; +const bitwiseOperatorMapExtensions = new Set([ + ExtensionKind.BitwiseAndOperatorType, + ExtensionKind.BitwiseAndOperatorMethodType, + ExtensionKind.BitwiseOrOperatorType, + ExtensionKind.BitwiseOrOperatorMethodType, + ExtensionKind.BitwiseExclusiveOrOperatorType, + ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + ExtensionKind.BitwiseLeftShiftOperatorType, + ExtensionKind.BitwiseLeftShiftOperatorMethodType, + ExtensionKind.BitwiseRightShiftOperatorType, + ExtensionKind.BitwiseRightShiftOperatorMethodType, + ExtensionKind.BitwiseNotOperatorType, + ExtensionKind.BitwiseNotOperatorMethodType, +]); -const bitwiseOperatorMapExtensions = new Set([ - extensions.ExtensionKind.BitwiseAndOperatorType, - extensions.ExtensionKind.BitwiseAndOperatorMethodType, - extensions.ExtensionKind.BitwiseOrOperatorType, - extensions.ExtensionKind.BitwiseOrOperatorMethodType, - extensions.ExtensionKind.BitwiseExclusiveOrOperatorType, - extensions.ExtensionKind.BitwiseExclusiveOrOperatorMethodType, - extensions.ExtensionKind.BitwiseLeftShiftOperatorType, - extensions.ExtensionKind.BitwiseLeftShiftOperatorMethodType, - extensions.ExtensionKind.BitwiseRightShiftOperatorType, - extensions.ExtensionKind.BitwiseRightShiftOperatorMethodType, - extensions.ExtensionKind.BitwiseNotOperatorType, - extensions.ExtensionKind.BitwiseNotOperatorMethodType, +const requiresLua53 = new Set([ + ...bitwiseOperatorMapExtensions, + ExtensionKind.FloorDivisionOperatorType, + ExtensionKind.FloorDivisionOperatorMethodType, ]); -function getOperatorMapExtensionKindForCall(context: TransformationContext, node: ts.CallExpression) { - const type = getFunctionTypeForCall(context, node); - return type && operatorMapExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); +export const operatorExtensionTransformers: LanguageExtensionCallTransformerMap = {}; +for (const kind of binaryOperatorMappings.keys()) { + operatorExtensionTransformers[kind] = transformBinaryOperator; +} +for (const kind of unaryOperatorMappings.keys()) { + operatorExtensionTransformers[kind] = transformUnaryOperator; } -export function isOperatorMapping(context: TransformationContext, node: ts.CallExpression | ts.Identifier) { - if (ts.isCallExpression(node)) { - return getOperatorMapExtensionKindForCall(context, node) !== undefined; - } else { - const type = context.checker.getTypeAtLocation(node); - return operatorMapExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); +function transformBinaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { + if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); + + let args: readonly ts.Expression[] = node.arguments; + if ( + args.length === 1 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + args = [node.expression.expression, ...args]; } + + const luaOperator = binaryOperatorMappings.get(kind); + assert(luaOperator); + return lua.createBinaryExpression( + context.transformExpression(args[0]), + context.transformExpression(args[1]), + luaOperator + ); } -export function transformOperatorMappingExpression( - context: TransformationContext, - node: ts.CallExpression, - isOptionalCall: boolean -): lua.Expression | undefined { - const extensionKind = getOperatorMapExtensionKindForCall(context, node); - if (!extensionKind) return undefined; - if (isOptionalCall) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); +function transformUnaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { + if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); + + let arg: ts.Expression; + if ( + node.arguments.length === 0 && + (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + ) { + arg = node.expression.expression; + } else { + arg = node.arguments[0]; } + const luaOperator = unaryOperatorMappings.get(kind); + assert(luaOperator); + return lua.createUnaryExpression(context.transformExpression(arg), luaOperator); +} + +function checkHasLua53(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { const isBefore53 = context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Lua52 || @@ -99,45 +124,14 @@ export function transformOperatorMappingExpression( context.luaTarget === LuaTarget.Universal; if (isBefore53) { const luaTarget = context.luaTarget === LuaTarget.Universal ? LuaTarget.Lua51 : context.luaTarget; - if (bitwiseOperatorMapExtensions.has(extensionKind)) { - context.diagnostics.push(unsupportedForTarget(node, "Native bitwise operations", luaTarget)); - } else if ( - extensionKind === extensions.ExtensionKind.FloorDivisionOperatorType || - extensionKind === extensions.ExtensionKind.FloorDivisionOperatorMethodType - ) { - context.diagnostics.push(unsupportedForTarget(node, "Floor division operator", luaTarget)); - } - } - - const args = node.arguments.slice(); - if (binaryOperatorMappings.has(extensionKind)) { if ( - args.length === 1 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) + kind === ExtensionKind.FloorDivisionOperatorType || + kind === ExtensionKind.FloorDivisionOperatorMethodType ) { - args.unshift(node.expression.expression); - } - - const luaOperator = binaryOperatorMappings.get(extensionKind); - assert(luaOperator); - return lua.createBinaryExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - luaOperator - ); - } else { - let arg: ts.Expression; - if ( - args.length === 0 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - arg = node.expression.expression; + context.diagnostics.push(unsupportedForTarget(node, "Floor division operator", luaTarget)); } else { - arg = args[0]; + // is bitwise operator + context.diagnostics.push(unsupportedForTarget(node, "Native bitwise operations", luaTarget)); } - - const luaOperator = unaryOperatorMappings.get(extensionKind); - assert(luaOperator); - return lua.createUnaryExpression(context.transformExpression(arg), luaOperator); } } diff --git a/src/transformation/visitors/language-extensions/pairsIterable.ts b/src/transformation/visitors/language-extensions/pairsIterable.ts deleted file mode 100644 index a688ded2f..000000000 --- a/src/transformation/visitors/language-extensions/pairsIterable.ts +++ /dev/null @@ -1,84 +0,0 @@ -import * as ts from "typescript"; -import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; -import { TransformationContext } from "../../context"; -import { invalidPairsIterableWithoutDestructuring } from "../../utils/diagnostics"; -import * as extensions from "../../utils/language-extensions"; -import { getVariableDeclarationBinding, transformForInitializer } from "../loops/utils"; -import { transformArrayBindingElement } from "../variable-declaration"; - -function isPairsIterableType(type: ts.Type): boolean { - return extensions.isExtensionType(type, extensions.ExtensionKind.PairsIterableType); -} - -export function isPairsIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { - const type = context.checker.getTypeAtLocation(expression); - return isPairsIterableType(type); -} - -function isPairsKeyIterableType(type: ts.Type): boolean { - return extensions.isExtensionType(type, extensions.ExtensionKind.PairsKeyIterableType); -} - -export function isPairsKeyIterableExpression(context: TransformationContext, expression: ts.Expression): boolean { - const type = context.checker.getTypeAtLocation(expression); - return isPairsKeyIterableType(type); -} - -export function transformForOfPairsIterableStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ - context.transformExpression(statement.expression), - ]); - - let identifiers: lua.Identifier[] = []; - - if (ts.isVariableDeclarationList(statement.initializer)) { - // Variables declared in for loop - // for key, value in iterable do - const binding = getVariableDeclarationBinding(context, statement.initializer); - if (ts.isArrayBindingPattern(binding)) { - identifiers = binding.elements.map(e => transformArrayBindingElement(context, e)); - } else { - context.diagnostics.push(invalidPairsIterableWithoutDestructuring(binding)); - } - } else if (ts.isArrayLiteralExpression(statement.initializer)) { - // Variables NOT declared in for loop - catch iterator values in temps and assign - // for ____key, ____value in iterable do - // key, value = ____key, ____value - identifiers = statement.initializer.elements.map(e => context.createTempNameForNode(e)); - if (identifiers.length > 0) { - block.statements.unshift( - lua.createAssignmentStatement( - statement.initializer.elements.map(e => - cast(context.transformExpression(e), lua.isAssignmentLeftHandSideExpression) - ), - identifiers - ) - ); - } - } else { - context.diagnostics.push(invalidPairsIterableWithoutDestructuring(statement.initializer)); - } - - if (identifiers.length === 0) { - identifiers.push(lua.createAnonymousIdentifier()); - } - - return lua.createForInStatement(block, identifiers, [pairsCall], statement); -} - -export function transformForOfPairsKeyIterableStatement( - context: TransformationContext, - statement: ts.ForOfStatement, - block: lua.Block -): lua.Statement { - const pairsCall = lua.createCallExpression(lua.createIdentifier("pairs"), [ - context.transformExpression(statement.expression), - ]); - const identifier = transformForInitializer(context, statement.initializer, block); - return lua.createForInStatement(block, [identifier], [pairsCall], statement); -} diff --git a/src/transformation/visitors/language-extensions/range.ts b/src/transformation/visitors/language-extensions/range.ts index 43f297a9a..00647180c 100644 --- a/src/transformation/visitors/language-extensions/range.ts +++ b/src/transformation/visitors/language-extensions/range.ts @@ -7,14 +7,18 @@ import { transformIdentifier } from "../identifier"; import { transformArguments } from "../call"; import { assert } from "../../../utils"; import { invalidRangeControlVariable } from "../../utils/diagnostics"; +import { getExtensionKindForNode } from "../../utils/language-extensions"; export function isRangeFunction(context: TransformationContext, expression: ts.CallExpression): boolean { return isRangeFunctionNode(context, expression.expression); } export function isRangeFunctionNode(context: TransformationContext, node: ts.Node): boolean { - const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.RangeFunction) : false; + return ( + ts.isIdentifier(node) && + node.text === "$range" && + getExtensionKindForNode(context, node) === extensions.ExtensionKind.RangeFunction + ); } function getControlVariable(context: TransformationContext, statement: ts.ForOfStatement) { diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index eedc42c8e..2d22adf15 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -1,109 +1,44 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import * as extensions from "../../utils/language-extensions"; -import { getFunctionTypeForCall } from "../../utils/typescript"; +import { ExtensionKind, getExtensionKindForNode } from "../../utils/language-extensions"; import { transformExpressionList } from "../expression-list"; -import { unsupportedBuiltinOptionalCall } from "../../utils/diagnostics"; - -const tableCallExtensions = [ - extensions.ExtensionKind.TableDeleteType, - extensions.ExtensionKind.TableDeleteMethodType, - extensions.ExtensionKind.TableGetType, - extensions.ExtensionKind.TableGetMethodType, - extensions.ExtensionKind.TableHasType, - extensions.ExtensionKind.TableHasMethodType, - extensions.ExtensionKind.TableSetType, - extensions.ExtensionKind.TableSetMethodType, - extensions.ExtensionKind.TableAddType, - extensions.ExtensionKind.TableAddMethodType, -]; - -const tableExtensions = [extensions.ExtensionKind.TableNewType, ...tableCallExtensions]; - -function getTableExtensionKindForCall( - context: TransformationContext, - node: ts.CallExpression, - validExtensions: extensions.ExtensionKind[] -) { - const type = getFunctionTypeForCall(context, node); - return type && validExtensions.find(extensionKind => extensions.isExtensionType(type, extensionKind)); -} - -export function isTableExtensionIdentifier(context: TransformationContext, node: ts.Identifier) { - const type = context.checker.getTypeAtLocation(node); - return tableExtensions.some(extensionKind => extensions.isExtensionType(type, extensionKind)); -} +import { LanguageExtensionCallTransformer } from "./call-extension"; export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { - const type = context.checker.getTypeAtLocation(node.expression); - return extensions.isExtensionType(type, extensions.ExtensionKind.TableNewType); -} - -export function transformTableExtensionCall( - context: TransformationContext, - node: ts.CallExpression, - isOptionalCall: boolean -): lua.Expression | undefined { - const extensionType = getTableExtensionKindForCall(context, node, tableCallExtensions); - if (!extensionType) return; - if (isOptionalCall) { - context.diagnostics.push(unsupportedBuiltinOptionalCall(node)); - return lua.createNilLiteral(); - } - - if ( - extensionType === extensions.ExtensionKind.TableDeleteType || - extensionType === extensions.ExtensionKind.TableDeleteMethodType - ) { - return transformTableDeleteExpression(context, node, extensionType); - } - - if ( - extensionType === extensions.ExtensionKind.TableGetType || - extensionType === extensions.ExtensionKind.TableGetMethodType - ) { - return transformTableGetExpression(context, node, extensionType); - } - - if ( - extensionType === extensions.ExtensionKind.TableHasType || - extensionType === extensions.ExtensionKind.TableHasMethodType - ) { - return transformTableHasExpression(context, node, extensionType); - } - - if ( - extensionType === extensions.ExtensionKind.TableSetType || - extensionType === extensions.ExtensionKind.TableSetMethodType - ) { - return transformTableSetExpression(context, node, extensionType); - } - - if ( - extensionType === extensions.ExtensionKind.TableAddType || - extensionType === extensions.ExtensionKind.TableAddMethodType - ) { - return transformTableAddExpression(context, node, extensionType); - } + return getExtensionKindForNode(context, node.expression) === ExtensionKind.TableNewType; } +export const tableNewExtensions = [ExtensionKind.TableNewType]; + +export const tableExtensionTransformers: { [P in ExtensionKind]?: LanguageExtensionCallTransformer } = { + [ExtensionKind.TableDeleteType]: transformTableDeleteExpression, + [ExtensionKind.TableDeleteMethodType]: transformTableDeleteExpression, + [ExtensionKind.TableGetType]: transformTableGetExpression, + [ExtensionKind.TableGetMethodType]: transformTableGetExpression, + [ExtensionKind.TableHasType]: transformTableHasExpression, + [ExtensionKind.TableHasMethodType]: transformTableHasExpression, + [ExtensionKind.TableSetType]: transformTableSetExpression, + [ExtensionKind.TableSetMethodType]: transformTableSetExpression, + [ExtensionKind.TableAddKeyType]: transformTableAddExpression, + [ExtensionKind.TableAddKeyMethodType]: transformTableAddExpression, +}; function transformTableDeleteExpression( context: TransformationContext, node: ts.CallExpression, - extensionKind: extensions.ExtensionKind + extensionKind: ExtensionKind ): lua.Expression { const args = node.arguments.slice(); if ( - extensionKind === extensions.ExtensionKind.TableDeleteMethodType && + extensionKind === ExtensionKind.TableDeleteMethodType && (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) ) { // In case of method (no table argument), push method owner to front of args list args.unshift(node.expression.expression); } - // arg0[arg1] = nil const [table, accessExpression] = transformExpressionList(context, args); + // arg0[arg1] = nil context.addPrecedingStatements( lua.createAssignmentStatement( lua.createTableIndexExpression(table, accessExpression), @@ -114,21 +49,25 @@ function transformTableDeleteExpression( return lua.createBooleanLiteral(true); } +function transformWithTableArgument(context: TransformationContext, node: ts.CallExpression): lua.Expression[] { + if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { + return transformExpressionList(context, [node.expression.expression, ...node.arguments]); + } + // todo: report diagnostic? + return [lua.createNilLiteral(), ...transformExpressionList(context, node.arguments)]; +} + function transformTableGetExpression( context: TransformationContext, node: ts.CallExpression, - extensionKind: extensions.ExtensionKind + extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === extensions.ExtensionKind.TableGetMethodType && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - // In case of method (no table argument), push method owner to front of args list - args.unshift(node.expression.expression); - } + const args = + extensionKind === ExtensionKind.TableGetMethodType + ? transformWithTableArgument(context, node) + : transformExpressionList(context, node.arguments); - const [table, accessExpression] = transformExpressionList(context, args); + const [table, accessExpression] = args; // arg0[arg1] return lua.createTableIndexExpression(table, accessExpression, node); } @@ -136,19 +75,15 @@ function transformTableGetExpression( function transformTableHasExpression( context: TransformationContext, node: ts.CallExpression, - extensionKind: extensions.ExtensionKind + extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === extensions.ExtensionKind.TableHasMethodType && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - // In case of method (no table argument), push method owner to front of args list - args.unshift(node.expression.expression); - } + const args = + extensionKind === ExtensionKind.TableHasMethodType + ? transformWithTableArgument(context, node) + : transformExpressionList(context, node.arguments); + const [table, accessExpression] = args; // arg0[arg1] - const [table, accessExpression] = transformExpressionList(context, args); const tableIndexExpression = lua.createTableIndexExpression(table, accessExpression); // arg0[arg1] ~= nil @@ -163,19 +98,15 @@ function transformTableHasExpression( function transformTableSetExpression( context: TransformationContext, node: ts.CallExpression, - extensionKind: extensions.ExtensionKind + extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === extensions.ExtensionKind.TableSetMethodType && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - // In case of method (no table argument), push method owner to front of args list - args.unshift(node.expression.expression); - } + const args = + extensionKind === ExtensionKind.TableSetMethodType + ? transformWithTableArgument(context, node) + : transformExpressionList(context, node.arguments); + const [table, accessExpression, value] = args; // arg0[arg1] = arg2 - const [table, accessExpression, value] = transformExpressionList(context, args); context.addPrecedingStatements( lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), value, node) ); @@ -185,19 +116,15 @@ function transformTableSetExpression( function transformTableAddExpression( context: TransformationContext, node: ts.CallExpression, - extensionKind: extensions.ExtensionKind + extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === extensions.ExtensionKind.TableAddMethodType && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - // In case of method (no table argument), push method owner to front of args list - args.unshift(node.expression.expression); - } + const args = + extensionKind === ExtensionKind.TableAddKeyMethodType + ? transformWithTableArgument(context, node) + : transformExpressionList(context, node.arguments); + const [table, value] = args; // arg0[arg1] = true - const [table, value] = transformExpressionList(context, args); context.addPrecedingStatements( lua.createAssignmentStatement( lua.createTableIndexExpression(table, value), diff --git a/src/transformation/visitors/language-extensions/vararg.ts b/src/transformation/visitors/language-extensions/vararg.ts index 99eea82a9..4576737c8 100644 --- a/src/transformation/visitors/language-extensions/vararg.ts +++ b/src/transformation/visitors/language-extensions/vararg.ts @@ -1,16 +1,20 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; import * as extensions from "../../utils/language-extensions"; +import { getExtensionKindForSymbol } from "../../utils/language-extensions"; import { Scope, ScopeType } from "../../utils/scope"; export function isGlobalVarargConstant(context: TransformationContext, symbol: ts.Symbol, scope: Scope) { + return scope.type === ScopeType.File && isVarargConstantSymbol(context, symbol); +} +function isVarargConstantSymbol(context: TransformationContext, symbol: ts.Symbol) { return ( - scope.type === ScopeType.File && - extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) + symbol.getName() === "$vararg" && + getExtensionKindForSymbol(context, symbol) === extensions.ExtensionKind.VarargConstant ); } export function isVarargConstantNode(context: TransformationContext, node: ts.Node): boolean { const symbol = context.checker.getSymbolAtLocation(node); - return symbol ? extensions.isExtensionValue(context, symbol, extensions.ExtensionKind.VarargConstant) : false; + return symbol !== undefined && isVarargConstantSymbol(context, symbol); } diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index e33af39e6..838b8d5c2 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -2,19 +2,13 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext, Visitors } from "../context"; -import { - invalidMultiFunctionUse, - undefinedInArrayLiteral, - unsupportedAccessorInObjectLiteral, -} from "../utils/diagnostics"; -import { createExportedIdentifier, getSymbolExportScope } from "../utils/export"; +import { undefinedInArrayLiteral, unsupportedAccessorInObjectLiteral } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { createSafeName, hasUnsafeIdentifierName, hasUnsafeSymbolName } from "../utils/safe-names"; -import { getSymbolIdOfSymbol, trackSymbolReference } from "../utils/symbols"; +import { trackSymbolReference } from "../utils/symbols"; import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; -import { findMultiAssignmentViolations } from "./language-extensions/multi"; +import { transformIdentifierWithSymbol } from "./identifier"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -34,26 +28,7 @@ export function createShorthandIdentifier( valueSymbol: ts.Symbol | undefined, propertyIdentifier: ts.Identifier ): lua.Expression { - const propertyName = propertyIdentifier.text; - - const isUnsafeName = valueSymbol - ? hasUnsafeSymbolName(context, valueSymbol, propertyIdentifier) - : hasUnsafeIdentifierName(context, propertyIdentifier, false); - - const name = isUnsafeName ? createSafeName(propertyName) : propertyName; - - let identifier = context.transformExpression(ts.factory.createIdentifier(name)); - lua.setNodeOriginal(identifier, propertyIdentifier); - if (valueSymbol !== undefined && lua.isIdentifier(identifier)) { - identifier.symbolId = getSymbolIdOfSymbol(context, valueSymbol); - - const exportScope = getSymbolExportScope(context, valueSymbol); - if (exportScope) { - identifier = createExportedIdentifier(context, identifier, exportScope); - } - } - - return identifier; + return transformIdentifierWithSymbol(context, propertyIdentifier, valueSymbol); } const transformNumericLiteralExpression: FunctionVisitor = expression => { @@ -67,12 +42,6 @@ const transformNumericLiteralExpression: FunctionVisitor = ex }; const transformObjectLiteralExpression: FunctionVisitor = (expression, context) => { - const violations = findMultiAssignmentViolations(context, expression); - if (violations.length > 0) { - context.diagnostics.push(...violations.map(e => invalidMultiFunctionUse(e))); - return lua.createNilLiteral(expression); - } - const properties: lua.Expression[] = []; const initializers: ts.Node[] = []; const keyPrecedingStatements: lua.Statement[][] = []; diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index 70a64e643..c2da717c5 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -1,19 +1,17 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { AnnotationKind, isForRangeType, isLuaIteratorType } from "../../utils/annotations"; -import { annotationRemoved } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType } from "../../utils/typescript"; -import { isIterableExpression, transformForOfIterableStatement } from "../language-extensions/iterable"; import { - isPairsIterableExpression, + transformForOfIterableStatement, transformForOfPairsIterableStatement, - isPairsKeyIterableExpression, transformForOfPairsKeyIterableStatement, -} from "../language-extensions/pairsIterable"; +} from "../language-extensions/iterable"; import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformForInitializer, transformLoopBody } from "./utils"; +import { getIterableExtensionKindForNode, IterableExtensionKind } from "../../utils/language-extensions"; +import { assertNever } from "../../../utils"; function transformForOfArrayStatement( context: TransformationContext, @@ -49,19 +47,22 @@ export const transformForOfStatement: FunctionVisitor = (node if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { return transformRangeStatement(context, node, body); - } else if (ts.isCallExpression(node.expression) && isForRangeType(context, node.expression.expression)) { - context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.ForRange)); - } else if (isIterableExpression(context, node.expression)) { - return transformForOfIterableStatement(context, node, body); - } else if (isPairsIterableExpression(context, node.expression)) { - return transformForOfPairsIterableStatement(context, node, body); - } else if (isPairsKeyIterableExpression(context, node.expression)) { - return transformForOfPairsKeyIterableStatement(context, node, body); - } else if (isLuaIteratorType(context, node.expression)) { - context.diagnostics.push(annotationRemoved(node.expression, AnnotationKind.LuaIterator)); - } else if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { + } + const iterableExtensionType = getIterableExtensionKindForNode(context, node.expression); + if (iterableExtensionType) { + if (iterableExtensionType === IterableExtensionKind.Iterable) { + return transformForOfIterableStatement(context, node, body); + } else if (iterableExtensionType === IterableExtensionKind.Pairs) { + return transformForOfPairsIterableStatement(context, node, body); + } else if (iterableExtensionType === IterableExtensionKind.PairsKey) { + return transformForOfPairsKeyIterableStatement(context, node, body); + } else { + assertNever(iterableExtensionType); + } + } + if (isArrayType(context, context.checker.getTypeAtLocation(node.expression))) { return transformForOfArrayStatement(context, node, body); - } else { - return transformForOfIteratorStatement(context, node, body); } + + return transformForOfIteratorStatement(context, node, body); }; diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 3c5887281..e24a92269 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; -import { performHoisting, popScope, pushScope, ScopeType } from "../../utils/scope"; +import { performHoisting, ScopeType } from "../../utils/scope"; import { isAssignmentPattern } from "../../utils/typescript"; import { transformAssignment } from "../binary-expression/assignments"; import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; @@ -14,9 +14,9 @@ export function transformLoopBody( context: TransformationContext, loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement ): lua.Statement[] { - pushScope(context, ScopeType.Loop); + context.pushScope(ScopeType.Loop); const body = performHoisting(context, transformBlockOrStatement(context, loop.statement)); - const scope = popScope(context); + const scope = context.popScope(); const scopeId = scope.id; if (!scope.loopContinued) { @@ -50,7 +50,7 @@ export function transformForInitializer( ): lua.Identifier { const valueVariable = lua.createIdentifier("____value"); - pushScope(context, ScopeType.LoopInitializer); + context.pushScope(ScopeType.LoopInitializer); if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable @@ -63,7 +63,7 @@ export function transformForInitializer( block.statements.unshift(...precedingStatements, ...bindings); } else { // Single variable declared in for loop - popScope(context); + context.popScope(); return transformIdentifier(context, binding); } } else { @@ -76,7 +76,7 @@ export function transformForInitializer( ); } - popScope(context); + context.popScope(); return valueVariable; } diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 3f41d81b1..4e0727753 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -1,15 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { annotationRemoved } from "../utils/diagnostics"; import { addExportToIdentifier, createExportedIdentifier, getIdentifierExportScope } from "../utils/export"; import { createHoistableVariableDeclarationStatement, createLocalOrExportedOrGlobalDeclaration, } from "../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../utils/safe-names"; -import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { performHoisting, ScopeType } from "../utils/scope"; import { getSymbolIdOfSymbol } from "../utils/symbols"; import { transformIdentifier } from "./identifier"; @@ -47,17 +45,8 @@ function moduleHasEmittedBody( return false; } -// Static context -> namespace dictionary keeping the current namespace for each transformation context -const currentNamespaces = new WeakMap(); - export const transformModuleDeclaration: FunctionVisitor = (node, context) => { - const annotations = getTypeAnnotations(context.checker.getTypeAtLocation(node)); - // If phantom namespace elide the declaration and return the body - if (annotations.has(AnnotationKind.Phantom)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.Phantom)); - } - - const currentNamespace = currentNamespaces.get(context); + const currentNamespace = context.currentNamespaces; const result: lua.Statement[] = []; const symbol = context.checker.getSymbolAtLocation(node.name); @@ -115,20 +104,21 @@ export const transformModuleDeclaration: FunctionVisitor = // Set current namespace for nested NS // Keep previous namespace to reset after block transpilation - currentNamespaces.set(context, node); + + context.currentNamespaces = node; // Transform moduleblock to block and visit it if (moduleHasEmittedBody(node)) { - pushScope(context, ScopeType.Block); + context.pushScope(ScopeType.Block); const statements = performHoisting( context, context.transformStatements(ts.isModuleBlock(node.body) ? node.body.statements : node.body) ); - popScope(context); + context.popScope(); result.push(lua.createDoStatement(statements)); } - currentNamespaces.set(context, currentNamespace); + context.currentNamespaces = currentNamespace; return result; }; diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index ef2e36e51..13fceeecf 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -83,8 +83,6 @@ export function createReturnStatement( values: lua.Expression[], node: ts.Node ): lua.ReturnStatement { - const results = [...values]; - if (isInAsyncFunction(node)) { return lua.createReturnStatement([ lua.createCallExpression(lua.createIdentifier("____awaiter_resolve"), [lua.createNilLiteral(), ...values]), @@ -93,10 +91,10 @@ export function createReturnStatement( if (isInTryCatch(context)) { // Bubble up explicit return flag and check if we're inside a try/catch block - results.unshift(lua.createBooleanLiteral(true)); + values = [lua.createBooleanLiteral(true), ...values]; } - return lua.createReturnStatement(results, node); + return lua.createReturnStatement(values, node); } function isInTryCatch(context: TransformationContext): boolean { diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 903ec0a11..6870d292b 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -3,9 +3,8 @@ import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor } from "../context"; import { createExportsIdentifier } from "../utils/lua-ast"; -import { getUsedLuaLibFeatures } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; -import { performHoisting, popScope, pushScope, ScopeType } from "../utils/scope"; +import { performHoisting, ScopeType } from "../utils/scope"; import { hasExportEquals } from "../utils/typescript"; export const transformSourceFileNode: FunctionVisitor = (node, context) => { @@ -27,10 +26,10 @@ export const transformSourceFileNode: FunctionVisitor = (node, co statements.push(lua.createExpressionStatement(errorCall)); } } else { - pushScope(context, ScopeType.File); + context.pushScope(ScopeType.File); statements = performHoisting(context, context.transformStatements(node.statements)); - popScope(context); + context.popScope(); if (context.isModule) { // If export equals was not used. Create the exports table. @@ -47,5 +46,5 @@ export const transformSourceFileNode: FunctionVisitor = (node, co } const trivia = node.getFullText().match(/^#!.*\r?\n/)?.[0] ?? ""; - return lua.createFile(statements, getUsedLuaLibFeatures(context), trivia, node); + return lua.createFile(statements, context.usedLuaLibFeatures, trivia, node); }; diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 1cfbe18ea..270ee7d36 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,7 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { AnnotationKind, isVarargType } from "../utils/annotations"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { @@ -13,7 +12,6 @@ import { } from "../utils/scope"; import { isArrayType, findFirstNonOuterParent } from "../utils/typescript"; import { isMultiReturnCall } from "./language-extensions/multi"; -import { annotationRemoved } from "../utils/diagnostics"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; export function isOptimizedVarArgSpread(context: TransformationContext, symbol: ts.Symbol, identifier: ts.Identifier) { @@ -65,9 +63,6 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: export const transformSpreadElement: FunctionVisitor = (node, context) => { const tsInnerExpression = ts.skipOuterExpressions(node.expression); if (ts.isIdentifier(tsInnerExpression)) { - if (isVarargType(context, tsInnerExpression)) { - context.diagnostics.push(annotationRemoved(node, AnnotationKind.Vararg)); - } const symbol = context.checker.getSymbolAtLocation(tsInnerExpression); if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) { return lua.createDotsLiteral(node); diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index e14df3002..913e6ce71 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; -import { popScope, pushScope, ScopeType, separateHoistedStatements } from "../utils/scope"; +import { ScopeType, separateHoistedStatements } from "../utils/scope"; import { createShortCircuitBinaryExpressionPrecedingStatements } from "./binary-expression"; const containsBreakOrReturn = (nodes: Iterable): boolean => { @@ -64,7 +64,7 @@ const coalesceCondition = ( }; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { - const scope = pushScope(context, ScopeType.Switch); + const scope = context.pushScope(ScopeType.Switch); // Give the switch and condition accumulator a unique name to prevent nested switches from acting up. const switchName = `____switch${scope.id}`; @@ -242,7 +242,7 @@ export const transformSwitchStatement: FunctionVisitor = (st statements.unshift(lua.createVariableDeclarationStatement(hoistedIdentifiers)); } - popScope(context); + context.popScope(); // Add the switch expression after hoisting const expression = context.transformExpression(statement.expression); diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 9cae749ce..58dc8a76a 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -277,7 +277,7 @@ export function transformVariableDeclaration( if (!ts.isFunctionExpression(initializer) && !ts.isArrowFunction(initializer)) return false; // Skip named function expressions because they will have been wrapped already if (ts.isFunctionExpression(initializer) && initializer.name) return false; - return isFunctionTypeWithProperties(context.checker.getTypeAtLocation(statement.name)); + return isFunctionTypeWithProperties(context, context.checker.getTypeAtLocation(statement.name)); } } diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index f425c5488..13c96be64 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -4,6 +4,7 @@ import { CompilerOptions } from "../CompilerOptions"; import { Printer } from "../LuaPrinter"; import { Visitors } from "../transformation/context"; import { EmitFile, getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils"; +import * as performance from "../measure-performance"; export interface Plugin { /** @@ -47,6 +48,7 @@ export interface Plugin { } export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } { + performance.startSection("getPlugins"); const diagnostics: ts.Diagnostic[] = []; const pluginsFromOptions: Plugin[] = []; const options = program.getCompilerOptions() as CompilerOptions; @@ -73,5 +75,7 @@ export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; console.log(`Loaded ${pluginsFromOptions.length} plugins`); } + performance.endSection("getPlugins"); + return { diagnostics, plugins: pluginsFromOptions }; } diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 4bff1528c..d3f108955 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -23,9 +23,11 @@ interface ResolutionResult { } class ResolutionContext { - private resultsCache = new Map(); private noResolvePaths: Set; + public diagnostics: ts.Diagnostic[] = []; + public resolvedFiles = new Map(); + constructor( public readonly program: ts.Program, public readonly options: CompilerOptions, @@ -34,206 +36,183 @@ class ResolutionContext { this.noResolvePaths = new Set(options.noResolvePaths); } - public resolve(file: ProcessedFile, required: string): ResolutionResult { - if (this.noResolvePaths.has(required)) { - if (this.options.tstlVerbose) { - console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`); - } - return { resolvedFiles: [], diagnostics: [] }; - } + public addAndResolveDependencies(file: ProcessedFile): void { + if (this.resolvedFiles.has(file.fileName)) return; + this.resolvedFiles.set(file.fileName, file); + + for (const required of findRequiredPaths(file.code)) { + // Do not resolve noResolution paths + if (required.startsWith("@NoResolution:")) { + // Remove @NoResolution prefix if not building in library mode + if (!isBuildModeLibrary(this.program)) { + const path = required.replace("@NoResolution:", ""); + replaceRequireInCode(file, required, path); + replaceRequireInSourceMap(file, required, path); + } - const resolvedDependency = resolveDependency(file, required, this.program, this.emitHost); - if (resolvedDependency) { - if (this.options.tstlVerbose) { - console.log(`Resolved ${required} to ${normalizeSlashes(resolvedDependency)}`); + // Skip + continue; } + // Try to resolve the import starting from the directory `file` is in + this.resolveImport(file, required); + } + } - // Figure out resolved require path and dependency output path - const resolvedRequire = getEmitPathRelativeToOutDir(resolvedDependency, this.program); + public resolveImport(file: ProcessedFile, required: string): void { + // Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages + if (required === "lualib_bundle") { + this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" }); + return; + } - if (shouldRewriteRequires(resolvedDependency, this.program)) { - replaceRequireInCode(file, required, resolvedRequire); - replaceRequireInSourceMap(file, required, resolvedRequire); + if (this.noResolvePaths.has(required)) { + if (this.options.tstlVerbose) { + console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`); } + return; + } - // Check cache to prevent resolving nested dependencies double to break dependency loops - if (this.resultsCache.has(resolvedDependency)) { - if (this.options.tstlVerbose) { - console.log(`Resolution cache hit for ${normalizeSlashes(resolvedDependency)}`); - } - return this.resultsCache.get(resolvedDependency)!; - } + const dependencyPath = this.resolveDependencyPath(file, required); + if (!dependencyPath) return this.couldNotResolveImport(required, file); - // If dependency is not part of project, add dependency to output and resolve its dependencies recursively - if (shouldIncludeDependency(resolvedDependency, this.program)) { - // If dependency resolved successfully, read its content - const dependencyContent = this.emitHost.readFile(resolvedDependency); - if (dependencyContent === undefined) { - return { resolvedFiles: [], diagnostics: [couldNotReadDependency(resolvedDependency)] }; - } + if (this.options.tstlVerbose) { + console.log(`Resolved ${required} to ${normalizeSlashes(dependencyPath)}`); + } - const dependency = { - fileName: resolvedDependency, - code: dependencyContent, - }; - const nestedDependencies = resolveFileDependencies(dependency, this); - - // Cache result and return - const result = { - resolvedFiles: [dependency, ...nestedDependencies.resolvedFiles], - diagnostics: [...nestedDependencies.diagnostics], - }; - this.resultsCache.set(resolvedDependency, result); - return result; - } else { - const result = { - resolvedFiles: [], - diagnostics: [], - }; - this.resultsCache.set(resolvedDependency, result); - return result; - } - } else { - const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); - replaceRequireInCode(file, required, fallbackRequire); - replaceRequireInSourceMap(file, required, fallbackRequire); - - return { - resolvedFiles: [], - diagnostics: [ - couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)), - ], - }; + this.processDependency(dependencyPath); + // Figure out resolved require path and dependency output path + if (shouldRewriteRequires(dependencyPath, this.program)) { + const resolvedRequire = getEmitPathRelativeToOutDir(dependencyPath, this.program); + replaceRequireInCode(file, required, resolvedRequire); + replaceRequireInSourceMap(file, required, resolvedRequire); } } -} -export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { - const outFiles: ProcessedFile[] = [...files]; - const diagnostics: ts.Diagnostic[] = []; - const options = program.getCompilerOptions() as CompilerOptions; + public processedDependencies = new Set(); - const resolutionContext = new ResolutionContext(program, options, emitHost); + private processDependency(dependencyPath: string): void { + if (this.processedDependencies.has(dependencyPath)) return; + this.processedDependencies.add(dependencyPath); - // Resolve dependencies for all processed files - for (const file of files) { - if (options.tstlVerbose) { - console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); + if (!shouldIncludeDependency(dependencyPath, this.program)) return; + + // If dependency is not part of project, add dependency to output and resolve its dependencies recursively + const dependencyContent = this.emitHost.readFile(dependencyPath); + if (dependencyContent === undefined) { + this.diagnostics.push(couldNotReadDependency(dependencyPath)); + return; } - const resolutionResult = resolveFileDependencies(file, resolutionContext); - outFiles.push(...resolutionResult.resolvedFiles); - diagnostics.push(...resolutionResult.diagnostics); + const dependency = { + fileName: dependencyPath, + code: dependencyContent, + }; + this.addAndResolveDependencies(dependency); } - return { resolvedFiles: deduplicateResolvedFiles(outFiles), diagnostics }; -} - -function deduplicateResolvedFiles(files: ProcessedFile[]): ProcessedFile[] { - return [...new Map(files.map(f => [f.fileName, f])).values()]; -} + private couldNotResolveImport(required: string, file: ProcessedFile): void { + const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); + replaceRequireInCode(file, required, fallbackRequire); + replaceRequireInSourceMap(file, required, fallbackRequire); -function resolveFileDependencies(file: ProcessedFile, context: ResolutionContext): ResolutionResult { - const dependencies: ProcessedFile[] = []; - const diagnostics: ts.Diagnostic[] = []; + this.diagnostics.push( + couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)) + ); + } - for (const required of findRequiredPaths(file.code)) { - // Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages - if (required === "lualib_bundle") { - dependencies.push({ fileName: "lualib_bundle", code: "" }); - continue; + private resolveDependencyPath(requiringFile: ProcessedFile, dependency: string): string | undefined { + const fileDirectory = path.dirname(requiringFile.fileName); + if (this.options.tstlVerbose) { + console.log(`Resolving "${dependency}" from ${normalizeSlashes(requiringFile.fileName)}`); } - // Do not resolve noResolution paths - if (required.startsWith("@NoResolution:")) { - // Remove @NoResolution prefix if not building in library mode - if (!isBuildModeLibrary(context.program)) { - const path = required.replace("@NoResolution:", ""); - replaceRequireInCode(file, required, path); - replaceRequireInSourceMap(file, required, path); - } + // Check if the import is relative + const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); - // Skip - continue; - } + // If the import is relative, always resolve it relative to the requiring file + // If the import is not relative, resolve it relative to options.baseUrl if it is set + const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; - // Try to resolve the import starting from the directory `file` is in - const resolvedDependency = context.resolve(file, required); - dependencies.push(...resolvedDependency.resolvedFiles); - diagnostics.push(...resolvedDependency.diagnostics); - } - return { resolvedFiles: deduplicateResolvedFiles(dependencies), diagnostics }; -} + // Check if file is a file in the project + const resolvedPath = path.join(relativeTo, dependency); + const fileFromPath = this.getFileFromPath(resolvedPath); + if (fileFromPath) return fileFromPath; -function resolveDependency( - requiringFile: ProcessedFile, - dependency: string, - program: ts.Program, - emitHost: EmitHost -): string | undefined { - const options = program.getCompilerOptions() as CompilerOptions; - - const fileDirectory = path.dirname(requiringFile.fileName); - if (options.tstlVerbose) { - console.log(`Resolving "${dependency}" from ${normalizeSlashes(requiringFile.fileName)}`); - } + // Check if this is a sibling of a required lua file + if (requiringFile.fileName.endsWith(".lua")) { + const luaFilePath = resolveLuaPath(fileDirectory, dependency, this.emitHost); + if (luaFilePath) { + return luaFilePath; + } + } - // Check if the import is relative - const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); + // Not a TS file in our project sources, use resolver to check if we can find dependency + try { + const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); + if (resolveResult) return resolveResult; + } catch (e) { + // resolveSync errors if it fails to resolve + } - // If the import is relative, always resolve it relative to the requiring file - // If the import is not relative, resolve it relative to options.baseUrl if it is set - const relativeTo = isRelative ? fileDirectory : options.baseUrl ?? fileDirectory; + return undefined; + } - // Check if file is a file in the project - const resolvedPath = path.join(relativeTo, dependency); + // value is false if already searched but not found + private pathToFile = new Map(); - const possibleProjectFiles = [ - resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, - resolvedPath + ".ts", // Regular ts file - path.join(resolvedPath, "index.ts"), // Index ts file, - resolvedPath + ".tsx", // tsx file - path.join(resolvedPath, "index.tsx"), // tsx index - ]; + private getFileFromPath(resolvedPath: string): string | undefined { + const existingFile = this.pathToFile.get(resolvedPath); + if (existingFile) return existingFile; + if (existingFile === false) return undefined; - for (const possibleFile of possibleProjectFiles) { - if (isProjectFile(possibleFile, program)) { - return possibleFile; - } + const file = this.searchForFileFromPath(resolvedPath); + this.pathToFile.set(resolvedPath, file ?? false); + return file; } - // Check if this is a lua file in the project sources - const possibleLuaProjectFiles = [ - resolvedPath + ".lua", // lua file in sources - path.join(resolvedPath, "index.lua"), // lua index file in sources - path.join(resolvedPath, "init.lua"), // lua looks for /init.lua if it cannot find .lua - ]; - - for (const possibleFile of possibleLuaProjectFiles) { - if (emitHost.fileExists(possibleFile)) { - return possibleFile; + private searchForFileFromPath(resolvedPath: string): string | undefined { + const possibleProjectFiles = [ + resolvedPath, // JSON files need their extension as part of the import path, caught by this branch, + resolvedPath + ".ts", // Regular ts file + path.join(resolvedPath, "index.ts"), // Index ts file, + resolvedPath + ".tsx", // tsx file + path.join(resolvedPath, "index.tsx"), // tsx index + ]; + + for (const possibleFile of possibleProjectFiles) { + if (isProjectFile(possibleFile, this.program)) { + return possibleFile; + } } - } - // Check if this is a sibling of a required lua file - if (requiringFile.fileName.endsWith(".lua")) { - const luaFilePath = resolveLuaPath(fileDirectory, dependency, emitHost); - if (luaFilePath) { - return luaFilePath; + // Check if this is a lua file in the project sources + const possibleLuaProjectFiles = [ + resolvedPath + ".lua", // lua file in sources + path.join(resolvedPath, "index.lua"), // lua index file in sources + path.join(resolvedPath, "init.lua"), // lua looks for /init.lua if it cannot find .lua + ]; + for (const possibleFile of possibleLuaProjectFiles) { + if (this.emitHost.fileExists(possibleFile)) { + return possibleFile; + } } } +} + +export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { + const options = program.getCompilerOptions() as CompilerOptions; + + const resolutionContext = new ResolutionContext(program, options, emitHost); - // Not a TS file in our project sources, use resolver to check if we can find dependency - try { - const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); - if (resolveResult) { - return resolveResult; + // Resolve dependencies for all processed files + for (const file of files) { + if (options.tstlVerbose) { + console.log(`Resolving dependencies for ${normalizeSlashes(file.fileName)}`); } - } catch (e) { - // resolveSync errors if it fails to resolve + resolutionContext.addAndResolveDependencies(file); } - return undefined; + return { resolvedFiles: [...resolutionContext.resolvedFiles.values()], diagnostics: resolutionContext.diagnostics }; } function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost) { @@ -270,21 +249,16 @@ function walkUpFileTreeUntil(fromDirectory: string, predicate: (dir: string) => } function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { - return !isNodeModulesFile(resolvedDependency) || !isBuildModeLibrary(program); + return !isBuildModeLibrary(program) || !isNodeModulesFile(resolvedDependency); } function shouldIncludeDependency(resolvedDependency: string, program: ts.Program) { // Never include lua files (again) that are transpiled from project sources - if (!hasSourceFileInProject(resolvedDependency, program)) { - // Always include lua files not in node_modules (internal lua sources) - if (!isNodeModulesFile(resolvedDependency)) { - return true; - } else { - // Only include node_modules files if not in library mode - return !isBuildModeLibrary(program); - } - } - return false; + if (hasSourceFileInProject(resolvedDependency, program)) return false; + // Always include lua files not in node_modules (internal lua sources) + if (!isNodeModulesFile(resolvedDependency)) return true; + // Only include node_modules files if not in library mode + return !isBuildModeLibrary(program); } function isBuildModeLibrary(program: ts.Program) { diff --git a/src/transpilation/transpile.ts b/src/transpilation/transpile.ts index c693fa35a..6adfa5fc4 100644 --- a/src/transpilation/transpile.ts +++ b/src/transpilation/transpile.ts @@ -7,6 +7,7 @@ import { isNonNull } from "../utils"; import { Plugin } from "./plugins"; import { getTransformers } from "./transformers"; import { EmitHost, ProcessedFile } from "./utils"; +import * as performance from "../measure-performance"; export interface TranspileOptions { program: ts.Program; @@ -25,6 +26,8 @@ export function getProgramTranspileResult( writeFileResult: ts.WriteFileCallback, { program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins = [] }: TranspileOptions ): TranspileResult { + performance.startSection("beforeTransform"); + const options = program.getCompilerOptions() as CompilerOptions; if (options.tstlVerbose) { @@ -56,6 +59,7 @@ export function getProgramTranspileResult( } if (preEmitDiagnostics.length > 0) { + performance.endSection("beforeTransform"); return { diagnostics: preEmitDiagnostics, transpiledFiles }; } } @@ -69,15 +73,21 @@ export function getProgramTranspileResult( const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull)); const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull)); + const processSourceFile = (sourceFile: ts.SourceFile) => { if (options.tstlVerbose) { console.log(`Transforming ${sourceFile.fileName}`); } - const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); + performance.startSection("transpile"); + const { file, diagnostics: transformDiagnostics } = transformSourceFile(program, sourceFile, visitorMap); diagnostics.push(...transformDiagnostics); + + performance.endSection("transpile"); + if (!options.noEmit && !options.emitDeclarationOnly) { + performance.startSection("print"); if (options.tstlVerbose) { console.log(`Printing ${sourceFile.fileName}`); } @@ -89,6 +99,7 @@ export function getProgramTranspileResult( luaAst: file, ...printResult, }); + performance.endSection("print"); } }; @@ -109,6 +120,8 @@ export function getProgramTranspileResult( } }; + performance.endSection("beforeTransform"); + if (targetSourceFiles) { for (const file of targetSourceFiles) { if (isEmittableJsonFile(file)) { @@ -124,6 +137,8 @@ export function getProgramTranspileResult( program.getSourceFiles().filter(isEmittableJsonFile).forEach(processSourceFile); } + performance.startSection("afterPrint"); + options.noEmit = oldNoEmit; if (options.noEmit || (options.noEmitOnError && diagnostics.length > 0)) { @@ -137,5 +152,7 @@ export function getProgramTranspileResult( } } + performance.endSection("afterPrint"); + return { diagnostics, transpiledFiles }; } diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 6314fdded..216e80aba 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -4,10 +4,11 @@ import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; -import { getPlugins } from "./plugins"; +import { getPlugins, Plugin } from "./plugins"; import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; import { EmitFile, EmitHost, ProcessedFile } from "./utils"; +import * as performance from "../measure-performance"; export interface TranspilerOptions { emitHost?: EmitHost; @@ -24,28 +25,52 @@ export interface EmitResult { export class Transpiler { protected emitHost: EmitHost; + constructor({ emitHost = ts.sys }: TranspilerOptions = {}) { this.emitHost = emitHost; } public emit(emitOptions: EmitOptions): EmitResult { const { program, writeFile = this.emitHost.writeFile, plugins: optionsPlugins = [] } = emitOptions; - const options = program.getCompilerOptions() as CompilerOptions; const { diagnostics: getPluginsDiagnostics, plugins: configPlugins } = getPlugins(program); const plugins = [...optionsPlugins, ...configPlugins]; - const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(this.emitHost, writeFile, { - ...emitOptions, - plugins, - }); + const { diagnostics: transpileDiagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult( + this.emitHost, + writeFile, + { + ...emitOptions, + plugins, + } + ); + + const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles); - const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles); + const emitDiagnostics = this.emitFiles(program, plugins, emitPlan, writeFile); + + return { + diagnostics: getPluginsDiagnostics.concat(transpileDiagnostics, emitDiagnostics), + emitSkipped: emitPlan.length === 0, + }; + } + + private emitFiles( + program: ts.Program, + plugins: Plugin[], + emitPlan: EmitFile[], + writeFile: ts.WriteFileCallback + ): ts.Diagnostic[] { + performance.startSection("emit"); + + const options = program.getCompilerOptions() as CompilerOptions; if (options.tstlVerbose) { console.log("Emitting output"); } + const diagnostics: ts.Diagnostic[] = []; + for (const plugin of plugins) { if (plugin.beforeEmit) { const beforeEmitPluginDiagnostics = plugin.beforeEmit(program, options, this.emitHost, emitPlan) ?? []; @@ -69,7 +94,9 @@ export class Transpiler { console.log("Emit finished!"); } - return { diagnostics: getPluginsDiagnostics.concat(diagnostics), emitSkipped: emitPlan.length === 0 }; + performance.endSection("emit"); + + return diagnostics; } protected getEmitPlan( @@ -77,6 +104,7 @@ export class Transpiler { diagnostics: ts.Diagnostic[], files: ProcessedFile[] ): { emitPlan: EmitFile[] } { + performance.startSection("getEmitPlan"); const options = program.getCompilerOptions() as CompilerOptions; if (options.tstlVerbose) { @@ -113,6 +141,8 @@ export class Transpiler { })); } + performance.endSection("getEmitPlan"); + return { emitPlan }; } } diff --git a/src/tstl.ts b/src/tstl.ts index 01a1d463b..813347a21 100644 --- a/src/tstl.ts +++ b/src/tstl.ts @@ -7,6 +7,7 @@ import { parseCommandLine } from "./cli/parse"; import { createDiagnosticReporter } from "./cli/report"; import { createConfigFileUpdater, locateConfigFile, parseConfigFileWithSystem } from "./cli/tsconfig"; import { isBundleEnabled } from "./CompilerOptions"; +import * as performance from "./measure-performance"; const shouldBePretty = ({ pretty }: ts.CompilerOptions = {}) => pretty !== undefined ? (pretty as boolean) : ts.sys.writeOutputIsTTY?.() ?? false; @@ -95,20 +96,27 @@ function performCompilation( options: tstl.CompilerOptions, configFileParsingDiagnostics?: readonly ts.Diagnostic[] ): void { + if (options.measurePerformance) performance.enableMeasurement(); + + performance.startSection("createProgram"); + const program = ts.createProgram({ rootNames, options, projectReferences, configFileParsingDiagnostics, }); - const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); + performance.endSection("createProgram"); + const { diagnostics: transpileDiagnostics, emitSkipped } = new tstl.Transpiler().emit({ program }); const diagnostics = ts.sortAndDeduplicateDiagnostics([...preEmitDiagnostics, ...transpileDiagnostics]); - diagnostics.forEach(reportDiagnostic); + + if (options.measurePerformance) reportPerformance(); + const exitCode = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error).length === 0 ? ts.ExitStatus.Success @@ -158,6 +166,9 @@ function updateWatchCompilationHost( host.afterProgramCreate = builderProgram => { const program = builderProgram.getProgram(); const options = builderProgram.getCompilerOptions() as tstl.CompilerOptions; + + if (options.measurePerformance) performance.enableMeasurement(); + const configFileParsingDiagnostics: ts.Diagnostic[] = updateConfigFile(options); let sourceFiles: ts.SourceFile[] | undefined; @@ -188,6 +199,8 @@ function updateWatchCompilationHost( diagnostics.forEach(reportDiagnostic); + if (options.measurePerformance) reportPerformance(); + const errors = diagnostics.filter(d => d.category === ts.DiagnosticCategory.Error); hadErrorLastTime = errors.length > 0; @@ -195,6 +208,17 @@ function updateWatchCompilationHost( }; } +function reportPerformance() { + if (performance.isMeasurementEnabled()) { + console.log("Performance measurements: "); + performance.forEachMeasure((name, duration) => { + console.log(` ${name}: ${duration.toFixed(2)}ms`); + }); + console.log(`Total: ${performance.getTotalDuration().toFixed(2)}ms`); + performance.disableMeasurement(); + } +} + function checkNodeVersion(): void { const [major, minor] = process.version.slice(1).split(".").map(Number); const isValid = major > 12 || (major === 12 && minor >= 13); diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index c1e644fff..8d85b9374 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -24,8 +24,19 @@ declare module "typescript" { interface TypeChecker { getElementTypeOfArrayType(type: Type): Type | undefined; getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined; + + isTupleType(type: Type): boolean; + isArrayType(type: Type): boolean; + } + + interface Symbol { + // false positive + // eslint-disable-next-line @typescript-eslint/ban-types + parent?: Symbol; } + function getObjectFlags(type: Type): ObjectFlags; + function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; export type OuterExpression = diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 26fbcf046..94655ca01 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -5,7 +5,7 @@ exports[`Unsupported optional chains Builtin global method: code 1`] = ` local __TS__Number = ____lualib.__TS__Number local ____Number_result_0 = Number if ____Number_result_0 ~= nil then - ____Number_result_0 = nil + ____Number_result_0 = __TS__Number(\\"3\\") end" `; @@ -14,16 +14,22 @@ exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `" exports[`Unsupported optional chains Builtin global property: code 1`] = ` "local ____console_log_result_0 = console if ____console_log_result_0 ~= nil then - ____console_log_result_0 = nil + ____console_log_result_0 = print(\\"3\\") end" `; exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` -"local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach +local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach if ____table_forEach_result_0 ~= nil then - ____table_forEach_result_0 = nil + ____table_forEach_result_0 = __TS__ArrayForEach( + {1, 2, 3, 4}, + function() + end + ) end" `; @@ -57,7 +63,7 @@ exports[`Unsupported optional chains Compile members only: diagnostics 1`] = `"m exports[`Unsupported optional chains Language extensions: code 1`] = ` "local ____table_has_result_0 = ({}).has if ____table_has_result_0 ~= nil then - ____table_has_result_0 = nil + ____table_has_result_0 = nil[3] ~= nil end" `; diff --git a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap b/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap deleted file mode 100644 index 87d39ce95..000000000 --- a/test/unit/annotations/__snapshots__/deprecated.spec.ts.snap +++ /dev/null @@ -1,166 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`LuaTable deprecation warning property access set: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - return tbl:set(\\"foo\\", 0) -end -return ____exports" -`; - -exports[`LuaTable deprecation warning property access set: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; - -exports[`LuaTable removed warning constructor: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__New = ____lualib.__TS__New -____table = __TS__New(Table)" -`; - -exports[`LuaTable removed warning constructor: diagnostics 1`] = `"main.ts(11,15): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; - -exports[`LuaTable removed warning property access get: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - return tbl:get(\\"foo\\") -end -return ____exports" -`; - -exports[`LuaTable removed warning property access get: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; - -exports[`LuaTable removed warning property access length: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - return tbl.length -end -return ____exports" -`; - -exports[`LuaTable removed warning property access length: diagnostics 1`] = `"main.ts(12,16): error TSTL: '@luaTable' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luatable for more information."`; - -exports[`extension removed: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__Class = ____lualib.__TS__Class -local __TS__ClassExtends = ____lualib.__TS__ClassExtends ---- --- @extension -B = __TS__Class() -B.name = \\"B\\" -__TS__ClassExtends(B, A)" -`; - -exports[`extension removed: code 2`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__Class = ____lualib.__TS__Class -local __TS__ClassExtends = ____lualib.__TS__ClassExtends ---- --- @metaExtension -B = __TS__Class() -B.name = \\"B\\" -__TS__ClassExtends(B, A)" -`; - -exports[`extension removed: diagnostics 1`] = `"main.ts(4,9): error TSTL: '@extension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#extension for more information."`; - -exports[`extension removed: diagnostics 2`] = `"main.ts(4,9): error TSTL: '@metaExtension' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#metaextension for more information."`; - -exports[`forRange removed: code 1`] = `""`; - -exports[`forRange removed: diagnostics 1`] = `"main.ts(4,25): error TSTL: '@forRange' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#forrange for more information."`; - -exports[`luaiterator removed: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local arr = {\\"a\\", \\"b\\", \\"c\\"} - local function luaIter(self) - local i = 0 - return function() - local ____i_0 = i - i = ____i_0 + 1 - return arr[____i_0 + 1] - end - end - local result = \\"\\" - return result -end -return ____exports" -`; - -exports[`luaiterator removed: diagnostics 1`] = `"main.ts(10,23): error TSTL: '@luaIterator' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#luaiterator for more information."`; - -exports[`phantom removed: code 1`] = ` -"A = A or ({}) -do - local function nsMember(self) - end -end" -`; - -exports[`phantom removed: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@phantom' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#phantom for more information."`; - -exports[`pureAbstract removed: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") -local __TS__Class = ____lualib.__TS__Class -local __TS__ClassExtends = ____lualib.__TS__ClassExtends -ClassB = __TS__Class() -ClassB.name = \\"ClassB\\" -__TS__ClassExtends(ClassB, ClassA)" -`; - -exports[`pureAbstract removed: diagnostics 1`] = `"main.ts(4,22): error TSTL: '@pureAbstract' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#pureabstract for more information."`; - -exports[`tuplereturn lambda: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - --- - -- @tupleReturn - local function f() - return {3, 4} - end -end -return ____exports" -`; - -exports[`tuplereturn lambda: diagnostics 1`] = `"main.ts(2,39): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; - -exports[`tuplereturn removed on function declaration: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - --- - -- @tupleReturn - local function tuple(self) - return {3, 5, 1} - end -end -return ____exports" -`; - -exports[`tuplereturn removed on function declaration: diagnostics 1`] = `"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information."`; - -exports[`tuplereturn removed: code 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - --- - -- @tupleReturn - local function tuple(self) - return {3, 5, 1} - end - return tuple(nil)[3] -end -return ____exports" -`; - -exports[`tuplereturn removed: diagnostics 1`] = ` -"main.ts(3,9): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information. -main.ts(4,16): error TSTL: '@tupleReturn' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#tuplereturn for more information." -`; - -exports[`vararg removed: code 1`] = ` -"function foo(self, ...) -end -function vararg(self, ...) - foo(_G, ...) -end" -`; - -exports[`vararg removed: diagnostics 1`] = `"main.ts(6,17): error TSTL: '@vararg' has been removed and will no longer have any effect.See https://typescripttolua.github.io/docs/advanced/compiler-annotations#vararg for more information."`; diff --git a/test/unit/annotations/deprecated.spec.ts b/test/unit/annotations/deprecated.spec.ts deleted file mode 100644 index 091d681f2..000000000 --- a/test/unit/annotations/deprecated.spec.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { annotationRemoved } from "../../../src/transformation/utils/diagnostics"; -import * as util from "../../util"; - -test.each(["extension", "metaExtension"])("extension removed", extensionType => { - util.testModule` - declare class A {} - /** @${extensionType} */ - class B extends A {} - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("phantom removed", () => { - util.testModule` - /** @phantom */ - namespace A { - function nsMember() {} - } - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("pureAbstract removed", () => { - util.testModule` - /** @pureAbstract */ - declare class ClassA {} - class ClassB extends ClassA {} - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("forRange removed", () => { - util.testModule` - /** @forRange */ - declare function forRange(start: number, limit: number, step?: number): number[]; - for (const i of forRange(1, 10)) {} - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("vararg removed", () => { - util.testModule` - /** @vararg */ - type VarArg = T & { readonly __brand: unique symbol }; - function foo(...args: any[]) {} - function vararg(...args: VarArg) { - foo(...args); - } - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("luaiterator removed", () => { - util.testFunction` - const arr = ["a", "b", "c"]; - /** @luaIterator */ - interface Iter extends Iterable {} - function luaIter(): Iter { - let i = 0; - return (() => arr[i++]) as any; - } - let result = ""; - for (let e of luaIter()) { result += e; } - return result; - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("tuplereturn removed", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3, 5, 1]; } - return tuple()[2]; - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code, annotationRemoved.code]); // One annotation on the function, one on the call -}); - -test("tuplereturn removed on function declaration", () => { - util.testFunction` - /** @tupleReturn */ - function tuple(): [number, number, number] { return [3, 5, 1]; } - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("tuplereturn lambda", () => { - util.testFunction` - const f = /** @tupleReturn */ () => [3, 4]; - `.expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -const tableLibClass = ` -/** @luaTable */ -declare class Table { - length: number; - constructor(notAllowed?: any); - set(key?: K, value?: V, notAllowed?: any): void; - get(key?: K, notAllowed?: any): V; - other(): void; -} -declare let tbl: Table; -`; - -test("LuaTable removed warning constructor", () => { - util.testModule("const table = new Table();") - .setTsHeader(tableLibClass) - .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("LuaTable removed warning property access length", () => { - util.testFunction` - return tbl.length; - ` - .setTsHeader(tableLibClass) - .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("LuaTable removed warning property access get", () => { - util.testFunction` - return tbl.get("foo"); - ` - .setTsHeader(tableLibClass) - .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); - -test("LuaTable deprecation warning property access set", () => { - util.testFunction` - return tbl.set("foo", 0); - ` - .setTsHeader(tableLibClass) - .expectDiagnosticsToMatchSnapshot([annotationRemoved.code]); -}); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 9bb7fbebf..db745cb98 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -13,6 +13,10 @@ test("Supported lua string function", () => { util.testExpression`"test".upper()`.setTsHeader(tsHeader).expectToEqual("TEST"); }); +test("string.toString()", () => { + util.testExpression`"test".toString()`.expectToEqual("test"); +}); + test.each([[], [65], [65, 66], [65, 66, 67]])("String.fromCharCode (%p)", (...args) => { util.testExpression`String.fromCharCode(${util.formatCode(...args)})`.expectToMatchJsResult(); }); diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index 98678b857..a04b12eee 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -48,7 +48,7 @@ end" exports[`invalid $multi call (([a] = $multi(1)) => {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = nil"`; +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = {[\\"$multi\\"] = ____}"`; exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap index cfeef91c8..fff18a4cc 100644 --- a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -2,23 +2,23 @@ exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): code 1`] = `"foo = op(_G, 1, 2)"`; -exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; +exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must be called directly and cannot be referred to."`; exports[`operator mapping - invalid use (const foo = [op];): code 1`] = `"foo = {op}"`; -exports[`operator mapping - invalid use (const foo = [op];): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must always be directly called and cannot be referred to."`; +exports[`operator mapping - invalid use (const foo = [op];): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must be called directly and cannot be referred to."`; exports[`operator mapping - invalid use (const foo = \`\${op}\`): code 1`] = `"foo = tostring(op)"`; -exports[`operator mapping - invalid use (const foo = \`\${op}\`): diagnostics 1`] = `"main.ts(3,24): error TSTL: This function must always be directly called and cannot be referred to."`; +exports[`operator mapping - invalid use (const foo = \`\${op}\`): diagnostics 1`] = `"main.ts(3,24): error TSTL: This function must be called directly and cannot be referred to."`; exports[`operator mapping - invalid use (const foo: unknown = op;): code 1`] = `"foo = op"`; -exports[`operator mapping - invalid use (const foo: unknown = op;): diagnostics 1`] = `"main.ts(3,30): error TSTL: This function must always be directly called and cannot be referred to."`; +exports[`operator mapping - invalid use (const foo: unknown = op;): diagnostics 1`] = `"main.ts(3,30): error TSTL: This function must be called directly and cannot be referred to."`; exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): code 1`] = `"foo(_G, op)"`; -exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must always be directly called and cannot be referred to."`; +exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must be called directly and cannot be referred to."`; exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index c84f8aac9..bdd28339c 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -1,9 +1,8 @@ import * as path from "path"; import * as util from "../../util"; import * as tstl from "../../../src"; -import { invalidOperatorMappingUse } from "../../../src/transformation/utils/diagnostics"; import { LuaTarget } from "../../../src"; -import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; +import { unsupportedForTarget, invalidCallExtensionUse } from "../../../src/transformation/utils/diagnostics"; const operatorsProjectOptions: tstl.CompilerOptions = { luaTarget: LuaTarget.Lua54, @@ -388,5 +387,5 @@ test.each([ ${invalidCode} ` .setOptions(operatorsProjectOptions) - .expectDiagnosticsToMatchSnapshot([invalidOperatorMappingUse.code]); + .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index f42ababa7..90e9b8394 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -1,5 +1,5 @@ import * as util from "../../util"; -import { invalidTableExtensionUse } from "../../../src/transformation/utils/diagnostics"; +import { invalidCallExtensionUse } from "../../../src/transformation/utils/diagnostics"; describe("LuaTableGet & LuaTableSet extensions", () => { test("stand-alone function", () => { @@ -78,7 +78,7 @@ describe("LuaTableGet & LuaTableSet extensions", () => { ${statement} ` .withLanguageExtensions() - .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); }); @@ -168,7 +168,7 @@ describe("LuaTableHas extension", () => { ${statement} ` .withLanguageExtensions() - .expectDiagnosticsToMatchSnapshot([invalidTableExtensionUse.code]); + .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); }); From b0deccc48bb9598e6d9e5452e63ebf727b7f53ca Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 18 Jul 2022 22:18:52 +0200 Subject: [PATCH 503/764] Fix benchmark (#1310) --- .github/workflows/ci.yml | 26 ++++++++++---- .github/workflows/release.yml | 2 +- package-lock.json | 67 +++++++++++++---------------------- package.json | 2 +- 4 files changed, 46 insertions(+), 51 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8cfb0d49..65a3c2637 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 15.14.0 + - name: Use Node.js 16.14.0 uses: actions/setup-node@v1 with: node-version: 16.14.0 @@ -59,16 +59,30 @@ jobs: uses: actions/checkout@v2 with: path: commit - - name: Use Node.js 12.13.1 + - name: Use Node.js 16.14.0 uses: actions/setup-node@v1 with: node-version: 16.14.0 # NPM - - name: NPM master - run: npm ci && npm run build + # install and build master + - name: npm ci master + run: npm ci working-directory: master - - name: NPM commit - run: npm ci && npm run build + - name: Use local tstl language extensions + run: npm i lua-types@latest && npm i -D file:. + working-directory: master + - name: Build master + run: npm run build + working-directory: master + # install and build commit + - name: npm ci commit + run: npm ci + working-directory: commit + - name: Use local tstl language extensions + run: npm i -D file:. + working-directory: commit + - name: Build commit + run: npm run build working-directory: commit # Benchmark directory setup - name: Ensure benchmark data dir exists diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 22e242d03..904eae1b0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -11,7 +11,7 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 12.13.1 + - name: Use Node.js 16.14.0 uses: actions/setup-node@v1 with: node-version: 16.14.0 diff --git a/package-lock.json b/package-lock.json index e8b7cb5eb..72ae0649f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "javascript-stringify": "^2.0.1", "jest": "^27.3.0", "jest-circus": "^27.3.0", - "lua-types": "2.10.1", + "lua-types": "^2.11.0", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^27.1.3", @@ -4803,12 +4803,12 @@ } }, "node_modules/lua-types": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", - "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", + "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", "dev": true, - "dependencies": { - "typescript-to-lua": "^0.39.0" + "peerDependencies": { + "typescript-to-lua": "^1.0.0" } }, "node_modules/lua-wasm-bindings": { @@ -6038,34 +6038,24 @@ } }, "node_modules/typescript-to-lua": { - "version": "0.39.6", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", - "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", + "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", "dev": true, + "peer": true, "dependencies": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.3.2" + "source-map": "^0.7.3" }, "bin": { "tstl": "dist/tstl.js" }, "engines": { "node": ">=12.13.0" - } - }, - "node_modules/typescript-to-lua/node_modules/typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" }, - "engines": { - "node": ">=4.2.0" + "peerDependencies": { + "typescript": "~4.7.3" } }, "node_modules/unbox-primitive": { @@ -9984,13 +9974,11 @@ } }, "lua-types": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.10.1.tgz", - "integrity": "sha512-Ai7L25I5kHZYGN5C3LALUse7Eus0k/kM9tEO2zwReG2Xuker0c+0e2M4iyfiEvlGOmBc7cDouqJ5lFwyg8JqiQ==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", + "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", "dev": true, - "requires": { - "typescript-to-lua": "^0.39.0" - } + "requires": {} }, "lua-wasm-bindings": { "version": "0.2.2", @@ -10863,22 +10851,15 @@ "dev": true }, "typescript-to-lua": { - "version": "0.39.6", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-0.39.6.tgz", - "integrity": "sha512-Yq+XsmFKknMlz9jm1FvTw5B7R4H8lYUly4uwxlR44aT4OFyG9S7mOImrTIF07j414PdrJSQ5dAAhQOBVRqHbMw==", + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", + "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", "dev": true, + "peer": true, "requires": { + "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", - "source-map": "^0.7.3", - "typescript": "~4.3.2" - }, - "dependencies": { - "typescript": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz", - "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==", - "dev": true - } + "source-map": "^0.7.3" } }, "unbox-primitive": { diff --git a/package.json b/package.json index f01b5790d..73ee89025 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "javascript-stringify": "^2.0.1", "jest": "^27.3.0", "jest-circus": "^27.3.0", - "lua-types": "2.10.1", + "lua-types": "^2.11.0", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", "ts-jest": "^27.1.3", From c96283709f9410c8a5d680b31773f52eb77d6d0e Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 19 Jul 2022 09:55:50 -0700 Subject: [PATCH 504/764] Fixes for Optimize PR (#1312) * Fix function prototype calls for explicitly given function types * Fix getPropertyValue type flags optimization. * Fix language extension calls in optional chaining --- src/transformation/builtins/function.ts | 2 +- src/transformation/builtins/index.ts | 2 ++ .../utils/language-extensions.ts | 10 +++++--- test/unit/functions/functions.spec.ts | 23 ++++++++++++------- test/unit/language-extensions/table.spec.ts | 19 +++++++++++++++ 5 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index ebf0a83ca..f2ee043c9 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -4,9 +4,9 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedForTarget, unsupportedProperty, unsupportedSelfFunctionConversion } from "../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../utils/function-context"; -import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformCallAndArguments } from "../visitors/call"; +import { createUnpackCall } from "../utils/lua-ast"; export function transformFunctionPrototypeCall( context: TransformationContext, diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index f7ed149b9..b5a92095b 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -145,6 +145,8 @@ function tryTransformBuiltinPropertyCall( case "ReadonlyArray": return transformArrayPrototypeCall(context, node, calledMethod); case "Function": + case "CallableFunction": + case "NewableFunction": return transformFunctionPrototypeCall(context, node, calledMethod); } } diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index f5e446195..bb904471f 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -63,8 +63,8 @@ export function getExtensionKindForType(context: TransformationContext, type: ts } const excludedTypeFlags: ts.TypeFlags = - ((1 << 18) - 1) & // All flags from Any...Never - ts.TypeFlags.Index & + ((1 << 18) - 1) | // All flags from Any...Never + ts.TypeFlags.Index | ts.TypeFlags.NonPrimitive; function getPropertyValue(context: TransformationContext, type: ts.Type, propertyName: string): string | undefined { @@ -76,7 +76,11 @@ function getPropertyValue(context: TransformationContext, type: ts.Type, propert } export function getExtensionKindForNode(context: TransformationContext, node: ts.Node): ExtensionKind | undefined { - const type = context.checker.getTypeAtLocation(node); + const originalNode = ts.getOriginalNode(node); + let type = context.checker.getTypeAtLocation(originalNode); + if (ts.isOptionalChain(originalNode)) { + type = context.checker.getNonNullableType(type); + } return getExtensionKindForType(context, type); } diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 6c8819f70..8f2dc1199 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -159,24 +159,31 @@ test("Class static dot method with parameter", () => { `.expectToMatchJsResult(); }); -test("Function bind", () => { +const functionTypeDeclarations = [ + ["arrow", ": (...args: any) => any"], + ["call signature", ": { (...args: any): any; }"], + ["generic", ": Function"], + ["inferred", ""], +]; + +test.each(functionTypeDeclarations)("Function bind (%s)", (_, type) => { util.testFunction` - const abc = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } + const abc${type} = function (this: { a: number }, a: string, b: string) { return this.a + a + b; } return abc.bind({ a: 4 }, "b")("c"); `.expectToMatchJsResult(); }); -test("Function apply", () => { +test.each(functionTypeDeclarations)("Function apply (%s)", (_, type) => { util.testFunction` - const abc = function (this: { a: number }, a: string) { return this.a + a; } + const abc${type} = function (this: { a: number }, a: string) { return this.a + a; } return abc.apply({ a: 4 }, ["b"]); `.expectToMatchJsResult(); }); // Fix #1226: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1226 -test("function apply without arguments should not lead to exception", () => { +test.each(functionTypeDeclarations)("function apply without arguments should not lead to exception (%s)", (_, type) => { util.testFunction` - const f = function (this: number) { return this + 3; } + const f${type} = function (this: number) { return this + 3; } return f.apply(4); `.expectToMatchJsResult(); }); @@ -193,9 +200,9 @@ test.each(["() => 4", "undefined"])("prototype call on nullable function (%p)", .expectToMatchJsResult(); }); -test("Function call", () => { +test.each(functionTypeDeclarations)("Function call (%s)", (_, type) => { util.testFunction` - const abc = function (this: { a: number }, a: string) { return this.a + a; } + const abc${type} = function (this: { a: number }, a: string) { return this.a + a; } return abc.call({ a: 4 }, "b"); `.expectToMatchJsResult(); }); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 90e9b8394..8f21dc8d1 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -424,3 +424,22 @@ describe("LuaTable extension interface", () => { .expectToEqual({ foo: 1, bar: 3, baz: 5 }); }); }); + +test.each([ + [undefined, undefined], + ["new LuaSet()", true], +])("call on optional table with strictNullChecks (%s)", (value, expected) => { + util.testFunction` + function getFoo(): LuaSet | undefined { + return ${value} + } + const foo = getFoo() + foo?.add("foo") + return foo?.has("foo") + ` + .setOptions({ + strictNullChecks: true, + }) + .withLanguageExtensions() + .expectToEqual(expected); +}); From 4b83485ce26839b256e71954e4b3a136385f9e6c Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Tue, 19 Jul 2022 09:56:06 -0700 Subject: [PATCH 505/764] Update tsconfig-schema (#1311) --- tsconfig-schema.json | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tsconfig-schema.json b/tsconfig-schema.json index ca6f9be8c..5a3543a03 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -23,6 +23,10 @@ "default": "library", "enum": ["default", "library"] }, + "extension": { + "description": "File extension for the resulting Lua files. Defaults to \".lua\"", + "type": "string" + }, "lua51AllowTryCatchInAsyncAwait": { "description": "Disable the warning that try/catch is not allowed in async functions in Lua 5.1, in case you are using a patched 5.1 lua version that supports this.", "type": "boolean", @@ -40,13 +44,13 @@ "description": "Specifies how js standard features missing in lua are imported.", "type": "string", "default": "require", - "enum": ["none", "always", "inline", "require"] + "enum": ["none", "inline", "require"] }, "luaTarget": { "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["5.1", "5.2", "5.3", "JIT"] + "enum": ["universal", "5.1", "5.2", "5.3", "JIT"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", @@ -94,6 +98,10 @@ } } } + }, + "measurePerformance": { + "description": "Measure and report performance of the tstl compiler.", + "type": "boolean" } }, "dependencies": { From 37c4779aa6d0343cc137722294fda34dc86a54b5 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 19 Jul 2022 19:39:59 +0200 Subject: [PATCH 506/764] CHANGELOG.md 1.7.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e786c078..c1b6475c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.7.0 + +- Added support for `LuaMap` and `LuaSet` language extensions that translate to very low level Lua table operations. See [our docs](https://typescripttolua.github.io/docs/advanced/language-extensions/#luamap-and-luaset) for more information. +- Big performance improvements, speeding up TSTL translation by 2-3x. Thanks @GlassBricks! +- Reduced the use of temorary variables. +- Moved tsconfig-schema into main TypeScriptToLua repository. +- Added support for array options in tstl CLI. +- Fixed bug where promise `then` was not correctly forwarding the result value to chained promises. +- Fixed a bug causing false positive errors from jsdoc documentation comments. +- Fixed various calling context bugs. + ## 1.6.0 - **[Breaking]** Upgraded TypeScript to 4.7 From a21e6557eda90de9d96dc964badf0cd498433b49 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 19 Jul 2022 19:51:37 +0200 Subject: [PATCH 507/764] 1.7.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72ae0649f..e3df6feaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.6.3", + "version": "1.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.6.3", + "version": "1.7.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 73ee89025..1aec869fe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.6.3", + "version": "1.7.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 92c6e0aed245588c530e49f1022626913984eb51 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Wed, 20 Jul 2022 09:33:37 -0700 Subject: [PATCH 508/764] Rename LuaReadonlyMap/Set to ReadonlyLuaMap/Set (#1313) --- language-extensions/index.d.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index c18e68690..ac2e129bb 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -630,7 +630,7 @@ declare const LuaMap: (new () => LuaMa * @param K The type of the keys used to access the table. * @param V The type of the values stored in the table. */ -declare interface LuaReadonlyMap extends LuaPairsIterable { +declare interface ReadonlyLuaMap extends LuaPairsIterable { get: LuaTableGetMethod; has: LuaTableHasMethod; } @@ -660,6 +660,6 @@ declare const LuaSet: (new () => LuaSet) & L * * @param T The type of the keys used to access the table. */ -declare interface LuaReadonlySet extends LuaPairsKeyIterable { +declare interface ReadonlyLuaSet extends LuaPairsKeyIterable { has: LuaTableHasMethod; } From a21b9f77ad49fc908233c62d2083db41b953e2ef Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Wed, 20 Jul 2022 23:53:51 -0700 Subject: [PATCH 509/764] Add ObjectConstructor method overrides for LuaPairsIterable types (#1314) --- language-extensions/index.d.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index ac2e129bb..37f4809c8 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -663,3 +663,14 @@ declare const LuaSet: (new () => LuaSet) & L declare interface ReadonlyLuaSet extends LuaPairsKeyIterable { has: LuaTableHasMethod; } + +interface ObjectConstructor { + /** Returns an array of keys of an object, when iterated with `pairs`. */ + keys(o: LuaPairsIterable | LuaPairsKeyIterable): K[]; + + /** Returns an array of values of an object, when iterated with `pairs`. */ + values(o: LuaPairsIterable): V[]; + + /** Returns an array of key/values of an object, when iterated with `pairs`. */ + entries(o: LuaPairsIterable): Array<[K, V]>; +} From 100120778be862c725068a37d9af4922a790c6e2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 21 Jul 2022 18:08:55 +0200 Subject: [PATCH 510/764] 1.7.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e3df6feaa..d0a132d14 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.7.0", + "version": "1.7.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.7.0", + "version": "1.7.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 1aec869fe..7d5f55f4b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.7.0", + "version": "1.7.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From bd3bcedd0f61c5cd595aec45a5b2713a988b4604 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 29 Jul 2022 22:10:44 +0200 Subject: [PATCH 511/764] Fix lua file resolutoin using the wrong root dirs (#1316) --- src/transpilation/resolve.ts | 82 +++++++++---------- test/transpile/module-resolution.spec.ts | 13 +++ .../index.ts | 1 + .../node_modules/mymodule/constants.lua | 3 + .../mymodule/feature/constants.lua | 3 + .../node_modules/mymodule/feature/feature.lua | 8 ++ .../node_modules/mymodule/index.d.ts | 2 + .../node_modules/mymodule/index.lua | 10 +++ .../tsconfig.json | 1 + 9 files changed, 80 insertions(+), 43 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/index.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/constants.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/constants.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/feature.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.d.ts create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.lua create mode 100644 test/transpile/module-resolution/project-with-dependency-with-same-file-names/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index d3f108955..ccf0bdfa4 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -126,6 +126,15 @@ class ResolutionContext { console.log(`Resolving "${dependency}" from ${normalizeSlashes(requiringFile.fileName)}`); } + const requiredFromLuaFile = requiringFile.fileName.endsWith(".lua"); + const dependencyPath = requiredFromLuaFile ? luaRequireToPath(dependency) : dependency; + + if (requiredFromLuaFile && isNodeModulesFile(requiringFile.fileName)) { + // If requiring file is in lua module, try to resolve sibling in that file first + const resolvedNodeModulesFile = this.resolveLuaDependencyPathFromNodeModules(requiringFile, dependencyPath); + if (resolvedNodeModulesFile) return resolvedNodeModulesFile; + } + // Check if the import is relative const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); @@ -134,21 +143,13 @@ class ResolutionContext { const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; // Check if file is a file in the project - const resolvedPath = path.join(relativeTo, dependency); + const resolvedPath = path.join(relativeTo, dependencyPath); const fileFromPath = this.getFileFromPath(resolvedPath); if (fileFromPath) return fileFromPath; - // Check if this is a sibling of a required lua file - if (requiringFile.fileName.endsWith(".lua")) { - const luaFilePath = resolveLuaPath(fileDirectory, dependency, this.emitHost); - if (luaFilePath) { - return luaFilePath; - } - } - // Not a TS file in our project sources, use resolver to check if we can find dependency try { - const resolveResult = resolver.resolveSync({}, fileDirectory, dependency); + const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); if (resolveResult) return resolveResult; } catch (e) { // resolveSync errors if it fails to resolve @@ -157,6 +158,30 @@ class ResolutionContext { return undefined; } + private resolveLuaDependencyPathFromNodeModules( + requiringFile: ProcessedFile, + dependency: string + ): string | undefined { + // We don't know for sure where the lua root is, so guess it is at package root + const splitPath = path.normalize(requiringFile.fileName).split(path.sep); + let packageRootIndex = splitPath.lastIndexOf("node_modules") + 2; + let packageRoot = splitPath.slice(0, packageRootIndex).join(path.sep); + + while (packageRootIndex < splitPath.length) { + // Try to find lua file relative to currently guessed Lua root + const resolvedPath = path.join(packageRoot, dependency); + const fileFromPath = this.getFileFromPath(resolvedPath); + if (fileFromPath) { + return fileFromPath; + } else { + // Did not find file at current root, try again one directory deeper + packageRoot = path.join(packageRoot, splitPath[packageRootIndex++]); + } + } + + return undefined; + } + // value is false if already searched but not found private pathToFile = new Map(); @@ -215,39 +240,6 @@ export function resolveDependencies(program: ts.Program, files: ProcessedFile[], return { resolvedFiles: [...resolutionContext.resolvedFiles.values()], diagnostics: resolutionContext.diagnostics }; } -function resolveLuaPath(fromPath: string, dependency: string, emitHost: EmitHost) { - const splitDependency = dependency.split("."); - if (splitDependency.length === 1) { - // If dependency has just one part (the file), look for a lua file with that name - const fileDirectory = walkUpFileTreeUntil(fromPath, dir => - emitHost.fileExists(path.join(dir, dependency) + ".lua") - ); - if (fileDirectory) { - return path.join(fileDirectory, dependency) + ".lua"; - } - } else { - // If dependency has multiple parts, look for the first directory of the require path, which must be in the lua root - const luaRoot = walkUpFileTreeUntil(fromPath, dir => - emitHost.directoryExists(path.join(dir, splitDependency[0])) - ); - if (luaRoot) { - return path.join(luaRoot, dependency.replace(/\./g, path.sep)) + ".lua"; - } - } -} - -function walkUpFileTreeUntil(fromDirectory: string, predicate: (dir: string) => boolean) { - const currentDir = path.normalize(fromDirectory).split(path.sep); - while (currentDir.length > 0) { - const dir = currentDir.join(path.sep); - if (predicate(dir)) { - return dir; - } - currentDir.pop(); - } - return undefined; -} - function shouldRewriteRequires(resolvedDependency: string, program: ts.Program) { return !isBuildModeLibrary(program) || !isNodeModulesFile(resolvedDependency); } @@ -344,3 +336,7 @@ function fallbackResolve(required: string, sourceRootDir: string, fileDir: strin .join(path.sep) ); } + +function luaRequireToPath(requirePath: string): string { + return requirePath.replace(/\./g, path.sep); +} diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index cd7869c70..c18990225 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -525,3 +525,16 @@ test("require matches correct pattern", () => { .addExtraFile("c.lua", "return function(self, a) return a end") .expectToEqual({ addResult: 3 + 5, callResult: "foo" }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1307 +test("lualib_module with parent directory import (#1307)", () => { + const projectDir = path.join(__dirname, "module-resolution", "project-with-dependency-with-same-file-names"); + const inputProject = path.join(projectDir, "tsconfig.json"); + + util.testProject(inputProject).setMainFileName(path.join(projectDir, "index.ts")).expectToEqual({ + // eslint-disable-next-line @typescript-eslint/naming-convention + BASE_CONSTANT: 123, + // eslint-disable-next-line @typescript-eslint/naming-convention + FEATURE_CONSTANT: 456, + }); +}); diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/index.ts b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/index.ts new file mode 100644 index 000000000..0ab21dc4e --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/index.ts @@ -0,0 +1 @@ +export * from "mymodule"; diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/constants.lua b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/constants.lua new file mode 100644 index 000000000..de5917dd7 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/constants.lua @@ -0,0 +1,3 @@ +local ____exports = {} +____exports.BASE_CONSTANT = 123 +return ____exports diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/constants.lua b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/constants.lua new file mode 100644 index 000000000..9d3bd6110 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/constants.lua @@ -0,0 +1,3 @@ +local ____exports = {} +____exports.FEATURE_CONSTANT = 456 +return ____exports diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/feature.lua b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/feature.lua new file mode 100644 index 000000000..103496eaa --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/feature/feature.lua @@ -0,0 +1,8 @@ +local ____exports = {} +local ____constants = require("constants") +local BASE_CONSTANT = ____constants.BASE_CONSTANT +local ____constants = require("feature.constants") +local FEATURE_CONSTANT = ____constants.FEATURE_CONSTANT +____exports.BASE_CONSTANT = BASE_CONSTANT +____exports.FEATURE_CONSTANT = FEATURE_CONSTANT +return ____exports diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.d.ts b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.d.ts new file mode 100644 index 000000000..90401efad --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.d.ts @@ -0,0 +1,2 @@ +export declare const BASE_CONSTANT: number; +export declare const FEATURE_CONSTANT: number; diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.lua b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.lua new file mode 100644 index 000000000..4e57411d3 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/node_modules/mymodule/index.lua @@ -0,0 +1,10 @@ +local ____exports = {} +do + local ____export = require("feature.feature") + for ____exportKey, ____exportValue in pairs(____export) do + if ____exportKey ~= "default" then + ____exports[____exportKey] = ____exportValue + end + end +end +return ____exports diff --git a/test/transpile/module-resolution/project-with-dependency-with-same-file-names/tsconfig.json b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/transpile/module-resolution/project-with-dependency-with-same-file-names/tsconfig.json @@ -0,0 +1 @@ +{} From a4f2666cb5a67dbd96b3452cd0bb87b83ce174d1 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Wed, 3 Aug 2022 12:21:25 -0700 Subject: [PATCH 512/764] Fix nested destructuring in for-loop initialization with multi-return (#1318) * Fix nested destructuring in for-loop initialization in multi-return * Fix tests --- .../visitors/language-extensions/iterable.ts | 3 ++ .../__snapshots__/iterable.spec.ts.snap | 4 +- .../unit/language-extensions/iterable.spec.ts | 45 +++++++++++++------ 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts index dc792df6d..5d96f409e 100644 --- a/src/transformation/visitors/language-extensions/iterable.ts +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -17,6 +17,7 @@ function transformForOfMultiIterableStatement( luaIterator: lua.Expression, invalidMultiUseDiagnostic: (node: ts.Node) => ts.Diagnostic ): lua.Statement { + context.pushPrecedingStatements(); let identifiers: lua.Identifier[] = []; if (ts.isVariableDeclarationList(statement.initializer)) { @@ -51,6 +52,8 @@ function transformForOfMultiIterableStatement( identifiers.push(lua.createAnonymousIdentifier()); } + block.statements.unshift(...context.popPrecedingStatements()); + return lua.createForInStatement(block, identifiers, [luaIterator], statement); } diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap index d866c5e31..8e1601a39 100644 --- a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -4,7 +4,7 @@ exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable { test("basic destructuring", () => { util.testFunction` ${testIterable} - const results: Array = []; + const results = []; for (const [x, y] of testIterable()) { results.push([x, y]); } @@ -252,7 +252,7 @@ describe("LuaIterable with array value type", () => { test("destructure with external control variable", () => { util.testFunction` ${testIterable} - const results: Array = []; + const results = [] let x: string, y: string; for ([x, y] of testIterable()) { results.push([x, y]); @@ -326,8 +326,8 @@ describe("LuaIterable with array value type", () => { describe("LuaIterable with LuaMultiReturn value type", () => { const testIterable = ` - function testIterable(this: void): LuaIterable> { - const strsArray = [["a1", "a2"], ["b1", "b2"], ["c1", "c2"]]; + function testIterable(this: void): LuaIterable> { + const strsArray = [["a1", {a: "a"}], ["b1", {a: "b"}], ["c1", {a: "c"}]]; let i = 0; return (() => { const strs = strsArray[i++]; @@ -338,15 +338,15 @@ describe("LuaIterable with LuaMultiReturn value type", () => { } `; const testResults = [ - ["a1", "a2"], - ["b1", "b2"], - ["c1", "c2"], + ["a1", { a: "a" }], + ["b1", { a: "b" }], + ["c1", { a: "c" }], ]; test("basic destructuring", () => { util.testFunction` ${testIterable} - const results: Array = []; + const results = []; for (const [x, y] of testIterable()) { results.push([x, y]); } @@ -359,8 +359,8 @@ describe("LuaIterable with LuaMultiReturn value type", () => { test("destructure with external control variable", () => { util.testFunction` ${testIterable} - const results: Array = []; - let x: string, y: string; + const results = []; + let x: string, y: any; for ([x, y] of testIterable()) { results.push([x, y]); } @@ -374,7 +374,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { util.testFunction` ${testIterable} function forward() { return testIterable(); } - const results: Array = []; + const results = []; for (const [x, y] of forward()) { results.push([x, y]); } @@ -388,7 +388,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { util.testFunction` ${testIterable} function forward() { const iter = testIterable(); return iter; } - const results: Array = []; + const results = []; for (const [x, y] of forward()) { results.push([x, y]); } @@ -402,7 +402,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { util.testFunction` ${testIterable} const forward = () => testIterable(); - const results: Array = []; + const results = []; for (const [x, y] of forward()) { results.push([x, y]); } @@ -415,7 +415,7 @@ describe("LuaIterable with LuaMultiReturn value type", () => { test("destructure manual use", () => { util.testFunction` ${testIterable} - const results: Array = []; + const results = []; const iter = testIterable(); while (true) { const [x, y] = iter(); @@ -430,6 +430,23 @@ describe("LuaIterable with LuaMultiReturn value type", () => { .expectToEqual(testResults); }); + test("nested destructuring", () => { + util.testFunction` + ${testIterable} + const results = []; + for (const [x, {a}] of testIterable()) { + results.push([x, a]); + } + return results; + ` + .withLanguageExtensions() + .expectToEqual([ + ["a1", "a"], + ["b1", "b"], + ["c1", "c"], + ]); + }); + test.each(["for (const s of testIterable()) {}", "let s; for (s of testIterable()) {}"])( "invalid LuaIterable without destructuring (%p)", statement => { From 82f4f8b0cb5683d31f04a2c70e3e77cf52a79185 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 3 Aug 2022 21:21:34 +0200 Subject: [PATCH 513/764] Support for tsconfig.json paths (#1319) * module resolution with paths tests * paths support --- src/transpilation/resolve.ts | 52 +++++++++++++++++ .../module-resolution.spec.ts.snap | 17 ++++++ test/transpile/module-resolution.spec.ts | 58 ++++++++++++++++++- .../packages/mypackage/src/bar.ts | 1 + .../packages/mypackage/src/index.ts | 1 + .../packages/mypackage/tsconfig.json | 7 +++ .../packages/myprogram/src/main.ts | 4 ++ .../packages/myprogram/tsconfig.json | 7 +++ .../monorepo-complicated/tsconfig.base.json | 10 ++++ .../monorepo-with-paths/mypackage/bar.ts | 1 + .../monorepo-with-paths/mypackage/index.ts | 1 + .../mypackage/tsconfig.json | 1 + .../monorepo-with-paths/myprogram/main.ts | 4 ++ .../myprogram/tsconfig.json | 9 +++ 14 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 test/transpile/__snapshots__/module-resolution.spec.ts.snap create mode 100644 test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts create mode 100644 test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts create mode 100644 test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json create mode 100644 test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts create mode 100644 test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json create mode 100644 test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json create mode 100644 test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts create mode 100644 test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts create mode 100644 test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json create mode 100644 test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts create mode 100644 test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index ccf0bdfa4..ff4ba1e84 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -147,6 +147,16 @@ class ResolutionContext { const fileFromPath = this.getFileFromPath(resolvedPath); if (fileFromPath) return fileFromPath; + if (this.options.paths && this.options.baseUrl) { + // If no file found yet and paths are present, try to find project file via paths mappings + const fileFromPaths = this.tryGetModuleNameFromPaths( + dependencyPath, + this.options.paths, + this.options.baseUrl + ); + if (fileFromPaths) return fileFromPaths; + } + // Not a TS file in our project sources, use resolver to check if we can find dependency try { const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); @@ -222,6 +232,40 @@ class ResolutionContext { } } } + + // Taken from TS and modified: https://github.com/microsoft/TypeScript/blob/88a1e3a1dd8d2d86e844ff1c16d5f041cebcfdb9/src/compiler/moduleSpecifiers.ts#L562 + private tryGetModuleNameFromPaths(relativeToBaseUrl: string, paths: ts.MapLike, baseUrl: string) { + const relativeImport = removeTrailingDirectorySeparator(normalizeSlashes(relativeToBaseUrl)); + for (const [importPattern, targetPatterns] of Object.entries(paths)) { + const pattern = removeFileExtension(normalizeSlashes(importPattern)); + const indexOfStar = pattern.indexOf("*"); + if (indexOfStar !== -1) { + // Try to match * to relativeImport + const prefix = pattern.substring(0, indexOfStar); + const suffix = pattern.substring(indexOfStar + 1); + if ( + (relativeImport.length >= prefix.length + suffix.length && + relativeImport.startsWith(prefix) && + relativeImport.endsWith(suffix)) || + (!suffix && relativeImport === removeTrailingDirectorySeparator(prefix)) + ) { + // If import matches *, extract the matched * path + const matchedStar = relativeImport.substring(prefix.length, relativeImport.length - suffix.length); + // Try to resolve to the target patterns with filled in * pattern + for (const target of targetPatterns) { + const file = this.getFileFromPath(path.join(baseUrl, target.replace("*", matchedStar))); + if (file) return file; + } + } + } else if (pattern === relativeImport) { + // If there is no * pattern, check for exact matches and try those targets + for (const target of targetPatterns) { + const file = this.getFileFromPath(path.join(baseUrl, target)); + if (file) return file; + } + } + } + } } export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { @@ -340,3 +384,11 @@ function fallbackResolve(required: string, sourceRootDir: string, fileDir: strin function luaRequireToPath(requirePath: string): string { return requirePath.replace(/\./g, path.sep); } + +function removeFileExtension(path: string) { + return path.includes(".") ? trimExtension(path) : path; +} + +function removeTrailingDirectorySeparator(path: string) { + return path.endsWith("/") || path.endsWith("\\") ? path.substring(0, -1) : path; +} diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap new file mode 100644 index 000000000..5cb03e86b --- /dev/null +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -0,0 +1,17 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`supports complicated paths configuration 1`] = ` +Array [ + "/monorepo-complicated/dist/packages/tstl-program/packages/mypackage/src/bar.lua", + "/monorepo-complicated/dist/packages/tstl-program/packages/mypackage/src/index.lua", + "/monorepo-complicated/dist/packages/tstl-program/packages/myprogram/src/main.lua", +] +`; + +exports[`supports paths configuration 1`] = ` +Array [ + "/monorepo-with-paths/myprogram/dist/mypackage/bar.lua", + "/monorepo-with-paths/myprogram/dist/mypackage/index.lua", + "/monorepo-with-paths/myprogram/dist/myprogram/main.lua", +] +`; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index c18990225..348b502d2 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,7 +2,8 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; -import { BuildMode, transpileProject } from "../../src"; +import { BuildMode } from "../../src"; +import { normalizeSlashes } from "../../src/utils"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -236,8 +237,8 @@ describe("module resolution project with dependencies built by tstl library mode const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-modules"); // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow - transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); - transpileProject(path.join(projectPath, "dependency2-ts", "tsconfig.json")); + tstl.transpileProject(path.join(projectPath, "dependency1-ts", "tsconfig.json")); + tstl.transpileProject(path.join(projectPath, "dependency2-ts", "tsconfig.json")); const expectedResult = { dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", @@ -538,3 +539,54 @@ test("lualib_module with parent directory import (#1307)", () => { FEATURE_CONSTANT: 456, }); }); + +test("supports paths configuration", () => { + // Package root + const baseProjectPath = path.resolve(__dirname, "module-resolution", "monorepo-with-paths"); + // myprogram package + const projectPath = path.join(baseProjectPath, "myprogram"); + const projectTsConfig = path.join(projectPath, "tsconfig.json"); + const mainFile = path.join(projectPath, "main.ts"); + + const luaResult = util + .testProject(projectTsConfig) + .setMainFileName(mainFile) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect(snapshotPaths(luaResult.transpiledFiles)).toMatchSnapshot(); + + // Bundle to have all files required to execute and check result + util.testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ foo: 314, bar: 271 }); +}); + +test("supports complicated paths configuration", () => { + // Package root + const baseProjectPath = path.resolve(__dirname, "module-resolution", "monorepo-complicated"); + // myprogram package + const projectPath = path.join(baseProjectPath, "packages", "myprogram"); + const projectTsConfig = path.join(projectPath, "tsconfig.json"); + const mainFile = path.join(projectPath, "src", "main.ts"); + + const luaResult = util + .testProject(projectTsConfig) + .setMainFileName(mainFile) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect(snapshotPaths(luaResult.transpiledFiles)).toMatchSnapshot(); + + // Bundle to have all files required to execute + util.testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .debug() + .expectToEqual({ foo: 314, bar: 271 }); +}); + +function snapshotPaths(files: tstl.TranspiledFile[]) { + return files.map(f => normalizeSlashes(f.outPath).split("module-resolution")[1]).sort(); +} diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts new file mode 100644 index 000000000..fef4e9ed6 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts @@ -0,0 +1 @@ +export const bar = 271; diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts new file mode 100644 index 000000000..c932fa9f5 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts @@ -0,0 +1 @@ +export const foo = 314; diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json new file mode 100644 index 000000000..5ac343336 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "../../dist/packages/tstl-module" + }, + "include": ["./src/**/*.ts"] +} diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts b/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts new file mode 100644 index 000000000..973b93922 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts @@ -0,0 +1,4 @@ +import { foo } from "mypackage"; +import { bar } from "mypackage/bar"; + +export { foo, bar }; diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json b/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json new file mode 100644 index 000000000..a0ba7c18e --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "outDir": "../../dist/packages/tstl-program" + }, + "include": ["./src/**/*.ts"] +} diff --git a/test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json b/test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json new file mode 100644 index 000000000..3f961c78a --- /dev/null +++ b/test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "rootDir": ".", + "baseUrl": ".", + "paths": { + "mypackage": ["packages/mypackage/src/index.ts"], + "mypackage/*": ["packages/mypackage/src/*"] + } + } +} diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts b/test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts new file mode 100644 index 000000000..fef4e9ed6 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts @@ -0,0 +1 @@ +export const bar = 271; diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts b/test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts new file mode 100644 index 000000000..c932fa9f5 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts @@ -0,0 +1 @@ +export const foo = 314; diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json b/test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json @@ -0,0 +1 @@ +{} diff --git a/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts b/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts new file mode 100644 index 000000000..973b93922 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts @@ -0,0 +1,4 @@ +import { foo } from "mypackage"; +import { bar } from "mypackage/bar"; + +export { foo, bar }; diff --git a/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json b/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json new file mode 100644 index 000000000..d5f59e8b5 --- /dev/null +++ b/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": "..", + "outDir": "dist", + "paths": { + "mypackage": ["mypackage"] + } + } +} From dd334923d3ea74c022ff71c8582186c2da1af0c5 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 3 Aug 2022 21:55:24 +0200 Subject: [PATCH 514/764] Fix import expression (#1321) * Fix import expression * removed incorrect assert --- src/transformation/visitors/modules/import.ts | 5 +++-- src/transpilation/resolve.ts | 4 ++-- test/unit/modules/modules.spec.ts | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 7a320d558..66432fb44 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -167,6 +167,7 @@ export const transformImportEqualsDeclaration: FunctionVisitor = (node, context) => { importLuaLibFeature(context, LuaLibFeature.Promise); - const importPath = node.arguments.map(a => context.transformExpression(a)); - return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", node), importPath, node); + const moduleRequire = + node.arguments.length > 0 ? createModuleRequire(context, node.arguments[0], node) : lua.createNilLiteral(); + return lua.createCallExpression(createStaticPromiseFunctionAccessor("resolve", node), [moduleRequire], node); }; diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index ff4ba1e84..f0037c249 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -304,7 +304,7 @@ function isBuildModeLibrary(program: ts.Program) { function findRequiredPaths(code: string): string[] { // Find all require("") paths in a lua code string const paths: string[] = []; - const pattern = /(^|\s|;|=)require\("(.+?)"\)/g; + const pattern = /(^|\s|;|=|\()require\("(.+?)"\)/g; // eslint-disable-next-line @typescript-eslint/ban-types let match: RegExpExecArray | null; while ((match = pattern.exec(code))) { @@ -321,7 +321,7 @@ function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newR const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); file.code = file.code.replace( - new RegExp(`(^|\\s|;|=)require\\("${escapedRequire}"\\)`), + new RegExp(`(^|\\s|;|=|\\()require\\("${escapedRequire}"\\)`), `$1require("${requirePath}")` ); } diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index 73f7c5be1..bbe978226 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -289,5 +289,5 @@ test("import expression", () => { ` .addExtraFile("module.ts", 'export function foo() { return "foo"; }') .setOptions({ module: ts.ModuleKind.ESNext }) - .expectToMatchJsResult(); + .expectToEqual({ result: "foo" }); }); From 244b5687bd13d316e4e4489a3a387ec5af7df96e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 3 Aug 2022 22:38:21 +0200 Subject: [PATCH 515/764] Sourcemap super call (#1322) * Fix super call source mapping * Fixed some more missing source mappings in call expressions * Remove stray debug --- src/transformation/visitors/call.ts | 7 ++++--- test/transpile/module-resolution.spec.ts | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 6b2fc602f..9fac8aa0f 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -183,7 +183,7 @@ function transformPropertyCall( if (calledMethod.expression.kind === ts.SyntaxKind.SuperKeyword) { // Super calls take the format of super.call(self,...) const parameters = transformArguments(context, node.arguments, signature, ts.factory.createThis()); - return lua.createCallExpression(context.transformExpression(node.expression), parameters); + return lua.createCallExpression(context.transformExpression(node.expression), parameters, node); } const signatureDeclaration = signature?.getDeclaration(); @@ -207,7 +207,7 @@ function transformElementCall(context: TransformationContext, node: ts.CallExpre } else { // No context const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); - return lua.createCallExpression(expression, parameters); + return lua.createCallExpression(expression, parameters, node); } } @@ -257,7 +257,8 @@ export const transformCallExpression: FunctionVisitor = (node context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), - parameters + parameters, + node ); } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 348b502d2..d78114ef4 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -583,7 +583,6 @@ test("supports complicated paths configuration", () => { util.testProject(projectTsConfig) .setMainFileName(mainFile) .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) - .debug() .expectToEqual({ foo: 314, bar: 271 }); }); From 96edec45e3a8cdcbec194d84207e0399cd90a16d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 3 Aug 2022 22:48:35 +0200 Subject: [PATCH 516/764] 1.7.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d0a132d14..f20a5f2f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.7.1", + "version": "1.7.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.7.1", + "version": "1.7.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 7d5f55f4b..38f786672 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.7.1", + "version": "1.7.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From b5ad882bd9746dbc5fa9a6dd4c65ea7e3537f5d4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 7 Aug 2022 15:32:27 +0200 Subject: [PATCH 517/764] Support spreading lua iterables (#1323) --- src/LuaLib.ts | 1 + src/lualib/LuaIteratorSpread.ts | 13 ++++++ .../utils/language-extensions.ts | 4 ++ src/transformation/visitors/spread.ts | 5 +++ test/unit/spread.spec.ts | 40 +++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 src/lualib/LuaIteratorSpread.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 60ffcf8c7..7780a35eb 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -44,6 +44,7 @@ export enum LuaLibFeature { InstanceOf = "InstanceOf", InstanceOfObject = "InstanceOfObject", Iterator = "Iterator", + LuaIteratorSpread = "LuaIteratorSpread", Map = "Map", MathAtan2 = "MathAtan2", MathSign = "MathSign", diff --git a/src/lualib/LuaIteratorSpread.ts b/src/lualib/LuaIteratorSpread.ts new file mode 100644 index 000000000..abe18e454 --- /dev/null +++ b/src/lualib/LuaIteratorSpread.ts @@ -0,0 +1,13 @@ +export function __TS__LuaIteratorSpread( + this: (this: void, state: TState, key: TKey) => LuaMultiReturn<[TKey, TValue]>, + state: TState, + firstKey: TKey +): LuaMultiReturn> { + const results = []; + let [key, value] = this(state, firstKey); + while (key) { + results.push([key, value]); + [key, value] = this(state, key); + } + return $multi(...results); +} diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index bb904471f..881da105b 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -98,6 +98,10 @@ export enum IterableExtensionKind { PairsKey = "PairsKey", } +export function isLuaIterable(context: TransformationContext, type: ts.Type): boolean { + return getPropertyValue(context, type, "__tstlIterable") !== undefined; +} + export function getIterableExtensionTypeForType( context: TransformationContext, type: ts.Type diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 270ee7d36..84a13f0fd 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; +import { isLuaIterable } from "../utils/language-extensions"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { @@ -73,6 +74,10 @@ export const transformSpreadElement: FunctionVisitor = (node, if (isMultiReturnCall(context, tsInnerExpression)) return innerExpression; const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts + if (isLuaIterable(context, type)) { + return transformLuaLibFunction(context, LuaLibFeature.LuaIteratorSpread, node, innerExpression); + } + if (isArrayType(context, type)) { return createUnpackCall(context, innerExpression, node); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index c3fe72b07..29f7110d3 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -478,3 +478,43 @@ describe("vararg spread in IIFE", () => { `.expectToMatchJsResult(); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 +test.each(["pairs", "ipairs"])("can spread %s (#1244)", func => { + util.testFunction` + const arr = ["a", "b", "c"]; + return [...${func}(arr)]; + ` + .withLanguageExtensions() + .setTsHeader( + ` + declare function ipairs(this: void, t: T): LuaIterable]>>; + declare function pairs(this: void, t: T): LuaIterable]>>; + ` + ) + .expectToEqual([ + [1, "a"], + [2, "b"], + [3, "c"], + ]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 +test.each(["LuaTable", "LuaMap"])("can spread %s (#1244)", type => { + const result: Array<[string, string]> = util.testFunction` + const tbl = new ${type}(); + tbl.set("foo", "bar"); + tbl.set("fizz", "buzz"); + return [...pairs(tbl)]; + ` + .withLanguageExtensions() + .setTsHeader( + "declare function pairs(this: void, t: T): LuaIterable]>>;" + ) + .getLuaExecutionResult(); + + // We don't know the order so match like this + expect(result).toHaveLength(2); + expect(result.some(([k, v]) => k === "foo" && v === "bar")).toBe(true); + expect(result.some(([k, v]) => k === "fizz" && v === "buzz")).toBe(true); +}); From 47e47723d3b48ca60856a44fe6022d49096430b7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Aug 2022 15:42:03 +0200 Subject: [PATCH 518/764] CHANGELOG.md 1.8.0 --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1b6475c6..af604ffc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 1.8.0 + +- Added support for the [tsconfig.json paths](https://www.typescriptlang.org/tsconfig#paths) configuration option. +- Fixed spreading lua iterables & iterators translating to incorrect lua. + - You can now write things like `[...pairs(obj)]`. +- Fixed a bug in module resolution resolving the wrong lua files when having the same file names in nested directories. +- Fixed a bug causing temporary variables for nested destructuring in loop variables to be outside the loop, instead of inside. +- Fixed import expressions not actually requiring their import. +- Fixed `super` calls not being source-mapped correctly. + ## 1.7.0 - Added support for `LuaMap` and `LuaSet` language extensions that translate to very low level Lua table operations. See [our docs](https://typescripttolua.github.io/docs/advanced/language-extensions/#luamap-and-luaset) for more information. From 079f7040d8697c1d9df5e1df4775a4311fb9bb45 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 7 Aug 2022 15:54:17 +0200 Subject: [PATCH 519/764] 1.8.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f20a5f2f0..ccdb0e8db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.7.2", + "version": "1.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.7.2", + "version": "1.8.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 38f786672..da0beda47 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.7.2", + "version": "1.8.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e04608f53b550dc926de97492393cad53079087b Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 9 Aug 2022 20:31:09 +0200 Subject: [PATCH 520/764] Improve paths tests and add baseUrl requiring check when specifying paths (#1324) * Improve paths tests and add baseUrl requiring check when specifying paths * Fix jsx test --- src/CompilerOptions.ts | 4 ++++ src/transpilation/diagnostics.ts | 4 ++++ .../__snapshots__/module-resolution.spec.ts.snap | 12 ++++++------ test/transpile/module-resolution.spec.ts | 9 +++++++-- .../monorepo-with-paths/myprogram/main.ts | 4 ---- .../monorepo-with-paths/myprogram/tsconfig.json | 9 --------- .../packages/mypackage/src/bar.ts | 0 .../packages/mypackage/src/index.ts | 0 .../packages/mypackage/tsconfig.json | 0 .../packages/myprogram/src/main.ts | 0 .../packages/myprogram/tsconfig.json | 0 .../tsconfig.base.json | 0 .../mypackage/bar.ts | 0 .../mypackage/index.ts | 0 .../mypackage/tsconfig.json | 0 .../module-resolution/paths-simple/myprogram/main.ts | 4 ++++ .../paths-simple/myprogram/tsconfig.json | 10 ++++++++++ test/unit/jsx.spec.ts | 4 +++- 18 files changed, 38 insertions(+), 22 deletions(-) delete mode 100644 test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts delete mode 100644 test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/packages/mypackage/src/bar.ts (100%) rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/packages/mypackage/src/index.ts (100%) rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/packages/mypackage/tsconfig.json (100%) rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/packages/myprogram/src/main.ts (100%) rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/packages/myprogram/tsconfig.json (100%) rename test/transpile/module-resolution/{monorepo-complicated => paths-base-tsconfig}/tsconfig.base.json (100%) rename test/transpile/module-resolution/{monorepo-with-paths => paths-simple}/mypackage/bar.ts (100%) rename test/transpile/module-resolution/{monorepo-with-paths => paths-simple}/mypackage/index.ts (100%) rename test/transpile/module-resolution/{monorepo-with-paths => paths-simple}/mypackage/tsconfig.json (100%) create mode 100644 test/transpile/module-resolution/paths-simple/myprogram/main.ts create mode 100644 test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index b22ee031a..deee41b70 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -87,5 +87,9 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.unsupportedJsxEmit()); } + if (options.paths && !options.baseUrl) { + diagnostics.push(diagnosticFactories.pathsWithoutBaseUrl()); + } + return diagnostics; } diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 0aa772cd3..1f37f3260 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -55,3 +55,7 @@ export const cannotBundleLibrary = createDiagnosticFactory( ); export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); + +export const pathsWithoutBaseUrl = createDiagnosticFactory( + () => "When configuring 'paths' in tsconfig.json, the option 'baseUrl' must also be provided." +); diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap index 5cb03e86b..2e4d888cb 100644 --- a/test/transpile/__snapshots__/module-resolution.spec.ts.snap +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -2,16 +2,16 @@ exports[`supports complicated paths configuration 1`] = ` Array [ - "/monorepo-complicated/dist/packages/tstl-program/packages/mypackage/src/bar.lua", - "/monorepo-complicated/dist/packages/tstl-program/packages/mypackage/src/index.lua", - "/monorepo-complicated/dist/packages/tstl-program/packages/myprogram/src/main.lua", + "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/bar.lua", + "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/index.lua", + "/paths-base-tsconfig/dist/packages/tstl-program/packages/myprogram/src/main.lua", ] `; exports[`supports paths configuration 1`] = ` Array [ - "/monorepo-with-paths/myprogram/dist/mypackage/bar.lua", - "/monorepo-with-paths/myprogram/dist/mypackage/index.lua", - "/monorepo-with-paths/myprogram/dist/myprogram/main.lua", + "/paths-simple/myprogram/dist/mypackage/bar.lua", + "/paths-simple/myprogram/dist/mypackage/index.lua", + "/paths-simple/myprogram/dist/myprogram/main.lua", ] `; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index d78114ef4..4e8f3d49b 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -4,6 +4,7 @@ import * as util from "../util"; import * as ts from "typescript"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; +import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -542,7 +543,7 @@ test("lualib_module with parent directory import (#1307)", () => { test("supports paths configuration", () => { // Package root - const baseProjectPath = path.resolve(__dirname, "module-resolution", "monorepo-with-paths"); + const baseProjectPath = path.resolve(__dirname, "module-resolution", "paths-simple"); // myprogram package const projectPath = path.join(baseProjectPath, "myprogram"); const projectTsConfig = path.join(projectPath, "tsconfig.json"); @@ -565,7 +566,7 @@ test("supports paths configuration", () => { test("supports complicated paths configuration", () => { // Package root - const baseProjectPath = path.resolve(__dirname, "module-resolution", "monorepo-complicated"); + const baseProjectPath = path.resolve(__dirname, "module-resolution", "paths-base-tsconfig"); // myprogram package const projectPath = path.join(baseProjectPath, "packages", "myprogram"); const projectTsConfig = path.join(projectPath, "tsconfig.json"); @@ -586,6 +587,10 @@ test("supports complicated paths configuration", () => { .expectToEqual({ foo: 314, bar: 271 }); }); +test("paths without baseUrl is error", () => { + util.testFunction``.setOptions({ paths: {} }).expectToHaveDiagnostics([pathsWithoutBaseUrl.code]); +}); + function snapshotPaths(files: tstl.TranspiledFile[]) { return files.map(f => normalizeSlashes(f.outPath).split("module-resolution")[1]).sort(); } diff --git a/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts b/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts deleted file mode 100644 index 973b93922..000000000 --- a/test/transpile/module-resolution/monorepo-with-paths/myprogram/main.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { foo } from "mypackage"; -import { bar } from "mypackage/bar"; - -export { foo, bar }; diff --git a/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json b/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json deleted file mode 100644 index d5f59e8b5..000000000 --- a/test/transpile/module-resolution/monorepo-with-paths/myprogram/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "compilerOptions": { - "baseUrl": "..", - "outDir": "dist", - "paths": { - "mypackage": ["mypackage"] - } - } -} diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts b/test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/src/bar.ts similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/bar.ts rename to test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/src/bar.ts diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts b/test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/src/index.ts similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/packages/mypackage/src/index.ts rename to test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/src/index.ts diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json b/test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/tsconfig.json similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/packages/mypackage/tsconfig.json rename to test/transpile/module-resolution/paths-base-tsconfig/packages/mypackage/tsconfig.json diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts b/test/transpile/module-resolution/paths-base-tsconfig/packages/myprogram/src/main.ts similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/packages/myprogram/src/main.ts rename to test/transpile/module-resolution/paths-base-tsconfig/packages/myprogram/src/main.ts diff --git a/test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json b/test/transpile/module-resolution/paths-base-tsconfig/packages/myprogram/tsconfig.json similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/packages/myprogram/tsconfig.json rename to test/transpile/module-resolution/paths-base-tsconfig/packages/myprogram/tsconfig.json diff --git a/test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json b/test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json similarity index 100% rename from test/transpile/module-resolution/monorepo-complicated/tsconfig.base.json rename to test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts b/test/transpile/module-resolution/paths-simple/mypackage/bar.ts similarity index 100% rename from test/transpile/module-resolution/monorepo-with-paths/mypackage/bar.ts rename to test/transpile/module-resolution/paths-simple/mypackage/bar.ts diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts b/test/transpile/module-resolution/paths-simple/mypackage/index.ts similarity index 100% rename from test/transpile/module-resolution/monorepo-with-paths/mypackage/index.ts rename to test/transpile/module-resolution/paths-simple/mypackage/index.ts diff --git a/test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json b/test/transpile/module-resolution/paths-simple/mypackage/tsconfig.json similarity index 100% rename from test/transpile/module-resolution/monorepo-with-paths/mypackage/tsconfig.json rename to test/transpile/module-resolution/paths-simple/mypackage/tsconfig.json diff --git a/test/transpile/module-resolution/paths-simple/myprogram/main.ts b/test/transpile/module-resolution/paths-simple/myprogram/main.ts new file mode 100644 index 000000000..e7687877a --- /dev/null +++ b/test/transpile/module-resolution/paths-simple/myprogram/main.ts @@ -0,0 +1,4 @@ +import { foo } from "myOtherPackage"; +import { bar } from "myOtherPackage/bar"; + +export { foo, bar }; diff --git a/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json b/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json new file mode 100644 index 000000000..f01271ac9 --- /dev/null +++ b/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "outDir": "dist", + "paths": { + "myOtherPackage": ["../mypackage"], + "myOtherPackage/*": ["../mypackage/*"] + } + } +} diff --git a/test/unit/jsx.spec.ts b/test/unit/jsx.spec.ts index 03b00e95d..a72d0d7f9 100644 --- a/test/unit/jsx.spec.ts +++ b/test/unit/jsx.spec.ts @@ -1,6 +1,8 @@ import * as util from "../util"; import { TestBuilder } from "../util"; import { JsxEmit } from "typescript"; +import { unsupportedJsxEmit } from "../../src/transpilation/diagnostics"; +import { unsupportedNodeKind } from "../../src/transformation/utils/diagnostics"; // language=TypeScript const reactLib = ` @@ -368,6 +370,6 @@ describe("jsx", () => { .setOptions({ jsx: JsxEmit.Preserve, }) - .expectToHaveDiagnostics(); + .expectToHaveDiagnostics([unsupportedJsxEmit.code, unsupportedNodeKind.code]); }); }); From 08707913cbbcb1de115764c29f5c5c28458028c7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 9 Aug 2022 20:41:10 +0200 Subject: [PATCH 521/764] 1.8.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ccdb0e8db..ac4c75609 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.8.0", + "version": "1.8.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.8.0", + "version": "1.8.1", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index da0beda47..59cb4adac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.8.0", + "version": "1.8.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e5451924568f4f0134a7c270fb4f1ba6171c503d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 11 Aug 2022 15:24:32 +0200 Subject: [PATCH 522/764] Exception trying to read symbol from undefined type (#1326) * Fix excaption due to undefined call symbol * Add reproducing test * Hopefully actually sustainable solution --- src/transformation/builtins/index.ts | 32 +++++++++++++++------------ test/unit/functions/functions.spec.ts | 13 +++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index b5a92095b..711015b5f 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -4,13 +4,7 @@ import { TransformationContext } from "../context"; import { createNaN } from "../utils/lua-ast"; import { importLuaLibFeature, LuaLibFeature } from "../utils/lualib"; import { getIdentifierSymbolId } from "../utils/symbols"; -import { - isStandardLibraryType, - isStandardLibraryDeclaration, - isStringType, - isArrayType, - isFunctionType, -} from "../utils/typescript"; +import { isStandardLibraryType, isStringType, isArrayType, isFunctionType } from "../utils/typescript"; import { getCalledExpression } from "../visitors/call"; import { transformArrayConstructorCall, transformArrayProperty, transformArrayPrototypeCall } from "./array"; import { transformConsoleCall } from "./console"; @@ -85,9 +79,7 @@ function tryTransformBuiltinGlobalMethodCall( calledMethod: ts.PropertyAccessExpression ) { const ownerType = context.checker.getTypeAtLocation(calledMethod.expression); - if (!isStandardLibraryType(context, ownerType, undefined)) return; - - const ownerSymbol = ownerType.symbol; + const ownerSymbol = tryGetStandardLibrarySymbolOfType(context, ownerType); if (!ownerSymbol || ownerSymbol.parent) return; let result: lua.Expression | undefined; @@ -129,10 +121,9 @@ function tryTransformBuiltinPropertyCall( node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression ) { - const signatureDeclaration = context.checker.getResolvedSignature(node)?.declaration; - if (!signatureDeclaration || !isStandardLibraryDeclaration(context, signatureDeclaration)) return; - - const callSymbol = context.checker.getTypeAtLocation(signatureDeclaration).symbol; + const functionType = context.checker.getTypeAtLocation(node.expression); + const callSymbol = tryGetStandardLibrarySymbolOfType(context, functionType); + if (!callSymbol) return; const ownerSymbol = callSymbol.parent; if (!ownerSymbol || ownerSymbol.parent) return; @@ -217,3 +208,16 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type importLuaLibFeature(context, LuaLibFeature.Error); } } + +function tryGetStandardLibrarySymbolOfType(context: TransformationContext, type: ts.Type): ts.Symbol | undefined { + if (type.isUnionOrIntersection()) { + for (const subType of type.types) { + const symbol = tryGetStandardLibrarySymbolOfType(context, subType); + if (symbol) return symbol; + } + } else if (isStandardLibraryType(context, type, undefined)) { + return type.symbol; + } + + return undefined; +} diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 8f2dc1199..c44364c9f 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -1,3 +1,4 @@ +import * as ts from "typescript"; import * as tstl from "../../../src"; import * as util from "../../util"; import { unsupportedForTarget } from "../../../src/transformation/utils/diagnostics"; @@ -512,3 +513,15 @@ test("top-level function declaration is global", () => { .addExtraFile("a.ts", 'function foo() { return "foo" }') .expectToEqual({ result: "foo" }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1325 +test("call expression should not throw (#1325)", () => { + util.testModule` + function test(iterator:Iterator) { + iterator.return?.(); + } + ` + // Note: does not reproduce without strict=true + .setOptions({ target: ts.ScriptTarget.ESNext, strict: true }) + .expectToHaveNoDiagnostics(); +}); From 8f60f9f56c0a27d061e186c11c67cacc07ea39bb Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 11 Aug 2022 06:29:35 -0700 Subject: [PATCH 523/764] Allow MultiReturn to be typed as any (#1327) --- .../visitors/language-extensions/multi.ts | 6 +++- src/transformation/visitors/return.ts | 22 +++++++++----- test/unit/language-extensions/multi.spec.ts | 30 +++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 5dd239deb..73dec6d9c 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -14,7 +14,11 @@ export function isMultiReturnType(type: ts.Type): boolean { } export function canBeMultiReturnType(type: ts.Type): boolean { - return isMultiReturnType(type) || (type.isUnion() && type.types.some(t => canBeMultiReturnType(t))); + return ( + (type.flags & ts.TypeFlags.Any) !== 0 || + isMultiReturnType(type) || + (type.isUnion() && type.types.some(t => canBeMultiReturnType(t))) + ); } export function isMultiFunctionCall(context: TransformationContext, expression: ts.CallExpression): boolean { diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 13fceeecf..14d785166 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -23,16 +23,20 @@ function transformExpressionsInReturn( ): lua.Expression[] { const expressionType = context.checker.getTypeAtLocation(node); - if (ts.isCallExpression(node)) { + // skip type assertions + // don't skip parenthesis as it may arise confusion with lua behavior (where parenthesis are significant) + const innerNode = ts.skipOuterExpressions(node, ts.OuterExpressionKinds.Assertions); + + if (ts.isCallExpression(innerNode)) { // $multi(...) - if (isMultiFunctionCall(context, node)) { + if (isMultiFunctionCall(context, innerNode)) { // Don't allow $multi to be implicitly cast to something other than LuaMultiReturn const type = context.checker.getContextualType(node); if (type && !canBeMultiReturnType(type)) { - context.diagnostics.push(invalidMultiFunctionReturnType(node)); + context.diagnostics.push(invalidMultiFunctionReturnType(innerNode)); } - let returnValues = transformArguments(context, node.arguments); + let returnValues = transformArguments(context, innerNode.arguments); if (insideTryCatch) { returnValues = [wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch } @@ -40,12 +44,16 @@ function transformExpressionsInReturn( } // Force-wrap LuaMultiReturn when returning inside try/catch - if (insideTryCatch && returnsMultiType(context, node) && !shouldMultiReturnCallBeWrapped(context, node)) { + if ( + insideTryCatch && + returnsMultiType(context, innerNode) && + !shouldMultiReturnCallBeWrapped(context, innerNode) + ) { return [wrapInTable(context.transformExpression(node))]; } - } else if (isInMultiReturnFunction(context, node) && isMultiReturnType(expressionType)) { + } else if (isInMultiReturnFunction(context, innerNode) && isMultiReturnType(expressionType)) { // Unpack objects typed as LuaMultiReturn - return [createUnpackCall(context, context.transformExpression(node), node)]; + return [createUnpackCall(context, context.transformExpression(innerNode), innerNode)]; } return [context.transformExpression(node)]; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 50784a3db..ed7213b2b 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -184,6 +184,36 @@ test("forward $multi call in ArrowFunction body", () => { .expectToEqual([1, 2]); }); +test("$multi call in function typed as any", () => { + util.testFunction` + function foo(): any { return $multi(1, 2); } + return foo() + ` + .withLanguageExtensions() + .expectToHaveNoDiagnostics() + .expectToEqual(1); +}); + +test("$multi call cast to any", () => { + util.testFunction` + function foo() { return $multi(1, 2) as any; } + return foo() + ` + .withLanguageExtensions() + .expectToHaveNoDiagnostics() + .expectToEqual(1); +}); + +test("$multi call cast to MultiReturn type", () => { + util.testFunction` + function foo() { return $multi(1, 2) as unknown as LuaMultiReturn; } + return foo() + ` + .withLanguageExtensions() + .expectToHaveNoDiagnostics() + .expectToEqual(1); +}); + test.each(["0", "i"])("allow LuaMultiReturn numeric access (%s)", expression => { util.testFunction` ${multiFunction} From 37b632a8041817d9db07727671321a24188fa6cb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Aug 2022 15:40:37 +0200 Subject: [PATCH 524/764] 1.8.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac4c75609..767d8d74b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.8.1", + "version": "1.8.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.8.1", + "version": "1.8.2", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 59cb4adac..436883362 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.8.1", + "version": "1.8.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 7f1d4a55c9c742dc692f3b94e70e34755b884cd1 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 14 Aug 2022 04:44:40 -0700 Subject: [PATCH 525/764] Fix get() return type of ReadonlyLuaMap (#1329) --- language-extensions/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 37f4809c8..1d80f0856 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -631,7 +631,7 @@ declare const LuaMap: (new () => LuaMa * @param V The type of the values stored in the table. */ declare interface ReadonlyLuaMap extends LuaPairsIterable { - get: LuaTableGetMethod; + get: LuaTableGetMethod; has: LuaTableHasMethod; } From f8228586b1d363a4ca74a33a188d552cf446848b Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 17 Aug 2022 21:09:33 +0200 Subject: [PATCH 526/764] Fix issue leading to wrong bundle entry requires (#1332) * Fix issue leading to wrong bundle entry requires * Resolve bundle entry module from project root instead of source directory * Use TS to figure out actual entry point filename --- src/transpilation/bundle.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 0c039ad4f..547c3b110 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -5,7 +5,7 @@ import { CompilerOptions } from "../CompilerOptions"; import { escapeString, tstlHeader } from "../LuaPrinter"; import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; -import { getEmitOutDir, getEmitPathRelativeToOutDir, getSourceDir } from "./transpiler"; +import { getEmitOutDir, getEmitPathRelativeToOutDir, getProjectRoot } from "./transpiler"; import { EmitFile, ProcessedFile } from "./utils"; const createModulePath = (pathToResolve: string, program: ts.Program) => @@ -85,10 +85,12 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const entryModule = cast(options.luaBundleEntry, isNonNull); // Resolve project settings relative to project file. - const resolvedEntryModule = path.resolve(getSourceDir(program), entryModule); + const resolvedEntryModule = path.resolve(getProjectRoot(program), entryModule); const outputPath = path.resolve(getEmitOutDir(program), bundleFile); + const entryModuleFilePath = + program.getSourceFile(entryModule)?.fileName ?? program.getSourceFile(resolvedEntryModule)?.fileName; - if (program.getSourceFile(resolvedEntryModule) === undefined && program.getSourceFile(entryModule) === undefined) { + if (entryModuleFilePath === undefined) { diagnostics.push(couldNotFindBundleEntryPoint(entryModule)); } @@ -99,7 +101,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(entryModule, program)}, ...)\n`; + const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ...)\n`; const footers: string[] = []; if (options.sourceMapTraceback) { From 61d073803f6b31bcc2c62dccabd8fee0883fe9e6 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 18 Aug 2022 13:02:33 +0200 Subject: [PATCH 527/764] Warning if truthiness (#1333) * Add warning diagnostic when using condition variable that will never be false in Lua * Fix tests * Fix ugly import --- src/transformation/utils/diagnostics.ts | 4 ++ src/transformation/visitors/conditional.ts | 14 +++++ src/transformation/visitors/loops/do-while.ts | 7 +++ test/unit/conditionals.spec.ts | 51 ++++++++++++++++++- test/unit/identifiers.spec.ts | 4 +- 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 6520694ed..7fc7d814b 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -147,6 +147,10 @@ export const annotationDeprecated = createWarningDiagnosticFactory( `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` ); +export const truthyOnlyConditionalValue = createWarningDiagnosticFactory( + "Numbers and strings will always evaluate to true in Lua. Explicitly check the value with ===." +); + export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( "The left-hand side of an assignment expression may not be an optional property access." ); diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 0c8434890..82d214cdd 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -5,6 +5,7 @@ import { transformInPrecedingStatementScope } from "../utils/preceding-statement import { performHoisting, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; +import { truthyOnlyConditionalValue } from "../utils/diagnostics"; type EvaluatedExpression = [precedingStatemens: lua.Statement[], value: lua.Expression]; @@ -39,6 +40,9 @@ function transformProtectedConditionalExpression( } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { + // Check if we need to add diagnostic about Lua truthiness + checkOnlyTruthyCondition(expression.condition, context); + const condition = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.condition) ); @@ -64,6 +68,10 @@ export const transformConditionalExpression: FunctionVisitor = (statement, context) => { + // Check if we need to add diagnostic about Lua truthiness + checkOnlyTruthyCondition(statement.expression, context); + const body = transformLoopBody(context, statement); let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => @@ -37,6 +41,9 @@ export const transformWhileStatement: FunctionVisitor = (stat }; export const transformDoStatement: FunctionVisitor = (statement, context) => { + // Check if we need to add diagnostic about Lua truthiness + checkOnlyTruthyCondition(statement.expression, context); + const body = lua.createDoStatement(transformLoopBody(context, statement)); let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index a1a234cf6..ffbff9ab4 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -1,5 +1,6 @@ import * as tstl from "../../src"; import * as util from "../util"; +import { truthyOnlyConditionalValue } from "../../src/transformation/utils/diagnostics"; test.each([0, 1])("if (%p)", inp => { util.testFunction` @@ -88,7 +89,9 @@ test.each([ { condition: false, lhs: 4, rhs: 5 }, { condition: 3, lhs: 4, rhs: 5 }, ])("Ternary Conditional (%p)", ({ condition, lhs, rhs }) => { - util.testExpressionTemplate`${condition} ? ${lhs} : ${rhs}`.expectToMatchJsResult(); + util.testExpressionTemplate`${condition} ? ${lhs} : ${rhs}` + .ignoreDiagnostics([truthyOnlyConditionalValue.code]) + .expectToMatchJsResult(); }); test.each(["true", "false", "a < 4", "a == 8"])("Ternary Conditional Delayed (%p)", condition => { @@ -138,3 +141,49 @@ test.each([false, true])("Ternary conditional with preceding statements in false }) .expectToMatchJsResult(); }); + +test.each(["string", "number", "string | number"])( + "Warning when using if statement that cannot evaluate to false undefined or null (%p)", + type => { + util.testFunction` + if (condition) {} + ` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true }) + .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); + } +); + +test.each(["string", "number", "string | number"])( + "Warning when using while statement that cannot evaluate to false undefined or null (%p)", + type => { + util.testFunction` + while (condition) {} + ` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true }) + .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); + } +); + +test.each(["string", "number", "string | number"])( + "Warning when using do while statement that cannot evaluate to false undefined or null (%p)", + type => { + util.testFunction` + do {} while (condition) + ` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true }) + .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); + } +); + +test.each(["string", "number", "string | number"])( + "Warning when using ternary that cannot evaluate to false undefined or null (%p)", + type => { + util.testExpression`condition ? 1 : 0` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true }) + .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); + } +); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 7c0722938..b5b627b4d 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -302,7 +302,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (elseif)", () => { util.testFunction` - const elseif = "foobar"; + const elseif: string | undefined = "foobar"; if (false) { } else if (elseif) { return elseif; @@ -350,7 +350,7 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (then)", () => { util.testFunction` - const then = "foobar"; + const then: string | undefined = "foobar"; if (then) { return then; } From 5fab1472e7f84707b1c1f04da65be3110cff36ac Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 18 Aug 2022 15:30:37 +0200 Subject: [PATCH 528/764] Fix call language extensions diagnostic trying to use them incorrectly (#1334) * Fix broken diagnostic when trying to directly use call extensions * prettier * Update snapshot * prettier --- src/transformation/visitors/access.ts | 20 +++++++- src/transformation/visitors/identifier.ts | 5 +- test/setup.ts | 4 +- .../__snapshots__/table.spec.ts.snap | 48 +++++++++++++++++++ test/unit/language-extensions/table.spec.ts | 24 ++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index f0eced595..12e9385ad 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -3,12 +3,18 @@ import * as lua from "../../LuaAST"; import { transformBuiltinPropertyAccessExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { invalidMultiReturnAccess, unsupportedOptionalCompileMembersOnly } from "../utils/diagnostics"; +import { + invalidCallExtensionUse, + invalidMultiReturnAccess, + unsupportedOptionalCompileMembersOnly, +} from "../utils/diagnostics"; +import { getExtensionKindForNode } from "../utils/language-extensions"; import { addToNumericExpression } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; import { transformOrderedExpressions } from "./expression-list"; +import { callExtensions } from "./language-extensions/call-extension"; import { isMultiReturnCall, returnsMultiType } from "./language-extensions/multi"; import { transformOptionalChainWithCapture, @@ -143,6 +149,18 @@ export function transformPropertyAccessExpressionWithCapture( return { expression: builtinResult }; } + if ( + ts.isIdentifier(node.expression) && + node.parent && + (!ts.isCallExpression(node.parent) || node.parent.expression !== node) + ) { + // Check if this is a method call extension that is not used as a call + const extensionType = getExtensionKindForNode(context, node); + if (extensionType && callExtensions.has(extensionType)) { + context.diagnostics.push(invalidCallExtensionUse(node)); + } + } + const table = context.transformExpression(node.expression); if (thisValueCapture) { diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index efb5349bc..78f2bb8c2 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -31,7 +31,10 @@ function transformNonValueIdentifier( if (extensionKind) { if (callExtensions.has(extensionKind)) { - context.diagnostics.push(invalidCallExtensionUse(identifier)); + // Avoid putting duplicate diagnostic on the name of a variable declaration, due to the inferred type + if (!(ts.isVariableDeclaration(identifier.parent) && identifier.parent.name === identifier)) { + context.diagnostics.push(invalidCallExtensionUse(identifier)); + } // fall through } else if (isIdentifierExtensionValue(symbol, extensionKind)) { reportInvalidExtensionValue(context, identifier, extensionKind); diff --git a/test/setup.ts b/test/setup.ts index de78ad24b..e468c5ab8 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -37,7 +37,9 @@ expect.extend({ const message = this.isNot ? diagnosticMessages : expected - ? `Expected:\n${expected.join("\n")}\nReceived:\n${diagnostics.map(diag => diag.code).join("\n")}\n` + ? `Expected:\n${expected.join("\n")}\nReceived:\n${diagnostics + .map(diag => diag.code) + .join("\n")}\n\n${diagnosticMessages}\n` : `Received: ${this.utils.printReceived([])}\n`; return matcherHint + "\n\n" + message; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 831d1ec54..9821d9777 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -85,3 +85,51 @@ exports[`LuaTableHas extension invalid use ("const foo: unknown = tableHas;"): d exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): code 1`] = `"foo(_G, tableHas)"`; exports[`LuaTableHas extension invalid use ("declare function foo(tableHas: LuaTableHas<{}, string>): void; foo(tableHas);"): diagnostics 1`] = `"main.ts(3,80): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaMap"): code 1`] = ` +"____table = {} +has = ____table.has" +`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaMap"): diagnostics 1`] = `"main.ts(3,29): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaSet"): code 1`] = ` +"____table = {} +has = ____table.has" +`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaSet"): diagnostics 1`] = `"main.ts(3,29): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaTable"): code 1`] = ` +"____table = {} +has = ____table.has" +`; + +exports[`LuaTableHas extension invalid use method assignment ("LuaTable"): diagnostics 1`] = `"main.ts(3,29): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method expression ("LuaMap"): code 1`] = ` +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +____table = {} +__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +`; + +exports[`LuaTableHas extension invalid use method expression ("LuaMap"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method expression ("LuaSet"): code 1`] = ` +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +____table = {} +__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +`; + +exports[`LuaTableHas extension invalid use method expression ("LuaSet"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`LuaTableHas extension invalid use method expression ("LuaTable"): code 1`] = ` +"local ____lualib = require(\\"lualib_bundle\\") +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +____table = {} +__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +`; + +exports[`LuaTableHas extension invalid use method expression ("LuaTable"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 8f21dc8d1..ed9e8e37c 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -170,6 +170,30 @@ describe("LuaTableHas extension", () => { .withLanguageExtensions() .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); + + test.each(["LuaTable", "LuaMap", "LuaSet"])( + "invalid use method assignment (%p)", + type => { + util.testModule` + const table = new ${type}(); + const has = table.has; + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); + } + ); + + test.each(["LuaTable", "LuaMap", "LuaSet"])( + "invalid use method expression (%p)", + type => { + util.testModule` + const table = new ${type}(); + ["a", "b", "c"].map(table.has); + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); + } + ); }); describe("LuaTableDelete extension", () => { From 33f0a458487cf73f40e1379e6564ed724f079037 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 18 Aug 2022 15:42:44 +0200 Subject: [PATCH 529/764] CHANGELOG.md 1.9.0 --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index af604ffc6..3ffd37a4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 1.9.0 + +- Added a warning when trying to use a type in a condition that can never be false in Lua, such as numbers or strings. (Only when `strictNullChecks` is enabled.) +- Fixed some missing and misplaced errors when trying to reference LuaTable/LuaMap/LuaSet functions without calling them. +- Fixed a bug in the `get()` type of `ReadOnlyLuaMap`. It is now typed the same as `LuaMap`, i.e. it can return `undefined`. +- Fixed an issue in bundling that could sometimes lead to invalid bundle entry requires. +- Added a warning when using `paths` without specifying `baseUrl`. +- Fixed exception while checking for standard library types. + ## 1.8.0 - Added support for the [tsconfig.json paths](https://www.typescriptlang.org/tsconfig#paths) configuration option. From c3dd2283bef3781110c891198625e22ce7b86e1f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 18 Aug 2022 15:47:07 +0200 Subject: [PATCH 530/764] 1.9.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 767d8d74b..cedb3f0c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.8.2", + "version": "1.9.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.8.2", + "version": "1.9.0", "license": "MIT", "dependencies": { "enhanced-resolve": "^5.8.2", diff --git a/package.json b/package.json index 436883362..0a6cbbc48 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.8.2", + "version": "1.9.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e1a1fa699742e95f7480d8fe98579a48df6c424e Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 28 Aug 2022 02:10:41 -0700 Subject: [PATCH 531/764] Support typescript 4.7 instantiation expressions (#1340) --- src/transformation/visitors/typescript.ts | 1 + test/unit/expressions.spec.ts | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/transformation/visitors/typescript.ts b/src/transformation/visitors/typescript.ts index ab6c940f6..ddd319381 100644 --- a/src/transformation/visitors/typescript.ts +++ b/src/transformation/visitors/typescript.ts @@ -20,6 +20,7 @@ export const typescriptVisitors: Visitors = { [ts.SyntaxKind.InterfaceDeclaration]: () => undefined, [ts.SyntaxKind.NonNullExpression]: (node, context) => context.transformExpression(node.expression), + [ts.SyntaxKind.ExpressionWithTypeArguments]: (node, context) => context.transformExpression(node.expression), [ts.SyntaxKind.AsExpression]: transformAssertionExpression, [ts.SyntaxKind.TypeAssertionExpression]: transformAssertionExpression, [ts.SyntaxKind.NotEmittedStatement]: () => undefined, diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 71c014fda..329b6317e 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -153,6 +153,14 @@ test("Non-null expression", () => { `.expectToMatchJsResult(); }); +test("Typescript 4.7 instantiation expression", () => { + util.testFunction` + function foo(x: T): T { return x; } + const bar = foo; + return bar(3); + `.expectToMatchJsResult(); +}); + test.each([ '"foobar"', "17", From 0d7e54bcaebe60ebf54452ca7a54f0f04bdd3175 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 31 Aug 2022 21:04:01 +0200 Subject: [PATCH 532/764] Upgrade to TypeScript 4.8 (#1338) * Upgrade to TypeScript 4.8 * Try without upgrading lua-types * also revert package lock * more upgrades * Try to fix package-lock * Upgrade lua-types --- jest.config.js | 2 +- language-extensions/index.d.ts | 4 +- package-lock.json | 12053 +++++++++------- package.json | 26 +- src/transformation/utils/typescript/index.ts | 4 +- src/transformation/visitors/class/index.ts | 4 +- .../visitors/class/members/fields.ts | 6 +- .../visitors/class/members/method.ts | 20 +- src/transformation/visitors/modules/export.ts | 7 +- src/utils.ts | 2 +- 10 files changed, 7108 insertions(+), 5020 deletions(-) diff --git a/jest.config.js b/jest.config.js index 2d390c93d..d07ef2022 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,4 +1,4 @@ -const isCI = require("is-ci"); +const isCI = process.env.GITHUB_ACTIONS !== undefined; /** @type {Partial} */ module.exports = { diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 1d80f0856..07b5cb335 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -666,11 +666,11 @@ declare interface ReadonlyLuaSet extends LuaPai interface ObjectConstructor { /** Returns an array of keys of an object, when iterated with `pairs`. */ - keys(o: LuaPairsIterable | LuaPairsKeyIterable): K[]; + keys(o: LuaPairsIterable | LuaPairsKeyIterable): K[]; /** Returns an array of values of an object, when iterated with `pairs`. */ values(o: LuaPairsIterable): V[]; /** Returns an array of key/values of an object, when iterated with `pairs`. */ - entries(o: LuaPairsIterable): Array<[K, V]>; + entries(o: LuaPairsIterable): Array<[K, V]>; } diff --git a/package-lock.json b/package-lock.json index cedb3f0c8..dd7f2d749 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,59 +22,84 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.27.0", - "@typescript-eslint/parser": "^5.27.0", - "eslint": "^8.17.0", + "@typescript-eslint/eslint-plugin": "^5.35.1", + "@typescript-eslint/parser": "^5.35.1", + "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.4.6", + "eslint-plugin-jest": "^26.8.7", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^27.3.0", - "jest-circus": "^27.3.0", - "lua-types": "^2.11.0", + "jest": "^28.1.3", + "jest-circus": "^29.0.1", + "lua-types": "^2.12.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^27.1.3", - "ts-node": "^10.3.0", - "typescript": "~4.7.3" + "ts-jest": "^28.0.8", + "ts-node": "^10.9.1", + "typescript": "~4.8.2" }, "engines": { - "node": ">=12.13.0" + "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.7.3" + "typescript": "~4.8.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", + "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", + "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "json5": "^2.2.1", + "semver": "^6.3.0" }, "engines": { "node": ">=6.9.0" @@ -84,18 +109,6 @@ "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/core/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/core/node_modules/semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -105,47 +118,43 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/core/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", + "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", "dev": true, "dependencies": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.18.13", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, "engines": { - "node": ">=0.10.0" + "node": ">=6.0.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", "semver": "^6.3.0" }, "engines": { @@ -164,186 +173,152 @@ "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", "dev": true, - "dependencies": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "node_modules/@babel/helper-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", - "dev": true, - "dependencies": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", "dev": true, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", + "node_modules/@babel/helper-simple-access": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "dependencies": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "node_modules/@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", "dev": true, - "dependencies": { - "@babel/types": "^7.15.4" - }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", "dev": true, "dependencies": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -389,13 +364,13 @@ "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -404,7 +379,7 @@ "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, "engines": { "node": ">=4" @@ -423,9 +398,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -494,6 +469,21 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -582,12 +572,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" @@ -597,44 +587,33 @@ } }, "node_modules/@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", + "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -642,18 +621,6 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/traverse/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -664,12 +631,13 @@ } }, "node_modules/@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", + "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" }, "engines": { @@ -682,36 +650,37 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" + "@jridgewell/trace-mapping": "0.3.9" }, "engines": { "node": ">=12" } }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.2", + "espree": "^9.4.0", "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -721,30 +690,15 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -755,6 +709,29 @@ "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", @@ -777,6 +754,15 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -790,6 +776,19 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -829,24 +828,6 @@ "node": ">=8" } }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -866,59 +847,60 @@ } }, "node_modules/@jest/console": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", - "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^27.3.0", - "jest-util": "^27.3.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/@jest/core": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", - "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", "dev": true, "dependencies": { - "@jest/console": "^27.3.0", - "@jest/reporters": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.8.1", + "ci-info": "^3.2.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-resolve-dependencies": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "jest-watcher": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", "rimraf": "^3.0.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -929,2383 +911,3253 @@ } } }, - "node_modules/@jest/environment": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", - "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", - "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", - "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" + "node": ">=10" }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/globals": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", - "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/types": "^27.2.5", - "expect": "^27.3.0" + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@jest/reporters": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", - "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", + "node_modules/@jest/core/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/environment": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.1.tgz", + "integrity": "sha512-iLcFfoq2K6DAB+Mc+2VNLzZVmHdwQFeSqvoM/X8SMON6s/+yEi1iuRX3snx/JfwSnvmiMXjSr0lktxNxOcqXYA==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^29.0.1", + "@jest/types": "^29.0.1", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" + "jest-mock": "^29.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/reporters/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/environment/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "node_modules/@jest/environment/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", "dev": true, "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/source-map/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/@jest/expect": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.1.tgz", + "integrity": "sha512-qKB3q52XDV8VUEiqKKLgLrJx7puQ8sYVqIDlul6n7SIXWS97DOK3KqbR2rDDaMtmenRHqEUl2fI+aFzx0oSemA==", "dev": true, + "dependencies": { + "expect": "^29.0.1", + "jest-snapshot": "^29.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-result": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", - "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", + "node_modules/@jest/expect-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.1.tgz", + "integrity": "sha512-Tw5kUUOKmXGQDmQ9TSgTraFFS7HMC1HG/B7y0AN2G2UzjdAXz9BzK2rmNpCSDl7g7y0Gf/VLBm//blonvhtOTQ==", "dev": true, "dependencies": { - "@jest/console": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "jest-get-type": "^29.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/test-sequencer": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", - "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", + "node_modules/@jest/expect/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, "dependencies": { - "@jest/test-result": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-runtime": "^27.3.0" + "@sinclair/typebox": "^0.24.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", - "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", + "node_modules/@jest/expect/node_modules/@jest/transform": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", + "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", + "@babel/core": "^7.11.6", + "@jest/types": "^29.0.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" + "write-file-atomic": "^4.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "node_modules/@jest/expect/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", "dev": true, "dependencies": { + "@jest/schemas": "^29.0.0", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@jest/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, "engines": { - "node": ">= 8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@jest/expect/node_modules/diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", "dev": true, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@jest/expect/node_modules/jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "node_modules/@jest/expect/node_modules/jest-haste-map": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", + "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@jest/types": "^29.0.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "jest-worker": "^29.0.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "node_modules/@jest/expect/node_modules/jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "chalk": "^4.0.0", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "node_modules/@jest/expect/node_modules/jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, "engines": { - "node": ">= 6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true + "node_modules/@jest/expect/node_modules/jest-regex-util": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", + "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true + "node_modules/@jest/expect/node_modules/jest-snapshot": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", + "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.0.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-haste-map": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.0.1", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "node_modules/@jest/expect/node_modules/jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "node_modules/@jest/expect/node_modules/jest-worker": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", + "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/@jest/expect/node_modules/pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "node_modules/@jest/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/@jest/expect/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "node_modules/@jest/fake-timers": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.1.tgz", + "integrity": "sha512-XZ+kAhLChVQ+KJNa5034p7O1Mz3vtWrelxDcMoxhZkgqmWDaEQAW9qJeutaeCfPvwaEwKYVyKDYfWpcyT8RiMw==", "dev": true, "dependencies": { - "@types/node": "*" + "@jest/types": "^29.0.1", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^29.0.1", + "jest-mock": "^29.0.1", + "jest-util": "^29.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "node_modules/@jest/fake-timers/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", "dev": true, "dependencies": { - "@types/node": "*" + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true + "node_modules/@jest/fake-timers/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/@jest/fake-timers/node_modules/jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", "dev": true, "dependencies": { - "@types/istanbul-lib-coverage": "*" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "node_modules/@jest/fake-timers/node_modules/pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", "dev": true, "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "node_modules/@jest/fake-timers/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/@types/resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "node_modules/@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "dependencies": { - "@types/node": "*" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "node_modules/@jest/globals/node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "node_modules/@jest/globals/node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, "dependencies": { - "@types/yargs-parser": "*" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", - "dev": true + "node_modules/@jest/globals/node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", - "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", + "node_modules/@jest/globals/node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/type-utils": "5.27.0", - "@typescript-eslint/utils": "5.27.0", - "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.2.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", - "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", + "node_modules/@jest/globals/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", - "debug": "^4.3.4" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=10" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", - "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", + "node_modules/@jest/globals/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", - "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", + "node_modules/@jest/globals/node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.27.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", - "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", + "node_modules/@jest/globals/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", - "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", + "node_modules/@jest/globals/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", - "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", "dev": true, "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", - "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", + "node_modules/@jest/globals/node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.27.0", - "eslint-visitor-keys": "^3.3.0" + "@jest/types": "^28.1.3", + "@types/node": "*" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/@jest/globals/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "node_modules/@jest/globals/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "node_modules/@jest/reporters": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": ">=0.4.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "node_modules/@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@jest/source-map": { + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.13", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "node_modules/@jest/test-result": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, "engines": { - "node": ">=0.4.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@jest/test-sequencer": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, "dependencies": { - "debug": "4" + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" }, "engines": { - "node": ">= 6.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/@jest/transform": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@jest/types": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "dependencies": { - "type-fest": "^0.21.3" + "@jest/schemas": "^28.1.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.0.0" } }, - "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, "engines": { - "node": ">= 8" + "node": ">=6.0.0" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", "dev": true, "dependencies": { - "sprintf-js": "~1.0.2" + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.24.28", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", + "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", + "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==", + "dev": true + }, + "node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", + "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", + "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", + "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/type-utils": "5.35.1", + "@typescript-eslint/utils": "5.35.1", + "debug": "^4.3.4", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.2.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", + "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", + "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", + "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.35.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", + "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", + "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", + "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", + "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.35.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" }, "engines": { - "node": ">= 0.4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/babel-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "dev": true, + "dependencies": { + "@jest/transform": "^28.1.3", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^28.1.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001383", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", + "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, - "node_modules/babel-jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", - "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "slash": "^3.0.0" + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, - "peerDependencies": { - "@babel/core": "^7.8.0" + "engines": { + "node": ">= 8" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" + "ms": "2.1.2" }, "engines": { - "node": ">=8" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", - "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, "engines": { "node": ">=8" } }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=0.3.1" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "path-type": "^4.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">=8" } }, - "node_modules/babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^27.2.0", - "babel-preset-current-node-syntax": "^1.0.0" + "esutils": "^2.0.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=6.0.0" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/electron-to-chromium": { + "version": "1.4.233", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz", + "integrity": "sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw==", "dev": true }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "dependencies": { - "fill-range": "^7.0.1" + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" }, "engines": { - "node": ">=8" + "node": ">=10.13.0" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "is-arrayish": "^0.2.1" } }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "node_modules/es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "dependencies": { - "fast-json-stable-stringify": "2.x" + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "dev": true, "dependencies": { - "node-int64": "^0.4.0" + "has": "^1.0.3" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, "engines": { "node": ">=6" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", - "dev": true, + "node": ">=10" + }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/eslint": { + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^6.0.1", + "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, - "node_modules/ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", - "dev": true - }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" + "debug": "^3.2.7", + "resolve": "^1.20.0" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "debug": "^3.2.7" }, "engines": { - "node": ">=7.0.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "dependencies": { - "delayed-stream": "~1.0.0" + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { - "node": ">= 0.8" + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "safe-buffer": "~5.1.1" + "ms": "2.0.0" } }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "esutils": "^2.0.2" }, "engines": { - "node": ">= 8" + "node": ">=0.10.0" } }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "node_modules/eslint-plugin-jest": { + "version": "26.8.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", + "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", "dev": true, "dependencies": { - "cssom": "~0.3.6" + "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" }, "engines": { - "node": ">=10" + "node": ">=8.0.0" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "dev": true, "dependencies": { - "ms": "2.1.2" + "eslint-visitor-keys": "^2.0.0" }, "engines": { - "node": ">=6.0" + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": true - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" } }, - "node_modules/define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", "dev": true, - "dependencies": { - "object-keys": "^1.0.12" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true, "engines": { - "node": ">=0.4.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=0.3.1" + "node": ">=4.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "dependencies": { - "esutils": "^2.0.2" + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": ">=6.0.0" + "node": ">=4" } }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", "dev": true, "dependencies": { - "webidl-conversions": "^5.0.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=8" + "node": ">=0.10" } }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=8" + "node": ">=4.0" } }, - "node_modules/electron-to-chromium": { - "version": "1.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "node_modules/enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=4.0" } }, - "node_modules/es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "get-intrinsic": "^1.1.1", - "get-symbol-description": "^1.0.0", - "has": "^1.0.3", - "has-symbols": "^1.0.2", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", - "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4.0" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=4.0" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, "engines": { - "node": ">=6" + "node": ">=0.10.0" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" + "node": ">= 0.8.0" } }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/expect": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.1.tgz", + "integrity": "sha512-yQgemsjLU+1S8t2A7pXT3Sn/v5/37LY8J+tocWtKEA0iEYYc6gfKbbJJX2fxHZmd7K9WpdbQqXUpmYkq1aewYg==", "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1" + }, "engines": { - "node": ">=4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/expect/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "@sinclair/typebox": "^0.24.1" }, "engines": { - "node": ">= 0.8.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/expect/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", "dev": true, "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/escodegen/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/expect/node_modules/diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", "dev": true, - "optional": true, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/expect/node_modules/jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", "dev": true, "dependencies": { - "prelude-ls": "~1.1.2" + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "node_modules/expect/node_modules/jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/expect/node_modules/jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "node_modules/expect/node_modules/pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", "dev": true, "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "engines": { + "node": ">=8.6.0" } }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "node": ">= 6" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", + "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", "dev": true, "dependencies": { - "ms": "2.0.0" + "reusify": "^1.0.4" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", "dev": true, "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" + "bser": "2.1.1" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-jest": { - "version": "26.4.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", - "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "flat-cache": "^3.0.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=8.0.0" + "node": ">=8" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, "engines": { - "node": ">=10" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, "dependencies": { - "is-glob": "^4.0.3" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" }, "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" + "node": ">= 0.4" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true, - "dependencies": { - "acorn": "^8.7.1", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree/node_modules/acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "bin": { - "acorn": "bin/acorn" - }, "engines": { - "node": ">=0.4.0" + "node": ">=6.9.0" } }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/ljharb" } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, "engines": { - "node": ">=0.10" + "node": ">=8.0.0" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, "engines": { - "node": ">=4.0" + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": ">=4.0" + "node": ">=10.13.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/globals": { + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/expect": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", - "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", - "dev": true, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dependencies": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6" + "function-bind": "^1.1.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4.0" } }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=8.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "dependencies": { - "reusify": "^1.0.4" + "engines": { + "node": ">=10.17.0" } }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true, - "dependencies": { - "bser": "2.1.1" + "engines": { + "node": ">= 4" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" }, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, "engines": { - "node": ">=4" + "node": ">=0.8.19" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, "engines": { - "node": ">= 6" + "node": ">= 0.4" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "has-bigints": "^1.0.1" }, - "engines": { - "node": ">=6 <7 || >=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true, "engines": { - "node": ">=6.9.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "engines": { - "node": "6.* || 8.* || >= 10.*" + "node_modules/is-core-module": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=6" } }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": "*" + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=0.12.0" } }, - "node_modules/globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { - "type-fest": "^0.20.2" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -3313,10 +4165,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { "has-symbols": "^1.0.2" @@ -3328,965 +4180,1277 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { - "whatwg-encoding": "^1.0.5" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "node_modules/istanbul-lib-instrument": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", "dev": true, "dependencies": { - "agent-base": "6", - "debug": "4" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=10.17.0" + "node": ">=8" } }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">= 4" + "node": ">=0.10.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "node_modules/jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" }, "bin": { - "import-local-fixture": "fixtures/cli.js" + "jest": "bin/jest.js" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/import-local/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", "dev": true, "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "execa": "^5.0.0", + "p-limit": "^3.1.0" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/import-local/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "node_modules/jest-circus": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.1.tgz", + "integrity": "sha512-I5J4LyK3qPo8EnqPmxsMAVR+2SFx7JOaZsbqW9xQmk4UDmTCD92EQgS162Ey3Jq6CfpKJKFDhzhG3QqiE0fRbw==", "dev": true, "dependencies": { - "p-locate": "^4.1.0" + "@jest/environment": "^29.0.1", + "@jest/expect": "^29.0.1", + "@jest/test-result": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-runtime": "^29.0.1", + "jest-snapshot": "^29.0.1", + "jest-util": "^29.0.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "node_modules/jest-circus/node_modules/@jest/console": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.1.tgz", + "integrity": "sha512-SxLvSKf9gk4Rvt3p2KRQWVQ3sVj7S37rjlCHwp2+xNcRO/X+Uw0idbkfOtciUpjghHIxyggqcrrKhThQ+vClLQ==", "dev": true, "dependencies": { - "p-try": "^2.0.0" + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "node_modules/jest-circus/node_modules/@jest/globals": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.1.tgz", + "integrity": "sha512-BtZWrVrKRKNUt7T1H2S8Mz31PN7ItROCmH+V5pn10hJDUfjOCTIUwb0WtLZzm0f1tJ3Uvx+5lVZrF/VTKqNaFg==", "dev": true, "dependencies": { - "p-limit": "^2.2.0" + "@jest/environment": "^29.0.1", + "@jest/expect": "^29.0.1", + "@jest/types": "^29.0.1", + "jest-mock": "^29.0.1" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local/node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/jest-circus/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/jest-circus/node_modules/@jest/source-map": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", + "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local/node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/jest-circus/node_modules/@jest/test-result": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.1.tgz", + "integrity": "sha512-XCA4whh/igxjBaR/Hg8qwFd/uTsauoD7QAdAYUjV2CSGx0+iunhjoCRRWTwqjQrETRqOJABx6kNfw0+C0vMSgQ==", "dev": true, "dependencies": { - "find-up": "^4.0.0" + "@jest/console": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "node_modules/jest-circus/node_modules/@jest/transform": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", + "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.0.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, "engines": { - "node": ">=0.8.19" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/jest-circus/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "node_modules/jest-circus/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus/node_modules/jest-haste-map": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", + "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.0.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "jest-worker": "^29.0.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "chalk": "^4.0.0", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/jest-circus/node_modules/jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "node_modules/jest-circus/node_modules/jest-regex-util": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", + "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", + "node_modules/jest-circus/node_modules/jest-resolve": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.1.tgz", + "integrity": "sha512-dwb5Z0lLZbptlBtPExqsHfdDamXeiRLv4vdkfPrN84vBwLSWHWcXjlM2JXD/KLSQfljBcXbzI/PDvUJuTQ84Nw==", "dev": true, "dependencies": { - "ci-info": "^3.1.1" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.0.1", + "jest-validate": "^29.0.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" }, - "bin": { - "is-ci": "bin.js" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "node_modules/jest-circus/node_modules/jest-runtime": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.1.tgz", + "integrity": "sha512-yDgz5OE0Rm44PUAfTqwA6cDFnTYnVcYbRpPECsokSASQ0I5RXpnKPVr2g0CYZWKzbsXqqtmM7TIk7CAutZJ7gQ==", + "dev": true, "dependencies": { - "has": "^1.0.3" + "@jest/environment": "^29.0.1", + "@jest/fake-timers": "^29.0.1", + "@jest/globals": "^29.0.1", + "@jest/source-map": "^29.0.0", + "@jest/test-result": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-mock": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-resolve": "^29.0.1", + "jest-snapshot": "^29.0.1", + "jest-util": "^29.0.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/jest-circus/node_modules/jest-snapshot": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", + "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.0.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-haste-map": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.0.1", + "semver": "^7.3.5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "node_modules/jest-circus/node_modules/jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", "dev": true, + "dependencies": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-circus/node_modules/jest-validate": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.1.tgz", + "integrity": "sha512-mS4q7F738YXZFWBPqE+NjHU/gEOs7IBIFQ8i9zq5EO691cLrUbLhFq4larf8/lNcmauRO71tn/+DTW2y+MrLow==", "dev": true, + "dependencies": { + "@jest/types": "^29.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.0.0", + "leven": "^3.1.0", + "pretty-format": "^29.0.1" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/jest-circus/node_modules/jest-worker": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", + "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, "engines": { - "node": ">=6" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-cli": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", "dev": true, + "dependencies": { + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=0.12.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "node_modules/jest-config": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, "engines": { - "node": ">= 0.4" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "node_modules/jest-config/node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", + "node_modules/jest-config/node_modules/@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/jest-config/node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "jest-get-type": "^28.0.2" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/jest-config/node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "node_modules/jest-config/node_modules/diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "node_modules/is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "node_modules/jest-config/node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", "dev": true, "dependencies": { - "call-bind": "^1.0.0" + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "node_modules/jest-config/node_modules/jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "node_modules/jest-config/node_modules/jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "node_modules/jest-config/node_modules/jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", "dev": true, "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/jest-config/node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/jest-config/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "node_modules/jest-config/node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "@jest/types": "^28.1.3", + "@types/node": "*" }, "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", + "node_modules/jest-config/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=8" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", - "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, "dependencies": { - "@jest/core": "^27.3.0", - "import-local": "^3.0.2", - "jest-cli": "^27.3.0" - }, - "bin": { - "jest": "bin/jest.js" + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } } }, - "node_modules/jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", + "node_modules/jest-diff/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, - "dependencies": { - "@jest/types": "^27.2.5", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-circus": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", - "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", + "node_modules/jest-docblock": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" + "detect-newline": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-cli": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", - "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", + "node_modules/jest-each": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.1.tgz", + "integrity": "sha512-UmCZYU9LPvRfSDoCrKJqrCNmgTYGGb3Ga6IVsnnVjedBTRRR9GJMca7UmDKRrJ1s+U632xrVtiRD27BxaG1aaQ==", "dev": true, "dependencies": { - "@jest/core": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/types": "^29.0.1", "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "import-local": "^3.0.2", - "jest-config": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" + "jest-get-type": "^29.0.0", + "jest-util": "^29.0.1", + "pretty-format": "^29.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-config": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", - "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", + "node_modules/jest-each/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", "dev": true, "dependencies": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.0", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.0", - "chalk": "^4.0.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.3.0", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "micromatch": "^4.0.4", - "pretty-format": "^27.3.0" + "@sinclair/typebox": "^0.24.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-config/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "node_modules/jest-each/node_modules/jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", "dev": true, "dependencies": { - "detect-newline": "^3.0.0" + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", - "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0" + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-each/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-environment-node": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-environment-jsdom": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", - "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", + "node_modules/jest-environment-node/node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0", - "jsdom": "^16.6.0" + "jest-mock": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-environment-node": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", - "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", + "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-environment-node/node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", + "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", - "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "micromatch": "^4.0.4", - "walker": "^1.0.7" + "walker": "^1.0.8" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, - "node_modules/jest-jasmine2": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", - "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", + "node_modules/jest-leak-detector": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, "dependencies": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "throat": "^6.0.1" + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-leak-detector": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", - "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-matcher-utils": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", - "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-matcher-utils/node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/jest-matcher-utils/node_modules/jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-matcher-utils/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", - "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.3.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-message-util/node_modules/@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "dependencies": { - "@babel/highlight": "^7.14.5" + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.1.tgz", + "integrity": "sha512-i1yTceg2GKJwUNZFjIzrH7Y74fN1SKJWxQX/Vu3LT4TiJerFARH5l+4URNyapZ+DNpchHYrGOP2deVbn3ma8JA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.0.1", "@types/node": "*" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock/node_modules/@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.24.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock/node_modules/@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -4307,238 +5471,395 @@ } }, "node_modules/jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-resolve": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", - "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", - "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "dev": true, + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner/node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.0" + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-runner": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", - "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", + "node_modules/jest-runner/node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", "dev": true, "dependencies": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-leak-detector": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "@jest/types": "^28.1.3", + "@types/node": "*" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-runtime": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", - "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/globals": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" + "strip-bom": "^4.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, - "node_modules/jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", + "node_modules/jest-runtime/node_modules/@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "dependencies": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "graceful-fs": "^4.2.4" + "jest-mock": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime/node_modules/@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime/node_modules/jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.3", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-snapshot": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", - "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "dev": true, "dependencies": { - "@babel/core": "^7.7.2", + "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.0", - "semver": "^7.3.2" + "pretty-format": "^28.1.3", + "semver": "^7.3.5" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", - "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-validate": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", - "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "dev": true, "dependencies": { - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", + "jest-get-type": "^28.0.2", "leven": "^3.1.0", - "pretty-format": "^27.3.0" + "pretty-format": "^28.1.3" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "engines": { "node": ">=10" @@ -4548,36 +5869,58 @@ } }, "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, "node_modules/jest-watcher": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", - "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dev": true, "dependencies": { - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", "string-length": "^4.0.1" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-worker": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", - "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, "dependencies": { "@types/node": "*", @@ -4585,7 +5928,7 @@ "supports-color": "^8.0.0" }, "engines": { - "node": ">= 10.13.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, "node_modules/jest-worker/node_modules/supports-color": { @@ -4610,76 +5953,17 @@ "dev": true }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -4692,6 +5976,12 @@ "node": ">=4" } }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -4701,17 +5991,14 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, "bin": { "json5": "lib/cli.js" }, @@ -4722,7 +6009,7 @@ "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -4759,29 +6046,31 @@ "node": ">= 0.8.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, "node_modules/lodash.merge": { @@ -4803,9 +6092,9 @@ } }, "node_modules/lua-types": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", - "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.1.tgz", + "integrity": "sha512-yWZmHe1nvaLy8tt13uDFZeOE6X80piCY48Y8KkHBSFXeclWk1hSOcMIuiEIskUbc+AQkac8FbPVfZMFm1AJceQ==", "dev": true, "peerDependencies": { "typescript-to-lua": "^1.0.0" @@ -4848,12 +6137,12 @@ "dev": true }, "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "dependencies": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "node_modules/merge-stream": { @@ -4872,39 +6161,18 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", - "dev": true, - "dependencies": { - "mime-db": "1.50.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -4941,28 +6209,19 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node_modules/node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "node_modules/normalize-path": { @@ -4986,16 +6245,10 @@ "node": ">=8" } }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, "node_modules/object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5011,14 +6264,14 @@ } }, "node_modules/object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, "engines": { @@ -5048,7 +6301,7 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { "wrappy": "1" @@ -5087,36 +6340,42 @@ } }, "node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/parent-module": { @@ -5131,25 +6390,37 @@ "node": ">=6" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5184,28 +6455,89 @@ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/picomatch": { + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, "engines": { - "node": ">=8.6" + "node": ">=6" }, "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "node-modules-regexp": "^1.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": ">= 6" + "node": ">=8" } }, "node_modules/prelude-ls": { @@ -5218,15 +6550,18 @@ } }, "node_modules/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/pretty-format": { @@ -5268,12 +6603,6 @@ "node": ">= 6" } }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -5309,6 +6638,23 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -5324,18 +6670,18 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5439,24 +6785,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -5508,9 +6836,9 @@ } }, "node_modules/signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "node_modules/sisteransi": { @@ -5529,17 +6857,17 @@ } }, "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { "node": ">= 8" } }, "node_modules/source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "dependencies": { "buffer-from": "^1.0.0", @@ -5558,7 +6886,7 @@ "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "node_modules/stack-utils": { @@ -5610,26 +6938,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5713,12 +7043,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "node_modules/tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -5760,13 +7084,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/tmpl": { @@ -5778,7 +7096,7 @@ "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, "engines": { "node": ">=4" @@ -5796,66 +7114,39 @@ "node": ">=8.0" } }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", "dev": true, "dependencies": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", "lodash.memoize": "4.x", "make-error": "1.x", "semver": "7.x", - "yargs-parser": "20.x" + "yargs-parser": "^21.0.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "esbuild": "~0.14.0", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" + "@jest/types": "^28.0.0", + "babel-jest": "^28.0.0", + "jest": "^28.0.0", + "typescript": ">=4.3" }, "peerDependenciesMeta": { "@babel/core": { "optional": true }, - "@types/jest": { + "@jest/types": { "optional": true }, "babel-jest": { @@ -5867,12 +7158,12 @@ } }, "node_modules/ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "dependencies": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -5883,11 +7174,13 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" }, "bin": { "ts-node": "dist/bin.js", "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", "ts-node-script": "dist/bin-script.js", "ts-node-transpile-only": "dist/bin-transpile.js", "ts-script": "dist/bin-script-deprecated.js" @@ -5907,27 +7200,6 @@ } } }, - "node_modules/ts-node/node_modules/acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ts-node/node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/tsconfig-paths": { "version": "3.14.1", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", @@ -5955,7 +7227,7 @@ "node_modules/tsconfig-paths/node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "engines": { "node": ">=4" @@ -6015,19 +7287,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, "node_modules/typescript": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", + "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6037,36 +7300,15 @@ "node": ">=4.2.0" } }, - "node_modules/typescript-to-lua": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", - "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", - "dev": true, - "peer": true, - "dependencies": { - "enhanced-resolve": "^5.8.2", - "resolve": "^1.15.1", - "source-map": "^0.7.3" - }, - "bin": { - "tstl": "dist/tstl.js" - }, - "engines": { - "node": ">=12.13.0" - }, - "peerDependencies": { - "typescript": "~4.7.3" - } - }, "node_modules/unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" }, "funding": { @@ -6082,6 +7324,32 @@ "node": ">= 4.0.0" } }, + "node_modules/update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -6091,92 +7359,33 @@ "punycode": "^2.1.0" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "node_modules/v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" + "convert-source-map": "^1.6.0" }, "engines": { "node": ">=10.12.0" } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "dependencies": { - "makeerror": "1.0.x" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" + "makeerror": "1.0.12" } }, "node_modules/which": { @@ -6239,54 +7448,22 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true, - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "signal-exit": "^3.0.7" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -6303,30 +7480,30 @@ "dev": true }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "dev": true, "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yn": { @@ -6337,89 +7514,110 @@ "engines": { "node": ">=6" } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } }, "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, "@babel/compat-data": { - "version": "7.15.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", - "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", + "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", "dev": true }, "@babel/core": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz", - "integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.15.8", - "@babel/generator": "^7.15.8", - "@babel/helper-compilation-targets": "^7.15.4", - "@babel/helper-module-transforms": "^7.15.8", - "@babel/helpers": "^7.15.4", - "@babel/parser": "^7.15.8", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", + "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-compilation-targets": "^7.18.9", + "@babel/helper-module-transforms": "^7.18.9", + "@babel/helpers": "^7.18.9", + "@babel/parser": "^7.18.13", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.18.13", + "@babel/types": "^7.18.13", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.1.2", - "semver": "^6.3.0", - "source-map": "^0.5.0" + "json5": "^2.2.1", + "semver": "^6.3.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true } } }, "@babel/generator": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz", - "integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", + "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", "dev": true, "requires": { - "@babel/types": "^7.15.6", - "jsesc": "^2.5.1", - "source-map": "^0.5.0" + "@babel/types": "^7.18.13", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" }, "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } } } }, "@babel/helper-compilation-targets": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz", - "integrity": "sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", + "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", "dev": true, "requires": { - "@babel/compat-data": "^7.15.0", - "@babel/helper-validator-option": "^7.14.5", - "browserslist": "^4.16.6", + "@babel/compat-data": "^7.18.8", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.20.2", "semver": "^6.3.0" }, "dependencies": { @@ -6431,144 +7629,116 @@ } } }, - "@babel/helper-function-name": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz", - "integrity": "sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.15.4", - "@babel/template": "^7.15.4", - "@babel/types": "^7.15.4" - } + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true }, - "@babel/helper-get-function-arity": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz", - "integrity": "sha512-1/AlxSF92CmGZzHnC515hm4SirTxtpDnLEJ0UyEMgTMZN+6bxXKg04dKhiRx5Enel+SUA1G1t5Ed/yQia0efrA==", + "@babel/helper-function-name": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", + "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/template": "^7.18.6", + "@babel/types": "^7.18.9" } }, "@babel/helper-hoist-variables": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz", - "integrity": "sha512-VTy085egb3jUGVK9ycIxQiPbquesq0HUQ+tPO0uv5mPEBZipk+5FkRKiWq5apuyTE9FUrjENB0rCf8y+n+UuhA==", - "dev": true, - "requires": { - "@babel/types": "^7.15.4" - } - }, - "@babel/helper-member-expression-to-functions": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz", - "integrity": "sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-imports": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz", - "integrity": "sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" } }, "@babel/helper-module-transforms": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz", - "integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==", - "dev": true, - "requires": { - "@babel/helper-module-imports": "^7.15.4", - "@babel/helper-replace-supers": "^7.15.4", - "@babel/helper-simple-access": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/helper-validator-identifier": "^7.15.7", - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.6" - } - }, - "@babel/helper-optimise-call-expression": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz", - "integrity": "sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", + "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.18.6", + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" } }, "@babel/helper-plugin-utils": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz", - "integrity": "sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", + "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", "dev": true }, - "@babel/helper-replace-supers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz", - "integrity": "sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw==", - "dev": true, - "requires": { - "@babel/helper-member-expression-to-functions": "^7.15.4", - "@babel/helper-optimise-call-expression": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" - } - }, "@babel/helper-simple-access": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz", - "integrity": "sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", + "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" } }, "@babel/helper-split-export-declaration": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.15.4.tgz", - "integrity": "sha512-HsFqhLDZ08DxCpBdEVtKmywj6PQbwnF6HHybur0MAnkAKnlS6uHkwnmRIkElB2Owpfb4xL4NwDmDLFubueDXsw==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, "requires": { - "@babel/types": "^7.15.4" + "@babel/types": "^7.18.6" } }, + "@babel/helper-string-parser": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", + "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.15.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz", - "integrity": "sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", + "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", "dev": true }, "@babel/helper-validator-option": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz", - "integrity": "sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", "dev": true }, "@babel/helpers": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.15.4.tgz", - "integrity": "sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ==", + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", + "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", "dev": true, "requires": { - "@babel/template": "^7.15.4", - "@babel/traverse": "^7.15.4", - "@babel/types": "^7.15.4" + "@babel/template": "^7.18.6", + "@babel/traverse": "^7.18.9", + "@babel/types": "^7.18.9" } }, "@babel/highlight": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", - "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.18.6", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -6605,19 +7775,19 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, "supports-color": { @@ -6632,9 +7802,9 @@ } }, "@babel/parser": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz", - "integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", + "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -6682,6 +7852,15 @@ "@babel/helper-plugin-utils": "^7.8.0" } }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, "@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", @@ -6746,62 +7925,43 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz", - "integrity": "sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==", + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", + "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/helper-plugin-utils": "^7.18.6" } }, "@babel/template": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.15.4.tgz", - "integrity": "sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg==", + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", "dev": true, "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - } + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" } }, "@babel/traverse": { - "version": "7.15.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.4.tgz", - "integrity": "sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.15.4", - "@babel/helper-function-name": "^7.15.4", - "@babel/helper-hoist-variables": "^7.15.4", - "@babel/helper-split-export-declaration": "^7.15.4", - "@babel/parser": "^7.15.4", - "@babel/types": "^7.15.4", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", + "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.18.13", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.18.9", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.18.13", + "@babel/types": "^7.18.13", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.14.5" - } - }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -6811,12 +7971,13 @@ } }, "@babel/types": { - "version": "7.15.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.6.tgz", - "integrity": "sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig==", + "version": "7.18.13", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", + "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.9", + "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-validator-identifier": "^7.18.6", "to-fast-properties": "^2.0.0" } }, @@ -6826,363 +7987,885 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } + } + }, + "@eslint/eslintrc": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", + "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.15.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + } + }, + "@humanwhocodes/config-array": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", + "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.4" + } + }, + "@humanwhocodes/gitignore-to-minimatch": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", + "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", + "dev": true + }, + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "@jest/console": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", + "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", + "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "dev": true, + "requires": { + "@jest/console": "^28.1.3", + "@jest/reporters": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.1.3", + "jest-config": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-resolve-dependencies": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", + "jest-watcher": "^28.1.3", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.3", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } + } + }, + "@jest/environment": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.1.tgz", + "integrity": "sha512-iLcFfoq2K6DAB+Mc+2VNLzZVmHdwQFeSqvoM/X8SMON6s/+yEi1iuRX3snx/JfwSnvmiMXjSr0lktxNxOcqXYA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/node": "*", + "jest-mock": "^29.0.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + } + } + }, + "@jest/expect": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.1.tgz", + "integrity": "sha512-qKB3q52XDV8VUEiqKKLgLrJx7puQ8sYVqIDlul6n7SIXWS97DOK3KqbR2rDDaMtmenRHqEUl2fI+aFzx0oSemA==", + "dev": true, + "requires": { + "expect": "^29.0.1", + "jest-snapshot": "^29.0.1" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/transform": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", + "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.0.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "dev": true + }, + "jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-haste-map": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", + "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "jest-worker": "^29.0.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-regex-util": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", + "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "dev": true + }, + "jest-snapshot": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", + "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.0.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-haste-map": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.0.1", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-worker": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", + "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/expect-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.1.tgz", + "integrity": "sha512-Tw5kUUOKmXGQDmQ9TSgTraFFS7HMC1HG/B7y0AN2G2UzjdAXz9BzK2rmNpCSDl7g7y0Gf/VLBm//blonvhtOTQ==", "dev": true, "requires": { - "@cspotcode/source-map-consumer": "0.8.0" + "jest-get-type": "^29.0.0" } }, - "@eslint/eslintrc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", - "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", + "@jest/fake-timers": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.1.tgz", + "integrity": "sha512-XZ+kAhLChVQ+KJNa5034p7O1Mz3vtWrelxDcMoxhZkgqmWDaEQAW9qJeutaeCfPvwaEwKYVyKDYfWpcyT8RiMw==", "dev": true, "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.3.2", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@jest/types": "^29.0.1", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^29.0.1", + "jest-mock": "^29.0.1", + "jest-util": "^29.0.1" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", "dev": true, "requires": { - "argparse": "^2.0.1" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, - "@humanwhocodes/config-array": { - "version": "0.9.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", - "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "@jest/globals": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", + "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", "dev": true, "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/types": "^28.1.3" }, "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" } }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", "dev": true, "requires": { - "p-try": "^2.0.0" + "jest-get-type": "^28.0.2" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + } + }, + "jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + } + }, + "jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*" + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.3.0.tgz", - "integrity": "sha512-+Tr/xoNiosjckq96xIGpDaGsybeIm45VWXpSvDR8T9deXmWjYKX85prhz8yFPhLG4UVOeMo/B6RI/+flw3sO8A==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.3.0", - "jest-util": "^27.3.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.3.0.tgz", - "integrity": "sha512-0B3PWQouwS651m8AbQDse08dfRlzLHqSmywRPGYn2ZzU6RT4aP2Xwz8mEWfSPXXZmtwAtNgUXy0Cbt6QsBqKvw==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/reporters": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^27.3.0", - "jest-config": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-resolve-dependencies": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", - "jest-watcher": "^27.3.0", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.3.0.tgz", - "integrity": "sha512-OWx5RBd8QaPLlw7fL6l2IVyhYDpamaW3dDXlBnXb4IPGCIwoXAHZkmHV+VPIzb6xAkcPyXOmVm/rSaEneTqweg==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0" - } - }, - "@jest/fake-timers": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.3.0.tgz", - "integrity": "sha512-GCWgnItK6metb75QKflFxcVRlraVGomZonBQ+9B5UPc6wxBB3xzS7dATDWe/73R5P6BfnzCEaiizna771M5r9w==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" - } - }, - "@jest/globals": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.3.0.tgz", - "integrity": "sha512-EEqmQHMLXgEZfchMVAavUfJuZmORRrP+zhomfREqVE85d1nccd7nw8uN4FQDJ53m5Glm1XtVCyOIJ9kQLrqjeA==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/types": "^27.2.5", - "expect": "^27.3.0" - } - }, "@jest/reporters": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.3.0.tgz", - "integrity": "sha512-D9QLaLgbH+nIjDbKIvoX7yiRX6aXHO56/GzOxKNzKuvJVYhrzeQHcCMttXpp5SB08TdxVvFOPKZfFvkIcVgfBA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", + "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-instrument": "^5.1.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "slash": "^3.0.0", - "source-map": "^0.6.0", "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", + "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" } }, "@jest/source-map": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.0.6.tgz", - "integrity": "sha512-Fek4mi5KQrqmlY07T23JRi0e7Z9bXTOOD86V/uS0EIW4PClvPDqZOyFlLpNJheS6QI0FNX1CgmPjtJ4EA/2M+g==", + "version": "28.1.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", + "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.13", "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.3.0.tgz", - "integrity": "sha512-5+rYZgj562oPKjExQngfboobeIF2FSrgAvoxlkrogEMIbgT7FY+VAMIkp03klVfJtqo3XKzVWkTfsDSmZFI29w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", + "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", "dev": true, "requires": { - "@jest/console": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^28.1.3", + "@jest/types": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.3.0.tgz", - "integrity": "sha512-6eQHyBUCtK06sPfsufzEVijZtAtT7yGR1qaAZBlcz6P+FGJ569VW2O5o7mZc+L++uZc7BH4X2Ks7SMIgy1npJw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", + "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", "dev": true, "requires": { - "@jest/test-result": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-runtime": "^27.3.0" + "@jest/test-result": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "slash": "^3.0.0" } }, "@jest/transform": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.3.0.tgz", - "integrity": "sha512-IKrFhIT/+WIfeNjIRKTwQN7HYCdjKF/mmBqoD660gyGWVw1MzCO9pQuEJK9GXEnFWIuOcMHlm8XfUaDohP/zxA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", + "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.2.5", - "babel-plugin-istanbul": "^6.0.0", + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.3", + "@jridgewell/trace-mapping": "^0.3.13", + "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-util": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", "micromatch": "^4.0.4", - "pirates": "^4.0.1", + "pirates": "^4.0.4", "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "write-file-atomic": "^4.0.1" } }, "@jest/types": { - "version": "27.2.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", - "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", + "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", "dev": true, "requires": { + "@jest/schemas": "^28.1.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^16.0.0", + "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.15", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", + "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7209,6 +8892,12 @@ "fastq": "^1.6.0" } }, + "@sinclair/typebox": { + "version": "0.24.28", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", + "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", + "dev": true + }, "@sinonjs/commons": { "version": "1.8.3", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", @@ -7219,48 +8908,42 @@ } }, "@sinonjs/fake-timers": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.0.1.tgz", - "integrity": "sha512-AU7kwFxreVd6OAXcAFlKSmZquiRUU0FvYm44k1Y1QbK7Co4m0aqfGMhjykIeQp/H6rcl+nFmj0zfdUcGVs9Dew==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0" } }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true - }, "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", "dev": true }, "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", "dev": true }, "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", "dev": true }, "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", "dev": true }, "@types/babel__core": { - "version": "7.1.16", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.16.tgz", - "integrity": "sha512-EAEHtisTMM+KaKwfWdC3oyllIqswlznXCIVCt7/oRNrh+DhgT4UEBNC/jlADNjvw7UnfbcdkGQcPVZ1xYiLcrQ==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -7271,9 +8954,9 @@ } }, "@types/babel__generator": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.3.tgz", - "integrity": "sha512-/GWCmzJWqV7diQW54smJZzWbSFf4QYtF71WCKhcx6Ru/tFyQIY2eiiITcCAeuPbNSvT9YCGkVMqqvSk2Z0mXiA==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" @@ -7290,9 +8973,9 @@ } }, "@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", + "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -7308,9 +8991,9 @@ } }, "@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "requires": { "@types/minimatch": "*", @@ -7327,9 +9010,9 @@ } }, "@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", "dev": true }, "@types/istanbul-lib-report": { @@ -7361,9 +9044,9 @@ } }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/json5": { @@ -7373,9 +9056,9 @@ "dev": true }, "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", + "integrity": "sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==", "dev": true }, "@types/node": { @@ -7385,9 +9068,9 @@ "dev": true }, "@types/prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-Fo79ojj3vdEZOHg3wR9ksAMRz4P3S5fDB5e/YWZiFnyFQI1WY2Vftu9XoXVVtJfxB7Bpce/QTqWSSntkz2Znrw==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", + "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", "dev": true }, "@types/resolve": { @@ -7406,29 +9089,29 @@ "dev": true }, "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "version": "17.0.11", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", + "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", - "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.0.tgz", - "integrity": "sha512-DDrIA7GXtmHXr1VCcx9HivA39eprYBIFxbQEHI6NyraRDxCGpxAFiYQAT/1Y0vh1C+o2vfBiy4IuPoXxtTZCAQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", + "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/type-utils": "5.27.0", - "@typescript-eslint/utils": "5.27.0", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/type-utils": "5.35.1", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -7438,52 +9121,52 @@ } }, "@typescript-eslint/parser": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.0.tgz", - "integrity": "sha512-8oGjQF46c52l7fMiPPvX4It3u3V3JipssqDfHQ2hcR0AeR8Zge+OYyKUCm5b70X72N1qXt0qgHenwN6Gc2SXZA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", + "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.27.0.tgz", - "integrity": "sha512-VnykheBQ/sHd1Vt0LJ1JLrMH1GzHO+SzX6VTXuStISIsvRiurue/eRkTqSrG0CexHQgKG8shyJfR4o5VYioB9g==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", + "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0" + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1" } }, "@typescript-eslint/type-utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.27.0.tgz", - "integrity": "sha512-vpTvRRchaf628Hb/Xzfek+85o//zEUotr1SmexKvTfs7czXfYjXVT/a5yDbpzLBX1rhbqxjDdr1Gyo0x1Fc64g==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", + "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.27.0", + "@typescript-eslint/utils": "5.35.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.27.0.tgz", - "integrity": "sha512-lY6C7oGm9a/GWhmUDOs3xAVRz4ty/XKlQ2fOLr8GAIryGn0+UBOoJDWyHer3UgrHkenorwvBnphhP+zPmzmw0A==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", + "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.27.0.tgz", - "integrity": "sha512-QywPMFvgZ+MHSLRofLI7BDL+UczFFHyj0vF5ibeChDAJgdTV8k4xgEwF0geFhVlPc1p8r70eYewzpo6ps+9LJQ==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", + "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/visitor-keys": "5.27.0", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/visitor-keys": "5.35.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7492,81 +9175,47 @@ } }, "@typescript-eslint/utils": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.27.0.tgz", - "integrity": "sha512-nZvCrkIJppym7cIbP3pOwIkAefXOmfGPnCM0LQfzNaKxJHI6VjI8NC662uoiPlaf5f6ymkTy9C3NQXev2mdXmA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", + "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.27.0", - "@typescript-eslint/types": "5.27.0", - "@typescript-eslint/typescript-estree": "5.27.0", + "@typescript-eslint/scope-manager": "5.35.1", + "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/typescript-estree": "5.35.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.27.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.27.0.tgz", - "integrity": "sha512-46cYrteA2MrIAjv9ai44OQDUoCZyHeGIc4lsjCUX2WT6r4C+kidz1bNiR4017wHOPUythYeH+Sc7/cFP97KEAA==", + "version": "5.35.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", + "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.27.0", + "@typescript-eslint/types": "5.35.1", "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } } }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "version": "8.8.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", + "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", "dev": true }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -7628,23 +9277,20 @@ "dev": true }, "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" } @@ -7656,35 +9302,29 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, "babel-jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.3.0.tgz", - "integrity": "sha512-+Utvd2yZkT7tkgbBqVcH3uRpgRSTKRi0uBtVkjmuw2jFxp45rQ9fROSqqeHKzHYRelgdVOtQ3M745Wnyme/xOg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", + "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", "dev": true, "requires": { - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/transform": "^28.1.3", "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^27.2.0", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.1.3", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "slash": "^3.0.0" } }, @@ -7699,38 +9339,17 @@ "@istanbuljs/schema": "^0.1.2", "istanbul-lib-instrument": "^5.0.4", "test-exclude": "^6.0.0" - }, - "dependencies": { - "istanbul-lib-instrument": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.0.4.tgz", - "integrity": "sha512-W6jJF9rLGEISGoCyXRqa/JCGQGmmxPO10TMu7izaUTynxvBvTjqzAIIGCK9USBmIbQAaSWD6XJPrM9Pv5INknw==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "babel-plugin-jest-hoist": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.2.0.tgz", - "integrity": "sha512-TOux9khNKdi64mW+0OIhcmbAn75tTlzKhxmiNXevQaPbrBYK7YKjP1jl6NHTJ6XR5UgUrJbCnWlKVnJn29dfjw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", + "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", "dev": true, "requires": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", + "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" } }, @@ -7755,12 +9374,12 @@ } }, "babel-preset-jest": { - "version": "27.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.2.0.tgz", - "integrity": "sha512-z7MgQ3peBwN5L5aCqBKnF6iqdlvZvFUQynEhu0J+X9nHLU72jO3iY331lcYrg+AssJ8q7xsv5/3AICzVmJ/wvg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", + "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^27.2.0", + "babel-plugin-jest-hoist": "^28.1.3", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -7789,23 +9408,16 @@ "fill-range": "^7.0.1" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "browserslist": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.4.tgz", - "integrity": "sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ==", + "version": "4.21.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", + "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001265", - "electron-to-chromium": "^1.3.867", - "escalade": "^3.1.1", - "node-releases": "^2.0.0", - "picocolors": "^1.0.0" + "caniuse-lite": "^1.0.30001370", + "electron-to-chromium": "^1.4.202", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.5" } }, "bs-logger": { @@ -7855,9 +9467,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001269", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001269.tgz", - "integrity": "sha512-UOy8okEVs48MyHYgV+RdW1Oiudl1H6KolybD6ZquD0VcrPSgj25omXO1S7rDydjpqaISCwA8Pyx+jUQKZwWO5w==", + "version": "1.0.30001383", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", + "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", "dev": true }, "chalk": { @@ -7877,9 +9489,9 @@ "dev": true }, "ci-info": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.2.0.tgz", - "integrity": "sha512-dVqRX7fLUm8J6FgHJ418XuIgDLZDkYcDFTeL6TA2gt5WlIZUQrrH6EZrNClwT/H0FateUsZkGIOPRrLbP+PR9A==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", + "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", "dev": true }, "cjs-module-lexer": { @@ -7902,7 +9514,7 @@ "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true }, "collect-v8-coverage": { @@ -7926,19 +9538,10 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "requires": { - "delayed-stream": "~1.0.0" - } - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "convert-source-map": { @@ -7967,40 +9570,6 @@ "which": "^2.0.1" } }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -8010,16 +9579,10 @@ "ms": "2.1.2" } }, - "decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", "dev": true }, "deep-is": { @@ -8035,20 +9598,15 @@ "dev": true }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -8061,6 +9619,12 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -8079,33 +9643,16 @@ "esutils": "^2.0.2" } }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, "electron-to-chromium": { - "version": "1.3.871", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.871.tgz", - "integrity": "sha512-qcLvDUPf8DSIMWarHT2ptgcqrYg62n3vPA7vhrOF24d8UNzbUBaHu2CySiENR3nEDzYgaN60071t0F6KLYMQ7Q==", + "version": "1.4.233", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz", + "integrity": "sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw==", "dev": true }, "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", "dev": true }, "emoji-regex": { @@ -8115,40 +9662,61 @@ "dev": true }, "enhanced-resolve": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz", - "integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" } }, "es-to-primitive": { @@ -8174,81 +9742,16 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, "eslint": { - "version": "8.17.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", - "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "version": "8.23.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", + "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.0", - "@humanwhocodes/config-array": "^0.9.2", + "@eslint/eslintrc": "^1.3.1", + "@humanwhocodes/config-array": "^0.10.4", + "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@humanwhocodes/module-importer": "^1.0.1", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -8258,14 +9761,17 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.2", + "espree": "^9.4.0", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", + "globby": "^11.1.0", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -8280,16 +9786,9 @@ "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "dependencies": { - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -8300,35 +9799,11 @@ "estraverse": "^5.2.0" } }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - }, "estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } } } }, @@ -8354,13 +9829,12 @@ } }, "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" + "debug": "^3.2.7" }, "dependencies": { "debug": { @@ -8416,15 +9890,15 @@ "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true } } }, "eslint-plugin-jest": { - "version": "26.4.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.4.6.tgz", - "integrity": "sha512-R3mq1IepnhtsukHQsWxdyKra3OVwYB+N4k8i45ndqSfr8p9KZV6G+EIUt1Z7hzAh4KlsbXG+nCTlNeGFLFLNvA==", + "version": "26.8.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", + "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -8447,37 +9921,31 @@ "dev": true, "requires": { "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } } }, "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", "dev": true }, "espree": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", - "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", "dev": true, "requires": { - "acorn": "^8.7.1", + "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" - }, - "dependencies": { - "acorn": { - "version": "8.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", - "dev": true - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true - } } }, "esprima": { @@ -8496,9 +9964,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -8513,9 +9981,9 @@ }, "dependencies": { "estraverse": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", - "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true } } @@ -8552,33 +10020,127 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true }, "expect": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.3.0.tgz", - "integrity": "sha512-JBRU82EBkZUBqLBAoF3ovzNGEBm14QQnePK4PmZdm6de6q/UzPnmIuWP3dRCw/FE8wRQhf/1eKzy1p1q8d6EvQ==", + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.1.tgz", + "integrity": "sha512-yQgemsjLU+1S8t2A7pXT3Sn/v5/37LY8J+tocWtKEA0iEYYc6gfKbbJJX2fxHZmd7K9WpdbQqXUpmYkq1aewYg==", "dev": true, "requires": { - "@jest/types": "^27.2.5", - "ansi-styles": "^5.0.0", - "jest-get-type": "^27.0.6", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-regex-util": "^27.0.6" + "@jest/expect-utils": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1" }, "dependencies": { + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "dev": true + }, + "jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } @@ -8600,6 +10162,17 @@ "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } } }, "fast-json-stable-stringify": { @@ -8611,7 +10184,7 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "fastq": { @@ -8651,12 +10224,13 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" } }, "flat-cache": { @@ -8670,22 +10244,11 @@ } }, "flatted": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.2.tgz", - "integrity": "sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -8700,7 +10263,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "fsevents": { @@ -8715,10 +10278,28 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", + "dev": true + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", "dev": true }, "gensync": { @@ -8734,14 +10315,14 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", "dev": true, "requires": { "function-bind": "^1.1.1", "has": "^1.0.3", - "has-symbols": "^1.0.1" + "has-symbols": "^1.0.3" } }, "get-package-type": { @@ -8767,32 +10348,32 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "requires": { - "is-glob": "^4.0.1" + "is-glob": "^4.0.3" } }, "globals": { - "version": "13.15.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", - "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", + "version": "13.17.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", + "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8813,9 +10394,15 @@ } }, "graceful-fs": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", - "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==" + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true }, "has": { "version": "1.0.3", @@ -8826,9 +10413,9 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, "has-flag": { @@ -8837,10 +10424,19 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, "has-tostringtag": { @@ -8852,57 +10448,18 @@ "has-symbols": "^1.0.2" } }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, "human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", @@ -8920,85 +10477,25 @@ } }, "import-local": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.3.tgz", - "integrity": "sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, "requires": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - } - } } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -9022,6 +10519,12 @@ "side-channel": "^1.0.4" } }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, "is-bigint": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", @@ -9047,19 +10550,10 @@ "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, - "is-ci": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.0.tgz", - "integrity": "sha512-kDXyttuLeslKAHYL/K28F2YkM3x5jvFPEw3yXbRptXydjD9rpLEz+C5K5iutY9ZiUu6AP41JdvRQwF4Iqs4ZCQ==", - "dev": true, - "requires": { - "ci-info": "^3.1.1" - } - }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", + "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", "requires": { "has": "^1.0.3" } @@ -9076,7 +10570,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true }, "is-fullwidth-code-point": { @@ -9101,9 +10595,9 @@ } }, "is-negative-zero": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", - "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true }, "is-number": { @@ -9113,20 +10607,14 @@ "dev": true }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" } }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -9138,10 +10626,13 @@ } }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { "version": "2.0.1", @@ -9167,25 +10658,19 @@ "has-symbols": "^1.0.2" } }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, "is-weakref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.1.tgz", - "integrity": "sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "requires": { - "call-bind": "^1.0.0" + "call-bind": "^1.0.2" } }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "istanbul-lib-coverage": { @@ -9195,14 +10680,15 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", "dev": true, "requires": { - "@babel/core": "^7.7.5", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" }, "dependencies": { @@ -9244,563 +10730,1314 @@ } } }, - "istanbul-reports": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.5.tgz", - "integrity": "sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "dev": true - }, - "jest": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.3.0.tgz", - "integrity": "sha512-ZSwT6ROUbUs3bXirxzxBvohE/1y7t+IHIu3fL8WgIeJppE2XsFoa2dB03CI9kXA81znW0Kt0t2R+QVOWeY8cYw==", - "dev": true, - "requires": { - "@jest/core": "^27.3.0", - "import-local": "^3.0.2", - "jest-cli": "^27.3.0" - } - }, - "jest-changed-files": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.3.0.tgz", - "integrity": "sha512-9DJs9garMHv4RhylUMZgbdCJ3+jHSkpL9aaVKp13xtXAD80qLTLrqcDZL1PHA9dYA0bCI86Nv2BhkLpLhrBcPg==", - "dev": true, - "requires": { - "@jest/types": "^27.2.5", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.3.0.tgz", - "integrity": "sha512-i2P6t92Z6qujHD7C0nVYWm9YofUBMbOOTE9q9vEGi9qFotKUZv1H8M0H3NPTOWButgFuSXZfcwGBXGDAt7b9NA==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "jest": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", + "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", + "dev": true, + "requires": { + "@jest/core": "^28.1.3", + "@jest/types": "^28.1.3", + "import-local": "^3.0.2", + "jest-cli": "^28.1.3" + } + }, + "jest-changed-files": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", + "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.1.tgz", + "integrity": "sha512-I5J4LyK3qPo8EnqPmxsMAVR+2SFx7JOaZsbqW9xQmk4UDmTCD92EQgS162Ey3Jq6CfpKJKFDhzhG3QqiE0fRbw==", + "dev": true, + "requires": { + "@jest/environment": "^29.0.1", + "@jest/expect": "^29.0.1", + "@jest/test-result": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-runtime": "^29.0.1", + "jest-snapshot": "^29.0.1", + "jest-util": "^29.0.1", + "p-limit": "^3.1.0", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "@jest/console": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.1.tgz", + "integrity": "sha512-SxLvSKf9gk4Rvt3p2KRQWVQ3sVj7S37rjlCHwp2+xNcRO/X+Uw0idbkfOtciUpjghHIxyggqcrrKhThQ+vClLQ==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "slash": "^3.0.0" + } + }, + "@jest/globals": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.1.tgz", + "integrity": "sha512-BtZWrVrKRKNUt7T1H2S8Mz31PN7ItROCmH+V5pn10hJDUfjOCTIUwb0WtLZzm0f1tJ3Uvx+5lVZrF/VTKqNaFg==", + "dev": true, + "requires": { + "@jest/environment": "^29.0.1", + "@jest/expect": "^29.0.1", + "@jest/types": "^29.0.1", + "jest-mock": "^29.0.1" + } + }, + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/source-map": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", + "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.1.tgz", + "integrity": "sha512-XCA4whh/igxjBaR/Hg8qwFd/uTsauoD7QAdAYUjV2CSGx0+iunhjoCRRWTwqjQrETRqOJABx6kNfw0+C0vMSgQ==", + "dev": true, + "requires": { + "@jest/console": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/transform": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", + "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.0.1", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "diff-sequences": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", + "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "dev": true + }, + "jest-diff": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", + "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.0.0", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-haste-map": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", + "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.0.0", + "jest-util": "^29.0.1", + "jest-worker": "^29.0.1", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-matcher-utils": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", + "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "pretty-format": "^29.0.1" + } + }, + "jest-message-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", + "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.0.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.0.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-regex-util": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", + "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "dev": true + }, + "jest-resolve": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.1.tgz", + "integrity": "sha512-dwb5Z0lLZbptlBtPExqsHfdDamXeiRLv4vdkfPrN84vBwLSWHWcXjlM2JXD/KLSQfljBcXbzI/PDvUJuTQ84Nw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.0.1", + "jest-validate": "^29.0.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-runtime": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.1.tgz", + "integrity": "sha512-yDgz5OE0Rm44PUAfTqwA6cDFnTYnVcYbRpPECsokSASQ0I5RXpnKPVr2g0CYZWKzbsXqqtmM7TIk7CAutZJ7gQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.0.1", + "@jest/fake-timers": "^29.0.1", + "@jest/globals": "^29.0.1", + "@jest/source-map": "^29.0.0", + "@jest/test-result": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-mock": "^29.0.1", + "jest-regex-util": "^29.0.0", + "jest-resolve": "^29.0.1", + "jest-snapshot": "^29.0.1", + "jest-util": "^29.0.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", + "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.0.1", + "@jest/transform": "^29.0.1", + "@jest/types": "^29.0.1", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.0.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.0.1", + "jest-get-type": "^29.0.0", + "jest-haste-map": "^29.0.1", + "jest-matcher-utils": "^29.0.1", + "jest-message-util": "^29.0.1", + "jest-util": "^29.0.1", + "natural-compare": "^1.4.0", + "pretty-format": "^29.0.1", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.1.tgz", + "integrity": "sha512-mS4q7F738YXZFWBPqE+NjHU/gEOs7IBIFQ8i9zq5EO691cLrUbLhFq4larf8/lNcmauRO71tn/+DTW2y+MrLow==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.0.0", + "leven": "^3.1.0", + "pretty-format": "^29.0.1" + } + }, + "jest-worker": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", + "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + } + }, + "pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "jest-cli": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.3.0.tgz", - "integrity": "sha512-PUM2RHhqgGRuGc+7QTuyfqPPWGDTCQNMKhtlVBTBYOvhP+7g8a1a7OztM/wfpsKHfqQLHFIe1Mms6jVSXSi4Vg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", + "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", "dev": true, "requires": { - "@jest/core": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/core": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "jest-config": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "prompts": "^2.0.1", - "yargs": "^16.2.0" + "yargs": "^17.3.1" } }, "jest-config": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.3.0.tgz", - "integrity": "sha512-hGknSnu6qJmwENNSUNY4qQjE9PENIYp4P8yHLVzo7qoQN4wuYHZuZEwAKaoQ66iHeSXmcZkCqFvAUa5WFdB0sg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", + "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", "dev": true, "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^27.3.0", - "@jest/types": "^27.2.5", - "babel-jest": "^27.3.0", + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.3", + "@jest/types": "^28.1.3", + "babel-jest": "^28.1.3", "chalk": "^4.0.0", + "ci-info": "^3.2.0", "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", - "jest-circus": "^27.3.0", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-jasmine2": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-runner": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.3", + "jest-environment-node": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-runner": "^28.1.3", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "micromatch": "^4.0.4", - "pretty-format": "^27.3.0" + "parse-json": "^5.2.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + } + }, + "@jest/expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "dev": true, + "requires": { + "expect": "^28.1.3", + "jest-snapshot": "^28.1.3" + } + }, + "@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2" + } + }, + "@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "diff-sequences": { + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "dev": true + }, + "expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "jest-circus": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", + "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.3", + "@jest/expect": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", + "p-limit": "^3.1.0", + "pretty-format": "^28.1.3", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-diff": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + } + }, + "jest-each": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", + "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.3", + "pretty-format": "^28.1.3" + } + }, + "jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + } + }, + "jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*" + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + } + } + }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "dependencies": { "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true } } }, "jest-docblock": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.0.6.tgz", - "integrity": "sha512-Fid6dPcjwepTFraz0YxIMCi7dejjJ/KL9FBjPYhBp4Sv1Y9PdhImlKZqYU555BlN4TQKaTc+F2Av1z+anVyGkA==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", + "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.3.0.tgz", - "integrity": "sha512-i7qQt+puYusxOoiNyq/M6EyNcfEbvKvqOp89FbiHfm6/POTxgzpp5wAmoS9+BAssoX20t7Zt1A1M7yT3FLVvdg==", + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.1.tgz", + "integrity": "sha512-UmCZYU9LPvRfSDoCrKJqrCNmgTYGGb3Ga6IVsnnVjedBTRRR9GJMca7UmDKRrJ1s+U632xrVtiRD27BxaG1aaQ==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.0.1", "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0" + "jest-get-type": "^29.0.0", + "jest-util": "^29.0.1", + "pretty-format": "^29.0.1" }, "dependencies": { - "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "jest-util": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", + "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "dev": true, + "requires": { + "@jest/types": "^29.0.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "pretty-format": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", + "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } }, - "jest-environment-jsdom": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.3.0.tgz", - "integrity": "sha512-2R1w1z7ZlQkK22bo/MrMp7ItuCxXXFspn3HNdbusbtW4OfutaPNWPmAch1Shtuu7G75jEnDb2q0PXSfFD6kEHQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0", - "jsdom": "^16.6.0" - } - }, "jest-environment-node": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.3.0.tgz", - "integrity": "sha512-bH2Zb73K4x2Yw8j83mmlJUUOFJLzwIpupRvlS9PXiCeIgVTPxL5syBeq5lz310DQBQkNLDTSD5+yYRhheVKvWg==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", + "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", "dev": true, "requires": { - "@jest/environment": "^27.3.0", - "@jest/fake-timers": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", - "jest-mock": "^27.3.0", - "jest-util": "^27.3.0" + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + }, + "dependencies": { + "@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + } + }, + "@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*" + } + } } }, + "jest-get-type": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", + "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "dev": true + }, "jest-haste-map": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.3.0.tgz", - "integrity": "sha512-HV7BXCWhHFuQyLCnmy+VzvYQDccTdt5gpmt2abwIrWTnQiHNAklLB3Djq7Ze3OypTmWBMLgF8AHcKNmLKx8Rzw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", + "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", - "@types/graceful-fs": "^4.1.2", + "@jest/types": "^28.1.3", + "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", - "graceful-fs": "^4.2.4", - "jest-regex-util": "^27.0.6", - "jest-serializer": "^27.0.6", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.3", + "jest-worker": "^28.1.3", "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.3.0.tgz", - "integrity": "sha512-c12xS913sE56pBYZYIuukttDyMJTgK+T/aYKuHse/jyBHk2r78IFxrEl0BL8iiezLZw6g6bKtyww/j9XWOVxqg==", - "dev": true, - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.3.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "pretty-format": "^27.3.0", - "throat": "^6.0.1" + "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.3.0.tgz", - "integrity": "sha512-xlCDZUaVVpCOAAiW7b8sgxIzTkEmpElwmWe9wVdU01WnFCvQ0aQiq2JTNbeCgalhjxJVeZlACRHIsLjWrmtlRA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", + "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", "dev": true, "requires": { - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } }, "jest-matcher-utils": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.3.0.tgz", - "integrity": "sha512-AK2ds5J29PJcZhfJ/5J8ycbjCXTHnwc6lQeOV1a1GahU1MCpSvyHG1iIevyvp6PXPy6r0q9ywGdCObWHmkK16g==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" }, "dependencies": { - "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", - "dev": true - }, - "jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" - } - }, "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true } } }, "jest-message-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.3.0.tgz", - "integrity": "sha512-0c79aomiyE3mlta4NCWsICydvv2W0HlM/eVx46YEO+vdDuwUvNuQn8LqOtcHC1hSd25i03RrPvscrWgHBJQpRQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", + "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", + "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^27.3.0", + "pretty-format": "^28.1.3", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { - "@babel/code-frame": { - "version": "7.15.8", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz", - "integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==", + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", "dev": true, "requires": { - "@babel/highlight": "^7.14.5" + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true } } }, "jest-mock": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.3.0.tgz", - "integrity": "sha512-ziZiLk0elZOQjD08bLkegBzv5hCABu/c8Ytx45nJKkysQwGaonvmTxwjLqEA4qGdasq9o2I8/HtdGMNnVsMTGw==", + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.1.tgz", + "integrity": "sha512-i1yTceg2GKJwUNZFjIzrH7Y74fN1SKJWxQX/Vu3LT4TiJerFARH5l+4URNyapZ+DNpchHYrGOP2deVbn3ma8JA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^29.0.1", "@types/node": "*" + }, + "dependencies": { + "@jest/schemas": { + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", + "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.24.1" + } + }, + "@jest/types": { + "version": "29.0.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", + "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "dev": true, + "requires": { + "@jest/schemas": "^29.0.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + } } }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "requires": {} + "dev": true }, "jest-regex-util": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.0.6.tgz", - "integrity": "sha512-SUhPzBsGa1IKm8hx2F4NfTGGp+r7BXJ4CulsZ1k2kI+mGLG+lxGrs76veN2LF/aUdGosJBzKgXmNCw+BzFqBDQ==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", "dev": true }, "jest-resolve": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.3.0.tgz", - "integrity": "sha512-SZxjtEkM0+f5vxJVpaGztQfnzEqgVnQqHzeGW1P9UON9qDtAET01HWaPCnb10SNUaNRG9NhhOMP418zl44FaIA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", + "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", "dev": true, "requires": { - "@jest/types": "^27.2.5", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "jest-util": "^28.1.3", + "jest-validate": "^28.1.3", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.3.0.tgz", - "integrity": "sha512-YVmlWHdSUCOLrJl8lOIjda6+DtbgOCfExfoSx9gvHFYaXPq0UP2EELiX514H0rURTbSaLsDTodLNyqqEd/IqeA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", + "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", - "jest-regex-util": "^27.0.6", - "jest-snapshot": "^27.3.0" + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.3" } }, "jest-runner": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.3.0.tgz", - "integrity": "sha512-gbkXXJdV5YpGjHvHZAAl5905qAgi+HLYO9lvLqGBxAWpx+oPOpBcMZfkRef7u86heZj1lmULzEdLjY459Z+rNQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", + "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", "dev": true, "requires": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/console": "^28.1.3", + "@jest/environment": "^28.1.3", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-docblock": "^27.0.6", - "jest-environment-jsdom": "^27.3.0", - "jest-environment-node": "^27.3.0", - "jest-haste-map": "^27.3.0", - "jest-leak-detector": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-runtime": "^27.3.0", - "jest-util": "^27.3.0", - "jest-worker": "^27.3.0", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.1.1", + "jest-environment-node": "^28.1.3", + "jest-haste-map": "^28.1.3", + "jest-leak-detector": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-resolve": "^28.1.3", + "jest-runtime": "^28.1.3", + "jest-util": "^28.1.3", + "jest-watcher": "^28.1.3", + "jest-worker": "^28.1.3", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "dependencies": { + "@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + } + }, + "@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*" + } + } } }, "jest-runtime": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.3.0.tgz", - "integrity": "sha512-CRhIM45UlYVY2u5IfCx+0jsCm6DLvY9fz34CzDi3c4W1prb7hGKLOJlxbayQIHHMhUx22WhK4eRqXjOKDnKdAQ==", - "dev": true, - "requires": { - "@jest/console": "^27.3.0", - "@jest/environment": "^27.3.0", - "@jest/globals": "^27.3.0", - "@jest/source-map": "^27.0.6", - "@jest/test-result": "^27.3.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/yargs": "^16.0.0", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", + "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.3", + "@jest/fake-timers": "^28.1.3", + "@jest/globals": "^28.1.3", + "@jest/source-map": "^28.1.2", + "@jest/test-result": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "execa": "^5.0.0", - "exit": "^0.1.2", "glob": "^7.1.3", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-mock": "^27.3.0", - "jest-regex-util": "^27.0.6", - "jest-resolve": "^27.3.0", - "jest-snapshot": "^27.3.0", - "jest-util": "^27.3.0", - "jest-validate": "^27.3.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.3", + "jest-snapshot": "^28.1.3", + "jest-util": "^28.1.3", "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^16.2.0" - } - }, - "jest-serializer": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.0.6.tgz", - "integrity": "sha512-PtGdVK9EGC7dsaziskfqaAPib6wTViY3G8E5wz9tLVPhHyiDNTZn/xjZ4khAw+09QkoOVpn7vF5nPSN6dtBexA==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.4" + "strip-bom": "^4.0.0" + }, + "dependencies": { + "@jest/environment": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", + "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/node": "*", + "jest-mock": "^28.1.3" + } + }, + "@jest/fake-timers": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", + "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@sinonjs/fake-timers": "^9.1.2", + "@types/node": "*", + "jest-message-util": "^28.1.3", + "jest-mock": "^28.1.3", + "jest-util": "^28.1.3" + } + }, + "jest-mock": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", + "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.3", + "@types/node": "*" + } + } } }, "jest-snapshot": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.3.0.tgz", - "integrity": "sha512-JaFXNS6D1BxvU2ORKaQwpen3Qic7IJAtGb09lbYiYk/GXXlde67Ts990i2nC5oBs0CstbeQE3jTeRayIZpM1Pw==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", + "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", "dev": true, "requires": { - "@babel/core": "^7.7.2", + "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", - "@babel/parser": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.3.0", - "@jest/types": "^27.2.5", - "@types/babel__traverse": "^7.0.4", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.3", + "@jest/transform": "^28.1.3", + "@jest/types": "^28.1.3", + "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^27.3.0", - "graceful-fs": "^4.2.4", - "jest-diff": "^27.3.0", - "jest-get-type": "^27.0.6", - "jest-haste-map": "^27.3.0", - "jest-matcher-utils": "^27.3.0", - "jest-message-util": "^27.3.0", - "jest-resolve": "^27.3.0", - "jest-util": "^27.3.0", + "expect": "^28.1.3", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.3", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3", "natural-compare": "^1.4.0", - "pretty-format": "^27.3.0", - "semver": "^7.3.2" + "pretty-format": "^28.1.3", + "semver": "^7.3.5" }, "dependencies": { + "@jest/expect-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", + "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2" + } + }, + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "diff-sequences": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.0.6.tgz", - "integrity": "sha512-ag6wfpBFyNXZ0p8pcuIDS//D8H062ZQJ3fzYxjpmeKjnz8W4pekL3AI8VohmyZmsWW2PWaHgjsmqR6L13101VQ==", + "version": "28.1.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", + "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", "dev": true }, + "expect": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", + "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.3", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.3", + "jest-message-util": "^28.1.3", + "jest-util": "^28.1.3" + } + }, "jest-diff": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.3.0.tgz", - "integrity": "sha512-Nl2rE58B2ye+RvPcU4hN+6wBCHxX7aWz6RMTMFxe9jAg8ZueMj5QQ+T/nmHRutbBc5BEjrbbEWOrRzp9rUEsYA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", + "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^27.0.6", - "jest-get-type": "^27.0.6", - "pretty-format": "^27.3.0" + "diff-sequences": "^28.1.1", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" } }, "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-matcher-utils": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", + "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.3", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.3" + } + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } }, "jest-util": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.3.0.tgz", - "integrity": "sha512-SFSDBGKkxXi4jClmU1WLp/cMMlb4YX6+5Lb0CUySxmonArio8yJ2NALMWvQuXchgySiH7Rb912hVZ2QZ6t3x7w==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", + "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "@types/node": "*", "chalk": "^4.0.0", - "graceful-fs": "^4.2.4", - "is-ci": "^3.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "jest-validate": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.3.0.tgz", - "integrity": "sha512-5oqWnb9MrkicE+ywR+BxoZr0L7H3WBDAt6LZggnyFHieAk8nnIQAKRpSodNPhiNJTwaMSbNjCe7SxAzKwTsBoA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", + "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", "dev": true, "requires": { - "@jest/types": "^27.2.5", + "@jest/types": "^28.1.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^27.0.6", + "jest-get-type": "^28.0.2", "leven": "^3.1.0", - "pretty-format": "^27.3.0" + "pretty-format": "^28.1.3" }, "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + }, "camelcase": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, "jest-get-type": { - "version": "27.0.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.6.tgz", - "integrity": "sha512-XTkK5exIeUbbveehcSR8w0bhH+c0yloW/Wpl+9vZrjzztCPWrxhHwkIFpZzCt71oRBsgxmuUfxEqOYoZI2macg==", + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "pretty-format": { + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", + "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.1.3", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + } + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true } } }, "jest-watcher": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.3.0.tgz", - "integrity": "sha512-xpTFRhqzUnNwTGaSBoHcyXROGbAfj2u4LS7Xosb+hzgrFgWgiHtCy3PWyN1DQk31Na98bBjXKxAbfSBACrvEiQ==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", + "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", "dev": true, "requires": { - "@jest/test-result": "^27.3.0", - "@jest/types": "^27.2.5", + "@jest/test-result": "^28.1.3", + "@jest/types": "^28.1.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^27.3.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.3", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "27.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.3.0.tgz", - "integrity": "sha512-xTTvvJqOjKBqE1AmwDHiQN8qzp9VoT981LtfXA+XiJVxHn4435vpnrzVcJ6v/ESiuB+IXPjZakn/ppT00xBCWA==", + "version": "28.1.3", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", + "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", "dev": true, "requires": { "@types/node": "*", @@ -9826,56 +12063,12 @@ "dev": true }, "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - } + "argparse": "^2.0.1" } }, "jsesc": { @@ -9884,6 +12077,12 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -9893,22 +12092,19 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "requires": { "graceful-fs": "^4.1.6" @@ -9936,26 +12132,25 @@ "type-check": "~0.4.0" } }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "p-locate": "^5.0.0" } }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true }, "lodash.merge": { @@ -9974,11 +12169,10 @@ } }, "lua-types": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz", - "integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w==", - "dev": true, - "requires": {} + "version": "2.12.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.1.tgz", + "integrity": "sha512-yWZmHe1nvaLy8tt13uDFZeOE6X80piCY48Y8KkHBSFXeclWk1hSOcMIuiEIskUbc+AQkac8FbPVfZMFm1AJceQ==", + "dev": true }, "lua-wasm-bindings": { "version": "0.2.2", @@ -10010,12 +12204,12 @@ "dev": true }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "merge-stream": { @@ -10031,28 +12225,13 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", - "dev": true, - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" - } - }, - "mime-db": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.50.0.tgz", - "integrity": "sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==", - "dev": true - }, - "mime-types": { - "version": "2.1.33", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.33.tgz", - "integrity": "sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "mime-db": "1.50.0" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "mimic-fn": { @@ -10085,25 +12264,19 @@ "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, "node-releases": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.0.tgz", - "integrity": "sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", + "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", "dev": true }, "normalize-path": { @@ -10121,16 +12294,10 @@ "path-key": "^3.0.0" } }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, "object-inspect": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.11.0.tgz", - "integrity": "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -10140,14 +12307,14 @@ "dev": true }, "object.assign": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", - "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3", - "has-symbols": "^1.0.1", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, @@ -10165,7 +12332,7 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" @@ -10195,27 +12362,27 @@ } }, "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^1.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "requires": { - "p-limit": "^1.1.0" + "p-limit": "^3.0.2" } }, "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parent-module": { @@ -10227,22 +12394,28 @@ "callsites": "^3.0.0" } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } }, "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-key": { @@ -10269,18 +12442,63 @@ "dev": true }, "picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "requires": { - "node-modules-regexp": "^1.0.0" + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } } }, "prelude-ls": { @@ -10290,9 +12508,9 @@ "dev": true }, "prettier": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.4.1.tgz", - "integrity": "sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", + "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", "dev": true }, "pretty-format": { @@ -10324,12 +12542,6 @@ "sisteransi": "^1.0.5" } }, - "psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -10348,6 +12560,17 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -10357,15 +12580,15 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "resolve": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", - "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "requires": { - "is-core-module": "^2.8.1", + "is-core-module": "^2.9.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -10429,21 +12652,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, "semver": { "version": "7.3.7", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", @@ -10480,9 +12688,9 @@ } }, "signal-exit": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.5.tgz", - "integrity": "sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==", + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true }, "sisteransi": { @@ -10498,14 +12706,14 @@ "dev": true }, "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" }, "source-map-support": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.20.tgz", - "integrity": "sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==", + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -10523,7 +12731,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "stack-utils": { @@ -10565,23 +12773,25 @@ } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { @@ -10635,12 +12845,6 @@ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true - }, "tapable": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", @@ -10670,13 +12874,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "tmpl": { @@ -10688,7 +12886,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, "to-regex-range": { @@ -10700,49 +12898,29 @@ "is-number": "^7.0.0" } }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, "ts-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.3.tgz", - "integrity": "sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==", + "version": "28.0.8", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", + "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", "dev": true, "requires": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", + "jest-util": "^28.0.0", + "json5": "^2.2.1", "lodash.memoize": "4.x", "make-error": "1.x", "semver": "7.x", - "yargs-parser": "20.x" + "yargs-parser": "^21.0.1" } }, "ts-node": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.3.0.tgz", - "integrity": "sha512-RYIy3i8IgpFH45AX4fQHExrT8BxDeKTdC83QFJkNzkvt8uFB6QJ8XMyhynYiKMLxt9a7yuXaDBZNOYS3XjDcYw==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, "requires": { - "@cspotcode/source-map-support": "0.7.0", + "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", "@tsconfig/node12": "^1.0.7", "@tsconfig/node14": "^1.0.0", @@ -10753,21 +12931,8 @@ "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", "yn": "3.1.1" - }, - "dependencies": { - "acorn": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz", - "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - } } }, "tsconfig-paths": { @@ -10794,7 +12959,7 @@ "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true } } @@ -10835,42 +13000,21 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, "typescript": { - "version": "4.7.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", + "version": "4.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", + "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", "dev": true }, - "typescript-to-lua": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.6.3.tgz", - "integrity": "sha512-yfXxGjOwX6453wSgEB37lLdxZZ8m+LH1g3PfebNfKaZHGGtbm9owxE6oRKB3sWcy2CICkfobAjWf3VdhKnEETg==", - "dev": true, - "peer": true, - "requires": { - "enhanced-resolve": "^5.8.2", - "resolve": "^1.15.1", - "source-map": "^0.7.3" - } - }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, @@ -10880,6 +13024,16 @@ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true }, + "update-browserslist-db": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", + "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, "uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -10889,80 +13043,30 @@ "punycode": "^2.1.0" } }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, "v8-to-istanbul": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.0.tgz", - "integrity": "sha512-/PRhfd8aTNp9Ggr62HPzXg2XasNFGy5PBt0Rp04du7/8GNNSgxFL6WBTkgMKSL9bFjH+8kKEG3f37FmxiTqUUA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", "dev": true, "requires": { + "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" + "convert-source-map": "^1.6.0" } }, "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "dev": true, - "requires": { - "makeerror": "1.0.x" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" + "makeerror": "1.0.12" } }, "which": { @@ -11007,40 +13111,19 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "requires": { "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.7" } }, - "ws": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.5.tgz", - "integrity": "sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==", - "dev": true, - "requires": {} - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -11054,24 +13137,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", "dev": true, "requires": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.0.0" } }, "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true }, "yn": { @@ -11079,6 +13162,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 0a6cbbc48..736258059 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint . --ext .js,.ts", "fix:prettier": "prettier --write .", - "check:language-extensions": "tsc language-extensions/index.d.ts", + "check:language-extensions": "tsc --strict language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, @@ -40,10 +40,10 @@ "tstl": "dist/tstl.js" }, "engines": { - "node": ">=12.13.0" + "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.7.3" + "typescript": "~4.8.2" }, "dependencies": { "enhanced-resolve": "^5.8.2", @@ -56,20 +56,20 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.27.0", - "@typescript-eslint/parser": "^5.27.0", - "eslint": "^8.17.0", + "@typescript-eslint/eslint-plugin": "^5.35.1", + "@typescript-eslint/parser": "^5.35.1", + "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.4.6", + "eslint-plugin-jest": "^26.8.7", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^27.3.0", - "jest-circus": "^27.3.0", - "lua-types": "^2.11.0", + "jest": "^28.1.3", + "jest-circus": "^29.0.1", + "lua-types": "^2.12.1", "lua-wasm-bindings": "^0.2.2", "prettier": "^2.3.2", - "ts-jest": "^27.1.3", - "ts-node": "^10.3.0", - "typescript": "~4.7.3" + "ts-jest": "^28.0.8", + "ts-node": "^10.9.1", + "typescript": "~4.8.2" } } diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index cac697064..dca15e00b 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -91,7 +91,7 @@ export function isExpressionWithEvaluationEffect(node: ts.Expression): boolean { export function getFunctionTypeForCall(context: TransformationContext, node: ts.CallExpression) { const signature = context.checker.getResolvedSignature(node); - if (!signature || !signature.declaration) { + if (!signature?.declaration) { return; } const typeDeclaration = findFirstNodeAbove(signature.declaration, ts.isTypeAliasDeclaration); @@ -110,7 +110,7 @@ export function isConstIdentifier(context: TransformationContext, node: ts.Node) return false; } const symbol = context.checker.getSymbolAtLocation(identifier); - if (!symbol || !symbol.declarations) { + if (!symbol?.declarations) { return false; } return symbol.declarations.some( diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 3aee65a36..f2662132c 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -187,11 +187,11 @@ function transformClassLikeDeclaration( result.push(...decorationStatements); // Decorate the class - if (classDeclaration.decorators) { + if (ts.canHaveDecorators(classDeclaration) && ts.getDecorators(classDeclaration)) { const decoratingExpression = createDecoratingExpression( context, classDeclaration.kind, - classDeclaration.decorators.map(d => transformDecoratorExpression(context, d)), + ts.getDecorators(classDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? [], localClassName ); const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 49edacdb3..27075bf6e 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -12,13 +12,15 @@ export function createPropertyDecoratingExpression( node: ts.PropertyDeclaration | ts.AccessorDeclaration, className: lua.Identifier ): lua.Expression | undefined { - if (!node.decorators) return; + if (!ts.canHaveDecorators(node)) return; + const decorators = ts.getDecorators(node); + if (!decorators) return; const propertyName = transformPropertyName(context, node.name); const propertyOwnerTable = transformMemberExpressionOwnerName(node, className); return createDecoratingExpression( context, node.kind, - node.decorators.map(d => transformDecoratorExpression(context, d)), + decorators.map(d => transformDecoratorExpression(context, d)), propertyOwnerTable, propertyName ); diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index c902ea8de..840aa9ca3 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -53,19 +53,21 @@ export function createMethodDecoratingExpression( const parameterDecorators = node.parameters .flatMap((parameter, index) => - parameter.decorators?.map(decorator => - transformLuaLibFunction( - context, - LuaLibFeature.DecorateParam, - node, - lua.createNumericLiteral(index), - transformDecoratorExpression(context, decorator) + ts + .getDecorators(parameter) + ?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) ) - ) ) .filter(isNonNull); - const methodDecorators = node.decorators?.map(d => transformDecoratorExpression(context, d)) ?? []; + const methodDecorators = ts.getDecorators(node)?.map(d => transformDecoratorExpression(context, d)) ?? []; if (methodDecorators.length > 0 || parameterDecorators.length > 0) { const decorateMethod = createDecoratingExpression( diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 219e99eee..025ac4465 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -136,12 +136,7 @@ function transformExportSpecifiersFrom( ) ); - const importDeclaration = ts.factory.createImportDeclaration( - statement.decorators, - statement.modifiers, - importClause, - moduleSpecifier - ); + const importDeclaration = ts.factory.createImportDeclaration(statement.modifiers, importClause, moduleSpecifier); // Wrap in block to prevent imports from hoisting out of `do` statement const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); diff --git a/src/utils.ts b/src/utils.ts index 72e6ee168..7e6cdf879 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,7 +5,7 @@ import * as path from "path"; export function castArray(value: T | T[]): T[]; export function castArray(value: T | readonly T[]): readonly T[]; export function castArray(value: T | readonly T[]): readonly T[] { - return Array.isArray(value) ? value : [value]; + return Array.isArray(value) ? value : [value as T]; } export const intersperse = (values: readonly T[], separator: T): T[] => From 7497dbf8caf071dfc6bec1a9eecd6e5a154eda38 Mon Sep 17 00:00:00 2001 From: Ryan Young Date: Sat, 3 Sep 2022 04:23:24 -0700 Subject: [PATCH 533/764] Lua 5.0 support (#1263) * feat: add flag for lua 5.0 target * feat(5.0): implement spread arguments * fix(5.0): in general, cases that apply to 5.1 should also apply to 5.0 * style: run prettier * test(5.0): share the expected results of the obvious cases with 5.1 * feat(5.0): work around the missing '#' and '%' operators * fix: log the correct lua version for unsupported features * style: condense spread table if branch * test: add a special case for modulo for 5.0 * style: fix indentation for test function snippet * feat(5.0): implement spread element correctly * fix: report correct lua version in bitops diagnostic message * test: refactor spread tests to accomodate 5.0 * Revert "test: add a special case for modulo for 5.0" This reverts commit fac16d27576b541b3f5d3b248999b995e373b8fa. * test: test basic numeric expressions against all versions * style: run prettier * refactor: use the convenience function to make an unpack call * style(lualib): use @noselfinfile for the modulo polyfill * fix: make bundling compatible with lua 5.0 * fix(5.0): optimized single element array push for 5.0 * fix(5.0): fix constructor w/ instance fields for 5.0 * fix(lualib): count varargs correctly with lua 5.0 * fix(lualib): tracebacks don't support threads with lua 5.0 * fix(lualib): work around missing math.modf() in lua 5.0 * fix(lualib): work around missing string.match() in lua 5.0 * fix(lualib): detect lua 5.0 minor versions correctly * refactor(lualib): lua 5.0 check can be a constant instead of a function * fix(5.0): get json test library to load * style: rename 5.0 json file * style: use a better definition of infinity * feat(5.0): don't transform infinity to math.huge, which doesn't exist in 5.0 * chore: bump lua-types version * feat: build another copy of lualib for 5.0 * style: run prettier * fix: small issues discovered in testing * chore: bump lua-wasm-bindings version * fix(lualib): select() call was not using vararg optimization, breaking some spead cases * test: use inline lualib imports to get around problems with preloading the entire bundle * test: remove old snapshots * fix: json files can't contain comments * Revert "fix: json files can't contain comments" This reverts commit 581fb52f3a0b9ecb98a4a2444af9730df45fc2e2. Turns out they CAN contain comments, when they're named tsconfig.json! * test: exclude lualib-lua50 from coverage * style: move 5.0 tsconfig.json to existing lualib dir * style: refactor lualib resolution into common function * style: factor out table length transpilation into common function * style: format 5.0 and non-5.0 require shims * test: remove obsolete lua 5.0 arg test * refactor(lualib): use builtins for the 5.0 branches instead of a version check * refactor(lualib): move 5.0-specific to its own directory * chore: add tsconfig to eslint * refactor(lualib): reorganize dist/lualib directories to better support future targets * fix(lualib): cache should account for multiple possible versions * Revert "test: use inline lualib imports to get around problems with preloading the entire bundle" This reverts commit 8d9ce98446cde7dc38e8fa3b988968c4dfb83bd8. * chore: adjust jest and npm configs for new lualib structure * refactor: cache lualib by file path so the universal target isn't cached several times * chore: bump lua-types * refactor: deduplicate require boilerplate * refactor: simplify universal definition of TS_Match * style: rename TS_Modulo -> TS_Modulo50 * refactor(lualib): use unpack helper to avoid code duplication in Generator.ts * refactor(lualib): eliminate duplication in SourceMapTraceBack.ts * chore(lualib): fix comment in CountVarargs.ts * refactor(lualib): eliminate duplication in Error.ts * fix(lualib): modules info should be cached per-target * refactor(lualib): eliminate duplication in NumbertToString.ts * refactor(lualib): modules info can also be cached by file path to avoid duplication * style: for locating lualib features, it makes more sense to default to the universal target * style: delete unnecessary noselfinfile * chore: add 5.0 target to tsconfig schema --- .eslintrc.js | 1 + package-lock.json | 52 ++- package.json | 8 +- src/CompilerOptions.ts | 1 + src/LuaAST.ts | 16 +- src/LuaLib.ts | 59 ++-- src/LuaPrinter.ts | 15 +- src/lualib-build/plugin.ts | 13 +- src/lualib/5.0/CountVarargs.ts | 7 + src/lualib/5.0/Match.ts | 12 + src/lualib/5.0/MathModf.ts | 6 + src/lualib/5.0/SparseArraySpread.ts | 5 + src/lualib/5.0/Unpack.ts | 1 + src/lualib/ArrayReduce.ts | 4 +- src/lualib/ArrayReduceRight.ts | 4 +- src/lualib/ArraySplice.ts | 4 +- src/lualib/Error.ts | 11 +- src/lualib/Generator.ts | 6 +- src/lualib/Modulo50.ts | 5 + src/lualib/NumberToString.ts | 4 +- src/lualib/ParseFloat.ts | 6 +- src/lualib/ParseInt.ts | 8 +- src/lualib/SourceMapTraceBack.ts | 7 +- src/lualib/SparseArrayNew.ts | 4 +- src/lualib/SparseArrayPush.ts | 3 +- src/lualib/tsconfig.json | 5 +- src/lualib/tsconfig.lua50.json | 20 ++ src/lualib/universal/CountVarargs.ts | 6 + src/lualib/universal/Match.ts | 1 + src/lualib/universal/MathModf.ts | 1 + .../{ => universal}/SparseArraySpread.ts | 0 src/lualib/{ => universal}/Unpack.ts | 0 src/transformation/builtins/array.ts | 19 +- src/transformation/builtins/function.ts | 8 +- src/transformation/builtins/index.ts | 13 +- src/transformation/builtins/string.ts | 13 +- src/transformation/utils/diagnostics.ts | 6 +- src/transformation/utils/lua-ast.ts | 4 +- .../visitors/binary-expression/bit.ts | 6 +- .../visitors/binary-expression/index.ts | 5 + src/transformation/visitors/break-continue.ts | 8 +- src/transformation/visitors/class/index.ts | 9 +- src/transformation/visitors/errors.ts | 10 +- src/transformation/visitors/function.ts | 4 +- .../visitors/language-extensions/operators.ts | 1 + src/transformation/visitors/literal.ts | 15 +- src/transformation/visitors/spread.ts | 5 +- src/transpilation/bundle.ts | 17 +- src/transpilation/transpiler.ts | 5 +- test/cli/parse.spec.ts | 1 + test/json.50.lua | 147 ++++++++ test/transpile/lualib.spec.ts | 4 +- .../__snapshots__/expressions.spec.ts.snap | 110 ++++++ test/unit/__snapshots__/loops.spec.ts.snap | 69 +++- test/unit/__snapshots__/spread.spec.ts.snap | 168 --------- test/unit/builtins/async-await.spec.ts | 6 + test/unit/builtins/math.spec.ts | 1 + test/unit/expressions.spec.ts | 18 +- .../__snapshots__/functions.spec.ts.snap | 16 +- test/unit/functions/functions.spec.ts | 19 +- test/unit/functions/generators.spec.ts | 1 + .../__snapshots__/operators.spec.ts.snap | 28 ++ .../language-extensions/operators.spec.ts | 2 +- test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 319 +++++++++--------- test/util.ts | 45 ++- tsconfig-schema.json | 2 +- 67 files changed, 943 insertions(+), 457 deletions(-) create mode 100644 src/lualib/5.0/CountVarargs.ts create mode 100644 src/lualib/5.0/Match.ts create mode 100644 src/lualib/5.0/MathModf.ts create mode 100644 src/lualib/5.0/SparseArraySpread.ts create mode 100644 src/lualib/5.0/Unpack.ts create mode 100644 src/lualib/Modulo50.ts create mode 100644 src/lualib/tsconfig.lua50.json create mode 100644 src/lualib/universal/CountVarargs.ts create mode 100644 src/lualib/universal/Match.ts create mode 100644 src/lualib/universal/MathModf.ts rename src/lualib/{ => universal}/SparseArraySpread.ts (100%) rename src/lualib/{ => universal}/Unpack.ts (100%) create mode 100644 test/json.50.lua diff --git a/.eslintrc.js b/.eslintrc.js index 5b8fe5f4a..632294177 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,7 @@ module.exports = { project: [ "test/tsconfig.json", "src/lualib/tsconfig.json", + "src/lualib/tsconfig.lua50.json", "benchmark/tsconfig.json", "language-extensions/tsconfig.json", ], diff --git a/package-lock.json b/package-lock.json index dd7f2d749..c2633715a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,8 +31,8 @@ "javascript-stringify": "^2.0.1", "jest": "^28.1.3", "jest-circus": "^29.0.1", - "lua-types": "^2.12.1", - "lua-wasm-bindings": "^0.2.2", + "lua-types": "^2.12.2", + "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", @@ -1985,6 +1985,12 @@ "@types/node": "*" } }, + "node_modules/@types/semver": { + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "dev": true + }, "node_modules/@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -6092,19 +6098,23 @@ } }, "node_modules/lua-types": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.1.tgz", - "integrity": "sha512-yWZmHe1nvaLy8tt13uDFZeOE6X80piCY48Y8KkHBSFXeclWk1hSOcMIuiEIskUbc+AQkac8FbPVfZMFm1AJceQ==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.2.tgz", + "integrity": "sha512-E9TfcaJ01YW6XrnXhdw9dvO495wkuXRfFJsWNfj/ZTvWrbloWQ0eNnGUkQ8OW/jaJCczJXuT9tW7wdtqL0sc+A==", "dev": true, "peerDependencies": { "typescript-to-lua": "^1.0.0" } }, "node_modules/lua-wasm-bindings": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", - "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", - "dev": true + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", + "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", + "dev": true, + "dependencies": { + "@types/semver": "^7.3.9", + "semver": "^7.3.7" + } }, "node_modules/make-dir": { "version": "3.1.0", @@ -9082,6 +9092,12 @@ "@types/node": "*" } }, + "@types/semver": { + "version": "7.3.12", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", + "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "dev": true + }, "@types/stack-utils": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", @@ -12169,16 +12185,20 @@ } }, "lua-types": { - "version": "2.12.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.1.tgz", - "integrity": "sha512-yWZmHe1nvaLy8tt13uDFZeOE6X80piCY48Y8KkHBSFXeclWk1hSOcMIuiEIskUbc+AQkac8FbPVfZMFm1AJceQ==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.2.tgz", + "integrity": "sha512-E9TfcaJ01YW6XrnXhdw9dvO495wkuXRfFJsWNfj/ZTvWrbloWQ0eNnGUkQ8OW/jaJCczJXuT9tW7wdtqL0sc+A==", "dev": true }, "lua-wasm-bindings": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.2.2.tgz", - "integrity": "sha512-Z2v3An8jEvYbhUJ/gYxNd65ZBbaRyPMmUaleDoOhzJSIGrMgjURvy1EtHtgRGTzdtpmKtHA+YYKDrSZBE9g/ig==", - "dev": true + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", + "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", + "dev": true, + "requires": { + "@types/semver": "^7.3.9", + "semver": "^7.3.7" + } }, "make-dir": { "version": "3.1.0", diff --git a/package.json b/package.json index 736258059..e3e3df7c5 100644 --- a/package.json +++ b/package.json @@ -18,14 +18,14 @@ "dist/**/*.js", "dist/**/*.lua", "dist/**/*.ts", - "dist/lualib/*.json", + "dist/lualib/**/*.json", "language-extensions/**/*.ts" ], "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { "build": "tsc && npm run build-lualib", - "build-lualib": "node dist/tstl.js -p src/lualib/tsconfig.json", + "build-lualib": "node dist/tstl.js -p src/lualib/tsconfig.json && node dist/tstl.js -p src/lualib/tsconfig.lua50.json", "pretest": "npm run lint && npm run check:language-extensions && npm run build-lualib", "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", @@ -65,8 +65,8 @@ "javascript-stringify": "^2.0.1", "jest": "^28.1.3", "jest-circus": "^29.0.1", - "lua-types": "^2.12.1", - "lua-wasm-bindings": "^0.2.2", + "lua-types": "^2.12.2", + "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index deee41b70..9acc3589d 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -53,6 +53,7 @@ export enum LuaLibImportKind { export enum LuaTarget { Universal = "universal", + Lua50 = "5.0", Lua51 = "5.1", Lua52 = "5.2", Lua53 = "5.3", diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 472831451..698534d9e 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -32,6 +32,7 @@ export enum SyntaxKind { NumericLiteral, NilKeyword, DotsKeyword, + ArgKeyword, TrueKeyword, FalseKeyword, FunctionExpression, @@ -544,6 +545,18 @@ export function createDotsLiteral(tsOriginal?: ts.Node): DotsLiteral { return createNode(SyntaxKind.DotsKeyword, tsOriginal) as DotsLiteral; } +export interface ArgLiteral extends Expression { + kind: SyntaxKind.ArgKeyword; +} + +export function isArgLiteral(node: Node): node is ArgLiteral { + return node.kind === SyntaxKind.ArgKeyword; +} + +export function createArgLiteral(tsOriginal?: ts.Node): ArgLiteral { + return createNode(SyntaxKind.ArgKeyword, tsOriginal) as ArgLiteral; +} + // StringLiteral / NumberLiteral // TODO TS uses the export interface "LiteralLikeNode" with a "text: string" member // but since we don't parse from text I think we can simplify by just having a value member @@ -581,10 +594,11 @@ export function createStringLiteral(value: string, tsOriginal?: ts.Node): String export function isLiteral( node: Node -): node is NilLiteral | DotsLiteral | BooleanLiteral | NumericLiteral | StringLiteral { +): node is NilLiteral | DotsLiteral | ArgLiteral | BooleanLiteral | NumericLiteral | StringLiteral { return ( isNilLiteral(node) || isDotsLiteral(node) || + isArgLiteral(node) || isBooleanLiteral(node) || isNumericLiteral(node) || isStringLiteral(node) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 7780a35eb..2ab5d33ba 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,6 +1,7 @@ import * as path from "path"; import { EmitHost } from "./transpilation"; import * as lua from "./LuaAST"; +import { LuaTarget } from "./CompilerOptions"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -34,6 +35,7 @@ export enum LuaLibFeature { Class = "Class", ClassExtends = "ClassExtends", CloneDescriptor = "CloneDescriptor", + CountVarargs = "CountVarargs", Decorate = "Decorate", DecorateParam = "DecorateParam", Delete = "Delete", @@ -46,8 +48,11 @@ export enum LuaLibFeature { Iterator = "Iterator", LuaIteratorSpread = "LuaIteratorSpread", Map = "Map", + Match = "Match", MathAtan2 = "MathAtan2", + MathModf = "MathModf", MathSign = "MathSign", + Modulo50 = "Modulo50", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", @@ -107,23 +112,28 @@ export interface LuaLibFeatureInfo { } export type LuaLibModulesInfo = Record; +export function resolveLuaLibDir(luaTarget: LuaTarget) { + const luaLibDir = luaTarget === LuaTarget.Lua50 ? "5.0" : "universal"; + return path.resolve(__dirname, path.join("..", "dist", "lualib", luaLibDir)); +} + export const luaLibModulesInfoFileName = "lualib_module_info.json"; -let luaLibModulesInfo: LuaLibModulesInfo | undefined; -export function getLuaLibModulesInfo(emitHost: EmitHost): LuaLibModulesInfo { - if (luaLibModulesInfo === undefined) { - const lualibPath = path.resolve(__dirname, `../dist/lualib/${luaLibModulesInfoFileName}`); +const luaLibModulesInfo = new Map(); +export function getLuaLibModulesInfo(luaTarget: LuaTarget, emitHost: EmitHost): LuaLibModulesInfo { + const lualibPath = path.join(resolveLuaLibDir(luaTarget), luaLibModulesInfoFileName); + if (!luaLibModulesInfo.has(lualibPath)) { const result = emitHost.readFile(lualibPath); if (result !== undefined) { - luaLibModulesInfo = JSON.parse(result) as LuaLibModulesInfo; + luaLibModulesInfo.set(lualibPath, JSON.parse(result) as LuaLibModulesInfo); } else { throw new Error(`Could not load lualib dependencies from '${lualibPath}'`); } } - return luaLibModulesInfo; + return luaLibModulesInfo.get(lualibPath) as LuaLibModulesInfo; } -export function readLuaLibFeature(feature: LuaLibFeature, emitHost: EmitHost): string { - const featurePath = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); +export function readLuaLibFeature(feature: LuaLibFeature, luaTarget: LuaTarget, emitHost: EmitHost): string { + const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`); const luaLibFeature = emitHost.readFile(featurePath); if (luaLibFeature === undefined) { throw new Error(`Could not load lualib feature from '${featurePath}'`); @@ -133,8 +143,9 @@ export function readLuaLibFeature(feature: LuaLibFeature, emitHost: EmitHost): s export function resolveRecursiveLualibFeatures( features: Iterable, + luaTarget: LuaTarget, emitHost: EmitHost, - luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModulesInfo(emitHost) + luaLibModulesInfo: LuaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost) ): LuaLibFeature[] { const loadedFeatures = new Set(); const result: LuaLibFeature[] = []; @@ -158,19 +169,27 @@ export function resolveRecursiveLualibFeatures( return result; } -export function loadInlineLualibFeatures(features: Iterable, emitHost: EmitHost): string { +export function loadInlineLualibFeatures( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): string { let result = ""; - for (const feature of resolveRecursiveLualibFeatures(features, emitHost)) { - const luaLibFeature = readLuaLibFeature(feature, emitHost); + for (const feature of resolveRecursiveLualibFeatures(features, luaTarget, emitHost)) { + const luaLibFeature = readLuaLibFeature(feature, luaTarget, emitHost); result += luaLibFeature + "\n"; } return result; } -export function loadImportedLualibFeatures(features: Iterable, emitHost: EmitHost): lua.Statement[] { - const luaLibModuleInfo = getLuaLibModulesInfo(emitHost); +export function loadImportedLualibFeatures( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): lua.Statement[] { + const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost); const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports); @@ -196,17 +215,17 @@ export function loadImportedLualibFeatures(features: Iterable, em return statements; } -let luaLibBundleContent: string; -export function getLuaLibBundle(emitHost: EmitHost): string { - if (luaLibBundleContent === undefined) { - const lualibPath = path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"); +const luaLibBundleContent = new Map(); +export function getLuaLibBundle(luaTarget: LuaTarget, emitHost: EmitHost): string { + const lualibPath = path.join(resolveLuaLibDir(luaTarget), "lualib_bundle.lua"); + if (!luaLibBundleContent.has(lualibPath)) { const result = emitHost.readFile(lualibPath); if (result !== undefined) { - luaLibBundleContent = result; + luaLibBundleContent.set(lualibPath, result); } else { throw new Error(`Could not load lualib bundle from '${lualibPath}'`); } } - return luaLibBundleContent; + return luaLibBundleContent.get(lualibPath) as string; } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 62fda173a..ab2d373da 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -1,7 +1,7 @@ import * as path from "path"; import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions, isBundleEnabled, LuaLibImportKind } from "./CompilerOptions"; +import { CompilerOptions, isBundleEnabled, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; import * as lua from "./LuaAST"; import { loadInlineLualibFeatures, LuaLibFeature, loadImportedLualibFeatures } from "./LuaLib"; import { isValidLuaIdentifier, shouldAllowUnicode } from "./transformation/utils/safe-names"; @@ -233,14 +233,17 @@ export class LuaPrinter { sourceChunks.push(tstlHeader); } + const luaTarget = this.options.luaTarget ?? LuaTarget.Universal; const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; if (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) { // Import lualib features - sourceChunks = this.printStatementArray(loadImportedLualibFeatures(file.luaLibFeatures, this.emitHost)); + sourceChunks = this.printStatementArray( + loadImportedLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost) + ); } else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) { // Inline lualib features sourceChunks.push("-- Lua Library inline imports\n"); - sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, this.emitHost)); + sourceChunks.push(loadInlineLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost)); sourceChunks.push("-- End of Lua Library inline imports\n"); } @@ -583,6 +586,8 @@ export class LuaPrinter { return this.printNilLiteral(expression as lua.NilLiteral); case lua.SyntaxKind.DotsKeyword: return this.printDotsLiteral(expression as lua.DotsLiteral); + case lua.SyntaxKind.ArgKeyword: + return this.printArgLiteral(expression as lua.ArgLiteral); case lua.SyntaxKind.TrueKeyword: case lua.SyntaxKind.FalseKeyword: return this.printBooleanLiteral(expression as lua.BooleanLiteral); @@ -625,6 +630,10 @@ export class LuaPrinter { return this.createSourceNode(expression, "..."); } + public printArgLiteral(expression: lua.ArgLiteral): SourceNode { + return this.createSourceNode(expression, "arg"); + } + public printBooleanLiteral(expression: lua.BooleanLiteral): SourceNode { return this.createSourceNode(expression, expression.kind === lua.SyntaxKind.TrueKeyword ? "true" : "false"); } diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index 76b7e5008..4d7722d12 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -42,12 +42,23 @@ class LuaLibPlugin implements tstl.Plugin { emitBOM ); + // Flatten the output folder structure; we do not want to keep the target-specific directories + for (const file of result) { + let outPath = file.fileName; + while (outPath.includes("lualib") && path.basename(path.dirname(outPath)) !== "lualib") { + const upOne = path.join(path.dirname(outPath), "..", path.basename(outPath)); + outPath = path.normalize(upOne); + } + file.fileName = outPath; + } + // Create map of result files keyed by their 'lualib name' const exportedLualibFeatures = new Map(result.map(f => [path.basename(f.fileName).split(".")[0], f.code])); // Figure out the order required in the bundle by recursively resolving all dependency features const allFeatures = Object.values(LuaLibFeature) as LuaLibFeature[]; - const orderedFeatures = resolveRecursiveLualibFeatures(allFeatures, emitHost, luaLibModuleInfo); + const luaTarget = options.luaTarget ?? tstl.LuaTarget.Universal; + const orderedFeatures = resolveRecursiveLualibFeatures(allFeatures, luaTarget, emitHost, luaLibModuleInfo); // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLibFeature[f])).join("\n"); diff --git a/src/lualib/5.0/CountVarargs.ts b/src/lualib/5.0/CountVarargs.ts new file mode 100644 index 000000000..34467ebd4 --- /dev/null +++ b/src/lualib/5.0/CountVarargs.ts @@ -0,0 +1,7 @@ +/** @noSelfInFile */ + +export function __TS__CountVarargs(...args: T[]): number { + // select() is not available in Lua 5.0. In this version, the arg table + // includes trailing nils. + return args.length; +} diff --git a/src/lualib/5.0/Match.ts b/src/lualib/5.0/Match.ts new file mode 100644 index 000000000..3b1705939 --- /dev/null +++ b/src/lualib/5.0/Match.ts @@ -0,0 +1,12 @@ +/** @noSelfInFile */ + +export function __TS__Match(s: string, pattern: string, init?: number): LuaMultiReturn { + const [start, end, ...captures] = string.find(s, pattern, init); + if (start === undefined || end === undefined) { + return $multi(); + } else if (captures.length <= 0) { + return $multi(s.slice(start - 1, end)); + } else { + return $multi(...(captures as string[])); + } +} diff --git a/src/lualib/5.0/MathModf.ts b/src/lualib/5.0/MathModf.ts new file mode 100644 index 000000000..ec816ebe0 --- /dev/null +++ b/src/lualib/5.0/MathModf.ts @@ -0,0 +1,6 @@ +/** @noSelfInFile */ + +export function __TS__MathModf(x: number): LuaMultiReturn<[number, number]> { + const integral = x > 0 ? Math.floor(x) : Math.ceil(x); + return $multi(integral, x - integral); +} diff --git a/src/lualib/5.0/SparseArraySpread.ts b/src/lualib/5.0/SparseArraySpread.ts new file mode 100644 index 000000000..e404bac47 --- /dev/null +++ b/src/lualib/5.0/SparseArraySpread.ts @@ -0,0 +1,5 @@ +import { __TS__SparseArray } from "./SparseArray"; + +export function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { + return unpack(sparseArray, 1, sparseArray.sparseLength); +} diff --git a/src/lualib/5.0/Unpack.ts b/src/lualib/5.0/Unpack.ts new file mode 100644 index 000000000..6d1ef8edd --- /dev/null +++ b/src/lualib/5.0/Unpack.ts @@ -0,0 +1 @@ +export const __TS__Unpack = unpack; diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index eb26a9731..d21d97403 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -1,3 +1,5 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduce( this: TElement[], @@ -10,7 +12,7 @@ export function __TS__ArrayReduce( let accumulator: TAccumulator = undefined; // Check if initial value is present in function call - if (select("#", ...initial) !== 0) { + if (__TS__CountVarargs(...initial) !== 0) { [accumulator] = [...initial]; } else if (len > 0) { accumulator = this[0] as unknown as TAccumulator; diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index e32e87e79..13bfe17d9 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -1,3 +1,5 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.reduce export function __TS__ArrayReduceRight( this: TElement[], @@ -10,7 +12,7 @@ export function __TS__ArrayReduceRight( let accumulator: TAccumulator = undefined; // Check if initial value is present in function call - if (select("#", ...initial) !== 0) { + if (__TS__CountVarargs(...initial) !== 0) { [accumulator] = [...initial]; } else if (len > 0) { accumulator = this[k] as unknown as TAccumulator; diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index dc69e16fb..1d14cbda2 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -1,8 +1,10 @@ +import { __TS__CountVarargs } from "./CountVarargs"; + // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.splice export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { const len = this.length; - const actualArgumentCount = select("#", ...args); + const actualArgumentCount = __TS__CountVarargs(...args); let start = args[0] as number; const deleteCount = args[1] as number; diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index 2ebb2aaaa..ddad7d81f 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -17,14 +17,21 @@ function getErrorStack(constructor: () => any): string { } } - return debug.traceback(undefined, level); + if (_VERSION.includes("Lua 5.0")) { + return debug.traceback(`[Level ${level}]`); + } else { + // @ts-ignore Fails when compiled with Lua 5.0 types + return debug.traceback(undefined, level); + } } function wrapErrorToString(getDescription: (this: T) => string): (this: T) => string { return function (this: Error): string { const description = getDescription.call(this); const caller = debug.getinfo(3, "f"); - if (_VERSION === "Lua 5.1" || (caller && caller.func !== error)) { + // @ts-ignore Fails when compiled with Lua 5.0 types + const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1"; + if (isClassicLua || (caller && caller.func !== error)) { return description; } else { return `${description}\n${this.stack}`; diff --git a/src/lualib/Generator.ts b/src/lualib/Generator.ts index 0122602a2..c17aab8c7 100644 --- a/src/lualib/Generator.ts +++ b/src/lualib/Generator.ts @@ -1,4 +1,6 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { GeneratorIterator } from "./GeneratorIterator"; +import { __TS__Unpack } from "./Unpack"; function generatorIterator(this: GeneratorIterator) { return this; @@ -16,10 +18,10 @@ function generatorNext(this: GeneratorIterator, ...args: any[]) { export function __TS__Generator(this: void, fn: (this: void, ...args: any[]) => any) { return function (this: void, ...args: any[]): GeneratorIterator { - const argsLength = select("#", ...args); + const argsLength = __TS__CountVarargs(...args); return { // Using explicit this there, since we don't pass arguments after the first nil and context is likely to be nil - ____coroutine: coroutine.create(() => fn(...(unpack ?? table.unpack)(args, 1, argsLength))), + ____coroutine: coroutine.create(() => fn(...__TS__Unpack(args, 1, argsLength))), [Symbol.iterator]: generatorIterator, next: generatorNext, }; diff --git a/src/lualib/Modulo50.ts b/src/lualib/Modulo50.ts new file mode 100644 index 000000000..4b9729436 --- /dev/null +++ b/src/lualib/Modulo50.ts @@ -0,0 +1,5 @@ +/** @noSelfInFile */ + +export function __TS__Modulo50(a: number, b: number): number { + return a - Math.floor(a / b) * b; +} diff --git a/src/lualib/NumberToString.ts b/src/lualib/NumberToString.ts index 1e1a1ad03..6cdbaadc3 100644 --- a/src/lualib/NumberToString.ts +++ b/src/lualib/NumberToString.ts @@ -1,3 +1,5 @@ +import { __TS__MathModf } from "./MathModf"; + const radixChars = "0123456789abcdefghijklmnopqrstuvwxyz"; // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tostring @@ -11,7 +13,7 @@ export function __TS__NumberToString(this: number, radix?: number): string { throw "toString() radix argument must be between 2 and 36"; } - let [integer, fraction] = math.modf(Math.abs(this)); + let [integer, fraction] = __TS__MathModf(Math.abs(this)); let result = ""; if (radix === 8) { diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts index 94ca97429..e182370e2 100644 --- a/src/lualib/ParseFloat.ts +++ b/src/lualib/ParseFloat.ts @@ -1,11 +1,13 @@ +import { __TS__Match } from "./Match"; + export function __TS__ParseFloat(this: void, numberString: string): number { // Check if string is infinity - const [infinityMatch] = string.match(numberString, "^%s*(-?Infinity)"); + const [infinityMatch] = __TS__Match(numberString, "^%s*(-?Infinity)"); if (infinityMatch) { // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with return infinityMatch[0] === "-" ? -Infinity : Infinity; } - const number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")[0]); + const number = tonumber(__TS__Match(numberString, "^%s*(-?%d+%.?%d*)")[0]); return number ?? NaN; } diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index 208d84e44..2e1081a86 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -1,13 +1,15 @@ +import { __TS__Match } from "./Match"; + const parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ"; export function __TS__ParseInt(this: void, numberString: string, base?: number): number { // Check which base to use if none specified if (base === undefined) { base = 10; - const [hexMatch] = string.match(numberString, "^%s*-?0[xX]"); + const [hexMatch] = __TS__Match(numberString, "^%s*-?0[xX]"); if (hexMatch) { base = 16; - numberString = string.match(hexMatch, "-")[0] + numberString = __TS__Match(hexMatch, "-")[0] ? "-" + numberString.substr(hexMatch.length) : numberString.substr(hexMatch.length); } @@ -24,7 +26,7 @@ export function __TS__ParseInt(this: void, numberString: string, base?: number): const pattern = `^%s*(-?[${allowedDigits}]*)`; // Try to parse with Lua tonumber - const number = tonumber(string.match(numberString, pattern)[0], base); + const number = tonumber(__TS__Match(numberString, pattern)[0], base); if (number === undefined) { return NaN; diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index fe1714f1f..ba5908255 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -1,6 +1,8 @@ // TODO: In the future, change this to __TS__RegisterFileInfo and provide tstl interface to // get some metadata about transpilation. +import { __TS__Match } from "./Match"; + interface SourceMap { [line: number]: number | { line: number; file: string }; } @@ -18,7 +20,10 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap let trace: string; if (thread === undefined && message === undefined && level === undefined) { trace = originalTraceback(); + } else if (_VERSION.includes("Lua 5.0")) { + trace = originalTraceback(`[Level ${level}] ${message}`); } else { + // @ts-ignore Fails when compiled with Lua 5.0 types trace = originalTraceback(thread, message, level); } @@ -47,7 +52,7 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap const stringReplacer = (file: string, line: string) => { const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; if (fileSourceMap && fileSourceMap[line]) { - const chunkName = string.match(file, '%[string "([^"]+)"%]')[0]; + const chunkName = __TS__Match(file, '%[string "([^"]+)"%]')[0]; const [sourceName] = string.gsub(chunkName, ".lua$", ".ts"); const data = fileSourceMap[line]; if (typeof data === "number") { diff --git a/src/lualib/SparseArrayNew.ts b/src/lualib/SparseArrayNew.ts index 07bfae13e..c6877b9c2 100644 --- a/src/lualib/SparseArrayNew.ts +++ b/src/lualib/SparseArrayNew.ts @@ -1,9 +1,9 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { __TS__SparseArray } from "./SparseArray"; export function __TS__SparseArrayNew(this: void, ...args: T[]): __TS__SparseArray { const sparseArray = [...args] as __TS__SparseArray; - // select("#", ...) counts the number of args passed, including nils. // Note that we're depending on vararg optimization to occur here. - sparseArray.sparseLength = select("#", ...args); + sparseArray.sparseLength = __TS__CountVarargs(...args); return sparseArray; } diff --git a/src/lualib/SparseArrayPush.ts b/src/lualib/SparseArrayPush.ts index 8a089a192..253d6e223 100644 --- a/src/lualib/SparseArrayPush.ts +++ b/src/lualib/SparseArrayPush.ts @@ -1,7 +1,8 @@ +import { __TS__CountVarargs } from "./CountVarargs"; import { __TS__SparseArray } from "./SparseArray"; export function __TS__SparseArrayPush(this: void, sparseArray: __TS__SparseArray, ...args: T[]): void { - const argsLen = select("#", ...args); + const argsLen = __TS__CountVarargs(...args); const listLen = sparseArray.sparseLength; for (const i of $range(1, argsLen)) { sparseArray[listLen + i - 1] = args[i - 1]; diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index 246e46b90..de9c1fa7f 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -1,10 +1,11 @@ { "compilerOptions": { - "outDir": "../../dist/lualib", + "outDir": "../../dist/lualib/universal", "target": "esnext", "lib": ["esnext"], "types": ["lua-types/5.4"], "skipLibCheck": true, + "rootDirs": [".", "universal"], "noUnusedLocals": true, "noUnusedParameters": true @@ -14,5 +15,5 @@ "noHeader": true, "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] }, - "include": [".", "../../language-extensions/index.d.ts"] + "include": ["*.ts", "universal/*.ts", "declarations", "../../language-extensions/index.d.ts"] } diff --git a/src/lualib/tsconfig.lua50.json b/src/lualib/tsconfig.lua50.json new file mode 100644 index 000000000..ecf9409e1 --- /dev/null +++ b/src/lualib/tsconfig.lua50.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "outDir": "../../dist/lualib/5.0", + "target": "esnext", + "lib": ["esnext"], + "types": ["lua-types/5.0"], + "skipLibCheck": true, + "rootDirs": [".", "5.0"], + + "noUnusedLocals": true, + "noUnusedParameters": true + }, + "tstl": { + "luaLibImport": "none", + "noHeader": true, + "luaTarget": "5.0", + "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] + }, + "include": ["*.ts", "5.0/*.ts", "declarations", "../../language-extensions/index.d.ts"] +} diff --git a/src/lualib/universal/CountVarargs.ts b/src/lualib/universal/CountVarargs.ts new file mode 100644 index 000000000..dc6107bb5 --- /dev/null +++ b/src/lualib/universal/CountVarargs.ts @@ -0,0 +1,6 @@ +/** @noSelfInFile */ + +export function __TS__CountVarargs(...args: T[]): number { + // Note that we need vararg optimization for this call. + return select("#", ...args); +} diff --git a/src/lualib/universal/Match.ts b/src/lualib/universal/Match.ts new file mode 100644 index 000000000..de9420b59 --- /dev/null +++ b/src/lualib/universal/Match.ts @@ -0,0 +1 @@ +export const __TS__Match = string.match; diff --git a/src/lualib/universal/MathModf.ts b/src/lualib/universal/MathModf.ts new file mode 100644 index 000000000..139ae8f6a --- /dev/null +++ b/src/lualib/universal/MathModf.ts @@ -0,0 +1 @@ +export const __TS__MathModf = math.modf; diff --git a/src/lualib/SparseArraySpread.ts b/src/lualib/universal/SparseArraySpread.ts similarity index 100% rename from src/lualib/SparseArraySpread.ts rename to src/lualib/universal/SparseArraySpread.ts diff --git a/src/lualib/Unpack.ts b/src/lualib/universal/Unpack.ts similarity index 100% rename from src/lualib/Unpack.ts rename to src/lualib/universal/Unpack.ts diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 9eeca1a1c..c9074874f 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; @@ -29,6 +30,18 @@ export function transformArrayConstructorCall( } } +function createTableLengthExpression(context: TransformationContext, expression: lua.Expression, node?: ts.Expression) { + if (context.luaTarget === LuaTarget.Lua50) { + const tableGetn = lua.createTableIndexExpression( + lua.createIdentifier("table"), + lua.createStringLiteral("getn") + ); + return lua.createCallExpression(tableGetn, [expression], node); + } else { + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + } +} + /** * Optimized single element Array.push * @@ -47,7 +60,7 @@ function transformSingleElementArrayPush( // #array + 1 let lengthExpression: lua.Expression = lua.createBinaryExpression( - lua.createUnaryExpression(arrayIdentifier, lua.SyntaxKind.LengthOperator), + createTableLengthExpression(context, arrayIdentifier), lua.createNumericLiteral(1), lua.SyntaxKind.AdditionOperator ); @@ -180,11 +193,11 @@ export function transformArrayPrototypeCall( export function transformArrayProperty( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.UnaryExpression | undefined { +): lua.Expression | undefined { switch (node.name.text) { case "length": const expression = context.transformExpression(node.expression); - return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + return createTableLengthExpression(context, expression, node); default: return undefined; } diff --git a/src/transformation/builtins/function.ts b/src/transformation/builtins/function.ts index f2ee043c9..8b219b6ba 100644 --- a/src/transformation/builtins/function.ts +++ b/src/transformation/builtins/function.ts @@ -40,8 +40,12 @@ export function transformFunctionProperty( ): lua.Expression | undefined { switch (node.name.text) { case "length": - if (context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Universal) { - context.diagnostics.push(unsupportedForTarget(node, "function.length", LuaTarget.Lua51)); + if ( + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Universal + ) { + context.diagnostics.push(unsupportedForTarget(node, "function.length", context.luaTarget)); } // debug.getinfo(fn) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 711015b5f..64f0d4228 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -17,6 +17,7 @@ import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; +import { LuaTarget } from "../../CompilerOptions"; export function transformBuiltinPropertyAccessExpression( context: TransformationContext, @@ -152,9 +153,15 @@ export function transformBuiltinIdentifierExpression( return createNaN(node); case "Infinity": - const math = lua.createIdentifier("math"); - const huge = lua.createStringLiteral("huge"); - return lua.createTableIndexExpression(math, huge, node); + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, node); + } case "globalThis": return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node, symbol), "globalThis"); diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index 711f59230..a48f36ee5 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; @@ -177,11 +178,19 @@ export function transformStringConstructorCall( export function transformStringProperty( context: TransformationContext, node: ts.PropertyAccessExpression -): lua.UnaryExpression | undefined { +): lua.Expression | undefined { switch (node.name.text) { case "length": const expression = context.transformExpression(node.expression); - return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + if (context.luaTarget === LuaTarget.Lua50) { + const stringLen = lua.createTableIndexExpression( + lua.createIdentifier("string"), + lua.createStringLiteral("len") + ); + return lua.createCallExpression(stringLen, [expression], node); + } else { + return lua.createUnaryExpression(expression, lua.SyntaxKind.LengthOperator, node); + } default: context.diagnostics.push(unsupportedProperty(node.name, "string", node.name.text)); } diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 7fc7d814b..76c9c2a49 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -84,16 +84,14 @@ export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." ); -type NonUniversalTarget = Exclude; - const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); export const unsupportedForTarget = createErrorDiagnosticFactory( - (functionality: string, version: NonUniversalTarget) => + (functionality: string, version: LuaTarget) => `${functionality} is/are not supported for target ${getLuaTargetName(version)}.` ); export const unsupportedForTargetButOverrideAvailable = createErrorDiagnosticFactory( - (functionality: string, version: NonUniversalTarget, optionName: keyof TypeScriptToLuaOptions) => + (functionality: string, version: LuaTarget, optionName: keyof TypeScriptToLuaOptions) => `As a precaution, ${functionality} is/are not supported for target ${getLuaTargetName( version )} due to language features/limitations. ` + diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 31c101d13..0a8e158dc 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -72,7 +72,9 @@ export function createUnpackCall( } const unpack = - context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.LuaJIT + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.LuaJIT ? lua.createIdentifier("unpack") : lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("unpack")); diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index e284b2ea0..14ce4bdef 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -63,8 +63,9 @@ export function transformBinaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Universal: + case LuaTarget.Lua50: case LuaTarget.Lua51: - context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); case LuaTarget.LuaJIT: return transformBinaryBitLibOperation(node, left, right, operator, "bit"); @@ -107,8 +108,9 @@ export function transformUnaryBitOperation( ): lua.Expression { switch (context.luaTarget) { case LuaTarget.Universal: + case LuaTarget.Lua50: case LuaTarget.Lua51: - context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", LuaTarget.Lua51)); + context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); case LuaTarget.LuaJIT: return transformUnaryBitLibOperation(node, expression, operator, "bit"); diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index ba292d126..3b5521490 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../../CompilerOptions"; import * as lua from "../../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../../context"; import { wrapInToStringForConcat } from "../../utils/lua-ast"; @@ -68,6 +69,10 @@ function transformBinaryOperationWithNoPrecedingStatements( return transformNullishCoalescingOperationNoPrecedingStatements(context, node, left, right); } + if (operator === ts.SyntaxKind.PercentToken && context.luaTarget === LuaTarget.Lua50) { + return transformLuaLibFunction(context, LuaLibFeature.Modulo50, node, left, right); + } + let luaOperator = simpleOperatorsToLua[operator]; // Check if we need to use string concat operator diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 9e476b17e..580abf73f 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -11,8 +11,12 @@ export const transformBreakStatement: FunctionVisitor = (brea }; export const transformContinueStatement: FunctionVisitor = (statement, context) => { - if (context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua51) { - context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", LuaTarget.Lua51)); + if ( + context.luaTarget === LuaTarget.Universal || + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 + ) { + context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", context.luaTarget)); } const scope = findScope(context, ScopeType.Loop); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index f2662132c..68adcab39 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -22,6 +22,7 @@ import { import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; +import { LuaTarget } from "../../../CompilerOptions"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead @@ -125,16 +126,20 @@ function transformClassLikeDeclaration( } else if (instanceFields.length > 0) { // Generate a constructor if none was defined in a class with instance fields that need initialization // localClassName.prototype.____constructor = function(self, ...) - // baseClassName.prototype.____constructor(self, ...) + // baseClassName.prototype.____constructor(self, ...) // or unpack(arg) for Lua 5.0 // ... const constructorBody = transformClassInstanceFields(context, instanceFields); + const argsExpression = + context.luaTarget === LuaTarget.Lua50 + ? lua.createCallExpression(lua.createIdentifier("unpack"), [lua.createArgLiteral()]) + : lua.createDotsLiteral(); const superCall = lua.createExpressionStatement( lua.createCallExpression( lua.createTableIndexExpression( context.transformExpression(ts.factory.createSuper()), lua.createStringLiteral("____constructor") ), - [createSelfIdentifier(), lua.createDotsLiteral()] + [createSelfIdentifier(), argsExpression] ) ); constructorBody.unshift(superCall); diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 783a340e5..f81519e4c 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -16,7 +16,10 @@ import { createReturnStatement } from "./return"; const transformAsyncTry: FunctionVisitor = (statement, context) => { const [tryBlock] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if (context.options.luaTarget === LuaTarget.Lua51 && !context.options.lua51AllowTryCatchInAsyncAwait) { + if ( + (context.options.luaTarget === LuaTarget.Lua50 || context.options.luaTarget === LuaTarget.Lua51) && + !context.options.lua51AllowTryCatchInAsyncAwait + ) { context.diagnostics.push( unsupportedForTargetButOverrideAvailable( statement, @@ -79,7 +82,10 @@ export const transformTryStatement: FunctionVisitor = (statemen const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); - if (context.options.luaTarget === LuaTarget.Lua51 && isInGeneratorFunction(statement)) { + if ( + (context.options.luaTarget === LuaTarget.Lua50 || context.options.luaTarget === LuaTarget.Lua51) && + isInGeneratorFunction(statement) + ) { context.diagnostics.push( unsupportedForTarget(statement, "try/catch inside generator functions", LuaTarget.Lua51) ); diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 761c02571..dbcd76549 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { assert } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; @@ -140,7 +141,8 @@ export function transformFunctionBodyHeader( // Push spread operator here if (spreadIdentifier && isRestParameterReferenced(spreadIdentifier, bodyScope)) { - const spreadTable = wrapInTable(lua.createDotsLiteral()); + const spreadTable = + context.luaTarget === LuaTarget.Lua50 ? lua.createArgLiteral() : wrapInTable(lua.createDotsLiteral()); headerStatements.push(lua.createVariableDeclarationStatement(spreadIdentifier, spreadTable)); } diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index 2281712b8..657c98b92 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -118,6 +118,7 @@ function transformUnaryOperator(context: TransformationContext, node: ts.CallExp function checkHasLua53(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { const isBefore53 = + context.luaTarget === LuaTarget.Lua50 || context.luaTarget === LuaTarget.Lua51 || context.luaTarget === LuaTarget.Lua52 || context.luaTarget === LuaTarget.LuaJIT || diff --git a/src/transformation/visitors/literal.ts b/src/transformation/visitors/literal.ts index 838b8d5c2..1d91c89d9 100644 --- a/src/transformation/visitors/literal.ts +++ b/src/transformation/visitors/literal.ts @@ -9,6 +9,7 @@ import { isArrayType } from "../utils/typescript"; import { transformFunctionLikeDeclaration } from "./function"; import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; import { transformIdentifierWithSymbol } from "./identifier"; +import { LuaTarget } from "../../CompilerOptions"; // TODO: Move to object-literal.ts? export function transformPropertyName(context: TransformationContext, node: ts.PropertyName): lua.Expression { @@ -31,11 +32,17 @@ export function createShorthandIdentifier( return transformIdentifierWithSymbol(context, propertyIdentifier, valueSymbol); } -const transformNumericLiteralExpression: FunctionVisitor = expression => { +const transformNumericLiteralExpression: FunctionVisitor = (expression, context) => { if (expression.text === "Infinity") { - const math = lua.createIdentifier("math"); - const huge = lua.createStringLiteral("huge"); - return lua.createTableIndexExpression(math, huge, expression); + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, expression); + } } return lua.createNumericLiteral(Number(expression.text), expression); diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 84a13f0fd..a71fc01e8 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { isLuaIterable } from "../utils/language-extensions"; @@ -66,7 +67,9 @@ export const transformSpreadElement: FunctionVisitor = (node, if (ts.isIdentifier(tsInnerExpression)) { const symbol = context.checker.getSymbolAtLocation(tsInnerExpression); if (symbol && isOptimizedVarArgSpread(context, symbol, tsInnerExpression)) { - return lua.createDotsLiteral(node); + return context.luaTarget === LuaTarget.Lua50 + ? createUnpackCall(context, lua.createArgLiteral(), node) + : lua.createDotsLiteral(node); } } diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 547c3b110..c0b21b7d2 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -1,7 +1,7 @@ import * as path from "path"; import { SourceNode } from "source-map"; import * as ts from "typescript"; -import { CompilerOptions } from "../CompilerOptions"; +import { CompilerOptions, LuaTarget } from "../CompilerOptions"; import { escapeString, tstlHeader } from "../LuaPrinter"; import { cast, formatPathToLuaPath, isNonNull, trimExtension } from "../utils"; import { couldNotFindBundleEntryPoint } from "./diagnostics"; @@ -12,7 +12,12 @@ const createModulePath = (pathToResolve: string, program: ts.Program) => escapeString(formatPathToLuaPath(trimExtension(getEmitPathRelativeToOutDir(pathToResolve, program)))); // Override `require` to read from ____modules table. -const requireOverride = ` +function requireOverride(options: CompilerOptions) { + const runModule = + options.luaTarget === LuaTarget.Lua50 + ? "(table.getn(arg) > 0) and module(unpack(arg)) or module(file)" + : '(select("#", ...) > 0) and module(...) or module(file)'; + return ` local ____modules = {} local ____moduleCache = {} local ____originalRequire = require @@ -22,7 +27,7 @@ local function require(file, ...) end if ____modules[file] then local module = ____modules[file] - ____moduleCache[file] = { value = (select("#", ...) > 0) and module(...) or module(file) } + ____moduleCache[file] = { value = ${runModule} } return ____moduleCache[file].value else if ____originalRequire then @@ -33,6 +38,7 @@ local function require(file, ...) end end `; +} export const sourceMapTracebackBundlePlaceholder = "{#SourceMapTracebackBundle}"; @@ -101,7 +107,8 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t const moduleTable = createModuleTableNode(moduleTableEntries); // return require("") - const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ...)\n`; + const args = options.luaTarget === LuaTarget.Lua50 ? "unpack(arg == nil and {} or arg)" : "..."; + const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ${args})\n`; const footers: string[] = []; if (options.sourceMapTraceback) { @@ -110,7 +117,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t footers.push(`${sourceMapTracebackBundlePlaceholder}\n`); } - const sourceChunks = [requireOverride, moduleTable, ...footers, entryPoint]; + const sourceChunks = [requireOverride(options), moduleTable, ...footers, entryPoint]; if (!options.noHeader) { sourceChunks.unshift(tstlHeader); diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 216e80aba..2f05aae64 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions, isBundleEnabled } from "../CompilerOptions"; +import { CompilerOptions, isBundleEnabled, LuaTarget } from "../CompilerOptions"; import { getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; @@ -126,7 +126,8 @@ export class Transpiler { // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); - resolutionResult.resolvedFiles.unshift({ fileName, code: getLuaLibBundle(this.emitHost) }); + const luaTarget = options.luaTarget ?? LuaTarget.Universal; + resolutionResult.resolvedFiles.unshift({ fileName, code: getLuaLibBundle(luaTarget, this.emitHost) }); } let emitPlan: EmitFile[]; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 2def0b45a..283b4095e 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -242,6 +242,7 @@ describe("tsconfig", () => { ["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }], ["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }], + ["luaTarget", "5.0", { luaTarget: tstl.LuaTarget.Lua50 }], ["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }], ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], diff --git a/test/json.50.lua b/test/json.50.lua new file mode 100644 index 000000000..8e4109c8f --- /dev/null +++ b/test/json.50.lua @@ -0,0 +1,147 @@ +-- +-- json.lua +-- +-- Copyright (c) 2015 rxi +-- +-- This library is free software; you can redistribute it and/or modify it +-- under the terms of the MIT license. See LICENSE for details. +-- +-- +-- LICENSE CONTENTS: +-- +-- Copyright (c) 2015 rxi +-- +-- +-- Permission is hereby granted, free of charge, to any person obtaining a copy of +-- this software and associated documentation files (the "Software"), to deal in +-- the Software without restriction, including without limitation the rights to +-- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +-- of the Software, and to permit persons to whom the Software is furnished to do +-- so, subject to the following conditions: +-- +-- The above copyright notice and this permission notice shall be included in all +-- copies or substantial portions of the Software. +-- +-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +-- SOFTWARE. + +local json = { _version = "0.1.0" } + +------------------------------------------------------------------------------- +-- Encode +------------------------------------------------------------------------------- + +local encode + +local escape_char_map = { + [ "\\" ] = "\\\\", + [ "\"" ] = "\\\"", + [ "\b" ] = "\\b", + [ "\f" ] = "\\f", + [ "\n" ] = "\\n", + [ "\r" ] = "\\r", + [ "\t" ] = "\\t", +} + +local escape_char_map_inv = { [ "\\/" ] = "/" } +for k, v in pairs(escape_char_map) do + escape_char_map_inv[v] = k +end + + +local function escape_char(c) + return escape_char_map[c] or string.format("\\u%04x", c:byte()) +end + + +local function encode_nil(val) + return "null" +end + + +local function encode_table(val, stack) + local res = {} + stack = stack or {} + + -- Circular reference? + if stack[val] then error("circular reference") end + + stack[val] = true + + if val[1] ~= nil or next(val) == nil then + -- Treat as array -- check keys are valid and it is not sparse + local n = 0 + for k in pairs(val) do + if k ~= "n" then + if type(k) ~= "number" then + error("invalid table: mixed or invalid key types") + end + n = n + 1 + end + end + if n ~= table.getn(val) then + error("invalid table: sparse array") + end + -- Encode + for i, v in ipairs(val) do + table.insert(res, encode(v, stack)) + end + stack[val] = nil + return "[" .. table.concat(res, ",") .. "]" + + else + -- Treat as an object + for k, v in pairs(val) do + if type(k) ~= "string" then + error("invalid table: mixed or invalid key types") + end + table.insert(res, encode(k, stack) .. ":" .. encode(v, stack)) + end + stack[val] = nil + return "{" .. table.concat(res, ",") .. "}" + end +end + + +local function encode_string(val) + return '"' .. string.gsub(val, '[%z\1-\31\\"]', escape_char) .. '"' +end + + +local function encode_number(val) + if val ~= val then + return "NaN" + elseif val >= 1 / 0 then + return "Infinity" + elseif val <= 0 / 0 then + return "-Infinity" + else + return string.format("%.17g", val) + end +end + + +local type_func_map = { + [ "nil" ] = encode_nil, + [ "table" ] = encode_table, + [ "string" ] = encode_string, + [ "number" ] = encode_number, + [ "boolean" ] = tostring, +} + + +encode = function(val, stack) + local t = type(val) + local f = type_func_map[t] + if f then + return f(val, stack) + end + error("unexpected type '" .. t .. "'") +end + +return {stringify = function(val) return ( encode(val) ) end} diff --git a/test/transpile/lualib.spec.ts b/test/transpile/lualib.spec.ts index b35ab996b..20288bd8a 100644 --- a/test/transpile/lualib.spec.ts +++ b/test/transpile/lualib.spec.ts @@ -1,10 +1,10 @@ import * as ts from "typescript"; -import { LuaLibFeature } from "../../src"; +import { LuaLibFeature, LuaTarget } from "../../src"; import { readLuaLibFeature } from "../../src/LuaLib"; import * as util from "../util"; test.each(Object.entries(LuaLibFeature))("Lualib does not use ____exports (%p)", (_, feature) => { - const lualibCode = readLuaLibFeature(feature, ts.sys); + const lualibCode = readLuaLibFeature(feature, LuaTarget.Lua54, ts.sys); const exportsOccurrences = lualibCode.match(/____exports/g); expect(exportsOccurrences).toBeNull(); diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 5f58cde14..999459e57 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -36,6 +36,116 @@ ____exports.__result = 10 - (4 + 5) return ____exports" `; +exports[`Bitop [5.0] ("~a"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bnot(a) +return ____exports" +`; + +exports[`Bitop [5.0] ("~a"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a&=b"): code 1`] = ` +"local ____exports = {} +a = bit.band(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a&=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a&b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.band(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a&b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a<<=b"): code 1`] = ` +"local ____exports = {} +a = bit.lshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a<<=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a<>=b"): code 1`] = ` +"local ____exports = {} +a = bit.arshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>>=b"): code 1`] = ` +"local ____exports = {} +a = bit.rshift(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.rshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a>>b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.arshift(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a^=b"): code 1`] = ` +"local ____exports = {} +a = bit.bxor(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a^=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a^b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bxor(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a^b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a|=b"): code 1`] = ` +"local ____exports = {} +a = bit.bor(a, b) +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.0] ("a|=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`Bitop [5.0] ("a|b"): code 1`] = ` +"local ____exports = {} +____exports.__result = bit.bor(a, b) +return ____exports" +`; + +exports[`Bitop [5.0] ("a|b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Bitwise operations is/are not supported for target Lua 5.0."`; + exports[`Bitop [5.1] ("~a"): code 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap index e9b6be991..7b0c40ad2 100644 --- a/test/unit/__snapshots__/loops.spec.ts.snap +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -12,6 +12,19 @@ return ____exports" exports[`forin[Array]: diagnostics 1`] = `"main.ts(3,9): error TSTL: Iterating over arrays with 'for ... in' is not allowed."`; +exports[`loop continue (do { continue; } while (false)) [5.0]: code 1`] = ` +"repeat + do + do + goto __continue2 + end + ::__continue2:: + end +until not false" +`; + +exports[`loop continue (do { continue; } while (false)) [5.0]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; + exports[`loop continue (do { continue; } while (false)) [5.1]: code 1`] = ` "repeat do @@ -36,7 +49,20 @@ exports[`loop continue (do { continue; } while (false)) [universal]: code 1`] = until not false" `; -exports[`loop continue (do { continue; } while (false)) [universal]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (do { continue; } while (false)) [universal]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua universal."`; + +exports[`loop continue (for (;;) { continue; }) [5.0]: code 1`] = ` +"do + while true do + do + goto __continue2 + end + ::__continue2:: + end +end" +`; + +exports[`loop continue (for (;;) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; exports[`loop continue (for (;;) { continue; }) [5.1]: code 1`] = ` "do @@ -62,7 +88,18 @@ exports[`loop continue (for (;;) { continue; }) [universal]: code 1`] = ` end" `; -exports[`loop continue (for (;;) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (;;) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua universal."`; + +exports[`loop continue (for (const a in {}) { continue; }) [5.0]: code 1`] = ` +"for a in pairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a in {}) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; exports[`loop continue (for (const a in {}) { continue; }) [5.1]: code 1`] = ` "for a in pairs({}) do @@ -84,7 +121,18 @@ exports[`loop continue (for (const a in {}) { continue; }) [universal]: code 1`] end" `; -exports[`loop continue (for (const a in {}) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (const a in {}) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua universal."`; + +exports[`loop continue (for (const a of []) { continue; }) [5.0]: code 1`] = ` +"for ____, a in ipairs({}) do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (for (const a of []) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; exports[`loop continue (for (const a of []) { continue; }) [5.1]: code 1`] = ` "for ____, a in ipairs({}) do @@ -106,7 +154,18 @@ exports[`loop continue (for (const a of []) { continue; }) [universal]: code 1`] end" `; -exports[`loop continue (for (const a of []) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (for (const a of []) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua universal."`; + +exports[`loop continue (while (false) { continue; }) [5.0]: code 1`] = ` +"while false do + do + goto __continue2 + end + ::__continue2:: +end" +`; + +exports[`loop continue (while (false) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; exports[`loop continue (while (false) { continue; }) [5.1]: code 1`] = ` "while false do @@ -128,4 +187,4 @@ exports[`loop continue (while (false) { continue; }) [universal]: code 1`] = ` end" `; -exports[`loop continue (while (false) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; +exports[`loop continue (while (false) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua universal."`; diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index e0ef21233..d31bde3f1 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -16,171 +16,3 @@ function ____exports.__main(self) end return ____exports" `; - -exports[`vararg spread optimization With cast 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - return pick(nil, ...) - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization basic use 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - return pick(nil, ...) - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization block statement 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - local result - do - result = pick(nil, ...) - end - return result - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization body-less arrow function 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(____, ...) - return pick(nil, ...) - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization curry 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function test(self, fn, ...) - return fn(nil, ...) - end - return test( - nil, - function(____, arg) return arg end, - \\"foobar\\" - ) -end -return ____exports" -`; - -exports[`vararg spread optimization curry with indirect type 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function test(self, obj, ...) - local fn = obj.fn - return fn(nil, ...) - end - return test( - nil, - {fn = function(____, arg) return arg end}, - \\"foobar\\" - ) -end -return ____exports" -`; - -exports[`vararg spread optimization finally clause 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - do - pcall(function() - error(\\"foobar\\", 0) - end) - do - return pick(nil, ...) - end - end - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization function type declared inside scope 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function test(self, ...) - local function fn(____, ...) - local args = {...} - return args[1] - end - return fn(nil, ...) - end - test(nil, \\"foobar\\") -end -return ____exports" -`; - -exports[`vararg spread optimization if statement 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - if true then - return pick(nil, ...) - end - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; - -exports[`vararg spread optimization loop statement 1`] = ` -"local ____exports = {} -function ____exports.__main(self) - local function pick(self, ...) - local args = {...} - return args[2] - end - local function test(self, ...) - repeat - do - return pick(nil, ...) - end - until not false - end - return test(nil, \\"a\\", \\"b\\", \\"c\\") -end -return ____exports" -`; diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 8b7e0b5cf..3dbb77abe 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -541,6 +541,8 @@ describe("try/catch in async function", () => { // Cannot execute LuaJIT with test runner { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: 4 })), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } @@ -565,6 +567,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } @@ -593,6 +597,8 @@ describe("try/catch in async function", () => { ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ reason: "an error occurred in the async function: test error" }) ), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), } diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 9e191e1e2..3126a85ca 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -78,6 +78,7 @@ const expectLualibMathAtan2: util.TapCallback = builder => util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibMathAtan2), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 329b6317e..2aec6a6f2 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -18,9 +18,13 @@ test.each([ util.testFunction(input).disableSemanticCheck().expectLuaToMatchSnapshot(); }); -test.each(["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"])("Binary expressions basic numeric (%p)", input => { - util.testExpression(input).expectToMatchJsResult(); -}); +for (const expression of ["3+4", "5-2", "6*3", "6**3", "20/5", "15/10", "15%3"]) { + util.testEachVersion( + `Binary expressions basic numeric (${expression})`, + () => util.testExpression(expression), + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); +} test.each(["1==1", "1===1", "1!=1", "1!==1", "1>1", "1>=1", "1<1", "1<=1", "1&&1", "1||1"])( "Binary expressions basic boolean (%p)", @@ -48,6 +52,14 @@ test.each(["a+=b", "a-=b", "a*=b", "a/=b", "a%=b", "a**=b"])("Binary expressions const supportedInAll = ["~a", "a&b", "a&=b", "a|b", "a|=b", "a^b", "a^=b", "a<>>b", "a>>>=b"]; const unsupportedIn53And54 = ["a>>b", "a>>=b"]; const allBinaryOperators = [...supportedInAll, ...unsupportedIn53And54]; +test.each(allBinaryOperators)("Bitop [5.0] (%p)", input => { + // Bit operations not supported in 5.0, expect an exception + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua50, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); +}); + test.each(allBinaryOperators)("Bitop [5.1] (%p)", input => { // Bit operations not supported in 5.1, expect an exception util.testExpression(input) diff --git a/test/unit/functions/__snapshots__/functions.spec.ts.snap b/test/unit/functions/__snapshots__/functions.spec.ts.snap index 345e31731..4e07a4367 100644 --- a/test/unit/functions/__snapshots__/functions.spec.ts.snap +++ b/test/unit/functions/__snapshots__/functions.spec.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`function.length unsupported ("5.0"): code 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function fn(self) + end + return debug.getinfo(fn).nparams - 1 +end +return ____exports" +`; + +exports[`function.length unsupported ("5.0"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua 5.0."`; + exports[`function.length unsupported ("5.1"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) @@ -10,7 +22,7 @@ end return ____exports" `; -exports[`function.length unsupported ("5.1"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; +exports[`function.length unsupported ("5.1"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua 5.1."`; exports[`function.length unsupported ("universal"): code 1`] = ` "local ____exports = {} @@ -22,7 +34,7 @@ end return ____exports" `; -exports[`function.length unsupported ("universal"): diagnostics 1`] = `"main.ts(3,16): error TSTL: function.length is/are not supported for target Lua 5.1."`; +exports[`function.length unsupported ("universal"): diagnostics 1`] = `"main.ts(3,20): error TSTL: function.length is/are not supported for target Lua universal."`; exports[`missing declaration name: code 1`] = ` "function ____(self) diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index c44364c9f..7bd224fba 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -224,14 +224,17 @@ test.each([ `.expectToMatchJsResult(); }); -test.each([tstl.LuaTarget.Lua51, tstl.LuaTarget.Universal])("function.length unsupported (%p)", luaTarget => { - util.testFunction` - function fn() {} - return fn.length; - ` - .setOptions({ luaTarget }) - .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); -}); +test.each([tstl.LuaTarget.Lua50, tstl.LuaTarget.Lua51, tstl.LuaTarget.Universal])( + "function.length unsupported (%p)", + luaTarget => { + util.testFunction` + function fn() {} + return fn.length; + ` + .setOptions({ luaTarget }) + .expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]); + } +); test("Recursive function definition", () => { util.testFunction` diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index 03b7f3bfd..aa62d719d 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -165,6 +165,7 @@ util.testEachVersion( // Cannot execute LuaJIT with test runner { ...util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()), + [LuaTarget.Lua50]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), [LuaTarget.Lua51]: builder => builder.expectToHaveDiagnostics([unsupportedForTarget.code]), } ); diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap index fff18a4cc..dda0e61e2 100644 --- a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -20,6 +20,30 @@ exports[`operator mapping - invalid use (declare function foo(op: LuaAddition): void; foo(op);): diagnostics 1`] = `"main.ts(3,82): error TSTL: This function must be called directly and cannot be referred to."`; +exports[`unsupported binary operator mapping (5.0 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseExclusiveOr): code 1`] = `"local ____ = left ~ right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseExclusiveOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseLeftShift): code 1`] = `"local ____ = left << right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseLeftShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseOr): code 1`] = `"local ____ = left | right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseOr): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseRightShift): code 1`] = `"local ____ = left >> right"`; + +exports[`unsupported binary operator mapping (5.0 LuaBitwiseRightShift): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + +exports[`unsupported binary operator mapping (5.0 LuaFloorDivision): code 1`] = `"local ____ = left // right"`; + +exports[`unsupported binary operator mapping (5.0 LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.0."`; + exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): code 1`] = `"local ____ = left & right"`; exports[`unsupported binary operator mapping (5.1 LuaBitwiseAnd): diagnostics 1`] = `"main.ts(6,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; @@ -116,6 +140,10 @@ exports[`unsupported binary operator mapping (universal LuaFloorDivision): code exports[`unsupported binary operator mapping (universal LuaFloorDivision): diagnostics 1`] = `"main.ts(6,9): error TSTL: Floor division operator is/are not supported for target Lua 5.1."`; +exports[`unsupported unary operator mapping (5.0 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; + +exports[`unsupported unary operator mapping (5.0 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.0."`; + exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): code 1`] = `"local ____ = ~operand"`; exports[`unsupported unary operator mapping (5.1 LuaBitwiseNot): diagnostics 1`] = `"main.ts(5,9): error TSTL: Native bitwise operations is/are not supported for target Lua 5.1."`; diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index bdd28339c..043b1cebb 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -113,7 +113,7 @@ test.each(binaryMathOperatorTests)( } ); -const luaTargetsPre53 = [LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; +const luaTargetsPre53 = [LuaTarget.Lua50, LuaTarget.Lua51, LuaTarget.Lua52, LuaTarget.LuaJIT, LuaTarget.Universal]; const operatorTypesPost53 = [ "LuaFloorDivision", diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 427af9d06..0fff55d9d 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -520,6 +520,7 @@ for (const testCase of [ util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { [tstl.LuaTarget.Universal]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), + [tstl.LuaTarget.Lua50]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 29f7110d3..40f650055 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -76,6 +76,7 @@ describe("in function call", () => { { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), @@ -88,6 +89,7 @@ describe("in array literal", () => { util.testEachVersion(undefined, () => util.testExpression`[...[0, 1, 2]]`, { [tstl.LuaTarget.Universal]: builder => builder.tap(expectLualibUnpack).expectToMatchJsResult(), [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectUnpack), + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua51]: builder => builder.tap(expectUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), @@ -133,58 +135,55 @@ describe("in object literal", () => { }); describe("vararg spread optimization", () => { - test("basic use", () => { - util.testFunction` + util.testEachVersion( + "basic use", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { return pick(...args); } - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("body-less arrow function", () => { - util.testFunction` + util.testEachVersion( + "body-less arrow function", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } const test = (...args: string[]) => pick(...args); - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("if statement", () => { - util.testFunction` + util.testEachVersion( + "if statement", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { if (true) { return pick(...args); } } - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("loop statement", () => { - util.testFunction` + util.testEachVersion( + "loop statement", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { do { return pick(...args); } while (false); } - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("block statement", () => { - util.testFunction` + util.testEachVersion( + "block statement", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { let result: string; @@ -193,14 +192,13 @@ describe("vararg spread optimization", () => { } return result; } - return test("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("finally clause", () => { - util.testFunction` + util.testEachVersion( + "finally clause", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { try { @@ -210,11 +208,9 @@ describe("vararg spread optimization", () => { return pick(...args); } } - return test("a" ,"b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); test("$multi", () => { util.testFunction` @@ -231,68 +227,66 @@ describe("vararg spread optimization", () => { .expectToEqual("b"); }); - test("curry", () => { - util.testFunction` + util.testEachVersion( + "curry", + () => util.testFunction` function test(fn: (...args: A) => void, ...args: A) { return fn(...args); } - return test((arg: string) => arg, "foobar"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test((arg: string) => arg, "foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("curry with indirect type", () => { - util.testFunction` + util.testEachVersion( + "curry with indirect type", + () => util.testFunction` function test(obj: {fn: (...args: A) => void}, ...args: A) { const fn = obj.fn; return fn(...args); } - return test({fn: (arg: string) => arg}, "foobar"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test({fn: (arg: string) => arg}, "foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("function type declared inside scope", () => { - util.testFunction` + util.testEachVersion( + "function type declared inside scope", + () => util.testFunction` function test(...args: A) { const fn: (...args: A) => A[0] = (...args) => args[0]; return fn(...args); } - test("foobar"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + test("foobar");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("With cast", () => { - util.testFunction` + util.testEachVersion( + "With cast", + () => util.testFunction` function pick(...args: any[]) { return args[1]; } function testany>(...args: Parameters) { return pick(...(args as any[])); } - return test<(...args: string[])=>void>("a", "b", "c"); - ` - .expectLuaToMatchSnapshot() - .expectToMatchJsResult(); - }); + return test<(...args: string[])=>void>("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); describe("vararg spread de-optimization", () => { - test("array modification", () => { - util.testFunction` + util.testEachVersion( + "array modification", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { args[1] = "foobar"; return pick(...args); } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("array modification in hoisted function", () => { - util.testFunction` + util.testEachVersion( + "array modification in hoisted function", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { hoisted(); @@ -300,12 +294,13 @@ describe("vararg spread de-optimization", () => { function hoisted() { args[1] = "foobar"; } return result; } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("array modification in secondary hoisted function", () => { - util.testFunction` + util.testEachVersion( + "array modification in secondary hoisted function", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { function triggersHoisted() { hoisted(); } @@ -314,103 +309,112 @@ describe("vararg spread de-optimization", () => { function hoisted() { args[1] = "foobar"; } return result; } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); describe("vararg spread in IIFE", () => { - test("comma operator", () => { - util.testFunction` + util.testEachVersion( + "comma operator", + () => util.testFunction` function dummy() { return "foobar"; } function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { return (dummy(), pick(...args)); } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("assignment expression", () => { - util.testFunction` + util.testEachVersion( + "assignment expression", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { let x: string; return (x = pick(...args)); } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("destructured assignment expression", () => { - util.testFunction` + util.testEachVersion( + "destructured assignment expression", + () => util.testFunction` function pick(...args: string[]) { return [args[1]]; } function test(...args: string[]) { let x: string; return ([x] = pick(...args)); } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("property-access assignment expression", () => { - util.testFunction` + util.testEachVersion( + "property-access assignment expression", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { let x: {val?: string} = {}; return (x.val = pick(...args)); } - return test("a", "b", "c"); - `.expectToMatchJsResult(); - }); + return test("a", "b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("binary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "binary compound assignment", + () => util.testFunction` function pick(...args: number[]) { return args[1]; } function test(...args: number[]) { let x = 1; return x += pick(...args); } - return test(1, 2, 3); - `.expectToMatchJsResult(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("postfix unary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "postfix unary compound assignment", + () => util.testFunction` function pick(...args: number[]) { return args[1]; } function test(...args: number[]) { let x = [7, 8, 9]; return x[pick(...args)]++; } - return test(1, 2, 3); - `.expectToMatchJsResult(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("prefix unary compound assignment", () => { - util.testFunction` + util.testEachVersion( + "prefix unary compound assignment", + () => util.testFunction` function pick(...args: number[]) { return args[1]; } function test(...args: number[]) { let x = [7, 8, 9]; return ++x[pick(...args)]; } - return test(1, 2, 3); - `.expectToMatchJsResult(); - }); + return test(1, 2, 3);`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("try clause", () => { - util.testFunction` + util.testEachVersion( + "try clause", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { try { return pick(...args) } catch {} } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("catch clause", () => { - util.testFunction` + util.testEachVersion( + "catch clause", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { try { @@ -419,64 +423,69 @@ describe("vararg spread in IIFE", () => { return pick(...args) } } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("class expression", () => { - util.testFunction` + util.testEachVersion( + "class expression", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } function test(...args: string[]) { const fooClass = class Foo { foo = pick(...args); }; return new fooClass().foo; } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("self-referencing function expression", () => { - util.testFunction` + util.testEachVersion( + "self-referencing function expression", + () => util.testFunction` function pick(...args: string[]) { return args[1]; } const test = function testName(...args: string[]) { return \`\${typeof testName}:\${pick(...args)}\`; } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("method indirect access (access args)", () => { - util.testFunction` + util.testEachVersion( + "method indirect access (access args)", + () => util.testFunction` const obj = { $method: () => obj.arg, arg: "foobar" }; function getObj(...args: string[]) { obj.arg = args[1]; return obj; } function test(...args: string[]) { return getObj(...args).$method(); } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("method indirect access (method args)", () => { - util.testFunction` + util.testEachVersion( + "method indirect access (method args)", + () => util.testFunction` const obj = { $pick: (...args: string[]) => args[1] }; function getObj() { return obj; } function test(...args: string[]) { return getObj().$pick(...args); } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); - test("tagged template method indirect access", () => { - util.testFunction` + util.testEachVersion( + "tagged template method indirect access", + () => util.testFunction` const obj = { $tag: (t: TemplateStringsArray, ...args: string[]) => args[1] }; function getObj() { return obj; } function pick(...args: string[]): string { return args[1]; } function test(...args: string[]) { return getObj().$tag\`FOO\${pick(...args)}BAR\`; } - return test("a" ,"b", "c"); - `.expectToMatchJsResult(); - }); + return test("a" ,"b", "c");`, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 diff --git a/test/util.ts b/test/util.ts index ffc6bac68..8650f88ca 100644 --- a/test/util.ts +++ b/test/util.ts @@ -11,14 +11,25 @@ import * as tstl from "../src"; import { createEmitOutputCollector } from "../src/transpilation/output-collector"; import { EmitHost, getEmitOutDir, transpileProject } from "../src"; import { formatPathToLuaPath, normalizeSlashes } from "../src/utils"; +import { resolveLuaLibDir } from "../src/LuaLib"; -const jsonLib = fs.readFileSync(path.join(__dirname, "json.lua"), "utf8"); -const luaLib = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); +function readLuaLib(target: tstl.LuaTarget) { + return fs.readFileSync(path.join(resolveLuaLibDir(target), "lualib_bundle.lua"), "utf8"); +} + +function jsonLib(target: tstl.LuaTarget): string { + const fileName = target === tstl.LuaTarget.Lua50 ? "json.50.lua" : "json.lua"; + return fs.readFileSync(path.join(__dirname, fileName), "utf8"); +} // Using `test` directly makes eslint-plugin-jest consider this file as a test const defineTest = test; function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; lua: Lua; lualib: LuaLib } { + if (target === tstl.LuaTarget.Lua50) { + const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.50"); + return { lauxlib, lua, lualib }; + } if (target === tstl.LuaTarget.Lua51) { const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.51"); return { lauxlib, lua, lualib }; @@ -70,6 +81,7 @@ export function expectEachVersionExceptJit( ): Record void) | boolean> { return { [tstl.LuaTarget.Universal]: expectation, + [tstl.LuaTarget.Lua50]: expectation, [tstl.LuaTarget.Lua51]: expectation, [tstl.LuaTarget.Lua52]: expectation, [tstl.LuaTarget.Lua53]: expectation, @@ -402,20 +414,21 @@ export abstract class TestBuilder { // Main file const mainFile = this.getMainLuaCodeChunk(); - const { lauxlib, lua, lualib } = getLuaBindingsForVersion(this.options.luaTarget ?? tstl.LuaTarget.Lua54); + const luaTarget = this.options.luaTarget ?? tstl.LuaTarget.Lua54; + const { lauxlib, lua, lualib } = getLuaBindingsForVersion(luaTarget); const L = lauxlib.luaL_newstate(); lualib.luaL_openlibs(L); // Load modules // Json - this.packagePreloadLuaFile(L, lua, lauxlib, "json", jsonLib); + this.injectLuaFile(L, lua, lauxlib, "json", jsonLib(luaTarget)); // Lua lib if ( this.options.luaLibImport === tstl.LuaLibImportKind.Require || mainFile.includes('require("lualib_bundle")') ) { - this.packagePreloadLuaFile(L, lua, lauxlib, "lualib_bundle", luaLib); + this.injectLuaFile(L, lua, lauxlib, "lualib_bundle", readLuaLib(luaTarget)); } // Load all transpiled files into Lua's package cache @@ -423,7 +436,7 @@ export abstract class TestBuilder { for (const transpiledFile of transpiledFiles) { if (transpiledFile.lua) { const filePath = path.relative(getEmitOutDir(this.getProgram()), transpiledFile.outPath); - this.packagePreloadLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); + this.injectLuaFile(L, lua, lauxlib, filePath, transpiledFile.lua); } } @@ -454,12 +467,20 @@ end)());`; } } - private packagePreloadLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { - // Adding source Lua to the package.preload cache will allow require to find it - lua.lua_getglobal(state, "package"); - lua.lua_getfield(state, -1, "preload"); - lauxlib.luaL_loadstring(state, fileContent); - lua.lua_setfield(state, -2, formatPathToLuaPath(fileName.replace(".lua", ""))); + private injectLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { + const modName = formatPathToLuaPath(fileName.replace(".lua", "")); + if (this.options.luaTarget === tstl.LuaTarget.Lua50) { + // Adding source Lua to the _LOADED cache will allow require to find it + lua.lua_getglobal(state, "_LOADED"); + lauxlib.luaL_dostring(state, fileContent); + lua.lua_setfield(state, -2, modName); + } else { + // Adding source Lua to the package.preload cache will allow require to find it + lua.lua_getglobal(state, "package"); + lua.lua_getfield(state, -1, "preload"); + lauxlib.luaL_loadstring(state, fileContent); + lua.lua_setfield(state, -2, modName); + } } private executeJs(): any { diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 5a3543a03..0d43fe74c 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -50,7 +50,7 @@ "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["universal", "5.1", "5.2", "5.3", "JIT"] + "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "JIT"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", From ecd7a55569af7ae6eebb59fa12ed06488f91c29e Mon Sep 17 00:00:00 2001 From: Ryan Young Date: Sat, 3 Sep 2022 09:30:58 -0700 Subject: [PATCH 534/764] Update VS Code development container configuration (#1344) * build: update development container configuration Bump Node version, delete obsolete setting, fix npm error, run as a non-root user. * build: remove legacy-peer-deps from the dev container --- .devcontainer/devcontainer.json | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index fcfad7738..45207b077 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,14 +1,12 @@ { "name": "TypeScriptToLua", - "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:14", - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, + "image": "mcr.microsoft.com/vscode/devcontainers/javascript-node:18", "extensions": [ "typescript-to-lua.vscode-typescript-to-lua", "dbaeumer.vscode-eslint", "editorconfig.editorconfig", "esbenp.prettier-vscode" ], - "postCreateCommand": "npm ci" + "postCreateCommand": "npm ci", + "remoteUser": "node" } From 9446f6b3ec116bf76f601781909fd2212abdbf0d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 4 Sep 2022 17:10:23 +0200 Subject: [PATCH 535/764] Language extensions as npm package (#1345) * Language-extensions as npm package * Use new lua-types package * Add language extensions to benchmark tsconfigs --- benchmark/tsconfig.53.json | 2 +- benchmark/tsconfig.jit.json | 2 +- benchmark/tsconfig.json | 2 +- language-extensions/package.json | 23 ++++ package-lock.json | 198 ++++++++++++++++--------------- package.json | 10 +- 6 files changed, 136 insertions(+), 101 deletions(-) create mode 100644 language-extensions/package.json diff --git a/benchmark/tsconfig.53.json b/benchmark/tsconfig.53.json index 0a7096234..6dbbe3bca 100644 --- a/benchmark/tsconfig.53.json +++ b/benchmark/tsconfig.53.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "types": ["lua-types/5.3"] + "types": ["lua-types/5.3", "@typescript-to-lua/language-extensions"] }, "tstl": { "luaTarget": "5.3" diff --git a/benchmark/tsconfig.jit.json b/benchmark/tsconfig.jit.json index 1fe18fa2c..0c6912d31 100644 --- a/benchmark/tsconfig.jit.json +++ b/benchmark/tsconfig.jit.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "types": ["lua-types/jit"] + "types": ["lua-types/jit", "@typescript-to-lua/language-extensions"] }, "tstl": { "luaTarget": "JIT" diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json index aefc13ae9..e1c9c2941 100644 --- a/benchmark/tsconfig.json +++ b/benchmark/tsconfig.json @@ -3,7 +3,7 @@ "target": "esnext", "lib": ["esnext"], // Dev types are JIT - "types": ["lua-types/jit"], + "types": ["lua-types/jit", "@typescript-to-lua/language-extensions"], "moduleResolution": "node", "outDir": "dist", "rootDir": "src", diff --git a/language-extensions/package.json b/language-extensions/package.json new file mode 100644 index 000000000..0772d6541 --- /dev/null +++ b/language-extensions/package.json @@ -0,0 +1,23 @@ +{ + "name": "@typescript-to-lua/language-extensions", + "version": "1.0.0", + "description": "Language extensions used by typescript-to-lua", + "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", + "homepage": "https://typescripttolua.github.io/", + "bugs": { + "url": "https://github.com/TypeScriptToLua/TypeScriptToLua/issues" + }, + "license": "MIT", + "keywords": [ + "typescript", + "lua", + "tstl", + "transpiler", + "language extensions" + ], + "files": [ + "**.d.ts" + ], + "main": "", + "types": "index.d.ts" +} diff --git a/package-lock.json b/package-lock.json index c2633715a..e02084d6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "1.9.0", "license": "MIT", "dependencies": { + "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3" @@ -22,8 +23,8 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.35.1", - "@typescript-eslint/parser": "^5.35.1", + "@typescript-eslint/eslint-plugin": "^5.36.1", + "@typescript-eslint/parser": "^5.36.1", "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^26.8.7", @@ -31,7 +32,7 @@ "javascript-stringify": "^2.0.1", "jest": "^28.1.3", "jest-circus": "^29.0.1", - "lua-types": "^2.12.2", + "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", "ts-jest": "^28.0.8", @@ -2013,14 +2014,14 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", - "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", + "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/type-utils": "5.35.1", - "@typescript-eslint/utils": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/type-utils": "5.36.1", + "@typescript-eslint/utils": "5.36.1", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -2046,14 +2047,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", - "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", + "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/typescript-estree": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", "debug": "^4.3.4" }, "engines": { @@ -2073,13 +2074,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", - "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", + "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/visitor-keys": "5.35.1" + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2090,12 +2091,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", - "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", + "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", "dev": true, "dependencies": { - "@typescript-eslint/utils": "5.35.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/utils": "5.36.1", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2116,9 +2118,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", - "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", + "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2129,13 +2131,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", - "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", + "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/visitor-keys": "5.35.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2156,15 +2158,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", - "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", + "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/typescript-estree": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" }, @@ -2180,12 +2182,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", - "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", + "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/types": "5.36.1", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2196,6 +2198,11 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-to-lua/language-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", + "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + }, "node_modules/acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", @@ -6098,13 +6105,10 @@ } }, "node_modules/lua-types": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.2.tgz", - "integrity": "sha512-E9TfcaJ01YW6XrnXhdw9dvO495wkuXRfFJsWNfj/ZTvWrbloWQ0eNnGUkQ8OW/jaJCczJXuT9tW7wdtqL0sc+A==", - "dev": true, - "peerDependencies": { - "typescript-to-lua": "^1.0.0" - } + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", + "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==", + "dev": true }, "node_modules/lua-wasm-bindings": { "version": "0.3.1", @@ -9120,14 +9124,14 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz", - "integrity": "sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", + "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/type-utils": "5.35.1", - "@typescript-eslint/utils": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/type-utils": "5.36.1", + "@typescript-eslint/utils": "5.36.1", "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", "ignore": "^5.2.0", @@ -9137,52 +9141,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.35.1.tgz", - "integrity": "sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", + "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/typescript-estree": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz", - "integrity": "sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", + "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/visitor-keys": "5.35.1" + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1" } }, "@typescript-eslint/type-utils": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz", - "integrity": "sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", + "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", "dev": true, "requires": { - "@typescript-eslint/utils": "5.35.1", + "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/utils": "5.36.1", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.35.1.tgz", - "integrity": "sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", + "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz", - "integrity": "sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", + "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", "dev": true, "requires": { - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/visitor-keys": "5.35.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/visitor-keys": "5.36.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9191,29 +9196,34 @@ } }, "@typescript-eslint/utils": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.35.1.tgz", - "integrity": "sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", + "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.35.1", - "@typescript-eslint/types": "5.35.1", - "@typescript-eslint/typescript-estree": "5.35.1", + "@typescript-eslint/scope-manager": "5.36.1", + "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/typescript-estree": "5.36.1", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.35.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz", - "integrity": "sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g==", + "version": "5.36.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", + "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.35.1", + "@typescript-eslint/types": "5.36.1", "eslint-visitor-keys": "^3.3.0" } }, + "@typescript-to-lua/language-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", + "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + }, "acorn": { "version": "8.8.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", @@ -9224,7 +9234,8 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true + "dev": true, + "requires": {} }, "acorn-walk": { "version": "8.2.0", @@ -11683,7 +11694,8 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true + "dev": true, + "requires": {} }, "jest-regex-util": { "version": "28.0.2", @@ -12185,9 +12197,9 @@ } }, "lua-types": { - "version": "2.12.2", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.12.2.tgz", - "integrity": "sha512-E9TfcaJ01YW6XrnXhdw9dvO495wkuXRfFJsWNfj/ZTvWrbloWQ0eNnGUkQ8OW/jaJCczJXuT9tW7wdtqL0sc+A==", + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", + "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==", "dev": true }, "lua-wasm-bindings": { diff --git a/package.json b/package.json index e3e3df7c5..847e0cea7 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,7 @@ "dist/**/*.js", "dist/**/*.lua", "dist/**/*.ts", - "dist/lualib/**/*.json", - "language-extensions/**/*.ts" + "dist/lualib/**/*.json" ], "main": "dist/index.js", "types": "dist/index.d.ts", @@ -46,6 +45,7 @@ "typescript": "~4.8.2" }, "dependencies": { + "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", "resolve": "^1.15.1", "source-map": "^0.7.3" @@ -56,8 +56,8 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.35.1", - "@typescript-eslint/parser": "^5.35.1", + "@typescript-eslint/eslint-plugin": "^5.36.1", + "@typescript-eslint/parser": "^5.36.1", "eslint": "^8.23.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^26.8.7", @@ -65,7 +65,7 @@ "javascript-stringify": "^2.0.1", "jest": "^28.1.3", "jest-circus": "^29.0.1", - "lua-types": "^2.12.2", + "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", "ts-jest": "^28.0.8", From 9392c7e243b83d7bc05f6b085a44254a0394e6c4 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 4 Sep 2022 17:57:48 +0200 Subject: [PATCH 536/764] Fix require resolve (#1346) * Fixed missed require patterns for module resolution * fix bug with mixed quotes --- src/transpilation/resolve.ts | 6 +++--- test/unit/modules/resolution.spec.ts | 31 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index f0037c249..f8458fa49 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -304,11 +304,11 @@ function isBuildModeLibrary(program: ts.Program) { function findRequiredPaths(code: string): string[] { // Find all require("") paths in a lua code string const paths: string[] = []; - const pattern = /(^|\s|;|=|\()require\("(.+?)"\)/g; + const pattern = /(^|\s|;|=|\()require\s*\(?(["|'])(.+?)\2\)?/g; // eslint-disable-next-line @typescript-eslint/ban-types let match: RegExpExecArray | null; while ((match = pattern.exec(code))) { - paths.push(match[2]); + paths.push(match[3]); } return paths; @@ -321,7 +321,7 @@ function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newR const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); file.code = file.code.replace( - new RegExp(`(^|\\s|;|=|\\()require\\("${escapedRequire}"\\)`), + new RegExp(`(^|\\s|;|=|\\()require\\s*\\(?["|']${escapedRequire}["|']\\)?`), `$1require("${requirePath}")` ); } diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index b2c7194b5..26c147c68 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -87,6 +87,37 @@ test("doesn't resolve paths out of root dir", () => { .expectDiagnosticsToMatchSnapshot([couldNotResolveRequire.code]); }); +test("resolves non-standard requires", () => { + const { transpiledFiles } = util.testModule` + export * from "./externalLua"; + ` + .addExtraFile("externalLua.d.ts", "export const foo = 3;") + .addExtraFile( + "externalLua.lua", + ` + require("requiredLuaFile1") -- standard + require('requiredLuaFile2') -- single quote + require'requiredLuaFile3' -- no parentheses + require"requiredLuaFile4" -- no parentheses double quote + require "requiredLuaFile5" -- no parentheses and space + require "requiredLua'File6" -- no parentheses and space + require 'requiredLua"File7' -- no parentheses and space + ` + ) + .addExtraFile("requiredLuaFile1.lua", "") + .addExtraFile("requiredLuaFile2.lua", "") + .addExtraFile("requiredLuaFile3.lua", "") + .addExtraFile("requiredLuaFile4.lua", "") + .addExtraFile("requiredLuaFile5.lua", "") + .addExtraFile("requiredLua'File6.lua", "") + .addExtraFile('requiredLua"File7.lua', "") + .expectToHaveNoDiagnostics() + .getLuaResult(); + + // Expect main.lua, externalLua.lua and all 7 required lua files in there + expect(transpiledFiles.map(f => f.outPath)).toHaveLength(9); +}); + test.each([ { declarationStatement: ` From b508afdbd364f14f42327ae43b750ba18c5f5d5f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Sep 2022 18:10:12 +0200 Subject: [PATCH 537/764] CHANGELOG.md 1.10.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ffd37a4c..18f95e0d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.10.0 + +- **[Breaking]** Upgraded TypeScript to 4.8. +- **[Breaking]** Changed how language-extensions are distributed, you should now put `"types": ["@typescript-to-lua/language-extensions"]` in your tsconfig.json (instead of "typescript-to-lua/..."). +- Added support for **Lua 5.0**, thanks for the effort @YoRyan! +- Added support for TypeScript 4.7 [instantiation expressions](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-7.html#instantiation-expressions). +- Fixed a bug causing some `require` uses not being recognized my module resolution, leading to missing files in the output. + ## 1.9.0 - Added a warning when trying to use a type in a condition that can never be false in Lua, such as numbers or strings. (Only when `strictNullChecks` is enabled.) From b345e86484e46f619fbd67dc0c1e9ab66b16e126 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Sep 2022 18:17:58 +0200 Subject: [PATCH 538/764] 1.10.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e02084d6c..5966e39eb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.9.0", + "version": "1.10.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.9.0", + "version": "1.10.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 847e0cea7..7eed16ead 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.9.0", + "version": "1.10.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From a2219728eef64d346b17941697996ab8c9e27624 Mon Sep 17 00:00:00 2001 From: Ryan Young Date: Sat, 17 Sep 2022 08:18:18 -0700 Subject: [PATCH 539/764] fix(5.0): bad unpack() call in SparseArraySpread (#1347) --- src/lualib/5.0/SparseArraySpread.ts | 3 ++- src/lualib/5.0/Unpack.ts | 17 ++++++++++++++++- src/lualib/declarations/tstl.d.ts | 3 --- src/lualib/declarations/universal/unpack.d.ts | 4 ++++ 4 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 src/lualib/declarations/universal/unpack.d.ts diff --git a/src/lualib/5.0/SparseArraySpread.ts b/src/lualib/5.0/SparseArraySpread.ts index e404bac47..9a11f3cc9 100644 --- a/src/lualib/5.0/SparseArraySpread.ts +++ b/src/lualib/5.0/SparseArraySpread.ts @@ -1,5 +1,6 @@ import { __TS__SparseArray } from "./SparseArray"; +import { __TS__Unpack } from "./Unpack"; export function __TS__SparseArraySpread(this: void, sparseArray: __TS__SparseArray): LuaMultiReturn { - return unpack(sparseArray, 1, sparseArray.sparseLength); + return __TS__Unpack(sparseArray, 1, sparseArray.sparseLength); } diff --git a/src/lualib/5.0/Unpack.ts b/src/lualib/5.0/Unpack.ts index 6d1ef8edd..a84416233 100644 --- a/src/lualib/5.0/Unpack.ts +++ b/src/lualib/5.0/Unpack.ts @@ -1 +1,16 @@ -export const __TS__Unpack = unpack; +/** @noSelfInFile */ + +// We're not interested in emulating all of the behaviors of unpack() from Lua +// 5.1, just the ones needed by other parts of lualib. +export function __TS__Unpack(list: T[], i: number, j?: number): LuaMultiReturn { + if (i === 1 && j === undefined) { + return unpack(list); + } else { + j ??= list.length; + const slice: T[] = []; + for (let n = i; n <= j; n++) { + slice[n - i] = list[n - 1]; // We don't want to add 1 to the index into list. + } + return $multi(...slice); + } +} diff --git a/src/lualib/declarations/tstl.d.ts b/src/lualib/declarations/tstl.d.ts index 90a3283ef..9de44be80 100644 --- a/src/lualib/declarations/tstl.d.ts +++ b/src/lualib/declarations/tstl.d.ts @@ -18,9 +18,6 @@ interface LuaClassInstance extends LuaMetatable { constructor: LuaClass; } -// Declare unpack for versions that have it instead of table.unpack -declare const unpack: typeof table.unpack | undefined; - // Declare math atan2 for versions that have it instead of math.atan declare namespace math { const atan2: typeof atan; diff --git a/src/lualib/declarations/universal/unpack.d.ts b/src/lualib/declarations/universal/unpack.d.ts new file mode 100644 index 000000000..c199c09df --- /dev/null +++ b/src/lualib/declarations/universal/unpack.d.ts @@ -0,0 +1,4 @@ +/** @noSelfInFile */ + +// Declare unpack for versions that have it instead of table.unpack +declare const unpack: typeof table.unpack | undefined; From fc508a83e152d4450ed48ccfafb2fb272447d4fa Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 18 Sep 2022 18:30:14 +0200 Subject: [PATCH 540/764] Relaxed warning for checking always-true conditions (#1350) --- src/transformation/utils/diagnostics.ts | 2 +- src/transformation/visitors/conditional.ts | 3 +++ test/unit/conditionals.spec.ts | 16 ++++++++++++++++ test/unit/optionalChaining.spec.ts | 2 +- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 76c9c2a49..8216ab186 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -146,7 +146,7 @@ export const annotationDeprecated = createWarningDiagnosticFactory( ); export const truthyOnlyConditionalValue = createWarningDiagnosticFactory( - "Numbers and strings will always evaluate to true in Lua. Explicitly check the value with ===." + "Only false and nil evaluate to 'false' in Lua, everything else is considered 'true'. Explicitly compare the value with ===." ); export const notAllowedOptionalAssignment = createErrorDiagnosticFactory( diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 82d214cdd..a9b7b8d1c 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -113,6 +113,9 @@ export function transformIfStatement(statement: ts.IfStatement, context: Transfo } export function checkOnlyTruthyCondition(condition: ts.Expression, context: TransformationContext) { + if (context.options.strictNullChecks === false) return; // This check is not valid if everything could implicitly be nil + if (ts.isElementAccessExpression(condition)) return; // Array index could always implicitly return nil + if (!canBeFalsy(context, context.checker.getTypeAtLocation(condition))) { context.diagnostics.push(truthyOnlyConditionalValue(condition)); } diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index ffbff9ab4..5508748bc 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -154,6 +154,15 @@ test.each(["string", "number", "string | number"])( } ); +test.each(["string", "number", "string | number"])("Warning can be disabled when strict is true (%p)", type => { + util.testFunction` + if (condition) {} + ` + .setTsHeader(`declare var condition: ${type};`) + .setOptions({ strict: true, strictNullChecks: false }) + .expectToHaveNoDiagnostics(); +}); + test.each(["string", "number", "string | number"])( "Warning when using while statement that cannot evaluate to false undefined or null (%p)", type => { @@ -187,3 +196,10 @@ test.each(["string", "number", "string | number"])( .expectToHaveDiagnostics([truthyOnlyConditionalValue.code]); } ); + +test.each(["string", "number", "string | number"])("No warning when using element index in condition (%p)", type => { + util.testExpression`condition[0] ? 1 : 0` + .setTsHeader(`declare var condition: ${type}[];`) + .setOptions({ strict: true }) + .expectToHaveNoDiagnostics(); +}); diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 234bff14c..675fc59f9 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -253,7 +253,7 @@ describe("optional chaining function calls", () => { const result = func?.(i++); ` .setOptions({ - alwaysStrict: strict, + strict, target: ScriptTarget.ES5, }) .expectToMatchJsResult(); From 6b068dcf7e9647524b225c10eadca45ceedb236a Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 18 Sep 2022 18:40:15 +0200 Subject: [PATCH 541/764] 1.10.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5966e39eb..c81232199 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.10.0", + "version": "1.10.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.10.0", + "version": "1.10.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 7eed16ead..439686e58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.10.0", + "version": "1.10.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 2ecf2bffc046d619129bbbbb18061c8df314af8c Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Thu, 17 Nov 2022 13:01:39 +0100 Subject: [PATCH 542/764] Fix Brew missing in PATH (#1367) * Fix Brew not beging in PATH Seems like the default GitHub Actions Ubuntu image had an update and brew is no longer added to PATH by default. * Properly add to path * Next try --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65a3c2637..e49dbd30f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,6 +47,8 @@ jobs: steps: - name: Lua Install run: sudo apt-get install lua5.3 luajit + - name: Add Brew to Path (Required since Nov 2022) + run: echo "/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin" >> $GITHUB_PATH - name: Glow Install run: brew install glow # Checkout master & commit From 137d8cb502e719f2c925075effca739520c5eeaa Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 17 Nov 2022 13:21:42 -0800 Subject: [PATCH 543/764] Add support for Typescript 4.9 (#1365) * Update typescript dependency * Remove test cases which are now TS errors * Remove deprecated API usages * Add support for satisfies expressions * Cleanup issues found by code analysis * Fix prettier --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- src/LuaAST.ts | 3 ++- src/LuaPrinter.ts | 6 +++--- src/cli/parse.ts | 2 +- src/lualib/ParseInt.ts | 6 +++--- src/lualib/SetDescriptor.ts | 3 +-- src/transformation/context/context.ts | 5 ++++- src/transformation/context/visitors.ts | 2 ++ src/transformation/utils/diagnostics.ts | 13 ------------- src/transformation/utils/export.ts | 10 ++++++++-- .../visitors/binary-expression/bit.ts | 3 +++ .../visitors/binary-expression/compound.ts | 2 +- src/transformation/visitors/class/index.ts | 2 +- src/transformation/visitors/class/utils.ts | 6 +++--- src/transformation/visitors/template.ts | 2 +- src/transformation/visitors/typescript.ts | 1 + src/transpilation/utils.ts | 2 +- src/typescript-internal.d.ts | 2 -- test/unit/builtins/numbers.spec.ts | 2 -- test/unit/expressions.spec.ts | 7 +++++++ 21 files changed, 52 insertions(+), 47 deletions(-) diff --git a/package-lock.json b/package-lock.json index c81232199..e1293fd62 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,13 +37,13 @@ "prettier": "^2.3.2", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", - "typescript": "~4.8.2" + "typescript": "~4.9.3" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.8.2" + "typescript": "~4.9.3" } }, "node_modules/@ampproject/remapping": { @@ -7302,9 +7302,9 @@ } }, "node_modules/typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -13033,9 +13033,9 @@ "dev": true }, "typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", + "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 439686e58..fbe619c37 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.8.2" + "typescript": "~4.9.3" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", @@ -70,6 +70,6 @@ "prettier": "^2.3.2", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", - "typescript": "~4.8.2" + "typescript": "~4.9.3" } } diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 698534d9e..2bfa16c18 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -5,7 +5,7 @@ // because we don't create the AST from text import * as ts from "typescript"; -import { LuaLibFeature } from "./transformation/utils/lualib"; +import { LuaLibFeature } from "./LuaLib"; import { castArray } from "./utils"; export enum SyntaxKind { @@ -816,6 +816,7 @@ export function createTableIndexExpression( } export type AssignmentLeftHandSideExpression = Identifier | TableIndexExpression; + export function isAssignmentLeftHandSideExpression(node: Node): node is AssignmentLeftHandSideExpression { return isIdentifier(node) || isTableIndexExpression(node); } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index ab2d373da..757cb23de 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -3,7 +3,7 @@ import { Mapping, SourceMapGenerator, SourceNode } from "source-map"; import * as ts from "typescript"; import { CompilerOptions, isBundleEnabled, LuaLibImportKind, LuaTarget } from "./CompilerOptions"; import * as lua from "./LuaAST"; -import { loadInlineLualibFeatures, LuaLibFeature, loadImportedLualibFeatures } from "./LuaLib"; +import { loadImportedLualibFeatures, loadInlineLualibFeatures, LuaLibFeature } from "./LuaLib"; import { isValidLuaIdentifier, shouldAllowUnicode } from "./transformation/utils/safe-names"; import { EmitHost, getEmitPath } from "./transpilation"; import { intersperse, normalizeSlashes } from "./utils"; @@ -899,9 +899,9 @@ export class LuaPrinter { map.addMapping(currentMapping); } - for (const chunk of sourceNode.children) { + for (const chunk of sourceNode.children as SourceChunk[]) { if (typeof chunk === "string") { - const lines = (chunk as string).split("\n"); + const lines = chunk.split("\n"); if (lines.length > 1) { generatedLine += lines.length - 1; generatedColumn = 0; diff --git a/src/cli/parse.ts b/src/cli/parse.ts index a49510780..ca4f039ad 100644 --- a/src/cli/parse.ts +++ b/src/cli/parse.ts @@ -147,7 +147,7 @@ function updateParsedCommandLine(parsedCommandLine: ts.ParsedCommandLine, args: if (!args[i].startsWith("-")) continue; const isShorthand = !args[i].startsWith("--"); - const argumentName = args[i].substr(isShorthand ? 1 : 2); + const argumentName = args[i].substring(isShorthand ? 1 : 2); const option = optionDeclarations.find(option => { if (option.name.toLowerCase() === argumentName.toLowerCase()) return true; if (isShorthand && option.aliases) { diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index 2e1081a86..f6129f1df 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -10,8 +10,8 @@ export function __TS__ParseInt(this: void, numberString: string, base?: number): if (hexMatch) { base = 16; numberString = __TS__Match(hexMatch, "-")[0] - ? "-" + numberString.substr(hexMatch.length) - : numberString.substr(hexMatch.length); + ? "-" + numberString.substring(hexMatch.length) + : numberString.substring(hexMatch.length); } } @@ -22,7 +22,7 @@ export function __TS__ParseInt(this: void, numberString: string, base?: number): // Calculate string match pattern to use const allowedDigits = - base <= 10 ? parseIntBasePattern.substring(0, base) : parseIntBasePattern.substr(0, 10 + 2 * (base - 10)); + base <= 10 ? parseIntBasePattern.substring(0, base) : parseIntBasePattern.substring(0, 10 + 2 * (base - 10)); const pattern = `^%s*(-?[${allowedDigits}]*)`; // Try to parse with Lua tonumber diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 11c435162..1646ca7bd 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -73,8 +73,7 @@ export function __TS__SetDescriptor( if (value !== undefined) rawset(target, key, undefined); if (!rawget(metatable, "_descriptors")) metatable._descriptors = {}; - const descriptor = __TS__CloneDescriptor(desc); - metatable._descriptors[key] = descriptor; + metatable._descriptors[key] = __TS__CloneDescriptor(desc); metatable.__index = descriptorIndex; metatable.__newindex = descriptorNewIndex; } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 8fda0bc23..4ee8c04a5 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -65,7 +65,10 @@ export class TransformationContext { /** @internal */ public transformNodeRaw(node: ts.Node, isExpression?: boolean) { // TODO: Move to visitors? - if (node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword)) { + if ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword) + ) { return []; } diff --git a/src/transformation/context/visitors.ts b/src/transformation/context/visitors.ts index fff7441e5..429cce1b4 100644 --- a/src/transformation/context/visitors.ts +++ b/src/transformation/context/visitors.ts @@ -61,6 +61,7 @@ interface NodesBySyntaxKind { [ts.SyntaxKind.AsExpression]: ts.AsExpression; [ts.SyntaxKind.NonNullExpression]: ts.NonNullExpression; [ts.SyntaxKind.MetaProperty]: ts.MetaProperty; + [ts.SyntaxKind.SatisfiesExpression]: ts.SatisfiesExpression; [ts.SyntaxKind.TemplateSpan]: ts.TemplateSpan; [ts.SyntaxKind.SemicolonClassElement]: ts.SemicolonClassElement; [ts.SyntaxKind.Block]: ts.Block; @@ -148,6 +149,7 @@ export type VisitorResult = T extends ExpressionLikeNode export type Visitor = FunctionVisitor | ObjectVisitor; export type FunctionVisitor = (node: T, context: TransformationContext) => VisitorResult; + export interface ObjectVisitor { transform: FunctionVisitor; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8216ab186..94f7781de 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -119,12 +119,6 @@ export const invalidMultiFunctionReturnType = createErrorDiagnosticFactory( "The $multi function cannot be cast to a non-LuaMultiReturn type." ); -export const invalidMultiTypeToNonArrayLiteral = createErrorDiagnosticFactory("Expected an array literal."); - -export const invalidMultiTypeToEmptyPatternOrArrayLiteral = createErrorDiagnosticFactory( - "There must be one or more elements specified here." -); - export const invalidMultiReturnAccess = createErrorDiagnosticFactory( "The LuaMultiReturn type can only be accessed via an element access expression of a numeric type." ); @@ -132,13 +126,6 @@ export const invalidMultiReturnAccess = createErrorDiagnosticFactory( export const invalidCallExtensionUse = createErrorDiagnosticFactory( "This function must be called directly and cannot be referred to." ); - -export const annotationRemoved = createErrorDiagnosticFactory( - (kind: AnnotationKind) => - `'@${kind}' has been removed and will no longer have any effect.` + - `See https://typescripttolua.github.io/docs/advanced/compiler-annotations#${kind.toLowerCase()} for more information.` -); - export const annotationDeprecated = createWarningDiagnosticFactory( (kind: AnnotationKind) => `'@${kind}' is deprecated and will be removed in a future update. Please update your code before upgrading to the next release, otherwise your project will no longer compile. ` + diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index fafc26d86..a7e9db909 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -7,11 +7,17 @@ import { getSymbolInfo } from "./symbols"; import { findFirstNodeAbove } from "./typescript"; export function hasDefaultExportModifier(node: ts.Node): boolean { - return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword); + return ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.DefaultKeyword) === true + ); } export function hasExportModifier(node: ts.Node): boolean { - return (node.modifiers ?? []).some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword); + return ( + ts.canHaveModifiers(node) && + node.modifiers?.some(modifier => modifier.kind === ts.SyntaxKind.ExportKeyword) === true + ); } export const createDefaultExportStringLiteral = (original?: ts.Node): lua.StringLiteral => diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index 14ce4bdef..79e9c1f3c 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -49,6 +49,7 @@ function transformBitOperatorToLuaOperator( return lua.SyntaxKind.BitwiseLeftShiftOperator; case ts.SyntaxKind.GreaterThanGreaterThanToken: context.diagnostics.push(unsupportedRightShiftOperator(node)); + return lua.SyntaxKind.BitwiseRightShiftOperator; case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: return lua.SyntaxKind.BitwiseRightShiftOperator; } @@ -66,6 +67,7 @@ export function transformBinaryBitOperation( case LuaTarget.Lua50: case LuaTarget.Lua51: context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); + return transformBinaryBitLibOperation(node, left, right, operator, "bit"); case LuaTarget.LuaJIT: return transformBinaryBitLibOperation(node, left, right, operator, "bit"); @@ -111,6 +113,7 @@ export function transformUnaryBitOperation( case LuaTarget.Lua50: case LuaTarget.Lua51: context.diagnostics.push(unsupportedForTarget(node, "Bitwise operations", context.luaTarget)); + return transformUnaryBitLibOperation(node, expression, operator, "bit"); case LuaTarget.LuaJIT: return transformUnaryBitLibOperation(node, expression, operator, "bit"); diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 44c492505..a8180e78b 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -3,7 +3,7 @@ import * as lua from "../../../LuaAST"; import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; -import { transformBinaryOperation } from "../binary-expression"; +import { transformBinaryOperation } from "./index"; import { transformAssignmentWithRightPrecedingStatements } from "./assignments"; function isLuaExpressionWithSideEffect(expression: lua.Expression) { diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 68adcab39..5955d6e1f 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -116,7 +116,7 @@ function transformClassLikeDeclaration( // Generate a constructor if none was defined in a base class const constructorResult = transformConstructorDeclaration( context, - ts.factory.createConstructorDeclaration([], [], [], ts.factory.createBlock([], true)), + ts.factory.createConstructorDeclaration([], [], ts.factory.createBlock([], true)), localClassName, instanceFields, classDeclaration diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index 8708a54fb..d5b960662 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,12 +1,12 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; -export function isStaticNode(node: ts.Node): boolean { - return (node.modifiers ?? []).some(m => m.kind === ts.SyntaxKind.StaticKeyword); +export function isStaticNode(node: ts.HasModifiers): boolean { + return node.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) === true; } export function getExtendsClause(node: ts.ClassLikeDeclarationBase): ts.HeritageClause | undefined { - return (node.heritageClauses ?? []).find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); + return node.heritageClauses?.find(clause => clause.token === ts.SyntaxKind.ExtendsKeyword); } export function getExtendedNode(node: ts.ClassLikeDeclarationBase): ts.ExpressionWithTypeArguments | undefined { diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index 5f949adb1..bfad88057 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; import { ContextType, getDeclarationContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; -import { isStringType } from "../utils/typescript/types"; +import { isStringType } from "../utils/typescript"; import { transformArguments, transformContextualCallExpression } from "./call"; import { transformOrderedExpressions } from "./expression-list"; diff --git a/src/transformation/visitors/typescript.ts b/src/transformation/visitors/typescript.ts index ddd319381..0d9f8a8c1 100644 --- a/src/transformation/visitors/typescript.ts +++ b/src/transformation/visitors/typescript.ts @@ -21,6 +21,7 @@ export const typescriptVisitors: Visitors = { [ts.SyntaxKind.NonNullExpression]: (node, context) => context.transformExpression(node.expression), [ts.SyntaxKind.ExpressionWithTypeArguments]: (node, context) => context.transformExpression(node.expression), + [ts.SyntaxKind.SatisfiesExpression]: (node, context) => context.transformExpression(node.expression), [ts.SyntaxKind.AsExpression]: transformAssertionExpression, [ts.SyntaxKind.TypeAssertionExpression]: transformAssertionExpression, [ts.SyntaxKind.NotEmittedStatement]: () => undefined, diff --git a/src/transpilation/utils.ts b/src/transpilation/utils.ts index cef3af310..ce03fd854 100644 --- a/src/transpilation/utils.ts +++ b/src/transpilation/utils.ts @@ -40,7 +40,7 @@ export function resolvePlugin( kind: string, optionName: string, basedir: string, - query: string, + query: unknown, importName = "default" ): { error?: ts.Diagnostic; result?: unknown } { if (typeof query !== "string") { diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 8d85b9374..afcf45685 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -35,8 +35,6 @@ declare module "typescript" { parent?: Symbol; } - function getObjectFlags(type: Type): ObjectFlags; - function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; export type OuterExpression = diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index ab7e332a9..f3f0bb9b9 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -1,8 +1,6 @@ import * as util from "../../util"; test.each([ - "NaN === NaN", - "NaN !== NaN", "NaN + NaN", "NaN - NaN", "NaN * NaN", diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 2aec6a6f2..46ca2f7bd 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -173,6 +173,13 @@ test("Typescript 4.7 instantiation expression", () => { `.expectToMatchJsResult(); }); +test("Typescript 4.9 satisfies expression", () => { + util.testFunction` + const foo = { a: 1 } satisfies { a: number }; + return foo.a; + `.expectToMatchJsResult(); +}); + test.each([ '"foobar"', "17", From df6b4d0e85e2e1057a7bc3324dae486ea7262410 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 18 Nov 2022 19:31:50 +0100 Subject: [PATCH 544/764] Print resolver errors when tstlVerbose is enabled (#1369) --- src/transpilation/resolve.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index f8458fa49..fb4bb2e59 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -161,8 +161,12 @@ class ResolutionContext { try { const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); if (resolveResult) return resolveResult; - } catch (e) { + } catch (e: any) { // resolveSync errors if it fails to resolve + if (this.options.tstlVerbose && e.details) { + // Output resolver log + console.log(e.details); + } } return undefined; From a6d72b02510405701b8f275d05dc862196641bec Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 18 Nov 2022 21:11:30 +0100 Subject: [PATCH 545/764] Fix unsafe name default export (#1368) * Fix unsafe name default export * Nicely unpack preceding statements * Make functional tests instead of snapshots --- src/transformation/visitors/class/index.ts | 10 +++++-- test/unit/identifiers.spec.ts | 32 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 5955d6e1f..4235c722d 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -23,13 +23,17 @@ import { createMethodDecoratingExpression, transformMethodDeclaration } from "./ import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; import { LuaTarget } from "../../../CompilerOptions"; +import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { - const left = createDefaultExportExpression(declaration); - const right = transformClassAsExpression(declaration, context); - return [lua.createAssignmentStatement(left, right, declaration)]; + // Class declaration including assignment to ____exports.default are in preceding statements + const [precedingStatements] = transformInPrecedingStatementScope(context, () => { + transformClassAsExpression(declaration, context); + return []; + }); + return precedingStatements; } const { statements } = transformClassLikeDeclaration(declaration, context); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index b5b627b4d..e3acf8530 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -285,6 +285,38 @@ describe("unicode identifiers in supporting environments (luajit)", () => { }); }); +test("unicode export class", () => { + util.testModule` + import { 你好 } from "./utfclass"; + export const result = new 你好().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); +}); + +test("unicode export default class", () => { + util.testModule` + import c from "./utfclass"; + export const result = new c().hello(); + ` + .addExtraFile( + "utfclass.ts", + `export default class 你好 { + hello() { + return "你好"; + } + }` + ) + .expectToEqual({ result: "你好" }); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { util.testFunction` From 10211e00e5b9c0f87f78f53f88b0dcbaa9cd1375 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 18 Nov 2022 21:22:20 +0100 Subject: [PATCH 546/764] CHANGELOG.md 1.11.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 18f95e0d4..1c281595b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.11.0 + +- **[Breaking]** Upgraded TypeScript to 4.9. +- `--tstlVerbose` now prints more resolver output when failing to resolve Lua sources. +- Fixed a bug breaking default exported classes with unicode names +- Relaxed conditions for the always-true warning to false positives. + ## 1.10.0 - **[Breaking]** Upgraded TypeScript to 4.8. From 9244f54b23d480307d3fa7f8c2da793d7a43e9be Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 18 Nov 2022 21:30:52 +0100 Subject: [PATCH 547/764] 1.11.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e1293fd62..626c9775d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.10.1", + "version": "1.11.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.10.1", + "version": "1.11.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index fbe619c37..9ced87c4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.10.1", + "version": "1.11.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 74a404a1dcadd737c5114bc62c07dcfc9ae5bcde Mon Sep 17 00:00:00 2001 From: Ryan Young Date: Mon, 28 Nov 2022 12:08:54 -0800 Subject: [PATCH 548/764] 5.0: Emulate % with native math.mod() (#1370) * refactor(5.0): emulate modulo with native math.mod() * refactor(5.0): remove the modulo lualib feature altogether --- src/LuaLib.ts | 1 - src/lualib/Modulo50.ts | 5 ----- src/transformation/visitors/binary-expression/index.ts | 3 ++- 3 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 src/lualib/Modulo50.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 2ab5d33ba..4e4c8008a 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -52,7 +52,6 @@ export enum LuaLibFeature { MathAtan2 = "MathAtan2", MathModf = "MathModf", MathSign = "MathSign", - Modulo50 = "Modulo50", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", diff --git a/src/lualib/Modulo50.ts b/src/lualib/Modulo50.ts deleted file mode 100644 index 4b9729436..000000000 --- a/src/lualib/Modulo50.ts +++ /dev/null @@ -1,5 +0,0 @@ -/** @noSelfInFile */ - -export function __TS__Modulo50(a: number, b: number): number { - return a - Math.floor(a / b) * b; -} diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index 3b5521490..e02615be7 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -70,7 +70,8 @@ function transformBinaryOperationWithNoPrecedingStatements( } if (operator === ts.SyntaxKind.PercentToken && context.luaTarget === LuaTarget.Lua50) { - return transformLuaLibFunction(context, LuaLibFeature.Modulo50, node, left, right); + const mathMod = lua.createTableIndexExpression(lua.createIdentifier("math"), lua.createStringLiteral("mod")); + return lua.createCallExpression(mathMod, [left, right], node); } let luaOperator = simpleOperatorsToLua[operator]; From 893791bcb73648fc0e278934dc8b9037b4d13bba Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 28 Nov 2022 21:19:57 +0100 Subject: [PATCH 549/764] 1.11.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 626c9775d..4a3344cc1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.11.0", + "version": "1.11.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.11.0", + "version": "1.11.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 9ced87c4e..400e11ea5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.11.0", + "version": "1.11.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From c9fdd5c961cb05f7426ccfd33e4d0b3fa8291829 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 12 Jan 2023 20:52:23 +0100 Subject: [PATCH 550/764] Better require search (#1379) * Manual regex to find requires while skipping strings and comments * Unit tests for find-lua-requires * Resolve require-finding and rewriting without regex * Add support for requires without parentheses * fix stray tests * Fix prettier --- src/transpilation/find-lua-requires.ts | 168 +++++++++++++++++++++++ src/transpilation/resolve.ts | 66 ++++----- test/transpile/module-resolution.spec.ts | 2 +- test/unit/find-lua-requires.spec.ts | 159 +++++++++++++++++++++ 4 files changed, 357 insertions(+), 38 deletions(-) create mode 100644 src/transpilation/find-lua-requires.ts create mode 100644 test/unit/find-lua-requires.spec.ts diff --git a/src/transpilation/find-lua-requires.ts b/src/transpilation/find-lua-requires.ts new file mode 100644 index 000000000..90be465e6 --- /dev/null +++ b/src/transpilation/find-lua-requires.ts @@ -0,0 +1,168 @@ +export interface LuaRequire { + from: number; + to: number; + requirePath: string; +} + +export function findLuaRequires(lua: string): LuaRequire[] { + return findRequire(lua, 0); +} + +function findRequire(lua: string, offset: number): LuaRequire[] { + const result = []; + + while (offset < lua.length) { + const c = lua[offset]; + if ( + c === "r" && + (offset === 0 || + isWhitespace(lua[offset - 1]) || + lua[offset - 1] === "]" || + lua[offset - 1] === "(" || + lua[offset - 1] === "[") + ) { + const m = matchRequire(lua, offset); + if (m.matched) { + offset = m.match.to + 1; + result.push(m.match); + } else { + offset = m.end; + } + } else if (c === '"' || c === "'") { + offset = readString(lua, offset, c).offset; // Skip string and surrounding quotes + } else if (c === "-" && offset + 1 < lua.length && lua[offset + 1] === "-") { + offset = skipComment(lua, offset); + } else { + offset++; + } + } + + return result; +} + +type MatchResult = { matched: true; match: T } | { matched: false; end: number }; + +function matchRequire(lua: string, offset: number): MatchResult { + const start = offset; + for (const c of "require") { + if (offset > lua.length) { + return { matched: false, end: offset }; + } + + if (lua[offset] !== c) { + return { matched: false, end: offset }; + } + offset++; + } + + offset = skipWhitespace(lua, offset); + + let hasParentheses = false; + + if (offset > lua.length) { + return { matched: false, end: offset }; + } else { + if (lua[offset] === "(") { + hasParentheses = true; + offset++; + offset = skipWhitespace(lua, offset); + } else if (lua[offset] === '"' || lua[offset] === "'") { + // require without parentheses + } else { + // otherwise fail match + return { matched: false, end: offset }; + } + } + + if (offset > lua.length || (lua[offset] !== '"' && lua[offset] !== "'")) { + return { matched: false, end: offset }; + } + + const { value: requireString, offset: offsetAfterString } = readString(lua, offset, lua[offset]); + offset = offsetAfterString; // Skip string and surrounding quotes + + if (hasParentheses) { + offset = skipWhitespace(lua, offset); + + if (offset > lua.length || lua[offset] !== ")") { + return { matched: false, end: offset }; + } + + offset++; + } + + return { matched: true, match: { from: start, to: offset - 1, requirePath: requireString } }; +} + +function readString(lua: string, offset: number, delimiter: string): { value: string; offset: number } { + expect(lua, offset, delimiter); + offset++; + + let start = offset; + let result = ""; + + let escaped = false; + while (offset < lua.length && (lua[offset] !== delimiter || escaped)) { + if (lua[offset] === "\\" && !escaped) { + escaped = true; + } else { + if (lua[offset] === delimiter) { + result += lua.slice(start, offset - 1); + start = offset; + } + escaped = false; + } + + offset++; + } + + if (offset < lua.length) { + expect(lua, offset, delimiter); + } + + result += lua.slice(start, offset); + return { value: result, offset: offset + 1 }; +} + +function skipWhitespace(lua: string, offset: number): number { + while (offset < lua.length && isWhitespace(lua[offset])) { + offset++; + } + return offset; +} + +function isWhitespace(c: string): boolean { + return c === " " || c === "\t" || c === "\r" || c === "\n"; +} + +function skipComment(lua: string, offset: number): number { + expect(lua, offset, "-"); + expect(lua, offset + 1, "-"); + offset += 2; + + if (offset + 1 < lua.length && lua[offset] === "[" && lua[offset + 1] === "[") { + return skipMultiLineComment(lua, offset); + } else { + return skipSingleLineComment(lua, offset); + } +} + +function skipMultiLineComment(lua: string, offset: number): number { + while (offset < lua.length && !(lua[offset] === "]" && lua[offset - 1] === "]")) { + offset++; + } + return offset + 1; +} + +function skipSingleLineComment(lua: string, offset: number): number { + while (offset < lua.length && lua[offset] !== "\n") { + offset++; + } + return offset + 1; +} + +function expect(lua: string, offset: number, char: string) { + if (lua[offset] !== char) { + throw new Error(`Expected ${char} at position ${offset} but found ${lua[offset]}`); + } +} diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index fb4bb2e59..c7ea38dd1 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -8,6 +8,7 @@ import { getEmitPathRelativeToOutDir, getProjectRoot, getSourceDir } from "./tra import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; import { BuildMode, CompilerOptions } from "../CompilerOptions"; +import { findLuaRequires, LuaRequire } from "./find-lua-requires"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], @@ -40,12 +41,13 @@ class ResolutionContext { if (this.resolvedFiles.has(file.fileName)) return; this.resolvedFiles.set(file.fileName, file); - for (const required of findRequiredPaths(file.code)) { + // Do this backwards so the replacements do not mess with the positions of the previous requires + for (const required of findLuaRequires(file.code).reverse()) { // Do not resolve noResolution paths - if (required.startsWith("@NoResolution:")) { + if (required.requirePath.startsWith("@NoResolution:")) { // Remove @NoResolution prefix if not building in library mode if (!isBuildModeLibrary(this.program)) { - const path = required.replace("@NoResolution:", ""); + const path = required.requirePath.replace("@NoResolution:", ""); replaceRequireInCode(file, required, path); replaceRequireInSourceMap(file, required, path); } @@ -58,25 +60,27 @@ class ResolutionContext { } } - public resolveImport(file: ProcessedFile, required: string): void { + public resolveImport(file: ProcessedFile, required: LuaRequire): void { // Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages - if (required === "lualib_bundle") { + if (required.requirePath === "lualib_bundle") { this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" }); return; } - if (this.noResolvePaths.has(required)) { + if (this.noResolvePaths.has(required.requirePath)) { if (this.options.tstlVerbose) { - console.log(`Skipping module resolution of ${required} as it is in the tsconfig noResolvePaths.`); + console.log( + `Skipping module resolution of ${required.requirePath} as it is in the tsconfig noResolvePaths.` + ); } return; } - const dependencyPath = this.resolveDependencyPath(file, required); + const dependencyPath = this.resolveDependencyPath(file, required.requirePath); if (!dependencyPath) return this.couldNotResolveImport(required, file); if (this.options.tstlVerbose) { - console.log(`Resolved ${required} to ${normalizeSlashes(dependencyPath)}`); + console.log(`Resolved ${required.requirePath} to ${normalizeSlashes(dependencyPath)}`); } this.processDependency(dependencyPath); @@ -110,13 +114,13 @@ class ResolutionContext { this.addAndResolveDependencies(dependency); } - private couldNotResolveImport(required: string, file: ProcessedFile): void { + private couldNotResolveImport(required: LuaRequire, file: ProcessedFile): void { const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); replaceRequireInCode(file, required, fallbackRequire); replaceRequireInSourceMap(file, required, fallbackRequire); this.diagnostics.push( - couldNotResolveRequire(required, path.relative(getProjectRoot(this.program), file.fileName)) + couldNotResolveRequire(required.requirePath, path.relative(getProjectRoot(this.program), file.fileName)) ); } @@ -305,35 +309,23 @@ function isBuildModeLibrary(program: ts.Program) { return program.getCompilerOptions().buildMode === BuildMode.Library; } -function findRequiredPaths(code: string): string[] { - // Find all require("") paths in a lua code string - const paths: string[] = []; - const pattern = /(^|\s|;|=|\()require\s*\(?(["|'])(.+?)\2\)?/g; - // eslint-disable-next-line @typescript-eslint/ban-types - let match: RegExpExecArray | null; - while ((match = pattern.exec(code))) { - paths.push(match[3]); - } - - return paths; -} - -function replaceRequireInCode(file: ProcessedFile, originalRequire: string, newRequire: string): void { +function replaceRequireInCode(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void { const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); - - // Escape special characters to prevent the regex from breaking... - const escapedRequire = originalRequire.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&"); - - file.code = file.code.replace( - new RegExp(`(^|\\s|;|=|\\()require\\s*\\(?["|']${escapedRequire}["|']\\)?`), - `$1require("${requirePath}")` - ); + file.code = file.code = + file.code.substring(0, originalRequire.from) + + `require("${requirePath}")` + + file.code.substring(originalRequire.to + 1); } -function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: string, newRequire: string): void { +function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void { const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); if (file.sourceMapNode) { - replaceInSourceMap(file.sourceMapNode, file.sourceMapNode, `"${originalRequire}"`, `"${requirePath}"`); + replaceInSourceMap( + file.sourceMapNode, + file.sourceMapNode, + `"${originalRequire.requirePath}"`, + `"${requirePath}"` + ); } } @@ -375,10 +367,10 @@ function hasSourceFileInProject(filePath: string, program: ts.Program) { } // Transform an import path to a lua require that is probably not correct, but can be used as fallback when regular resolution fails -function fallbackResolve(required: string, sourceRootDir: string, fileDir: string): string { +function fallbackResolve(required: LuaRequire, sourceRootDir: string, fileDir: string): string { return formatPathToLuaPath( path - .normalize(path.join(path.relative(sourceRootDir, fileDir), required)) + .normalize(path.join(path.relative(sourceRootDir, fileDir), required.requirePath)) .split(path.sep) .filter(s => s !== "." && s !== "..") .join(path.sep) diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 4e8f3d49b..8f8cc0230 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -411,7 +411,7 @@ test("module resolution should not rewrite @NoResolution requires in library mod }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1050 -test("module resolution should not try to resolve resolve-like functions", () => { +test("module resolution should not try to resolve require-like functions", () => { util.testModule` function custom_require(this: void, value: string) { return value; diff --git a/test/unit/find-lua-requires.spec.ts b/test/unit/find-lua-requires.spec.ts new file mode 100644 index 000000000..bb879d642 --- /dev/null +++ b/test/unit/find-lua-requires.spec.ts @@ -0,0 +1,159 @@ +import { findLuaRequires, LuaRequire } from "../../src/transpilation/find-lua-requires"; + +test("empty string", () => { + expect(findLuaRequires("")).toEqual([]); +}); + +test("can find requires", () => { + const lua = ` + require("req1") + require('req2') + local r3 = require("req3") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2", "req3"]); +}); + +test("handles requires with spacing", () => { + const lua = 'require \t ( \t "req" )'; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req"]); +}); + +test("handles requires without parentheses", () => { + const lua = 'require "req"'; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req"]); +}); + +test("has correct offsets", () => { + const lua = ` + require("req1") + require('req2') + local r3 = require("req3") + `; + const requires = findLuaRequires(lua); + expect(requires).toHaveLength(3); + expect(lua.substring(requires[0].from, requires[0].to + 1)).toBe('require("req1")'); + expect(lua.substring(requires[1].from, requires[1].to + 1)).toBe("require('req2')"); + expect(lua.substring(requires[2].from, requires[2].to + 1)).toBe('require("req3")'); +}); + +test("has correct offsets for offsets without parentheses", () => { + const lua = ` + require"req1" + require 'req2' + local r3 = require"req3" + `; + const requires = findLuaRequires(lua); + expect(requires).toHaveLength(3); + expect(lua.substring(requires[0].from, requires[0].to + 1)).toBe('require"req1"'); + expect(lua.substring(requires[1].from, requires[1].to + 1)).toBe("require 'req2'"); + expect(lua.substring(requires[2].from, requires[2].to + 1)).toBe('require"req3"'); +}); + +test("ignores requires that should not be included", () => { + const lua = ` + require("req1") + local a = "require('This should not be included')" + require('req2') + local b = 'require("This should not be included")' + require("req3") + -- require("this should not be included") + require("req4") + --[[ require("this should not be included") ]] + require("req5") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2", "req3", "req4", "req5"]); +}); + +test("non-terminated require", () => { + expect(findLuaRequires("require('abc")).toEqual([]); +}); + +describe.each(['"', "'"])("strings with delimiter %p", delimiter => { + test("escaped delimiter", () => { + const lua = ` + require(${delimiter}req1${delimiter}); + local a = ${delimiter}require(excludeThis\\${delimiter})${delimiter} + require(${delimiter}req\\${delimiter}2${delimiter}); + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", `req${delimiter}2`]); + }); + + test("multiple escaped delimiters", () => { + const lua = ` + require(${delimiter}r\\${delimiter}e.- q%\\${delimiter}1${delimiter}) + `; + expect(requirePaths(findLuaRequires(lua))).toEqual([`r${delimiter}e.- q%${delimiter}1`]); + }); + + test("handles other escaped characters", () => { + expect(requirePaths(findLuaRequires(`require(${delimiter}req\\n\\\\${delimiter})`))).toEqual(["req\\n\\\\"]); + }); + + test("handles non-delimiter quote", () => { + const oppositeDelimiter = delimiter === "'" ? '"' : "'"; + const lua = ` + require(${delimiter}req1${delimiter}); + local a = ${delimiter}require(excludeThis${oppositeDelimiter})${delimiter}; + require(${delimiter}req2${oppositeDelimiter}${delimiter}); + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", `req2${oppositeDelimiter}`]); + }); + + test("non-terminated string", () => { + const lua = ` + require(${delimiter}myRequire${delimiter}); + local a = ${delimiter}require("excludeThis") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["myRequire"]); + }); +}); + +describe("single-line comments", () => { + test("comment at end of file", () => { + expect(findLuaRequires("--")).toEqual([]); + }); + + test("require before and after comment", () => { + const lua = ` + require("req1")-- comment\nrequire("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); + + test("require before and after empty comment", () => { + const lua = ` + require("req1")--\nrequire("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); +}); + +describe("multi-line comments", () => { + test("comment at end of file", () => { + expect(findLuaRequires("--[[]]")).toEqual([]); + }); + + test("unterminated comment", () => { + expect(findLuaRequires("--[[")).toEqual([]); + }); + + test("require before and after comment", () => { + const lua = ` + require("req1")--[[ + ml comment require("this should be excluded") + ]]require("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); + + test("require before and after empty comment", () => { + const lua = ` + require("req1")--[[]]require("req2") + `; + expect(requirePaths(findLuaRequires(lua))).toEqual(["req1", "req2"]); + }); +}); + +function requirePaths(matches: LuaRequire[]): string[] { + return matches.map(m => m.requirePath); +} From 48a697b68c00db048df7fe11e15a3034cfd19d78 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 12 Jan 2023 21:03:43 +0100 Subject: [PATCH 551/764] CHANGELOG.md 1.12.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c281595b..d576bb391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.12.0 + +- Reworked how tstl detects and rewrites `require` statements during dependency resolution. This should reduce the amount of false-positive matches of require statements: require statements in string literals or comments should no longer be detected by tstl. This means require statements in string literals or comments can survive the transpiler without causing a 'could not resolve lua sources' error or getting rewritten into nonsense. +- Now using `math.mod` for Lua 5.0 modulo operations. + ## 1.11.0 - **[Breaking]** Upgraded TypeScript to 4.9. From 5a9fdfd65ad2ee506e47f8c222a1a07373c38279 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 12 Jan 2023 21:36:53 +0100 Subject: [PATCH 552/764] 1.12.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a3344cc1..a1e96684a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.11.1", + "version": "1.12.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.11.1", + "version": "1.12.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 400e11ea5..b78233e0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.11.1", + "version": "1.12.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d315218330951b9130858a49d5e8c1c90003fcb9 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 15 Jan 2023 09:34:05 -0800 Subject: [PATCH 553/764] Minimal bundle luaLibImport option (#1383) * Fix typo * Add "require-minimal" lualib_bundle option that only includes used lualib features * Update snapshot * Increase specificity of search lualib import search pattern * PR feedback * Cache lualib info by luaTarget instead of file paths --- src/CompilerOptions.ts | 3 + src/LuaLib.ts | 107 ++++++++++++++++---- src/LuaPrinter.ts | 5 +- src/lualib-build/plugin.ts | 10 +- src/transpilation/diagnostics.ts | 2 +- src/transpilation/transpiler.ts | 23 ++++- test/unit/__snapshots__/bundle.spec.ts.snap | 2 +- test/unit/builtins/loading.spec.ts | 50 +++++++-- 8 files changed, 164 insertions(+), 38 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 9acc3589d..5f740123b 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -12,12 +12,14 @@ export interface TransformerImport { after?: boolean; afterDeclarations?: boolean; type?: "program" | "config" | "checker" | "raw" | "compilerOptions"; + [option: string]: any; } export interface LuaPluginImport { name: string; import?: string; + [option: string]: any; } @@ -49,6 +51,7 @@ export enum LuaLibImportKind { None = "none", Inline = "inline", Require = "require", + RequireMinimal = "require-minimal", } export enum LuaTarget { diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 4e4c8008a..8d776fb3a 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -2,6 +2,7 @@ import * as path from "path"; import { EmitHost } from "./transpilation"; import * as lua from "./LuaAST"; import { LuaTarget } from "./CompilerOptions"; +import { getOrUpdate } from "./utils"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -109,6 +110,7 @@ export interface LuaLibFeatureInfo { dependencies?: LuaLibFeature[]; exports: string[]; } + export type LuaLibModulesInfo = Record; export function resolveLuaLibDir(luaTarget: LuaTarget) { @@ -117,27 +119,55 @@ export function resolveLuaLibDir(luaTarget: LuaTarget) { } export const luaLibModulesInfoFileName = "lualib_module_info.json"; -const luaLibModulesInfo = new Map(); +const luaLibModulesInfo = new Map(); + export function getLuaLibModulesInfo(luaTarget: LuaTarget, emitHost: EmitHost): LuaLibModulesInfo { - const lualibPath = path.join(resolveLuaLibDir(luaTarget), luaLibModulesInfoFileName); - if (!luaLibModulesInfo.has(lualibPath)) { + if (!luaLibModulesInfo.has(luaTarget)) { + const lualibPath = path.join(resolveLuaLibDir(luaTarget), luaLibModulesInfoFileName); const result = emitHost.readFile(lualibPath); if (result !== undefined) { - luaLibModulesInfo.set(lualibPath, JSON.parse(result) as LuaLibModulesInfo); + luaLibModulesInfo.set(luaTarget, JSON.parse(result) as LuaLibModulesInfo); } else { throw new Error(`Could not load lualib dependencies from '${lualibPath}'`); } } - return luaLibModulesInfo.get(lualibPath) as LuaLibModulesInfo; + return luaLibModulesInfo.get(luaTarget)!; +} + +// This caches the names of lualib exports to their LuaLibFeature, avoiding a linear search for every lookup +const lualibExportToFeature = new Map>(); + +export function getLuaLibExportToFeatureMap( + luaTarget: LuaTarget, + emitHost: EmitHost +): ReadonlyMap { + if (!lualibExportToFeature.has(luaTarget)) { + const luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost); + const map = new Map(); + for (const [feature, info] of Object.entries(luaLibModulesInfo)) { + for (const exportName of info.exports) { + map.set(exportName, feature as LuaLibFeature); + } + } + lualibExportToFeature.set(luaTarget, map); + } + + return lualibExportToFeature.get(luaTarget)!; } +const lualibFeatureCache = new Map>(); + export function readLuaLibFeature(feature: LuaLibFeature, luaTarget: LuaTarget, emitHost: EmitHost): string { - const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`); - const luaLibFeature = emitHost.readFile(featurePath); - if (luaLibFeature === undefined) { - throw new Error(`Could not load lualib feature from '${featurePath}'`); + const featureMap = getOrUpdate(lualibFeatureCache, luaTarget, () => new Map()); + if (!featureMap.has(feature)) { + const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`); + const luaLibFeature = emitHost.readFile(featurePath); + if (luaLibFeature === undefined) { + throw new Error(`Could not load lualib feature from '${featurePath}'`); + } + featureMap.set(feature, luaLibFeature); } - return luaLibFeature; + return featureMap.get(feature)!; } export function resolveRecursiveLualibFeatures( @@ -173,14 +203,9 @@ export function loadInlineLualibFeatures( luaTarget: LuaTarget, emitHost: EmitHost ): string { - let result = ""; - - for (const feature of resolveRecursiveLualibFeatures(features, luaTarget, emitHost)) { - const luaLibFeature = readLuaLibFeature(feature, luaTarget, emitHost); - result += luaLibFeature + "\n"; - } - - return result; + return resolveRecursiveLualibFeatures(features, luaTarget, emitHost) + .map(feature => readLuaLibFeature(feature, luaTarget, emitHost)) + .join("\n"); } export function loadImportedLualibFeatures( @@ -191,13 +216,13 @@ export function loadImportedLualibFeatures( const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost); const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports); + if (imports.length === 0) { + return []; + } const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [ lua.createStringLiteral("lualib_bundle"), ]); - if (imports.length === 0) { - return []; - } const luaLibId = lua.createIdentifier("____lualib"); const importStatement = lua.createVariableDeclarationStatement(luaLibId, requireCall); @@ -215,6 +240,7 @@ export function loadImportedLualibFeatures( } const luaLibBundleContent = new Map(); + export function getLuaLibBundle(luaTarget: LuaTarget, emitHost: EmitHost): string { const lualibPath = path.join(resolveLuaLibDir(luaTarget), "lualib_bundle.lua"); if (!luaLibBundleContent.has(lualibPath)) { @@ -228,3 +254,42 @@ export function getLuaLibBundle(luaTarget: LuaTarget, emitHost: EmitHost): strin return luaLibBundleContent.get(lualibPath) as string; } + +export function getLualibBundleReturn(exportedValues: string[]): string { + return `\nreturn {\n${exportedValues.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; +} + +export function buildMinimalLualibBundle( + features: Iterable, + luaTarget: LuaTarget, + emitHost: EmitHost +): string { + const code = loadInlineLualibFeatures(features, luaTarget, emitHost); + const moduleInfo = getLuaLibModulesInfo(luaTarget, emitHost); + const exports = Array.from(features).flatMap(feature => moduleInfo[feature].exports); + + return code + getLualibBundleReturn(exports); +} + +export function findUsedLualibFeatures( + luaTarget: LuaTarget, + emitHost: EmitHost, + luaContents: string[] +): Set { + const features = new Set(); + const exportToFeatureMap = getLuaLibExportToFeatureMap(luaTarget, emitHost); + + for (const lua of luaContents) { + const regex = /^local (\w+) = ____lualib\.(\w+)$/gm; + while (true) { + const match = regex.exec(lua); + if (!match) break; + const [, localName, exportName] = match; + if (localName !== exportName) continue; + const feature = exportToFeatureMap.get(exportName); + if (feature) features.add(feature); + } + } + + return features; +} diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 757cb23de..97a68fd74 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -235,7 +235,10 @@ export class LuaPrinter { const luaTarget = this.options.luaTarget ?? LuaTarget.Universal; const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require; - if (luaLibImport === LuaLibImportKind.Require && file.luaLibFeatures.size > 0) { + if ( + (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.RequireMinimal) && + file.luaLibFeatures.size > 0 + ) { // Import lualib features sourceChunks = this.printStatementArray( loadImportedLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost) diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index 4d7722d12..d301e657e 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -2,7 +2,13 @@ import { SourceNode } from "source-map"; import * as ts from "typescript"; import * as tstl from ".."; import * as path from "path"; -import { LuaLibFeature, LuaLibModulesInfo, luaLibModulesInfoFileName, resolveRecursiveLualibFeatures } from "../LuaLib"; +import { + getLualibBundleReturn, + LuaLibFeature, + LuaLibModulesInfo, + luaLibModulesInfoFileName, + resolveRecursiveLualibFeatures, +} from "../LuaLib"; import { EmitHost, ProcessedFile } from "../transpilation/utils"; import { isExportAlias, @@ -63,7 +69,7 @@ class LuaLibPlugin implements tstl.Plugin { // Concatenate lualib files into bundle with exports table and add lualib_bundle.lua to results let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLibFeature[f])).join("\n"); const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports); - lualibBundle += `\nreturn {\n${exports.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; + lualibBundle += getLualibBundleReturn(exports); result.push({ fileName: "lualib_bundle.lua", code: lualibBundle }); return diagnostics; diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 1f37f3260..348542ac5 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -51,7 +51,7 @@ export const usingLuaBundleWithInlineMightGenerateDuplicateCode = createSerialDi export const cannotBundleLibrary = createDiagnosticFactory( () => - 'Cannot bundle probjects with"buildmode": "library". Projects including the library can still bundle (which will include external library files).' + 'Cannot bundle projects with "buildmode": "library". Projects including the library can still bundle (which will include external library files).' ); export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 2f05aae64..b4a9770d2 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -1,7 +1,7 @@ import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions, isBundleEnabled, LuaTarget } from "../CompilerOptions"; -import { getLuaLibBundle } from "../LuaLib"; +import { CompilerOptions, isBundleEnabled, LuaLibImportKind, LuaTarget } from "../CompilerOptions"; +import { buildMinimalLualibBundle, findUsedLualibFeatures, getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; import { getPlugins, Plugin } from "./plugins"; @@ -123,11 +123,10 @@ export class Transpiler { if (options.tstlVerbose) { console.log("Including lualib bundle"); } - // Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua")); - const luaTarget = options.luaTarget ?? LuaTarget.Universal; - resolutionResult.resolvedFiles.unshift({ fileName, code: getLuaLibBundle(luaTarget, this.emitHost) }); + const code = this.getLuaLibBundleContent(options, resolutionResult.resolvedFiles); + resolutionResult.resolvedFiles.unshift({ fileName, code }); } let emitPlan: EmitFile[]; @@ -146,6 +145,20 @@ export class Transpiler { return { emitPlan }; } + + private getLuaLibBundleContent(options: CompilerOptions, resolvedFiles: ProcessedFile[]) { + const luaTarget = options.luaTarget ?? LuaTarget.Universal; + if (options.luaLibImport === LuaLibImportKind.RequireMinimal) { + const usedFeatures = findUsedLualibFeatures( + luaTarget, + this.emitHost, + resolvedFiles.map(f => f.code) + ); + return buildMinimalLualibBundle(usedFeatures, luaTarget, this.emitHost); + } else { + return getLuaLibBundle(luaTarget, this.emitHost); + } + } } export function getEmitPath(file: string, program: ts.Program): string { diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 20d4ec657..51d2b73b9 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -2,7 +2,7 @@ exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; -exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle probjects with\\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; +exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle projects with \\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index ac76de5a1..e4363eb8c 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -16,17 +16,53 @@ describe("luaLibImport", () => { .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) .expectToMatchJsResult(); }); -}); -test.each([tstl.LuaLibImportKind.Inline, tstl.LuaLibImportKind.None, tstl.LuaLibImportKind.Require])( - "should not include lualib without code (%p)", - luaLibImport => { - util.testModule``.setOptions({ luaLibImport }).tap(builder => expect(builder.getMainLuaCodeChunk()).toBe("")); + function testLualibOnlyHasArrayIndexOf(builder: util.TestBuilder) { + const lualibBundle = builder.getLuaResult().transpiledFiles.find(f => f.outPath.endsWith("lualib_bundle.lua"))!; + expect(lualibBundle).toBeDefined(); + expect(lualibBundle.lua).toEqual(expect.stringMatching("^local function __TS__ArrayIndexOf")); + expect(lualibBundle.lua).not.toContain("__TS__ArrayConcat"); + expect(lualibBundle.lua).not.toContain("Error"); } -); + + test("require-minimal", () => { + util.testExpression`[0].indexOf(1)` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.RequireMinimal }) + .tap(builder => expect(builder.getMainLuaCodeChunk()).toContain('require("lualib_bundle")')) + .tap(testLualibOnlyHasArrayIndexOf) + .expectToMatchJsResult(); + }); + + test("require-minimal with lualib in another file", () => { + util.testModule` + import "./other"; + ` + .setOptions({ luaLibImport: tstl.LuaLibImportKind.RequireMinimal }) + .addExtraFile( + "other.lua", + ` +local ____lualib = require("lualib_bundle") +local __TS__ArrayIndexOf = ____lualib.__TS__ArrayIndexOf +__TS__ArrayIndexOf({}, 1) + ` + ) + // note: indent matters in above code, because searching for lualib checks for start & end of line + .tap(testLualibOnlyHasArrayIndexOf) + .expectNoExecutionError(); + }); +}); + +test.each([ + tstl.LuaLibImportKind.Inline, + tstl.LuaLibImportKind.None, + tstl.LuaLibImportKind.Require, + tstl.LuaLibImportKind.RequireMinimal, +])("should not include lualib without code (%p)", luaLibImport => { + util.testModule``.setOptions({ luaLibImport }).tap(builder => expect(builder.getMainLuaCodeChunk()).toBe("")); +}); test("lualib should not include tstl header", () => { - util.testExpression`[0].push(1)`.tap(builder => + util.testExpression`[0].indexOf(1)`.tap(builder => expect(builder.getMainLuaCodeChunk()).not.toContain("Generated with") ); }); From 3d0e98dd00fb525f30a8162dbe1941eb4688e2a6 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sat, 21 Jan 2023 06:06:07 -0800 Subject: [PATCH 554/764] Simplify optional chaining expressions where possible (#1381) * Simplify optional chaining expressions where possible * Fix case when right expression with preceding statements modifies left expression * Use if statement when left side can be a boolean * use `expressionResultIsUsed` where it was extracted from * Fix duplicate call (reversion) in ArrayPush * Fix canBeFalsyWhenNotNull This shouldn't depend on strictNullChecks * Add snapshot tests to some optional chaining tests. This tests that the output statements are correct. --- src/transformation/builtins/array.ts | 5 +- src/transformation/utils/typescript/index.ts | 4 + src/transformation/utils/typescript/types.ts | 2 - .../visitors/expression-statement.ts | 11 +- src/transformation/visitors/identifier.ts | 7 +- .../visitors/optional-chaining.ts | 140 ++++++++--- src/transformation/visitors/void.ts | 4 +- .../optionalChaining.spec.ts.snap | 234 ++++++++++++++++-- test/unit/optionalChaining.spec.ts | 98 +++++++- 9 files changed, 428 insertions(+), 77 deletions(-) diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index c9074874f..22afd5b45 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -5,7 +5,7 @@ import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../visitors/call"; -import { findFirstNonOuterParent, typeAlwaysHasSomeOfFlags } from "../utils/typescript"; +import { expressionResultIsUsed, typeAlwaysHasSomeOfFlags } from "../utils/typescript"; import { moveToPrecedingTemp } from "../visitors/expression-list"; import { isUnpackCall, wrapInTable } from "../utils/lua-ast"; @@ -54,8 +54,6 @@ function transformSingleElementArrayPush( caller: lua.Expression, param: lua.Expression ): lua.Expression { - const expressionIsUsed = !ts.isExpressionStatement(findFirstNonOuterParent(node)); - const arrayIdentifier = lua.isIdentifier(caller) ? caller : moveToPrecedingTemp(context, caller); // #array + 1 @@ -65,6 +63,7 @@ function transformSingleElementArrayPush( lua.SyntaxKind.AdditionOperator ); + const expressionIsUsed = expressionResultIsUsed(node); if (expressionIsUsed) { // store length in a temp lengthExpression = moveToPrecedingTemp(context, lengthExpression); diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index dca15e00b..e5984b08f 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -32,6 +32,10 @@ export function findFirstNonOuterParent(node: ts.Node): ts.Node { return current; } +export function expressionResultIsUsed(node: ts.Expression): boolean { + return !ts.isExpressionStatement(findFirstNonOuterParent(node)); +} + export function getFirstDeclarationInFile(symbol: ts.Symbol, sourceFile: ts.SourceFile): ts.Declaration | undefined { const originalSourceFile = ts.getParseTreeNode(sourceFile) ?? sourceFile; const declarations = (symbol.getDeclarations() ?? []).filter(d => d.getSourceFile() === originalSourceFile); diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index d13a40b38..1a657d673 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -115,8 +115,6 @@ export function canBeFalsy(context: TransformationContext, type: ts.Type): boole } export function canBeFalsyWhenNotNull(context: TransformationContext, type: ts.Type): boolean { - const strictNullChecks = context.options.strict === true || context.options.strictNullChecks === true; - if (!strictNullChecks && !type.isLiteral()) return true; const falsyFlags = ts.TypeFlags.Boolean | ts.TypeFlags.BooleanLiteral | diff --git a/src/transformation/visitors/expression-statement.ts b/src/transformation/visitors/expression-statement.ts index ebc0b1600..a247fd29b 100644 --- a/src/transformation/visitors/expression-statement.ts +++ b/src/transformation/visitors/expression-statement.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; -import { FunctionVisitor, tempSymbolId, TransformationContext } from "../context"; +import { FunctionVisitor, tempSymbolId } from "../context"; import { transformBinaryExpressionStatement } from "./binary-expression"; import { transformUnaryExpressionStatement } from "./unary-expression"; @@ -15,15 +15,10 @@ export const transformExpressionStatement: FunctionVisitor(); @@ -74,12 +77,16 @@ const optionalContinuations = new WeakMap() function createOptionalContinuationIdentifier(text: string, tsOriginal: ts.Expression): ts.Identifier { const identifier = ts.factory.createIdentifier(text); ts.setOriginalNode(identifier, tsOriginal); - optionalContinuations.set(identifier, {}); + optionalContinuations.set(identifier, { + usedIdentifiers: [], + }); return identifier; } + export function isOptionalContinuation(node: ts.Node): boolean { return ts.isIdentifier(node) && optionalContinuations.has(node); } + export function getOptionalContinuationData(identifier: ts.Identifier): OptionalContinuation | undefined { return optionalContinuations.get(identifier); } @@ -90,16 +97,16 @@ export function transformOptionalChain(context: TransformationContext, node: ts. export function transformOptionalChainWithCapture( context: TransformationContext, - node: ts.OptionalChain, + tsNode: ts.OptionalChain, thisValueCapture: lua.Identifier | undefined, isDelete?: ts.DeleteExpression ): ExpressionWithThisValue { - const luaTemp = context.createTempNameForNode(node); + const luaTempName = context.createTempName("opt"); - const { expression: tsLeftExpression, chain } = flattenChain(node); + const { expression: tsLeftExpression, chain } = flattenChain(tsNode); // build temp.b.c.d - const tsTemp = createOptionalContinuationIdentifier(luaTemp.text, tsLeftExpression); + const tsTemp = createOptionalContinuationIdentifier(luaTempName, tsLeftExpression); let tsRightExpression: ts.Expression = tsTemp; for (const link of chain) { if (ts.isPropertyAccessExpression(link)) { @@ -121,18 +128,18 @@ export function transformOptionalChainWithCapture( // transform right expression first to check if thisValue capture is needed // capture and return thisValue if requested from outside let returnThisValue: lua.Expression | undefined; - const [rightPrecedingStatements, rightAssignment] = transformInPrecedingStatementScope(context, () => { - let result: lua.Expression; - if (thisValueCapture) { - ({ expression: result, thisValue: returnThisValue } = transformExpressionWithThisValueCapture( - context, - tsRightExpression, - thisValueCapture - )); - } else { - result = context.transformExpression(tsRightExpression); + const [rightPrecedingStatements, rightExpression] = transformInPrecedingStatementScope(context, () => { + if (!thisValueCapture) { + return context.transformExpression(tsRightExpression); } - return lua.createAssignmentStatement(luaTemp, result); + + const { expression: result, thisValue } = transformExpressionWithThisValueCapture( + context, + tsRightExpression, + thisValueCapture + ); + returnThisValue = thisValue; + return result; }); // transform left expression, handle thisValue if needed by rightExpression @@ -140,7 +147,8 @@ export function transformOptionalChainWithCapture( const leftThisValueTemp = lua.createIdentifier(thisValueCaptureName, undefined, tempSymbolId); let capturedThisValue: lua.Expression | undefined; - const rightContextualCall = getOptionalContinuationData(tsTemp)?.contextualCall; + const optionalContinuationData = getOptionalContinuationData(tsTemp); + const rightContextualCall = optionalContinuationData?.contextualCall; const [leftPrecedingStatements, leftExpression] = transformInPrecedingStatementScope(context, () => { let result: lua.Expression; if (rightContextualCall) { @@ -177,26 +185,78 @@ export function transformOptionalChainWithCapture( } } - // - // local temp = - // if temp ~= nil then - // - // temp = temp.b.c.d - // end - // return temp - - context.addPrecedingStatements([ - ...leftPrecedingStatements, - lua.createVariableDeclarationStatement(luaTemp, leftExpression), - lua.createIfStatement( - lua.createBinaryExpression(luaTemp, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), - lua.createBlock([...rightPrecedingStatements, rightAssignment]) - ), - ]); - return { - expression: luaTemp, - thisValue: returnThisValue, - }; + // evaluate optional chain + context.addPrecedingStatements(leftPrecedingStatements); + + // try use existing variable instead of creating new one, if possible + let leftIdentifier: lua.Identifier | undefined; + const usedLuaIdentifiers = optionalContinuationData?.usedIdentifiers; + const reuseLeftIdentifier = + usedLuaIdentifiers && + usedLuaIdentifiers.length > 0 && + lua.isIdentifier(leftExpression) && + (rightPrecedingStatements.length === 0 || !shouldMoveToTemp(context, leftExpression, tsLeftExpression)); + if (reuseLeftIdentifier) { + leftIdentifier = leftExpression; + for (const usedIdentifier of usedLuaIdentifiers) { + usedIdentifier.text = leftIdentifier.text; + } + } else { + leftIdentifier = lua.createIdentifier(luaTempName, undefined, tempSymbolId); + context.addPrecedingStatements(lua.createVariableDeclarationStatement(leftIdentifier, leftExpression)); + } + + if (!expressionResultIsUsed(tsNode) || isDelete) { + // if left ~= nil then + // + // + // end + + const innerExpression = wrapInStatement(rightExpression); + const innerStatements = rightPrecedingStatements; + if (innerExpression) innerStatements.push(innerExpression); + + context.addPrecedingStatements( + lua.createIfStatement( + lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), + lua.createBlock(innerStatements) + ) + ); + return { expression: lua.createNilLiteral(), thisValue: returnThisValue }; + } else if ( + rightPrecedingStatements.length === 0 && + !canBeFalsyWhenNotNull(context, context.checker.getTypeAtLocation(tsLeftExpression)) + ) { + // return a && a.b + return { + expression: lua.createBinaryExpression(leftIdentifier, rightExpression, lua.SyntaxKind.AndOperator, tsNode), + thisValue: returnThisValue, + }; + } else { + let resultIdentifier: lua.Identifier; + if (!reuseLeftIdentifier) { + // reuse temp variable for output + resultIdentifier = leftIdentifier; + } else { + resultIdentifier = lua.createIdentifier(context.createTempName("opt_result"), undefined, tempSymbolId); + context.addPrecedingStatements(lua.createVariableDeclarationStatement(resultIdentifier)); + } + // if left ~= nil then + // + // result = + // end + // return result + context.addPrecedingStatements( + lua.createIfStatement( + lua.createBinaryExpression(leftIdentifier, lua.createNilLiteral(), lua.SyntaxKind.InequalityOperator), + lua.createBlock([ + ...rightPrecedingStatements, + lua.createAssignmentStatement(resultIdentifier, rightExpression), + ]) + ) + ); + return { expression: resultIdentifier, thisValue: returnThisValue }; + } } export function transformOptionalDeleteExpression( diff --git a/src/transformation/visitors/void.ts b/src/transformation/visitors/void.ts index ab5286db5..c942e859c 100644 --- a/src/transformation/visitors/void.ts +++ b/src/transformation/visitors/void.ts @@ -1,13 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { transformExpressionToStatement } from "./expression-statement"; +import { wrapInStatement } from "./expression-statement"; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void export const transformVoidExpression: FunctionVisitor = (node, context) => { // If content is a literal it is safe to replace the entire expression with nil if (!ts.isLiteralExpression(node.expression)) { - const statements = transformExpressionToStatement(context, node.expression); + const statements = wrapInStatement(context.transformExpression(node.expression)); if (statements) context.addPrecedingStatements(statements); } diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 94655ca01..e52fe69b8 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -3,18 +3,18 @@ exports[`Unsupported optional chains Builtin global method: code 1`] = ` "local ____lualib = require(\\"lualib_bundle\\") local __TS__Number = ____lualib.__TS__Number -local ____Number_result_0 = Number -if ____Number_result_0 ~= nil then - ____Number_result_0 = __TS__Number(\\"3\\") +local ____opt_0 = Number +if ____opt_0 ~= nil then + __TS__Number(\\"3\\") end" `; exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; exports[`Unsupported optional chains Builtin global property: code 1`] = ` -"local ____console_log_result_0 = console -if ____console_log_result_0 ~= nil then - ____console_log_result_0 = print(\\"3\\") +"local ____opt_0 = console +if ____opt_0 ~= nil then + print(\\"3\\") end" `; @@ -23,9 +23,9 @@ exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` "local ____lualib = require(\\"lualib_bundle\\") local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach -local ____table_forEach_result_0 = ({1, 2, 3, 4}).forEach -if ____table_forEach_result_0 ~= nil then - ____table_forEach_result_0 = __TS__ArrayForEach( +local ____opt_0 = ({1, 2, 3, 4}).forEach +if ____opt_0 ~= nil then + __TS__ArrayForEach( {1, 2, 3, 4}, function() end @@ -50,9 +50,9 @@ function ____exports.__main(self) --- -- @compileMembersOnly local D = \\"D\\" - local ____TestEnum_B_0 = TestEnum - if ____TestEnum_B_0 ~= nil then - ____TestEnum_B_0 = B + local ____opt_0 = TestEnum + if ____opt_0 ~= nil then + local ____ = B end end return ____exports" @@ -61,10 +61,214 @@ return ____exports" exports[`Unsupported optional chains Compile members only: diagnostics 1`] = `"main.ts(10,17): error TSTL: Optional calls are not supported on enums marked with @compileMembersOnly."`; exports[`Unsupported optional chains Language extensions: code 1`] = ` -"local ____table_has_result_0 = ({}).has -if ____table_has_result_0 ~= nil then - ____table_has_result_0 = nil[3] ~= nil +"local ____opt_0 = ({}).has +if ____opt_0 ~= nil then + local ____ = nil[3] ~= nil end" `; exports[`Unsupported optional chains Language extensions: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; + +exports[`long optional chain 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local a = {b = {c = {d = {e = {f = \\"hello!\\"}}}}} + local ____opt_2 = a.b + local ____opt_0 = ____opt_2 and ____opt_2.c + return ____opt_0 and ____opt_0.d.e.f +end +return ____exports" +`; + +exports[`optional chaining ("{ foo: \\"foo\\" }") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = {foo = \\"foo\\"} + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional chaining ("null") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = nil + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional chaining ("undefined") 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = nil + return obj and obj.foo +end +return ____exports" +`; + +exports[`optional element function calls 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = { + value = \\"foobar\\", + foo = function(v) return v + 10 end + } + local fooKey = \\"foo\\" + local barKey = \\"bar\\" + local ____opt_0 = obj[barKey] + local ____temp_4 = ____opt_0 and ____opt_0(5) + if ____temp_4 == nil then + local ____opt_2 = obj[fooKey] + ____temp_4 = ____opt_2 and ____opt_2(15) + end + return ____temp_4 +end +return ____exports" +`; + +exports[`unused call 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local result + local obj = {foo = function(self) + result = \\"bar\\" + end} + if obj ~= nil then + obj:foo() + end + return result +end +return ____exports" +`; + +exports[`unused expression 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local obj = {foo = \\"bar\\"} + if obj ~= nil then + local ____ = obj.foo + end +end +return ____exports" +`; + +exports[`unused result with preceding statements on right side 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0_foo_2(obj, ____i_1) + end + return i +end +return ____exports" +`; + +exports[`unused result with preceding statements on right side 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(self, val) + return val + end} + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0_foo_2(obj, ____i_1) + end + return i +end +return ____exports" +`; + +exports[`with preceding statements on right side 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + local ____opt_result_4 + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_result_4 = ____opt_0_foo_2(obj, ____i_1) + end + return {result = ____opt_result_4, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(____, v) return v end} + local ____opt_result_4 + if obj ~= nil then + local ____opt_0_foo_2 = obj.foo + local ____i_1 = i + i = ____i_1 + 1 + ____opt_result_4 = ____opt_0_foo_2(obj, ____i_1) + end + return {result = ____opt_result_4, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side modifying left 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = nil + local function bar(self) + if obj then + obj.foo = nil + end + obj = nil + return 1 + end + local ____opt_0 = obj + if ____opt_0 ~= nil then + local ____opt_0_foo_3 = ____opt_0.foo + local ____bar_result_2 = bar(nil) + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0 = ____opt_0_foo_3(____opt_0, ____bar_result_2, ____i_1) + end + return {result = ____opt_0, obj = obj, i = i} +end +return ____exports" +`; + +exports[`with preceding statements on right side modifying left 2`] = ` +"local ____exports = {} +function ____exports.__main(self) + local i = 0 + local obj = {foo = function(self, v) + return v + end} + local function bar(self) + if obj then + obj.foo = nil + end + obj = nil + return 1 + end + local ____opt_0 = obj + if ____opt_0 ~= nil then + local ____opt_0_foo_3 = ____opt_0.foo + local ____bar_result_2 = bar(nil) + local ____i_1 = i + i = ____i_1 + 1 + ____opt_0 = ____opt_0_foo_3(____opt_0, ____bar_result_2, ____i_1) + end + return {result = ____opt_0, obj = obj, i = i} +end +return ____exports" +`; diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 675fc59f9..8a30e1647 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -4,16 +4,22 @@ import { ScriptTarget } from "typescript"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` - const obj: any = ${value}; + const obj: {foo: string} | null | undefined = ${value}; return obj?.foo; - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use "and" expression }); test("long optional chain", () => { util.testFunction` const a = { b: { c: { d: { e: { f: "hello!"}}}}}; return a.b?.c?.d.e.f; - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use "and" expression }); test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { @@ -69,7 +75,89 @@ test("optional element function calls", () => { const fooKey = "foo"; const barKey = "bar"; return obj[barKey]?.(5) ?? obj[fooKey]?.(15); - `.expectToMatchJsResult(); + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should still use "and" statement, as functions have no self +}); + +test("unused expression", () => { + util.testFunction` + const obj = { foo: "bar" }; + obj?.foo; + ` + .expectToHaveNoDiagnostics() + .expectNoExecutionError() + .expectLuaToMatchSnapshot(); + // should use if statement, as result is not used +}); + +test("unused call", () => { + util.testFunction` + let result + const obj = { + foo() { + result = "bar" + } + }; + obj?.foo(); + return result; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as result is not used +}); + +test.each(["undefined", "{ foo: v=>v }"])("with preceding statements on right side", value => { + util.testFunction` + let i = 0 + const obj: any = ${value}; + return {result: obj?.foo(i++), i}; + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements +}); + +// unused, with preceding statements on right side +test.each(["undefined", "{ foo(val) {return val} }"])( + "unused result with preceding statements on right side", + value => { + util.testFunction` + let i = 0 + const obj = ${value}; + obj?.foo(i++); + return i + ` + .expectToHaveNoDiagnostics() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements + } +); + +test.each(["undefined", "{ foo(v) { return v} }"])("with preceding statements on right side modifying left", value => { + util.testFunction` + let i = 0 + let obj: any = ${value}; + function bar() { + if(obj) obj.foo = undefined + obj = undefined + return 1 + } + + return {result: obj?.foo(bar(), i++), obj, i} + ` + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements +}); + +test("does not suppress error if left side is false", () => { + const result = util.testFunction` + const obj: any = false + return obj?.foo + `.getLuaExecutionResult(); + expect(result).toBeInstanceOf(util.ExecutionError); }); describe("optional access method calls", () => { @@ -85,7 +173,7 @@ describe("optional access method calls", () => { `.expectToMatchJsResult(); }); - test("optional access call", () => { + test("property access call", () => { util.testFunction` const obj: { value: string; foo?(prefix: string): string; bar?(prefix: string): string; } = { value: "foobar", From 7e8c2fbe070fa231fe67d53737f688cf17c7c349 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Sun, 22 Jan 2023 11:32:47 -0800 Subject: [PATCH 555/764] Fix crash on invalid call extension operator use (#1386) * Fix crash on invalid call extension operator use * Fix prettier * Update snapshots --- src/transformation/utils/diagnostics.ts | 8 ++ .../utils/language-extensions.ts | 77 +++++++++++++++ .../visitors/language-extensions/operators.ts | 31 ++---- .../visitors/language-extensions/table.ts | 98 ++++++++----------- .../optionalChaining.spec.ts.snap | 6 +- .../__snapshots__/operators.spec.ts.snap | 12 +++ .../__snapshots__/table.spec.ts.snap | 8 ++ .../language-extensions/operators.spec.ts | 44 ++++++++- test/unit/language-extensions/table.spec.ts | 22 +++++ 9 files changed, 225 insertions(+), 81 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 94f7781de..fd443e596 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -155,3 +155,11 @@ export const unsupportedOptionalCompileMembersOnly = createErrorDiagnosticFactor export const undefinedInArrayLiteral = createErrorDiagnosticFactory( "Array literals may not contain undefined or null." ); + +export const invalidMethodCallExtensionUse = createErrorDiagnosticFactory( + "This language extension must be called as a method." +); + +export const invalidSpreadInCallExtension = createErrorDiagnosticFactory( + "Spread elements are not supported in call extensions." +); diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 881da105b..108c6eef1 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -1,5 +1,6 @@ import * as ts from "typescript"; import { TransformationContext } from "../context"; +import { invalidMethodCallExtensionUse, invalidSpreadInCallExtension } from "./diagnostics"; export enum ExtensionKind { MultiFunction = "MultiFunction", @@ -53,6 +54,7 @@ export enum ExtensionKind { TableAddKeyType = "TableAddKey", TableAddKeyMethodType = "TableAddKeyMethod", } + const extensionValues: Set = new Set(Object.values(ExtensionKind)); export function getExtensionKindForType(context: TransformationContext, type: ts.Type): ExtensionKind | undefined { @@ -119,3 +121,78 @@ export function getIterableExtensionKindForNode( const type = context.checker.getTypeAtLocation(node); return getIterableExtensionTypeForType(context, type); } + +export const methodExtensionKinds: ReadonlySet = new Set([ + ExtensionKind.AdditionOperatorMethodType, + ExtensionKind.SubtractionOperatorMethodType, + ExtensionKind.MultiplicationOperatorMethodType, + ExtensionKind.DivisionOperatorMethodType, + ExtensionKind.ModuloOperatorMethodType, + ExtensionKind.PowerOperatorMethodType, + ExtensionKind.FloorDivisionOperatorMethodType, + ExtensionKind.BitwiseAndOperatorMethodType, + ExtensionKind.BitwiseOrOperatorMethodType, + ExtensionKind.BitwiseExclusiveOrOperatorMethodType, + ExtensionKind.BitwiseLeftShiftOperatorMethodType, + ExtensionKind.BitwiseRightShiftOperatorMethodType, + ExtensionKind.ConcatOperatorMethodType, + ExtensionKind.LessThanOperatorMethodType, + ExtensionKind.GreaterThanOperatorMethodType, + ExtensionKind.NegationOperatorMethodType, + ExtensionKind.BitwiseNotOperatorMethodType, + ExtensionKind.LengthOperatorMethodType, + ExtensionKind.TableDeleteMethodType, + ExtensionKind.TableGetMethodType, + ExtensionKind.TableHasMethodType, + ExtensionKind.TableSetMethodType, + ExtensionKind.TableAddKeyMethodType, +]); + +export function getNaryCallExtensionArgs( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind, + numArgs: number +): readonly ts.Expression[] | undefined { + let expressions: readonly ts.Expression[]; + if (node.arguments.some(ts.isSpreadElement)) { + context.diagnostics.push(invalidSpreadInCallExtension(node)); + return undefined; + } + if (methodExtensionKinds.has(kind)) { + if (!(ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression))) { + context.diagnostics.push(invalidMethodCallExtensionUse(node)); + return undefined; + } + if (node.arguments.length < numArgs - 1) { + // assumed to be TS error + return undefined; + } + expressions = [node.expression.expression, ...node.arguments]; + } else { + if (node.arguments.length < numArgs) { + // assumed to be TS error + return undefined; + } + expressions = node.arguments; + } + return expressions; +} + +export function getUnaryCallExtensionArg( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind +): ts.Expression | undefined { + return getNaryCallExtensionArgs(context, node, kind, 1)?.[0]; +} + +export function getBinaryCallExtensionArgs( + context: TransformationContext, + node: ts.CallExpression, + kind: ExtensionKind +): readonly [ts.Expression, ts.Expression] | undefined { + const expressions = getNaryCallExtensionArgs(context, node, kind, 2); + if (expressions === undefined) return undefined; + return [expressions[0], expressions[1]]; +} diff --git a/src/transformation/visitors/language-extensions/operators.ts b/src/transformation/visitors/language-extensions/operators.ts index 657c98b92..4cb08abc2 100644 --- a/src/transformation/visitors/language-extensions/operators.ts +++ b/src/transformation/visitors/language-extensions/operators.ts @@ -4,8 +4,9 @@ import { TransformationContext } from "../../context"; import { assert } from "../../../utils"; import { LuaTarget } from "../../../CompilerOptions"; import { unsupportedForTarget } from "../../utils/diagnostics"; -import { ExtensionKind } from "../../utils/language-extensions"; +import { ExtensionKind, getBinaryCallExtensionArgs, getUnaryCallExtensionArg } from "../../utils/language-extensions"; import { LanguageExtensionCallTransformerMap } from "./call-extension"; +import { transformOrderedExpressions } from "../expression-list"; const binaryOperatorMappings = new Map([ [ExtensionKind.AdditionOperatorType, lua.SyntaxKind.AdditionOperator], @@ -81,35 +82,21 @@ for (const kind of unaryOperatorMappings.keys()) { function transformBinaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); - let args: readonly ts.Expression[] = node.arguments; - if ( - args.length === 1 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - args = [node.expression.expression, ...args]; - } + const args = getBinaryCallExtensionArgs(context, node, kind); + if (!args) return lua.createNilLiteral(); + + const [left, right] = transformOrderedExpressions(context, args); const luaOperator = binaryOperatorMappings.get(kind); assert(luaOperator); - return lua.createBinaryExpression( - context.transformExpression(args[0]), - context.transformExpression(args[1]), - luaOperator - ); + return lua.createBinaryExpression(left, right, luaOperator); } function transformUnaryOperator(context: TransformationContext, node: ts.CallExpression, kind: ExtensionKind) { if (requiresLua53.has(kind)) checkHasLua53(context, node, kind); - let arg: ts.Expression; - if ( - node.arguments.length === 0 && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - arg = node.expression.expression; - } else { - arg = node.arguments[0]; - } + const arg = getUnaryCallExtensionArg(context, node, kind); + if (!arg) return lua.createNilLiteral(); const luaOperator = unaryOperatorMappings.get(kind); assert(luaOperator); diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index 2d22adf15..d3aaedc5d 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -1,16 +1,22 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import { ExtensionKind, getExtensionKindForNode } from "../../utils/language-extensions"; -import { transformExpressionList } from "../expression-list"; -import { LanguageExtensionCallTransformer } from "./call-extension"; +import { + ExtensionKind, + getBinaryCallExtensionArgs, + getExtensionKindForNode, + getNaryCallExtensionArgs, +} from "../../utils/language-extensions"; +import { transformOrderedExpressions } from "../expression-list"; +import { LanguageExtensionCallTransformerMap } from "./call-extension"; export function isTableNewCall(context: TransformationContext, node: ts.NewExpression) { return getExtensionKindForNode(context, node.expression) === ExtensionKind.TableNewType; } + export const tableNewExtensions = [ExtensionKind.TableNewType]; -export const tableExtensionTransformers: { [P in ExtensionKind]?: LanguageExtensionCallTransformer } = { +export const tableExtensionTransformers: LanguageExtensionCallTransformerMap = { [ExtensionKind.TableDeleteType]: transformTableDeleteExpression, [ExtensionKind.TableDeleteMethodType]: transformTableDeleteExpression, [ExtensionKind.TableGetType]: transformTableGetExpression, @@ -19,8 +25,8 @@ export const tableExtensionTransformers: { [P in ExtensionKind]?: LanguageExtens [ExtensionKind.TableHasMethodType]: transformTableHasExpression, [ExtensionKind.TableSetType]: transformTableSetExpression, [ExtensionKind.TableSetMethodType]: transformTableSetExpression, - [ExtensionKind.TableAddKeyType]: transformTableAddExpression, - [ExtensionKind.TableAddKeyMethodType]: transformTableAddExpression, + [ExtensionKind.TableAddKeyType]: transformTableAddKeyExpression, + [ExtensionKind.TableAddKeyMethodType]: transformTableAddKeyExpression, }; function transformTableDeleteExpression( @@ -28,48 +34,32 @@ function transformTableDeleteExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = node.arguments.slice(); - if ( - extensionKind === ExtensionKind.TableDeleteMethodType && - (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) - ) { - // In case of method (no table argument), push method owner to front of args list - args.unshift(node.expression.expression); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); } - const [table, accessExpression] = transformExpressionList(context, args); + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] = nil context.addPrecedingStatements( - lua.createAssignmentStatement( - lua.createTableIndexExpression(table, accessExpression), - lua.createNilLiteral(), - node - ) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createNilLiteral(), node) ); return lua.createBooleanLiteral(true); } -function transformWithTableArgument(context: TransformationContext, node: ts.CallExpression): lua.Expression[] { - if (ts.isPropertyAccessExpression(node.expression) || ts.isElementAccessExpression(node.expression)) { - return transformExpressionList(context, [node.expression.expression, ...node.arguments]); - } - // todo: report diagnostic? - return [lua.createNilLiteral(), ...transformExpressionList(context, node.arguments)]; -} - function transformTableGetExpression( context: TransformationContext, node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableGetMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] - return lua.createTableIndexExpression(table, accessExpression, node); + return lua.createTableIndexExpression(table, key, node); } function transformTableHasExpression( @@ -77,14 +67,14 @@ function transformTableHasExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableHasMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getBinaryCallExtensionArgs(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] - const tableIndexExpression = lua.createTableIndexExpression(table, accessExpression); + const tableIndexExpression = lua.createTableIndexExpression(table, key); // arg0[arg1] ~= nil return lua.createBinaryExpression( @@ -100,37 +90,33 @@ function transformTableSetExpression( node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableSetMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getNaryCallExtensionArgs(context, node, extensionKind, 3); + if (!args) { + return lua.createNilLiteral(); + } - const [table, accessExpression, value] = args; + const [table, key, value] = transformOrderedExpressions(context, args); // arg0[arg1] = arg2 context.addPrecedingStatements( - lua.createAssignmentStatement(lua.createTableIndexExpression(table, accessExpression), value, node) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), value, node) ); return lua.createNilLiteral(); } -function transformTableAddExpression( +function transformTableAddKeyExpression( context: TransformationContext, node: ts.CallExpression, extensionKind: ExtensionKind ): lua.Expression { - const args = - extensionKind === ExtensionKind.TableAddKeyMethodType - ? transformWithTableArgument(context, node) - : transformExpressionList(context, node.arguments); + const args = getNaryCallExtensionArgs(context, node, extensionKind, 2); + if (!args) { + return lua.createNilLiteral(); + } - const [table, value] = args; + const [table, key] = transformOrderedExpressions(context, args); // arg0[arg1] = true context.addPrecedingStatements( - lua.createAssignmentStatement( - lua.createTableIndexExpression(table, value), - lua.createBooleanLiteral(true), - node - ) + lua.createAssignmentStatement(lua.createTableIndexExpression(table, key), lua.createBooleanLiteral(true), node) ); return lua.createNilLiteral(); } diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index e52fe69b8..707ecf68b 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -63,11 +63,13 @@ exports[`Unsupported optional chains Compile members only: diagnostics 1`] = `"m exports[`Unsupported optional chains Language extensions: code 1`] = ` "local ____opt_0 = ({}).has if ____opt_0 ~= nil then - local ____ = nil[3] ~= nil end" `; -exports[`Unsupported optional chains Language extensions: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; +exports[`Unsupported optional chains Language extensions: diagnostics 1`] = ` +"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions. +main.ts(2,17): error TSTL: This language extension must be called as a method." +`; exports[`long optional chain 1`] = ` "local ____exports = {} diff --git a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap index dda0e61e2..a4554a8a1 100644 --- a/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/operators.spec.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`does not crash on invalid operator use global function: code 1`] = `""`; + +exports[`does not crash on invalid operator use global function: diagnostics 1`] = `"main.ts(3,13): error TS2554: Expected 2 arguments, but got 1."`; + +exports[`does not crash on invalid operator use method: code 1`] = `"left = {}"`; + +exports[`does not crash on invalid operator use method: diagnostics 1`] = `"main.ts(5,18): error TS2554: Expected 1 arguments, but got 0."`; + +exports[`does not crash on invalid operator use unary operator: code 1`] = `"op(_G)"`; + +exports[`does not crash on invalid operator use unary operator: diagnostics 1`] = `"main.ts(2,31): error TS2304: Cannot find name 'LuaUnaryMinus'."`; + exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): code 1`] = `"foo = op(_G, 1, 2)"`; exports[`operator mapping - invalid use (const foo = (op as any)(1, 2);): diagnostics 1`] = `"main.ts(3,22): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 9821d9777..5bf4ef2c8 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -133,3 +133,11 @@ __TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaTable"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; + +exports[`does not crash on invalid extension use global function: code 1`] = `""`; + +exports[`does not crash on invalid extension use global function: diagnostics 1`] = `"main.ts(3,9): error TS2554: Expected 2 arguments, but got 1."`; + +exports[`does not crash on invalid extension use method: code 1`] = `"left = {}"`; + +exports[`does not crash on invalid extension use method: diagnostics 1`] = `"main.ts(5,14): error TS2554: Expected 2 arguments, but got 0."`; diff --git a/test/unit/language-extensions/operators.spec.ts b/test/unit/language-extensions/operators.spec.ts index 043b1cebb..303a5d0be 100644 --- a/test/unit/language-extensions/operators.spec.ts +++ b/test/unit/language-extensions/operators.spec.ts @@ -2,7 +2,11 @@ import * as path from "path"; import * as util from "../../util"; import * as tstl from "../../../src"; import { LuaTarget } from "../../../src"; -import { unsupportedForTarget, invalidCallExtensionUse } from "../../../src/transformation/utils/diagnostics"; +import { + unsupportedForTarget, + invalidCallExtensionUse, + invalidSpreadInCallExtension, +} from "../../../src/transformation/utils/diagnostics"; const operatorsProjectOptions: tstl.CompilerOptions = { luaTarget: LuaTarget.Lua54, @@ -389,3 +393,41 @@ test.each([ .setOptions(operatorsProjectOptions) .expectDiagnosticsToMatchSnapshot([invalidCallExtensionUse.code]); }); + +describe("does not crash on invalid operator use", () => { + test("global function", () => { + util.testModule` + declare const op: LuaAddition; + op(1) + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); + test("unary operator", () => { + util.testModule` + declare const op: LuaUnaryMinus; + op() + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); + test("method", () => { + util.testModule` + const left = {} as { + op: LuaAdditionMethod; + } + left.op() + ` + .setOptions(operatorsProjectOptions) + .expectDiagnosticsToMatchSnapshot(); + }); +}); + +test("does not allow spread", () => { + util.testModule` + declare const op: LuaAddition; + op(...[1, 2] as const); + ` + .setOptions(operatorsProjectOptions) + .expectToHaveDiagnostics([invalidSpreadInCallExtension.code]); +}); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index ed9e8e37c..b833de22b 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -467,3 +467,25 @@ test.each([ .withLanguageExtensions() .expectToEqual(expected); }); + +describe("does not crash on invalid extension use", () => { + test("global function", () => { + util.testModule` + declare const op: LuaTableGet<{}, string, any> + op({}) + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(); + }); + + test("method", () => { + util.testModule` + const left = {} as { + op: LuaTableGet<{}, string, any> + } + left.op() + ` + .withLanguageExtensions() + .expectDiagnosticsToMatchSnapshot(); + }); +}); From 93ff05d082340ccfd77942a602cac0c3e96fd67f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 22 Jan 2023 20:47:59 +0100 Subject: [PATCH 556/764] 1.12.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1e96684a..6975939b4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.12.0", + "version": "1.12.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.12.0", + "version": "1.12.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index b78233e0a..bc4f19525 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.12.0", + "version": "1.12.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 4c695cf6687c870738e450ea83f03e0b144284ed Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sun, 5 Feb 2023 23:23:51 +0800 Subject: [PATCH 557/764] Support 'exports' field in package.json of published modules. (#1392) * Support 'exports' field in package.json of published modules. * add exports field test * use fs symlink during test * remove package-lock in test --- .eslintignore | 3 +- .gitignore | 2 + .prettierignore | 2 + src/transpilation/resolve.ts | 1 + test/transpile/module-resolution.spec.ts | 47 +++++++++++++++++++ .../app/main.ts | 5 ++ .../app/package.json | 7 +++ .../app/tsconfig.json | 6 +++ .../dependency1-ts/package.json | 14 ++++++ .../dependency1-ts/src/d1otherfile.ts | 3 ++ .../dependency1-ts/src/index.ts | 10 ++++ .../dependency1-ts/tsconfig.json | 13 +++++ 12 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts create mode 100644 test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json diff --git a/.eslintignore b/.eslintignore index 492195f96..a1a50129e 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,5 +3,6 @@ /test/cli/errors /test/cli/watch /test/transpile/directories -/test/transpile/module-resolution/*/node_modules +/test/transpile/module-resolution/**/node_modules +/test/transpile/module-resolution/**/dist /test/transpile/outFile diff --git a/.gitignore b/.gitignore index e9fe7f092..fc3920330 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ node_modules /dist /coverage +/test/transpile/module-resolution/**/dist +/test/transpile/module-resolution/**/tsconfig.tsbuildinfo yarn.lock .vscode diff --git a/.prettierignore b/.prettierignore index 23b85e3bd..656f1a4d6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,3 +2,5 @@ /coverage /test/translation/transformation/characterEscapeSequence.ts /benchmark/dist +/test/transpile/module-resolution/**/node_modules +/test/transpile/module-resolution/**/dist diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index c7ea38dd1..fa0a5200a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -15,6 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({ enforceExtension: true, // Resolved file must be a lua file fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, useSyncFileSystemCalls: true, + conditionNames: ["require", "node", "default"], symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) }); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 8f8cc0230..f9e1894d5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,6 +2,7 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; +import * as fs from "fs-extra"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; @@ -272,6 +273,52 @@ describe("module resolution project with dependencies built by tstl library mode }); }); +describe("module resolution project with dependencies built by tstl library mode and has exports field", () => { + const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-has-exports-field"); + const appPath = path.join(projectPath, "app"); + + // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow + const dependency1Path = path.join(projectPath, "dependency1-ts"); + tstl.transpileProject(path.join(dependency1Path, "tsconfig.json")); + + // Install dependencies. This will create node_modules folder with dependency1-ts in it. + const nodeModulesPath = path.join(appPath, "node_modules"); + fs.ensureDirSync(nodeModulesPath); + fs.ensureSymlinkSync(dependency1Path, path.join(nodeModulesPath, "dependency1"), "dir"); + + const expectedResult = { + dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", + dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", + }; + + test("can resolve lua dependencies", () => { + const transpileResult = util + .testProject(path.join(appPath, "tsconfig.json")) + .setMainFileName(path.join(appPath, "main.ts")) + .setOptions({ outDir: "tstl-out", moduleResolution: ts.ModuleResolutionKind.Node16 }) + .expectToEqual(expectedResult) + .getLuaResult(); + + // Assert node_modules file requires the correct lualib_bundle + const requiringLuaFile = path.join("lua_modules", "dependency1", "dist", "index.lua"); + const lualibRequiringFile = transpileResult.transpiledFiles.find(f => f.outPath.endsWith(requiringLuaFile)); + expect(lualibRequiringFile).toBeDefined(); + expect(lualibRequiringFile?.lua).toContain('require("lualib_bundle")'); + }); + + test("can resolve dependencies and bundle", () => { + const mainFile = path.join(appPath, "main.ts"); + util.testProject(path.join(appPath, "tsconfig.json")) + .setMainFileName(mainFile) + .setOptions({ + luaBundle: "bundle.lua", + luaBundleEntry: mainFile, + moduleResolution: ts.ModuleResolutionKind.Node16, + }) + .expectToEqual(expectedResult); + }); +}); + // Test fix for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1037 describe("module resolution with tsx", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tsx"); diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts new file mode 100644 index 000000000..3421911f2 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts @@ -0,0 +1,5 @@ +import { dependency1IndexFunc } from "dependency1/sub"; +import { dependency1OtherFileFunc } from "dependency1/sub/d1otherfile"; + +export const dependency1IndexResult = dependency1IndexFunc(); +export const dependency1OtherFileFuncResult = dependency1OtherFileFunc(); diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json new file mode 100644 index 000000000..b88dc4bc0 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json @@ -0,0 +1,7 @@ +{ + "name": "app", + "version": "0.0.1", + "dependencies": { + "dependency1": "file:../dependency1-ts" + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json new file mode 100644 index 000000000..7b0969155 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json @@ -0,0 +1,6 @@ +{ + "compilerOptions": { + "moduleResolution": "node16" + }, + "references": [{ "path": "./node_modules/dependency1" }] +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json new file mode 100644 index 000000000..c74b862a1 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json @@ -0,0 +1,14 @@ +{ + "name": "dependency1", + "version": "0.0.1", + "exports": { + "./sub": { + "require": "./dist/index", + "types": "./dist/index.d.ts" + }, + "./sub/*": { + "require": "./dist/*", + "types": "./dist/*.d.ts" + } + } +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts new file mode 100644 index 000000000..3877a1c52 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts @@ -0,0 +1,3 @@ +export function dependency1OtherFileFunc() { + return "dependency1OtherFileFunc in dependency1/d1otherfile"; +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts new file mode 100644 index 000000000..03cff47c5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts @@ -0,0 +1,10 @@ +import { dependency1OtherFileFunc } from "./d1otherfile"; + +export function dependency1IndexFunc() { + return "function in dependency 1 index: " + dependency1OtherFileFunc(); +} + +export function squares(nums: number[]) { + // Require lualib functionality + return nums.map(n => n * n); +} diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json new file mode 100644 index 000000000..d6ffcdc0c --- /dev/null +++ b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist", + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true + }, + "tstl": { + "buildMode": "library" + } +} From 1e6fbfc2eac08101fcde56f85871defabb406fdf Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Fri, 10 Feb 2023 00:57:15 +0800 Subject: [PATCH 558/764] Add resolver condition "tstl" (#1397) --- src/transpilation/resolve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index fa0a5200a..ad1aa1c84 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -15,7 +15,7 @@ const resolver = resolve.ResolverFactory.createResolver({ enforceExtension: true, // Resolved file must be a lua file fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, useSyncFileSystemCalls: true, - conditionNames: ["require", "node", "default"], + conditionNames: ["require", "node", "tstl", "default"], symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) }); From 96e76caa898d4b52a797e08bdccc0e6917d9cd96 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Feb 2023 15:01:19 +0100 Subject: [PATCH 559/764] Fix cast exception when transforming compound length assignment (#1398) --- .../utils/preceding-statements.ts | 7 ++ .../visitors/binary-expression/compound.ts | 91 ++++++++++++++++--- test/unit/builtins/array.spec.ts | 17 ++++ 3 files changed, 104 insertions(+), 11 deletions(-) diff --git a/src/transformation/utils/preceding-statements.ts b/src/transformation/utils/preceding-statements.ts index c64d0b90a..8ce121f0d 100644 --- a/src/transformation/utils/preceding-statements.ts +++ b/src/transformation/utils/preceding-statements.ts @@ -1,6 +1,13 @@ import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; +export interface WithPrecedingStatements< + T extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] +> { + precedingStatements: lua.Statement[]; + result: T; +} + export function transformInPrecedingStatementScope< TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] >(context: TransformationContext, transformer: () => TReturn): [lua.Statement[], TReturn] { diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index a8180e78b..43bcab9cb 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -2,9 +2,11 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { cast, assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; -import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../../utils/preceding-statements"; import { transformBinaryOperation } from "./index"; import { transformAssignmentWithRightPrecedingStatements } from "./assignments"; +import { isArrayLength } from "./destructuring-assignments"; +import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; function isLuaExpressionWithSideEffect(expression: lua.Expression) { return !(lua.isLiteral(expression) || lua.isIdentifier(expression)); @@ -63,14 +65,26 @@ export const isCompoundAssignmentToken = (token: ts.BinaryOperator): token is ts export const unwrapCompoundAssignmentToken = (token: ts.CompoundAssignmentOperator): CompoundAssignmentToken => compoundToAssignmentTokens[token]; -export function transformCompoundAssignment( +function transformCompoundAssignment( context: TransformationContext, expression: ts.Expression, lhs: ts.Expression, rhs: ts.Expression, operator: CompoundAssignmentToken, isPostfix: boolean -) { +): WithPrecedingStatements { + if (isArrayLength(context, lhs)) { + const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter( + context, + expression, + lhs, + rhs, + operator + ); + + return { precedingStatements, result: lengthSetterStatement.expression }; + } + const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => context.transformExpression(rhs) @@ -101,13 +115,13 @@ export function transformCompoundAssignment( ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); return { - statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], result: tmp, }; } else { if (isSetterSkippingCompoundAssignmentOperator(operator)) { return { - statements: [ + precedingStatements: [ objAndIndexDeclaration, ...transformSetterSkippingCompoundAssignment( accessExpression, @@ -133,7 +147,7 @@ export function transformCompoundAssignment( const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, operatorExpression); const assignStatement = lua.createAssignmentStatement(accessExpression, tmp); return { - statements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], + precedingStatements: [objAndIndexDeclaration, ...precedingStatements, tmpDeclaration, assignStatement], result: tmp, }; } @@ -158,11 +172,19 @@ export function transformCompoundAssignment( operatorExpression, rightPrecedingStatements ); - return { statements: [tmpDeclaration, ...precedingStatements, ...assignStatements], result: tmpIdentifier }; + return { + precedingStatements: [tmpDeclaration, ...precedingStatements, ...assignStatements], + result: tmpIdentifier, + }; } else { if (rightPrecedingStatements.length > 0 && isSetterSkippingCompoundAssignmentOperator(operator)) { return { - statements: transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements), + precedingStatements: transformSetterSkippingCompoundAssignment( + left, + operator, + right, + rightPrecedingStatements + ), result: left, }; } @@ -183,7 +205,7 @@ export function transformCompoundAssignment( operatorExpression, precedingStatements ); - return { statements, result: left }; + return { precedingStatements: statements, result: left }; } } @@ -196,8 +218,15 @@ export function transformCompoundAssignmentExpression( operator: CompoundAssignmentToken, isPostfix: boolean ): lua.Expression { - const { statements, result } = transformCompoundAssignment(context, expression, lhs, rhs, operator, isPostfix); - context.addPrecedingStatements(statements); + const { precedingStatements, result } = transformCompoundAssignment( + context, + expression, + lhs, + rhs, + operator, + isPostfix + ); + context.addPrecedingStatements(precedingStatements); return result; } @@ -208,6 +237,18 @@ export function transformCompoundAssignmentStatement( rhs: ts.Expression, operator: CompoundAssignmentToken ): lua.Statement[] { + if (isArrayLength(context, lhs)) { + const { precedingStatements, result: lengthSetterStatement } = transformCompoundLengthSetter( + context, + node, + lhs, + rhs, + operator + ); + + return [...precedingStatements, lengthSetterStatement]; + } + const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => context.transformExpression(rhs) @@ -319,3 +360,31 @@ function transformSetterSkippingCompoundAssignment( ), ]; } + +function transformCompoundLengthSetter( + context: TransformationContext, + node: ts.Node, + lhs: ts.PropertyAccessExpression | ts.ElementAccessExpression, + rhs: ts.Expression, + operator: CompoundAssignmentToken +): WithPrecedingStatements { + const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => + context.transformExpression(rhs) + ); + const table = context.transformExpression(lhs.expression); + const lengthExpression = lua.createUnaryExpression(table, lua.SyntaxKind.LengthOperator, lhs); + const [precedingStatements, operatorExpression] = transformBinaryOperation( + context, + lengthExpression, + right, + rightPrecedingStatements, + operator, + node + ); + + const arrayLengthAssignment = lua.createExpressionStatement( + transformLuaLibFunction(context, LuaLibFeature.ArraySetLength, node, table, operatorExpression) + ); + + return { precedingStatements, result: arrayLengthAssignment }; +} diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 6c73c1588..98ba1b61d 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -176,6 +176,23 @@ describe("array.length", () => { `.expectToEqual(new util.ExecutionError(`invalid array length: ${luaSpecialValueString}`)); }); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1395 + test("in compound assignment (#1395)", () => { + util.testFunction` + const arr = [1,2,3,4]; + const returnVal = arr.length -= 2; + return { arr, returnVal }; + `.expectToMatchJsResult(); + }); + + test("as standalone compound assignment (#1395)", () => { + util.testFunction` + const arr = [1,2,3,4]; + arr.length -= 2; + return arr; + `.expectToMatchJsResult(); + }); + test("in array destructuring", () => { util.testFunction` const array = [0, 1, 2]; From 207cabe595288629e9bfbf647fdf363edd0bcd84 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Feb 2023 16:33:22 +0100 Subject: [PATCH 560/764] Refactor WithPrecedingStatements type (#1399) * Refactor WithPrecedingStatements type * Remove symlinking from test --- .../utils/preceding-statements.ts | 4 +- .../visitors/binary-expression/assignments.ts | 9 ++-- .../visitors/binary-expression/compound.ts | 35 +++++++------ .../destructuring-assignments.ts | 33 ++++++------ .../visitors/binary-expression/index.ts | 44 ++++++++++------ src/transformation/visitors/call.ts | 10 ++-- src/transformation/visitors/class/index.ts | 2 +- .../visitors/class/members/fields.ts | 2 +- src/transformation/visitors/conditional.ts | 34 ++++++------ .../visitors/expression-list.ts | 5 +- src/transformation/visitors/function.ts | 4 +- src/transformation/visitors/loops/do-while.ts | 10 ++-- src/transformation/visitors/loops/for.ts | 7 +-- src/transformation/visitors/loops/utils.ts | 2 +- .../visitors/optional-chaining.ts | 52 ++++++++++--------- src/transformation/visitors/sourceFile.ts | 2 +- src/transformation/visitors/switch.ts | 28 ++++++---- src/transformation/visitors/typeof.ts | 2 +- .../visitors/variable-declaration.ts | 12 ++--- test/transpile/module-resolution.spec.ts | 17 ++---- .../{app => }/main.ts | 0 .../dependency1}/package.json | 0 .../dependency1}/src/d1otherfile.ts | 0 .../dependency1}/src/index.ts | 0 .../dependency1}/tsconfig.json | 0 .../{app => }/package.json | 0 .../{app => }/tsconfig.json | 0 27 files changed, 165 insertions(+), 149 deletions(-) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{app => }/main.ts (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{dependency1-ts => node_modules/dependency1}/package.json (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{dependency1-ts => node_modules/dependency1}/src/d1otherfile.ts (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{dependency1-ts => node_modules/dependency1}/src/index.ts (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{dependency1-ts => node_modules/dependency1}/tsconfig.json (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{app => }/package.json (100%) rename test/transpile/module-resolution/project-with-tstl-library-has-exports-field/{app => }/tsconfig.json (100%) diff --git a/src/transformation/utils/preceding-statements.ts b/src/transformation/utils/preceding-statements.ts index 8ce121f0d..16cefac12 100644 --- a/src/transformation/utils/preceding-statements.ts +++ b/src/transformation/utils/preceding-statements.ts @@ -10,9 +10,9 @@ export interface WithPrecedingStatements< export function transformInPrecedingStatementScope< TReturn extends lua.Statement | lua.Statement[] | lua.Expression | lua.Expression[] ->(context: TransformationContext, transformer: () => TReturn): [lua.Statement[], TReturn] { +>(context: TransformationContext, transformer: () => TReturn): WithPrecedingStatements { context.pushPrecedingStatements(); const statementOrStatements = transformer(); const precedingStatements = context.popPrecedingStatements(); - return [precedingStatements, statementOrStatements]; + return { precedingStatements, result: statementOrStatements }; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index efd7180cb..2cceff755 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -107,8 +107,9 @@ function transformDestructuredAssignmentExpression( context: TransformationContext, expression: ts.DestructuringAssignment ) { - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expression.right) + let { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(expression.right) ); context.addPrecedingStatements(rightPrecedingStatements); if (isMultiReturnCall(context, expression.right)) { @@ -153,7 +154,7 @@ export function transformAssignmentExpression( } if (ts.isPropertyAccessExpression(expression.left) || ts.isElementAccessExpression(expression.left)) { - const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: right } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); @@ -233,7 +234,7 @@ export function transformAssignmentStatement( const { statements } = transformDestructuredAssignmentExpression(context, expression); return statements; } else { - const [precedingStatements, right] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: right } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression.right) ); return transformAssignmentWithRightPrecedingStatements(context, expression.left, right, precedingStatements); diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 43bcab9cb..437f66a61 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -86,8 +86,9 @@ function transformCompoundAssignment( } const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rhs) + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) ); if (lua.isTableIndexExpression(left)) { @@ -105,7 +106,7 @@ function transformCompoundAssignment( // ____obj[____index] = ____tmp ${replacementOperator} ${right}; // return ____tmp const tmpDeclaration = lua.createVariableDeclarationStatement(tmp, accessExpression); - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, tmp, right, @@ -136,7 +137,7 @@ function transformCompoundAssignment( // local ____tmp = ____obj[____index] ${replacementOperator} ${right}; // ____obj[____index] = ____tmp; // return ____tmp - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, accessExpression, right, @@ -158,7 +159,7 @@ function transformCompoundAssignment( // return ____tmp const tmpIdentifier = context.createTempNameForLuaExpression(left); const tmpDeclaration = lua.createVariableDeclarationStatement(tmpIdentifier, left); - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, tmpIdentifier, right, @@ -191,7 +192,7 @@ function transformCompoundAssignment( // Simple expressions // ${left} = ${left} ${operator} ${right} - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, left, right, @@ -250,8 +251,9 @@ export function transformCompoundAssignmentStatement( } const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); - let [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rhs) + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) ); if (lua.isTableIndexExpression(left) && shouldCacheTableIndexExpressions(left, rightPrecedingStatements)) { @@ -277,8 +279,7 @@ export function transformCompoundAssignmentStatement( ]; } - let operatorExpression: lua.Expression; - [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = transformBinaryOperation( context, accessExpression, right, @@ -287,7 +288,7 @@ export function transformCompoundAssignmentStatement( node ); const assignStatement = lua.createAssignmentStatement(accessExpression, operatorExpression); - return [objAndIndexDeclaration, ...rightPrecedingStatements, assignStatement]; + return [objAndIndexDeclaration, ...rightPrecedingStatements2, assignStatement]; } else { if (isSetterSkippingCompoundAssignmentOperator(operator)) { return transformSetterSkippingCompoundAssignment(left, operator, right, rightPrecedingStatements, node); @@ -295,8 +296,7 @@ export function transformCompoundAssignmentStatement( // Simple statements // ${left} = ${left} ${replacementOperator} ${right} - let operatorExpression: lua.Expression; - [rightPrecedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements2, result: operatorExpression } = transformBinaryOperation( context, left, right, @@ -308,7 +308,7 @@ export function transformCompoundAssignmentStatement( context, lhs, operatorExpression, - rightPrecedingStatements + rightPrecedingStatements2 ); } } @@ -368,12 +368,13 @@ function transformCompoundLengthSetter( rhs: ts.Expression, operator: CompoundAssignmentToken ): WithPrecedingStatements { - const [rightPrecedingStatements, right] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rhs) + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(rhs) ); const table = context.transformExpression(lhs.expression); const lengthExpression = lua.createUnaryExpression(table, lua.SyntaxKind.LengthOperator, lhs); - const [precedingStatements, operatorExpression] = transformBinaryOperation( + const { precedingStatements, result: operatorExpression } = transformBinaryOperation( context, lengthExpression, right, diff --git a/src/transformation/visitors/binary-expression/destructuring-assignments.ts b/src/transformation/visitors/binary-expression/destructuring-assignments.ts index d3d0086c0..aa7042727 100644 --- a/src/transformation/visitors/binary-expression/destructuring-assignments.ts +++ b/src/transformation/visitors/binary-expression/destructuring-assignments.ts @@ -97,15 +97,14 @@ function transformArrayLiteralAssignmentPattern( lua.SyntaxKind.EqualityOperator ); - const [defaultPrecedingStatements, defaultAssignmentStatements] = transformInPrecedingStatementScope( - context, - () => + const { precedingStatements: defaultPrecedingStatements, result: defaultAssignmentStatements } = + transformInPrecedingStatementScope(context, () => transformAssignment( context, (element as ts.BinaryExpression).left, context.transformExpression((element as ts.BinaryExpression).right) ) - ); + ); // Keep preceding statements inside if block defaultAssignmentStatements.unshift(...defaultPrecedingStatements); @@ -126,7 +125,7 @@ function transformArrayLiteralAssignmentPattern( case ts.SyntaxKind.Identifier: case ts.SyntaxKind.PropertyAccessExpression: case ts.SyntaxKind.ElementAccessExpression: - const [precedingStatements, statements] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: statements } = transformInPrecedingStatementScope(context, () => transformAssignment(context, element, indexedRoot, rightHasPrecedingStatements) ); return [...precedingStatements, ...statements]; // Keep preceding statements in order @@ -144,14 +143,15 @@ function transformArrayLiteralAssignmentPattern( lua.createNumericLiteral(index) ); - const [spreadPrecedingStatements, spreadStatements] = transformInPrecedingStatementScope(context, () => - transformAssignment( - context, - (element as ts.SpreadElement).expression, - restElements, - rightHasPrecedingStatements - ) - ); + const { precedingStatements: spreadPrecedingStatements, result: spreadStatements } = + transformInPrecedingStatementScope(context, () => + transformAssignment( + context, + (element as ts.SpreadElement).expression, + restElements, + rightHasPrecedingStatements + ) + ); return [...spreadPrecedingStatements, ...spreadStatements]; // Keep preceding statements in order case ts.SyntaxKind.OmittedExpression: return []; @@ -279,9 +279,8 @@ function transformPropertyAssignment( const left = cast(context.transformExpression(node.initializer.left), lua.isTableIndexExpression); const rightExpression = node.initializer.right; - const [defaultPrecedingStatements, defaultExpression] = transformInPrecedingStatementScope(context, () => - context.transformExpression(rightExpression) - ); + const { precedingStatements: defaultPrecedingStatements, result: defaultExpression } = + transformInPrecedingStatementScope(context, () => context.transformExpression(rightExpression)); const tableTemp = context.createTempNameForLuaExpression(left.table); const indexTemp = context.createTempNameForLuaExpression(left.index); @@ -292,7 +291,7 @@ function transformPropertyAssignment( ); // obj[index] = extractingExpression ?? defaultExpression - const [rightPrecedingStatements, rhs] = transformBinaryOperation( + const { precedingStatements: rightPrecedingStatements, result: rhs } = transformBinaryOperation( context, extractingExpression, defaultExpression, diff --git a/src/transformation/visitors/binary-expression/index.ts b/src/transformation/visitors/binary-expression/index.ts index e02615be7..f2b0acb16 100644 --- a/src/transformation/visitors/binary-expression/index.ts +++ b/src/transformation/visitors/binary-expression/index.ts @@ -16,7 +16,7 @@ import { } from "./compound"; import { assert } from "../../../utils"; import { transformOrderedExpressions } from "../expression-list"; -import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../../utils/preceding-statements"; type ShortCircuitOperator = | ts.SyntaxKind.AmpersandAmpersandToken @@ -100,7 +100,7 @@ export function createShortCircuitBinaryExpressionPrecedingStatements( rightPrecedingStatements: lua.Statement[], operator: ShortCircuitOperator, node?: ts.BinaryExpression -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { const conditionIdentifier = context.createTempNameForLuaExpression(lhs); const assignmentStatement = lua.createVariableDeclarationStatement(conditionIdentifier, lhs, node?.left); @@ -132,19 +132,19 @@ export function createShortCircuitBinaryExpressionPrecedingStatements( undefined, node?.left ); - return [[assignmentStatement, ifStatement], conditionIdentifier]; + return { precedingStatements: [assignmentStatement, ifStatement], result: conditionIdentifier }; } function transformShortCircuitBinaryExpression( context: TransformationContext, node: ts.BinaryExpression, operator: ShortCircuitOperator -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { const lhs = context.transformExpression(node.left); - const [rightPrecedingStatements, rhs] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result } = transformInPrecedingStatementScope(context, () => context.transformExpression(node.right) ); - return transformBinaryOperation(context, lhs, rhs, rightPrecedingStatements, operator, node); + return transformBinaryOperation(context, lhs, result, precedingStatements, operator, node); } export function transformBinaryOperation( @@ -154,7 +154,7 @@ export function transformBinaryOperation( rightPrecedingStatements: lua.Statement[], operator: BitOperator | SimpleOperator | ts.SyntaxKind.QuestionQuestionToken, node: ts.Node -): [lua.Statement[], lua.Expression] { +): WithPrecedingStatements { if (rightPrecedingStatements.length > 0 && isShortCircuitOperator(operator)) { assert(ts.isBinaryExpression(node)); return createShortCircuitBinaryExpressionPrecedingStatements( @@ -167,10 +167,10 @@ export function transformBinaryOperation( ); } - return [ - rightPrecedingStatements, - transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node), - ]; + return { + precedingStatements: rightPrecedingStatements, + result: transformBinaryOperationWithNoPrecedingStatements(context, left, right, operator, node), + }; } export const transformBinaryExpression: FunctionVisitor = (node, context) => { @@ -216,7 +216,7 @@ export const transformBinaryExpression: FunctionVisitor = ( case ts.SyntaxKind.CommaToken: { const statements = context.transformStatements(ts.factory.createExpressionStatement(node.left)); - const [precedingStatements, result] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result } = transformInPrecedingStatementScope(context, () => context.transformExpression(node.right) ); statements.push(...precedingStatements); @@ -227,17 +227,27 @@ export const transformBinaryExpression: FunctionVisitor = ( case ts.SyntaxKind.QuestionQuestionToken: case ts.SyntaxKind.AmpersandAmpersandToken: case ts.SyntaxKind.BarBarToken: { - const [precedingStatements, result] = transformShortCircuitBinaryExpression(context, node, operator); + const { precedingStatements, result } = transformShortCircuitBinaryExpression(context, node, operator); context.addPrecedingStatements(precedingStatements); return result; } } - let [precedingStatements, [lhs, rhs]] = transformInPrecedingStatementScope(context, () => + const { + precedingStatements: orderedExpressionPrecedingStatements, + result: [lhs, rhs], + } = transformInPrecedingStatementScope(context, () => transformOrderedExpressions(context, [node.left, node.right]) ); - let result: lua.Expression; - [precedingStatements, result] = transformBinaryOperation(context, lhs, rhs, precedingStatements, operator, node); + + const { precedingStatements, result } = transformBinaryOperation( + context, + lhs, + rhs, + orderedExpressionPrecedingStatements, + operator, + node + ); context.addPrecedingStatements(precedingStatements); return result; }; @@ -277,7 +287,7 @@ function transformNullishCoalescingOperationNoPrecedingStatements( // Check if we can take a shortcut to 'lhs or rhs' if the left-hand side cannot be 'false'. if (canBeFalsyWhenNotNull(context, lhsType)) { // reuse logic from case with preceding statements - const [precedingStatements, result] = createShortCircuitBinaryExpressionPrecedingStatements( + const { precedingStatements, result } = createShortCircuitBinaryExpressionPrecedingStatements( context, transformedLeft, transformedRight, diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 9fac8aa0f..679ae6dc1 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -80,9 +80,8 @@ export function transformCallAndArguments( signature?: ts.Signature, callContext?: ts.Expression ): [lua.Expression, lua.Expression[]] { - const [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => - transformArguments(context, params, signature, callContext) - ); + const { precedingStatements: argPrecedingStatements, result: transformedArguments } = + transformInPrecedingStatementScope(context, () => transformArguments(context, params, signature, callContext)); return transformCallWithArguments(context, callExpression, transformedArguments, argPrecedingStatements); } @@ -125,9 +124,8 @@ export function transformContextualCallExpression( } const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag; - let [argPrecedingStatements, transformedArguments] = transformInPrecedingStatementScope(context, () => - transformArguments(context, args, signature) - ); + let { precedingStatements: argPrecedingStatements, result: transformedArguments } = + transformInPrecedingStatementScope(context, () => transformArguments(context, args, signature)); if ( ts.isPropertyAccessExpression(left) && diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 4235c722d..4fe5f1fd9 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -29,7 +29,7 @@ export const transformClassDeclaration: FunctionVisitor // If declaration is a default export, transform to export variable assignment instead if (hasDefaultExportModifier(declaration)) { // Class declaration including assignment to ____exports.default are in preceding statements - const [precedingStatements] = transformInPrecedingStatementScope(context, () => { + const { precedingStatements } = transformInPrecedingStatementScope(context, () => { transformClassAsExpression(declaration, context); return []; }); diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 27075bf6e..0e7c3e51f 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -33,7 +33,7 @@ export function transformClassInstanceFields( const statements: lua.Statement[] = []; for (const f of instanceFields) { - const [precedingStatements, statement] = transformInPrecedingStatementScope(context, () => { + const { precedingStatements, result: statement } = transformInPrecedingStatementScope(context, () => { // Get identifier const fieldName = transformPropertyName(context, f.name); diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index a9b7b8d1c..178f6ac2d 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -1,36 +1,34 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../utils/preceding-statements"; import { performHoisting, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; import { truthyOnlyConditionalValue } from "../utils/diagnostics"; -type EvaluatedExpression = [precedingStatemens: lua.Statement[], value: lua.Expression]; - function transformProtectedConditionalExpression( context: TransformationContext, expression: ts.ConditionalExpression, - condition: EvaluatedExpression, - whenTrue: EvaluatedExpression, - whenFalse: EvaluatedExpression + condition: WithPrecedingStatements, + whenTrue: WithPrecedingStatements, + whenFalse: WithPrecedingStatements ): lua.Expression { const tempVar = context.createTempNameForNode(expression.condition); - const trueStatements = whenTrue[0].concat( - lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue[1], expression.whenTrue) + const trueStatements = whenTrue.precedingStatements.concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenTrue.result, expression.whenTrue) ); - const falseStatements = whenFalse[0].concat( - lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse[1], expression.whenFalse) + const falseStatements = whenFalse.precedingStatements.concat( + lua.createAssignmentStatement(lua.cloneIdentifier(tempVar), whenFalse.result, expression.whenFalse) ); context.addPrecedingStatements([ lua.createVariableDeclarationStatement(tempVar, undefined, expression.condition), - ...condition[0], + ...condition.precedingStatements, lua.createIfStatement( - condition[1], + condition.result, lua.createBlock(trueStatements, expression.whenTrue), lua.createBlock(falseStatements, expression.whenFalse), expression @@ -53,17 +51,17 @@ export const transformConditionalExpression: FunctionVisitor 0 || - whenFalse[0].length > 0 || + whenTrue.precedingStatements.length > 0 || + whenFalse.precedingStatements.length > 0 || canBeFalsy(context, context.checker.getTypeAtLocation(expression.whenTrue)) ) { return transformProtectedConditionalExpression(context, expression, condition, whenTrue, whenFalse); } // condition and v1 or v2 - context.addPrecedingStatements(condition[0]); - const conditionAnd = lua.createBinaryExpression(condition[1], whenTrue[1], lua.SyntaxKind.AndOperator); - return lua.createBinaryExpression(conditionAnd, whenFalse[1], lua.SyntaxKind.OrOperator, expression); + context.addPrecedingStatements(condition.precedingStatements); + const conditionAnd = lua.createBinaryExpression(condition.result, whenTrue.result, lua.SyntaxKind.AndOperator); + return lua.createBinaryExpression(conditionAnd, whenFalse.result, lua.SyntaxKind.OrOperator, expression); }; export function transformIfStatement(statement: ts.IfStatement, context: TransformationContext): lua.IfStatement { @@ -80,7 +78,7 @@ export function transformIfStatement(statement: ts.IfStatement, context: Transfo if (statement.elseStatement) { if (ts.isIfStatement(statement.elseStatement)) { const tsElseStatement = statement.elseStatement; - const [precedingStatements, elseStatement] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: elseStatement } = transformInPrecedingStatementScope(context, () => transformIfStatement(tsElseStatement, context) ); // If else-if condition generates preceding statements, we can't use elseif, we have to break it down: diff --git a/src/transformation/visitors/expression-list.ts b/src/transformation/visitors/expression-list.ts index 475108922..617d09d4a 100644 --- a/src/transformation/visitors/expression-list.ts +++ b/src/transformation/visitors/expression-list.ts @@ -47,9 +47,8 @@ function transformExpressions( const transformedExpressions: lua.Expression[] = []; let lastPrecedingStatementsIndex = -1; for (let i = 0; i < expressions.length; ++i) { - const [expressionPrecedingStatements, expression] = transformInPrecedingStatementScope(context, () => - context.transformExpression(expressions[i]) - ); + const { precedingStatements: expressionPrecedingStatements, result: expression } = + transformInPrecedingStatementScope(context, () => context.transformExpression(expressions[i])); transformedExpressions.push(expression); if (expressionPrecedingStatements.length > 0) { lastPrecedingStatementsIndex = i; diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index dbcd76549..f79682223 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -90,7 +90,7 @@ export function isFunctionTypeWithProperties(context: TransformationContext, fun export function transformFunctionBodyContent(context: TransformationContext, body: ts.ConciseBody): lua.Statement[] { if (!ts.isBlock(body)) { - const [precedingStatements, returnStatement] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: returnStatement } = transformInPrecedingStatementScope(context, () => transformExpressionBodyToReturnStatement(context, body) ); return [...precedingStatements, returnStatement]; @@ -123,7 +123,7 @@ export function transformFunctionBodyHeader( // Binding pattern const name = declaration.name; - const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: bindings } = transformInPrecedingStatementScope(context, () => transformBindingPattern(context, name, identifier) ); bindingPatternDeclarations.push(...precedingStatements, ...bindings); diff --git a/src/transformation/visitors/loops/do-while.ts b/src/transformation/visitors/loops/do-while.ts index 806876631..f4c714c71 100644 --- a/src/transformation/visitors/loops/do-while.ts +++ b/src/transformation/visitors/loops/do-while.ts @@ -11,8 +11,9 @@ export const transformWhileStatement: FunctionVisitor = (stat const body = transformLoopBody(context, statement); - let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - context.transformExpression(statement.expression) + let { precedingStatements: conditionPrecedingStatements, result: condition } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(statement.expression) ); // If condition has preceding statements, ensure they are executed every iteration by using the form: @@ -46,8 +47,9 @@ export const transformDoStatement: FunctionVisitor = (statement, const body = lua.createDoStatement(transformLoopBody(context, statement)); - let [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - invertCondition(context.transformExpression(statement.expression)) + let { precedingStatements: conditionPrecedingStatements, result: condition } = transformInPrecedingStatementScope( + context, + () => invertCondition(context.transformExpression(statement.expression)) ); // If condition has preceding statements, ensure they are executed every iteration by using the form: diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 3fbbb6353..3a82b5a24 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -22,11 +22,12 @@ export const transformForStatement: FunctionVisitor = (statemen let condition: lua.Expression; if (statement.condition) { - let conditionPrecedingStatements: lua.Statement[]; const tsCondition = statement.condition; - [conditionPrecedingStatements, condition] = transformInPrecedingStatementScope(context, () => - context.transformExpression(tsCondition) + const { precedingStatements: conditionPrecedingStatements, result } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(tsCondition) ); + condition = result; // If condition has preceding statements, ensure they are executed every iteration by using the form: // diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index e24a92269..7f522edb2 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -57,7 +57,7 @@ export function transformForInitializer( const binding = getVariableDeclarationBinding(context, initializer); if (ts.isArrayBindingPattern(binding) || ts.isObjectBindingPattern(binding)) { - const [precedingStatements, bindings] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: bindings } = transformInPrecedingStatementScope(context, () => transformBindingPattern(context, binding, valueVariable) ); block.statements.unshift(...precedingStatements, ...bindings); diff --git a/src/transformation/visitors/optional-chaining.ts b/src/transformation/visitors/optional-chaining.ts index 73f32b1e6..893add0f0 100644 --- a/src/transformation/visitors/optional-chaining.ts +++ b/src/transformation/visitors/optional-chaining.ts @@ -128,19 +128,20 @@ export function transformOptionalChainWithCapture( // transform right expression first to check if thisValue capture is needed // capture and return thisValue if requested from outside let returnThisValue: lua.Expression | undefined; - const [rightPrecedingStatements, rightExpression] = transformInPrecedingStatementScope(context, () => { - if (!thisValueCapture) { - return context.transformExpression(tsRightExpression); - } + const { precedingStatements: rightPrecedingStatements, result: rightExpression } = + transformInPrecedingStatementScope(context, () => { + if (!thisValueCapture) { + return context.transformExpression(tsRightExpression); + } - const { expression: result, thisValue } = transformExpressionWithThisValueCapture( - context, - tsRightExpression, - thisValueCapture - ); - returnThisValue = thisValue; - return result; - }); + const { expression: result, thisValue } = transformExpressionWithThisValueCapture( + context, + tsRightExpression, + thisValueCapture + ); + returnThisValue = thisValue; + return result; + }); // transform left expression, handle thisValue if needed by rightExpression const thisValueCaptureName = context.createTempName("this"); @@ -149,19 +150,22 @@ export function transformOptionalChainWithCapture( const optionalContinuationData = getOptionalContinuationData(tsTemp); const rightContextualCall = optionalContinuationData?.contextualCall; - const [leftPrecedingStatements, leftExpression] = transformInPrecedingStatementScope(context, () => { - let result: lua.Expression; - if (rightContextualCall) { - ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture( - context, - tsLeftExpression, - leftThisValueTemp - )); - } else { - result = context.transformExpression(tsLeftExpression); + const { precedingStatements: leftPrecedingStatements, result: leftExpression } = transformInPrecedingStatementScope( + context, + () => { + let result: lua.Expression; + if (rightContextualCall) { + ({ expression: result, thisValue: capturedThisValue } = transformExpressionWithThisValueCapture( + context, + tsLeftExpression, + leftThisValueTemp + )); + } else { + result = context.transformExpression(tsLeftExpression); + } + return result; } - return result; - }); + ); // handle context if (rightContextualCall) { if (capturedThisValue) { diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 6870d292b..4a0c62c6d 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -13,7 +13,7 @@ export const transformSourceFileNode: FunctionVisitor = (node, co const [statement] = node.statements; if (statement) { assert(ts.isExpressionStatement(statement)); - const [precedingStatements, expression] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: expression } = transformInPrecedingStatementScope(context, () => context.transformExpression(statement.expression) ); statements.push(...precedingStatements); diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 913e6ce71..04323bdbf 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; -import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; +import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../utils/preceding-statements"; import { ScopeType, separateHoistedStatements } from "../utils/scope"; import { createShortCircuitBinaryExpressionPrecedingStatements } from "./binary-expression"; @@ -24,7 +24,7 @@ const createOrExpression = ( left: lua.Expression, right: lua.Expression, rightPrecedingStatements: lua.Statement[] -): [lua.Statement[], lua.Expression] => { +): WithPrecedingStatements => { if (rightPrecedingStatements.length > 0) { return createShortCircuitBinaryExpressionPrecedingStatements( context, @@ -34,7 +34,10 @@ const createOrExpression = ( ts.SyntaxKind.BarBarToken ); } else { - return [rightPrecedingStatements, lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator)]; + return { + precedingStatements: rightPrecedingStatements, + result: lua.createBinaryExpression(left, right, lua.SyntaxKind.OrOperator), + }; } }; @@ -44,8 +47,8 @@ const coalesceCondition = ( switchVariable: lua.Identifier, expression: ts.Expression, context: TransformationContext -): [lua.Statement[], lua.Expression] => { - const [precedingStatements, transformedExpression] = transformInPrecedingStatementScope(context, () => +): WithPrecedingStatements => { + const { precedingStatements, result: transformedExpression } = transformInPrecedingStatementScope(context, () => context.transformExpression(expression) ); @@ -60,7 +63,7 @@ const coalesceCondition = ( } // Next condition - return [[...conditionPrecedingStatements, ...precedingStatements], comparison]; + return { precedingStatements: [...conditionPrecedingStatements, ...precedingStatements], result: comparison }; }; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { @@ -108,13 +111,15 @@ export const transformSwitchStatement: FunctionVisitor = (st // Compute the condition for the if statement if (!ts.isDefaultClause(clause)) { - [conditionPrecedingStatements, condition] = coalesceCondition( + const { precedingStatements, result } = coalesceCondition( condition, conditionPrecedingStatements, switchVariable, clause.expression, context ); + conditionPrecedingStatements = precedingStatements; + condition = result; // Skip empty clauses unless final clause (i.e side-effects) if (i !== clauses.length - 1 && clause.statements.length === 0) continue; @@ -126,12 +131,15 @@ export const transformSwitchStatement: FunctionVisitor = (st lua.createVariableDeclarationStatement(conditionVariable, condition) ); } else { - [conditionPrecedingStatements, condition] = createOrExpression( + const { precedingStatements, result } = createOrExpression( context, conditionVariable, condition, conditionPrecedingStatements ); + conditionPrecedingStatements = precedingStatements; + condition = result; + statements.push( ...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition) @@ -159,12 +167,14 @@ export const transformSwitchStatement: FunctionVisitor = (st if (i === clauses.length - 1) { // Evaluate the final condition that we may be skipping if (condition) { - [conditionPrecedingStatements, condition] = createOrExpression( + const { precedingStatements, result } = createOrExpression( context, conditionVariable, condition, conditionPrecedingStatements ); + conditionPrecedingStatements = precedingStatements; + condition = result; statements.push( ...conditionPrecedingStatements, lua.createAssignmentStatement(conditionVariable, condition) diff --git a/src/transformation/visitors/typeof.ts b/src/transformation/visitors/typeof.ts index aaa094491..6b70946a3 100644 --- a/src/transformation/visitors/typeof.ts +++ b/src/transformation/visitors/typeof.ts @@ -47,7 +47,7 @@ export function transformTypeOfBinaryExpression( const innerExpression = context.transformExpression(typeOfExpression.expression); const typeCall = lua.createCallExpression(lua.createIdentifier("type"), [innerExpression], typeOfExpression); - const [precedingStatements, result] = transformBinaryOperation( + const { precedingStatements, result } = transformBinaryOperation( context, typeCall, comparedExpression, diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 58dc8a76a..42a2b6538 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -71,7 +71,7 @@ export function transformBindingPattern( const variableName = transformIdentifier(context, element.name); // The field to extract const elementName = element.propertyName ?? element.name; - const [precedingStatements, propertyName] = transformInPrecedingStatementScope(context, () => + const { precedingStatements, result: propertyName } = transformInPrecedingStatementScope(context, () => transformPropertyName(context, elementName) ); result.push(...precedingStatements); // Keep property's preceding statements in order @@ -135,9 +135,8 @@ export function transformBindingPattern( if (element.initializer) { const identifier = addExportToIdentifier(context, variableName); const tsInitializer = element.initializer; - const [initializerPrecedingStatements, initializer] = transformInPrecedingStatementScope(context, () => - context.transformExpression(tsInitializer) - ); + const { precedingStatements: initializerPrecedingStatements, result: initializer } = + transformInPrecedingStatementScope(context, () => context.transformExpression(tsInitializer)); result.push( lua.createIfStatement( lua.createBinaryExpression(identifier, lua.createNilLiteral(), lua.SyntaxKind.EqualityOperator), @@ -173,8 +172,9 @@ export function transformBindingVariableDeclaration( if (isMultiReturnCall(context, initializer)) { expression = wrapInTable(expression); } - const [moveStatements, movedExpr] = transformInPrecedingStatementScope(context, () => - moveToPrecedingTemp(context, expression, initializer) + const { precedingStatements: moveStatements, result: movedExpr } = transformInPrecedingStatementScope( + context, + () => moveToPrecedingTemp(context, expression, initializer) ); statements.push(...moveStatements); table = movedExpr; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index f9e1894d5..bde9e434d 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -2,7 +2,6 @@ import * as path from "path"; import * as tstl from "../../src"; import * as util from "../util"; import * as ts from "typescript"; -import * as fs from "fs-extra"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; @@ -275,17 +274,11 @@ describe("module resolution project with dependencies built by tstl library mode describe("module resolution project with dependencies built by tstl library mode and has exports field", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-tstl-library-has-exports-field"); - const appPath = path.join(projectPath, "app"); // First compile dependencies into node_modules. NOTE: Actually writing to disk, very slow - const dependency1Path = path.join(projectPath, "dependency1-ts"); + const dependency1Path = path.join(projectPath, "node_modules", "dependency1"); tstl.transpileProject(path.join(dependency1Path, "tsconfig.json")); - // Install dependencies. This will create node_modules folder with dependency1-ts in it. - const nodeModulesPath = path.join(appPath, "node_modules"); - fs.ensureDirSync(nodeModulesPath); - fs.ensureSymlinkSync(dependency1Path, path.join(nodeModulesPath, "dependency1"), "dir"); - const expectedResult = { dependency1IndexResult: "function in dependency 1 index: dependency1OtherFileFunc in dependency1/d1otherfile", dependency1OtherFileFuncResult: "dependency1OtherFileFunc in dependency1/d1otherfile", @@ -293,8 +286,8 @@ describe("module resolution project with dependencies built by tstl library mode test("can resolve lua dependencies", () => { const transpileResult = util - .testProject(path.join(appPath, "tsconfig.json")) - .setMainFileName(path.join(appPath, "main.ts")) + .testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "main.ts")) .setOptions({ outDir: "tstl-out", moduleResolution: ts.ModuleResolutionKind.Node16 }) .expectToEqual(expectedResult) .getLuaResult(); @@ -307,8 +300,8 @@ describe("module resolution project with dependencies built by tstl library mode }); test("can resolve dependencies and bundle", () => { - const mainFile = path.join(appPath, "main.ts"); - util.testProject(path.join(appPath, "tsconfig.json")) + const mainFile = path.join(projectPath, "main.ts"); + util.testProject(path.join(projectPath, "tsconfig.json")) .setMainFileName(mainFile) .setOptions({ luaBundle: "bundle.lua", diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/main.ts similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/main.ts rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/main.ts diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/package.json similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/package.json rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/package.json diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/d1otherfile.ts similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/d1otherfile.ts rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/d1otherfile.ts diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/index.ts similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/src/index.ts rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/src/index.ts diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/tsconfig.json similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/dependency1-ts/tsconfig.json rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/node_modules/dependency1/tsconfig.json diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/package.json similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/package.json rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/package.json diff --git a/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json b/test/transpile/module-resolution/project-with-tstl-library-has-exports-field/tsconfig.json similarity index 100% rename from test/transpile/module-resolution/project-with-tstl-library-has-exports-field/app/tsconfig.json rename to test/transpile/module-resolution/project-with-tstl-library-has-exports-field/tsconfig.json From 589baeb7fcd61452b8af8097f9e8506001bcc2f6 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 12 Feb 2023 21:38:33 +0100 Subject: [PATCH 561/764] Correctly handle custom extensions during module resolution (#1400) * Correctly handle custom extensions during module resolution * Fix tests --- src/transpilation/output-collector.ts | 6 ++-- src/transpilation/resolve.ts | 38 +++++++++++++++++------- test/transpile/module-resolution.spec.ts | 8 +++++ test/util.ts | 11 ++++--- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/transpilation/output-collector.ts b/src/transpilation/output-collector.ts index 866c1f79a..1458b2403 100644 --- a/src/transpilation/output-collector.ts +++ b/src/transpilation/output-collector.ts @@ -14,7 +14,7 @@ export interface TranspiledFile { jsSourceMap?: string; } -export function createEmitOutputCollector() { +export function createEmitOutputCollector(luaExtension = ".lua") { const files: TranspiledFile[] = []; const writeFile: ts.WriteFileCallback = (fileName, data, _bom, _onError, sourceFiles = []) => { let file = files.find(f => intersection(f.sourceFiles, sourceFiles).length > 0); @@ -25,9 +25,9 @@ export function createEmitOutputCollector() { file.sourceFiles = union(file.sourceFiles, sourceFiles); } - if (fileName.endsWith(".lua")) { + if (fileName.endsWith(luaExtension)) { file.lua = data; - } else if (fileName.endsWith(".lua.map")) { + } else if (fileName.endsWith(`${luaExtension}.map`)) { file.luaSourceMap = data; } else if (fileName.endsWith(".js")) { file.js = data; diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index ad1aa1c84..558870f21 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -49,8 +49,8 @@ class ResolutionContext { // Remove @NoResolution prefix if not building in library mode if (!isBuildModeLibrary(this.program)) { const path = required.requirePath.replace("@NoResolution:", ""); - replaceRequireInCode(file, required, path); - replaceRequireInSourceMap(file, required, path); + replaceRequireInCode(file, required, path, this.options.extension); + replaceRequireInSourceMap(file, required, path, this.options.extension); } // Skip @@ -88,8 +88,8 @@ class ResolutionContext { // Figure out resolved require path and dependency output path if (shouldRewriteRequires(dependencyPath, this.program)) { const resolvedRequire = getEmitPathRelativeToOutDir(dependencyPath, this.program); - replaceRequireInCode(file, required, resolvedRequire); - replaceRequireInSourceMap(file, required, resolvedRequire); + replaceRequireInCode(file, required, resolvedRequire, this.options.extension); + replaceRequireInSourceMap(file, required, resolvedRequire, this.options.extension); } } @@ -117,8 +117,8 @@ class ResolutionContext { private couldNotResolveImport(required: LuaRequire, file: ProcessedFile): void { const fallbackRequire = fallbackResolve(required, getSourceDir(this.program), path.dirname(file.fileName)); - replaceRequireInCode(file, required, fallbackRequire); - replaceRequireInSourceMap(file, required, fallbackRequire); + replaceRequireInCode(file, required, fallbackRequire, this.options.extension); + replaceRequireInSourceMap(file, required, fallbackRequire, this.options.extension); this.diagnostics.push( couldNotResolveRequire(required.requirePath, path.relative(getProjectRoot(this.program), file.fileName)) @@ -310,16 +310,26 @@ function isBuildModeLibrary(program: ts.Program) { return program.getCompilerOptions().buildMode === BuildMode.Library; } -function replaceRequireInCode(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void { - const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); +function replaceRequireInCode( + file: ProcessedFile, + originalRequire: LuaRequire, + newRequire: string, + extension: string | undefined +): void { + const requirePath = requirePathForFile(newRequire, extension); file.code = file.code = file.code.substring(0, originalRequire.from) + `require("${requirePath}")` + file.code.substring(originalRequire.to + 1); } -function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: LuaRequire, newRequire: string): void { - const requirePath = formatPathToLuaPath(newRequire.replace(".lua", "")); +function replaceRequireInSourceMap( + file: ProcessedFile, + originalRequire: LuaRequire, + newRequire: string, + extension?: string | undefined +): void { + const requirePath = requirePathForFile(newRequire, extension); if (file.sourceMapNode) { replaceInSourceMap( file.sourceMapNode, @@ -330,6 +340,14 @@ function replaceRequireInSourceMap(file: ProcessedFile, originalRequire: LuaRequ } } +function requirePathForFile(filePath: string, extension = ".lua"): string { + if (filePath.endsWith(extension)) { + return formatPathToLuaPath(filePath.substring(0, filePath.length - extension.length)); + } else { + return formatPathToLuaPath(filePath); + } +} + function replaceInSourceMap(node: SourceNode, parent: SourceNode, require: string, resolvedRequire: string): boolean { if ((!node.children || node.children.length === 0) && node.toString() === require) { parent.children = [new SourceNode(node.line, node.column, node.source, [resolvedRequire])]; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index bde9e434d..f95771687 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -174,6 +174,14 @@ describe("module resolution with sourceDir", () => { .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) .expectToEqual(expectedResult); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1394 + test("can resolve files with non-standard extension (#1394)", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out", extension: ".script" }) + .expectToEqual(expectedResult); + }); }); describe("module resolution project with lua sources", () => { diff --git a/test/util.ts b/test/util.ts index 8650f88ca..c86d40453 100644 --- a/test/util.ts +++ b/test/util.ts @@ -236,7 +236,7 @@ export abstract class TestBuilder { public getLuaResult(): tstl.TranspileVirtualProjectResult { const program = this.getProgram(); const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics: transpileDiagnostics } = new tstl.Transpiler({ emitHost: this.getEmitHost() }).emit({ program, customTransformers: this.customTransformers, @@ -277,7 +277,7 @@ export abstract class TestBuilder { const program = this.getProgram(); program.getCompilerOptions().module = ts.ModuleKind.CommonJS; - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics } = program.emit(undefined, collector.writeFile); return { transpiledFiles: collector.files, diagnostics: [...diagnostics] }; } @@ -468,7 +468,10 @@ end)());`; } private injectLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { - const modName = formatPathToLuaPath(fileName.replace(".lua", "")); + const extension = this.options.extension ?? ".lua"; + const modName = fileName.endsWith(extension) + ? formatPathToLuaPath(fileName.substring(0, fileName.length - extension.length)) + : fileName; if (this.options.luaTarget === tstl.LuaTarget.Lua50) { // Adding source Lua to the _LOADED cache will allow require to find it lua.lua_getglobal(state, "_LOADED"); @@ -610,7 +613,7 @@ class ProjectTestBuilder extends ModuleTestBuilder { @memoize public getLuaResult(): tstl.TranspileVirtualProjectResult { // Override getLuaResult to use transpileProject with tsconfig.json instead - const collector = createEmitOutputCollector(); + const collector = createEmitOutputCollector(this.options.extension); const { diagnostics } = transpileProject(this.tsConfig, this.options, collector.writeFile); return { diagnostics: [...diagnostics], transpiledFiles: collector.files }; From e215973ac4f411ea353b0c7816bbc918c1104827 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 12 Feb 2023 21:41:47 +0100 Subject: [PATCH 562/764] CHANGELOG.md 1.13.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d576bb391..13ecfd9a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.13.0 + +- Fixed alternate file extensions (other than .lua, if configured) breaking module resolution and emitted require statements. +- Added experimental support for `"luaLibImport": "require-minimal"` configuration option. This will output a lualib bundle containing only the lualib functions used by your code. This might not work if you are including external tstl-generated Lua, for example from a npm package. +- Added support for the "exports" field in package.json. +- Fixed some exceptions resulting from invalid language-extensions use. +- Fixed an exception when using compound assignment (like `+=`) with array length. + ## 1.12.0 - Reworked how tstl detects and rewrites `require` statements during dependency resolution. This should reduce the amount of false-positive matches of require statements: require statements in string literals or comments should no longer be detected by tstl. This means require statements in string literals or comments can survive the transpiler without causing a 'could not resolve lua sources' error or getting rewritten into nonsense. From 9c79d72ffda4a384fec658fe1c1cffb7a9110730 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 12 Feb 2023 22:00:31 +0100 Subject: [PATCH 563/764] 1.13.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6975939b4..0f8ce69be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.12.1", + "version": "1.13.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.12.1", + "version": "1.13.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index bc4f19525..c90d1880d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.12.1", + "version": "1.13.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 16cd2d5805af8166e2d9e7804e14ad4713ad34c2 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 16 Feb 2023 12:12:17 +0100 Subject: [PATCH 564/764] Set lualib tsconfig to strict (#1401) --- package-lock.json | 3682 ++++++++++------- package.json | 12 +- src/lualib/ArrayFrom.ts | 2 +- src/lualib/ArrayReduce.ts | 2 +- src/lualib/ArrayReduceRight.ts | 2 +- src/lualib/ArraySetLength.ts | 2 +- src/lualib/ArraySplice.ts | 8 +- src/lualib/Decorate.ts | 4 +- src/lualib/DecorateParam.ts | 2 +- src/lualib/Error.ts | 4 +- src/lualib/InstanceOf.ts | 4 +- src/lualib/LuaIteratorSpread.ts | 2 +- src/lualib/Map.ts | 34 +- src/lualib/ObjectEntries.ts | 7 +- src/lualib/ObjectGetOwnPropertyDescriptor.ts | 2 +- src/lualib/ObjectGetOwnPropertyDescriptors.ts | 2 +- src/lualib/ParseFloat.ts | 2 +- src/lualib/ParseInt.ts | 2 +- src/lualib/Promise.ts | 10 +- src/lualib/Set.ts | 26 +- src/lualib/SetDescriptor.ts | 4 +- src/lualib/SourceMapTraceBack.ts | 16 +- src/lualib/Spread.ts | 4 +- src/lualib/Symbol.ts | 2 +- src/lualib/SymbolRegistry.ts | 4 +- src/lualib/WeakMap.ts | 4 +- src/lualib/WeakSet.ts | 4 +- src/lualib/tsconfig.json | 5 +- src/lualib/tsconfig.lua50.json | 5 +- 29 files changed, 2293 insertions(+), 1566 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f8ce69be..4d461e679 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,15 +23,15 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.36.1", - "@typescript-eslint/parser": "^5.36.1", - "eslint": "^8.23.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.8.7", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^28.1.3", - "jest-circus": "^29.0.1", + "jest-circus": "^29.4.2", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", @@ -72,34 +72,34 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", - "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.13", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "engines": { @@ -120,12 +120,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, "dependencies": { - "@babel/types": "^7.18.13", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -148,14 +148,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.18.8", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -184,13 +185,13 @@ } }, "node_modules/@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -221,40 +222,40 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -273,18 +274,18 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true, "engines": { "node": ">=6.9.0" @@ -300,14 +301,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, "dependencies": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -399,9 +400,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -573,12 +574,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -588,33 +589,33 @@ } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -632,13 +633,13 @@ } }, "node_modules/@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, "engines": { @@ -674,15 +675,15 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -697,29 +698,19 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -946,39 +937,39 @@ "dev": true }, "node_modules/@jest/environment": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.1.tgz", - "integrity": "sha512-iLcFfoq2K6DAB+Mc+2VNLzZVmHdwQFeSqvoM/X8SMON6s/+yEi1iuRX3snx/JfwSnvmiMXjSr0lktxNxOcqXYA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", + "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/fake-timers": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", - "jest-mock": "^29.0.1" + "jest-mock": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/environment/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -989,76 +980,82 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/environment/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/@jest/expect": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.1.tgz", - "integrity": "sha512-qKB3q52XDV8VUEiqKKLgLrJx7puQ8sYVqIDlul6n7SIXWS97DOK3KqbR2rDDaMtmenRHqEUl2fI+aFzx0oSemA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", + "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", "dev": true, "dependencies": { - "expect": "^29.0.1", - "jest-snapshot": "^29.0.1" + "expect": "^29.4.2", + "jest-snapshot": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.1.tgz", - "integrity": "sha512-Tw5kUUOKmXGQDmQ9TSgTraFFS7HMC1HG/B7y0AN2G2UzjdAXz9BzK2rmNpCSDl7g7y0Gf/VLBm//blonvhtOTQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", + "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", "dev": true, "dependencies": { - "jest-get-type": "^29.0.0" + "jest-get-type": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/@jest/transform": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", - "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", + "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1069,6 +1066,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/expect/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/@jest/expect/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -1081,45 +1084,51 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@jest/expect/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/@jest/expect/node_modules/diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-haste-map": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", - "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", + "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "jest-worker": "^29.0.1", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", + "jest-worker": "^29.4.2", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -1131,33 +1140,33 @@ } }, "node_modules/@jest/expect/node_modules/jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1166,18 +1175,18 @@ } }, "node_modules/@jest/expect/node_modules/jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", + "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-snapshot": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", - "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", + "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -1186,23 +1195,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/expect-utils": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.1", + "expect": "^29.4.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-haste-map": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "semver": "^7.3.5" }, "engines": { @@ -1210,12 +1219,12 @@ } }, "node_modules/@jest/expect/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1227,12 +1236,13 @@ } }, "node_modules/@jest/expect/node_modules/jest-worker": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", - "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", + "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", "dev": true, "dependencies": { "@types/node": "*", + "jest-util": "^29.4.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -1241,12 +1251,12 @@ } }, "node_modules/@jest/expect/node_modules/pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -1276,41 +1286,41 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.1.tgz", - "integrity": "sha512-XZ+kAhLChVQ+KJNa5034p7O1Mz3vtWrelxDcMoxhZkgqmWDaEQAW9qJeutaeCfPvwaEwKYVyKDYfWpcyT8RiMw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", + "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", - "@sinonjs/fake-timers": "^9.1.2", + "@jest/types": "^29.4.2", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.0.1", - "jest-mock": "^29.0.1", - "jest-util": "^29.0.1" + "jest-message-util": "^29.4.2", + "jest-mock": "^29.4.2", + "jest-util": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1321,6 +1331,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/@jest/fake-timers/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -1334,18 +1350,18 @@ } }, "node_modules/@jest/fake-timers/node_modules/jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1354,12 +1370,12 @@ } }, "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1371,12 +1387,12 @@ } }, "node_modules/@jest/fake-timers/node_modules/pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -1461,6 +1477,24 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/@jest/globals/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@jest/globals/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, "node_modules/@jest/globals/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -1752,13 +1786,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -1797,27 +1831,27 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.24.28", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", - "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^2.0.0" } }, "node_modules/@tsconfig/node10": { @@ -1845,13 +1879,13 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -1877,9 +1911,9 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", - "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" @@ -1905,9 +1939,9 @@ } }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "dependencies": { "@types/node": "*" @@ -1960,9 +1994,9 @@ "dev": true }, "node_modules/@types/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, "node_modules/@types/node": { @@ -1972,9 +2006,9 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, "node_modules/@types/resolve": { @@ -1987,9 +2021,9 @@ } }, "node_modules/@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1999,9 +2033,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", - "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -2014,17 +2048,18 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", + "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/type-utils": "5.52.0", + "@typescript-eslint/utils": "5.52.0", "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" @@ -2047,14 +2082,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", + "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", "debug": "^4.3.4" }, "engines": { @@ -2074,13 +2109,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", + "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2091,13 +2126,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", + "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/utils": "5.52.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2118,9 +2153,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", + "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2131,13 +2166,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", + "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2158,17 +2193,19 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", + "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2182,12 +2219,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", + "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/types": "5.52.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -2204,9 +2241,9 @@ "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2301,9 +2338,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -2326,15 +2363,15 @@ "dev": true }, "node_modules/array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" }, "engines": { @@ -2354,14 +2391,32 @@ } }, "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -2371,6 +2426,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-jest": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", @@ -2491,9 +2558,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "funding": [ { @@ -2506,10 +2573,10 @@ } ], "dependencies": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" }, "bin": { "browserslist": "cli.js" @@ -2577,9 +2644,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001383", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", - "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", + "version": "1.0.30001451", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", + "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", "dev": true, "funding": [ { @@ -2618,10 +2685,19 @@ } }, "node_modules/ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", - "dev": true + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -2630,14 +2706,17 @@ "dev": true }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/co": { @@ -2681,13 +2760,10 @@ "dev": true }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "node_modules/create-require": { "version": "1.1.1", @@ -2739,18 +2815,18 @@ "dev": true }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", "dev": true, "engines": { "node": ">=0.10.0" } }, "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "dependencies": { "has-property-descriptors": "^1.0.0", @@ -2815,9 +2891,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.4.233", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz", - "integrity": "sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw==", + "version": "1.4.295", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", + "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", "dev": true }, "node_modules/emittery": { @@ -2839,9 +2915,9 @@ "dev": true }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -2860,34 +2936,44 @@ } }, "node_modules/es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, "dependencies": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" }, "engines": { "node": ">= 0.4" @@ -2896,6 +2982,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-shim-unscopables": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", @@ -2944,15 +3044,15 @@ } }, "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", + "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -2968,15 +3068,15 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -3000,13 +3100,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", "dev": true, "dependencies": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -3045,23 +3146,25 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", "dev": true, "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", "has": "^1.0.3", - "is-core-module": "^2.8.1", + "is-core-module": "^2.11.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", "tsconfig-paths": "^3.14.1" }, "engines": { @@ -3072,12 +3175,12 @@ } }, "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "node_modules/eslint-plugin-import/node_modules/doctrine": { @@ -3092,16 +3195,19 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } }, "node_modules/eslint-plugin-jest": { - "version": "26.8.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", - "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", + "version": "26.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", + "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -3194,9 +3300,9 @@ } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -3316,40 +3422,40 @@ } }, "node_modules/expect": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.1.tgz", - "integrity": "sha512-yQgemsjLU+1S8t2A7pXT3Sn/v5/37LY8J+tocWtKEA0iEYYc6gfKbbJJX2fxHZmd7K9WpdbQqXUpmYkq1aewYg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", + "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1" + "@jest/expect-utils": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -3360,6 +3466,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/expect/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/expect/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -3373,57 +3485,57 @@ } }, "node_modules/expect/node_modules/diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -3432,12 +3544,12 @@ } }, "node_modules/expect/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -3449,12 +3561,12 @@ } }, "node_modules/expect/node_modules/pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -3475,9 +3587,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3515,18 +3627,18 @@ "dev": true }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { "reusify": "^1.0.4" } }, "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "dependencies": { "bser": "2.1.1" @@ -3591,6 +3703,15 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -3648,12 +3769,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -3682,9 +3797,9 @@ } }, "node_modules/get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "dependencies": { "function-bind": "^1.1.1", @@ -3765,9 +3880,9 @@ } }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3779,6 +3894,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -3799,6 +3929,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -3851,6 +3993,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -3894,9 +4048,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -3963,12 +4117,12 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" }, @@ -3976,6 +4130,20 @@ "node": ">= 0.4" } }, + "node_modules/is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -4011,9 +4179,9 @@ } }, "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { "node": ">= 0.4" @@ -4023,9 +4191,9 @@ } }, "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dependencies": { "has": "^1.0.3" }, @@ -4123,6 +4291,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -4193,6 +4370,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4221,9 +4417,9 @@ } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", @@ -4341,28 +4537,28 @@ } }, "node_modules/jest-circus": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.1.tgz", - "integrity": "sha512-I5J4LyK3qPo8EnqPmxsMAVR+2SFx7JOaZsbqW9xQmk4UDmTCD92EQgS162Ey3Jq6CfpKJKFDhzhG3QqiE0fRbw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", + "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.1", - "@jest/expect": "^29.0.1", - "@jest/test-result": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/environment": "^29.4.2", + "@jest/expect": "^29.4.2", + "@jest/test-result": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-runtime": "^29.0.1", - "jest-snapshot": "^29.0.1", - "jest-util": "^29.0.1", + "jest-each": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-runtime": "^29.4.2", + "jest-snapshot": "^29.4.2", + "jest-util": "^29.4.2", "p-limit": "^3.1.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4371,16 +4567,16 @@ } }, "node_modules/jest-circus/node_modules/@jest/console": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.1.tgz", - "integrity": "sha512-SxLvSKf9gk4Rvt3p2KRQWVQ3sVj7S37rjlCHwp2+xNcRO/X+Uw0idbkfOtciUpjghHIxyggqcrrKhThQ+vClLQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", + "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "slash": "^3.0.0" }, "engines": { @@ -4388,36 +4584,36 @@ } }, "node_modules/jest-circus/node_modules/@jest/globals": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.1.tgz", - "integrity": "sha512-BtZWrVrKRKNUt7T1H2S8Mz31PN7ItROCmH+V5pn10hJDUfjOCTIUwb0WtLZzm0f1tJ3Uvx+5lVZrF/VTKqNaFg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", + "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.1", - "@jest/expect": "^29.0.1", - "@jest/types": "^29.0.1", - "jest-mock": "^29.0.1" + "@jest/environment": "^29.4.2", + "@jest/expect": "^29.4.2", + "@jest/types": "^29.4.2", + "jest-mock": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/@jest/source-map": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", - "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", + "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", @@ -4429,13 +4625,13 @@ } }, "node_modules/jest-circus/node_modules/@jest/test-result": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.1.tgz", - "integrity": "sha512-XCA4whh/igxjBaR/Hg8qwFd/uTsauoD7QAdAYUjV2CSGx0+iunhjoCRRWTwqjQrETRqOJABx6kNfw0+C0vMSgQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", + "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", "dev": true, "dependencies": { - "@jest/console": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/console": "^29.4.2", + "@jest/types": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -4444,38 +4640,38 @@ } }, "node_modules/jest-circus/node_modules/@jest/transform": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", - "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", + "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -4486,6 +4682,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-circus/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/jest-circus/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -4510,45 +4712,51 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jest-circus/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/jest-circus/node_modules/diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-haste-map": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", - "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", + "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "jest-worker": "^29.0.1", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", + "jest-worker": "^29.4.2", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4560,33 +4768,33 @@ } }, "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4595,28 +4803,28 @@ } }, "node_modules/jest-circus/node_modules/jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", + "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-resolve": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.1.tgz", - "integrity": "sha512-dwb5Z0lLZbptlBtPExqsHfdDamXeiRLv4vdkfPrN84vBwLSWHWcXjlM2JXD/KLSQfljBcXbzI/PDvUJuTQ84Nw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", + "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", + "jest-haste-map": "^29.4.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.1", - "jest-validate": "^29.0.1", + "jest-util": "^29.4.2", + "jest-validate": "^29.4.2", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { @@ -4624,31 +4832,32 @@ } }, "node_modules/jest-circus/node_modules/jest-runtime": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.1.tgz", - "integrity": "sha512-yDgz5OE0Rm44PUAfTqwA6cDFnTYnVcYbRpPECsokSASQ0I5RXpnKPVr2g0CYZWKzbsXqqtmM7TIk7CAutZJ7gQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.0.1", - "@jest/fake-timers": "^29.0.1", - "@jest/globals": "^29.0.1", - "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", + "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.2", + "@jest/fake-timers": "^29.4.2", + "@jest/globals": "^29.4.2", + "@jest/source-map": "^29.4.2", + "@jest/test-result": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-mock": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.1", - "jest-snapshot": "^29.0.1", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-mock": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-resolve": "^29.4.2", + "jest-snapshot": "^29.4.2", + "jest-util": "^29.4.2", + "semver": "^7.3.5", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4657,9 +4866,9 @@ } }, "node_modules/jest-circus/node_modules/jest-snapshot": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", - "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", + "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -4668,23 +4877,23 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/expect-utils": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.1", + "expect": "^29.4.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-haste-map": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "semver": "^7.3.5" }, "engines": { @@ -4692,12 +4901,12 @@ } }, "node_modules/jest-circus/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -4709,29 +4918,30 @@ } }, "node_modules/jest-circus/node_modules/jest-validate": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.1.tgz", - "integrity": "sha512-mS4q7F738YXZFWBPqE+NjHU/gEOs7IBIFQ8i9zq5EO691cLrUbLhFq4larf8/lNcmauRO71tn/+DTW2y+MrLow==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", + "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", + "jest-get-type": "^29.4.2", "leven": "^3.1.0", - "pretty-format": "^29.0.1" + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-worker": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", - "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", + "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", "dev": true, "dependencies": { "@types/node": "*", + "jest-util": "^29.4.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -4740,12 +4950,12 @@ } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4759,6 +4969,15 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "node_modules/jest-circus/node_modules/resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-circus/node_modules/supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -4910,6 +5129,24 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-config/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/jest-config/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, "node_modules/jest-config/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -5103,40 +5340,40 @@ } }, "node_modules/jest-each": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.1.tgz", - "integrity": "sha512-UmCZYU9LPvRfSDoCrKJqrCNmgTYGGb3Ga6IVsnnVjedBTRRR9GJMca7UmDKRrJ1s+U632xrVtiRD27BxaG1aaQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", + "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", - "jest-util": "^29.0.1", - "pretty-format": "^29.0.1" + "jest-get-type": "^29.4.2", + "jest-util": "^29.4.2", + "pretty-format": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -5147,6 +5384,12 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-each/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "node_modules/jest-each/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -5160,12 +5403,12 @@ } }, "node_modules/jest-each/node_modules/jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -5177,12 +5420,12 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -5245,6 +5488,24 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-environment-node/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, "node_modules/jest-environment-node/node_modules/jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -5259,9 +5520,9 @@ } }, "node_modules/jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", + "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5425,37 +5686,38 @@ "dev": true }, "node_modules/jest-mock": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.1.tgz", - "integrity": "sha512-i1yTceg2GKJwUNZFjIzrH7Y74fN1SKJWxQX/Vu3LT4TiJerFARH5l+4URNyapZ+DNpchHYrGOP2deVbn3ma8JA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", + "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.1", - "@types/node": "*" + "@jest/types": "^29.4.2", + "@types/node": "*", + "jest-util": "^29.4.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock/node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock/node_modules/@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -5466,10 +5728,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-mock/node_modules/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "node_modules/jest-mock/node_modules/jest-util": { + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -5589,6 +5874,24 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-runner/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, "node_modules/jest-runner/node_modules/jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -5667,6 +5970,24 @@ "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" } }, + "node_modules/jest-runtime/node_modules/@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, "node_modules/jest-runtime/node_modules/jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -5959,6 +6280,16 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -6008,9 +6339,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -6093,21 +6424,18 @@ "dev": true }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/lua-types": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", - "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", "dev": true }, "node_modules/lua-wasm-bindings": { @@ -6209,10 +6537,13 @@ } }, "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": true + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/ms": { "version": "2.1.2", @@ -6226,6 +6557,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6233,9 +6570,9 @@ "dev": true }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, "node_modules/normalize-path": { @@ -6260,9 +6597,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6296,14 +6633,14 @@ } }, "node_modules/object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { "node": ">= 0.4" @@ -6564,9 +6901,9 @@ } }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -6618,9 +6955,9 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" @@ -6737,9 +7074,9 @@ } }, "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", "dev": true, "engines": { "node": ">=10" @@ -6793,16 +7130,24 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6814,6 +7159,24 @@ "node": ">=10" } }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -6904,9 +7267,9 @@ "dev": true }, "node_modules/stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -6952,28 +7315,28 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -7034,9 +7397,9 @@ } }, "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "dependencies": { "has-flag": "^4.0.0", @@ -7227,9 +7590,9 @@ } }, "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { "minimist": "^1.2.0" @@ -7301,10 +7664,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -7339,9 +7716,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "funding": [ { @@ -7433,6 +7810,26 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -7488,24 +7885,24 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" @@ -7563,31 +7960,31 @@ } }, "@babel/compat-data": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.13.tgz", - "integrity": "sha512-5yUzC5LqyTFp2HLmDoxGQelcdYgSpP9xsnMWBphAscOdFrHSAVbLNzWiy32sVNDqJRDiJK6klfDnAgu6PAGSHw==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", "dev": true }, "@babel/core": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.13.tgz", - "integrity": "sha512-ZisbOvRRusFktksHSG6pjj1CSvkPkcZq/KHD45LAkVP/oiHJkNBZWfpvlLmX8OtHDG8IuzsFlVRWo08w7Qxn0A==", + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", - "@babel/helper-compilation-targets": "^7.18.9", - "@babel/helper-module-transforms": "^7.18.9", - "@babel/helpers": "^7.18.9", - "@babel/parser": "^7.18.13", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", + "json5": "^2.2.2", "semver": "^6.3.0" }, "dependencies": { @@ -7600,12 +7997,12 @@ } }, "@babel/generator": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.13.tgz", - "integrity": "sha512-CkPg8ySSPuHTYPJYo7IRALdqyjM9HCbt/3uOBEFbzyGVP6Mn8bwFPB0jX6982JVNBlYzM1nnPkfjuXSOPtQeEQ==", + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, "requires": { - "@babel/types": "^7.18.13", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -7624,14 +8021,15 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz", - "integrity": "sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.18.8", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.20.2", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "dependencies": { @@ -7650,13 +8048,13 @@ "dev": true }, "@babel/helper-function-name": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz", - "integrity": "sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/types": "^7.18.9" + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, "@babel/helper-hoist-variables": { @@ -7678,34 +8076,34 @@ } }, "@babel/helper-module-transforms": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz", - "integrity": "sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g==", + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" } }, "@babel/helper-plugin-utils": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz", - "integrity": "sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" } }, "@babel/helper-split-export-declaration": { @@ -7718,15 +8116,15 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz", - "integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g==", + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", "dev": true }, "@babel/helper-validator-option": { @@ -7736,14 +8134,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz", - "integrity": "sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, "requires": { - "@babel/template": "^7.18.6", - "@babel/traverse": "^7.18.9", - "@babel/types": "^7.18.9" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" } }, "@babel/highlight": { @@ -7816,9 +8214,9 @@ } }, "@babel/parser": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.13.tgz", - "integrity": "sha512-dgXcIfMuQ0kgzLB2b9tRZs7TTFFaGM2AbtA4fJgUUYukzGH4jwsS7hzQHEGs67jdehpm22vkgKwvbU+aEflgwg==", + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -7939,39 +8337,39 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.13.tgz", - "integrity": "sha512-N6kt9X1jRMLPxxxPYWi7tgvJRH/rtoU+dbKAPDM44RFHiMH8igdsaSBgFeskhSl/kLWLDUvIh1RXCrTmg0/zvA==", + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.18.13", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.18.13", - "@babel/types": "^7.18.13", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -7985,13 +8383,13 @@ } }, "@babel/types": { - "version": "7.18.13", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.13.tgz", - "integrity": "sha512-ePqfTihzW0W6XAU+aMw2ykilisStJfDnsejDCXRchCcMJ4O0+8DhPXf2YUbZ6wjBlsEmZwLK/sPweWtu8hcJYQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.18.6", + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } }, @@ -8023,15 +8421,15 @@ } }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -8040,22 +8438,16 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz", - "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "dev": true - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -8229,91 +8621,97 @@ } }, "@jest/environment": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.1.tgz", - "integrity": "sha512-iLcFfoq2K6DAB+Mc+2VNLzZVmHdwQFeSqvoM/X8SMON6s/+yEi1iuRX3snx/JfwSnvmiMXjSr0lktxNxOcqXYA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", + "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", "dev": true, "requires": { - "@jest/fake-timers": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/fake-timers": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", - "jest-mock": "^29.0.1" + "jest-mock": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } + }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true } } }, "@jest/expect": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.1.tgz", - "integrity": "sha512-qKB3q52XDV8VUEiqKKLgLrJx7puQ8sYVqIDlul6n7SIXWS97DOK3KqbR2rDDaMtmenRHqEUl2fI+aFzx0oSemA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", + "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", "dev": true, "requires": { - "expect": "^29.0.1", - "jest-snapshot": "^29.0.1" + "expect": "^29.4.2", + "jest-snapshot": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/transform": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", - "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", + "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8321,89 +8719,101 @@ "chalk": "^4.0.0" } }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true }, "jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-haste-map": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", - "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", + "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "jest-worker": "^29.0.1", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", + "jest-worker": "^29.4.2", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", + "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", "dev": true }, "jest-snapshot": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", - "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", + "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -8412,33 +8822,33 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/expect-utils": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.1", + "expect": "^29.4.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-haste-map": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "semver": "^7.3.5" } }, "jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8447,23 +8857,24 @@ } }, "jest-worker": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", - "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", + "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.4.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -8486,44 +8897,44 @@ } }, "@jest/expect-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.1.tgz", - "integrity": "sha512-Tw5kUUOKmXGQDmQ9TSgTraFFS7HMC1HG/B7y0AN2G2UzjdAXz9BzK2rmNpCSDl7g7y0Gf/VLBm//blonvhtOTQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", + "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", "dev": true, "requires": { - "jest-get-type": "^29.0.0" + "jest-get-type": "^29.4.2" } }, "@jest/fake-timers": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.1.tgz", - "integrity": "sha512-XZ+kAhLChVQ+KJNa5034p7O1Mz3vtWrelxDcMoxhZkgqmWDaEQAW9qJeutaeCfPvwaEwKYVyKDYfWpcyT8RiMw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", + "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", "dev": true, "requires": { - "@jest/types": "^29.0.1", - "@sinonjs/fake-timers": "^9.1.2", + "@jest/types": "^29.4.2", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.0.1", - "jest-mock": "^29.0.1", - "jest-util": "^29.0.1" + "jest-message-util": "^29.4.2", + "jest-mock": "^29.4.2", + "jest-util": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8531,6 +8942,12 @@ "chalk": "^4.0.0" } }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -8538,29 +8955,29 @@ "dev": true }, "jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8569,12 +8986,12 @@ } }, "pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -8643,6 +9060,24 @@ "jest-util": "^28.1.3" } }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -8871,13 +9306,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@nodelib/fs.scandir": { @@ -8907,27 +9342,27 @@ } }, "@sinclair/typebox": { - "version": "0.24.28", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.28.tgz", - "integrity": "sha512-dgJd3HLOkLmz4Bw50eZx/zJwtBq65nms3N9VBYu5LTjJ883oBFkTyXRlCB/ZGGwqYpJJHA5zW2Ibhl5ngITfow==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "requires": { "type-detect": "4.0.8" } }, "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^2.0.0" } }, "@tsconfig/node10": { @@ -8955,13 +9390,13 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" @@ -8987,9 +9422,9 @@ } }, "@types/babel__traverse": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.0.tgz", - "integrity": "sha512-v4Vwdko+pgymgS+A2UIaJru93zQd85vIGWObM5ekZNdXCKtDYqATlEYnWgfo86Q6I1Lh0oXnksDnMU1cwmlPDw==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "requires": { "@babel/types": "^7.3.0" @@ -9015,9 +9450,9 @@ } }, "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "requires": { "@types/node": "*" @@ -9070,9 +9505,9 @@ "dev": true }, "@types/minimatch": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.0.tgz", - "integrity": "sha512-0RJHq5FqDWo17kdHe+SMDJLfxmLaqHbWnqZ6gNKzDvStUlrmx/eKIY17+ifLS1yybo7X86aUshQMlittDOVNnw==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, "@types/node": { @@ -9082,9 +9517,9 @@ "dev": true }, "@types/prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.0.tgz", - "integrity": "sha512-RI1L7N4JnW5gQw2spvL7Sllfuf1SaHdrZpCHiBlCXjIlufi1SMNnbu2teze3/QE67Fg2tBlH7W+mi4hVNk4p0A==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "dev": true }, "@types/resolve": { @@ -9097,9 +9532,9 @@ } }, "@types/semver": { - "version": "7.3.12", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz", - "integrity": "sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A==", + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "@types/stack-utils": { @@ -9109,9 +9544,9 @@ "dev": true }, "@types/yargs": { - "version": "17.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.11.tgz", - "integrity": "sha512-aB4y9UDUXTSMxmM4MH+YnuR0g5Cph3FLQBoWoMB21DSvFVAxRVEHEMx3TLh+zUZYMCQtKiqazz0Q4Rre31f/OA==", + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -9124,70 +9559,71 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.36.1.tgz", - "integrity": "sha512-iC40UK8q1tMepSDwiLbTbMXKDxzNy+4TfPWgIL661Ym0sD42vRcQU93IsZIrmi+x292DBr60UI/gSwfdVYexCA==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", + "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/type-utils": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/type-utils": "5.52.0", + "@typescript-eslint/utils": "5.52.0", "debug": "^4.3.4", - "functional-red-black-tree": "^1.0.1", + "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/parser": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.36.1.tgz", - "integrity": "sha512-/IsgNGOkBi7CuDfUbwt1eOqUXF9WGVBW9dwEe1pi+L32XrTsZIgmDFIi2RxjzsvB/8i+MIf5JIoTEH8LOZ368A==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", + "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.36.1.tgz", - "integrity": "sha512-pGC2SH3/tXdu9IH3ItoqciD3f3RRGCh7hb9zPdN2Drsr341zgd6VbhP5OHQO/reUqihNltfPpMpTNihFMarP2w==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", + "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1" + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0" } }, "@typescript-eslint/type-utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.36.1.tgz", - "integrity": "sha512-xfZhfmoQT6m3lmlqDvDzv9TiCYdw22cdj06xY0obSznBsT///GK5IEZQdGliXpAOaRL34o8phEvXzEo/VJx13Q==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", + "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.36.1", - "@typescript-eslint/utils": "5.36.1", + "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/utils": "5.52.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.36.1.tgz", - "integrity": "sha512-jd93ShpsIk1KgBTx9E+hCSEuLCUFwi9V/urhjOWnOaksGZFbTOxAT47OH2d4NLJnLhkVD+wDbB48BuaycZPLBg==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", + "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.36.1.tgz", - "integrity": "sha512-ih7V52zvHdiX6WcPjsOdmADhYMDN15SylWRZrT2OMy80wzKbc79n8wFW0xpWpU0x3VpBz/oDgTm2xwDAnFTl+g==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", + "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/visitor-keys": "5.36.1", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/visitor-keys": "5.52.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9196,26 +9632,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.36.1.tgz", - "integrity": "sha512-lNj4FtTiXm5c+u0pUehozaUWhh7UYKnwryku0nxJlYUEWetyG92uw2pr+2Iy4M/u0ONMKzfrx7AsGBTCzORmIg==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", + "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.36.1", - "@typescript-eslint/types": "5.36.1", - "@typescript-eslint/typescript-estree": "5.36.1", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.52.0", + "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/typescript-estree": "5.52.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.36.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.36.1.tgz", - "integrity": "sha512-ojB9aRyRFzVMN3b5joSYni6FAS10BBSCAfKJhjJAV08t/a95aM6tAhz+O1jF+EtgxktuSO3wJysp2R+Def/IWQ==", + "version": "5.52.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", + "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.36.1", + "@typescript-eslint/types": "5.52.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9225,9 +9663,9 @@ "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, "acorn-jsx": { @@ -9288,9 +9726,9 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", @@ -9310,15 +9748,15 @@ "dev": true }, "array-includes": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", - "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5", - "get-intrinsic": "^1.1.1", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", "is-string": "^1.0.7" } }, @@ -9329,17 +9767,35 @@ "dev": true }, "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", "es-shim-unscopables": "^1.0.0" } }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, "babel-jest": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", @@ -9436,15 +9892,15 @@ } }, "browserslist": { - "version": "4.21.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz", - "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==", + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001370", - "electron-to-chromium": "^1.4.202", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.5" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" } }, "bs-logger": { @@ -9494,9 +9950,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001383", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001383.tgz", - "integrity": "sha512-swMpEoTp5vDoGBZsYZX7L7nXHe6dsHxi9o6/LKf/f0LukVtnrxly5GVb/fWdCDTqi/yw6Km6tiJ0pmBacm0gbg==", + "version": "1.0.30001451", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", + "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", "dev": true }, "chalk": { @@ -9516,9 +9972,9 @@ "dev": true }, "ci-info": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.2.tgz", - "integrity": "sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", "dev": true }, "cjs-module-lexer": { @@ -9528,13 +9984,13 @@ "dev": true }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -9572,13 +10028,10 @@ "dev": true }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - } + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, "create-require": { "version": "1.1.1", @@ -9619,15 +10072,15 @@ "dev": true }, "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", + "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", "dev": true }, "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "requires": { "has-property-descriptors": "^1.0.0", @@ -9671,9 +10124,9 @@ } }, "electron-to-chromium": { - "version": "1.4.233", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.233.tgz", - "integrity": "sha512-ejwIKXTg1wqbmkcRJh9Ur3hFGHFDZDw1POzdsVrB2WZjgRuRMHIQQKNpe64N/qh3ZtH2otEoRoS+s6arAAuAAw==", + "version": "1.4.295", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", + "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", "dev": true }, "emittery": { @@ -9689,9 +10142,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", "requires": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -9707,34 +10160,55 @@ } }, "es-abstract": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", - "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, "requires": { + "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.1", + "get-intrinsic": "^1.1.3", "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", "has": "^1.0.3", "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.4", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.0", + "object-inspect": "^1.12.2", "object-keys": "^1.1.1", - "object.assign": "^4.1.2", + "object.assign": "^4.1.4", "regexp.prototype.flags": "^1.4.3", - "string.prototype.trimend": "^1.0.5", - "string.prototype.trimstart": "^1.0.5", - "unbox-primitive": "^1.0.2" + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" + } + }, + "es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" } }, "es-shim-unscopables": { @@ -9770,15 +10244,15 @@ "dev": true }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.34.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", + "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", - "@humanwhocodes/config-array": "^0.10.4", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -9794,15 +10268,15 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -9835,13 +10309,14 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", "dev": true, "requires": { "debug": "^3.2.7", - "resolve": "^1.20.0" + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" }, "dependencies": { "debug": { @@ -9876,33 +10351,35 @@ } }, "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", "dev": true, "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", "has": "^1.0.3", - "is-core-module": "^2.8.1", + "is-core-module": "^2.11.0", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, "doctrine": { @@ -9914,18 +10391,18 @@ "esutils": "^2.0.2" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true } } }, "eslint-plugin-jest": { - "version": "26.8.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz", - "integrity": "sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q==", + "version": "26.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", + "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" @@ -9965,9 +10442,9 @@ "dev": true }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -10051,34 +10528,34 @@ "dev": true }, "expect": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.1.tgz", - "integrity": "sha512-yQgemsjLU+1S8t2A7pXT3Sn/v5/37LY8J+tocWtKEA0iEYYc6gfKbbJJX2fxHZmd7K9WpdbQqXUpmYkq1aewYg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", + "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", "dev": true, "requires": { - "@jest/expect-utils": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1" + "@jest/expect-utils": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -10086,6 +10563,12 @@ "chalk": "^4.0.0" } }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -10093,59 +10576,59 @@ "dev": true }, "diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true }, "jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -10154,12 +10637,12 @@ } }, "pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -10179,9 +10662,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -10215,18 +10698,18 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" } }, "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "requires": { "bser": "2.1.1" @@ -10276,6 +10759,15 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "requires": { + "is-callable": "^1.1.3" + } + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -10317,12 +10809,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -10342,9 +10828,9 @@ "dev": true }, "get-intrinsic": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", - "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "requires": { "function-bind": "^1.1.1", @@ -10398,14 +10884,23 @@ } }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, + "globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3" + } + }, "globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -10420,6 +10915,15 @@ "slash": "^3.0.0" } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -10460,6 +10964,12 @@ "get-intrinsic": "^1.1.1" } }, + "has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true + }, "has-symbols": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", @@ -10488,9 +10998,9 @@ "dev": true }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "import-fresh": { @@ -10536,16 +11046,27 @@ "dev": true }, "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.0", + "get-intrinsic": "^1.2.0", "has": "^1.0.3", "side-channel": "^1.0.4" } }, + "is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -10572,15 +11093,15 @@ } }, "is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "requires": { "has": "^1.0.3" } @@ -10642,6 +11163,12 @@ "has-tostringtag": "^1.0.0" } }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true + }, "is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -10685,6 +11212,19 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + } + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -10707,9 +11247,9 @@ "dev": true }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -10796,71 +11336,71 @@ } }, "jest-circus": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.1.tgz", - "integrity": "sha512-I5J4LyK3qPo8EnqPmxsMAVR+2SFx7JOaZsbqW9xQmk4UDmTCD92EQgS162Ey3Jq6CfpKJKFDhzhG3QqiE0fRbw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", + "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", "dev": true, "requires": { - "@jest/environment": "^29.0.1", - "@jest/expect": "^29.0.1", - "@jest/test-result": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/environment": "^29.4.2", + "@jest/expect": "^29.4.2", + "@jest/test-result": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-runtime": "^29.0.1", - "jest-snapshot": "^29.0.1", - "jest-util": "^29.0.1", + "jest-each": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-runtime": "^29.4.2", + "jest-snapshot": "^29.4.2", + "jest-util": "^29.4.2", "p-limit": "^3.1.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { "@jest/console": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.1.tgz", - "integrity": "sha512-SxLvSKf9gk4Rvt3p2KRQWVQ3sVj7S37rjlCHwp2+xNcRO/X+Uw0idbkfOtciUpjghHIxyggqcrrKhThQ+vClLQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", + "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "slash": "^3.0.0" } }, "@jest/globals": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.1.tgz", - "integrity": "sha512-BtZWrVrKRKNUt7T1H2S8Mz31PN7ItROCmH+V5pn10hJDUfjOCTIUwb0WtLZzm0f1tJ3Uvx+5lVZrF/VTKqNaFg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", + "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", "dev": true, "requires": { - "@jest/environment": "^29.0.1", - "@jest/expect": "^29.0.1", - "@jest/types": "^29.0.1", - "jest-mock": "^29.0.1" + "@jest/environment": "^29.4.2", + "@jest/expect": "^29.4.2", + "@jest/types": "^29.4.2", + "jest-mock": "^29.4.2" } }, "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", - "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", + "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.15", @@ -10869,47 +11409,47 @@ } }, "@jest/test-result": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.1.tgz", - "integrity": "sha512-XCA4whh/igxjBaR/Hg8qwFd/uTsauoD7QAdAYUjV2CSGx0+iunhjoCRRWTwqjQrETRqOJABx6kNfw0+C0vMSgQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", + "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", "dev": true, "requires": { - "@jest/console": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/console": "^29.4.2", + "@jest/types": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/transform": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.1.tgz", - "integrity": "sha512-6UxXtqrPScFdDhoip8ys60dQAIYppQinyR87n9nlasR/ZnFfJohKToqzM29KK4gb9gHRv5oDFChdqZKE0SIhsg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", + "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -10917,6 +11457,12 @@ "chalk": "^4.0.0" } }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -10929,130 +11475,137 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", + "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", "dev": true }, "jest-diff": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.1.tgz", - "integrity": "sha512-l8PYeq2VhcdxG9tl5cU78ClAlg/N7RtVSp0v3MlXURR0Y99i6eFnegmasOandyTmO6uEdo20+FByAjBFEO9nuw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", + "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "diff-sequences": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-haste-map": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.1.tgz", - "integrity": "sha512-gcKOAydafpGoSBvcj/mGCfhOKO8fRLkAeee1KXGdcJ1Pb9O2nnOl4I8bQSIID2MaZeMHtLLgNboukh/pUGkBtg==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", + "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.1", - "jest-worker": "^29.0.1", + "jest-regex-util": "^29.4.2", + "jest-util": "^29.4.2", + "jest-worker": "^29.4.2", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-matcher-utils": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.1.tgz", - "integrity": "sha512-/e6UbCDmprRQFnl7+uBKqn4G22c/OmwriE5KCMVqxhElKCQUDcFnq5XM9iJeKtzy4DUjxT27y9VHmKPD8BQPaw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", + "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.1" + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "pretty-format": "^29.4.2" } }, "jest-message-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.1.tgz", - "integrity": "sha512-wRMAQt3HrLpxSubdnzOo68QoTfQ+NLXFzU0Heb18ZUzO2S9GgaXNEdQ4rpd0fI9dq2NXkpCk1IUWSqzYKji64A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", + "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", + "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", "dev": true }, "jest-resolve": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.1.tgz", - "integrity": "sha512-dwb5Z0lLZbptlBtPExqsHfdDamXeiRLv4vdkfPrN84vBwLSWHWcXjlM2JXD/KLSQfljBcXbzI/PDvUJuTQ84Nw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", + "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", + "jest-haste-map": "^29.4.2", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.1", - "jest-validate": "^29.0.1", + "jest-util": "^29.4.2", + "jest-validate": "^29.4.2", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "jest-runtime": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.1.tgz", - "integrity": "sha512-yDgz5OE0Rm44PUAfTqwA6cDFnTYnVcYbRpPECsokSASQ0I5RXpnKPVr2g0CYZWKzbsXqqtmM7TIk7CAutZJ7gQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", + "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", "dev": true, "requires": { - "@jest/environment": "^29.0.1", - "@jest/fake-timers": "^29.0.1", - "@jest/globals": "^29.0.1", - "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/environment": "^29.4.2", + "@jest/fake-timers": "^29.4.2", + "@jest/globals": "^29.4.2", + "@jest/source-map": "^29.4.2", + "@jest/test-result": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-mock": "^29.0.1", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.1", - "jest-snapshot": "^29.0.1", - "jest-util": "^29.0.1", + "jest-haste-map": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-mock": "^29.4.2", + "jest-regex-util": "^29.4.2", + "jest-resolve": "^29.4.2", + "jest-snapshot": "^29.4.2", + "jest-util": "^29.4.2", + "semver": "^7.3.5", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.1.tgz", - "integrity": "sha512-OuYGp+lsh7RhB3DDX36z/pzrGm2F740e5ERG9PQpJyDknCRtWdhaehBQyMqDnsQdKkvC2zOcetcxskiHjO7e8Q==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", + "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -11061,33 +11614,33 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.1", - "@jest/transform": "^29.0.1", - "@jest/types": "^29.0.1", + "@jest/expect-utils": "^29.4.2", + "@jest/transform": "^29.4.2", + "@jest/types": "^29.4.2", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.1", + "expect": "^29.4.2", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.1", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.1", - "jest-matcher-utils": "^29.0.1", - "jest-message-util": "^29.0.1", - "jest-util": "^29.0.1", + "jest-diff": "^29.4.2", + "jest-get-type": "^29.4.2", + "jest-haste-map": "^29.4.2", + "jest-matcher-utils": "^29.4.2", + "jest-message-util": "^29.4.2", + "jest-util": "^29.4.2", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.1", + "pretty-format": "^29.4.2", "semver": "^7.3.5" } }, "jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -11096,37 +11649,38 @@ } }, "jest-validate": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.1.tgz", - "integrity": "sha512-mS4q7F738YXZFWBPqE+NjHU/gEOs7IBIFQ8i9zq5EO691cLrUbLhFq4larf8/lNcmauRO71tn/+DTW2y+MrLow==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", + "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", + "jest-get-type": "^29.4.2", "leven": "^3.1.0", - "pretty-format": "^29.0.1" + "pretty-format": "^29.4.2" } }, "jest-worker": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.1.tgz", - "integrity": "sha512-+B/2/8WW7goit7qVezG9vnI1QP3dlmuzi2W0zxazAQQ8dcDIA63dDn6j4pjOGBARha/ZevcwYQtNIzCySbS7fQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", + "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.4.2", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -11137,6 +11691,12 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, + "resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true + }, "supports-color": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", @@ -11243,6 +11803,24 @@ "jest-util": "^28.1.3" } }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -11398,34 +11976,34 @@ } }, "jest-each": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.1.tgz", - "integrity": "sha512-UmCZYU9LPvRfSDoCrKJqrCNmgTYGGb3Ga6IVsnnVjedBTRRR9GJMca7UmDKRrJ1s+U632xrVtiRD27BxaG1aaQ==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", + "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", - "jest-util": "^29.0.1", - "pretty-format": "^29.0.1" + "jest-get-type": "^29.4.2", + "jest-util": "^29.4.2", + "pretty-format": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -11433,6 +12011,12 @@ "chalk": "^4.0.0" } }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -11440,12 +12024,12 @@ "dev": true }, "jest-util": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.1.tgz", - "integrity": "sha512-GIWkgNfkeA9d84rORDHPGGTFBrRD13A38QVSKE0bVrGSnoR1KDn8Kqz+0yI5kezMgbT/7zrWaruWP1Kbghlb2A==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", + "@jest/types": "^29.4.2", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -11454,12 +12038,12 @@ } }, "pretty-format": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.1.tgz", - "integrity": "sha512-iTHy3QZMzuL484mSTYbQIM1AHhEQsH8mXWS2/vd2yFBYnG3EBqGiMONo28PlPgrW7P/8s/1ISv+y7WH306l8cw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", + "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -11512,6 +12096,24 @@ "jest-util": "^28.1.3" } }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -11525,9 +12127,9 @@ } }, "jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", + "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", "dev": true }, "jest-haste-map": { @@ -11656,44 +12258,65 @@ } }, "jest-mock": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.1.tgz", - "integrity": "sha512-i1yTceg2GKJwUNZFjIzrH7Y74fN1SKJWxQX/Vu3LT4TiJerFARH5l+4URNyapZ+DNpchHYrGOP2deVbn3ma8JA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", + "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", "dev": true, "requires": { - "@jest/types": "^29.0.1", - "@types/node": "*" + "@jest/types": "^29.4.2", + "@types/node": "*", + "jest-util": "^29.4.2" }, "dependencies": { "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", + "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.0.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.1.tgz", - "integrity": "sha512-ft01rxzVsbh9qZPJ6EFgAIj3PT9FCRfBF9Xljo2/33VDOUjLZr0ZJ2oKANqh9S/K0/GERCsHDAQlBwj7RxA+9g==", + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", + "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", "dev": true, "requires": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.4.2", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } + }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "jest-util": { + "version": "29.4.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", + "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "dev": true, + "requires": { + "@jest/types": "^29.4.2", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } } } }, "jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "requires": {} }, @@ -11785,6 +12408,24 @@ "jest-util": "^28.1.3" } }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -11853,6 +12494,24 @@ "jest-util": "^28.1.3" } }, + "@sinonjs/commons": { + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "jest-mock": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", @@ -12084,6 +12743,12 @@ } } }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12124,9 +12789,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true }, "jsonfile": { @@ -12188,18 +12853,18 @@ "dev": true }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "lua-types": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.0.tgz", - "integrity": "sha512-wra+mIPZlcbm8bYoM6QutEwTOAjZ9KyKMiaidGeZ+QJItIAK9hwG+1I6GCDKnW0T9E/Xv2IoTFtZwxQv4zAIJw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", "dev": true }, "lua-wasm-bindings": { @@ -12282,9 +12947,9 @@ } }, "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true }, "ms": { @@ -12299,6 +12964,12 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -12306,9 +12977,9 @@ "dev": true }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", "dev": true }, "normalize-path": { @@ -12327,9 +12998,9 @@ } }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true }, "object-keys": { @@ -12351,14 +13022,14 @@ } }, "object.values": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.5.tgz", - "integrity": "sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" } }, "once": { @@ -12540,9 +13211,9 @@ "dev": true }, "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true }, "pretty-format": { @@ -12575,9 +13246,9 @@ } }, "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, "queue-microtask": { @@ -12649,9 +13320,9 @@ "dev": true }, "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", + "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", "dev": true }, "reusify": { @@ -12678,19 +13349,41 @@ "queue-microtask": "^1.2.2" } }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "shebang-command": { @@ -12767,9 +13460,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", - "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -12805,25 +13498,25 @@ } }, "string.prototype.trimend": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", - "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "string.prototype.trimstart": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", - "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.4", - "es-abstract": "^1.19.5" + "es-abstract": "^1.20.4" } }, "strip-ansi": { @@ -12863,9 +13556,9 @@ } }, "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", "dev": true, "requires": { "has-flag": "^4.0.0", @@ -12980,9 +13673,9 @@ }, "dependencies": { "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "requires": { "minimist": "^1.2.0" @@ -13032,10 +13725,21 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + } + }, "typescript": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.3.tgz", - "integrity": "sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==", + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true }, "unbox-primitive": { @@ -13057,9 +13761,9 @@ "dev": true }, "update-browserslist-db": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz", - "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -13123,6 +13827,20 @@ "is-symbol": "^1.0.3" } }, + "which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -13163,24 +13881,24 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { diff --git a/package.json b/package.json index c90d1880d..a4e580457 100644 --- a/package.json +++ b/package.json @@ -56,15 +56,15 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.36.1", - "@typescript-eslint/parser": "^5.36.1", - "eslint": "^8.23.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.8.7", + "@typescript-eslint/eslint-plugin": "^5.52.0", + "@typescript-eslint/parser": "^5.52.0", + "eslint": "^8.34.0", + "eslint-plugin-import": "^2.27.5", + "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^28.1.3", - "jest-circus": "^29.0.1", + "jest-circus": "^29.4.2", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.3.2", diff --git a/src/lualib/ArrayFrom.ts b/src/lualib/ArrayFrom.ts index fda55580f..67e78d914 100644 --- a/src/lualib/ArrayFrom.ts +++ b/src/lualib/ArrayFrom.ts @@ -11,7 +11,7 @@ function arrayLikeStep(this: ArrayLike, index: number): LuaMultiReturn< const arrayLikeIterator: ( this: void, arr: ArrayLike | Iterable -) => LuaIterable> = (arr => { +) => LuaIterable> = ((arr: any) => { if (typeof arr.length === "number") return $multi(arrayLikeStep, arr, 0); return __TS__Iterator(arr); }) as any; diff --git a/src/lualib/ArrayReduce.ts b/src/lualib/ArrayReduce.ts index d21d97403..cc569409a 100644 --- a/src/lualib/ArrayReduce.ts +++ b/src/lualib/ArrayReduce.ts @@ -9,7 +9,7 @@ export function __TS__ArrayReduce( const len = this.length; let k = 0; - let accumulator: TAccumulator = undefined; + let accumulator: TAccumulator = undefined!; // Check if initial value is present in function call if (__TS__CountVarargs(...initial) !== 0) { diff --git a/src/lualib/ArrayReduceRight.ts b/src/lualib/ArrayReduceRight.ts index 13bfe17d9..2316fa048 100644 --- a/src/lualib/ArrayReduceRight.ts +++ b/src/lualib/ArrayReduceRight.ts @@ -9,7 +9,7 @@ export function __TS__ArrayReduceRight( const len = this.length; let k = len - 1; - let accumulator: TAccumulator = undefined; + let accumulator: TAccumulator = undefined!; // Check if initial value is present in function call if (__TS__CountVarargs(...initial) !== 0) { diff --git a/src/lualib/ArraySetLength.ts b/src/lualib/ArraySetLength.ts index 4ec78715d..6f4de4b18 100644 --- a/src/lualib/ArraySetLength.ts +++ b/src/lualib/ArraySetLength.ts @@ -9,7 +9,7 @@ export function __TS__ArraySetLength(this: T[], length: number): number { throw `invalid array length: ${length}`; } for (const i of $range(length + 1, this.length)) { - this[i - 1] = undefined; + this[i - 1] = undefined!; } return length; } diff --git a/src/lualib/ArraySplice.ts b/src/lualib/ArraySplice.ts index 1d14cbda2..24b5264b2 100644 --- a/src/lualib/ArraySplice.ts +++ b/src/lualib/ArraySplice.ts @@ -58,11 +58,11 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { if (this[from - 1]) { this[to - 1] = this[from - 1]; } else { - this[to - 1] = undefined; + this[to - 1] = undefined!; } } for (const k of $range(len - actualDeleteCount + itemCount + 1, len)) { - this[k - 1] = undefined; + this[k - 1] = undefined!; } } else if (itemCount > actualDeleteCount) { for (const k of $range(len - actualDeleteCount, start + 1, -1)) { @@ -72,7 +72,7 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { if (this[from - 1]) { this[to - 1] = this[from - 1]; } else { - this[to - 1] = undefined; + this[to - 1] = undefined!; } } } @@ -84,7 +84,7 @@ export function __TS__ArraySplice(this: T[], ...args: any[]): T[] { } for (const k of $range(this.length, len - actualDeleteCount + itemCount + 1, -1)) { - this[k - 1] = undefined; + this[k - 1] = undefined!; } return out; diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index 50510f12c..f9f8d083e 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -16,14 +16,14 @@ export function __TS__Decorate= 0; i--) { const decorator = decorators[i]; - if (decorator) { + if (decorator !== undefined) { const oldResult = result; if (key === undefined) { result = decorator(result); } else if (desc === true) { const value = rawget(target, key); - const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) || { + const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) ?? { configurable: true, writable: true, value, diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index f6c405015..2eb59bc96 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -2,7 +2,7 @@ import { Decorator } from "./Decorator"; type ParamDecorator = ( target: TTarget, - key: TKey, + key: TKey | undefined, index: number ) => TTarget; export function __TS__DecorateParam( diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index ddad7d81f..fa1fa0bc0 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -27,7 +27,7 @@ function getErrorStack(constructor: () => any): string { function wrapErrorToString(getDescription: (this: T) => string): (this: T) => string { return function (this: Error): string { - const description = getDescription.call(this); + const description = getDescription.call(this as T); const caller = debug.getinfo(3, "f"); // @ts-ignore Fails when compiled with Lua 5.0 types const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1"; @@ -54,7 +54,7 @@ export const Error: ErrorConstructor = initErrorClass( constructor(public message = "") { this.stack = getErrorStack((this.constructor as any).new); const metatable = getmetatable(this); - if (!metatable.__errorToStringPatched) { + if (metatable && !metatable.__errorToStringPatched) { metatable.__errorToStringPatched = true; metatable.__tostring = wrapErrorToString(metatable.__tostring); } diff --git a/src/lualib/InstanceOf.ts b/src/lualib/InstanceOf.ts index a469cc35f..317c0b794 100644 --- a/src/lualib/InstanceOf.ts +++ b/src/lualib/InstanceOf.ts @@ -5,7 +5,7 @@ export function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: Lu if (classTbl[Symbol.hasInstance] !== undefined) { // eslint-disable-next-line no-implicit-coercion - return !!classTbl[Symbol.hasInstance](obj); + return !!classTbl[Symbol.hasInstance]!(obj); } if (typeof obj === "object") { @@ -14,7 +14,7 @@ export function __TS__InstanceOf(this: void, obj: LuaClassInstance, classTbl: Lu if (luaClass === classTbl) { return true; } - luaClass = luaClass.____super; + luaClass = luaClass.____super!; } } return false; diff --git a/src/lualib/LuaIteratorSpread.ts b/src/lualib/LuaIteratorSpread.ts index abe18e454..b846bc535 100644 --- a/src/lualib/LuaIteratorSpread.ts +++ b/src/lualib/LuaIteratorSpread.ts @@ -9,5 +9,5 @@ export function __TS__LuaIteratorSpread( results.push([key, value]); [key, value] = this(state, key); } - return $multi(...results); + return $multi(...results) as LuaMultiReturn>; } diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index fb1382fc3..16fa7e453 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -1,4 +1,4 @@ -export class Map { +export class Map { public static [Symbol.species] = Map; public [Symbol.toStringTag] = "Map"; @@ -52,24 +52,24 @@ export class Map { // Do order bookkeeping const next = this.nextKey.get(key); const previous = this.previousKey.get(key); - if (next && previous) { + if (next !== undefined && previous !== undefined) { this.nextKey.set(previous, next); this.previousKey.set(next, previous); - } else if (next) { + } else if (next !== undefined) { this.firstKey = next; - this.previousKey.set(next, undefined); - } else if (previous) { + this.previousKey.set(next, undefined!); + } else if (previous !== undefined) { this.lastKey = previous; - this.nextKey.set(previous, undefined); + this.nextKey.set(previous, undefined!); } else { this.firstKey = undefined; this.lastKey = undefined; } - this.nextKey.set(key, undefined); - this.previousKey.set(key, undefined); + this.nextKey.set(key, undefined!); + this.previousKey.set(key, undefined!); } - this.items.set(key, undefined); + this.items.set(key, undefined!); return contains; } @@ -100,8 +100,8 @@ export class Map { this.firstKey = key; this.lastKey = key; } else if (isNewValue) { - this.nextKey.set(this.lastKey, key); - this.previousKey.set(key, this.lastKey); + this.nextKey.set(this.lastKey!, key); + this.previousKey.set(key, this.lastKey!); this.lastKey = key; } @@ -120,8 +120,8 @@ export class Map { return this; }, next(): IteratorResult<[K, V]> { - const result = { done: !key, value: [key, items.get(key)] as [K, V] }; - key = nextKey.get(key); + const result = { done: !key, value: [key, items.get(key!)] as [K, V] }; + key = nextKey.get(key!); return result; }, }; @@ -136,8 +136,8 @@ export class Map { }, next(): IteratorResult { const result = { done: !key, value: key }; - key = nextKey.get(key); - return result; + key = nextKey.get(key!); + return result as IteratorResult; }, }; } @@ -150,8 +150,8 @@ export class Map { return this; }, next(): IteratorResult { - const result = { done: !key, value: items.get(key) }; - key = nextKey.get(key); + const result = { done: !key, value: items.get(key!) }; + key = nextKey.get(key!); return result; }, }; diff --git a/src/lualib/ObjectEntries.ts b/src/lualib/ObjectEntries.ts index 5daeee1e0..20fde96ad 100644 --- a/src/lualib/ObjectEntries.ts +++ b/src/lualib/ObjectEntries.ts @@ -1,5 +1,8 @@ -export function __TS__ObjectEntries(this: void, obj: any): Array { - const result = []; +export function __TS__ObjectEntries( + this: void, + obj: Record +): Array<[TKey, TValue]> { + const result: Array<[TKey, TValue]> = []; let len = 0; for (const key in obj) { len++; diff --git a/src/lualib/ObjectGetOwnPropertyDescriptor.ts b/src/lualib/ObjectGetOwnPropertyDescriptor.ts index 1f7e660bf..975de6712 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptor.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptor.ts @@ -6,5 +6,5 @@ export function __TS__ObjectGetOwnPropertyDescriptor( const metatable = getmetatable(object); if (!metatable) return; if (!rawget(metatable, "_descriptors")) return; - return rawget(metatable, "_descriptors")[key]; + return rawget(metatable, "_descriptors")![key]; } diff --git a/src/lualib/ObjectGetOwnPropertyDescriptors.ts b/src/lualib/ObjectGetOwnPropertyDescriptors.ts index 41d92ddfc..69d23af06 100644 --- a/src/lualib/ObjectGetOwnPropertyDescriptors.ts +++ b/src/lualib/ObjectGetOwnPropertyDescriptors.ts @@ -4,5 +4,5 @@ export function __TS__ObjectGetOwnPropertyDescriptors( ): Record { const metatable = getmetatable(object); if (!metatable) return {}; - return rawget(metatable, "_descriptors") || {}; + return rawget(metatable, "_descriptors") ?? {}; } diff --git a/src/lualib/ParseFloat.ts b/src/lualib/ParseFloat.ts index e182370e2..7720acb6b 100644 --- a/src/lualib/ParseFloat.ts +++ b/src/lualib/ParseFloat.ts @@ -3,7 +3,7 @@ import { __TS__Match } from "./Match"; export function __TS__ParseFloat(this: void, numberString: string): number { // Check if string is infinity const [infinityMatch] = __TS__Match(numberString, "^%s*(-?Infinity)"); - if (infinityMatch) { + if (infinityMatch !== undefined) { // eslint-disable-next-line @typescript-eslint/prefer-string-starts-ends-with return infinityMatch[0] === "-" ? -Infinity : Infinity; } diff --git a/src/lualib/ParseInt.ts b/src/lualib/ParseInt.ts index f6129f1df..c27d62662 100644 --- a/src/lualib/ParseInt.ts +++ b/src/lualib/ParseInt.ts @@ -7,7 +7,7 @@ export function __TS__ParseInt(this: void, numberString: string, base?: number): if (base === undefined) { base = 10; const [hexMatch] = __TS__Match(numberString, "^%s*-?0[xX]"); - if (hexMatch) { + if (hexMatch !== undefined) { base = 16; numberString = __TS__Match(hexMatch, "-")[0] ? "-" + numberString.substring(hexMatch.length) diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index b55330713..3ba075326 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -20,6 +20,7 @@ function promiseDeferred() { reject = rej; }); + // @ts-ignore This is alright because TS doesnt understand the callback will immediately be called return { promise, resolve, reject }; } @@ -36,6 +37,7 @@ export class __TS__Promise implements Promise { private rejectedCallbacks: Array> = []; private finallyCallbacks: Array<() => void> = []; + // @ts-ignore public [Symbol.toStringTag]: string; // Required to implement interface, no output Lua // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve @@ -81,7 +83,7 @@ export class __TS__Promise implements Promise { if (isFulfilled) { // If promise already resolved, immediately call callback - internalCallback(this.value); + internalCallback(this.value!); } } else { // We always want to resolve our child promise if this promise is resolved, even if we have no handler @@ -103,7 +105,7 @@ export class __TS__Promise implements Promise { if (isFulfilled) { // If promise already resolved, also resolve returned promise - resolve(this.value); + resolve(this.value!); } if (isRejected) { @@ -175,7 +177,7 @@ export class __TS__Promise implements Promise { resolve: FulfillCallback, reject: RejectCallback ) { - return value => { + return (value: T) => { try { this.handleCallbackData(f(value), resolve, reject); } catch (e) { @@ -195,7 +197,7 @@ export class __TS__Promise implements Promise { if (nextpromise.state === PromiseState.Fulfilled) { // If a handler function returns an already fulfilled promise, // the promise returned by then gets fulfilled with that promise's value - resolve(nextpromise.value); + resolve(nextpromise.value!); } else if (nextpromise.state === PromiseState.Rejected) { // If a handler function returns an already rejected promise, // the promise returned by then gets fulfilled with that promise's value diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index e4ac5e1cb..1f525ce3d 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -1,4 +1,4 @@ -export class Set { +export class Set { public static [Symbol.species] = Set; public [Symbol.toStringTag] = "Set"; @@ -42,8 +42,8 @@ export class Set { this.firstKey = value; this.lastKey = value; } else if (isNewValue) { - this.nextKey.set(this.lastKey, value); - this.previousKey.set(value, this.lastKey); + this.nextKey.set(this.lastKey!, value); + this.previousKey.set(value, this.lastKey!); this.lastKey = value; } @@ -66,22 +66,22 @@ export class Set { // Do order bookkeeping const next = this.nextKey.get(value); const previous = this.previousKey.get(value); - if (next && previous) { + if (next !== undefined && previous !== undefined) { this.nextKey.set(previous, next); this.previousKey.set(next, previous); - } else if (next) { + } else if (next !== undefined) { this.firstKey = next; - this.previousKey.set(next, undefined); - } else if (previous) { + this.previousKey.set(next, undefined!); + } else if (previous !== undefined) { this.lastKey = previous; - this.nextKey.set(previous, undefined); + this.nextKey.set(previous, undefined!); } else { this.firstKey = undefined; this.lastKey = undefined; } - this.nextKey.set(value, undefined); - this.previousKey.set(value, undefined); + this.nextKey.set(value, undefined!); + this.previousKey.set(value, undefined!); } return contains; @@ -103,7 +103,7 @@ export class Set { public entries(): IterableIterator<[T, T]> { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator<[T, T]> { return this; @@ -118,7 +118,7 @@ export class Set { public keys(): IterableIterator { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator { return this; @@ -133,7 +133,7 @@ export class Set { public values(): IterableIterator { const nextKey = this.nextKey; - let key: T = this.firstKey; + let key: T = this.firstKey!; return { [Symbol.iterator](): IterableIterator { return this; diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 1646ca7bd..389992c75 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -16,7 +16,7 @@ function descriptorIndex(this: any, key: string): void { const descriptors = rawget(metatable, "_descriptors"); if (descriptors) { const descriptor: PropertyDescriptor = descriptors[key]; - if (descriptor) { + if (descriptor !== undefined) { if (descriptor.get) { return descriptor.get.call(this); } @@ -35,7 +35,7 @@ function descriptorNewIndex(this: any, key: string, value: any): void { const descriptors = rawget(metatable, "_descriptors"); if (descriptors) { const descriptor: PropertyDescriptor = descriptors[key]; - if (descriptor) { + if (descriptor !== undefined) { if (descriptor.set) { descriptor.set.call(this, value); } else { diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index ba5908255..47c2c8739 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -4,10 +4,14 @@ import { __TS__Match } from "./Match"; interface SourceMap { - [line: number]: number | { line: number; file: string }; + [line: string]: number | { line: number; file: string }; } -declare function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number); +declare global { + function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number): void; + // eslint-disable-next-line no-var + var __TS__sourcemap: Record; +} export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap: SourceMap): void { globalThis.__TS__sourcemap = globalThis.__TS__sourcemap || {}; @@ -15,8 +19,8 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap if (globalThis.__TS__originalTraceback === undefined) { const originalTraceback = debug.traceback; - globalThis.__TS__originalTraceback = originalTraceback; - debug.traceback = ((thread, message, level) => { + globalThis.__TS__originalTraceback = originalTraceback as typeof __TS__originalTraceback; + debug.traceback = ((thread?: LuaThread, message?: string, level?: number) => { let trace: string; if (thread === undefined && message === undefined && level === undefined) { trace = originalTraceback(); @@ -33,7 +37,7 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap const replacer = (file: string, srcFile: string, line: string) => { const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; - if (fileSourceMap && fileSourceMap[line]) { + if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) { const data = fileSourceMap[line]; if (typeof data === "number") { return `${srcFile}:${data}`; @@ -51,7 +55,7 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap const stringReplacer = (file: string, line: string) => { const fileSourceMap: SourceMap = globalThis.__TS__sourcemap[file]; - if (fileSourceMap && fileSourceMap[line]) { + if (fileSourceMap !== undefined && fileSourceMap[line] !== undefined) { const chunkName = __TS__Match(file, '%[string "([^"]+)"%]')[0]; const [sourceName] = string.gsub(chunkName, ".lua$", ".ts"); const data = fileSourceMap[line]; diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index ffe745b6d..3abc66f42 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,9 +1,9 @@ export function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { - const arr = []; + const arr: T[] = []; if (typeof iterable === "string") { // eslint-disable-next-line @typescript-eslint/prefer-for-of for (const i of $range(0, iterable.length - 1)) { - arr[i] = iterable[i]; + arr[i] = iterable[i] as T; } } else { let len = 0; diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index d06eec37e..9d16cae3a 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -1,6 +1,6 @@ const symbolMetatable = { __tostring(this: symbol): string { - return `Symbol(${this.description || ""})`; + return `Symbol(${this.description ?? ""})`; }, }; diff --git a/src/lualib/SymbolRegistry.ts b/src/lualib/SymbolRegistry.ts index d8e68e3dd..4deaa0993 100644 --- a/src/lualib/SymbolRegistry.ts +++ b/src/lualib/SymbolRegistry.ts @@ -9,8 +9,10 @@ export function __TS__SymbolRegistryFor(this: void, key: string): symbol { return symbolRegistry[key]; } -export function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string { +export function __TS__SymbolRegistryKeyFor(this: void, sym: symbol): string | undefined { for (const key in symbolRegistry) { if (symbolRegistry[key] === sym) return key; } + + return undefined; } diff --git a/src/lualib/WeakMap.ts b/src/lualib/WeakMap.ts index e5f333293..65d1ae4da 100644 --- a/src/lualib/WeakMap.ts +++ b/src/lualib/WeakMap.ts @@ -1,4 +1,4 @@ -export class WeakMap { +export class WeakMap { public static [Symbol.species] = WeakMap; public [Symbol.toStringTag] = "WeakMap"; @@ -30,7 +30,7 @@ export class WeakMap { public delete(key: K): boolean { const contains = this.has(key); - this.items.set(key, undefined); + this.items.set(key, undefined!); return contains; } diff --git a/src/lualib/WeakSet.ts b/src/lualib/WeakSet.ts index 0873861ab..b921efc17 100644 --- a/src/lualib/WeakSet.ts +++ b/src/lualib/WeakSet.ts @@ -1,4 +1,4 @@ -export class WeakSet { +export class WeakSet { public static [Symbol.species] = WeakSet; public [Symbol.toStringTag] = "WeakSet"; @@ -33,7 +33,7 @@ export class WeakSet { public delete(value: T): boolean { const contains = this.has(value); - this.items.set(value, undefined); + this.items.set(value, undefined!); return contains; } diff --git a/src/lualib/tsconfig.json b/src/lualib/tsconfig.json index de9c1fa7f..0f0874d0d 100644 --- a/src/lualib/tsconfig.json +++ b/src/lualib/tsconfig.json @@ -7,13 +7,12 @@ "skipLibCheck": true, "rootDirs": [".", "universal"], - "noUnusedLocals": true, - "noUnusedParameters": true + "strict": true }, "tstl": { "luaLibImport": "none", "noHeader": true, "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] }, - "include": ["*.ts", "universal/*.ts", "declarations", "../../language-extensions/index.d.ts"] + "include": ["*.ts", "universal/**/*.ts", "declarations/**/*.ts", "../../language-extensions/index.d.ts"] } diff --git a/src/lualib/tsconfig.lua50.json b/src/lualib/tsconfig.lua50.json index ecf9409e1..a0b5aee4b 100644 --- a/src/lualib/tsconfig.lua50.json +++ b/src/lualib/tsconfig.lua50.json @@ -7,8 +7,7 @@ "skipLibCheck": true, "rootDirs": [".", "5.0"], - "noUnusedLocals": true, - "noUnusedParameters": true + "strict": true }, "tstl": { "luaLibImport": "none", @@ -16,5 +15,5 @@ "luaTarget": "5.0", "luaPlugins": [{ "name": "../../dist/lualib-build/plugin.js" }] }, - "include": ["*.ts", "5.0/*.ts", "declarations", "../../language-extensions/index.d.ts"] + "include": ["*.ts", "5.0/**/*.ts", "declarations/**/*.ts", "../../language-extensions/index.d.ts"] } From 625d0699a95c234273cc310afbe02380068493b8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 16 Feb 2023 14:21:59 +0100 Subject: [PATCH 565/764] Make module resolution with custom extension work for extensions starting with and without period (#1402) --- src/transpilation/resolve.ts | 3 +++ test/transpile/module-resolution.spec.ts | 8 ++++++++ test/util.ts | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 558870f21..781da43c2 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -341,6 +341,9 @@ function replaceRequireInSourceMap( } function requirePathForFile(filePath: string, extension = ".lua"): string { + if (!extension.startsWith(".")) { + extension = `.${extension}`; + } if (filePath.endsWith(extension)) { return formatPathToLuaPath(filePath.substring(0, filePath.length - extension.length)); } else { diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index f95771687..7aa96001a 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -182,6 +182,14 @@ describe("module resolution with sourceDir", () => { .setOptions({ outDir: "tstl-out", extension: ".script" }) .expectToEqual(expectedResult); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1394 + test("can resolve files with non-standard extension without separator (#1394)", () => { + util.testProject(path.join(projectPath, "tsconfig.json")) + .setMainFileName(path.join(projectPath, "src", "main.ts")) + .setOptions({ outDir: "tstl-out", extension: "script" }) + .expectToEqual(expectedResult); + }); }); describe("module resolution project with lua sources", () => { diff --git a/test/util.ts b/test/util.ts index c86d40453..1b41bb4a2 100644 --- a/test/util.ts +++ b/test/util.ts @@ -468,7 +468,10 @@ end)());`; } private injectLuaFile(state: LuaState, lua: Lua, lauxlib: LauxLib, fileName: string, fileContent: string) { - const extension = this.options.extension ?? ".lua"; + let extension = this.options.extension ?? ".lua"; + if (!extension.startsWith(".")) { + extension = `.${extension}`; + } const modName = fileName.endsWith(extension) ? formatPathToLuaPath(fileName.substring(0, fileName.length - extension.length)) : fileName; From 45d91ec5b29f8315cc102d4755a9b63704791717 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 16 Feb 2023 14:44:16 +0100 Subject: [PATCH 566/764] 1.13.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4d461e679..6a65f529d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.13.0", + "version": "1.13.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.13.0", + "version": "1.13.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index a4e580457..5426c3f97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.13.0", + "version": "1.13.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5a758ea7ed2123002256fd9a657009402aa24e18 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 25 Feb 2023 13:36:00 +0100 Subject: [PATCH 567/764] Fix crash missing arguments (#1407) * Fix exception when calling string indexOf or string splice without arguments * Fix some more potential undefined references --- src/transformation/builtins/array.ts | 6 +++--- src/transformation/builtins/math.ts | 19 ++++++++++++++++--- src/transformation/builtins/string.ts | 15 +++++++++++---- src/transformation/utils/lua-ast.ts | 18 ++++++++++-------- test/unit/builtins/string.spec.ts | 12 ++++++++++++ 5 files changed, 52 insertions(+), 18 deletions(-) diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 22afd5b45..417a81e87 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -94,14 +94,14 @@ export function transformArrayPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); case "push": if (node.arguments.length === 1) { - const param = params[0]; + const param = params[0] ?? lua.createNilLiteral(); if (isUnpackCall(param)) { return transformLuaLibFunction( context, LuaLibFeature.ArrayPushArray, node, caller, - (param as lua.CallExpression).params[0] + (param as lua.CallExpression).params[0] ?? lua.createNilLiteral() ); } if (!lua.isDotsLiteral(param)) { @@ -162,7 +162,7 @@ export function transformArrayPrototypeCall( typeAlwaysHasSomeOfFlags(context, elementType, ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike) ) { const defaultSeparatorLiteral = lua.createStringLiteral(","); - const param = params[0]; + const param = params[0] ?? lua.createNilLiteral(); const parameters = [ caller, node.arguments.length === 0 diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 630f33646..4be4e77cb 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -66,20 +66,33 @@ export function transformMathCall( case "log1p": { const log = lua.createStringLiteral("log"); const one = lua.createNumericLiteral(1); - const add = lua.createBinaryExpression(one, params[0], lua.SyntaxKind.AdditionOperator); + const add = lua.createBinaryExpression( + one, + params[0] ?? lua.createNilLiteral(), + lua.SyntaxKind.AdditionOperator + ); return lua.createCallExpression(lua.createTableIndexExpression(math, log), [add], node); } case "pow": { // Translate to base ^ power - return lua.createBinaryExpression(params[0], params[1], lua.SyntaxKind.PowerOperator, node); + return lua.createBinaryExpression( + params[0] ?? lua.createNilLiteral(), + params[1] ?? lua.createNilLiteral(), + lua.SyntaxKind.PowerOperator, + node + ); } // math.floor(x + 0.5) case "round": { const floor = lua.createStringLiteral("floor"); const half = lua.createNumericLiteral(0.5); - const add = lua.createBinaryExpression(params[0], half, lua.SyntaxKind.AdditionOperator); + const add = lua.createBinaryExpression( + params[0] ?? lua.createNilLiteral(), + half, + lua.SyntaxKind.AdditionOperator + ); return lua.createCallExpression(lua.createTableIndexExpression(math, floor), [add], node); } diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index a48f36ee5..b7c56a08c 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -42,7 +42,7 @@ export function transformStringPrototypeCall( "find", node, caller, - params[0], + params[0] ?? lua.createNilLiteral(), params[1] ? // string.find handles negative indexes by making it relative to string end, but for indexOf it's the same as 0 lua.createCallExpression( @@ -110,7 +110,7 @@ export function transformStringPrototypeCall( const literalValue = getNumberLiteralValue(params[0]); // Inline string.sub call if we know that parameter is pure and isn't negative if (literalValue !== undefined && literalValue >= 0) { - const firstParamPlusOne = addToNumericExpression(params[0], 1); + const firstParamPlusOne = addToNumericExpression(params[0] ?? lua.createNilLiteral(), 1); return createStringCall("sub", node, caller, firstParamPlusOne, firstParamPlusOne); } @@ -122,7 +122,12 @@ export function transformStringPrototypeCall( // Inline string.sub call if we know that parameter is pure and isn't negative if (literalValue !== undefined && literalValue >= 0) { return lua.createBinaryExpression( - createStringCall("byte", node, caller, addToNumericExpression(params[0], 1)), + createStringCall( + "byte", + node, + caller, + addToNumericExpression(params[0] ?? lua.createNilLiteral(), 1) + ), createNaN(), lua.SyntaxKind.OrOperator ); @@ -140,7 +145,9 @@ export function transformStringPrototypeCall( case "repeat": const math = lua.createIdentifier("math"); const floor = lua.createStringLiteral("floor"); - const parameter = lua.createCallExpression(lua.createTableIndexExpression(math, floor), [params[0]]); + const parameter = lua.createCallExpression(lua.createTableIndexExpression(math, floor), [ + params[0] ?? lua.createNilLiteral(), + ]); return createStringCall("rep", node, caller, parameter); case "padStart": return transformLuaLibFunction(context, LuaLibFeature.StringPadStart, node, caller, ...params); diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index 0a8e158dc..b947e0bf6 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -305,15 +305,17 @@ function getJSDocCommentFromTSNode( // https://stevedonovan.github.io/ldoc/manual/doc.md.html // LDoc comments require that the first line starts with three hyphens. // Thus, need to add a hyphen to the first line. - const firstLine = lines[0]; - if (firstLine.startsWith(" @")) { - lines.unshift("-"); - } else { - lines.shift(); - lines.unshift("-" + firstLine); - } + if (lines.length > 0) { + const firstLine = lines[0]; + if (firstLine.startsWith(" @")) { + lines.unshift("-"); + } else { + lines.shift(); + lines.unshift("-" + firstLine); + } - return lines; + return lines; + } } export const createNaN = (tsOriginal?: ts.Node) => diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index db745cb98..d87786231 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -398,3 +398,15 @@ test.each(["string | undefined", "string | null", "null | string", "null | undef .expectToMatchJsResult(); } ); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 +test("string.indexOf without arguments (#1406)", () => { + // Just test we do not throw here + util.testExpression`"".indexOf()`.expectToHaveDiagnostics(); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 +test("string.repeat without arguments (#1406)", () => { + // Just test we do not throw here + util.testExpression`"".repeat()`.expectToHaveDiagnostics(); +}); From 26d7c03d022ac9a2fbf98985c75b9ed970525178 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 25 Feb 2023 15:09:46 +0100 Subject: [PATCH 568/764] Fix exception when unwrapping parenthesised multireturn calls (#1408) * Fix exception when unwrapping parenthesised multireturn calls * reorder * Update test/unit/language-extensions/multi.spec.ts Co-authored-by: hazzard993 --------- Co-authored-by: hazzard993 --- .../visitors/language-extensions/multi.ts | 22 ++++++++++--------- test/unit/language-extensions/multi.spec.ts | 11 ++++++++++ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/transformation/visitors/language-extensions/multi.ts b/src/transformation/visitors/language-extensions/multi.ts index 73dec6d9c..d9d7cbc02 100644 --- a/src/transformation/visitors/language-extensions/multi.ts +++ b/src/transformation/visitors/language-extensions/multi.ts @@ -6,7 +6,7 @@ import { IterableExtensionKind, } from "../../utils/language-extensions"; import { TransformationContext } from "../../context"; -import { findFirstNodeAbove } from "../../utils/typescript"; +import { findFirstNodeAbove, findFirstNonOuterParent } from "../../utils/typescript"; const multiReturnExtensionName = "__tstlMultiReturn"; export function isMultiReturnType(type: ts.Type): boolean { @@ -58,46 +58,48 @@ export function shouldMultiReturnCallBeWrapped(context: TransformationContext, n return false; } + const parent = findFirstNonOuterParent(node); + // Variable declaration with destructuring - if (ts.isVariableDeclaration(node.parent) && ts.isArrayBindingPattern(node.parent.name)) { + if (ts.isVariableDeclaration(parent) && ts.isArrayBindingPattern(parent.name)) { return false; } // Variable assignment with destructuring if ( - ts.isBinaryExpression(node.parent) && - node.parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && - ts.isArrayLiteralExpression(node.parent.left) + ts.isBinaryExpression(parent) && + parent.operatorToken.kind === ts.SyntaxKind.EqualsToken && + ts.isArrayLiteralExpression(parent.left) ) { return false; } // Spread operator - if (ts.isSpreadElement(node.parent)) { + if (ts.isSpreadElement(parent)) { return false; } // Stand-alone expression - if (ts.isExpressionStatement(node.parent)) { + if (ts.isExpressionStatement(parent)) { return false; } // Forwarded multi-return call if ( - (ts.isReturnStatement(node.parent) || ts.isArrowFunction(node.parent)) && // Body-less arrow func + (ts.isReturnStatement(parent) || ts.isArrowFunction(parent)) && // Body-less arrow func isInMultiReturnFunction(context, node) ) { return false; } // Element access expression 'foo()[0]' will be optimized using 'select' - if (ts.isElementAccessExpression(node.parent)) { + if (ts.isElementAccessExpression(parent)) { return false; } // LuaIterable in for...of if ( - ts.isForOfStatement(node.parent) && + ts.isForOfStatement(parent) && getIterableExtensionKindForNode(context, node) === IterableExtensionKind.Iterable ) { return false; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index ed7213b2b..3350876e8 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -327,3 +327,14 @@ test("return LuaMultiReturn from catch", () => { .withLanguageExtensions() .expectToEqual(2); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1404 +test("LuaMultiReturn applies after casting a function (#1404)", () => { + util.testFunction` + let swap: any = (a: number, b: number) => $multi(b, a); + let [a, b] = (swap as (...args: any) => LuaMultiReturn<[number, number]>)(4, 3); + return [a, b]; + ` + .withLanguageExtensions() + .expectToEqual([3, 4]); +}); From 3b30b09fce2c9740502f3e939f986218d2f65ce1 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 26 Feb 2023 11:29:00 +0100 Subject: [PATCH 569/764] Spread LuaPairsIterable and LuaPairsKeysIterable (#1409) * Spread LuaPairsIterable and LuaPairsKeysIterable * Use expect.toContainEqual in tests --- src/transformation/visitors/spread.ts | 20 +++++++++++--- test/unit/spread.spec.ts | 40 +++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index a71fc01e8..d0fc1335c 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -1,8 +1,9 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; +import { assertNever } from "../../utils"; import { FunctionVisitor, TransformationContext } from "../context"; -import { isLuaIterable } from "../utils/language-extensions"; +import { getIterableExtensionKindForNode, IterableExtensionKind } from "../utils/language-extensions"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { @@ -76,11 +77,22 @@ export const transformSpreadElement: FunctionVisitor = (node, const innerExpression = context.transformExpression(node.expression); if (isMultiReturnCall(context, tsInnerExpression)) return innerExpression; - const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts - if (isLuaIterable(context, type)) { - return transformLuaLibFunction(context, LuaLibFeature.LuaIteratorSpread, node, innerExpression); + const iterableExtensionType = getIterableExtensionKindForNode(context, node.expression); + if (iterableExtensionType) { + if (iterableExtensionType === IterableExtensionKind.Iterable) { + return transformLuaLibFunction(context, LuaLibFeature.LuaIteratorSpread, node, innerExpression); + } else if (iterableExtensionType === IterableExtensionKind.Pairs) { + const objectEntries = transformLuaLibFunction(context, LuaLibFeature.ObjectEntries, node, innerExpression); + return createUnpackCall(context, objectEntries, node); + } else if (iterableExtensionType === IterableExtensionKind.PairsKey) { + const objectKeys = transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, node, innerExpression); + return createUnpackCall(context, objectKeys, node); + } else { + assertNever(iterableExtensionType); + } } + const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts if (isArrayType(context, type)) { return createUnpackCall(context, innerExpression, node); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 40f650055..f0f57d164 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -509,7 +509,7 @@ test.each(["pairs", "ipairs"])("can spread %s (#1244)", func => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1244 -test.each(["LuaTable", "LuaMap"])("can spread %s (#1244)", type => { +test.each(["LuaTable", "LuaMap"])("can spread %s with pairs (#1244)", type => { const result: Array<[string, string]> = util.testFunction` const tbl = new ${type}(); tbl.set("foo", "bar"); @@ -524,6 +524,40 @@ test.each(["LuaTable", "LuaMap"])("can spread %s (#1244)", type => { // We don't know the order so match like this expect(result).toHaveLength(2); - expect(result.some(([k, v]) => k === "foo" && v === "bar")).toBe(true); - expect(result.some(([k, v]) => k === "fizz" && v === "buzz")).toBe(true); + expect(result).toContainEqual(["foo", "bar"]); + expect(result).toContainEqual(["fizz", "buzz"]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1384 +test.each(["LuaTable", "LuaMap"])("can spread %s (#1384)", type => { + const result: Array<[string, string]> = util.testFunction` + const tbl = new ${type}(); + tbl.set("foo", "bar"); + tbl.set("fizz", "buzz"); + return [...tbl]; + ` + .withLanguageExtensions() + .getLuaExecutionResult(); + + // We don't know the order so match like this + expect(result).toHaveLength(2); + expect(result).toContainEqual(["foo", "bar"]); + expect(result).toContainEqual(["fizz", "buzz"]); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1384 +test("can spread LuaSet (#1384)", () => { + const result: Array<[string, string]> = util.testFunction` + const tbl = new LuaSet(); + tbl.add("foo"); + tbl.add("bar"); + return [...tbl]; + ` + .withLanguageExtensions() + .getLuaExecutionResult(); + + // We don't know the order so match like this + expect(result).toHaveLength(2); + expect(result).toContain("foo"); + expect(result).toContain("bar"); }); From 4511e17e3aa3c0995087d0e1c9501281e488777a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 26 Feb 2023 15:03:42 +0100 Subject: [PATCH 570/764] Fix element access exception caused by invalid TS (#1410) * Fix element access exception caused by invalid TS * Chang test name --- src/transformation/utils/diagnostics.ts | 5 +++++ .../visitors/binary-expression/assignments.ts | 16 +++++++++++----- test/unit/builtins/string.spec.ts | 6 ++---- test/unit/destructuring.spec.ts | 12 ++++++++++++ test/util.ts | 5 +++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index fd443e596..8fe4a22f5 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import * as lua from "../../LuaAST"; import { LuaTarget, TypeScriptToLuaOptions } from "../../CompilerOptions"; import { createSerialDiagnosticFactory } from "../../utils"; import { AnnotationKind } from "./annotations"; @@ -163,3 +164,7 @@ export const invalidMethodCallExtensionUse = createErrorDiagnosticFactory( export const invalidSpreadInCallExtension = createErrorDiagnosticFactory( "Spread elements are not supported in call extensions." ); + +export const cannotAssignToNodeOfKind = createErrorDiagnosticFactory( + (kind: lua.SyntaxKind) => `Cannot create assignment assigning to a node of type ${lua.SyntaxKind[kind]}.` +); diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 2cceff755..a138781dc 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -1,6 +1,5 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast } from "../../../utils"; import { TransformationContext } from "../../context"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; @@ -9,7 +8,7 @@ import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; import { isMultiReturnCall } from "../language-extensions/multi"; -import { notAllowedOptionalAssignment } from "../../utils/diagnostics"; +import { cannotAssignToNodeOfKind, notAllowedOptionalAssignment } from "../../utils/diagnostics"; import { transformElementAccessArgument } from "../access"; import { moveToPrecedingTemp, transformExpressionList } from "../expression-list"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; @@ -37,9 +36,16 @@ export function transformAssignmentLeftHandSideExpression( const symbol = context.checker.getSymbolAtLocation(node); const left = context.transformExpression(node); - return lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol) - ? createExportedIdentifier(context, left) - : cast(left, lua.isAssignmentLeftHandSideExpression); + if (lua.isIdentifier(left) && symbol && isSymbolExported(context, symbol)) { + return createExportedIdentifier(context, left); + } + + if (lua.isAssignmentLeftHandSideExpression(left)) { + return left; + } else { + context.diagnostics.push(cannotAssignToNodeOfKind(node, left.kind)); + return lua.createAnonymousIdentifier(); + } } export function transformAssignment( diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index d87786231..fecb0e466 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -401,12 +401,10 @@ test.each(["string | undefined", "string | null", "null | string", "null | undef // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 test("string.indexOf without arguments (#1406)", () => { - // Just test we do not throw here - util.testExpression`"".indexOf()`.expectToHaveDiagnostics(); + util.testExpression`"".indexOf()`.expectNoTranspileException(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1406 test("string.repeat without arguments (#1406)", () => { - // Just test we do not throw here - util.testExpression`"".repeat()`.expectToHaveDiagnostics(); + util.testExpression`"".repeat()`.expectNoTranspileException(); }); diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index e44f8f0c3..80d3d482c 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -1,3 +1,4 @@ +import { cannotAssignToNodeOfKind, invalidMultiReturnAccess } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; const allBindings = "x, y, z, rest"; @@ -225,3 +226,14 @@ describe("array destructuring optimization", () => { .expectToMatchJsResult(); }); }); + +test("no exception from semantically invalid TS", () => { + util.testModule` + declare function testFunc(value: number): LuaMultiReturn<[number, number]>; + let [a, b] = testFunc(5) // Missing ; + [a, b] = testFunc(b) // Interpreted as testFunc(5)[a, b] + ` + .withLanguageExtensions() + .disableSemanticCheck() + .expectToHaveDiagnostics([invalidMultiReturnAccess.code, cannotAssignToNodeOfKind.code]); +}); diff --git a/test/util.ts b/test/util.ts index 1b41bb4a2..a560b94f5 100644 --- a/test/util.ts +++ b/test/util.ts @@ -346,6 +346,11 @@ export abstract class TestBuilder { return this; } + public expectNoTranspileException(): this { + expect(() => this.getLuaResult()).not.toThrow(); + return this; + } + public expectNoExecutionError(): this { const luaResult = this.getLuaExecutionResult(); if (luaResult instanceof ExecutionError) { From 1af3db3b044ae72e37ca56a397b111e6822a5f50 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 26 Feb 2023 15:15:55 +0100 Subject: [PATCH 571/764] 1.13.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a65f529d..e23af706b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.13.1", + "version": "1.13.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.13.1", + "version": "1.13.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 5426c3f97..42a10a9b7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.13.1", + "version": "1.13.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 2dfca0b5ec8badd7ae11685a3b934004d2f2f513 Mon Sep 17 00:00:00 2001 From: Dimava Date: Wed, 1 Mar 2023 22:21:52 +0300 Subject: [PATCH 572/764] Implement Number.toFixed (#1413) --- src/LuaLib.ts | 1 + src/lualib/NumberToFixed.ts | 14 ++++++++++++++ src/transformation/builtins/number.ts | 2 ++ test/unit/builtins/numbers.spec.ts | 20 ++++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 src/lualib/NumberToFixed.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 8d776fb3a..b2f6383a6 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -58,6 +58,7 @@ export enum LuaLibFeature { NumberIsFinite = "NumberIsFinite", NumberIsNaN = "NumberIsNaN", NumberToString = "NumberToString", + NumberToFixed = "NumberToFixed", ObjectAssign = "ObjectAssign", ObjectDefineProperty = "ObjectDefineProperty", ObjectEntries = "ObjectEntries", diff --git a/src/lualib/NumberToFixed.ts b/src/lualib/NumberToFixed.ts new file mode 100644 index 000000000..355da13f0 --- /dev/null +++ b/src/lualib/NumberToFixed.ts @@ -0,0 +1,14 @@ +/// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-number.prototype.tofixed +export function __TS__NumberToFixed(this: number, fractionDigits?: number): string { + if (Math.abs(this) >= 1e21 || this !== this) { + return this.toString(); + } + const f = Math.floor(fractionDigits ?? 0); + // reduced to 99 as string.format only supports 2-digit numbers + if (f < 0 || f > 99) { + throw "toFixed() digits argument must be between 0 and 99"; + } + // throws "invalid format (width or precision too long)" if strlen > 99 + // if (f < 80) return fmt; else try {return fmt} catch(_) { throw "toFixed() digits argument..." } + return string.format(`%.${f}f`, this); +} diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index 3376c0db3..a5e7d4a1a 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -20,6 +20,8 @@ export function transformNumberPrototypeCall( return params.length === 0 ? lua.createCallExpression(lua.createIdentifier("tostring"), [caller], node) : transformLuaLibFunction(context, LuaLibFeature.NumberToString, node, caller, ...params); + case "toFixed": + return transformLuaLibFunction(context, LuaLibFeature.NumberToFixed, node, caller, ...params); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "number", expressionName)); } diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index f3f0bb9b9..c91d883cb 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -69,6 +69,26 @@ test.each([ util.testExpressionTemplate`(${value}).toString(2)`.expectToEqual(luaNativeSpecialNumString); }); +const toFixedFractions = [undefined, 0, 1, 2, Math.PI, 5, 99]; +// 1.5, 1.25 and 1.125 fails as rounding differ +const toFixedValues = [-1, 0, 1, Math.PI, -1.1234, -9.99e19, 1e22]; +const toFixedPairs = toFixedValues.flatMap(value => toFixedFractions.map(frac => [value, frac] as const)); +test.each(toFixedPairs)("(%p).toFixed(%p)", (value, frac) => { + util.testExpressionTemplate`(${value}).toFixed(${frac})`.expectToMatchJsResult(); +}); + +test.each([ + [NaN, "(0/0)"], + [Infinity, "(1/0)"], + [-Infinity, "(-(1/0))"], +])("%p.toFixed(2)", (value, luaNativeSpecialNum) => { + // Need to get the actual lua tostring version of inf/nan + // this is platform dependent so we can/should not hardcode it + const luaNativeSpecialNumString = util.testExpression`${luaNativeSpecialNum}.toString()`.getLuaExecutionResult(); + // Cannot use expectToMatchJsResult because this actually wont be the same in JS in Lua + util.testExpressionTemplate`(${value}).toFixed(2)`.expectToEqual(luaNativeSpecialNumString); +}); + test.each(cases)("isNaN(%p)", value => { util.testExpressionTemplate`isNaN(${value} as any)`.expectToMatchJsResult(); }); From ac8cc38b71cb10e3cbbf3fad03b8a7e166c270f2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 9 Mar 2023 13:48:37 +0100 Subject: [PATCH 573/764] 1.13.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e23af706b..cf79c61a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.13.2", + "version": "1.13.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.13.2", + "version": "1.13.3", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 42a10a9b7..ca8b9b98b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.13.2", + "version": "1.13.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f51fc0966a56f19c3cde0c29f0dd6a62f72359f7 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 18 Mar 2023 16:02:06 +0100 Subject: [PATCH 574/764] Upgrade TypeScript to 5.0 (#1417) * TS 5.0 * Fix build --- package-lock.json | 1856 +++++++++--------- package.json | 14 +- src/transformation/utils/typescript/nodes.ts | 6 +- src/transformation/visitors/spread.ts | 5 +- src/transpilation/transformers.ts | 2 +- test/transpile/transformers/utils.ts | 2 +- 6 files changed, 952 insertions(+), 933 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf79c61a4..a9e11883c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,27 +23,27 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "eslint": "^8.34.0", + "@typescript-eslint/eslint-plugin": "^5.55.0", + "@typescript-eslint/parser": "^5.55.0", + "eslint": "^8.36.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^28.1.3", - "jest-circus": "^29.4.2", + "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", - "prettier": "^2.3.2", + "prettier": "^2.8.4", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", - "typescript": "~4.9.3" + "typescript": "^5.0.2" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.9.3" + "typescript": "^5.0.2" } }, "node_modules/@ampproject/remapping": { @@ -674,15 +674,39 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -697,6 +721,15 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -937,24 +970,24 @@ "dev": true }, "node_modules/@jest/environment": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", - "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.4.2" + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/environment/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -964,12 +997,12 @@ } }, "node_modules/@jest/environment/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -981,40 +1014,40 @@ } }, "node_modules/@jest/environment/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/@jest/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", "dev": true, "dependencies": { - "expect": "^29.4.2", - "jest-snapshot": "^29.4.2" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", - "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.2" + "jest-get-type": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -1024,22 +1057,22 @@ } }, "node_modules/@jest/expect/node_modules/@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1050,12 +1083,12 @@ } }, "node_modules/@jest/expect/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1067,9 +1100,9 @@ } }, "node_modules/@jest/expect/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/@jest/expect/node_modules/ansi-styles": { @@ -1091,44 +1124,44 @@ "dev": true }, "node_modules/@jest/expect/node_modules/diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -1140,33 +1173,33 @@ } }, "node_modules/@jest/expect/node_modules/jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1175,18 +1208,18 @@ } }, "node_modules/@jest/expect/node_modules/jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect/node_modules/jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -1195,23 +1228,22 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "semver": "^7.3.5" }, "engines": { @@ -1219,12 +1251,12 @@ } }, "node_modules/@jest/expect/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1236,13 +1268,13 @@ } }, "node_modules/@jest/expect/node_modules/jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -1251,12 +1283,12 @@ } }, "node_modules/@jest/expect/node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -1286,26 +1318,26 @@ } }, "node_modules/@jest/fake-timers": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", - "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -1315,12 +1347,12 @@ } }, "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1332,9 +1364,9 @@ } }, "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/@jest/fake-timers/node_modules/ansi-styles": { @@ -1350,18 +1382,18 @@ } }, "node_modules/@jest/fake-timers/node_modules/jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -1370,12 +1402,12 @@ } }, "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -1387,12 +1419,12 @@ } }, "node_modules/@jest/fake-timers/node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -2048,19 +2080,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", - "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", + "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/type-utils": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/type-utils": "5.55.0", + "@typescript-eslint/utils": "5.55.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" }, @@ -2082,14 +2114,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", - "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", + "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", "debug": "^4.3.4" }, "engines": { @@ -2109,13 +2141,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", + "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2126,13 +2158,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", - "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", + "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/utils": "5.55.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -2153,9 +2185,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", + "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2166,13 +2198,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", + "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2193,18 +2225,18 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", + "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", "dev": true, "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" }, "engines": { @@ -2219,12 +2251,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", + "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.55.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -3044,12 +3076,15 @@ } }, "node_modules/eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.4.1", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -3060,10 +3095,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -3084,7 +3118,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -3241,33 +3274,6 @@ "node": ">=8.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, "node_modules/eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", @@ -3300,9 +3306,9 @@ } }, "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "dependencies": { "acorn": "^8.8.0", @@ -3330,9 +3336,9 @@ } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -3422,25 +3428,25 @@ } }, "node_modules/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -3450,12 +3456,12 @@ } }, "node_modules/expect/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -3467,9 +3473,9 @@ } }, "node_modules/expect/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/expect/node_modules/ansi-styles": { @@ -3485,57 +3491,57 @@ } }, "node_modules/expect/node_modules/diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -3544,12 +3550,12 @@ } }, "node_modules/expect/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -3561,12 +3567,12 @@ } }, "node_modules/expect/node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4537,28 +4543,29 @@ } }, "node_modules/jest-circus": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", - "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", "dev": true, "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "p-limit": "^3.1.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4567,16 +4574,16 @@ } }, "node_modules/jest-circus/node_modules/@jest/console": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", - "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" }, "engines": { @@ -4584,24 +4591,24 @@ } }, "node_modules/jest-circus/node_modules/@jest/globals": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", - "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/types": "^29.4.2", - "jest-mock": "^29.4.2" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -4611,9 +4618,9 @@ } }, "node_modules/jest-circus/node_modules/@jest/source-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", - "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", @@ -4625,13 +4632,13 @@ } }, "node_modules/jest-circus/node_modules/@jest/test-result": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", - "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "dependencies": { - "@jest/console": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -4640,22 +4647,22 @@ } }, "node_modules/jest-circus/node_modules/@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -4666,12 +4673,12 @@ } }, "node_modules/jest-circus/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -4683,9 +4690,9 @@ } }, "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/jest-circus/node_modules/ansi-styles": { @@ -4719,44 +4726,44 @@ "dev": true }, "node_modules/jest-circus/node_modules/diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4768,33 +4775,33 @@ } }, "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4803,26 +4810,26 @@ } }, "node_modules/jest-circus/node_modules/jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-resolve": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", - "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -4832,32 +4839,31 @@ } }, "node_modules/jest-circus/node_modules/jest-runtime": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", - "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/globals": "^29.4.2", - "@jest/source-map": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "semver": "^7.3.5", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4866,9 +4872,9 @@ } }, "node_modules/jest-circus/node_modules/jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -4877,23 +4883,22 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "semver": "^7.3.5" }, "engines": { @@ -4901,12 +4906,12 @@ } }, "node_modules/jest-circus/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -4918,30 +4923,30 @@ } }, "node_modules/jest-circus/node_modules/jest-validate": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", - "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.4.2" + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "dependencies": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -4950,12 +4955,12 @@ } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4970,9 +4975,9 @@ "dev": true }, "node_modules/jest-circus/node_modules/resolve.exports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", - "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", + "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", "dev": true, "engines": { "node": ">=10" @@ -5340,25 +5345,25 @@ } }, "node_modules/jest-each": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", - "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", - "jest-util": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-each/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -5368,12 +5373,12 @@ } }, "node_modules/jest-each/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -5385,9 +5390,9 @@ } }, "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/jest-each/node_modules/ansi-styles": { @@ -5403,12 +5408,12 @@ } }, "node_modules/jest-each/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -5420,12 +5425,12 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -5520,9 +5525,9 @@ } }, "node_modules/jest-get-type": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", - "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5686,23 +5691,23 @@ "dev": true }, "node_modules/jest-mock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", - "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-util": "^29.4.2" + "jest-util": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-mock/node_modules/@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "dependencies": { "@sinclair/typebox": "^0.25.16" @@ -5712,12 +5717,12 @@ } }, "node_modules/jest-mock/node_modules/@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -5729,18 +5734,18 @@ } }, "node_modules/jest-mock/node_modules/@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "node_modules/jest-mock/node_modules/jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -6963,6 +6968,22 @@ "node": ">=6" } }, + "node_modules/pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7006,18 +7027,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7679,16 +7688,16 @@ } }, "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=12.20" } }, "node_modules/unbox-primitive": { @@ -8420,15 +8429,30 @@ } } }, + "@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^3.3.0" + } + }, + "@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "dev": true + }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", + "espree": "^9.5.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -8437,6 +8461,12 @@ "strip-json-comments": "^3.1.1" } }, + "@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "dev": true + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -8621,33 +8651,33 @@ } }, "@jest/environment": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.2.tgz", - "integrity": "sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", "dev": true, "requires": { - "@jest/fake-timers": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^29.4.2" + "jest-mock": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8656,49 +8686,49 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true } } }, "@jest/expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", "dev": true, "requires": { - "expect": "^29.4.2", - "jest-snapshot": "^29.4.2" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -8706,12 +8736,12 @@ } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8720,9 +8750,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "ansi-styles": { @@ -8738,82 +8768,82 @@ "dev": true }, "diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, "jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -8822,33 +8852,32 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "semver": "^7.3.5" } }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8857,24 +8886,24 @@ } }, "jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -8897,44 +8926,44 @@ } }, "@jest/expect-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.2.tgz", - "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", "dev": true, "requires": { - "jest-get-type": "^29.4.2" + "jest-get-type": "^29.4.3" } }, "@jest/fake-timers": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.2.tgz", - "integrity": "sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-util": "^29.4.2" + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -8943,9 +8972,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "ansi-styles": { @@ -8955,29 +8984,29 @@ "dev": true }, "jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -8986,12 +9015,12 @@ } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -9559,71 +9588,71 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.52.0.tgz", - "integrity": "sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", + "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/type-utils": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/type-utils": "5.55.0", + "@typescript-eslint/utils": "5.55.0", "debug": "^4.3.4", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", "semver": "^7.3.7", "tsutils": "^3.21.0" } }, "@typescript-eslint/parser": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.52.0.tgz", - "integrity": "sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", + "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.52.0.tgz", - "integrity": "sha512-AR7sxxfBKiNV0FWBSARxM8DmNxrwgnYMPwmpkC1Pl1n+eT8/I2NAUPuwDy/FmDcC6F8pBfmOcaxcxRHspgOBMw==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", + "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0" + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0" } }, "@typescript-eslint/type-utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.52.0.tgz", - "integrity": "sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", + "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.52.0", - "@typescript-eslint/utils": "5.52.0", + "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/utils": "5.55.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.52.0.tgz", - "integrity": "sha512-oV7XU4CHYfBhk78fS7tkum+/Dpgsfi91IIDy7fjCyq2k6KB63M6gMC0YIvy+iABzmXThCRI6xpCEyVObBdWSDQ==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", + "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.52.0.tgz", - "integrity": "sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", + "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/visitor-keys": "5.52.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9632,28 +9661,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.52.0.tgz", - "integrity": "sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", + "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", "dev": true, "requires": { + "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.52.0", - "@typescript-eslint/types": "5.52.0", - "@typescript-eslint/typescript-estree": "5.52.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.52.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.52.0.tgz", - "integrity": "sha512-qMwpw6SU5VHCPr99y274xhbm+PRViK/NATY6qzt+Et7+mThGuFSl/ompj2/hrBlRP/kq+BFdgagnOSgw9TB0eA==", + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", + "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.52.0", + "@typescript-eslint/types": "5.55.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -10244,12 +10273,15 @@ "dev": true }, "eslint": { - "version": "8.34.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.34.0.tgz", - "integrity": "sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg==", + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -10260,10 +10292,9 @@ "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -10284,7 +10315,6 @@ "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", - "regexpp": "^3.2.0", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -10418,23 +10448,6 @@ "estraverse": "^4.1.1" } }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, "eslint-visitor-keys": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", @@ -10442,9 +10455,9 @@ "dev": true }, "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, "requires": { "acorn": "^8.8.0", @@ -10459,9 +10472,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -10528,34 +10541,34 @@ "dev": true }, "expect": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.2.tgz", - "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, "requires": { - "@jest/expect-utils": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2" + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -10564,9 +10577,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "ansi-styles": { @@ -10576,59 +10589,59 @@ "dev": true }, "diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, "jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -10637,12 +10650,12 @@ } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -11336,71 +11349,72 @@ } }, "jest-circus": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.2.tgz", - "integrity": "sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-runtime": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "p-limit": "^3.1.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, "dependencies": { "@jest/console": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.2.tgz", - "integrity": "sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" } }, "@jest/globals": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.2.tgz", - "integrity": "sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/expect": "^29.4.2", - "@jest/types": "^29.4.2", - "jest-mock": "^29.4.2" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" } }, "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.2.tgz", - "integrity": "sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.15", @@ -11409,34 +11423,34 @@ } }, "@jest/test-result": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.2.tgz", - "integrity": "sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "requires": { - "@jest/console": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/transform": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.2.tgz", - "integrity": "sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -11444,12 +11458,12 @@ } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -11458,9 +11472,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "ansi-styles": { @@ -11482,130 +11496,129 @@ "dev": true }, "diff-sequences": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.2.tgz", - "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, "jest-diff": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.2.tgz", - "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-haste-map": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.2.tgz", - "integrity": "sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.2", - "jest-util": "^29.4.2", - "jest-worker": "^29.4.2", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-matcher-utils": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz", - "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "jest-message-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.2.tgz", - "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-regex-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.2.tgz", - "integrity": "sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-resolve": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.2.tgz", - "integrity": "sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.4.2", - "jest-validate": "^29.4.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "jest-runtime": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.2.tgz", - "integrity": "sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", "dev": true, "requires": { - "@jest/environment": "^29.4.2", - "@jest/fake-timers": "^29.4.2", - "@jest/globals": "^29.4.2", - "@jest/source-map": "^29.4.2", - "@jest/test-result": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-mock": "^29.4.2", - "jest-regex-util": "^29.4.2", - "jest-resolve": "^29.4.2", - "jest-snapshot": "^29.4.2", - "jest-util": "^29.4.2", - "semver": "^7.3.5", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.2.tgz", - "integrity": "sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -11614,33 +11627,32 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.4.2", - "@jest/transform": "^29.4.2", - "@jest/types": "^29.4.2", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.4.2", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.4.2", - "jest-get-type": "^29.4.2", - "jest-haste-map": "^29.4.2", - "jest-matcher-utils": "^29.4.2", - "jest-message-util": "^29.4.2", - "jest-util": "^29.4.2", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.4.2", + "pretty-format": "^29.5.0", "semver": "^7.3.5" } }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -11649,38 +11661,38 @@ } }, "jest-validate": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.2.tgz", - "integrity": "sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^29.4.2" + "pretty-format": "^29.5.0" } }, "jest-worker": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.2.tgz", - "integrity": "sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "requires": { "@types/node": "*", - "jest-util": "^29.4.2", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -11692,9 +11704,9 @@ "dev": true }, "resolve.exports": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", - "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", + "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", "dev": true }, "supports-color": { @@ -11976,34 +11988,34 @@ } }, "jest-each": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.2.tgz", - "integrity": "sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.2", - "jest-util": "^29.4.2", - "pretty-format": "^29.4.2" + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -12012,9 +12024,9 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "ansi-styles": { @@ -12024,12 +12036,12 @@ "dev": true }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -12038,12 +12050,12 @@ } }, "pretty-format": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.2.tgz", - "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -12127,9 +12139,9 @@ } }, "jest-get-type": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.2.tgz", - "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true }, "jest-haste-map": { @@ -12258,32 +12270,32 @@ } }, "jest-mock": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.2.tgz", - "integrity": "sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-util": "^29.4.2" + "jest-util": "^29.5.0" }, "dependencies": { "@jest/schemas": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.2.tgz", - "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { "@sinclair/typebox": "^0.25.16" } }, "@jest/types": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.2.tgz", - "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^29.4.2", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -12292,18 +12304,18 @@ } }, "@sinclair/typebox": { - "version": "0.25.21", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", - "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "jest-util": { - "version": "29.4.2", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.2.tgz", - "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^29.4.2", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -13251,6 +13263,12 @@ "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -13274,12 +13292,6 @@ "functions-have-names": "^1.2.2" } }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -13737,9 +13749,9 @@ } }, "typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index ca8b9b98b..bb87bddee 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~4.9.3" + "typescript": "^5.0.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", @@ -56,20 +56,20 @@ "@types/jest": "^27.5.2", "@types/node": "^13.7.7", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.52.0", - "@typescript-eslint/parser": "^5.52.0", - "eslint": "^8.34.0", + "@typescript-eslint/eslint-plugin": "^5.55.0", + "@typescript-eslint/parser": "^5.55.0", + "eslint": "^8.36.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^28.1.3", - "jest-circus": "^29.4.2", + "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", - "prettier": "^2.3.2", + "prettier": "^2.8.4", "ts-jest": "^28.0.8", "ts-node": "^10.9.1", - "typescript": "~4.9.3" + "typescript": "^5.0.2" } } diff --git a/src/transformation/utils/typescript/nodes.ts b/src/transformation/utils/typescript/nodes.ts index ef6cec08f..09e2791c7 100644 --- a/src/transformation/utils/typescript/nodes.ts +++ b/src/transformation/utils/typescript/nodes.ts @@ -33,7 +33,11 @@ export function isInAsyncFunction(node: ts.Node): boolean { return false; } - return declaration.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; + if (ts.canHaveModifiers(declaration)) { + return ts.getModifiers(declaration)?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) ?? false; + } else { + return false; + } } export function isInGeneratorFunction(node: ts.Node): boolean { diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index d0fc1335c..9d473e040 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -39,7 +39,10 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: } // Scope cannot be an async function - if (scope.node.modifiers?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword)) { + if ( + ts.canHaveModifiers(scope.node) && + ts.getModifiers(scope.node)?.some(m => m.kind === ts.SyntaxKind.AsyncKeyword) + ) { return false; } diff --git a/src/transpilation/transformers.ts b/src/transpilation/transformers.ts index b06131e8c..0080b6e4e 100644 --- a/src/transpilation/transformers.ts +++ b/src/transpilation/transformers.ts @@ -79,7 +79,7 @@ export const stripParenthesisExpressionsTransformer: ts.TransformerFactory(context: ts.TransformationContext, node: T, visitor: ts.Visitor): T { const visit: ts.Visitor = node => visitor(node) ?? ts.visitEachChild(node, visit, context); - return ts.visitNode(node, visit); + return ts.visitEachChild(node, visit, context); } From f802fa591cb6c870bb041118afd6c30617c3b9a1 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 19 Mar 2023 11:36:33 +0100 Subject: [PATCH 575/764] Remove extra unused parameter from new call (#1418) * Remove extra unused parameter from new call * Fix prettier --- src/transformation/visitors/class/new.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 9fcdc3c94..7c608bc65 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -13,12 +13,7 @@ export const transformNewExpression: FunctionVisitor = (node, } const signature = context.checker.getResolvedSignature(node); - const [name, params] = transformCallAndArguments( - context, - node.expression, - node.arguments ?? [ts.factory.createTrue()], - signature - ); + const [name, params] = transformCallAndArguments(context, node.expression, node.arguments ?? [], signature); const type = context.checker.getTypeAtLocation(node); const annotations = getTypeAnnotations(type); From a17d9b15090b267d5fffae1a30f273870b6d1a51 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 19 Mar 2023 11:36:43 +0100 Subject: [PATCH 576/764] Fix cast exception (#1419) --- .../visitors/binary-expression/compound.ts | 17 ++++++++++++++--- test/unit/assignments.spec.ts | 10 ++++++++++ test/util.ts | 13 ++++++++++++- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/binary-expression/compound.ts b/src/transformation/visitors/binary-expression/compound.ts index 437f66a61..4532fe56c 100644 --- a/src/transformation/visitors/binary-expression/compound.ts +++ b/src/transformation/visitors/binary-expression/compound.ts @@ -1,12 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { cast, assertNever } from "../../../utils"; +import { assertNever } from "../../../utils"; import { TransformationContext } from "../../context"; import { transformInPrecedingStatementScope, WithPrecedingStatements } from "../../utils/preceding-statements"; import { transformBinaryOperation } from "./index"; import { transformAssignmentWithRightPrecedingStatements } from "./assignments"; import { isArrayLength } from "./destructuring-assignments"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { cannotAssignToNodeOfKind } from "../../utils/diagnostics"; function isLuaExpressionWithSideEffect(expression: lua.Expression) { return !(lua.isLiteral(expression) || lua.isIdentifier(expression)); @@ -85,7 +86,12 @@ function transformCompoundAssignment( return { precedingStatements, result: lengthSetterStatement.expression }; } - const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); + const left = context.transformExpression(lhs); + if (!lua.isAssignmentLeftHandSideExpression(left)) { + context.diagnostics.push(cannotAssignToNodeOfKind(expression, left.kind)); + return { precedingStatements: [], result: left }; + } + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( context, () => context.transformExpression(rhs) @@ -250,7 +256,12 @@ export function transformCompoundAssignmentStatement( return [...precedingStatements, lengthSetterStatement]; } - const left = cast(context.transformExpression(lhs), lua.isAssignmentLeftHandSideExpression); + const left = context.transformExpression(lhs); + if (!lua.isAssignmentLeftHandSideExpression(left)) { + context.diagnostics.push(cannotAssignToNodeOfKind(node, left.kind)); + return []; + } + const { precedingStatements: rightPrecedingStatements, result: right } = transformInPrecedingStatementScope( context, () => context.transformExpression(rhs) diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 398f0513b..53291f50f 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -506,3 +506,13 @@ test.each([ return [obj, objGot]; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1412 +test("invalid assignment to call expression (#1412)", () => { + util.testFunction` + function foo(): number { + return 3; + } + foo() += 4; + `.expectNoTranspileException(); +}); diff --git a/test/util.ts b/test/util.ts index a560b94f5..aab9d303f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -313,12 +313,23 @@ export abstract class TestBuilder { // Actions public debug(includeLualib = false): this { - const transpiledFiles = this.getLuaResult().transpiledFiles; + const { transpiledFiles, diagnostics } = this.getLuaResult(); const luaCode = transpiledFiles .filter(f => includeLualib || f.outPath !== "lualib_bundle.lua") .map(f => `[${f.outPath}]:\n${f.lua?.replace(/^/gm, " ")}`); const value = prettyFormat.format(this.getLuaExecutionResult()).replace(/^/gm, " "); console.log(`Lua Code:\n${luaCode.join("\n")}\n\nValue:\n${value}`); + + if (diagnostics.length > 0) { + console.log( + ts.formatDiagnostics(diagnostics.map(tstl.prepareDiagnosticForFormatting), { + getCurrentDirectory: () => "", + getCanonicalFileName: fileName => fileName, + getNewLine: () => "\n", + }) + ); + } + return this; } From 4578c3c144fbf6fdd0d1682c26e1ea4ea5384572 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 19 Mar 2023 11:36:53 +0100 Subject: [PATCH 577/764] Fix exception from function validation on functions with composite signatures (#1420) --- src/transformation/utils/function-context.ts | 8 ++++++++ src/typescript-internal.d.ts | 4 ++++ .../validation/invalidFunctionAssignments.spec.ts | 15 +++++++++++++++ .../validation/validFunctionAssignments.spec.ts | 15 +++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 41e70d40f..154150bd1 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -116,7 +116,15 @@ function reduceContextTypes(contexts: ContextType[]): ContextType { } function getSignatureDeclarations(context: TransformationContext, signature: ts.Signature): ts.SignatureDeclaration[] { + if (signature.compositeSignatures) { + return signature.compositeSignatures.flatMap(s => getSignatureDeclarations(context, s)); + } + const signatureDeclaration = signature.getDeclaration(); + if (signatureDeclaration === undefined) { + return []; + } + let inferredType: ts.Type | undefined; if ( ts.isMethodDeclaration(signatureDeclaration) && diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index afcf45685..59995ebce 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -35,6 +35,10 @@ declare module "typescript" { parent?: Symbol; } + interface Signature { + compositeSignatures?: Signature[]; + } + function transformJsx(context: TransformationContext): (x: SourceFile) => SourceFile; export type OuterExpression = diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index caf3576a7..95b26b7d0 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -226,3 +226,18 @@ test.each([ let f: ${assignType} = o; `.expectDiagnosticsToMatchSnapshot([unsupportedOverloadAssignment.code], true); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/896 +test("Does not fail on union type signatures (#896)", () => { + util.testExpression`foo<'a'>(() => {});` + .setTsHeader( + ` + declare interface Events { + a(): void; + [key: string]: (this: void) => void; + } + declare function foo(callback: Events[T]): void; + ` + ) + .expectToHaveDiagnostics([unsupportedOverloadAssignment.code]); +}); diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 8c98196d9..7a68d0ea6 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -233,3 +233,18 @@ test.each([ return f(${args.map(a => '"' + a + '"').join(", ")}); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/896 +test("Does not fail on union type signatures (#896)", () => { + util.testExpression`foo<'a'>(() => {});` + .setTsHeader( + ` + declare interface Events { + a(): void; + [key: string]: Function; + } + declare function foo(callback: Events[T]): void; + ` + ) + .expectToHaveNoDiagnostics(); +}); From 502eb61795a61a57afcc8c93dc336133bd836423 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 Mar 2023 11:53:49 +0100 Subject: [PATCH 578/764] CHANGELOG.md 1.14.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13ecfd9a3..4e7a82fdb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.14.0 + +- **[Breaking]** Upgraded TypeScript to 5.0. +- Added support for `Number.toFixed`. +- Added support for spread expressions with `LuaPairsIterable` and `LuaPairsKeysIterable`. +- Fixed a bug breaking module resolution when using a custom file extension. +- Fixed various exceptions that could happen when trying to translate invalid TS. + ## 1.13.0 - Fixed alternate file extensions (other than .lua, if configured) breaking module resolution and emitted require statements. From d69641896cb1577a8f770043ae77d3a59fe09abd Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 19 Mar 2023 12:02:16 +0100 Subject: [PATCH 579/764] 1.14.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a9e11883c..d1f94c985 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.13.3", + "version": "1.14.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.13.3", + "version": "1.14.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index bb87bddee..46c3b3af5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.13.3", + "version": "1.14.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From bfba5b7f4263c8c1340ddc58d4b9223d597a3432 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 30 Mar 2023 12:54:35 -0700 Subject: [PATCH 580/764] Don't output parameter initializer statement if default value is nil (#1424) * Don't output initializer if default value is nil * Handle preceding statements in default parameter value * Update test snapshots * Changes for PR --- src/transformation/visitors/function.ts | 36 +++++++++------- .../__snapshots__/functions.spec.ts.snap | 22 ++++++++++ test/unit/functions/functions.spec.ts | 42 +++++++++++++++++++ 3 files changed, 86 insertions(+), 14 deletions(-) diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index f79682223..1c21a0f7c 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -24,11 +24,17 @@ import { transformBindingPattern } from "./variable-declaration"; function transformParameterDefaultValueDeclaration( context: TransformationContext, parameterName: lua.Identifier, - value?: ts.Expression, + value: ts.Expression, tsOriginal?: ts.Node -): lua.Statement { - const parameterValue = value ? context.transformExpression(value) : undefined; - const assignment = lua.createAssignmentStatement(parameterName, parameterValue); +): lua.Statement | undefined { + const { precedingStatements: statements, result: parameterValue } = transformInPrecedingStatementScope( + context, + () => context.transformExpression(value) + ); + if (!lua.isNilLiteral(parameterValue)) { + statements.push(lua.createAssignmentStatement(parameterName, parameterValue)); + } + if (statements.length === 0) return undefined; const nilCondition = lua.createBinaryExpression( parameterName, @@ -36,7 +42,7 @@ function transformParameterDefaultValueDeclaration( lua.SyntaxKind.EqualityOperator ); - const ifBlock = lua.createBlock([assignment]); + const ifBlock = lua.createBlock(statements, tsOriginal); return lua.createIfStatement(nilCondition, ifBlock, undefined, tsOriginal); } @@ -106,7 +112,7 @@ export function transformFunctionBodyHeader( parameters: ts.NodeArray, spreadIdentifier?: lua.Identifier ): lua.Statement[] { - const headerStatements = []; + const headerStatements: lua.Statement[] = []; // Add default parameters and object binding patterns const bindingPatternDeclarations: lua.Statement[] = []; @@ -116,9 +122,12 @@ export function transformFunctionBodyHeader( const identifier = lua.createIdentifier(`____bindingPattern${bindPatternIndex++}`); if (declaration.initializer !== undefined) { // Default binding parameter - headerStatements.push( - transformParameterDefaultValueDeclaration(context, identifier, declaration.initializer) + const initializer = transformParameterDefaultValueDeclaration( + context, + identifier, + declaration.initializer ); + if (initializer) headerStatements.push(initializer); } // Binding pattern @@ -129,13 +138,12 @@ export function transformFunctionBodyHeader( bindingPatternDeclarations.push(...precedingStatements, ...bindings); } else if (declaration.initializer !== undefined) { // Default parameter - headerStatements.push( - transformParameterDefaultValueDeclaration( - context, - transformIdentifier(context, declaration.name), - declaration.initializer - ) + const initializer = transformParameterDefaultValueDeclaration( + context, + transformIdentifier(context, declaration.name), + declaration.initializer ); + if (initializer) headerStatements.push(initializer); } } diff --git a/test/unit/functions/__snapshots__/functions.spec.ts.snap b/test/unit/functions/__snapshots__/functions.spec.ts.snap index 4e07a4367..83345e13b 100644 --- a/test/unit/functions/__snapshots__/functions.spec.ts.snap +++ b/test/unit/functions/__snapshots__/functions.spec.ts.snap @@ -1,5 +1,27 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Function default parameter with value "null" 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function foo(self, x) + return x + end + return foo(nil) +end +return ____exports" +`; + +exports[`Function default parameter with value "undefined" 1`] = ` +"local ____exports = {} +function ____exports.__main(self) + local function foo(self, x) + return x + end + return foo(nil) +end +return ____exports" +`; + exports[`function.length unsupported ("5.0"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 7bd224fba..7bdf6b040 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -107,6 +107,48 @@ test("Function default binding parameter maintains order", () => { `.expectToMatchJsResult(); }); +test.each(["undefined", "null"])("Function default parameter with value %p", defaultValue => { + util.testFunction` + function foo(x = ${defaultValue}) { + return x; + } + return foo(); + ` + .expectToMatchJsResult() + .tap(builder => { + const lua = builder.getMainLuaCodeChunk(); + expect(lua).not.toMatch("if x == nil then"); + }) + .expectLuaToMatchSnapshot(); +}); + +test("Function default parameter with preceding statements", () => { + util.testFunction` + let i = 1 + function foo(x = i++) { + return x; + } + return [i, foo(), i]; + `.expectToMatchJsResult(); +}); + +test("Function default parameter with nil value and preceding statements", () => { + util.testFunction` + const a = new LuaTable() + a.set("foo", "bar") + function foo(x: any = a.set("foo", "baz")) { + return x ?? "nil"; + } + return [a.get("foo"), foo(), a.get("foo")]; + ` + .withLanguageExtensions() + .tap(builder => { + const lua = builder.getMainLuaCodeChunk(); + expect(lua).not.toMatch(" x = nil"); + }) + .expectToEqual(["bar", "nil", "baz"]); +}); + test("Class method call", () => { util.testFunction` class TestClass { From d13f80090479a7b4c17063dc4ef6756bb66d7fe8 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Wed, 12 Apr 2023 20:16:30 +0200 Subject: [PATCH 581/764] Fixed multi returning all values (#1428) We try to avoid using `select()` when we use `[0]` to access the first value of multiple returns (e.g. `multiCall()[0]`) In that case, we used to simply omit the `select()`. Unfortunately, this only works if the value is assigned directly (`local x = multiCall()`). In cases where the value is not assigned, omitting the select and keeping the original expression (`multiCall()`) will lead to all return values being passed on. (See #1411) To fix this, we now wrap the multireturncall in parentheses. using a new Lua parentheses expression. Using parenthesis is the correct way to keep only the first value of multiple returns (see https://www.lua.org/manual/5.1/manual.html#2.5) This fixes #1411 --- src/LuaAST.ts | 18 +++++++++++ src/LuaPrinter.ts | 6 ++++ src/transformation/visitors/access.ts | 14 +++++---- test/unit/language-extensions/multi.spec.ts | 35 +++++++++++++++++++++ test/util.ts | 5 +-- 5 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 2bfa16c18..994755617 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -44,6 +44,7 @@ export enum SyntaxKind { MethodCallExpression, Identifier, TableIndexExpression, + ParenthesizedExpression, // Operators @@ -843,3 +844,20 @@ export function isInlineFunctionExpression(expression: FunctionExpression): expr (expression.flags & NodeFlags.Inline) !== 0 ); } + +export type ParenthesizedExpression = Expression & { + expression: Expression; +}; + +export function isParenthesizedExpression(node: Node): node is ParenthesizedExpression { + return node.kind === SyntaxKind.ParenthesizedExpression; +} + +export function createParenthesizedExpression(expression: Expression, tsOriginal?: ts.Node): ParenthesizedExpression { + const parenthesizedExpression = createNode( + SyntaxKind.ParenthesizedExpression, + tsOriginal + ) as ParenthesizedExpression; + parenthesizedExpression.expression = expression; + return parenthesizedExpression; +} diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 97a68fd74..1f89dd4ec 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -612,6 +612,8 @@ export class LuaPrinter { return this.printIdentifier(expression as lua.Identifier); case lua.SyntaxKind.TableIndexExpression: return this.printTableIndexExpression(expression as lua.TableIndexExpression); + case lua.SyntaxKind.ParenthesizedExpression: + return this.printParenthesizedExpression(expression as lua.ParenthesizedExpression); default: throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`); } @@ -822,6 +824,10 @@ export class LuaPrinter { return this.createSourceNode(expression, chunks); } + public printParenthesizedExpression(expression: lua.ParenthesizedExpression) { + return this.createSourceNode(expression, ["(", this.printExpression(expression.expression), ")"]); + } + public printOperator(kind: lua.Operator): SourceNode { return new SourceNode(null, null, this.relativeSourcePath, LuaPrinter.operatorMap[kind]); } diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 12e9385ad..92955d15d 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -79,13 +79,15 @@ export function transformElementAccessExpressionWithCapture( context.diagnostics.push(invalidMultiReturnAccess(node)); } - // When selecting the first element, we can shortcut - if (ts.isNumericLiteral(node.argumentExpression) && node.argumentExpression.text === "0") { - return { expression: table }; - } else { - const selectIdentifier = lua.createIdentifier("select"); - return { expression: lua.createCallExpression(selectIdentifier, [updatedAccessExpression, table]) }; + const canOmitSelect = ts.isNumericLiteral(node.argumentExpression) && node.argumentExpression.text === "0"; + if (canOmitSelect) { + // wrapping in parenthesis ensures only the first return value is used + // https://www.lua.org/manual/5.1/manual.html#2.5 + return { expression: lua.createParenthesizedExpression(table) }; } + + const selectIdentifier = lua.createIdentifier("select"); + return { expression: lua.createCallExpression(selectIdentifier, [updatedAccessExpression, table]) }; } if (thisValueCapture) { diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 3350876e8..8282ef4fc 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -338,3 +338,38 @@ test("LuaMultiReturn applies after casting a function (#1404)", () => { .withLanguageExtensions() .expectToEqual([3, 4]); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1411 +describe("LuaMultiReturn returns all values even when indexed with [0] #1411", () => { + const sharedCode = ` + declare function select(this:void, index: '#', ...args: T[]): number; + + function foo(this: void): LuaMultiReturn<[number, number]> { + return $multi(123, 456); + } + + function bar(this: void): number { + return foo()[0]; + } + `; + test("Returns the correct value", () => { + util.testFunction` + return bar(); + ` + .setTsHeader(sharedCode) + .withLanguageExtensions() + .expectToEqual(123); + }); + + // We require an extra test since the test above would succeed even if bar() returned more than one value. + // This is because our test helper always returns just the first lua value returned from the testFunction. + // Here we need to test explicitly that only one value is returned. + test("Does not return multiple values", () => { + util.testFunction` + return select("#", bar()); + ` + .setTsHeader(sharedCode) + .withLanguageExtensions() + .expectToEqual(1); + }); +}); diff --git a/test/util.ts b/test/util.ts index aab9d303f..f2c73e1e2 100644 --- a/test/util.ts +++ b/test/util.ts @@ -161,7 +161,7 @@ export abstract class TestBuilder { skipLibCheck: true, target: ts.ScriptTarget.ES2017, lib: ["lib.esnext.d.ts"], - moduleResolution: ts.ModuleResolutionKind.NodeJs, + moduleResolution: ts.ModuleResolutionKind.Node10, resolveJsonModule: true, experimentalDecorators: true, sourceMap: true, @@ -173,7 +173,8 @@ export abstract class TestBuilder { } public withLanguageExtensions(): this { - this.setOptions({ types: [path.resolve(__dirname, "..", "language-extensions")] }); + const langExtTypes = path.resolve(__dirname, "..", "language-extensions"); + this.options.types = this.options.types ? [...this.options.types, langExtTypes] : [langExtTypes]; // Polyfill lualib for JS this.setJsHeader(` function $multi(...args) { return args; } From 2982567139e5e29dd6b7488b2b8a3e6bbcac2c61 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 1 May 2023 21:20:34 +0200 Subject: [PATCH 582/764] Fix nested namespace merging (#1435) * Upgrade ts-jest * Fix nested namespaces leading to invalid Lua --- jest.config.js | 13 +- package-lock.json | 11961 ++++++---------- package.json | 4 +- src/transformation/utils/export.ts | 4 +- src/transformation/visitors/namespace.ts | 11 +- .../__snapshots__/transformation.spec.ts.snap | 86 +- .../__snapshots__/directories.spec.ts.snap | 8 +- .../module-resolution.spec.ts.snap | 4 +- .../__snapshots__/project.spec.ts.snap | 12 +- .../__snapshots__/plugins.spec.ts.snap | 4 +- test/unit/__snapshots__/bundle.spec.ts.snap | 4 +- test/unit/__snapshots__/comments.spec.ts.snap | 2 +- .../__snapshots__/expressions.spec.ts.snap | 16 +- .../__snapshots__/identifiers.spec.ts.snap | 104 +- .../optionalChaining.spec.ts.snap | 24 +- test/unit/__snapshots__/spread.spec.ts.snap | 2 +- test/unit/__snapshots__/switch.spec.ts.snap | 40 +- .../customConstructor.spec.ts.snap | 4 +- .../__snapshots__/console.spec.ts.snap | 48 +- .../__snapshots__/classes.spec.ts.snap | 4 +- .../__snapshots__/decorators.spec.ts.snap | 4 +- .../__snapshots__/iterable.spec.ts.snap | 4 +- .../__snapshots__/multi.spec.ts.snap | 6 +- .../__snapshots__/pairsIterable.spec.ts.snap | 4 +- .../__snapshots__/range.spec.ts.snap | 4 +- .../__snapshots__/table.spec.ts.snap | 12 +- .../__snapshots__/resolution.spec.ts.snap | 2 +- test/unit/namespaces.spec.ts | 12 + .../__snapshots__/semicolons.spec.ts.snap | 16 +- 29 files changed, 4767 insertions(+), 7652 deletions(-) diff --git a/jest.config.js b/jest.config.js index d07ef2022..26b60c1cf 100644 --- a/jest.config.js +++ b/jest.config.js @@ -15,10 +15,13 @@ module.exports = { testEnvironment: "node", testRunner: "jest-circus/runner", preset: "ts-jest", - globals: { - "ts-jest": { - tsconfig: "/test/tsconfig.json", - diagnostics: { warnOnly: !isCI }, - }, + transform: { + "^.+\\.ts?$": [ + "ts-jest", + { + tsconfig: "/test/tsconfig.json", + diagnostics: { warnOnly: !isCI }, + }, + ], }, }; diff --git a/package-lock.json b/package-lock.json index d1f94c985..b3f3befaa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,12 +30,12 @@ "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^28.1.3", + "jest": "^29.5.0", "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.8.4", - "ts-jest": "^28.0.8", + "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typescript": "^5.0.2" }, @@ -872,60 +872,59 @@ } }, "node_modules/@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", - "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", "dev": true, "dependencies": { - "@jest/console": "^28.1.3", - "@jest/reporters": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.1.3", - "jest-config": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-resolve-dependencies": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "jest-watcher": "^28.1.3", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "rimraf": "^3.0.0", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -949,18 +948,17 @@ } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/core/node_modules/react-is": { @@ -984,67 +982,107 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "node_modules/@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.25.16" + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment/node_modules/@jest/types": { + "node_modules/@jest/expect-utils": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "jest-get-type": "^29.4.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/environment/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "node_modules/@jest/fake-timers": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, - "node_modules/@jest/expect": { + "node_modules/@jest/globals": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", "dev": true, "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/expect-utils": { + "node_modules/@jest/reporters": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "dependencies": { - "jest-get-type": "^29.4.3" + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@jest/expect/node_modules/@jest/schemas": { + "node_modules/@jest/schemas": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", @@ -1056,7 +1094,51 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/expect/node_modules/@jest/transform": { + "node_modules/@jest/source-map": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "dev": true, + "dependencies": { + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", @@ -1082,7 +1164,13 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/expect/node_modules/@jest/types": { + "node_modules/@jest/transform/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, + "node_modules/@jest/types": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", @@ -1099,1913 +1187,1921 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/expect/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } }, - "node_modules/@jest/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", "dev": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.0.0" } }, - "node_modules/@jest/expect/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", "dev": true }, - "node_modules/@jest/expect/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@jest/expect/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 8" } }, - "node_modules/@jest/expect/node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">= 8" } }, - "node_modules/@jest/expect/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "node_modules/@sinclair/typebox": { + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "type-detect": "4.0.8" } }, - "node_modules/@jest/expect/node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@sinonjs/commons": "^2.0.0" } }, - "node_modules/@jest/expect/node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "node_modules/@tsconfig/node10": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", + "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", + "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "dev": true + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/@jest/expect/node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@babel/types": "^7.0.0" } }, - "node_modules/@jest/expect/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/@jest/expect/node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@babel/types": "^7.3.0" } }, - "node_modules/@jest/expect/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "node_modules/@types/fs-extra": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", + "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/node": "*" } }, - "node_modules/@jest/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/@jest/expect/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "@types/minimatch": "*", + "@types/node": "*" } }, - "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/node": "*" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/istanbul-lib-coverage": "*" } }, - "node_modules/@jest/fake-timers/node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/istanbul-lib-report": "*" } }, - "node_modules/@jest/fake-timers/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/@jest/fake-timers/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/fake-timers/node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "node_modules/@types/jest": { + "version": "27.5.2", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", + "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" } }, - "node_modules/@jest/fake-timers/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true }, - "node_modules/@jest/fake-timers/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true }, - "node_modules/@jest/fake-timers/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", "dev": true }, - "node_modules/@jest/globals": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", - "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", + "node_modules/@types/node": { + "version": "13.13.52", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", + "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/resolve": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", + "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/types": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "@types/node": "*" } }, - "node_modules/@jest/globals/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.22", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", + "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "@types/yargs-parser": "*" } }, - "node_modules/@jest/globals/node_modules/@jest/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", + "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", "dev": true, "dependencies": { - "expect": "^28.1.3", - "jest-snapshot": "^28.1.3" + "@eslint-community/regexpp": "^4.4.0", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/type-utils": "5.55.0", + "@typescript-eslint/utils": "5.55.0", + "debug": "^4.3.4", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/globals/node_modules/@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "node_modules/@typescript-eslint/parser": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", + "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", "dev": true, "dependencies": { - "jest-get-type": "^28.0.2" + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", + "debug": "^4.3.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", + "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/globals/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "node_modules/@typescript-eslint/type-utils": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", + "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@jest/globals/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/utils": "5.55.0", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, "engines": { - "node": ">=10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/globals/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "node_modules/@typescript-eslint/types": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", + "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/globals/node_modules/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", + "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", "dev": true, "dependencies": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/visitor-keys": "5.55.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "node_modules/@typescript-eslint/utils": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", + "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/@jest/globals/node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true, + "@eslint-community/eslint-utils": "^4.2.0", + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.55.0", + "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/typescript-estree": "5.55.0", + "eslint-scope": "^5.1.1", + "semver": "^7.3.7" + }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.55.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", + "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "@typescript-eslint/types": "5.55.0", + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "node_modules/@typescript-to-lua/language-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", + "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" + "bin": { + "acorn": "bin/acorn" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=0.4.0" } }, - "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/@jest/globals/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } }, - "node_modules/@jest/reporters": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", - "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.24.1" + "type-fest": "^0.21.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@jest/source-map": { - "version": "28.1.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", - "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.13", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "dependencies": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "color-convert": "^2.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/test-sequencer": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", - "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { - "@jest/test-result": "^28.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "slash": "^3.0.0" + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 8" } }, - "node_modules/@jest/transform": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", - "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", "dev": true, "engines": { - "node": ">=6.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/babel-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@jest/transform": "^29.5.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.5.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/babel-plugin-jest-hoist": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true - }, - "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "node_modules/babel-preset-jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^2.0.0" + "babel-plugin-jest-hoist": "^29.5.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, - "node_modules/@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "dependencies": { - "@babel/types": "^7.0.0" + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/browserslist": { + "version": "4.21.5", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", + "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "caniuse-lite": "^1.0.30001449", + "electron-to-chromium": "^1.4.284", + "node-releases": "^2.0.8", + "update-browserslist-db": "^1.0.10" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "dependencies": { - "@babel/types": "^7.3.0" + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "dependencies": { - "@types/node": "*" + "node-int64": "^0.4.0" } }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@types/graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, - "dependencies": { - "@types/node": "*" + "engines": { + "node": ">=6" } }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" + "engines": { + "node": ">=6" } }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "node_modules/caniuse-lite": { + "version": "1.0.30001451", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", + "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "@types/istanbul-lib-report": "*" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" + "engines": { + "node": ">=10" } }, - "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "node_modules/ci-info": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", + "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", "dev": true }, - "node_modules/@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", "dev": true }, - "node_modules/@types/resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "@types/node": "*" + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, - "node_modules/@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", "dev": true }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", - "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/type-utils": "5.55.0", - "@typescript-eslint/utils": "5.55.0", - "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 8" } }, - "node_modules/@typescript-eslint/parser": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", - "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", - "debug": "^4.3.4" + "ms": "2.1.2" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": ">=6.0" }, "peerDependenciesMeta": { - "typescript": { + "supports-color": { "optional": true } } }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", - "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=0.10.0" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", - "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", + "node_modules/define-properties": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", + "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.55.0", - "@typescript-eslint/utils": "5.55.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/@typescript-eslint/types": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", - "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=8" } }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", - "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=0.3.1" } }, - "node_modules/@typescript-eslint/utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", - "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", - "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.55.0", - "eslint-visitor-keys": "^3.3.0" + "path-type": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "node": ">=8" } }, - "node_modules/@typescript-to-lua/language-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", - "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, - "bin": { - "acorn": "bin/acorn" + "dependencies": { + "esutils": "^2.0.2" }, "engines": { - "node": ">=0.4.0" + "node": ">=6.0.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/electron-to-chromium": { + "version": "1.4.295", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", + "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" } }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enhanced-resolve": { + "version": "5.12.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", + "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, "engines": { - "node": ">=0.4.0" + "node": ">=10.13.0" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "is-arrayish": "^0.2.1" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/es-abstract": { + "version": "1.21.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", + "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", "dev": true, "dependencies": { - "type-fest": "^0.21.3" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.4", + "is-array-buffer": "^3.0.1", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.10", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.9" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "node_modules/es-set-tostringtag": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", + "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "get-intrinsic": "^1.1.3", + "has": "^1.0.3", + "has-tostringtag": "^1.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 0.4" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "has": "^1.0.3" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">=8" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, "engines": { - "node": ">= 8" + "node": ">=6" } }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "node_modules/eslint": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", + "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.4.0", + "@eslint/eslintrc": "^2.0.1", + "@eslint/js": "8.36.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "doctrine": "^3.0.0", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^7.1.1", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.5.0", + "esquery": "^1.4.2", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^6.0.1", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">= 0.4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://opencollective.com/eslint" } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", + "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.11.0", + "resolve": "^1.22.1" } }, - "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "ms": "^2.1.1" } }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" + "debug": "^3.2.7" }, "engines": { - "node": ">= 0.4" + "node": ">=4" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "dependencies": { + "ms": "^2.1.1" } }, - "node_modules/babel-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", - "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "node_modules/eslint-plugin-import": { + "version": "2.27.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", + "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", "dev": true, "dependencies": { - "@jest/transform": "^28.1.3", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "array.prototype.flatmap": "^1.3.1", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.7", + "eslint-module-utils": "^2.7.4", + "has": "^1.0.3", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.6", + "resolve": "^1.22.1", + "semver": "^6.3.0", + "tsconfig-paths": "^3.14.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=4" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" + "ms": "^2.1.1" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", - "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "esutils": "^2.0.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=0.10.0" } }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/babel-preset-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", - "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "node_modules/eslint-plugin-jest": { + "version": "26.9.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", + "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^28.1.3", - "babel-preset-current-node-syntax": "^1.0.0" + "@typescript-eslint/utils": "^5.10.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "dev": true, "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "node_modules/eslint/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/espree": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", + "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, "bin": { - "browserslist": "cli.js" + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": ">=4" } }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { - "fast-json-stable-stringify": "2.x" + "estraverse": "^5.1.0" }, "engines": { - "node": ">= 6" + "node": ">=0.10" } }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "node_modules/esquery/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "dependencies": { - "node-int64": "^0.4.0" + "engines": { + "node": ">=4.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "estraverse": "^5.2.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=4.0" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4.0" } }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4.0" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001451", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", - "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] + "engines": { + "node": ">=0.10.0" + } }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "node_modules/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], + "dependencies": { + "@jest/expect-utils": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "node_modules/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, "engines": { - "node": ">=12" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "node_modules/expect/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/expect/node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">=7.0.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "node_modules/expect/node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/expect/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "ms": "2.1.2" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "node_modules/expect/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/deepmerge": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", - "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "node_modules/fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8.6.0" } }, - "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" + "is-glob": "^4.0.1" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 6" } }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true + }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "reusify": "^1.0.4" } }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, - "engines": { - "node": ">=0.3.1" + "dependencies": { + "bser": "2.1.1" } }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "node_modules/file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "dependencies": { - "path-type": "^4.0.0" + "to-regex-range": "^5.0.1" }, "engines": { "node": ">=8" } }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": ">=6.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/electron-to-chromium": { - "version": "1.4.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", - "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", - "dev": true - }, - "node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "dev": true, - "engines": { - "node": ">=12" + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" + "engines": { + "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, - "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" + "is-callable": "^1.1.3" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" }, "engines": { "node": ">= 0.4" @@ -3014,59 +3110,60 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=6.9.0" } }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "dependencies": { - "has": "^1.0.3" + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "node_modules/get-intrinsic": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", + "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", "dev": true, "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "engines": { - "node": ">=6" + "node": ">=8.0.0" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "engines": { "node": ">=10" @@ -3075,2503 +3172,2200 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "dependencies": { - "debug": "^3.2.7" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=4" + "node": "*" }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" } }, - "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "node_modules/globals": { + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "type-fest": "^0.20.2" }, "engines": { - "node": ">=4" + "node": ">=8" }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", "dev": true, "dependencies": { - "ms": "^2.1.1" + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, "dependencies": { - "esutils": "^2.0.2" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-jest": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", - "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", - "dev": true, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "function-bind": "^1.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } + "node": ">= 0.4.0" } }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "get-intrinsic": "^1.1.1" }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "dependencies": { + "has-symbols": "^1.0.2" }, "engines": { - "node": ">=4" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, "engines": { - "node": ">=0.10" + "node": ">=10.17.0" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">= 4" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" }, "engines": { - "node": ">=4.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, "engines": { - "node": ">=4.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "engines": { - "node": ">=4.0" + "node": ">=0.8.19" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", + "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" + "get-intrinsic": "^1.2.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" } }, - "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "node_modules/is-array-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", + "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-typed-array": "^1.1.10" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", "dev": true, "dependencies": { - "@sinclair/typebox": "^0.25.16" + "has-bigints": "^1.0.1" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/expect/node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/expect/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/expect/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "is-extglob": "^2.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, "engines": { - "node": ">=8.6.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, "engines": { - "node": ">= 6" + "node": ">=0.12.0" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "dependencies": { - "reusify": "^1.0.4" + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, - "dependencies": { - "bser": "2.1.1" + "engines": { + "node": ">=8" } }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", "dev": true, "dependencies": { - "flat-cache": "^3.0.4" + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", "dev": true, "dependencies": { - "to-regex-range": "^5.0.1" + "call-bind": "^1.0.2" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "has-tostringtag": "^1.0.0" }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", "dev": true, "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "has-symbols": "^1.0.2" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "node_modules/is-typed-array": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", + "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", "dev": true, "dependencies": { - "is-callable": "^1.1.3" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "call-bind": "^1.0.2" }, - "engines": { - "node": ">=6 <7 || >=8" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=8" } }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "engines": { - "node": ">=6.9.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=8" } }, - "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=10" } }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, "engines": { - "node": ">=8.0.0" + "node": ">=0.10.0" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "node_modules/jest": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", + "import-local": "^3.0.2", + "jest-cli": "^29.5.0" + }, + "bin": { + "jest": "bin/jest.js" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "node_modules/jest-changed-files": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "execa": "^5.0.0", + "p-limit": "^3.1.0" }, "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/jest-circus": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", + "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", "dev": true, "dependencies": { - "is-glob": "^4.0.3" + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.5.0", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.5.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=10.13.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "node_modules/jest-circus/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, - "dependencies": { - "define-properties": "^1.1.3" - }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/jest-circus/node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "node_modules/jest-circus/node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3" + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/jest-circus/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "dev": true, "dependencies": { - "function-bind": "^1.1.1" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 0.4.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "node_modules/jest-circus/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/jest-cli": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, + "dependencies": { + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "node_modules/jest-config": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "dev": true, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "node_modules/jest-config/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "node_modules/jest-config/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, "engines": { - "node": ">=10.17.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "node_modules/jest-diff/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, "engines": { - "node": ">= 4" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "node_modules/jest-docblock": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "detect-newline": "^3.0.0" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "node_modules/jest-each": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", + "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", "dev": true, "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" + "@jest/types": "^29.5.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.4.3", + "jest-util": "^29.5.0", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">=0.8.19" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "node_modules/jest-each/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "once": "^1.3.0", - "wrappy": "1" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "node_modules/jest-each/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "node_modules/jest-environment-node": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 0.4" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "node_modules/jest-get-type": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", + "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-typed-array": "^1.1.10" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "node_modules/jest-haste-map": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "dependencies": { - "has-bigints": "^1.0.1" + "@jest/types": "^29.5.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" } }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "node_modules/jest-leak-detector": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dependencies": { - "has": "^1.0.3" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "node_modules/jest-leak-detector/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } + "node_modules/jest-leak-detector/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, "engines": { - "node": ">=8" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "node_modules/jest-matcher-utils/node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, "engines": { - "node": ">=6" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "node_modules/jest-message-util": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "dependencies": { - "is-extglob": "^2.1.1" + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.5.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" }, "engines": { - "node": ">=0.10.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/jest-message-util/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, "engines": { - "node": ">=0.12.0" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "node_modules/jest-message-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-mock": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", + "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-util": "^29.5.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" + "node": ">=6" }, - "engines": { - "node": ">= 0.4" + "peerDependencies": { + "jest-resolve": "*" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } } }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "node_modules/jest-regex-util": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "node_modules/jest-resolve-dependencies": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "node_modules/jest-runner": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "dependencies": { - "has-tostringtag": "^1.0.0" + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "node_modules/jest-runtime": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "node_modules/jest-snapshot": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.5.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.5.0", + "semver": "^7.3.5" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "node_modules/jest-snapshot/node_modules/diff-sequences": { + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "node_modules/jest-snapshot/node_modules/jest-diff": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "chalk": "^4.0.0", + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/jest-snapshot/node_modules/pretty-format": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=8" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "node_modules/jest-snapshot/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true }, - "node_modules/jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", - "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", - "dev": true, - "dependencies": { - "@jest/core": "^28.1.3", - "@jest/types": "^28.1.3", - "import-local": "^3.0.2", - "jest-cli": "^28.1.3" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", - "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", - "dev": true, - "dependencies": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-circus": { + "node_modules/jest-util": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/console": { + "node_modules/jest-validate": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "dependencies": { "@jest/types": "^29.5.0", - "@types/node": "*", + "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" + "jest-get-type": "^29.4.3", + "leven": "^3.1.0", + "pretty-format": "^29.5.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.25.16" + "node": ">=10" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-circus/node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-circus/node_modules/@jest/test-result": { + "node_modules/jest-validate/node_modules/pretty-format": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@jest/schemas": "^29.4.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/transform": { + "node_modules/jest-validate/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/jest-watcher": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", + "@jest/test-result": "^29.5.0", "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", + "emittery": "^0.13.1", "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "string-length": "^4.0.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@jest/types": { + "node_modules/jest-worker": { "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "jest-util": "^29.5.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-circus/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/jest-circus/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jest-circus/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", "dev": true, - "engines": { - "node": ">=10" - }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" } }, - "node_modules/jest-circus/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true }, - "node_modules/jest-circus/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jest-circus/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=4" } }, - "node_modules/jest-circus/node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" + "bin": { + "json5": "lib/cli.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "node": ">=6" } }, - "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "optionalDependencies": { + "graceful-fs": "^4.1.6" } }, - "node_modules/jest-circus/node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/jest-circus/node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=6" } }, - "node_modules/jest-circus/node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 0.8.0" } }, - "node_modules/jest-circus/node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" + "p-locate": "^5.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-circus/node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "yallist": "^3.0.2" } }, - "node_modules/jest-circus/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "node_modules/lua-types": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", + "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", + "dev": true + }, + "node_modules/lua-wasm-bindings": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", + "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "@types/semver": "^7.3.9", + "semver": "^7.3.7" } }, - "node_modules/jest-circus/node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", "dev": true, "dependencies": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "semver": "^6.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-circus/node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "node": ">=8" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/jest-circus/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/jest-circus/node_modules/resolve.exports": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", - "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "tmpl": "1.0.5" } }, - "node_modules/jest-circus/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": ">= 8" } }, - "node_modules/jest-cli": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", - "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "@jest/core": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - }, - "bin": { - "jest": "bin/jest.js" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "node": ">=8.6" } }, - "node_modules/jest-config": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", - "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, - "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.3", - "@jest/types": "^28.1.3", - "babel-jest": "^28.1.3", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.3", - "jest-environment-node": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "ts-node": { - "optional": true - } + "node": ">=6" } }, - "node_modules/jest-config/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "*" } }, - "node_modules/jest-config/node_modules/@jest/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, - "dependencies": { - "expect": "^28.1.3", - "jest-snapshot": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", + "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", + "dev": true + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, - "dependencies": { - "jest-get-type": "^28.0.2" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-config/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" + "path-key": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-config/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/jest-config/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" + "node": ">=8" } }, - "node_modules/jest-config/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/object-inspect": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", + "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", "dev": true, - "engines": { - "node": ">=10" - }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 0.4" } }, - "node_modules/jest-config/node_modules/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", "dev": true, "dependencies": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/jest-circus": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", - "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "p-limit": "^3.1.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-config/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "wrappy": "1" } }, - "node_modules/jest-config/node_modules/jest-each": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", - "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "jest-util": "^28.1.3", - "pretty-format": "^28.1.3" + "mimic-fn": "^2.1.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-config/node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 0.8.0" } }, - "node_modules/jest-config/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" + "yocto-queue": "^0.1.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-config/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "callsites": "^3.0.0" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=6" } }, - "node_modules/jest-diff/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-docblock": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", - "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-each/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-each/node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-each/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", "dev": true }, - "node_modules/jest-each/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/jest-each/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">= 6" } }, - "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "dependencies": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "find-up": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-each/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-environment-node": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", - "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" + "p-locate": "^4.1.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" + "p-try": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-environment-node/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/jest-environment-node/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/jest-environment-node/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "node_modules/prettier": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", + "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" + "bin": { + "prettier": "bin-prettier.js" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", - "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", - "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10.13.0" }, - "optionalDependencies": { - "fsevents": "^2.3.2" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/jest-leak-detector": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", - "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "dependencies": { - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/jest-leak-detector/node_modules/ansi-styles": { + "node_modules/pretty-format/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", @@ -5583,3603 +5377,1667 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/jest-leak-detector/node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 6" } }, - "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=6" } }, - "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "node_modules/pure-rand": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", + "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ] + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" }, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-matcher-utils/node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", - "dev": true, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-message-util/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" + "bin": { + "resolve": "bin/resolve" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "resolve-from": "^5.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-mock/node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.25.16" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=4" } }, - "node_modules/jest-mock/node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, - "dependencies": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=10" } }, - "node_modules/jest-mock/node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "node_modules/jest-mock/node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "dependencies": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, - "engines": { - "node": ">=6" + "dependencies": { + "glob": "^7.1.3" }, - "peerDependencies": { - "jest-resolve": "*" + "bin": { + "rimraf": "bin.js" }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "node_modules/jest-resolve": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", - "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-resolve-dependencies": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", - "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { - "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.3" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" } }, - "node_modules/jest-runner": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", - "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "dev": true, "dependencies": { - "@jest/console": "^28.1.3", - "@jest/environment": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "graceful-fs": "^4.2.9", - "jest-docblock": "^28.1.1", - "jest-environment-node": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-leak-detector": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-resolve": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-util": "^28.1.3", - "jest-watcher": "^28.1.3", - "jest-worker": "^28.1.3", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" + "yallist": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" } }, - "node_modules/jest-runner/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" + "shebang-regex": "^3.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-runner/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-runner/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "dependencies": { - "type-detect": "4.0.8" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-runner/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true }, - "node_modules/jest-runner/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-runtime": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", - "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", - "dev": true, - "dependencies": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/globals": "^28.1.3", - "@jest/source-map": "^28.1.2", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">= 8" } }, - "node_modules/jest-runtime/node_modules/@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "dependencies": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/jest-runtime/node_modules/@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=0.10.0" } }, - "node_modules/jest-runtime/node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true }, - "node_modules/jest-runtime/node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.7.0" + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/jest-runtime/node_modules/jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-snapshot": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", - "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^28.1.3", - "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "natural-compare": "^1.4.0", - "pretty-format": "^28.1.3", - "semver": "^7.3.5" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=10" } }, - "node_modules/jest-snapshot/node_modules/@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "dependencies": { - "jest-get-type": "^28.0.2" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-snapshot/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", "dev": true, - "engines": { - "node": ">=10" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-snapshot/node_modules/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", "dev": true, "dependencies": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-snapshot/node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=6" } }, - "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, - "dependencies": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/jest-validate": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", - "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "@jest/types": "^28.1.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "leven": "^3.1.0", - "pretty-format": "^28.1.3" + "has-flag": "^4.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=8" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/jest-validate/node_modules/jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=6" } }, - "node_modules/jest-validate/node_modules/pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "dependencies": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8" } }, - "node_modules/jest-validate/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, - "node_modules/jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, - "dependencies": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", - "string-length": "^4.0.1" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=4" } }, - "node_modules/jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "is-number": "^7.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + "node": ">=8.0" } }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/ts-jest": { + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", + "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^29.0.0", + "json5": "^2.2.3", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "^21.0.1" + }, + "bin": { + "ts-jest": "cli.js" }, "engines": { - "node": ">=10" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/types": "^29.0.0", + "babel-jest": "^29.0.0", + "jest": "^29.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } } }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "node_modules/ts-node": { + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", + "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } } }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", "dev": true, "dependencies": { - "argparse": "^2.0.1" + "minimist": "^1.2.0" }, "bin": { - "js-yaml": "bin/js-yaml.js" + "json5": "lib/cli.js" } }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "bin": { - "jsesc": "bin/jsesc" - }, "engines": { "node": ">=4" } }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "dev": true }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", "dev": true, - "bin": { - "json5": "lib/cli.js" + "dependencies": { + "tslib": "^1.8.1" }, "engines": { - "node": ">=6" + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", "dev": true, "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" }, - "engines": { - "node": ">= 0.8.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/typescript": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", + "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", "dev": true, - "dependencies": { - "p-locate": "^5.0.0" + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12.20" } }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "dependencies": { - "yallist": "^3.0.2" + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/lua-types": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", - "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", - "dev": true - }, - "node_modules/lua-wasm-bindings": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", - "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "dependencies": { - "@types/semver": "^7.3.9", - "semver": "^7.3.7" + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], "dependencies": { - "semver": "^6.0.0" + "escalade": "^3.1.1", + "picocolors": "^1.0.0" }, - "engines": { - "node": ">=8" + "bin": { + "browserslist-lint": "cli.js" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "bin": { - "semver": "bin/semver.js" + "dependencies": { + "punycode": "^2.1.0" } }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", "dev": true }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "node_modules/v8-to-istanbul": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "dependencies": { - "tmpl": "1.0.5" + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "engines": { - "node": ">= 8" + "dependencies": { + "makeerror": "1.0.12" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" }, "engines": { - "node": ">=8.6" + "node": ">= 8" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", "dev": true, "dependencies": { - "brace-expansion": "^1.1.7" + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/which-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", + "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.10" }, "engines": { - "node": ">=8" - } - }, - "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", - "dev": true, + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "dev": true, "engines": { - "node": ">= 0.4" + "node": ">=0.10.0" } }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "dependencies": { - "wrappy": "1" + "engines": { + "node": ">=10" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - }, "engines": { - "node": ">= 0.8.0" + "node": ">=12" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, "engines": { "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/p-try": { + } + }, + "dependencies": { + "@ampproject/remapping": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" + "requires": { + "@babel/highlight": "^7.18.6" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "@babel/compat-data": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", + "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "dev": true + }, + "@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "@babel/generator": { + "version": "7.20.14", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", + "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", "dev": true, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.18.6" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "requires": { + "@babel/types": "^7.18.6" } }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", "dev": true, - "engines": { - "node": ">= 6" + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.20.2" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/types": "^7.18.6" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } + "@babel/parser": { + "version": "7.20.15", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", + "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "dev": true }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, - "engines": { - "node": ">= 0.8.0" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/prettier": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", - "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", "dev": true, - "engines": { - "node": ">=6" + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" } }, - "node_modules/pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ] + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, - "engines": { - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, - "engines": { - "node": ">=4" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" } }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dev": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" } }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" + "requires": { + "@jridgewell/trace-mapping": "0.3.9" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" + "dependencies": { + "@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + } } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "@eslint-community/eslint-utils": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", + "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "requires": { + "eslint-visitor-keys": "^3.3.0" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "@eslint-community/regexpp": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", + "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", "dev": true }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-jest": { - "version": "28.0.8", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", - "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "^2.2.1", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/types": "^28.0.0", - "babel-jest": "^28.0.0", - "jest": "^28.0.0", - "typescript": ">=4.3" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@jest/types": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typescript": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", - "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", - "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", - "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", - "dev": true - }, - "@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", - "dev": true, - "requires": { - "@babel/types": "^7.20.7", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" - } - }, - "@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", - "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", - "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", - "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.5.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz", - "integrity": "sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz", - "integrity": "sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA==", - "dev": true, - "requires": { - "@jest/console": "^28.1.3", - "@jest/reporters": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^28.1.3", - "jest-config": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-resolve-dependencies": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", - "jest-watcher": "^28.1.3", - "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", - "dev": true, - "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - } - } - }, - "@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", - "dev": true, - "requires": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true - }, - "jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", - "dev": true - }, - "jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "@eslint/eslintrc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", + "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", "dev": true, "requires": { - "jest-get-type": "^29.4.3" + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.5.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" } - }, - "@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } + }, + "@eslint/js": { + "version": "8.36.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", + "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" } }, - "@jest/globals": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz", - "integrity": "sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA==", + "@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "requires": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/types": "^28.1.3" + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" }, "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" + "sprintf-js": "~1.0.2" } }, - "@jest/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "expect": "^28.1.3", - "jest-snapshot": "^28.1.3" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, - "@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { - "jest-get-type": "^28.0.2" + "argparse": "^1.0.7", + "esprima": "^4.0.0" } }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" + "p-locate": "^4.1.0" } }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { - "type-detect": "4.0.8" + "p-try": "^2.0.0" } }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.0" + "p-limit": "^2.2.0" } }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", + "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", + "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "dev": true, + "requires": { + "@jest/console": "^29.5.0", + "@jest/reporters": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.5.0", + "jest-config": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-resolve-dependencies": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", + "jest-watcher": "^29.5.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.5.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true - }, - "expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", - "dev": true, - "requires": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -9192,18 +7050,75 @@ } } }, + "@jest/environment": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", + "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", + "jest-mock": "^29.5.0" + } + }, + "@jest/expect": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", + "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "dev": true, + "requires": { + "expect": "^29.5.0", + "jest-snapshot": "^29.5.0" + } + }, + "@jest/expect-utils": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", + "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "dev": true, + "requires": { + "jest-get-type": "^29.4.3" + } + }, + "@jest/fake-timers": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", + "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "dev": true, + "requires": { + "@jest/types": "^29.5.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" + } + }, + "@jest/globals": { + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", + "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/expect": "^29.5.0", + "@jest/types": "^29.5.0", + "jest-mock": "^29.5.0" + } + }, "@jest/reporters": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz", - "integrity": "sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", + "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", + "@jest/console": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -9215,90 +7130,97 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", "v8-to-istanbul": "^9.0.1" } }, "@jest/schemas": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz", - "integrity": "sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", + "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", "dev": true, "requires": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.25.16" } }, "@jest/source-map": { - "version": "28.1.2", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz", - "integrity": "sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", + "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.13", + "@jridgewell/trace-mapping": "^0.3.15", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" } }, "@jest/test-result": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz", - "integrity": "sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", + "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", "dev": true, "requires": { - "@jest/console": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/console": "^29.5.0", + "@jest/types": "^29.5.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz", - "integrity": "sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", + "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", "dev": true, "requires": { - "@jest/test-result": "^28.1.3", + "@jest/test-result": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", + "jest-haste-map": "^29.5.0", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz", - "integrity": "sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", + "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^28.1.3", - "@jridgewell/trace-mapping": "^0.3.13", + "@jest/types": "^29.5.0", + "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", + "jest-haste-map": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" + }, + "dependencies": { + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + } } }, "@jest/types": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz", - "integrity": "sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", + "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", + "@jest/schemas": "^29.4.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -9371,9 +7293,9 @@ } }, "@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", + "version": "0.25.24", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", + "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "dev": true }, "@sinonjs/commons": { @@ -9826,15 +7748,15 @@ "dev": true }, "babel-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz", - "integrity": "sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", + "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", "dev": true, "requires": { - "@jest/transform": "^28.1.3", + "@jest/transform": "^29.5.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^28.1.3", + "babel-preset-jest": "^29.5.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -9854,9 +7776,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz", - "integrity": "sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", + "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -9886,12 +7808,12 @@ } }, "babel-preset-jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz", - "integrity": "sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", + "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^28.1.3", + "babel-plugin-jest-hoist": "^29.5.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -10101,9 +8023,9 @@ "dev": true }, "deepmerge": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.0.tgz", - "integrity": "sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, "define-properties": { @@ -10159,9 +8081,9 @@ "dev": true }, "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true }, "emoji-regex": { @@ -10553,35 +8475,6 @@ "jest-util": "^29.5.0" }, "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -10618,37 +8511,6 @@ "pretty-format": "^29.5.0" } }, - "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, "pretty-format": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", @@ -11327,21 +9189,21 @@ "dev": true }, "jest": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz", - "integrity": "sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", + "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", "dev": true, "requires": { - "@jest/core": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/core": "^29.5.0", + "@jest/types": "^29.5.0", "import-local": "^3.0.2", - "jest-cli": "^28.1.3" + "jest-cli": "^29.5.0" } }, "jest-changed-files": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz", - "integrity": "sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", + "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", "dev": true, "requires": { "execa": "^5.0.0", @@ -11376,125 +9238,12 @@ "stack-utils": "^2.0.3" }, "dependencies": { - "@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - } - }, - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "diff-sequences": { "version": "29.4.3", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", @@ -11513,26 +9262,6 @@ "pretty-format": "^29.5.0" } }, - "jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, "jest-matcher-utils": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", @@ -11545,147 +9274,6 @@ "pretty-format": "^29.5.0" } }, - "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", - "dev": true - }, - "jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - } - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - } - }, - "jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - } - }, "pretty-format": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", @@ -11702,250 +9290,72 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", "dev": true - }, - "resolve.exports": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.1.tgz", - "integrity": "sha512-OEJWVeimw8mgQuj3HfkNl4KqRevH7lzeQNaWRPfx0PPse7Jk6ozcsG4FKVgtzDsC1KUF+YlTHh17NcgHOPykLw==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } } } }, "jest-cli": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz", - "integrity": "sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", + "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", "dev": true, "requires": { - "@jest/core": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/core": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", + "jest-config": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "prompts": "^2.0.1", "yargs": "^17.3.1" } }, "jest-config": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz", - "integrity": "sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", + "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^28.1.3", - "@jest/types": "^28.1.3", - "babel-jest": "^28.1.3", + "@jest/test-sequencer": "^29.5.0", + "@jest/types": "^29.5.0", + "babel-jest": "^29.5.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^28.1.3", - "jest-environment-node": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-runner": "^28.1.3", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", + "jest-circus": "^29.5.0", + "jest-environment-node": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-runner": "^29.5.0", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^28.1.3", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw==", - "dev": true, - "requires": { - "expect": "^28.1.3", - "jest-snapshot": "^28.1.3" - } - }, - "@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", - "dev": true, - "requires": { - "jest-get-type": "^28.0.2" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", - "dev": true - }, - "expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", - "dev": true, - "requires": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "jest-circus": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz", - "integrity": "sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.3", - "@jest/expect": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", - "p-limit": "^3.1.0", - "pretty-format": "^28.1.3", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-each": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz", - "integrity": "sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", - "jest-util": "^28.1.3", - "pretty-format": "^28.1.3" - } - }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, - "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -11979,9 +9389,9 @@ } }, "jest-docblock": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz", - "integrity": "sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", + "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", "dev": true, "requires": { "detect-newline": "^3.0.0" @@ -11998,57 +9408,14 @@ "jest-get-type": "^29.4.3", "jest-util": "^29.5.0", "pretty-format": "^29.5.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, + }, + "dependencies": { "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, "pretty-format": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", @@ -12069,73 +9436,17 @@ } }, "jest-environment-node": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz", - "integrity": "sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", + "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", "dev": true, "requires": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - } + "jest-mock": "^29.5.0", + "jest-util": "^29.5.0" } }, "jest-get-type": { @@ -12145,33 +9456,33 @@ "dev": true }, "jest-haste-map": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz", - "integrity": "sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", + "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", "dev": true, "requires": { - "@jest/types": "^28.1.3", + "@jest/types": "^29.5.0", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^28.0.2", - "jest-util": "^28.1.3", - "jest-worker": "^28.1.3", + "jest-regex-util": "^29.4.3", + "jest-util": "^29.5.0", + "jest-worker": "^29.5.0", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz", - "integrity": "sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", + "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", "dev": true, "requires": { - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" }, "dependencies": { "ansi-styles": { @@ -12180,20 +9491,13 @@ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -12227,18 +9531,18 @@ } }, "jest-message-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz", - "integrity": "sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", + "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^28.1.3", + "@jest/types": "^29.5.0", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^28.1.3", + "pretty-format": "^29.5.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -12250,13 +9554,12 @@ "dev": true }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -12278,51 +9581,6 @@ "@jest/types": "^29.5.0", "@types/node": "*", "jest-util": "^29.5.0" - }, - "dependencies": { - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - } } }, "jest-pnp-resolver": { @@ -12333,249 +9591,128 @@ "requires": {} }, "jest-regex-util": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", - "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", + "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", "dev": true }, "jest-resolve": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz", - "integrity": "sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", + "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", + "jest-haste-map": "^29.5.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^28.1.3", - "jest-validate": "^28.1.3", + "jest-util": "^29.5.0", + "jest-validate": "^29.5.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz", - "integrity": "sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", + "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", "dev": true, "requires": { - "jest-regex-util": "^28.0.2", - "jest-snapshot": "^28.1.3" + "jest-regex-util": "^29.4.3", + "jest-snapshot": "^29.5.0" } }, "jest-runner": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz", - "integrity": "sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", + "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", "dev": true, "requires": { - "@jest/console": "^28.1.3", - "@jest/environment": "^28.1.3", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/console": "^29.5.0", + "@jest/environment": "^29.5.0", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.10.2", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^28.1.1", - "jest-environment-node": "^28.1.3", - "jest-haste-map": "^28.1.3", - "jest-leak-detector": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-resolve": "^28.1.3", - "jest-runtime": "^28.1.3", - "jest-util": "^28.1.3", - "jest-watcher": "^28.1.3", - "jest-worker": "^28.1.3", + "jest-docblock": "^29.4.3", + "jest-environment-node": "^29.5.0", + "jest-haste-map": "^29.5.0", + "jest-leak-detector": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-resolve": "^29.5.0", + "jest-runtime": "^29.5.0", + "jest-util": "^29.5.0", + "jest-watcher": "^29.5.0", + "jest-worker": "^29.5.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - } } }, "jest-runtime": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz", - "integrity": "sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw==", - "dev": true, - "requires": { - "@jest/environment": "^28.1.3", - "@jest/fake-timers": "^28.1.3", - "@jest/globals": "^28.1.3", - "@jest/source-map": "^28.1.2", - "@jest/test-result": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", + "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", + "dev": true, + "requires": { + "@jest/environment": "^29.5.0", + "@jest/fake-timers": "^29.5.0", + "@jest/globals": "^29.5.0", + "@jest/source-map": "^29.4.3", + "@jest/test-result": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", + "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-regex-util": "^28.0.2", - "jest-resolve": "^28.1.3", - "jest-snapshot": "^28.1.3", - "jest-util": "^28.1.3", + "jest-haste-map": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-mock": "^29.5.0", + "jest-regex-util": "^29.4.3", + "jest-resolve": "^29.5.0", + "jest-snapshot": "^29.5.0", + "jest-util": "^29.5.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" - }, - "dependencies": { - "@jest/environment": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz", - "integrity": "sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^28.1.3", - "@jest/types": "^28.1.3", - "@types/node": "*", - "jest-mock": "^28.1.3" - } - }, - "@jest/fake-timers": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz", - "integrity": "sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^28.1.3", - "jest-mock": "^28.1.3", - "jest-util": "^28.1.3" - } - }, - "@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "jest-mock": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz", - "integrity": "sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==", - "dev": true, - "requires": { - "@jest/types": "^28.1.3", - "@types/node": "*" - } - } } }, "jest-snapshot": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz", - "integrity": "sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", + "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", "dev": true, "requires": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^28.1.3", - "@jest/transform": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/expect-utils": "^29.5.0", + "@jest/transform": "^29.5.0", + "@jest/types": "^29.5.0", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^28.1.3", + "expect": "^29.5.0", "graceful-fs": "^4.2.9", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-haste-map": "^28.1.3", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3", + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "jest-matcher-utils": "^29.5.0", + "jest-message-util": "^29.5.0", + "jest-util": "^29.5.0", "natural-compare": "^1.4.0", - "pretty-format": "^28.1.3", + "pretty-format": "^29.5.0", "semver": "^7.3.5" }, "dependencies": { - "@jest/expect-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz", - "integrity": "sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==", - "dev": true, - "requires": { - "jest-get-type": "^28.0.2" - } - }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", @@ -12583,62 +9720,42 @@ "dev": true }, "diff-sequences": { - "version": "28.1.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz", - "integrity": "sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==", + "version": "29.4.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", + "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", "dev": true }, - "expect": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz", - "integrity": "sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==", - "dev": true, - "requires": { - "@jest/expect-utils": "^28.1.3", - "jest-get-type": "^28.0.2", - "jest-matcher-utils": "^28.1.3", - "jest-message-util": "^28.1.3", - "jest-util": "^28.1.3" - } - }, "jest-diff": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz", - "integrity": "sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", + "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^28.1.1", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "diff-sequences": "^29.4.3", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, "jest-matcher-utils": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz", - "integrity": "sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", + "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^28.1.3", - "jest-get-type": "^28.0.2", - "pretty-format": "^28.1.3" + "jest-diff": "^29.5.0", + "jest-get-type": "^29.4.3", + "pretty-format": "^29.5.0" } }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -12652,12 +9769,12 @@ } }, "jest-util": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz", - "integrity": "sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", + "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", "dev": true, "requires": { - "@jest/types": "^28.1.3", + "@jest/types": "^29.5.0", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -12666,17 +9783,17 @@ } }, "jest-validate": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz", - "integrity": "sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", + "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", "dev": true, "requires": { - "@jest/types": "^28.1.3", + "@jest/types": "^29.5.0", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^28.0.2", + "jest-get-type": "^29.4.3", "leven": "^3.1.0", - "pretty-format": "^28.1.3" + "pretty-format": "^29.5.0" }, "dependencies": { "ansi-styles": { @@ -12691,20 +9808,13 @@ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true }, - "jest-get-type": { - "version": "28.0.2", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", - "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", - "dev": true - }, "pretty-format": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", - "integrity": "sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", + "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", "dev": true, "requires": { - "@jest/schemas": "^28.1.3", - "ansi-regex": "^5.0.1", + "@jest/schemas": "^29.4.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } @@ -12718,28 +9828,29 @@ } }, "jest-watcher": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz", - "integrity": "sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", + "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", "dev": true, "requires": { - "@jest/test-result": "^28.1.3", - "@jest/types": "^28.1.3", + "@jest/test-result": "^29.5.0", + "@jest/types": "^29.5.0", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^28.1.3", + "emittery": "^0.13.1", + "jest-util": "^29.5.0", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "28.1.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz", - "integrity": "sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==", + "version": "29.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", + "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.5.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -13332,9 +10443,9 @@ "dev": true }, "resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true }, "reusify": { @@ -13567,16 +10678,6 @@ "has-flag": "^4.0.0" } }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, "supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", @@ -13587,16 +10688,6 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -13636,15 +10727,15 @@ } }, "ts-jest": { - "version": "28.0.8", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz", - "integrity": "sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg==", + "version": "29.1.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", + "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", "dev": true, "requires": { "bs-logger": "0.x", "fast-json-stable-stringify": "2.x", - "jest-util": "^28.0.0", - "json5": "^2.2.1", + "jest-util": "^29.0.0", + "json5": "^2.2.3", "lodash.memoize": "4.x", "make-error": "1.x", "semver": "7.x", @@ -13798,9 +10889,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", + "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.12", @@ -13899,9 +10990,9 @@ "dev": true }, "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", "dev": true, "requires": { "cliui": "^8.0.1", diff --git a/package.json b/package.json index 46c3b3af5..050cead7a 100644 --- a/package.json +++ b/package.json @@ -63,12 +63,12 @@ "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^28.1.3", + "jest": "^29.5.0", "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.8.4", - "ts-jest": "^28.0.8", + "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typescript": "^5.0.2" } diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index a7e9db909..fa1c03649 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { TransformationContext } from "../context"; -import { createModuleLocalNameIdentifier } from "../visitors/namespace"; +import { createModuleLocalName } from "../visitors/namespace"; import { createExportsIdentifier } from "./lua-ast"; import { getSymbolInfo } from "./symbols"; import { findFirstNodeAbove } from "./typescript"; @@ -144,7 +144,7 @@ export function createExportedIdentifier( const exportTable = exportScope && ts.isModuleDeclaration(exportScope) - ? createModuleLocalNameIdentifier(context, exportScope) + ? createModuleLocalName(context, exportScope) : createExportsIdentifier(); return lua.createTableIndexExpression(exportTable, lua.createStringLiteral(identifier.text)); diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 4e0727753..743b52b62 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -11,6 +11,16 @@ import { performHoisting, ScopeType } from "../utils/scope"; import { getSymbolIdOfSymbol } from "../utils/symbols"; import { transformIdentifier } from "./identifier"; +export function createModuleLocalName(context: TransformationContext, module: ts.ModuleDeclaration): lua.Expression { + if (!ts.isSourceFile(module.parent) && ts.isModuleDeclaration(module.parent)) { + const parentDeclaration = createModuleLocalName(context, module.parent); + const name = createModuleLocalNameIdentifier(context, module); + return lua.createTableIndexExpression(parentDeclaration, lua.createStringLiteral(name.text), module.name); + } + + return createModuleLocalNameIdentifier(context, module); +} + export function createModuleLocalNameIdentifier( context: TransformationContext, declaration: ts.ModuleDeclaration @@ -25,7 +35,6 @@ export function createModuleLocalNameIdentifier( ); } - // TODO: Should synthetic name nodes be escaped as well? return transformIdentifier(context, declaration.name as ts.Identifier); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 05bb647b8..48d2a7f9a 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -10,18 +10,18 @@ end" `; exports[`Transformation (characterEscapeSequence) 1`] = ` -"quoteInDoubleQuotes = \\"' ' '\\" -quoteInTemplateString = \\"' ' '\\" -doubleQuoteInQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -doubleQuoteInDoubleQuotes = \\"\\\\\\" \\\\\\" \\\\\\"\\" -doubleQuoteInTemplateString = \\"\\\\\\" \\\\\\" \\\\\\"\\" -backQuoteInQuotes = \\"\` \` \`\\" -backQuoteInDoubleQuotes = \\"\` \` \`\\" -backQuoteInTemplateString = \\"\` \` \`\\" -escapedCharsInQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -escapedCharsInDoubleQuotes = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -escapedCharsInTemplateString = \\"\\\\\\\\ \\\\0 \\\\b \\\\t \\\\n \\\\v \\\\f \\\\\\" ' \`\\" -nonEmptyTemplateString = (\\"Level 0: \\\\n\\\\t \\" .. (\\"Level 1: \\\\n\\\\t\\\\t \\" .. (\\"Level 3: \\\\n\\\\t\\\\t\\\\t \\" .. \\"Last level \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\") .. \\" \\\\n --\\"" +"quoteInDoubleQuotes = "' ' '" +quoteInTemplateString = "' ' '" +doubleQuoteInQuotes = "\\" \\" \\"" +doubleQuoteInDoubleQuotes = "\\" \\" \\"" +doubleQuoteInTemplateString = "\\" \\" \\"" +backQuoteInQuotes = "\` \` \`" +backQuoteInDoubleQuotes = "\` \` \`" +backQuoteInTemplateString = "\` \` \`" +escapedCharsInQuotes = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" +escapedCharsInDoubleQuotes = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" +escapedCharsInTemplateString = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" +nonEmptyTemplateString = ("Level 0: \\n\\t " .. ("Level 1: \\n\\t\\t " .. ("Level 3: \\n\\t\\t\\t " .. "Last level \\n --") .. " \\n --") .. " \\n --") .. " \\n --"" `; exports[`Transformation (exportStatement) 1`] = ` @@ -30,22 +30,22 @@ local xyz = 4 ____exports.xyz = xyz ____exports.uwv = xyz do - local ____export = require(\\"xyz\\") + local ____export = require("xyz") for ____exportKey, ____exportValue in pairs(____export) do - if ____exportKey ~= \\"default\\" then + if ____exportKey ~= "default" then ____exports[____exportKey] = ____exportValue end end end do - local ____xyz = require(\\"xyz\\") + local ____xyz = require("xyz") local abc = ____xyz.abc local def = ____xyz.def ____exports.abc = abc ____exports.def = def end do - local ____xyz = require(\\"xyz\\") + local ____xyz = require("xyz") local def = ____xyz.abc ____exports.def = def end @@ -58,10 +58,10 @@ return ____exports" `; exports[`Transformation (methodRestArguments) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class MyClass = __TS__Class() -MyClass.name = \\"MyClass\\" +MyClass.name = "MyClass" function MyClass.prototype.____constructor(self) end function MyClass.prototype.varargsFunction(self, a, ...) @@ -75,24 +75,24 @@ return ____exports" `; exports[`Transformation (modulesClassExport) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass -TestClass.name = \\"TestClass\\" +TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end return ____exports" `; exports[`Transformation (modulesClassWithMemberExport) 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local ____exports = {} ____exports.TestClass = __TS__Class() local TestClass = ____exports.TestClass -TestClass.name = \\"TestClass\\" +TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end function TestClass.prototype.memberFunc(self) @@ -114,14 +114,14 @@ end" exports[`Transformation (modulesImportAll) 1`] = ` "local ____exports = {} -local Test = require(\\"test\\") +local Test = require("test") local ____ = Test return ____exports" `; exports[`Transformation (modulesImportNamed) 1`] = ` "local ____exports = {} -local ____test = require(\\"test\\") +local ____test = require("test") local TestClass = ____test.TestClass local ____ = TestClass return ____exports" @@ -129,15 +129,15 @@ return ____exports" exports[`Transformation (modulesImportNamedSpecialChars) 1`] = ` "local ____exports = {} -local ____kebab_2Dmodule = require(\\"kebab-module\\") +local ____kebab_2Dmodule = require("kebab-module") local TestClass1 = ____kebab_2Dmodule.TestClass1 -local ____dollar_24module = require(\\"dollar$module\\") +local ____dollar_24module = require("dollar$module") local TestClass2 = ____dollar_24module.TestClass2 -local ____singlequote_27module = require(\\"singlequote'module\\") +local ____singlequote_27module = require("singlequote'module") local TestClass3 = ____singlequote_27module.TestClass3 -local ____hash_23module = require(\\"hash#module\\") +local ____hash_23module = require("hash#module") local TestClass4 = ____hash_23module.TestClass4 -local ____space_20module = require(\\"space module\\") +local ____space_20module = require("space module") local TestClass5 = ____space_20module.TestClass5 local ____ = TestClass1 local ____ = TestClass2 @@ -149,7 +149,7 @@ return ____exports" exports[`Transformation (modulesImportRenamed) 1`] = ` "local ____exports = {} -local ____test = require(\\"test\\") +local ____test = require("test") local RenamedClass = ____test.TestClass local ____ = RenamedClass return ____exports" @@ -157,15 +157,15 @@ return ____exports" exports[`Transformation (modulesImportRenamedSpecialChars) 1`] = ` "local ____exports = {} -local ____kebab_2Dmodule = require(\\"kebab-module\\") +local ____kebab_2Dmodule = require("kebab-module") local RenamedClass1 = ____kebab_2Dmodule.TestClass -local ____dollar_24module = require(\\"dollar$module\\") +local ____dollar_24module = require("dollar$module") local RenamedClass2 = ____dollar_24module.TestClass -local ____singlequote_27module = require(\\"singlequote'module\\") +local ____singlequote_27module = require("singlequote'module") local RenamedClass3 = ____singlequote_27module.TestClass -local ____hash_23module = require(\\"hash#module\\") +local ____hash_23module = require("hash#module") local RenamedClass4 = ____hash_23module.TestClass -local ____space_20module = require(\\"space module\\") +local ____space_20module = require("space module") local RenamedClass5 = ____space_20module.TestClass local ____ = RenamedClass1 local ____ = RenamedClass2 @@ -177,7 +177,7 @@ return ____exports" exports[`Transformation (modulesImportWithoutFromClause) 1`] = ` "local ____exports = {} -require(\\"test\\") +require("test") return ____exports" `; @@ -227,19 +227,19 @@ return ____exports" exports[`Transformation (modulesVariableExport) 1`] = ` "local ____exports = {} -____exports.foo = \\"bar\\" +____exports.foo = "bar" return ____exports" `; -exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = \\"bar\\""`; +exports[`Transformation (modulesVariableNoExport) 1`] = `"foo = "bar""`; exports[`Transformation (printFormat) 1`] = ` -"stringConcat = ((\\"a\\" .. \\"b\\" .. \\"c\\") .. \\"d\\") .. \\"e\\" +"stringConcat = (("a" .. "b" .. "c") .. "d") .. "e" numbers = 2 * 2 + 3 + 4 * (5 + 6) ~= 7 function func(...) end func(function() - local b = \\"A function\\" + local b = "A function" end) func(func()) array = {func()} @@ -252,8 +252,8 @@ bigObject = { a = 1, b = 2, c = 3, - d = \\"value1\\", - e = \\"value2\\" + d = "value1", + e = "value2" }" `; @@ -279,7 +279,7 @@ end" exports[`Transformation (unusedDefaultWithNamespaceImport) 1`] = ` "local ____exports = {} -local x = require(\\"module\\") +local x = require("module") local ____ = x return ____exports" `; diff --git a/test/transpile/__snapshots__/directories.spec.ts.snap b/test/transpile/__snapshots__/directories.spec.ts.snap index a76619460..d214dbba7 100644 --- a/test/transpile/__snapshots__/directories.spec.ts.snap +++ b/test/transpile/__snapshots__/directories.spec.ts.snap @@ -1,28 +1,28 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 1`] = ` -Array [ +[ "directories/basic/src/lib/file.lua", "directories/basic/src/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 2`] = ` -Array [ +[ "directories/basic/out/lib/file.lua", "directories/basic/out/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 3`] = ` -Array [ +[ "directories/basic/src/lib/file.lua", "directories/basic/src/main.lua", ] `; exports[`should be able to resolve ({"name": "basic", "options": [Object]}) 4`] = ` -Array [ +[ "directories/basic/out/lib/file.lua", "directories/basic/out/main.lua", ] diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap index 2e4d888cb..e87569ded 100644 --- a/test/transpile/__snapshots__/module-resolution.spec.ts.snap +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`supports complicated paths configuration 1`] = ` -Array [ +[ "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/bar.lua", "/paths-base-tsconfig/dist/packages/tstl-program/packages/mypackage/src/index.lua", "/paths-base-tsconfig/dist/packages/tstl-program/packages/myprogram/src/main.lua", @@ -9,7 +9,7 @@ Array [ `; exports[`supports paths configuration 1`] = ` -Array [ +[ "/paths-simple/myprogram/dist/mypackage/bar.lua", "/paths-simple/myprogram/dist/mypackage/index.lua", "/paths-simple/myprogram/dist/myprogram/main.lua", diff --git a/test/transpile/__snapshots__/project.spec.ts.snap b/test/transpile/__snapshots__/project.spec.ts.snap index c2f66a1e7..227e004f8 100644 --- a/test/transpile/__snapshots__/project.spec.ts.snap +++ b/test/transpile/__snapshots__/project.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should give verbose output 1`] = ` -Array [ +[ "Loaded 0 plugins", "Parsing project settings", "Transforming /test/transpile/project/otherFile.ts", @@ -11,7 +11,7 @@ Array [ "Constructing emit plan", "Resolving dependencies for /test/transpile/project/otherFile.ts", "Resolving dependencies for /test/transpile/project/index.ts", - "Resolving \\"./otherFile\\" from /test/transpile/project/index.ts", + "Resolving "./otherFile" from /test/transpile/project/index.ts", "Resolved ./otherFile to /test/transpile/project/otherFile.ts", "Emitting output", "Emitting /test/transpile/project/otherFile.lua", @@ -21,8 +21,8 @@ Array [ `; exports[`should transpile 1`] = ` -Array [ - Object { +[ + { "filePath": "otherFile.lua", "lua": "local ____exports = {} function ____exports.getNumber(self) @@ -31,10 +31,10 @@ end return ____exports ", }, - Object { + { "filePath": "index.lua", "lua": "local ____exports = {} -local ____otherFile = require(\\"otherFile\\") +local ____otherFile = require("otherFile") local getNumber = ____otherFile.getNumber local myNumber = getNumber(nil) setAPIValue(myNumber * 5) diff --git a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap index 9902416ab..7e3be754d 100644 --- a/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap +++ b/test/transpile/plugins/__snapshots__/plugins.spec.ts.snap @@ -5,11 +5,11 @@ exports[`statement comments 1`] = ` function ____exports.__main(self) --This comment on variable declaration was added by a plugin! --- This one too! - local foo = \\"bar\\" + local foo = "bar" -- This trailing comment was also added by a plugin! --- Example luadoc comment ---@param paramName ParamClass - foo = \\"baz\\" + foo = "baz" --[[ This plugin can also (kinda) create multiline comments. -- Line 2 --]] diff --git a/test/unit/__snapshots__/bundle.spec.ts.snap b/test/unit/__snapshots__/bundle.spec.ts.snap index 51d2b73b9..852b6a668 100644 --- a/test/unit/__snapshots__/bundle.spec.ts.snap +++ b/test/unit/__snapshots__/bundle.spec.ts.snap @@ -1,8 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: \\"inline\\"' might generate duplicate code. It is recommended to use 'luaLibImport: \\"require\\"'."`; +exports[`LuaLibImportKind.Inline generates a warning: diagnostics 1`] = `"warning TSTL: Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. It is recommended to use 'luaLibImport: "require"'."`; -exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle projects with \\"buildmode\\": \\"library\\". Projects including the library can still bundle (which will include external library files)."`; +exports[`bundling not allowed for buildmode library: diagnostics 1`] = `"error TSTL: Cannot bundle projects with "buildmode": "library". Projects including the library can still bundle (which will include external library files)."`; exports[`luaEntry doesn't exist: diagnostics 1`] = `"error TSTL: Could not find bundle entry point 'entry.ts'. It should be a file in the project."`; diff --git a/test/unit/__snapshots__/comments.spec.ts.snap b/test/unit/__snapshots__/comments.spec.ts.snap index 23b89dcb7..55052f60e 100644 --- a/test/unit/__snapshots__/comments.spec.ts.snap +++ b/test/unit/__snapshots__/comments.spec.ts.snap @@ -8,7 +8,7 @@ exports[`JSDoc is copied on a function with tags: code 1`] = ` -- @param arg2 This is the second argument. -- @returns A very powerful string. function foo(self, arg1, arg2) - return \\"bar\\" + return "bar" end" `; diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 999459e57..1e71d2976 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -613,21 +613,21 @@ return ____exports" `; exports[`Unary expressions basic ("delete tbl.test") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - __TS__Delete(tbl, \\"test\\") + __TS__Delete(tbl, "test") end return ____exports" `; exports[`Unary expressions basic ("delete tbl['test']") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - __TS__Delete(tbl, \\"test\\") + __TS__Delete(tbl, "test") end return ____exports" `; @@ -649,21 +649,21 @@ return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl.test") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - local a = __TS__Delete(tbl, \\"test\\") + local a = __TS__Delete(tbl, "test") end return ____exports" `; exports[`Unary expressions basic ("let a = delete tbl['test']") 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Delete = ____lualib.__TS__Delete local ____exports = {} function ____exports.__main(self) - local a = __TS__Delete(tbl, \\"test\\") + local a = __TS__Delete(tbl, "test") end return ____exports" `; diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 8af819bc0..4a8ddc751 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -72,59 +72,59 @@ exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): cod exports[`ambient identifier must be a valid lua identifier ("var $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {["$$$"] = _____24_24_24}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("$$"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {["_̀ः٠‿"] = ______300_903_660_203F}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {["and"] = ____and}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {["elseif"] = ____elseif}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {["end"] = ____end}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {["goto"] = ____goto}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {["local"] = ____local}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {["nil"] = ____nil}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {["not"] = ____not}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {["or"] = ____or}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {["repeat"] = ____repeat}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {["then"] = ____then}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {["until"] = ____until}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; +exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {["ɥɣɎɌͼƛಠ"] = _____265_263_24E_24C_37C_19B_CA0}"`; exports[`ambient identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(3,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; @@ -192,66 +192,66 @@ exports[`undeclared identifier must be a valid lua identifier ("ɥɣɎɌͼƛಠ" exports[`undeclared identifier must be a valid lua identifier ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,21): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {[\\"$$$\\"] = _____24_24_24}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): code 1`] = `"foo = {["$$$"] = _____24_24_24}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("$$"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {[\\"_̀ः٠‿\\"] = ______300_903_660_203F}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): code 1`] = `"foo = {["_̀ः٠‿"] = ______300_903_660_203F}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("_̀ः٠‿"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name '_̀ः٠‿'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {[\\"and\\"] = ____and}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): code 1`] = `"foo = {["and"] = ____and}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("and"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'and'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {[\\"elseif\\"] = ____elseif}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): code 1`] = `"foo = {["elseif"] = ____elseif}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("elseif"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'elseif'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {[\\"end\\"] = ____end}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): code 1`] = `"foo = {["end"] = ____end}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("end"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'end'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {[\\"goto\\"] = ____goto}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): code 1`] = `"foo = {["goto"] = ____goto}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("goto"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'goto'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {[\\"local\\"] = ____local}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): code 1`] = `"foo = {["local"] = ____local}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("local"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'local'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {[\\"nil\\"] = ____nil}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): code 1`] = `"foo = {["nil"] = ____nil}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("nil"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'nil'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {[\\"not\\"] = ____not}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): code 1`] = `"foo = {["not"] = ____not}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("not"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'not'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {[\\"or\\"] = ____or}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): code 1`] = `"foo = {["or"] = ____or}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("or"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'or'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {[\\"repeat\\"] = ____repeat}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): code 1`] = `"foo = {["repeat"] = ____repeat}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("repeat"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'repeat'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {[\\"then\\"] = ____then}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): code 1`] = `"foo = {["then"] = ____then}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("then"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'then'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {[\\"until\\"] = ____until}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): code 1`] = `"foo = {["until"] = ____until}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("until"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'until'. Ambient identifiers must be valid lua identifiers."`; -exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {[\\"ɥɣɎɌͼƛಠ\\"] = _____265_263_24E_24C_37C_19B_CA0}"`; +exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): code 1`] = `"foo = {["ɥɣɎɌͼƛಠ"] = _____265_263_24E_24C_37C_19B_CA0}"`; exports[`undeclared identifier must be a valid lua identifier (object literal shorthand) ("ɥɣɎɌͼƛಠ"): diagnostics 1`] = `"main.ts(2,27): error TSTL: Invalid ambient identifier name 'ɥɣɎɌͼƛಠ'. Ambient identifiers must be valid lua identifiers."`; exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local _̀ः٠‿ = ____temp_0.foo return _̀ः٠‿ end @@ -261,7 +261,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local ɥɣɎɌͼƛಠ = ____temp_0.foo return ɥɣɎɌͼƛಠ end @@ -271,7 +271,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring property name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {foo = \\"foobar\\"} + local ____temp_0 = {foo = "foobar"} local 𝛼𝛽𝚫 = ____temp_0.foo return 𝛼𝛽𝚫 end @@ -281,7 +281,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {_̀ः٠‿ = \\"foobar\\"} + local ____temp_0 = {_̀ः٠‿ = "foobar"} local _̀ः٠‿ = ____temp_0._̀ः٠‿ return _̀ः٠‿ end @@ -291,7 +291,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + local ____temp_0 = {ɥɣɎɌͼƛಠ = "foobar"} local ɥɣɎɌͼƛಠ = ____temp_0.ɥɣɎɌͼƛಠ return ɥɣɎɌͼƛಠ end @@ -301,7 +301,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) destructuring shorthand ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ____temp_0 = {𝛼𝛽𝚫 = \\"foobar\\"} + local ____temp_0 = {𝛼𝛽𝚫 = "foobar"} local 𝛼𝛽𝚫 = ____temp_0.𝛼𝛽𝚫 return 𝛼𝛽𝚫 end @@ -312,9 +312,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("_̀ "local ____exports = {} function ____exports.__main(self) local function _̀ः٠‿(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return _̀ः٠‿(nil, \\"bar\\") + return _̀ः٠‿(nil, "bar") end return ____exports" `; @@ -323,9 +323,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("ɥɣ "local ____exports = {} function ____exports.__main(self) local function ɥɣɎɌͼƛಠ(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return ɥɣɎɌͼƛಠ(nil, \\"bar\\") + return ɥɣɎɌͼƛಠ(nil, "bar") end return ____exports" `; @@ -334,9 +334,9 @@ exports[`unicode identifiers in supporting environments (luajit) function ("𝛼 "local ____exports = {} function ____exports.__main(self) local function 𝛼𝛽𝚫(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end - return 𝛼𝛽𝚫(nil, \\"bar\\") + return 𝛼𝛽𝚫(nil, "bar") end return ____exports" `; @@ -344,7 +344,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local _̀ः٠‿ = \\"foobar\\" + local _̀ः٠‿ = "foobar" return _̀ः٠‿ end return ____exports" @@ -353,7 +353,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local ɥɣɎɌͼƛಠ = \\"foobar\\" + local ɥɣɎɌͼƛಠ = "foobar" return ɥɣɎɌͼƛಠ end return ____exports" @@ -362,7 +362,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) identifier name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local 𝛼𝛽𝚫 = \\"foobar\\" + local 𝛼𝛽𝚫 = "foobar" return 𝛼𝛽𝚫 end return ____exports" @@ -372,9 +372,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("_̀ः "local ____exports = {} function ____exports.__main(self) local foo = {_̀ः٠‿ = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:_̀ः٠‿(\\"bar\\") + return foo:_̀ः٠‿("bar") end return ____exports" `; @@ -383,9 +383,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("ɥɣɎ "local ____exports = {} function ____exports.__main(self) local foo = {ɥɣɎɌͼƛಠ = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:ɥɣɎɌͼƛಠ(\\"bar\\") + return foo:ɥɣɎɌͼƛಠ("bar") end return ____exports" `; @@ -394,9 +394,9 @@ exports[`unicode identifiers in supporting environments (luajit) method ("𝛼 "local ____exports = {} function ____exports.__main(self) local foo = {𝛼𝛽𝚫 = function(self, arg) - return \\"foo\\" .. arg + return "foo" .. arg end} - return foo:𝛼𝛽𝚫(\\"bar\\") + return foo:𝛼𝛽𝚫("bar") end return ____exports" `; @@ -404,7 +404,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("_̀ः٠‿") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {_̀ः٠‿ = \\"foobar\\"} + local x = {_̀ः٠‿ = "foobar"} return x._̀ः٠‿ end return ____exports" @@ -413,7 +413,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("ɥɣɎɌͼƛಠ") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {ɥɣɎɌͼƛಠ = \\"foobar\\"} + local x = {ɥɣɎɌͼƛಠ = "foobar"} return x.ɥɣɎɌͼƛಠ end return ____exports" @@ -422,7 +422,7 @@ return ____exports" exports[`unicode identifiers in supporting environments (luajit) property name ("𝛼𝛽𝚫") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local x = {𝛼𝛽𝚫 = \\"foobar\\"} + local x = {𝛼𝛽𝚫 = "foobar"} return x.𝛼𝛽𝚫 end return ____exports" diff --git a/test/unit/__snapshots__/optionalChaining.spec.ts.snap b/test/unit/__snapshots__/optionalChaining.spec.ts.snap index 707ecf68b..19fa2a309 100644 --- a/test/unit/__snapshots__/optionalChaining.spec.ts.snap +++ b/test/unit/__snapshots__/optionalChaining.spec.ts.snap @@ -1,11 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Unsupported optional chains Builtin global method: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Number = ____lualib.__TS__Number local ____opt_0 = Number if ____opt_0 ~= nil then - __TS__Number(\\"3\\") + __TS__Number("3") end" `; @@ -14,14 +14,14 @@ exports[`Unsupported optional chains Builtin global method: diagnostics 1`] = `" exports[`Unsupported optional chains Builtin global property: code 1`] = ` "local ____opt_0 = console if ____opt_0 ~= nil then - print(\\"3\\") + print("3") end" `; exports[`Unsupported optional chains Builtin global property: diagnostics 1`] = `"main.ts(2,17): error TSTL: Optional calls are not supported for builtin or language extension functions."`; exports[`Unsupported optional chains Builtin prototype method: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayForEach = ____lualib.__TS__ArrayForEach local ____opt_0 = ({1, 2, 3, 4}).forEach if ____opt_0 ~= nil then @@ -49,7 +49,7 @@ function ____exports.__main(self) local C = 3 --- -- @compileMembersOnly - local D = \\"D\\" + local D = "D" local ____opt_0 = TestEnum if ____opt_0 ~= nil then local ____ = B @@ -74,7 +74,7 @@ main.ts(2,17): error TSTL: This language extension must be called as a method." exports[`long optional chain 1`] = ` "local ____exports = {} function ____exports.__main(self) - local a = {b = {c = {d = {e = {f = \\"hello!\\"}}}}} + local a = {b = {c = {d = {e = {f = "hello!"}}}}} local ____opt_2 = a.b local ____opt_0 = ____opt_2 and ____opt_2.c return ____opt_0 and ____opt_0.d.e.f @@ -85,7 +85,7 @@ return ____exports" exports[`optional chaining ("{ foo: \\"foo\\" }") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local obj = {foo = \\"foo\\"} + local obj = {foo = "foo"} return obj and obj.foo end return ____exports" @@ -113,11 +113,11 @@ exports[`optional element function calls 1`] = ` "local ____exports = {} function ____exports.__main(self) local obj = { - value = \\"foobar\\", + value = "foobar", foo = function(v) return v + 10 end } - local fooKey = \\"foo\\" - local barKey = \\"bar\\" + local fooKey = "foo" + local barKey = "bar" local ____opt_0 = obj[barKey] local ____temp_4 = ____opt_0 and ____opt_0(5) if ____temp_4 == nil then @@ -134,7 +134,7 @@ exports[`unused call 1`] = ` function ____exports.__main(self) local result local obj = {foo = function(self) - result = \\"bar\\" + result = "bar" end} if obj ~= nil then obj:foo() @@ -147,7 +147,7 @@ return ____exports" exports[`unused expression 1`] = ` "local ____exports = {} function ____exports.__main(self) - local obj = {foo = \\"bar\\"} + local obj = {foo = "bar"} if obj ~= nil then local ____ = obj.foo end diff --git a/test/unit/__snapshots__/spread.spec.ts.snap b/test/unit/__snapshots__/spread.spec.ts.snap index d31bde3f1..c1fba08eb 100644 --- a/test/unit/__snapshots__/spread.spec.ts.snap +++ b/test/unit/__snapshots__/spread.spec.ts.snap @@ -12,7 +12,7 @@ function ____exports.__main(self) multi(nil, ...) ) end - return test(nil, \\"a\\", \\"b\\", \\"c\\") + return test(nil, "a", "b", "c") end return ____exports" `; diff --git a/test/unit/__snapshots__/switch.spec.ts.snap b/test/unit/__snapshots__/switch.spec.ts.snap index ef5504938..a64e3f77d 100644 --- a/test/unit/__snapshots__/switch.spec.ts.snap +++ b/test/unit/__snapshots__/switch.spec.ts.snap @@ -8,7 +8,7 @@ function ____exports.__main(self) local ____switch3 = 0 local ____cond3 = ____switch3 == 1 do - out[#out + 1] = \\"default\\" + out[#out + 1] = "default" end until true return out @@ -24,7 +24,7 @@ function ____exports.__main(self) local ____switch3 = 1 local ____cond3 = ____switch3 == 1 do - out[#out + 1] = \\"default\\" + out[#out + 1] = "default" end until true return out @@ -36,12 +36,12 @@ exports[`switch hoisting hoisting from default clause is not duplicated when fal "local ____exports = {} function ____exports.__main(self) local x = 1 - local result = \\"\\" + local result = "" repeat local ____switch3 = x local hoisted function hoisted(self) - return \\"hoisted\\" + return "hoisted" end local ____cond3 = ____switch3 == 1 if ____cond3 then @@ -50,19 +50,19 @@ function ____exports.__main(self) end ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then - result = \\"2\\" + result = "2" end if ____cond3 then - result = \\"default\\" + result = "default" end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then - result = \\"3\\" + result = "3" break end do - result = \\"default\\" - result = \\"3\\" + result = "default" + result = "3" end until true return result @@ -74,12 +74,12 @@ exports[`switch hoisting hoisting from fallthrough clause after default is not d "local ____exports = {} function ____exports.__main(self) local x = 1 - local result = \\"\\" + local result = "" repeat local ____switch3 = x local hoisted function hoisted(self) - return \\"hoisted\\" + return "hoisted" end local ____cond3 = ____switch3 == 1 if ____cond3 then @@ -88,19 +88,19 @@ function ____exports.__main(self) end ____cond3 = ____cond3 or ____switch3 == 2 if ____cond3 then - result = \\"2\\" + result = "2" end if ____cond3 then - result = \\"default\\" + result = "default" end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then - result = \\"3\\" + result = "3" break end do - result = \\"default\\" - result = \\"3\\" + result = "default" + result = "3" end until true return result @@ -117,13 +117,13 @@ function ____exports.__main(self) local ____switch3 = 0 local ____cond3 = ____switch3 == 0 or ____switch3 == 1 or ____switch3 == 2 if ____cond3 then - out[#out + 1] = \\"0,1,2\\" + out[#out + 1] = "0,1,2" break end ____cond3 = ____cond3 or ____switch3 == 3 if ____cond3 then do - out[#out + 1] = \\"3\\" + out[#out + 1] = "3" break end end @@ -133,9 +133,9 @@ function ____exports.__main(self) end do x = x + 1 - out[#out + 1] = \\"default = \\" .. tostring(x) + out[#out + 1] = "default = " .. tostring(x) do - out[#out + 1] = \\"3\\" + out[#out + 1] = "3" break end end diff --git a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap index ad79b2eaa..11cab115c 100644 --- a/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap +++ b/test/unit/annotations/__snapshots__/customConstructor.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`IncorrectUsage: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local __TS__New = ____lualib.__TS__New local ____exports = {} @@ -9,7 +9,7 @@ function ____exports.__main(self) --- -- @customConstructor local Point2D = __TS__Class() - Point2D.name = \\"Point2D\\" + Point2D.name = "Point2D" function Point2D.prototype.____constructor(self) end __TS__New(Point2D) diff --git a/test/unit/builtins/__snapshots__/console.spec.ts.snap b/test/unit/builtins/__snapshots__/console.spec.ts.snap index 2af4f0446..2c9d8578c 100644 --- a/test/unit/builtins/__snapshots__/console.spec.ts.snap +++ b/test/unit/builtins/__snapshots__/console.spec.ts.snap @@ -13,7 +13,7 @@ exports[`console.assert ("console.assert(false, \\"message %%s\\", \\"info\\")") function ____exports.__main(self) assert( false, - string.format(\\"message %%s\\", \\"info\\") + string.format("message %%s", "info") ) end return ____exports" @@ -24,7 +24,7 @@ exports[`console.assert ("console.assert(false, \\"message %s\\", \\"info\\")") function ____exports.__main(self) assert( false, - string.format(\\"message %s\\", \\"info\\") + string.format("message %s", "info") ) end return ____exports" @@ -33,7 +33,7 @@ return ____exports" exports[`console.assert ("console.assert(false, \\"message\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - assert(false, \\"message\\") + assert(false, "message") end return ____exports" `; @@ -41,7 +41,7 @@ return ____exports" exports[`console.assert ("console.assert(false, \\"message\\", \\"more\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - assert(false, \\"message\\", \\"more\\") + assert(false, "message", "more") end return ____exports" `; @@ -57,7 +57,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -65,7 +65,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -73,7 +73,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -81,7 +81,7 @@ return ____exports" exports[`console.error ("console.error(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -97,7 +97,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -105,7 +105,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -113,7 +113,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -121,7 +121,7 @@ return ____exports" exports[`console.info ("console.info(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -137,7 +137,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -145,7 +145,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -153,7 +153,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -161,7 +161,7 @@ return ____exports" exports[`console.log ("console.log(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; @@ -177,7 +177,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(string.format(\\"Hello %%s\\", \\"there\\"))) + print(debug.traceback(string.format("Hello %%s", "there"))) end return ____exports" `; @@ -185,7 +185,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(string.format(\\"Hello %s\\", \\"there\\"))) + print(debug.traceback(string.format("Hello %s", "there"))) end return ____exports" `; @@ -193,7 +193,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"Hello\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(\\"Hello\\", \\"there\\")) + print(debug.traceback("Hello", "there")) end return ____exports" `; @@ -201,7 +201,7 @@ return ____exports" exports[`console.trace ("console.trace(\\"message\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(debug.traceback(\\"message\\")) + print(debug.traceback("message")) end return ____exports" `; @@ -217,7 +217,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %%s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %%s\\", \\"there\\")) + print(string.format("Hello %%s", "there")) end return ____exports" `; @@ -225,7 +225,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello %s\\", \\"there\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(string.format(\\"Hello %s\\", \\"there\\")) + print(string.format("Hello %s", "there")) end return ____exports" `; @@ -233,7 +233,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\") + print("Hello") end return ____exports" `; @@ -241,7 +241,7 @@ return ____exports" exports[`console.warn ("console.warn(\\"Hello\\", \\"There\\")") 1`] = ` "local ____exports = {} function ____exports.__main(self) - print(\\"Hello\\", \\"There\\") + print("Hello", "There") end return ____exports" `; diff --git a/test/unit/classes/__snapshots__/classes.spec.ts.snap b/test/unit/classes/__snapshots__/classes.spec.ts.snap index 7822867f5..9154d1911 100644 --- a/test/unit/classes/__snapshots__/classes.spec.ts.snap +++ b/test/unit/classes/__snapshots__/classes.spec.ts.snap @@ -1,10 +1,10 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`missing declaration name: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class ____class_0 = __TS__Class() -____class_0.name = \\"\\" +____class_0.name = "" function ____class_0.prototype.____constructor(self) end" `; diff --git a/test/unit/classes/__snapshots__/decorators.spec.ts.snap b/test/unit/classes/__snapshots__/decorators.spec.ts.snap index cef76f35e..e2f95d920 100644 --- a/test/unit/classes/__snapshots__/decorators.spec.ts.snap +++ b/test/unit/classes/__snapshots__/decorators.spec.ts.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Throws error if decorator function has void context: code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Class = ____lualib.__TS__Class local __TS__Decorate = ____lualib.__TS__Decorate local ____exports = {} @@ -9,7 +9,7 @@ function ____exports.__main(self) local function decorator(constructor) end local TestClass = __TS__Class() - TestClass.name = \\"TestClass\\" + TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end TestClass = __TS__Decorate({decorator}, TestClass) diff --git a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap index 8e1601a39..e3c25d948 100644 --- a/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/iterable.spec.ts.snap @@ -4,7 +4,7 @@ exports[`LuaIterable with LuaMultiReturn value type invalid LuaIterable {}): diagnostics 1`] = `"main.ts(2,16): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = {[\\"$multi\\"] = ____}"`; +exports[`invalid $multi call (({ $multi });): code 1`] = `"local ____ = {["$multi"] = ____}"`; exports[`invalid $multi call (({ $multi });): diagnostics 1`] = `"main.ts(2,12): error TSTL: The $multi function must be called in a return statement."`; @@ -71,7 +71,7 @@ exports[`invalid $multi call (const a = $multi();): diagnostics 1`] = `"main.ts( exports[`invalid $multi implicit cast: code 1`] = ` "function badMulti(self) - return \\"foo\\", 42 + return "foo", 42 end" `; diff --git a/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap index b54b0de77..f38856514 100644 --- a/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/pairsIterable.spec.ts.snap @@ -3,7 +3,7 @@ exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIterable) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + local testIterable = {a1 = "a2", b1 = "b2", c1 = "c2"} for ____ in pairs(testIterable) do end end @@ -15,7 +15,7 @@ exports[`invalid LuaPairsIterable without destructuring ("for (const s of testIt exports[`invalid LuaPairsIterable without destructuring ("let s; for (s of testIterable) {}"): code 1`] = ` "local ____exports = {} function ____exports.__main(self) - local testIterable = {a1 = \\"a2\\", b1 = \\"b2\\", c1 = \\"c2\\"} + local testIterable = {a1 = "a2", b1 = "b2", c1 = "c2"} local s for ____ in pairs(testIterable) do end diff --git a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap index 64273b8fe..73a56890b 100644 --- a/test/unit/language-extensions/__snapshots__/range.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/range.spec.ts.snap @@ -33,7 +33,7 @@ return ____exports" exports[`$range invalid use ("const x = $range(1, 10);"): diagnostics 1`] = `"main.ts(2,19): error TSTL: $range can only be used in a for...of loop."`; exports[`$range invalid use ("const y = [...$range(1, 10)];"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Spread = ____lualib.__TS__Spread local ____exports = {} function ____exports.__main(self) @@ -67,7 +67,7 @@ return ____exports" exports[`$range invalid use ("for (const i of $range(1, 10, 2) as number[]) {}"): diagnostics 1`] = `"main.ts(2,25): error TSTL: $range can only be used in a for...of loop."`; exports[`$range invalid use ("for (const i of ($range(1, 10, 2))) {}"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__Iterator = ____lualib.__TS__Iterator local ____exports = {} function ____exports.__main(self) diff --git a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap index 5bf4ef2c8..24abd6e71 100644 --- a/test/unit/language-extensions/__snapshots__/table.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/table.spec.ts.snap @@ -108,28 +108,28 @@ has = ____table.has" exports[`LuaTableHas extension invalid use method assignment ("LuaTable"): diagnostics 1`] = `"main.ts(3,29): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaMap"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaMap"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaSet"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaSet"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; exports[`LuaTableHas extension invalid use method expression ("LuaTable"): code 1`] = ` -"local ____lualib = require(\\"lualib_bundle\\") +"local ____lualib = require("lualib_bundle") local __TS__ArrayMap = ____lualib.__TS__ArrayMap ____table = {} -__TS__ArrayMap({\\"a\\", \\"b\\", \\"c\\"}, ____table.has)" +__TS__ArrayMap({"a", "b", "c"}, ____table.has)" `; exports[`LuaTableHas extension invalid use method expression ("LuaTable"): diagnostics 1`] = `"main.ts(3,37): error TSTL: This function must be called directly and cannot be referred to."`; diff --git a/test/unit/modules/__snapshots__/resolution.spec.ts.snap b/test/unit/modules/__snapshots__/resolution.spec.ts.snap index a250dbd46..8c40101e5 100644 --- a/test/unit/modules/__snapshots__/resolution.spec.ts.snap +++ b/test/unit/modules/__snapshots__/resolution.spec.ts.snap @@ -2,7 +2,7 @@ exports[`doesn't resolve paths out of root dir: code 1`] = ` "local ____exports = {} -local module = require(\\"module\\") +local module = require("module") local ____ = module return ____exports" `; diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 762152d67..01b2e3f92 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -144,3 +144,15 @@ test("enum in a namespace", () => { export const result = Test.TestEnum.A; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1431 +test("nested namespaces (#1431)", () => { + util.testModule` + namespace Foo.Bar {} + namespace Foo.Bar { + export const baz = 32; + } + + export { Foo } + `.expectToMatchJsResult(); +}); diff --git a/test/unit/printer/__snapshots__/semicolons.spec.ts.snap b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap index af1deb303..ac34dbdf8 100644 --- a/test/unit/printer/__snapshots__/semicolons.spec.ts.snap +++ b/test/unit/printer/__snapshots__/semicolons.spec.ts.snap @@ -3,9 +3,9 @@ exports[`semicolon insertion ("{}") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end do end @@ -18,9 +18,9 @@ return ____exports" exports[`semicolon insertion ("const a = 1; const b = a;") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local a = 1 local b = a; @@ -33,9 +33,9 @@ return ____exports" exports[`semicolon insertion ("const a = 1; let b: number; b = a;") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local a = 1 local b @@ -49,9 +49,9 @@ return ____exports" exports[`semicolon insertion ("function bar() {} bar();") 1`] = ` "local ____exports = {} function ____exports.__main(self) - local result = \\"\\" + local result = "" local function foo(self) - result = \\"foo\\" + result = "foo" end local function bar(self) end From 3148739ae439d24cc417dc979ecb10cb50cec2ef Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 2 May 2023 20:15:16 +0200 Subject: [PATCH 583/764] Correctly merge tstl options from extended tsconfig (#1436) * Correctly merge tstl options from extended tsconfig * Remove useless else statement * Handle tsconfig files with comments --- src/cli/tsconfig.ts | 60 ++++++++++++++++++- test/cli/tsconfig.spec.ts | 24 +++++++- test/cli/tsconfig/tsconfig-cycle1.json | 6 ++ test/cli/tsconfig/tsconfig-cycle2.json | 6 ++ test/cli/tsconfig/tsconfig.base.json | 6 ++ test/cli/tsconfig/tsconfig.json | 6 ++ test/cli/tsconfig/tsconfig.multi-extends.json | 6 ++ test/cli/tsconfig/tsconfig.with-comments.json | 8 +++ test/cli/tsconfig/tsconfig2.json | 5 ++ 9 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 test/cli/tsconfig/tsconfig-cycle1.json create mode 100644 test/cli/tsconfig/tsconfig-cycle2.json create mode 100644 test/cli/tsconfig/tsconfig.base.json create mode 100644 test/cli/tsconfig/tsconfig.json create mode 100644 test/cli/tsconfig/tsconfig.multi-extends.json create mode 100644 test/cli/tsconfig/tsconfig.with-comments.json create mode 100644 test/cli/tsconfig/tsconfig2.json diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index bc6fb5ae9..dd6c4e9aa 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { CompilerOptions } from "../CompilerOptions"; +import { CompilerOptions, TypeScriptToLuaOptions } from "../CompilerOptions"; import { normalizeSlashes } from "../utils"; import * as cliDiagnostics from "./diagnostics"; import { ParsedCommandLine, updateParsedConfigFile } from "./parse"; @@ -41,17 +41,73 @@ export function parseConfigFileWithSystem( commandLineOptions?: CompilerOptions, system = ts.sys ): ParsedCommandLine { + const configRootDir = path.dirname(configFileName); const parsedConfigFile = ts.parseJsonSourceFileConfigFileContent( ts.readJsonConfigFile(configFileName, system.readFile), system, - path.dirname(configFileName), + configRootDir, commandLineOptions, configFileName ); + const cycleCache = new Set(); + const extendedTstlOptions = getExtendedTstlOptions(configFileName, configRootDir, cycleCache, system); + + parsedConfigFile.raw.tstl = Object.assign(extendedTstlOptions, parsedConfigFile.raw.tstl ?? {}); + return updateParsedConfigFile(parsedConfigFile); } +function getExtendedTstlOptions( + configFilePath: string, + configRootDir: string, + cycleCache: Set, + system: ts.System +): TypeScriptToLuaOptions { + const absolutePath = path.isAbsolute(configFilePath) ? configFilePath : path.resolve(configRootDir, configFilePath); + const newConfigRoot = path.dirname(absolutePath); + + if (cycleCache.has(absolutePath)) { + return {}; + } + + cycleCache.add(absolutePath); + const fileContent = system.readFile(absolutePath); + const options = {}; + + if (fileContent) { + const { config: parsedConfig } = ts.parseConfigFileTextToJson(configFilePath, fileContent) as { + config?: { + extends?: string | string[]; + tstl?: TypeScriptToLuaOptions; + }; + }; + + if (!parsedConfig) { + return {}; + } + + if (parsedConfig.extends) { + if (Array.isArray(parsedConfig.extends)) { + for (const extendedConfigFile of parsedConfig.extends) { + Object.assign( + options, + getExtendedTstlOptions(extendedConfigFile, newConfigRoot, cycleCache, system) + ); + } + } else { + Object.assign(options, getExtendedTstlOptions(parsedConfig.extends, newConfigRoot, cycleCache, system)); + } + } + + if (parsedConfig.tstl) { + Object.assign(options, parsedConfig.tstl); + } + } + + return options; +} + export function createConfigFileUpdater( optionsToExtend: CompilerOptions ): (options: ts.CompilerOptions) => ts.Diagnostic[] { diff --git a/test/cli/tsconfig.spec.ts b/test/cli/tsconfig.spec.ts index 1608ac973..b4df23e08 100644 --- a/test/cli/tsconfig.spec.ts +++ b/test/cli/tsconfig.spec.ts @@ -1,7 +1,7 @@ import * as fs from "fs-extra"; import * as os from "os"; import * as path from "path"; -import { locateConfigFile } from "../../src/cli/tsconfig"; +import { locateConfigFile, parseConfigFileWithSystem } from "../../src/cli/tsconfig"; import { normalizeSlashes } from "../../src/utils"; let temp: string; @@ -91,3 +91,25 @@ describe("errors", () => { expect([locate("tsconfig.json", [""])]).toHaveDiagnostics(); }); }); + +describe("tsconfig extends", () => { + test("correctly merges extended tsconfig files", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.3", noHeader: true }); + }); + + test("can handle multiple extends", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.multi-extends.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.4", sourceMapTraceback: true }); + }); + + test("can handle cycles in configs", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig-cycle1.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.4" }); + }); + + test("can handle tsconfig files with comments", () => { + const parsedConfig = parseConfigFileWithSystem(path.join(__dirname, "tsconfig", "tsconfig.with-comments.json")); + expect(parsedConfig.options).toMatchObject({ luaTarget: "5.3" }); + }); +}); diff --git a/test/cli/tsconfig/tsconfig-cycle1.json b/test/cli/tsconfig/tsconfig-cycle1.json new file mode 100644 index 000000000..6383b5ccf --- /dev/null +++ b/test/cli/tsconfig/tsconfig-cycle1.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig-cycle2.json", + "tstl": { + "luaTarget": "5.4" + } +} diff --git a/test/cli/tsconfig/tsconfig-cycle2.json b/test/cli/tsconfig/tsconfig-cycle2.json new file mode 100644 index 000000000..14c3edcd1 --- /dev/null +++ b/test/cli/tsconfig/tsconfig-cycle2.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig-cycle1.json", + "tstl": { + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig.base.json b/test/cli/tsconfig/tsconfig.base.json new file mode 100644 index 000000000..6b296a8de --- /dev/null +++ b/test/cli/tsconfig/tsconfig.base.json @@ -0,0 +1,6 @@ +{ + "tstl": { + "noHeader": true, + "luaTarget": "jit" + } +} diff --git a/test/cli/tsconfig/tsconfig.json b/test/cli/tsconfig/tsconfig.json new file mode 100644 index 000000000..7e76044a2 --- /dev/null +++ b/test/cli/tsconfig/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig.base.json", + "tstl": { + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig.multi-extends.json b/test/cli/tsconfig/tsconfig.multi-extends.json new file mode 100644 index 000000000..7404a6266 --- /dev/null +++ b/test/cli/tsconfig/tsconfig.multi-extends.json @@ -0,0 +1,6 @@ +{ + "extends": ["./tsconfig.json", "./tsconfig2.json"], + "tstl": { + "sourceMapTraceback": true + } +} diff --git a/test/cli/tsconfig/tsconfig.with-comments.json b/test/cli/tsconfig/tsconfig.with-comments.json new file mode 100644 index 000000000..9baf9adda --- /dev/null +++ b/test/cli/tsconfig/tsconfig.with-comments.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.base.json", + "tstl": { + // Can handle comments + /* also of this kind */ + "luaTarget": "5.3" + } +} diff --git a/test/cli/tsconfig/tsconfig2.json b/test/cli/tsconfig/tsconfig2.json new file mode 100644 index 000000000..9cfef77e0 --- /dev/null +++ b/test/cli/tsconfig/tsconfig2.json @@ -0,0 +1,5 @@ +{ + "tstl": { + "luaTarget": "5.4" + } +} From 1793234f3711f7948ef1467b4c0a0a16a409cf7e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 2 May 2023 20:41:27 +0200 Subject: [PATCH 584/764] CHANGELOG.md 1.15.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e7a82fdb..1e439fe23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.15.0 + +- Using `extends` in tsconfig.json now also correctly merges settings in the `tstl` block (shallow merge). +- Now avoiding assigning default parameter values if the default value is `nil` (`null` or `undefined`). +- Fixed a bug where indexing a `LuaMultiReturn` value with [0] would still return everything. +- Fixed a bug with nested namespaces causing unexpected nil indexing errors. + ## 1.14.0 - **[Breaking]** Upgraded TypeScript to 5.0. From 186cd90e045302eaf56be039b5a69684f734693b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 2 May 2023 20:43:22 +0200 Subject: [PATCH 585/764] 1.15.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3f3befaa..61ee008ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.14.0", + "version": "1.15.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.14.0", + "version": "1.15.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 050cead7a..c41cb7abc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.14.0", + "version": "1.15.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 16bde883f98da23e40466b72844797770ae31501 Mon Sep 17 00:00:00 2001 From: Aleksander Ciesielski <23176604+aleksander-ciesielski@users.noreply.github.com> Date: Fri, 5 May 2023 09:01:30 +0200 Subject: [PATCH 586/764] Add support for constructor parameter decorators (#1439) --- src/transformation/visitors/class/index.ts | 9 ++++- .../visitors/class/members/method.ts | 35 ++++++++++++++----- test/unit/classes/decorators.spec.ts | 1 + 3 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 4fe5f1fd9..c5b4d9630 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -19,7 +19,11 @@ import { transformClassInstanceFields, transformStaticPropertyDeclaration, } from "./members/fields"; -import { createMethodDecoratingExpression, transformMethodDeclaration } from "./members/method"; +import { + createConstructorDecoratingExpression, + createMethodDecoratingExpression, + transformMethodDeclaration, +} from "./members/method"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; import { LuaTarget } from "../../../CompilerOptions"; @@ -116,6 +120,9 @@ function transformClassLikeDeclaration( ); if (constructorResult) result.push(constructorResult); + + const decoratingExpression = createConstructorDecoratingExpression(context, constructor, localClassName); + if (decoratingExpression) result.push(decoratingExpression); } else if (!extendedType) { // Generate a constructor if none was defined in a base class const constructorResult = transformConstructorDeclaration( diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 840aa9ca3..0c3c10672 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -43,15 +43,11 @@ export function transformMethodDeclaration( ); } -export function createMethodDecoratingExpression( +export function getParameterDecorators( context: TransformationContext, - node: ts.MethodDeclaration, - className: lua.Identifier -): lua.Statement | undefined { - const methodTable = transformMemberExpressionOwnerName(node, className); - const methodName = transformMethodName(context, node); - - const parameterDecorators = node.parameters + node: ts.FunctionLikeDeclarationBase +): lua.CallExpression[] { + return node.parameters .flatMap((parameter, index) => ts .getDecorators(parameter) @@ -66,7 +62,30 @@ export function createMethodDecoratingExpression( ) ) .filter(isNonNull); +} + +export function createConstructorDecoratingExpression( + context: TransformationContext, + node: ts.ConstructorDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + const parameterDecorators = getParameterDecorators(context, node); + + if (parameterDecorators.length > 0) { + const decorateMethod = createDecoratingExpression(context, node.kind, parameterDecorators, className); + return lua.createExpressionStatement(decorateMethod); + } +} + +export function createMethodDecoratingExpression( + context: TransformationContext, + node: ts.MethodDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + const methodTable = transformMemberExpressionOwnerName(node, className); + const methodName = transformMethodName(context, node); + const parameterDecorators = getParameterDecorators(context, node); const methodDecorators = ts.getDecorators(node)?.map(d => transformDecoratorExpression(context, d)) ?? []; if (methodDecorators.length > 0 || parameterDecorators.length > 0) { diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index 5b7b6e2ff..abc4b948b 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -142,6 +142,7 @@ test.each([ ["@decorator static ['evaluated property'];"], ["method(@decorator a) {}"], ["static method(@decorator a) {}"], + ["constructor(@decorator a) {}"], ])("Decorate class member (%p)", classMember => { util.testFunction` let decoratorParameters: any; From 6a37cf189eab26920124ed9e5f560fd2465aa40f Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Sat, 6 May 2023 02:52:02 +0800 Subject: [PATCH 587/764] support extends "tstl" object for tsconfig.json in node_modules (#1440) * support extends "tstl" object tsconfig.json in node_modules upgrade typescript to 5.0.4 to fix extends resolving. https://github.com/microsoft/TypeScript/pull/53443 * support extends "tstl" object tsconfig.json in node_modules upgrade typescript to 5.0.4 to fix extends resolving. https://github.com/microsoft/TypeScript/pull/53443 * using pathIsAbsolute and pathIsRelative from ts export with declaration. * add a comment in code explaining that if a path is not absolute and not relative that it is then a module path that needs to be resolved --- package-lock.json | 14 +++++++------- package.json | 2 +- src/cli/tsconfig.ts | 22 +++++++++++++++++++++- src/typescript-internal.d.ts | 9 +++++++++ 4 files changed, 38 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 61ee008ee..2b3dd2987 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.0.2" + "typescript": "^5.0.4" }, "engines": { "node": ">=16.10.0" @@ -6090,9 +6090,9 @@ } }, "node_modules/typescript": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", - "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10840,9 +10840,9 @@ } }, "typescript": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.2.tgz", - "integrity": "sha512-wVORMBGO/FAs/++blGNeAVdbNKtIh1rbBL2EyQ1+J9lClJ93KiiKe8PmFIVdXhHcyv44SL9oglmfeSsndo0jRw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", + "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index c41cb7abc..96cbd3876 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,6 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.0.2" + "typescript": "^5.0.4" } } diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index dd6c4e9aa..2bbe4eef7 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -58,13 +58,33 @@ export function parseConfigFileWithSystem( return updateParsedConfigFile(parsedConfigFile); } +function resolveNpmModuleConfig( + moduleName: string, + configRootDir: string, + host: ts.ModuleResolutionHost +): string | undefined { + const resolved = ts.nodeNextJsonConfigResolver(moduleName, path.join(configRootDir, "tsconfig.json"), host); + if (resolved.resolvedModule) { + return resolved.resolvedModule.resolvedFileName; + } +} + function getExtendedTstlOptions( configFilePath: string, configRootDir: string, cycleCache: Set, system: ts.System ): TypeScriptToLuaOptions { - const absolutePath = path.isAbsolute(configFilePath) ? configFilePath : path.resolve(configRootDir, configFilePath); + const absolutePath = ts.pathIsAbsolute(configFilePath) + ? configFilePath + : ts.pathIsRelative(configFilePath) + ? path.resolve(configRootDir, configFilePath) + : resolveNpmModuleConfig(configFilePath, configRootDir, system); // if a path is neither relative nor absolute, it is probably a npm module + + if (!absolutePath) { + return {}; + } + const newConfigRoot = path.dirname(absolutePath); if (cycleCache.has(absolutePath)) { diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 59995ebce..253bcade8 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -50,4 +50,13 @@ declare module "typescript" { function skipOuterExpressions(node: Expression, kinds?: OuterExpressionKinds): Expression; export function isOuterExpression(node: Node, kinds?: OuterExpressionKinds): node is OuterExpression; + + export function nodeNextJsonConfigResolver( + moduleName: string, + containingFile: string, + host: ModuleResolutionHost + ): ResolvedModuleWithFailedLookupLocations; + + export function pathIsAbsolute(path: string): boolean; + export function pathIsRelative(path: string): boolean; } From a20cb1e23d48155c62de3b70d64a4a748f08be7c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 5 May 2023 21:00:35 +0200 Subject: [PATCH 588/764] 1.15.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2b3dd2987..e777b986d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.15.0", + "version": "1.15.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.15.0", + "version": "1.15.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 96cbd3876..3345b1264 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.15.0", + "version": "1.15.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 4a3b9d04b7d3486c0a4b2a94ac43606647b55aae Mon Sep 17 00:00:00 2001 From: Jacob Date: Mon, 22 May 2023 22:34:52 +0400 Subject: [PATCH 589/764] Add "require-minimal" to the "luaLibImport" enum in tsconfig-schema.json (#1442) Add the `require-minimal` enum option to improve VSCode autocomplete. --- tsconfig-schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 0d43fe74c..7af154fc0 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -44,7 +44,7 @@ "description": "Specifies how js standard features missing in lua are imported.", "type": "string", "default": "require", - "enum": ["none", "inline", "require"] + "enum": ["none", "inline", "require", "require-minimal"] }, "luaTarget": { "description": "Specifies the Lua version you want to generate code for.", From ecf6d08186712fb2cd14476dc51da7b8517e36a2 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 4 Jun 2023 17:31:24 +0200 Subject: [PATCH 590/764] Ts 5.0 decorators (#1449) * Tests for new decorators * Rename old decorate function to DecorateLegacy * Method decorators and partially accessor decorators rewritten * Modern decorators except field decorators working but with some regression to legacy * All decorators legacy and modern work, except for field decorators * Finalize property decorators * Fix unit tests --- src/LuaLib.ts | 1 + src/lualib/Decorate.ts | 43 +- src/lualib/DecorateLegacy.ts | 54 ++ src/lualib/DecorateParam.ts | 4 +- src/lualib/Decorator.d.ts | 6 +- src/transformation/utils/diagnostics.ts | 4 + .../visitors/class/decorators.ts | 198 ++++++- src/transformation/visitors/class/index.ts | 66 +-- .../visitors/class/members/accessors.ts | 24 +- .../visitors/class/members/fields.ts | 22 +- .../visitors/class/members/method.ts | 85 +-- src/transformation/visitors/class/utils.ts | 4 + .../__snapshots__/decorators.spec.ts.snap | 46 +- test/unit/classes/classes.spec.ts | 4 +- test/unit/classes/decorators.spec.ts | 511 +++++++++++++++--- test/unit/identifiers.spec.ts | 4 +- test/util.ts | 25 +- 17 files changed, 838 insertions(+), 263 deletions(-) create mode 100644 src/lualib/DecorateLegacy.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index b2f6383a6..4bf86aa5c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -38,6 +38,7 @@ export enum LuaLibFeature { CloneDescriptor = "CloneDescriptor", CountVarargs = "CountVarargs", Decorate = "Decorate", + DecorateLegacy = "DecorateLegacy", DecorateParam = "DecorateParam", Delete = "Delete", DelegatedYield = "DelegatedYield", diff --git a/src/lualib/Decorate.ts b/src/lualib/Decorate.ts index f9f8d083e..fd65f44e8 100644 --- a/src/lualib/Decorate.ts +++ b/src/lualib/Decorate.ts @@ -1,47 +1,20 @@ /** - * SEE: https://github.com/Microsoft/TypeScript/blob/master/src/compiler/transformers/ts.ts#L3598 + * TypeScript 5.0 decorators */ -import { __TS__ObjectGetOwnPropertyDescriptor } from "./ObjectGetOwnPropertyDescriptor"; -import { __TS__SetDescriptor } from "./SetDescriptor"; import { Decorator } from "./Decorator"; -export function __TS__Decorate( - this: void, - decorators: Array>, - target: TTarget, - key?: TKey, - desc?: any +export function __TS__Decorate( + this: TClass, + originalValue: TTarget, + decorators: Array>, + context: DecoratorContext ): TTarget { - let result = target; + let result = originalValue; for (let i = decorators.length; i >= 0; i--) { const decorator = decorators[i]; if (decorator !== undefined) { - const oldResult = result; - - if (key === undefined) { - result = decorator(result); - } else if (desc === true) { - const value = rawget(target, key); - const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) ?? { - configurable: true, - writable: true, - value, - }; - const desc = decorator(target, key, descriptor) || descriptor; - const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set; - if (isSimpleValue) { - rawset(target, key, desc.value); - } else { - __TS__SetDescriptor(target, key, { ...descriptor, ...desc }); - } - } else if (desc === false) { - result = decorator(target, key, desc); - } else { - result = decorator(target, key); - } - - result = result || oldResult; + result = decorator.call(this, result, context) ?? result; } } diff --git a/src/lualib/DecorateLegacy.ts b/src/lualib/DecorateLegacy.ts new file mode 100644 index 000000000..0369623d3 --- /dev/null +++ b/src/lualib/DecorateLegacy.ts @@ -0,0 +1,54 @@ +/** + * Old-style decorators, activated by enabling the experimentalDecorators flag + */ +import { __TS__ObjectGetOwnPropertyDescriptor } from "./ObjectGetOwnPropertyDescriptor"; +import { __TS__SetDescriptor } from "./SetDescriptor"; + +export type LegacyDecorator = ( + target: TTarget, + key?: TKey, + descriptor?: PropertyDescriptor +) => TTarget; + +export function __TS__DecorateLegacy( + this: void, + decorators: Array>, + target: TTarget, + key?: TKey, + desc?: any +): TTarget { + let result = target; + + for (let i = decorators.length; i >= 0; i--) { + const decorator = decorators[i]; + if (decorator !== undefined) { + const oldResult = result; + + if (key === undefined) { + result = decorator(result); + } else if (desc === true) { + const value = rawget(target, key); + const descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) ?? { + configurable: true, + writable: true, + value, + }; + const desc = decorator(target, key, descriptor) || descriptor; + const isSimpleValue = desc.configurable === true && desc.writable === true && !desc.get && !desc.set; + if (isSimpleValue) { + rawset(target, key, desc.value); + } else { + __TS__SetDescriptor(target, key, { ...descriptor, ...desc }); + } + } else if (desc === false) { + result = decorator(target, key, desc); + } else { + result = decorator(target, key); + } + + result = result || oldResult; + } + } + + return result; +} diff --git a/src/lualib/DecorateParam.ts b/src/lualib/DecorateParam.ts index 2eb59bc96..0165294b2 100644 --- a/src/lualib/DecorateParam.ts +++ b/src/lualib/DecorateParam.ts @@ -1,4 +1,4 @@ -import { Decorator } from "./Decorator"; +import type { LegacyDecorator } from "./DecorateLegacy"; type ParamDecorator = ( target: TTarget, @@ -9,6 +9,6 @@ export function __TS__DecorateParam -): Decorator { +): LegacyDecorator { return (target: TTarget, key?: TKey) => decorator(target, key, paramIndex); } diff --git a/src/lualib/Decorator.d.ts b/src/lualib/Decorator.d.ts index 338b11b3f..d8f84febf 100644 --- a/src/lualib/Decorator.d.ts +++ b/src/lualib/Decorator.d.ts @@ -1,5 +1 @@ -export type Decorator = ( - target: TTarget, - key?: TKey, - descriptor?: PropertyDescriptor -) => TTarget; +export type Decorator = (target: TTarget, context: DecoratorContext) => TTarget; diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 8fe4a22f5..137bd15b8 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -168,3 +168,7 @@ export const invalidSpreadInCallExtension = createErrorDiagnosticFactory( export const cannotAssignToNodeOfKind = createErrorDiagnosticFactory( (kind: lua.SyntaxKind) => `Cannot create assignment assigning to a node of type ${lua.SyntaxKind[kind]}.` ); + +export const incompleteFieldDecoratorWarning = createWarningDiagnosticFactory( + "You are using a class field decorator, note that tstl ignores returned value initializers!" +); diff --git a/src/transformation/visitors/class/decorators.ts b/src/transformation/visitors/class/decorators.ts index 4b913485c..11e4b75c7 100644 --- a/src/transformation/visitors/class/decorators.ts +++ b/src/transformation/visitors/class/decorators.ts @@ -1,9 +1,13 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; -import { decoratorInvalidContext } from "../../utils/diagnostics"; +import { decoratorInvalidContext, incompleteFieldDecoratorWarning } from "../../utils/diagnostics"; import { ContextType, getFunctionContextType } from "../../utils/function-context"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; +import { isNonNull } from "../../../utils"; +import { transformMemberExpressionOwnerName, transformMethodName } from "./members/method"; +import { transformPropertyName } from "../literal"; +import { isPrivateNode, isStaticNode } from "./utils"; export function transformDecoratorExpression(context: TransformationContext, decorator: ts.Decorator): lua.Expression { const expression = decorator.expression; @@ -16,7 +20,161 @@ export function transformDecoratorExpression(context: TransformationContext, dec return context.transformExpression(expression); } -export function createDecoratingExpression( +export function createClassDecoratingExpression( + context: TransformationContext, + classDeclaration: ts.ClassDeclaration | ts.ClassExpression, + className: lua.Expression +): lua.Expression { + const classDecorators = + ts.getDecorators(classDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? []; + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + return createLegacyDecoratingExpression(context, classDeclaration.kind, classDecorators, className); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, className, classDecorators, { + kind: lua.createStringLiteral("class"), + name: lua.createStringLiteral(classDeclaration.name?.getText() ?? ""), + }); +} + +export function createClassMethodDecoratingExpression( + context: TransformationContext, + methodDeclaration: ts.MethodDeclaration, + originalMethod: lua.Expression, + className: lua.Identifier +): lua.Expression { + const parameterDecorators = getParameterDecorators(context, methodDeclaration); + const methodDecorators = + ts.getDecorators(methodDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? []; + + const methodName = transformMethodName(context, methodDeclaration); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const methodTable = transformMemberExpressionOwnerName(methodDeclaration, className); + return createLegacyDecoratingExpression( + context, + methodDeclaration.kind, + [...methodDecorators, ...parameterDecorators], + methodTable, + methodName + ); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, originalMethod, methodDecorators, { + kind: lua.createStringLiteral("method"), + name: methodName, + private: lua.createBooleanLiteral(isPrivateNode(methodDeclaration)), + static: lua.createBooleanLiteral(isStaticNode(methodDeclaration)), + }); +} + +export function createClassAccessorDecoratingExpression( + context: TransformationContext, + accessor: ts.AccessorDeclaration, + originalAccessor: lua.Expression, + className: lua.Identifier +): lua.Expression { + const accessorDecorators = ts.getDecorators(accessor)?.map(d => transformDecoratorExpression(context, d)) ?? []; + const propertyName = transformPropertyName(context, accessor.name); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const propertyOwnerTable = transformMemberExpressionOwnerName(accessor, className); + + return createLegacyDecoratingExpression( + context, + accessor.kind, + accessorDecorators, + propertyOwnerTable, + propertyName + ); + } + + // Else: TypeScript 5.0 decorator + return createDecoratingExpression(context, className, originalAccessor, accessorDecorators, { + kind: lua.createStringLiteral(accessor.kind === ts.SyntaxKind.SetAccessor ? "setter" : "getter"), + name: propertyName, + private: lua.createBooleanLiteral(isPrivateNode(accessor)), + static: lua.createBooleanLiteral(isStaticNode(accessor)), + }); +} + +export function createClassPropertyDecoratingExpression( + context: TransformationContext, + property: ts.PropertyDeclaration, + className: lua.Identifier +): lua.Expression { + const decorators = ts.getDecorators(property) ?? []; + const propertyDecorators = decorators.map(d => transformDecoratorExpression(context, d)); + + // If experimentalDecorators flag is set, decorate with legacy decorator logic + if (context.options.experimentalDecorators) { + const propertyName = transformPropertyName(context, property.name); + const propertyOwnerTable = transformMemberExpressionOwnerName(property, className); + + return createLegacyDecoratingExpression( + context, + property.kind, + propertyDecorators, + propertyOwnerTable, + propertyName + ); + } + + // Else: TypeScript 5.0 decorator + + // Add a diagnostic when something is returned from a field decorator + for (const decorator of decorators) { + const signature = context.checker.getResolvedSignature(decorator); + const decoratorReturnType = signature?.getReturnType(); + // If return type of decorator is NOT void + if (decoratorReturnType && (decoratorReturnType.flags & ts.TypeFlags.Void) === 0) { + context.diagnostics.push(incompleteFieldDecoratorWarning(property)); + } + } + + return createDecoratingExpression(context, className, lua.createNilLiteral(), propertyDecorators, { + kind: lua.createStringLiteral("field"), + name: lua.createStringLiteral(property.name.getText()), + private: lua.createBooleanLiteral(isPrivateNode(property)), + static: lua.createBooleanLiteral(isStaticNode(property)), + }); +} + +function createDecoratingExpression( + context: TransformationContext, + className: lua.Expression, + originalValue: TValue, + decorators: lua.Expression[], + decoratorContext: Record +): lua.Expression { + const decoratorTable = lua.createTableExpression(decorators.map(d => lua.createTableFieldExpression(d))); + const decoratorContextTable = objectToLuaTableLiteral(decoratorContext); + + return transformLuaLibFunction( + context, + LuaLibFeature.Decorate, + undefined, + className, + originalValue, + decoratorTable, + decoratorContextTable + ); +} + +function objectToLuaTableLiteral(obj: Record): lua.Expression { + return lua.createTableExpression( + Object.entries(obj).map(([key, value]) => lua.createTableFieldExpression(value, lua.createStringLiteral(key))) + ); +} + +// Legacy decorators: +function createLegacyDecoratingExpression( context: TransformationContext, kind: ts.SyntaxKind, decorators: lua.Expression[], @@ -35,5 +193,39 @@ export function createDecoratingExpression( trailingExpressions.push(isMethodOrAccessor ? lua.createBooleanLiteral(true) : lua.createNilLiteral()); } - return transformLuaLibFunction(context, LuaLibFeature.Decorate, undefined, ...trailingExpressions); + return transformLuaLibFunction(context, LuaLibFeature.DecorateLegacy, undefined, ...trailingExpressions); +} + +function getParameterDecorators( + context: TransformationContext, + node: ts.FunctionLikeDeclarationBase +): lua.CallExpression[] { + return node.parameters + .flatMap((parameter, index) => + ts + .getDecorators(parameter) + ?.map(decorator => + transformLuaLibFunction( + context, + LuaLibFeature.DecorateParam, + node, + lua.createNumericLiteral(index), + transformDecoratorExpression(context, decorator) + ) + ) + ) + .filter(isNonNull); +} + +export function createConstructorDecoratingExpression( + context: TransformationContext, + node: ts.ConstructorDeclaration, + className: lua.Identifier +): lua.Statement | undefined { + const parameterDecorators = getParameterDecorators(context, node); + + if (parameterDecorators.length > 0) { + const decorateMethod = createLegacyDecoratingExpression(context, node.kind, parameterDecorators, className); + return lua.createExpressionStatement(decorateMethod); + } } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index c5b4d9630..e19e2ccc5 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -11,23 +11,16 @@ import { import { createSelfIdentifier } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; import { transformIdentifier } from "../identifier"; -import { createDecoratingExpression, transformDecoratorExpression } from "./decorators"; +import { createClassDecoratingExpression, createConstructorDecoratingExpression } from "./decorators"; import { transformAccessorDeclarations } from "./members/accessors"; import { createConstructorName, transformConstructorDeclaration } from "./members/constructor"; -import { - createPropertyDecoratingExpression, - transformClassInstanceFields, - transformStaticPropertyDeclaration, -} from "./members/fields"; -import { - createConstructorDecoratingExpression, - createMethodDecoratingExpression, - transformMethodDeclaration, -} from "./members/method"; +import { transformClassInstanceFields, transformStaticPropertyDeclaration } from "./members/fields"; +import { transformMethodDeclaration } from "./members/method"; import { getExtendedNode, getExtendedType, isStaticNode } from "./utils"; import { createClassSetup } from "./setup"; import { LuaTarget } from "../../../CompilerOptions"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; +import { createClassPropertyDecoratingExpression } from "./decorators"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead @@ -121,6 +114,7 @@ function transformClassLikeDeclaration( if (constructorResult) result.push(constructorResult); + // Legacy constructor decorator const decoratingExpression = createConstructorDecoratingExpression(context, constructor, localClassName); if (decoratingExpression) result.push(decoratingExpression); } else if (!extendedType) { @@ -165,51 +159,39 @@ function transformClassLikeDeclaration( ); } - // Transform accessors - for (const member of classDeclaration.members) { - if (!ts.isAccessor(member)) continue; - const accessors = context.resolver.getAllAccessorDeclarations(member); - if (accessors.firstAccessor !== member) continue; - - const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); - if (accessorsResult) { - result.push(accessorsResult); - } - } - - const decorationStatements: lua.Statement[] = []; - + // Transform class members for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { - const expression = createPropertyDecoratingExpression(context, member, localClassName); - if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); + // Accessors + const accessors = context.resolver.getAllAccessorDeclarations(member); + if (accessors.firstAccessor !== member) continue; + + const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); + if (accessorsResult) { + result.push(accessorsResult); + } } else if (ts.isMethodDeclaration(member)) { + // Methods const statement = transformMethodDeclaration(context, member, localClassName); if (statement) result.push(statement); - if (member.body) { - const statement = createMethodDecoratingExpression(context, member, localClassName); - if (statement) decorationStatements.push(statement); - } } else if (ts.isPropertyDeclaration(member)) { + // Properties if (isStaticNode(member)) { const statement = transformStaticPropertyDeclaration(context, member, localClassName); - if (statement) decorationStatements.push(statement); + if (statement) result.push(statement); + } + + if (ts.getDecorators(member)?.length) { + result.push( + lua.createExpressionStatement(createClassPropertyDecoratingExpression(context, member, className)) + ); } - const expression = createPropertyDecoratingExpression(context, member, localClassName); - if (expression) decorationStatements.push(lua.createExpressionStatement(expression)); } } - result.push(...decorationStatements); - // Decorate the class if (ts.canHaveDecorators(classDeclaration) && ts.getDecorators(classDeclaration)) { - const decoratingExpression = createDecoratingExpression( - context, - classDeclaration.kind, - ts.getDecorators(classDeclaration)?.map(d => transformDecoratorExpression(context, d)) ?? [], - localClassName - ); + const decoratingExpression = createClassDecoratingExpression(context, classDeclaration, localClassName); const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); result.push(decoratingStatement); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index fe34a3d8a..165d3fa88 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -7,11 +7,27 @@ import { transformFunctionBody, transformParameters } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; import { createPrototypeName } from "./constructor"; +import { createClassAccessorDecoratingExpression } from "../decorators"; -function transformAccessor(context: TransformationContext, node: ts.AccessorDeclaration): lua.FunctionExpression { +function transformAccessor( + context: TransformationContext, + node: ts.AccessorDeclaration, + className: lua.Identifier +): lua.Expression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; - return lua.createFunctionExpression(lua.createBlock(body), params, dot, lua.NodeFlags.Declaration); + const accessorFunction = lua.createFunctionExpression( + lua.createBlock(body), + params, + dot, + lua.NodeFlags.Declaration + ); + + if (ts.getDecorators(node)?.length) { + return createClassAccessorDecoratingExpression(context, node, accessorFunction, className); + } else { + return accessorFunction; + } } export function transformAccessorDeclarations( @@ -23,12 +39,12 @@ export function transformAccessorDeclarations( const descriptor = lua.createTableExpression([]); if (getAccessor) { - const getterFunction = transformAccessor(context, getAccessor); + const getterFunction = transformAccessor(context, getAccessor, className); descriptor.fields.push(lua.createTableFieldExpression(getterFunction, lua.createStringLiteral("get"))); } if (setAccessor) { - const setterFunction = transformAccessor(context, setAccessor); + const setterFunction = transformAccessor(context, setAccessor, className); descriptor.fields.push(lua.createTableFieldExpression(setterFunction, lua.createStringLiteral("set"))); } diff --git a/src/transformation/visitors/class/members/fields.ts b/src/transformation/visitors/class/members/fields.ts index 0e7c3e51f..2308eaac8 100644 --- a/src/transformation/visitors/class/members/fields.ts +++ b/src/transformation/visitors/class/members/fields.ts @@ -4,27 +4,6 @@ import { TransformationContext } from "../../../context"; import { createSelfIdentifier } from "../../../utils/lua-ast"; import { transformInPrecedingStatementScope } from "../../../utils/preceding-statements"; import { transformPropertyName } from "../../literal"; -import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; -import { transformMemberExpressionOwnerName } from "./method"; - -export function createPropertyDecoratingExpression( - context: TransformationContext, - node: ts.PropertyDeclaration | ts.AccessorDeclaration, - className: lua.Identifier -): lua.Expression | undefined { - if (!ts.canHaveDecorators(node)) return; - const decorators = ts.getDecorators(node); - if (!decorators) return; - const propertyName = transformPropertyName(context, node.name); - const propertyOwnerTable = transformMemberExpressionOwnerName(node, className); - return createDecoratingExpression( - context, - node.kind, - decorators.map(d => transformDecoratorExpression(context, d)), - propertyOwnerTable, - propertyName - ); -} export function transformClassInstanceFields( context: TransformationContext, @@ -63,5 +42,6 @@ export function transformStaticPropertyDeclaration( const fieldName = transformPropertyName(context, field.name); const value = context.transformExpression(field.initializer); const classField = lua.createTableIndexExpression(lua.cloneIdentifier(className), fieldName); + return lua.createAssignmentStatement(classField, value); } diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index 0c3c10672..d7dcf6d9e 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -4,10 +4,8 @@ import { TransformationContext } from "../../../context"; import { transformFunctionToExpression } from "../../function"; import { transformPropertyName } from "../../literal"; import { isStaticNode } from "../utils"; -import { createDecoratingExpression, transformDecoratorExpression } from "../decorators"; import { createPrototypeName } from "./constructor"; -import { transformLuaLibFunction, LuaLibFeature } from "../../../utils/lualib"; -import { isNonNull } from "../../../../utils"; +import { createClassMethodDecoratingExpression } from "../decorators"; export function transformMemberExpressionOwnerName( node: ts.PropertyDeclaration | ts.MethodDeclaration | ts.AccessorDeclaration, @@ -36,66 +34,27 @@ export function transformMethodDeclaration( const methodName = transformMethodName(context, node); const [functionExpression] = transformFunctionToExpression(context, node); - return lua.createAssignmentStatement( - lua.createTableIndexExpression(methodTable, methodName), - functionExpression, - node - ); -} - -export function getParameterDecorators( - context: TransformationContext, - node: ts.FunctionLikeDeclarationBase -): lua.CallExpression[] { - return node.parameters - .flatMap((parameter, index) => - ts - .getDecorators(parameter) - ?.map(decorator => - transformLuaLibFunction( - context, - LuaLibFeature.DecorateParam, - node, - lua.createNumericLiteral(index), - transformDecoratorExpression(context, decorator) - ) - ) - ) - .filter(isNonNull); -} - -export function createConstructorDecoratingExpression( - context: TransformationContext, - node: ts.ConstructorDeclaration, - className: lua.Identifier -): lua.Statement | undefined { - const parameterDecorators = getParameterDecorators(context, node); - - if (parameterDecorators.length > 0) { - const decorateMethod = createDecoratingExpression(context, node.kind, parameterDecorators, className); - return lua.createExpressionStatement(decorateMethod); - } -} - -export function createMethodDecoratingExpression( - context: TransformationContext, - node: ts.MethodDeclaration, - className: lua.Identifier -): lua.Statement | undefined { - const methodTable = transformMemberExpressionOwnerName(node, className); - const methodName = transformMethodName(context, node); - - const parameterDecorators = getParameterDecorators(context, node); - const methodDecorators = ts.getDecorators(node)?.map(d => transformDecoratorExpression(context, d)) ?? []; - - if (methodDecorators.length > 0 || parameterDecorators.length > 0) { - const decorateMethod = createDecoratingExpression( - context, - node.kind, - [...methodDecorators, ...parameterDecorators], - methodTable, - methodName + const methodHasDecorators = (ts.getDecorators(node)?.length ?? 0) > 0; + const methodHasParameterDecorators = node.parameters.some(p => (ts.getDecorators(p)?.length ?? 0) > 0); // Legacy decorators + + if (methodHasDecorators || methodHasParameterDecorators) { + if (context.options.experimentalDecorators) { + // Legacy decorator statement + return lua.createExpressionStatement( + createClassMethodDecoratingExpression(context, node, functionExpression, className) + ); + } else { + return lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + createClassMethodDecoratingExpression(context, node, functionExpression, className), + node + ); + } + } else { + return lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression, + node ); - return lua.createExpressionStatement(decorateMethod); } } diff --git a/src/transformation/visitors/class/utils.ts b/src/transformation/visitors/class/utils.ts index d5b960662..0cd4384bb 100644 --- a/src/transformation/visitors/class/utils.ts +++ b/src/transformation/visitors/class/utils.ts @@ -1,6 +1,10 @@ import * as ts from "typescript"; import { TransformationContext } from "../../context"; +export function isPrivateNode(node: ts.HasModifiers): boolean { + return node.modifiers?.some(m => m.kind === ts.SyntaxKind.PrivateKeyword) === true; +} + export function isStaticNode(node: ts.HasModifiers): boolean { return node.modifiers?.some(m => m.kind === ts.SyntaxKind.StaticKeyword) === true; } diff --git a/test/unit/classes/__snapshots__/decorators.spec.ts.snap b/test/unit/classes/__snapshots__/decorators.spec.ts.snap index e2f95d920..681e4fa3d 100644 --- a/test/unit/classes/__snapshots__/decorators.spec.ts.snap +++ b/test/unit/classes/__snapshots__/decorators.spec.ts.snap @@ -6,15 +6,57 @@ local __TS__Class = ____lualib.__TS__Class local __TS__Decorate = ____lualib.__TS__Decorate local ____exports = {} function ____exports.__main(self) - local function decorator(constructor) + local function decorator(constructor, context) end local TestClass = __TS__Class() TestClass.name = "TestClass" function TestClass.prototype.____constructor(self) end - TestClass = __TS__Decorate({decorator}, TestClass) + TestClass = __TS__Decorate(TestClass, TestClass, {decorator}, {kind = "class", name = "TestClass"}) end return ____exports" `; exports[`Throws error if decorator function has void context: diagnostics 1`] = `"main.ts(4,9): error TSTL: Decorator function cannot have 'this: void'."`; + +exports[`class field decorator warns the return value is ignored: code 1`] = ` +"local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__Decorate = ____lualib.__TS__Decorate +local ____exports = {} +function ____exports.__main(self) + local fieldDecoratorContext + local function fieldDecorator(self, _, context) + fieldDecoratorContext = context + return function(____, initialValue) return initialValue * 12 end + end + local TestClass = __TS__Class() + TestClass.name = "TestClass" + function TestClass.prototype.____constructor(self) + self.value = 22 + end + __TS__Decorate(TestClass, nil, {fieldDecorator}, {kind = "field", name = "value", private = false, static = false}) +end +return ____exports" +`; + +exports[`class field decorator warns the return value is ignored: diagnostics 1`] = `"main.ts(11,13): warning TSTL: You are using a class field decorator, note that tstl ignores returned value initializers!"`; + +exports[`legacy experimentalDecorators Throws error if decorator function has void context: code 1`] = ` +"local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__DecorateLegacy = ____lualib.__TS__DecorateLegacy +local ____exports = {} +function ____exports.__main(self) + local function decorator(constructor) + end + local TestClass = __TS__Class() + TestClass.name = "TestClass" + function TestClass.prototype.____constructor(self) + end + TestClass = __TS__DecorateLegacy({decorator}, TestClass) +end +return ____exports" +`; + +exports[`legacy experimentalDecorators Throws error if decorator function has void context: diagnostics 1`] = `"main.ts(4,13): error TSTL: Decorator function cannot have 'this: void'."`; diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index f9ab4fe61..2e447ab54 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -749,9 +749,9 @@ test("default exported anonymous class has 'default' name property", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/584 -test("constructor class name available with constructor", () => { +test("constructor class name available with decorator", () => { util.testModule` - const decorator = any>(constructor: T) => class extends constructor {}; + const decorator = any>(constructor: T, context: ClassDecoratorContext) => class extends constructor {}; @decorator class MyClass {} diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index abc4b948b..d7399f058 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -1,27 +1,37 @@ -import { decoratorInvalidContext } from "../../../src/transformation/utils/diagnostics"; +import { + decoratorInvalidContext, + incompleteFieldDecoratorWarning, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("Class decorator with no parameters", () => { util.testFunction` - function setBool {}>(constructor: T) { + let classDecoratorContext; + + function classDecorator {}>(constructor: T, context: ClassDecoratorContext) { + classDecoratorContext = context; + return class extends constructor { decoratorBool = true; } } - @setBool + @classDecorator class TestClass { public decoratorBool = false; } - return new TestClass(); + return { decoratedClass: new TestClass(), context: { + kind: classDecoratorContext.kind, + name: classDecoratorContext.name, + } }; `.expectToMatchJsResult(); }); test("Class decorator with parameters", () => { util.testFunction` function setNum(numArg: number) { - return {}>(constructor: T) => { + return {}>(constructor: T, context: ClassDecoratorContext) => { return class extends constructor { decoratorNum = numArg; }; @@ -39,13 +49,13 @@ test("Class decorator with parameters", () => { test("Multiple class decorators", () => { util.testFunction` - function setTen {}>(constructor: T) { + function setTen {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorTen = 10; } } - function setNum {}>(constructor: T) { + function setNum {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorNum = 410; } @@ -64,7 +74,7 @@ test("Multiple class decorators", () => { test("Class decorator with inheritance", () => { util.testFunction` - function setTen {}>(constructor: T) { + function setTen {}>(constructor: T, context: ClassDecoratorContext) { return class extends constructor { decoratorTen = 10; } @@ -89,7 +99,7 @@ test("Class decorators are applied in order and executed in reverse order", () = function pushOrder(index: number) { order.push("eval " + index); - return (constructor: new (...args: any[]) => {}) => { + return (constructor: new (...args: any[]) => {}, context: ClassDecoratorContext) => { order.push("execute " + index); }; } @@ -105,7 +115,7 @@ test("Class decorators are applied in order and executed in reverse order", () = test("Throws error if decorator function has void context", () => { util.testFunction` - function decorator(this: void, constructor: new (...args: any[]) => {}) {} + function decorator(this: void, constructor: new (...args: any[]) => {}, context: ClassDecoratorContext) {} @decorator class TestClass {} @@ -114,7 +124,7 @@ test("Throws error if decorator function has void context", () => { test("Exported class decorator", () => { util.testModule` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; @@ -127,65 +137,6 @@ test("Exported class decorator", () => { .expectToMatchJsResult(); }); -test.each([ - ["@decorator method() {}"], - ["@decorator property;"], - ["@decorator propertyWithInitializer = () => {};"], - ["@decorator ['evaluated property'];"], - ["@decorator get getter() { return 5 }"], - ["@decorator set setter(value) {}"], - ["@decorator static method() {}"], - ["@decorator static property;"], - ["@decorator static propertyWithInitializer = () => {}"], - ["@decorator static get getter() { return 5 }"], - ["@decorator static set setter(value) {}"], - ["@decorator static ['evaluated property'];"], - ["method(@decorator a) {}"], - ["static method(@decorator a) {}"], - ["constructor(@decorator a) {}"], -])("Decorate class member (%p)", classMember => { - util.testFunction` - let decoratorParameters: any; - - const decorator = (target, key, index?) => { - const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; - decoratorParameters = { targetKind, key, index: typeof index }; - }; - - class Foo { - ${classMember} - } - - return decoratorParameters; - `.expectToMatchJsResult(); -}); - -describe("Decorators /w descriptors", () => { - test.each([ - ["return { writable: true }", "return { configurable: true }"], - ["desc.writable = true", "return { configurable: true }"], - ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { - util.testFunction` - const A = (target, key, desc): any => { ${decorateA} }; - const B = (target, key, desc): any => { ${decorateB} }; - class Foo { @A @B static method() {} } - const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); - return rest; - `.expectToMatchJsResult(); - }); - - test.each(["return { value: true }", "desc.value = true"])( - "Use decorator to override method value", - overrideStatement => { - util.testFunction` - const decorator = (target, key, desc): any => { ${overrideStatement} }; - class Foo { @decorator static method() {} } - return Foo.method; - `.expectToMatchJsResult(); - } - ); -}); - // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 test("exported class with decorator", () => { util.testModule` @@ -195,7 +146,7 @@ test("exported class with decorator", () => { ` .addExtraFile( "other.ts", - `function myDecorator(target: {new(): any}) { + `function myDecorator(target: {new(): any}, context: ClassDecoratorContext) { return class extends target { foo() { return "overridden"; @@ -221,7 +172,7 @@ test("default exported class with decorator", () => { ` .addExtraFile( "other.ts", - `function myDecorator(target: {new(): any}) { + `function myDecorator(target: {new(): any}, context: ClassDecoratorContext) { return class extends target { foo() { return "overridden"; @@ -238,3 +189,419 @@ test("default exported class with decorator", () => { ) .expectToEqual({ result: "overridden" }); }); + +test("class method decorator", () => { + util.testFunction` + let methodDecoratorContext; + + function methodDecorator(method: (v: number) => number, context: ClassMethodDecoratorContext) { + methodDecoratorContext = context; + + return (v: number) => { + return method(v) + 10; + }; + } + + class TestClass { + @methodDecorator + public myMethod(x: number) { + return x * 23; + } + } + + return { result: new TestClass().myMethod(4), context: { + kind: methodDecoratorContext.kind, + name: methodDecoratorContext.name, + private: methodDecoratorContext.private, + static: methodDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("this in decorator points to class being decorated", () => { + util.testFunction` + function methodDecorator(method: (v: number) => number, context: ClassMethodDecoratorContext) { + return function() { + const thisCallTime = this.myInstanceVariable; + return thisCallTime; + }; + } + + class TestClass { + constructor(protected myInstanceVariable: number) { } + + @methodDecorator + public myMethod() { + return 0; + } + } + + return new TestClass(5).myMethod(); + `.expectToMatchJsResult(); +}); + +test("class getter decorator", () => { + util.testFunction` + let getterDecoratorContext; + + function getterDecorator(getter: () => number, context: ClassGetterDecoratorContext) { + getterDecoratorContext = context; + + return () => { + return getter() + 10; + }; + } + + class TestClass { + @getterDecorator + get getterValue() { return 10; } + } + + return { result: new TestClass().getterValue, context: { + kind: getterDecoratorContext.kind, + name: getterDecoratorContext.name, + private: getterDecoratorContext.private, + static: getterDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("class setter decorator", () => { + util.testFunction` + let setterDecoratorContext; + + function setterDecorator(setter: (v: number) => void, context: ClassSetterDecoratorContext) { + setterDecoratorContext = context; + + return function(v: number) { + setter.call(this, v + 15); + }; + } + + class TestClass { + public value: number; + + @setterDecorator + set valueSetter(v: number) { this.value = v; } + } + + const instance = new TestClass(); + instance.valueSetter = 23; + return { result: instance.value, context: { + kind: setterDecoratorContext.kind, + name: setterDecoratorContext.name, + private: setterDecoratorContext.private, + static: setterDecoratorContext.static + } }; + `.expectToMatchJsResult(); +}); + +test("class field decorator", () => { + util.testFunction` + let fieldDecoratorContext; + + function fieldDecorator(_: undefined, context: ClassFieldDecoratorContext) { + fieldDecoratorContext = context; + } + + class TestClass { + @fieldDecorator + public value: number = 22; + } + + return { result: new TestClass(), context: { + kind: fieldDecoratorContext.kind, + name: fieldDecoratorContext.name, + private: fieldDecoratorContext.private, + static: fieldDecoratorContext.static, + } }; + `.expectToEqual({ + result: { + value: 22, // Different from JS because we ignore the value initializer + }, + context: { + kind: "field", + name: "value", + private: false, + static: false, + }, + }); +}); + +test("class field decorator warns the return value is ignored", () => { + util.testFunction` + let fieldDecoratorContext; + + function fieldDecorator(_: undefined, context: ClassFieldDecoratorContext) { + fieldDecoratorContext = context; + + return (initialValue: number) => initialValue * 12; + } + + class TestClass { + @fieldDecorator + public value: number = 22; + } + `.expectDiagnosticsToMatchSnapshot([incompleteFieldDecoratorWarning.code]); +}); + +describe("legacy experimentalDecorators", () => { + test("Class decorator with no parameters", () => { + util.testFunction` + function setBool {}>(constructor: T) { + return class extends constructor { + decoratorBool = true; + } + } + + @setBool + class TestClass { + public decoratorBool = false; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorator with parameters", () => { + util.testFunction` + function setNum(numArg: number) { + return {}>(constructor: T) => { + return class extends constructor { + decoratorNum = numArg; + }; + }; + } + + @setNum(420) + class TestClass { + public decoratorNum; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Multiple class decorators", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + function setNum {}>(constructor: T) { + return class extends constructor { + decoratorNum = 410; + } + } + + @setTen + @setNum + class TestClass { + public decoratorTen; + public decoratorNum; + } + + return new TestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorator with inheritance", () => { + util.testFunction` + function setTen {}>(constructor: T) { + return class extends constructor { + decoratorTen = 10; + } + } + + class TestClass { + public decoratorTen = 0; + } + + @setTen + class SubTestClass extends TestClass { + public decoratorTen = 5; + } + + return new SubTestClass(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Class decorators are applied in order and executed in reverse order", () => { + util.testFunction` + const order = []; + + function pushOrder(index: number) { + order.push("eval " + index); + return (constructor: new (...args: any[]) => {}) => { + order.push("execute " + index); + }; + } + + @pushOrder(1) + @pushOrder(2) + @pushOrder(3) + class TestClass {} + + return order; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test("Throws error if decorator function has void context", () => { + util.testFunction` + function decorator(this: void, constructor: new (...args: any[]) => {}) {} + + @decorator + class TestClass {} + ` + .setOptions({ experimentalDecorators: true }) + .expectDiagnosticsToMatchSnapshot([decoratorInvalidContext.code]); + }); + + test("Exported class decorator", () => { + util.testModule` + function decorator any>(Class: T): T { + return class extends Class { + public bar = "foobar"; + }; + } + + @decorator + export class Foo {} + ` + .setReturnExport("Foo", "bar") + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test.each([ + ["@decorator method() {}"], + ["@decorator property;"], + ["@decorator propertyWithInitializer = () => {};"], + ["@decorator ['evaluated property'];"], + ["@decorator get getter() { return 5 }"], + ["@decorator set setter(value) {}"], + ["@decorator static method() {}"], + ["@decorator static property;"], + ["@decorator static propertyWithInitializer = () => {}"], + ["@decorator static get getter() { return 5 }"], + ["@decorator static set setter(value) {}"], + ["@decorator static ['evaluated property'];"], + ["method(@decorator a) {}"], + ["static method(@decorator a) {}"], + ["constructor(@decorator a) {}"], + ])("Decorate class member (%p)", classMember => { + util.testFunction` + let decoratorParameters: any; + + const decorator = (target, key, index?) => { + const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; + decoratorParameters = { targetKind, key, index: typeof index }; + }; + + class Foo { + ${classMember} + } + + return decoratorParameters; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + describe("Decorators /w descriptors", () => { + test.each([ + ["return { writable: true }", "return { configurable: true }"], + ["desc.writable = true", "return { configurable: true }"], + ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { + util.testFunction` + const A = (target, key, desc): any => { ${decorateA} }; + const B = (target, key, desc): any => { ${decorateB} }; + class Foo { @A @B static method() {} } + const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); + return rest; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); + + test.each(["return { value: true }", "desc.value = true"])( + "Use decorator to override method value %s", + overrideStatement => { + util.testFunction` + const decorator = (target, key, desc): any => { ${overrideStatement} }; + class Foo { @decorator static method() {} } + return Foo.method; + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + } + ); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 + test("exported class with decorator", () => { + util.testModule` + import { MyClass } from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export class MyClass { + foo() { + return "foo"; + } + }` + ) + .setOptions({ experimentalDecorators: true }) + .expectToEqual({ result: "overridden" }); + }); + + test("default exported class with decorator", () => { + util.testModule` + import MyClass from "./other"; + const inst = new MyClass(); + export const result = inst.foo(); + ` + .addExtraFile( + "other.ts", + `function myDecorator(target: {new(): any}) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + @myDecorator + export default class { + foo() { + return "foo"; + } + }` + ) + .setOptions({ experimentalDecorators: true }) + .expectToEqual({ result: "overridden" }); + }); +}); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index e3acf8530..6e13a5e12 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -196,7 +196,7 @@ test.each(validTsInvalidLuaNames)("class with invalid lua name has correct name test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name => { util.testFunction` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; @@ -210,7 +210,7 @@ test.each(validTsInvalidLuaNames)("decorated class with invalid lua name", name test.each(validTsInvalidLuaNames)("exported decorated class with invalid lua name", name => { util.testModule` - function decorator any>(Class: T): T { + function decorator any>(Class: T, context: ClassDecoratorContext): T { return class extends Class { public bar = "foobar"; }; diff --git a/test/util.ts b/test/util.ts index f2c73e1e2..75b477849 100644 --- a/test/util.ts +++ b/test/util.ts @@ -122,35 +122,35 @@ export abstract class TestBuilder { // TODO: Use testModule in these cases? protected tsHeader = ""; public setTsHeader(tsHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setTsHeader"); this.tsHeader = tsHeader; return this; } private luaHeader = ""; public setLuaHeader(luaHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setLuaHeader"); this.luaHeader += luaHeader; return this; } protected jsHeader = ""; public setJsHeader(jsHeader: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setJsHeader"); this.jsHeader += jsHeader; return this; } protected abstract getLuaCodeWithWrapper(code: string): string; public setLuaFactory(luaFactory: (code: string) => string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setLuaFactory"); this.getLuaCodeWithWrapper = luaFactory; return this; } private semanticCheck = true; public disableSemanticCheck(): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("disableSemanticCheck"); this.semanticCheck = false; return this; } @@ -163,11 +163,10 @@ export abstract class TestBuilder { lib: ["lib.esnext.d.ts"], moduleResolution: ts.ModuleResolutionKind.Node10, resolveJsonModule: true, - experimentalDecorators: true, sourceMap: true, }; public setOptions(options: tstl.CompilerOptions = {}): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setOptions"); Object.assign(this.options, options); return this; } @@ -184,25 +183,31 @@ export abstract class TestBuilder { protected mainFileName = "main.ts"; public setMainFileName(mainFileName: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setMainFileName"); this.mainFileName = mainFileName; return this; } protected extraFiles: Record = {}; public addExtraFile(fileName: string, code: string): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("addExtraFile"); this.extraFiles[fileName] = normalizeSlashes(code); return this; } private customTransformers?: ts.CustomTransformers; public setCustomTransformers(customTransformers?: ts.CustomTransformers): this { - expect(this.hasProgram).toBe(false); + this.throwIfProgramExists("setCustomTransformers"); this.customTransformers = customTransformers; return this; } + private throwIfProgramExists(name: string) { + if (this.hasProgram) { + throw new Error(`${name}() should not be called after an .expect() or .debug()`); + } + } + // Transpilation and execution public getTsCode(): string { From a2ee2f7754d1fc1711adede50f58dc295b7688ad Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 4 Jun 2023 17:40:19 +0200 Subject: [PATCH 591/764] Add support for class static initialization blocks (#1451) * Tests for new decorators * Rename old decorate function to DecorateLegacy * Method decorators and partially accessor decorators rewritten * Modern decorators except field decorators working but with some regression to legacy * All decorators legacy and modern work, except for field decorators * Finalize property decorators * Fix unit tests * Add support for class static initialization blocks --- src/transformation/visitors/class/index.ts | 9 +++++++++ test/unit/classes/classes.spec.ts | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index e19e2ccc5..fe831045c 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -186,6 +186,15 @@ function transformClassLikeDeclaration( lua.createExpressionStatement(createClassPropertyDecoratingExpression(context, member, className)) ); } + } else if (ts.isClassStaticBlockDeclaration(member)) { + if (member.body.statements.length > 0) { + const bodyStatements = context.transformStatements(member.body.statements); + const iif = lua.createFunctionExpression(lua.createBlock(bodyStatements), [ + lua.createIdentifier("self"), + ]); + const iife = lua.createCallExpression(iif, [className]); + result.push(lua.createExpressionStatement(iife, member)); + } } } diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 2e447ab54..a2079d360 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -799,3 +799,22 @@ test.each(['(this["bar"])', '((((this["bar"]))))'])("methods in parentheses pass export const result = inst.foo(); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1447 +test("static initialization block (#1447)", () => { + util.testModule` + class A { + private static staticProperty1 = 3; + public static staticProperty2; + static { + this.staticProperty2 = this.staticProperty1 + 5; + } + public static staticProperty3; + static { + this.staticProperty3 = this.staticProperty1 + this.staticProperty2; + } + } + export const result1 = A.staticProperty2; + export const result2 = A.staticProperty3; + `.expectToMatchJsResult(); +}); From f01403f99419e8c9c45a3b774ec37a495089a14b Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 4 Jun 2023 17:55:02 +0200 Subject: [PATCH 592/764] Upgrade TS to 5.1.3 (#1452) * Tests for new decorators * Rename old decorate function to DecorateLegacy * Method decorators and partially accessor decorators rewritten * Modern decorators except field decorators working but with some regression to legacy * All decorators legacy and modern work, except for field decorators * Finalize property decorators * Fix unit tests * Upgrade TS to 5.1.3 --- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- src/transformation/utils/function-context.ts | 2 +- src/transformation/visitors/function.ts | 2 +- src/transformation/visitors/identifier.ts | 2 +- src/transformation/visitors/modules/export.ts | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package-lock.json b/package-lock.json index e777b986d..60b4b9546 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,13 +37,13 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.0.4" + "typescript": "~5.1.3" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "^5.0.2" + "typescript": "~5.1.3" } }, "node_modules/@ampproject/remapping": { @@ -6090,16 +6090,16 @@ } }, "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=12.20" + "node": ">=14.17" } }, "node_modules/unbox-primitive": { @@ -10840,9 +10840,9 @@ } }, "typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", + "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 3345b1264..35e8087d3 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "^5.0.2" + "typescript": "~5.1.3" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", @@ -70,6 +70,6 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.0.4" + "typescript": "~5.1.3" } } diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 154150bd1..2cac26836 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -30,7 +30,7 @@ function hasNoSelfAncestor(declaration: ts.Declaration): boolean { function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration): ts.ParameterDeclaration | undefined { const param = signatureDeclaration.parameters[0]; - if (param && ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + if (param && ts.isIdentifier(param.name) && ts.identifierToKeywordKind(param.name) === ts.SyntaxKind.ThisKeyword) { return param; } } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 1c21a0f7c..6f101c5ac 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -195,7 +195,7 @@ export function transformParameters( // Only push parameter name to paramName array if it isn't a spread parameter for (const param of parameters) { - if (ts.isIdentifier(param.name) && param.name.originalKeywordKind === ts.SyntaxKind.ThisKeyword) { + if (ts.isIdentifier(param.name) && ts.identifierToKeywordKind(param.name) === ts.SyntaxKind.ThisKeyword) { continue; } diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index ec89141b8..6262a316f 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -85,7 +85,7 @@ export function transformIdentifierWithSymbol( } export const transformIdentifierExpression: FunctionVisitor = (node, context) => { - if (node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword) { + if (ts.identifierToKeywordKind(node) === ts.SyntaxKind.UndefinedKeyword) { return lua.createNilLiteral(node); } diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 025ac4465..c32551aaf 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -105,8 +105,8 @@ function transformExportAll(context: TransformationContext, node: ts.ExportDecla } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => - (node.name && node.name.originalKeywordKind === ts.SyntaxKind.DefaultKeyword) || - (node.propertyName && node.propertyName.originalKeywordKind === ts.SyntaxKind.DefaultKeyword); + (node.name && ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) || + (node.propertyName && ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword); function transformExportSpecifier(context: TransformationContext, node: ts.ExportSpecifier): lua.AssignmentStatement { const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); From 4169d1c0bf1fab9076b09c0ca9a2dd5f457d2363 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Jun 2023 18:16:54 +0200 Subject: [PATCH 593/764] CHANGELOG.md 1.16.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e439fe23..ea9da99a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.16.0 + +- Upgraded TypeScript to 5.1.3. +- Added support for [TypeScript 5.0 decorators](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#decorators). + - Old-style decorators will still work as long as you have `experimentalDecorators` configured, otherwise the new standard is used. +- Added support for [class static initialization blocks](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks). +- Fixed a bug causing the `tstl` object in tsconfig.json not to be properly extended when extending a tsconfig from node_modules. + ## 1.15.0 - Using `extends` in tsconfig.json now also correctly merges settings in the `tstl` block (shallow merge). From 251ab0433e515971740db5e61d60d75d4f9e247c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Jun 2023 18:26:46 +0200 Subject: [PATCH 594/764] 1.16.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 60b4b9546..6854976f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.15.1", + "version": "1.16.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.15.1", + "version": "1.16.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 35e8087d3..6ab2fa978 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.15.1", + "version": "1.16.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 8656970ff0136c6048e5f9c0c55645d3ca7dace9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 5 Jun 2023 21:45:18 +0200 Subject: [PATCH 595/764] Fixed missing method implementations when using legacy method decorators (#1454) --- src/transformation/visitors/class/index.ts | 4 +- .../visitors/class/members/method.ts | 40 ++++++++++++------- test/unit/classes/decorators.spec.ts | 19 +++++++++ 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index fe831045c..51be1fe5a 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -172,8 +172,8 @@ function transformClassLikeDeclaration( } } else if (ts.isMethodDeclaration(member)) { // Methods - const statement = transformMethodDeclaration(context, member, localClassName); - if (statement) result.push(statement); + const statements = transformMethodDeclaration(context, member, localClassName); + result.push(...statements); } else if (ts.isPropertyDeclaration(member)) { // Properties if (isStaticNode(member)) { diff --git a/src/transformation/visitors/class/members/method.ts b/src/transformation/visitors/class/members/method.ts index d7dcf6d9e..adfe2c352 100644 --- a/src/transformation/visitors/class/members/method.ts +++ b/src/transformation/visitors/class/members/method.ts @@ -26,9 +26,9 @@ export function transformMethodDeclaration( context: TransformationContext, node: ts.MethodDeclaration, className: lua.Identifier -): lua.Statement | undefined { +): lua.Statement[] { // Don't transform methods without body (overload declarations) - if (!node.body) return; + if (!node.body) return []; const methodTable = transformMemberExpressionOwnerName(node, className); const methodName = transformMethodName(context, node); @@ -40,21 +40,31 @@ export function transformMethodDeclaration( if (methodHasDecorators || methodHasParameterDecorators) { if (context.options.experimentalDecorators) { // Legacy decorator statement - return lua.createExpressionStatement( - createClassMethodDecoratingExpression(context, node, functionExpression, className) - ); + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression + ), + lua.createExpressionStatement( + createClassMethodDecoratingExpression(context, node, functionExpression, className) + ), + ]; } else { - return lua.createAssignmentStatement( - lua.createTableIndexExpression(methodTable, methodName), - createClassMethodDecoratingExpression(context, node, functionExpression, className), - node - ); + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + createClassMethodDecoratingExpression(context, node, functionExpression, className), + node + ), + ]; } } else { - return lua.createAssignmentStatement( - lua.createTableIndexExpression(methodTable, methodName), - functionExpression, - node - ); + return [ + lua.createAssignmentStatement( + lua.createTableIndexExpression(methodTable, methodName), + functionExpression, + node + ), + ]; } } diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index d7399f058..1923f8b2b 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -604,4 +604,23 @@ describe("legacy experimentalDecorators", () => { .setOptions({ experimentalDecorators: true }) .expectToEqual({ result: "overridden" }); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1453 + test("Class methods with legacy decorators can still be called ($1453)", () => { + util.testFunction` + function decorator( + target: Class, + propertyKey: keyof Class, + ): void {} + + class Foo { + @decorator + public method2() { return 4; } + } + + return new Foo().method2(); + ` + .setOptions({ experimentalDecorators: true }) + .expectToMatchJsResult(); + }); }); From 308d9d81e17c33cd2ca3bcd02ad9c5b39c06f041 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 5 Jun 2023 21:48:15 +0200 Subject: [PATCH 596/764] 1.16.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6854976f1..9f7999d22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.16.0", + "version": "1.16.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.16.0", + "version": "1.16.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 6ab2fa978..4ae59350f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.16.0", + "version": "1.16.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 0e5df55f4fbadce5025add48fced11ec031278d7 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 11 Jun 2023 22:29:18 +0200 Subject: [PATCH 597/764] Change class initialization order (#1458) --- src/transformation/visitors/class/index.ts | 15 +++++++++++---- test/unit/classes/classes.spec.ts | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 51be1fe5a..9574d1efc 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -160,6 +160,17 @@ function transformClassLikeDeclaration( } // Transform class members + + // First transform the methods, in case the static properties call them + for (const member of classDeclaration.members) { + if (ts.isMethodDeclaration(member)) { + // Methods + const statements = transformMethodDeclaration(context, member, localClassName); + result.push(...statements); + } + } + + // Then transform the rest for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { // Accessors @@ -170,10 +181,6 @@ function transformClassLikeDeclaration( if (accessorsResult) { result.push(accessorsResult); } - } else if (ts.isMethodDeclaration(member)) { - // Methods - const statements = transformMethodDeclaration(context, member, localClassName); - result.push(...statements); } else if (ts.isPropertyDeclaration(member)) { // Properties if (isStaticNode(member)) { diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index a2079d360..93c7640cf 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -818,3 +818,18 @@ test("static initialization block (#1447)", () => { export const result2 = A.staticProperty3; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1457 +test("static member definition order (#1457)", () => { + util.testFunction` + class A { + static a = A.foo() + + static foo(): number { + return 5 + } + } + + return A.a; + `.expectToMatchJsResult(); +}); From 7cd693551d1c1c203654aff0711755dcbd8c2a79 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 11 Jun 2023 22:29:31 +0200 Subject: [PATCH 598/764] Fix optimizing spread to table unpack too often (#1459) * Fix optimizing spread to table unpack too often * Update test snapshot --- src/transformation/utils/typescript/types.ts | 20 +++++++++++++++++++ src/transformation/visitors/spread.ts | 5 +++-- .../__snapshots__/vararg.spec.ts.snap | 6 ++++-- test/unit/spread.spec.ts | 12 +++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 1a657d673..5ba2a013c 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -70,6 +70,22 @@ function isExplicitArrayType(context: TransformationContext, type: ts.Type): boo return false; } +function isAlwaysExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { + if (context.checker.isArrayType(type) || context.checker.isTupleType(type)) return true; + if (type.symbol) { + const baseConstraint = context.checker.getBaseConstraintOfType(type); + if (baseConstraint && baseConstraint !== type) { + return isAlwaysExplicitArrayType(context, baseConstraint); + } + } + + if (type.isUnionOrIntersection()) { + return type.types.every(t => isAlwaysExplicitArrayType(context, t)); + } + + return false; +} + /** * Iterate over a type and its bases until the callback returns true. */ @@ -95,6 +111,10 @@ export function isArrayType(context: TransformationContext, type: ts.Type): bool return forTypeOrAnySupertype(context, type, t => isExplicitArrayType(context, t)); } +export function isAlwaysArrayType(context: TransformationContext, type: ts.Type): boolean { + return forTypeOrAnySupertype(context, type, t => isAlwaysExplicitArrayType(context, t)); +} + export function isFunctionType(type: ts.Type): boolean { return type.getCallSignatures().length > 0; } diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 9d473e040..9c8cb6feb 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -13,7 +13,7 @@ import { isFunctionScopeWithDefinition, ScopeType, } from "../utils/scope"; -import { isArrayType, findFirstNonOuterParent } from "../utils/typescript"; +import { findFirstNonOuterParent, isAlwaysArrayType } from "../utils/typescript"; import { isMultiReturnCall } from "./language-extensions/multi"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; @@ -96,7 +96,8 @@ export const transformSpreadElement: FunctionVisitor = (node, } const type = context.checker.getTypeAtLocation(node.expression); // not ts-inner expression, in case of casts - if (isArrayType(context, type)) { + if (isAlwaysArrayType(context, type)) { + // All union members must be arrays to be able to shortcut to unpack call return createUnpackCall(context, innerExpression, node); } diff --git a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap index 819cc27a0..e2cf42298 100644 --- a/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/vararg.spec.ts.snap @@ -24,12 +24,14 @@ f(_G, ____)" exports[`$vararg invalid use ("function f(s: string[]) {} f($vararg);"): diagnostics 1`] = `"main.ts(2,38): error TSTL: $vararg can only be used in a spread element ('...$vararg') in global scope."`; exports[`$vararg invalid use ("function foo(...args: string[]) {} function bar() { foo(...$vararg); }"): code 1`] = ` -"function foo(self, ...) +"local ____lualib = require("lualib_bundle") +local __TS__Spread = ____lualib.__TS__Spread +function foo(self, ...) end function bar(self) foo( _G, - table.unpack(____) + __TS__Spread(____) ) end" `; diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index f0f57d164..04b1bd726 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -561,3 +561,15 @@ test("can spread LuaSet (#1384)", () => { expect(result).toContain("foo"); expect(result).toContain("bar"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1426 +test.each([true, false])("spread a decorator or array union type (#1426)", choice => { + util.testFunction` + function* things() { + yield "a"; + yield "b" + } + const c: boolean = ${util.formatCode(choice)}; + return [...(c ? things() : ["c", "d"])]; + `.expectToMatchJsResult(); +}); From 0795695a4324fa7c2d1ab1672aca14ec8d9bd1be Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 11 Jun 2023 22:39:16 +0200 Subject: [PATCH 599/764] 1.16.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9f7999d22..733d5c39a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.16.1", + "version": "1.16.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.16.1", + "version": "1.16.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 4ae59350f..49fd83c97 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.16.1", + "version": "1.16.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 278ead63924153c2806ccf60e9f1cf7c0be35639 Mon Sep 17 00:00:00 2001 From: Sam? Date: Thu, 15 Jun 2023 15:31:22 -0400 Subject: [PATCH 600/764] Add import resolution plugin hook (#1455) * added a plugin hook for custom module resolution strategies * fixed an issue with the plugin module resolution when importing scripts from other scripts * fixed a mistake I made when changing packageRoot to currentPackage * passed plugins directory to the emitPlan function so we can avoid using the getPlugins call again * delete an accidental output * moved module resolution logic to resolveImport and made the requested changes to the interface * reverted resolveLuaDependencyPathFromNodeModules because the changes are no longer needed * replaced some comments and change a conditional statement * - included compiler options and emit host in module resolution plugin interface - removed try catch on plugin execution * - some fixes to the module resolution - added test case * fixed passing the dependency path instead of the required path and fixed the test plugin * removed transformation to luaRequirePath so the module identifier meets the format specified in the interface * renamed param for formatPathToFile --- src/transpilation/plugins.ts | 7 ++ src/transpilation/resolve.ts | 85 ++++++++++++++++--- src/transpilation/transpiler.ts | 7 +- test/transpile/module-resolution.spec.ts | 30 +++++++ .../lua_sources/bar.lua | 5 ++ .../lua_sources/foo.d.ts | 1 + .../main.ts | 2 + .../tsconfig.json | 9 ++ test/transpile/plugins/moduleResolution.ts | 14 +++ 9 files changed, 145 insertions(+), 15 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json create mode 100644 test/transpile/plugins/moduleResolution.ts diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 13c96be64..f4c653e59 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -45,6 +45,13 @@ export interface Plugin { emitHost: EmitHost, result: EmitFile[] ) => ts.Diagnostic[] | void; + + moduleResolution?: ( + moduleIdentifier: string, + requiringFile: string, + options: CompilerOptions, + emitHost: EmitHost + ) => string | undefined; } export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } { diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 781da43c2..5768714a8 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -9,6 +9,7 @@ import { formatPathToLuaPath, normalizeSlashes, trimExtension } from "../utils"; import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; import { BuildMode, CompilerOptions } from "../CompilerOptions"; import { findLuaRequires, LuaRequire } from "./find-lua-requires"; +import { Plugin } from "./plugins"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], @@ -33,7 +34,8 @@ class ResolutionContext { constructor( public readonly program: ts.Program, public readonly options: CompilerOptions, - private readonly emitHost: EmitHost + private readonly emitHost: EmitHost, + private readonly plugins: Plugin[] ) { this.noResolvePaths = new Set(options.noResolvePaths); } @@ -77,7 +79,10 @@ class ResolutionContext { return; } - const dependencyPath = this.resolveDependencyPath(file, required.requirePath); + const dependencyPath = + this.resolveDependencyPathsWithPlugins(file, required.requirePath) ?? + this.resolveDependencyPath(file, required.requirePath); + if (!dependencyPath) return this.couldNotResolveImport(required, file); if (this.options.tstlVerbose) { @@ -93,8 +98,65 @@ class ResolutionContext { } } + private resolveDependencyPathsWithPlugins(requiringFile: ProcessedFile, dependency: string) { + const requiredFromLuaFile = requiringFile.fileName.endsWith(".lua"); + for (const plugin of this.plugins) { + if (plugin.moduleResolution != null) { + const pluginResolvedPath = plugin.moduleResolution( + dependency, + requiringFile.fileName, + this.options, + this.emitHost + ); + if (pluginResolvedPath !== undefined) { + // If lua file is in node_module + if (requiredFromLuaFile && isNodeModulesFile(requiringFile.fileName)) { + // If requiring file is in lua module, try to resolve sibling in that file first + const resolvedNodeModulesFile = this.resolveLuaDependencyPathFromNodeModules( + requiringFile, + pluginResolvedPath + ); + if (resolvedNodeModulesFile) { + if (this.options.tstlVerbose) { + console.log( + `Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.` + ); + } + return resolvedNodeModulesFile; + } + } + + const resolvedPath = this.formatPathToFile(pluginResolvedPath, requiringFile); + const fileFromPath = this.getFileFromPath(resolvedPath); + + if (fileFromPath) { + if (this.options.tstlVerbose) { + console.log( + `Resolved file path for module ${dependency} to path ${pluginResolvedPath} using plugin.` + ); + } + return fileFromPath; + } + } + } + } + } + public processedDependencies = new Set(); + private formatPathToFile(targetPath: string, required: ProcessedFile) { + const isRelative = ["/", "./", "../"].some(p => targetPath.startsWith(p)); + + // // If the import is relative, always resolve it relative to the requiring file + // // If the import is not relative, resolve it relative to options.baseUrl if it is set + const fileDirectory = path.dirname(required.fileName); + const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; + + // // Check if file is a file in the project + const resolvedPath = path.join(relativeTo, targetPath); + return resolvedPath; + } + private processDependency(dependencyPath: string): void { if (this.processedDependencies.has(dependencyPath)) return; this.processedDependencies.add(dependencyPath); @@ -140,15 +202,8 @@ class ResolutionContext { if (resolvedNodeModulesFile) return resolvedNodeModulesFile; } - // Check if the import is relative - const isRelative = ["/", "./", "../"].some(p => dependency.startsWith(p)); - - // If the import is relative, always resolve it relative to the requiring file - // If the import is not relative, resolve it relative to options.baseUrl if it is set - const relativeTo = isRelative ? fileDirectory : this.options.baseUrl ?? fileDirectory; - // Check if file is a file in the project - const resolvedPath = path.join(relativeTo, dependencyPath); + const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); const fileFromPath = this.getFileFromPath(resolvedPath); if (fileFromPath) return fileFromPath; @@ -235,6 +290,7 @@ class ResolutionContext { path.join(resolvedPath, "index.lua"), // lua index file in sources path.join(resolvedPath, "init.lua"), // lua looks for /init.lua if it cannot find .lua ]; + for (const possibleFile of possibleLuaProjectFiles) { if (this.emitHost.fileExists(possibleFile)) { return possibleFile; @@ -277,10 +333,15 @@ class ResolutionContext { } } -export function resolveDependencies(program: ts.Program, files: ProcessedFile[], emitHost: EmitHost): ResolutionResult { +export function resolveDependencies( + program: ts.Program, + files: ProcessedFile[], + emitHost: EmitHost, + plugins: Plugin[] +): ResolutionResult { const options = program.getCompilerOptions() as CompilerOptions; - const resolutionContext = new ResolutionContext(program, options, emitHost); + const resolutionContext = new ResolutionContext(program, options, emitHost, plugins); // Resolve dependencies for all processed files for (const file of files) { diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index b4a9770d2..65545e455 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -45,7 +45,7 @@ export class Transpiler { } ); - const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles); + const { emitPlan } = this.getEmitPlan(program, transpileDiagnostics, freshFiles, plugins); const emitDiagnostics = this.emitFiles(program, plugins, emitPlan, writeFile); @@ -102,7 +102,8 @@ export class Transpiler { protected getEmitPlan( program: ts.Program, diagnostics: ts.Diagnostic[], - files: ProcessedFile[] + files: ProcessedFile[], + plugins: Plugin[] ): { emitPlan: EmitFile[] } { performance.startSection("getEmitPlan"); const options = program.getCompilerOptions() as CompilerOptions; @@ -112,7 +113,7 @@ export class Transpiler { } // Resolve imported modules and modify output Lua requires - const resolutionResult = resolveDependencies(program, files, this.emitHost); + const resolutionResult = resolveDependencies(program, files, this.emitHost, plugins); diagnostics.push(...resolutionResult.diagnostics); const lualibRequired = resolutionResult.resolvedFiles.some(f => f.fileName === "lualib_bundle"); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index 7aa96001a..c2de18933 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -647,6 +647,36 @@ test("paths without baseUrl is error", () => { util.testFunction``.setOptions({ paths: {} }).expectToHaveDiagnostics([pathsWithoutBaseUrl.code]); }); +test("module resolution using plugin", () => { + const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); + const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); + const mainFile = path.join(baseProjectPath, "src", "main.ts"); + + const luaResult = util + .testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ + luaPlugins: [ + { + name: path.join(__dirname, "./plugins/moduleResolution.ts"), + }, + ], + }) + .expectToHaveNoDiagnostics() + .getLuaResult(); + + expect(luaResult.transpiledFiles).toHaveLength(2); + let hasResolvedFile = false; + for (const f of luaResult.transpiledFiles) { + hasResolvedFile = f.outPath.endsWith("bar.lua"); + if (hasResolvedFile) { + break; + } + } + + expect(hasResolvedFile).toBe(true); +}); + function snapshotPaths(files: tstl.TranspiledFile[]) { return files.map(f => normalizeSlashes(f.outPath).split("module-resolution")[1]).sort(); } diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua new file mode 100644 index 000000000..b821a15b5 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/bar.lua @@ -0,0 +1,5 @@ +local ____exports = {} +function ____exports.foo(self) + return "foo" +end +return ____exports \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts new file mode 100644 index 000000000..27e069e94 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/foo.d.ts @@ -0,0 +1 @@ +export declare function foo(): string; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts new file mode 100644 index 000000000..59c17ab79 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts @@ -0,0 +1,2 @@ +import { foo } from "./lua_sources/foo"; +export const result = foo(); diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json new file mode 100644 index 000000000..6d1f36cd6 --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "strict": true, + "target": "esnext", + "lib": ["esnext"], + "types": [], + "outDir": "./dist" + } +} diff --git a/test/transpile/plugins/moduleResolution.ts b/test/transpile/plugins/moduleResolution.ts new file mode 100644 index 000000000..166626fbc --- /dev/null +++ b/test/transpile/plugins/moduleResolution.ts @@ -0,0 +1,14 @@ +import path = require("path"); +import type * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + moduleResolution(moduleIdentifier) { + const modulePath = moduleIdentifier.replace(/\./g, path.sep); + if (moduleIdentifier.includes("foo")) { + return modulePath.replace("foo", "bar"); + } + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; From 793e7f00566c34aba19281747133e6a77a7e6a4a Mon Sep 17 00:00:00 2001 From: Xirvin <103050557+ImXirvin@users.noreply.github.com> Date: Wed, 5 Jul 2023 06:31:57 +1000 Subject: [PATCH 601/764] Add "5.4" to luaTarget tsconfig description (#1462) --- tsconfig-schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 7af154fc0..5af971b49 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -50,7 +50,7 @@ "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "JIT"] + "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "JIT"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", From c981124aa13480888f3cf044e40294585d641a59 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 5 Jul 2023 20:19:05 +0200 Subject: [PATCH 602/764] Fix synthetic transformer nodes throwing on getChildren when transforming a switch statement (#1465) --- src/transformation/visitors/switch.ts | 12 +++++++++--- .../transformers/transformers.spec.ts | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 04323bdbf..2ceaedb39 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -9,10 +9,16 @@ const containsBreakOrReturn = (nodes: Iterable): boolean => { for (const s of nodes) { if (ts.isBreakStatement(s) || ts.isReturnStatement(s)) { return true; - } else if (ts.isBlock(s) && containsBreakOrReturn(s.getChildren())) { - return true; - } else if (s.kind === ts.SyntaxKind.SyntaxList && containsBreakOrReturn(s.getChildren())) { + } else if (ts.isBlock(s) && containsBreakOrReturn(s.statements)) { return true; + } else if (s.kind === ts.SyntaxKind.SyntaxList) { + // We cannot use getChildren() because that breaks when using synthetic nodes from transformers + // So get children the long way + const children: ts.Node[] = []; + ts.forEachChild(s, c => children.push(c)); + if (containsBreakOrReturn(children)) { + return true; + } } } diff --git a/test/transpile/transformers/transformers.spec.ts b/test/transpile/transformers/transformers.spec.ts index 02290d9d1..34dd9dc15 100644 --- a/test/transpile/transformers/transformers.spec.ts +++ b/test/transpile/transformers/transformers.spec.ts @@ -35,3 +35,22 @@ describe("factory types", () => { .expectToEqual(true); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1464 +test("transformer with switch does not break (#1464)", () => { + util.testFunction` + const foo: number = 3; + switch (foo) { + case 2: { + return 10; + } + case 3: { + return false; + } + } + ` + .setOptions({ + plugins: [{ transform: path.join(__dirname, "fixtures.ts"), import: "program", value: true }], + }) + .expectToEqual(true); +}); From ff310f1c29872659057fcc14d996c18f281d3abb Mon Sep 17 00:00:00 2001 From: Perryvw Date: Wed, 5 Jul 2023 20:29:49 +0200 Subject: [PATCH 603/764] 1.16.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 733d5c39a..4a988553f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.16.2", + "version": "1.16.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.16.2", + "version": "1.16.3", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 49fd83c97..9dbdf8650 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.16.2", + "version": "1.16.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 13e2856606aa5478a0d7756667885d23c330dc07 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Sun, 30 Jul 2023 17:05:18 +0200 Subject: [PATCH 604/764] Lua table is empty (#1470) * Modified methodExtensionKinds to be auto generated from string enum as it can be easily forgotten to add new extensions here. * LuaTableIsEmpty language extensions Added LuaTableIsEmpty & LuaTableIsEmptyMethod and added an isEmpty method to LuaTable, LuaMap & LuaSet Refactored existing tests a bit. Usage of extensions inside expressions is now tested in a single suite. --- language-extensions/index.d.ts | 19 +++ .../utils/language-extensions.ts | 30 +---- .../visitors/language-extensions/table.ts | 23 ++++ test/unit/language-extensions/table.spec.ts | 115 ++++++++++++------ 4 files changed, 128 insertions(+), 59 deletions(-) diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 07b5cb335..1442e5aa3 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -562,6 +562,20 @@ declare type LuaTableDelete = ( declare type LuaTableDeleteMethod = ((key: TKey) => boolean) & LuaExtension<"TableDeleteMethod">; +/** + * Calls to functions with this type are translated to `next(myTable) == nil`. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + * + * @param TTable The type to access as a Lua table. + */ +declare type LuaTableIsEmpty = ((table: TTable) => boolean) & LuaExtension<"TableIsEmpty">; + +/** + * Calls to methods with this type are translated to `next(myTable) == nil`, where `table` is the object with the method. + * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions + */ +declare type LuaTableIsEmptyMethod = (() => boolean) & LuaExtension<"TableIsEmptyMethod">; + /** * A convenience type for working directly with a Lua table. * For more information see: https://typescripttolua.github.io/docs/advanced/language-extensions @@ -575,6 +589,7 @@ declare interface LuaTable ext set: LuaTableSetMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -612,6 +627,7 @@ declare interface LuaMap extends LuaPa set: LuaTableSetMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -633,6 +649,7 @@ declare const LuaMap: (new () => LuaMa declare interface ReadonlyLuaMap extends LuaPairsIterable { get: LuaTableGetMethod; has: LuaTableHasMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -645,6 +662,7 @@ declare interface LuaSet extends LuaPairsKeyIte add: LuaTableAddKeyMethod; has: LuaTableHasMethod; delete: LuaTableDeleteMethod; + isEmpty: LuaTableIsEmptyMethod; } /** @@ -662,6 +680,7 @@ declare const LuaSet: (new () => LuaSet) & L */ declare interface ReadonlyLuaSet extends LuaPairsKeyIterable { has: LuaTableHasMethod; + isEmpty: LuaTableIsEmptyMethod; } interface ObjectConstructor { diff --git a/src/transformation/utils/language-extensions.ts b/src/transformation/utils/language-extensions.ts index 108c6eef1..6da38837a 100644 --- a/src/transformation/utils/language-extensions.ts +++ b/src/transformation/utils/language-extensions.ts @@ -53,6 +53,8 @@ export enum ExtensionKind { TableSetMethodType = "TableSetMethod", TableAddKeyType = "TableAddKey", TableAddKeyMethodType = "TableAddKeyMethod", + TableIsEmptyType = "TableIsEmpty", + TableIsEmptyMethodType = "TableIsEmptyMethod", } const extensionValues: Set = new Set(Object.values(ExtensionKind)); @@ -122,31 +124,9 @@ export function getIterableExtensionKindForNode( return getIterableExtensionTypeForType(context, type); } -export const methodExtensionKinds: ReadonlySet = new Set([ - ExtensionKind.AdditionOperatorMethodType, - ExtensionKind.SubtractionOperatorMethodType, - ExtensionKind.MultiplicationOperatorMethodType, - ExtensionKind.DivisionOperatorMethodType, - ExtensionKind.ModuloOperatorMethodType, - ExtensionKind.PowerOperatorMethodType, - ExtensionKind.FloorDivisionOperatorMethodType, - ExtensionKind.BitwiseAndOperatorMethodType, - ExtensionKind.BitwiseOrOperatorMethodType, - ExtensionKind.BitwiseExclusiveOrOperatorMethodType, - ExtensionKind.BitwiseLeftShiftOperatorMethodType, - ExtensionKind.BitwiseRightShiftOperatorMethodType, - ExtensionKind.ConcatOperatorMethodType, - ExtensionKind.LessThanOperatorMethodType, - ExtensionKind.GreaterThanOperatorMethodType, - ExtensionKind.NegationOperatorMethodType, - ExtensionKind.BitwiseNotOperatorMethodType, - ExtensionKind.LengthOperatorMethodType, - ExtensionKind.TableDeleteMethodType, - ExtensionKind.TableGetMethodType, - ExtensionKind.TableHasMethodType, - ExtensionKind.TableSetMethodType, - ExtensionKind.TableAddKeyMethodType, -]); +export const methodExtensionKinds: ReadonlySet = new Set( + Object.values(ExtensionKind).filter(key => key.endsWith("Method")) +); export function getNaryCallExtensionArgs( context: TransformationContext, diff --git a/src/transformation/visitors/language-extensions/table.ts b/src/transformation/visitors/language-extensions/table.ts index d3aaedc5d..e42e3f8c7 100644 --- a/src/transformation/visitors/language-extensions/table.ts +++ b/src/transformation/visitors/language-extensions/table.ts @@ -6,6 +6,7 @@ import { getBinaryCallExtensionArgs, getExtensionKindForNode, getNaryCallExtensionArgs, + getUnaryCallExtensionArg, } from "../../utils/language-extensions"; import { transformOrderedExpressions } from "../expression-list"; import { LanguageExtensionCallTransformerMap } from "./call-extension"; @@ -27,6 +28,8 @@ export const tableExtensionTransformers: LanguageExtensionCallTransformerMap = { [ExtensionKind.TableSetMethodType]: transformTableSetExpression, [ExtensionKind.TableAddKeyType]: transformTableAddKeyExpression, [ExtensionKind.TableAddKeyMethodType]: transformTableAddKeyExpression, + [ExtensionKind.TableIsEmptyType]: transformTableIsEmptyExpression, + [ExtensionKind.TableIsEmptyMethodType]: transformTableIsEmptyExpression, }; function transformTableDeleteExpression( @@ -120,3 +123,23 @@ function transformTableAddKeyExpression( ); return lua.createNilLiteral(); } + +function transformTableIsEmptyExpression( + context: TransformationContext, + node: ts.CallExpression, + extensionKind: ExtensionKind +): lua.Expression { + const args = getUnaryCallExtensionArg(context, node, extensionKind); + if (!args) { + return lua.createNilLiteral(); + } + + const table = context.transformExpression(args); + // next(arg0) == nil + return lua.createBinaryExpression( + lua.createCallExpression(lua.createIdentifier("next"), [table], node), + lua.createNilLiteral(), + lua.SyntaxKind.EqualityOperator, + node + ); +} diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index b833de22b..40e46d61e 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -221,7 +221,7 @@ describe("LuaTableDelete extension", () => { .expectToEqual({ table: { baz: "baz" } }); }); - test("LuaTableHasMethod method", () => { + test("LuaTableDeleteMethod method", () => { util.testModule` interface TableWithDelete { delete: LuaTableDeleteMethod; @@ -235,33 +235,6 @@ describe("LuaTableDelete extension", () => { .withLanguageExtensions() .expectToEqual({ table: { bar: 12 } }); }); - - test.each([ - ["LuaTableDelete<{}, string>", 'func({}, "foo")', true], - ["LuaTableDelete<{}, string>", '"truthy" && func({}, "foo")', true], - ["LuaTableSet<{}, string, number>", 'func({}, "foo", 3)', undefined], - ])("Table functions used as expression", (funcType, expression, value) => { - util.testModule` - declare const func: ${funcType} - export const result = ${expression} - ` - .withLanguageExtensions() - .setReturnExport("result") - .expectToEqual(value); - }); - - test.each([ - ["LuaTableDeleteMethod", 'tbl.func("foo")', true], - ["LuaTableSetMethod", 'tbl.func("foo", 3)', undefined], - ])("Table methods used as expression", (funcType, expression, value) => { - util.testModule` - const tbl = {} as { func: ${funcType} } - export const result = ${expression} - ` - .withLanguageExtensions() - .setReturnExport("result") - .expectToEqual(value); - }); }); describe("LuaTableAddKey extension", () => { @@ -298,11 +271,67 @@ describe("LuaTableAddKey extension", () => { .withLanguageExtensions() .expectToEqual({ table: { bar: true } }); }); +}); + +describe("LuaIsEmpty extension", () => { + test("LuaIsEmpty standalone function", () => { + util.testModule` + declare const isTableEmpty: LuaTableIsEmpty<{}>; + + const table = { foo: "bar", baz: "baz" }; + const emptyTable = {}; + + export const result = [isTableEmpty(table), isTableEmpty(emptyTable)]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); + + test("LuaIsEmpty namespace function", () => { + util.testModule` + declare namespace Table { + export const isTableEmpty: LuaTableIsEmpty<{}>; + } + + const table = { foo: "bar", baz: "baz" }; + const emptyTable = {}; + + export const result = [Table.isTableEmpty(table), Table.isTableEmpty(emptyTable)]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); + test("LuaTableIsEmptyMethod method", () => { + util.testModule` + interface TableWithIsEmpty { + isEmpty: LuaTableIsEmptyMethod; + set: LuaTableSetMethod; + } + const table = {} as TableWithIsEmpty; + table.set("foo", 42); + table.set("bar", 12); + + const emptyTable = {} as TableWithIsEmpty; + + export const result = [table.isEmpty(), emptyTable.isEmpty()]; + ` + .withLanguageExtensions() + .expectToEqual({ result: [false, true] }); + }); +}); + +describe("Table extensions use as expression", () => { test.each([ ["LuaTableAddKey<{}, string>", 'func({}, "foo")', undefined], ["LuaTableAddKey<{}, string>", '"truthy" && func({}, "foo")', undefined], - ])("Table functions used as expression", (funcType, expression, value) => { + ["LuaTableDelete<{}, string>", 'func({}, "foo")', true], + ["LuaTableDelete<{}, string>", '"truthy" && func({}, "foo")', true], + ["LuaTableSet<{}, string, number>", 'func({}, "foo", 3)', undefined], + ["LuaTableIsEmpty<{}>", "func({})", true], + ["LuaTableIsEmpty<{}>", 'func({ foo: "bar", baz: "baz" })', false], + ["LuaTableIsEmpty<{}>", '"truthy" && func({})', true], + ])("functions used as expression", (funcType, expression, value) => { util.testModule` declare const func: ${funcType} export const result = ${expression} @@ -312,14 +341,19 @@ describe("LuaTableAddKey extension", () => { .expectToEqual(value); }); - test("Method used as expression", () => { + test.each([ + ["LuaTableDeleteMethod", 'tbl.func("foo")', true], + ["LuaTableSetMethod", 'tbl.func("foo", 3)', undefined], + ["LuaTableAddKeyMethod", 'tbl.func("foo")', undefined], + ["LuaTableIsEmpty<{}>", "tbl.func({})", true], + ])("methods used as expression", (funcType, expression, value) => { util.testModule` - const tbl = {} as { func: LuaTableAddKeyMethod } - export const result = tbl.func("foo") + const tbl = {} as { func: ${funcType} } + export const result = ${expression} ` .withLanguageExtensions() .setReturnExport("result") - .expectToEqual(undefined); + .expectToEqual(value); }); }); @@ -415,9 +449,22 @@ describe("LuaTable extension interface", () => { .expectToEqual({ baz: 5 }); }); + test("table isEmpty", () => { + util.testFunction` + const tbl = new LuaTable(); + tbl.set("foo", 1); + + const emptyTbl = new LuaTable(); + + return [tbl.isEmpty(), emptyTbl.isEmpty()]; + ` + .withLanguageExtensions() + .expectToEqual([false, true]); + }); + test("table add", () => { util.testFunction` - const tbl = new LuaSet() + const tbl = new LuaSet(); tbl.add("foo"); return tbl ` From ef97e819f959518f4d665ba011022d639b360e07 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 1 Aug 2023 22:18:56 +0200 Subject: [PATCH 605/764] CHANGELOG 1.17.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9da99a0..a8b812b66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.17.0 + +- Added the `moduleResolution` plugin, allowing you to provide custom module resolution logic. See [the docs](https://typescripttolua.github.io/docs/api/plugins#moduleresolution) for more info. +- Added `isEmpty` to `LuaTable`, `LuaMap` and `LuaSet` (and their read-only counterparts). This simply to `next(tbl) == nil`, allowing for a simple check to see if a table is empty or not. +- Fixed a bug with synthetic nodes (e.g. created by custom TypeScript transformers) throwing an exception. +- Fixed unnecessary extra unpacking of tables +- Fixed some bugs with new decorators + ## 1.16.0 - Upgraded TypeScript to 5.1.3. From abd6b35a05b13cdddc5b33004262e26a8668ce33 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 1 Aug 2023 22:27:42 +0200 Subject: [PATCH 606/764] 1.17.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4a988553f..3de90ea42 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.16.3", + "version": "1.17.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.16.3", + "version": "1.17.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 9dbdf8650..bd1c5ebd4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.16.3", + "version": "1.17.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From be032ce0f827fa7a716151fe0d5a652333b36f90 Mon Sep 17 00:00:00 2001 From: Noah <37805707+Curve@users.noreply.github.com> Date: Thu, 24 Aug 2023 18:45:24 +0200 Subject: [PATCH 607/764] Add support for Glob-Patterns in "noResolvePaths" (#1475) * Add support for Glob-Patterns in "noResolvePaths" * Add Tests for Glob noResolvePaths --- package.json | 2 + src/transpilation/resolve.ts | 11 +++-- test/transpile/module-resolution.spec.ts | 59 ++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index bd1c5ebd4..0463fb57e 100644 --- a/package.json +++ b/package.json @@ -47,10 +47,12 @@ "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", + "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" }, "devDependencies": { + "@types/picomatch": "^2.3.0", "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", "@types/jest": "^27.5.2", diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 5768714a8..803efb99a 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -10,11 +10,12 @@ import { couldNotReadDependency, couldNotResolveRequire } from "./diagnostics"; import { BuildMode, CompilerOptions } from "../CompilerOptions"; import { findLuaRequires, LuaRequire } from "./find-lua-requires"; import { Plugin } from "./plugins"; +import * as picomatch from "picomatch"; const resolver = resolve.ResolverFactory.createResolver({ extensions: [".lua"], enforceExtension: true, // Resolved file must be a lua file - fileSystem: { ...new resolve.CachedInputFileSystem(fs) }, + fileSystem: { ...new resolve.CachedInputFileSystem(fs, 0) }, useSyncFileSystemCalls: true, conditionNames: ["require", "node", "tstl", "default"], symlinks: false, // Do not resolve symlinks to their original paths (that breaks node_modules detection) @@ -26,7 +27,7 @@ interface ResolutionResult { } class ResolutionContext { - private noResolvePaths: Set; + private noResolvePaths: picomatch.Matcher[]; public diagnostics: ts.Diagnostic[] = []; public resolvedFiles = new Map(); @@ -37,7 +38,9 @@ class ResolutionContext { private readonly emitHost: EmitHost, private readonly plugins: Plugin[] ) { - this.noResolvePaths = new Set(options.noResolvePaths); + const unique = [...new Set(options.noResolvePaths)]; + const matchers = unique.map(x => picomatch(x)); + this.noResolvePaths = matchers; } public addAndResolveDependencies(file: ProcessedFile): void { @@ -70,7 +73,7 @@ class ResolutionContext { return; } - if (this.noResolvePaths.has(required.requirePath)) { + if (this.noResolvePaths.find(isMatch => isMatch(required.requirePath))) { if (this.options.tstlVerbose) { console.log( `Skipping module resolution of ${required.requirePath} as it is in the tsconfig noResolvePaths.` diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index c2de18933..e97b4a146 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -441,6 +441,65 @@ describe("module resolution should not try to resolve modules in noResolvePaths" .setOptions({ noResolvePaths: ["a.b.c.foo", "somethingExtra", "dontResolveThis"] }) .expectToHaveNoDiagnostics(); }); + + test("can ignore specific files with glob pattern", () => { + util.testModule` + // Pre-Load as to not error out at runtime + import "preload"; + + import "ignoreme"; + import * as b from "./actualfile"; + + export const result = b.foo(); + ` + .addExtraFile("preload.lua", 'package.preload["ignoreme"] = function() return nil end') + .addExtraFile( + "actualfile.ts", + `export function foo() + { + return 'foo'; + }` + ) + .addExtraFile( + "ignoreme.d.ts", + `declare module "ignoreme" { + export function foo(): void; + }` + ) + .setOptions({ noResolvePaths: ["ignore*"] }) + .expectToHaveNoDiagnostics() + .expectToEqual({ result: "foo" }); + }); + + test("can ignore all files with glob pattern in require", () => { + util.testModule` + declare function require(this: void, module: string): any; + + const a = require("a") + const b = require("b/b") + const c = require("c/c/c") + const d = require("!:?somefile") + ` + .setOptions({ noResolvePaths: ["**"] }) + .expectToHaveNoDiagnostics(); + }); + + test("can ignore all files with glob pattern as used in imported lua sources", () => { + util.testModule` + import * as lua from "./luasource"; + lua.foo(); + ` + .addExtraFile("luasource.d.ts", "export function foo(): void;") + .addExtraFile( + "luasource.lua", + ` + require("ignoreme!") + require("i.g.n.o.r.e") + ` + ) + .setOptions({ noResolvePaths: ["**"] }) + .expectToHaveNoDiagnostics(); + }); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1062 From 6c0f8e4e1621ef36f82e465645740bc68f0be837 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 24 Aug 2023 20:34:27 +0200 Subject: [PATCH 608/764] Upgrade TypeScript to 5.2 (#1476) --- package-lock.json | 554 +++++++++++------------ package.json | 12 +- test/transpile/module-resolution.spec.ts | 7 +- 3 files changed, 287 insertions(+), 286 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3de90ea42..aaecb4f33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", "enhanced-resolve": "^5.8.2", + "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" }, @@ -22,10 +23,11 @@ "@types/glob": "^7.1.1", "@types/jest": "^27.5.2", "@types/node": "^13.7.7", + "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.55.0", - "@typescript-eslint/parser": "^5.55.0", - "eslint": "^8.36.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.47.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", @@ -37,13 +39,22 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "~5.1.3" + "typescript": "^5.2.2" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~5.1.3" + "typescript": "5.2.2" + } + }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, "node_modules/@ampproject/remapping": { @@ -111,9 +122,9 @@ } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -167,9 +178,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -690,23 +701,23 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", - "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", + "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", - "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -722,18 +733,18 @@ } }, "node_modules/@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", @@ -1444,6 +1455,12 @@ "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "dev": true }, + "node_modules/@types/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g==", + "dev": true + }, "node_modules/@types/prettier": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", @@ -1487,17 +1504,17 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", - "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/type-utils": "5.55.0", - "@typescript-eslint/utils": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -1521,14 +1538,14 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", - "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" }, "engines": { @@ -1548,13 +1565,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", - "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1565,13 +1582,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", - "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "5.55.0", - "@typescript-eslint/utils": "5.55.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" }, @@ -1592,9 +1609,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", - "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1605,13 +1622,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", - "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1632,17 +1649,17 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", - "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" }, @@ -1658,12 +1675,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", - "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1680,9 +1697,9 @@ "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" }, "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -2483,27 +2500,27 @@ } }, "node_modules/eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2511,22 +2528,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -2636,9 +2650,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2682,18 +2696,21 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -2701,6 +2718,9 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint/node_modules/estraverse": { @@ -2713,14 +2733,14 @@ } }, "node_modules/espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -2928,9 +2948,9 @@ "dev": true }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -3221,9 +3241,9 @@ } }, "node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3287,10 +3307,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "node_modules/has": { @@ -3774,9 +3794,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -4716,16 +4736,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -4900,9 +4910,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -5110,17 +5120,17 @@ } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -5246,7 +5256,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -5585,9 +5594,9 @@ } }, "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6090,9 +6099,9 @@ } }, "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6241,15 +6250,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", @@ -6351,6 +6351,12 @@ } }, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@ampproject/remapping": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", @@ -6400,9 +6406,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -6445,9 +6451,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -6841,20 +6847,20 @@ } }, "@eslint-community/regexpp": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz", - "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==", + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", + "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.1.tgz", - "integrity": "sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", + "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.0", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -6864,15 +6870,15 @@ } }, "@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", + "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -7467,6 +7473,12 @@ "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", "dev": true }, + "@types/picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g==", + "dev": true + }, "@types/prettier": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", @@ -7510,17 +7522,17 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.55.0.tgz", - "integrity": "sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", + "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, "requires": { "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/type-utils": "5.55.0", - "@typescript-eslint/utils": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/type-utils": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", "natural-compare-lite": "^1.4.0", "semver": "^7.3.7", @@ -7528,53 +7540,53 @@ } }, "@typescript-eslint/parser": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.55.0.tgz", - "integrity": "sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", + "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.55.0.tgz", - "integrity": "sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", + "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", "dev": true, "requires": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0" } }, "@typescript-eslint/type-utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.55.0.tgz", - "integrity": "sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, "requires": { - "@typescript-eslint/typescript-estree": "5.55.0", - "@typescript-eslint/utils": "5.55.0", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.55.0.tgz", - "integrity": "sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.55.0.tgz", - "integrity": "sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dev": true, "requires": { - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/visitor-keys": "5.55.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -7583,28 +7595,28 @@ } }, "@typescript-eslint/utils": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.55.0.tgz", - "integrity": "sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", + "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@types/json-schema": "^7.0.9", "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.55.0", - "@typescript-eslint/types": "5.55.0", - "@typescript-eslint/typescript-estree": "5.55.0", + "@typescript-eslint/scope-manager": "5.62.0", + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/typescript-estree": "5.62.0", "eslint-scope": "^5.1.1", "semver": "^7.3.7" } }, "@typescript-eslint/visitor-keys": { - "version": "5.55.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.55.0.tgz", - "integrity": "sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==", + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", + "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.55.0", + "@typescript-eslint/types": "5.62.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -7614,9 +7626,9 @@ "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" }, "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -8195,27 +8207,27 @@ "dev": true }, "eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.47.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", + "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "^8.47.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -8223,29 +8235,26 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -8344,9 +8353,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -8371,20 +8380,20 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" } }, "esprima": { @@ -8537,9 +8546,9 @@ "dev": true }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", + "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -8759,9 +8768,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.21.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", + "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -8804,10 +8813,10 @@ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, "has": { @@ -9135,9 +9144,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -9866,12 +9875,6 @@ } } }, - "js-sdsl": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", - "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", - "dev": true - }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -10010,9 +10013,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -10174,17 +10177,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -10270,8 +10273,7 @@ "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" }, "pirates": { "version": "4.0.5", @@ -10484,9 +10486,9 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -10840,9 +10842,9 @@ } }, "typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true }, "unbox-primitive": { @@ -10944,12 +10946,6 @@ "is-typed-array": "^1.1.10" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index 0463fb57e..6bac86c69 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "~5.1.3" + "typescript": "5.2.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", @@ -52,15 +52,15 @@ "source-map": "^0.7.3" }, "devDependencies": { - "@types/picomatch": "^2.3.0", "@types/fs-extra": "^8.1.0", "@types/glob": "^7.1.1", "@types/jest": "^27.5.2", "@types/node": "^13.7.7", + "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.55.0", - "@typescript-eslint/parser": "^5.55.0", - "eslint": "^8.36.0", + "@typescript-eslint/eslint-plugin": "^5.62.0", + "@typescript-eslint/parser": "^5.62.0", + "eslint": "^8.47.0", "eslint-plugin-import": "^2.27.5", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", @@ -72,6 +72,6 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "~5.1.3" + "typescript": "^5.2.2" } } diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index e97b4a146..e0b4429a6 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -304,7 +304,11 @@ describe("module resolution project with dependencies built by tstl library mode const transpileResult = util .testProject(path.join(projectPath, "tsconfig.json")) .setMainFileName(path.join(projectPath, "main.ts")) - .setOptions({ outDir: "tstl-out", moduleResolution: ts.ModuleResolutionKind.Node16 }) + .setOptions({ + outDir: "tstl-out", + moduleResolution: ts.ModuleResolutionKind.Node16, + module: ts.ModuleKind.Node16, + }) .expectToEqual(expectedResult) .getLuaResult(); @@ -323,6 +327,7 @@ describe("module resolution project with dependencies built by tstl library mode luaBundle: "bundle.lua", luaBundleEntry: mainFile, moduleResolution: ts.ModuleResolutionKind.Node16, + module: ts.ModuleKind.Node16, }) .expectToEqual(expectedResult); }); From 1dcf5da1d0b1a3e7527250d386367f436f172290 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 24 Aug 2023 20:35:46 +0200 Subject: [PATCH 609/764] CHANGELOG.md 1.18.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8b812b66..9976e4a75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.18.0 + +- Upgraded TypeScript to 5.2.2 +- The `noResolvePaths` option now accepts glob paths (for example, 'mydir/hello\*' to not resolve any files in mydir starting with hello). + - This also allows disabling module resolution completely by providing a '\*\*' pattern in your tsconfig.json `noResolvePaths`. + ## 1.17.0 - Added the `moduleResolution` plugin, allowing you to provide custom module resolution logic. See [the docs](https://typescripttolua.github.io/docs/api/plugins#moduleresolution) for more info. From 5d1d77e985302bbb0addf3ad80ee4665004543bd Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 24 Aug 2023 20:37:55 +0200 Subject: [PATCH 610/764] 1.18.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index aaecb4f33..e7ee9ea46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.17.0", + "version": "1.18.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.17.0", + "version": "1.18.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 6bac86c69..edd533fc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.17.0", + "version": "1.18.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 1d23427e1d617415cf6d90d10783d6269678f8c9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 29 Aug 2023 11:57:26 +0200 Subject: [PATCH 611/764] Implement copying array methods (#1480) * Implement copying array methods * Prettier --- src/LuaLib.ts | 4 +++ src/lualib/ArrayToReversed.ts | 5 +++ src/lualib/ArrayToSorted.ts | 5 +++ src/lualib/ArrayToSpliced.ts | 5 +++ src/lualib/ArrayWith.ts | 5 +++ src/transformation/builtins/array.ts | 8 +++++ test/unit/builtins/array.spec.ts | 50 ++++++++++++++++++++++++++++ 7 files changed, 82 insertions(+) create mode 100644 src/lualib/ArrayToReversed.ts create mode 100644 src/lualib/ArrayToSorted.ts create mode 100644 src/lualib/ArrayToSpliced.ts create mode 100644 src/lualib/ArrayWith.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 4bf86aa5c..ade163514 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -32,6 +32,10 @@ export enum LuaLibFeature { ArrayFlat = "ArrayFlat", ArrayFlatMap = "ArrayFlatMap", ArraySetLength = "ArraySetLength", + ArrayToReversed = "ArrayToReversed", + ArrayToSorted = "ArrayToSorted", + ArrayToSpliced = "ArrayToSpliced", + ArrayWith = "ArrayWith", Await = "Await", Class = "Class", ClassExtends = "ClassExtends", diff --git a/src/lualib/ArrayToReversed.ts b/src/lualib/ArrayToReversed.ts new file mode 100644 index 000000000..50b58855f --- /dev/null +++ b/src/lualib/ArrayToReversed.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToReversed(this: T[]): T[] { + const copy = [...this]; + copy.reverse(); + return copy; +} diff --git a/src/lualib/ArrayToSorted.ts b/src/lualib/ArrayToSorted.ts new file mode 100644 index 000000000..47c033d2d --- /dev/null +++ b/src/lualib/ArrayToSorted.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToSorted(this: T[], compareFn?: (a: T, b: T) => number): T[] { + const copy = [...this]; + copy.sort(compareFn); + return copy; +} diff --git a/src/lualib/ArrayToSpliced.ts b/src/lualib/ArrayToSpliced.ts new file mode 100644 index 000000000..298ed8035 --- /dev/null +++ b/src/lualib/ArrayToSpliced.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayToSpliced(this: T[], start: number, deleteCount: number, ...items: T[]): T[] { + const copy = [...this]; + copy.splice(start, deleteCount, ...items); + return copy; +} diff --git a/src/lualib/ArrayWith.ts b/src/lualib/ArrayWith.ts new file mode 100644 index 000000000..90d818a5a --- /dev/null +++ b/src/lualib/ArrayWith.ts @@ -0,0 +1,5 @@ +export function __TS__ArrayWith(this: T[], index: number, value: T): T[] { + const copy = [...this]; + copy[index] = value; + return copy; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 417a81e87..71dc042c8 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -184,6 +184,14 @@ export function transformArrayPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.ArrayFlat, node, caller, ...params); case "flatMap": return transformLuaLibFunction(context, LuaLibFeature.ArrayFlatMap, node, caller, ...params); + case "toReversed": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToReversed, node, caller, ...params); + case "toSorted": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToSorted, node, caller, ...params); + case "toSpliced": + return transformLuaLibFunction(context, LuaLibFeature.ArrayToSpliced, node, caller, ...params); + case "with": + return transformLuaLibFunction(context, LuaLibFeature.ArrayWith, node, caller, ...params); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "array", expressionName)); } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 98ba1b61d..4a70c6d6b 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -769,3 +769,53 @@ test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", v .setOptions({ strictNullChecks: true }) .expectToMatchJsResult(); }); + +describe("copying array methods", () => { + test("toReversed", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const reversed = original.toReversed(); + + return {original, reversed}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + reversed: [5, 4, 3, 2, 1], + }); + }); + + test("toSorted", () => { + util.testFunction` + const original = [5,2,1,4,3]; + const sorted = original.toSorted(); + + return {original, sorted}; + `.expectToEqual({ + original: [5, 2, 1, 4, 3], + sorted: [1, 2, 3, 4, 5], + }); + }); + + test("toSpliced", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const spliced = original.toSpliced(2, 2, 10, 11); + + return {original, spliced}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + spliced: [1, 2, 10, 11, 5], + }); + }); + + test("with", () => { + util.testFunction` + const original = [1,2,3,4,5]; + const updated = original.with(2, 10); + + return {original, updated}; + `.expectToEqual({ + original: [1, 2, 3, 4, 5], + updated: [1, 2, 10, 4, 5], + }); + }); +}); From 87dab530f95ba0dc9c6282db10d99d22dda2d54a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 31 Aug 2023 11:46:27 +0200 Subject: [PATCH 612/764] Add support for TS 5.2 using and await using keywords (#1479) * Support for using * Async await * Some renaming and comments --- src/LuaLib.ts | 2 + src/lualib/Symbol.ts | 2 + src/lualib/Using.ts | 22 +++ src/lualib/UsingAsync.ts | 27 +++ src/transformation/index.ts | 9 +- .../pre-transformers/using-transformer.ts | 128 +++++++++++++ src/transformation/visitors/function.ts | 10 +- .../visitors/variable-declaration.ts | 4 +- src/typescript-internal.d.ts | 2 + test/unit/using.spec.ts | 177 ++++++++++++++++++ 10 files changed, 379 insertions(+), 4 deletions(-) create mode 100644 src/lualib/Using.ts create mode 100644 src/lualib/UsingAsync.ts create mode 100644 src/transformation/pre-transformers/using-transformer.ts create mode 100644 test/unit/using.spec.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index ade163514..cb63087e8 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -110,6 +110,8 @@ export enum LuaLibFeature { SymbolRegistry = "SymbolRegistry", TypeOf = "TypeOf", Unpack = "Unpack", + Using = "Using", + UsingAsync = "UsingAsync", } export interface LuaLibFeatureInfo { diff --git a/src/lualib/Symbol.ts b/src/lualib/Symbol.ts index 9d16cae3a..5c1d7076b 100644 --- a/src/lualib/Symbol.ts +++ b/src/lualib/Symbol.ts @@ -9,6 +9,8 @@ export function __TS__Symbol(this: void, description?: string | number): symbol } export const Symbol = { + asyncDispose: __TS__Symbol("Symbol.asyncDispose"), + dispose: __TS__Symbol("Symbol.dispose"), iterator: __TS__Symbol("Symbol.iterator"), hasInstance: __TS__Symbol("Symbol.hasInstance"), diff --git a/src/lualib/Using.ts b/src/lualib/Using.ts new file mode 100644 index 000000000..c61d544eb --- /dev/null +++ b/src/lualib/Using.ts @@ -0,0 +1,22 @@ +export function __TS__Using( + this: undefined, + cb: (...args: TArgs) => TReturn, + ...args: TArgs +): TReturn { + let thrownError; + const [ok, result] = xpcall( + () => cb(...args), + err => (thrownError = err) + ); + + const argArray = [...args]; + for (let i = argArray.length - 1; i >= 0; i--) { + argArray[i][Symbol.dispose](); + } + + if (!ok) { + throw thrownError; + } + + return result; +} diff --git a/src/lualib/UsingAsync.ts b/src/lualib/UsingAsync.ts new file mode 100644 index 000000000..e4b7593f9 --- /dev/null +++ b/src/lualib/UsingAsync.ts @@ -0,0 +1,27 @@ +export async function __TS__UsingAsync, TReturn>( + this: undefined, + cb: (...args: TArgs) => TReturn, + ...args: TArgs +): Promise { + let thrownError; + const [ok, result] = xpcall( + () => cb(...args), + err => (thrownError = err) + ); + + const argArray = [...args]; + for (let i = argArray.length - 1; i >= 0; i--) { + if (Symbol.dispose in argArray[i]) { + (argArray[i] as Disposable)[Symbol.dispose](); + } + if (Symbol.asyncDispose in argArray[i]) { + await (argArray[i] as AsyncDisposable)[Symbol.asyncDispose](); + } + } + + if (!ok) { + throw thrownError; + } + + return result; +} diff --git a/src/transformation/index.ts b/src/transformation/index.ts index 4580a3b80..b9e1f6241 100644 --- a/src/transformation/index.ts +++ b/src/transformation/index.ts @@ -3,6 +3,7 @@ import * as lua from "../LuaAST"; import { getOrUpdate } from "../utils"; import { ObjectVisitor, TransformationContext, VisitorMap, Visitors } from "./context"; import { standardVisitors } from "./visitors"; +import { usingTransformer } from "./pre-transformers/using-transformer"; export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { const objectVisitorMap: Map>> = new Map(); @@ -32,7 +33,13 @@ export function createVisitorMap(customVisitors: Visitors[]): VisitorMap { export function transformSourceFile(program: ts.Program, sourceFile: ts.SourceFile, visitorMap: VisitorMap) { const context = new TransformationContext(program, sourceFile, visitorMap); - const [file] = context.transformNode(sourceFile) as [lua.File]; + + // TS -> TS pre-transformation + const preTransformers = [usingTransformer(context)]; + const result = ts.transform(sourceFile, preTransformers); + + // TS -> Lua transformation + const [file] = context.transformNode(result.transformed[0]) as [lua.File]; return { file, diagnostics: context.diagnostics }; } diff --git a/src/transformation/pre-transformers/using-transformer.ts b/src/transformation/pre-transformers/using-transformer.ts new file mode 100644 index 000000000..51908a40a --- /dev/null +++ b/src/transformation/pre-transformers/using-transformer.ts @@ -0,0 +1,128 @@ +import * as ts from "typescript"; +import { TransformationContext } from "../context"; +import { LuaLibFeature, importLuaLibFeature } from "../utils/lualib"; + +export function usingTransformer(context: TransformationContext): ts.TransformerFactory { + return ctx => sourceFile => { + function visit(node: ts.Node): ts.Node { + if (ts.isBlock(node)) { + const [hasUsings, newStatements] = transformBlockWithUsing(context, node.statements, node); + if (hasUsings) { + // Recurse visitor into updated block to find further usings + const updatedBlock = ts.factory.updateBlock(node, newStatements); + const result = ts.visitEachChild(updatedBlock, visit, ctx); + + // Set all the synthetic node parents to something that makes sense + const parent: ts.Node[] = [updatedBlock]; + function setParent(node2: ts.Node): ts.Node { + ts.setParent(node2, parent[parent.length - 1]); + parent.push(node2); + ts.visitEachChild(node2, setParent, ctx); + parent.push(); + return node2; + } + ts.visitEachChild(updatedBlock, setParent, ctx); + ts.setParent(updatedBlock, node.parent); + + return result; + } + } + return ts.visitEachChild(node, visit, ctx); + } + return ts.visitEachChild(sourceFile, visit, ctx); + }; +} + +function isUsingDeclarationList(node: ts.Node): node is ts.VariableStatement { + return ts.isVariableStatement(node) && (node.declarationList.flags & ts.NodeFlags.Using) !== 0; +} + +function transformBlockWithUsing( + context: TransformationContext, + statements: ts.NodeArray | ts.Statement[], + block: ts.Block +): [true, ts.Statement[]] | [false] { + const newStatements: ts.Statement[] = []; + + for (let i = 0; i < statements.length; i++) { + const statement = statements[i]; + if (isUsingDeclarationList(statement)) { + const isAwaitUsing = (statement.declarationList.flags & ts.NodeFlags.AwaitContext) !== 0; + + if (isAwaitUsing) { + importLuaLibFeature(context, LuaLibFeature.UsingAsync); + } else { + importLuaLibFeature(context, LuaLibFeature.Using); + } + + // Make declared using variables callback function parameters + const variableNames = statement.declarationList.declarations.map(d => + ts.factory.createParameterDeclaration(undefined, undefined, d.name) + ); + // Add this: void as first parameter + variableNames.unshift(createThisVoidParameter(context.checker)); + + // Put all following statements in the callback body + const followingStatements = statements.slice(i + 1); + const [followingHasUsings, replacedFollowingStatements] = transformBlockWithUsing( + context, + followingStatements, + block + ); + const callbackBody = ts.factory.createBlock( + followingHasUsings ? replacedFollowingStatements : followingStatements + ); + + const callback = ts.factory.createFunctionExpression( + undefined, + undefined, + undefined, + undefined, + variableNames, + undefined, + callbackBody + ); + + // Replace using variable list with call to lualib function with callback and followed by all variable initializers + const functionIdentifier = ts.factory.createIdentifier(isAwaitUsing ? "__TS__UsingAsync" : "__TS__Using"); + let call: ts.Expression = ts.factory.createCallExpression( + functionIdentifier, + [], + [ + callback, + ...statement.declarationList.declarations.map( + d => d.initializer ?? ts.factory.createIdentifier("unidentified") + ), + ] + ); + + // If this is an 'await using ...', add an await statement here + if (isAwaitUsing) { + call = ts.factory.createAwaitExpression(call); + } + + if (ts.isBlock(block.parent) && block.parent.statements[block.parent.statements.length - 1] !== block) { + // If this is a free-standing block in a function (not the last statement), dont return the value + newStatements.push(ts.factory.createExpressionStatement(call)); + } else { + newStatements.push(ts.factory.createReturnStatement(call)); + } + + return [true, newStatements]; + } else { + newStatements.push(statement); + } + } + return [false]; +} + +function createThisVoidParameter(checker: ts.TypeChecker) { + const voidType = checker.typeToTypeNode(checker.getVoidType(), undefined, undefined); + return ts.factory.createParameterDeclaration( + undefined, + undefined, + ts.factory.createIdentifier("this"), + undefined, + voidType + ); +} diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 6f101c5ac..506d4a6f1 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -227,7 +227,15 @@ export function transformFunctionToExpression( const type = context.checker.getTypeAtLocation(node); let functionContext: lua.Identifier | undefined; - if (getFunctionContextType(context, type) !== ContextType.Void) { + + const firstParam = node.parameters[0]; + const hasThisVoidParameter = + firstParam && + ts.isIdentifier(firstParam.name) && + ts.identifierToKeywordKind(firstParam.name) === ts.SyntaxKind.ThisKeyword && + firstParam.type?.kind === ts.SyntaxKind.VoidKeyword; + + if (!hasThisVoidParameter && getFunctionContextType(context, type) !== ContextType.Void) { if (ts.isArrowFunction(node)) { // dummy context for arrow functions with parameters if (node.parameters.length > 0) { diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 42a2b6538..082ef9a6b 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -282,8 +282,8 @@ export function transformVariableDeclaration( } export function checkVariableDeclarationList(context: TransformationContext, node: ts.VariableDeclarationList): void { - if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const)) === 0) { - const token = node.getFirstToken(); + if ((node.flags & (ts.NodeFlags.Let | ts.NodeFlags.Const | ts.NodeFlags.Using | ts.NodeFlags.AwaitUsing)) === 0) { + const token = ts.getOriginalNode(node).getFirstToken(); assert(token); context.diagnostics.push(unsupportedVarDeclaration(token)); } diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 253bcade8..684be1292 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -59,4 +59,6 @@ declare module "typescript" { export function pathIsAbsolute(path: string): boolean; export function pathIsRelative(path: string): boolean; + + export function setParent(child: T, parent: T["parent"] | undefined): T; } diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts new file mode 100644 index 000000000..c43120bd6 --- /dev/null +++ b/test/unit/using.spec.ts @@ -0,0 +1,177 @@ +import { LuaLibImportKind } from "../../src"; +import * as util from "../util"; + +const usingTestLib = ` + export const logs: string[] = []; + + function loggedDisposable(id: string): Disposable { + logs.push(\`Creating \${id}\`); + + return { + [Symbol.dispose]() { + logs.push(\`Disposing \${id}\`); + } + } + }`; + +test("using disposes object at end of function", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); +}); + +test("handles multi-variable declarations", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"), b = loggedDisposable("b"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"] }); +}); + +test("using disposes object at end of nested block", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + + { + using b = loggedDisposable("b"); + logs.push("nested block"); + } + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + logs: ["Creating a", "Creating b", "nested block", "Disposing b", "function content", "Disposing a"], + }); +}); + +test("using does not affect function return value", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + logs.push("function content"); + + return "success"; + } + + export const result = func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + result: "success", + logs: ["Creating a", "Creating b", "function content", "Disposing b", "Disposing a"], + }); +}); + +test("using disposes even when error happens", () => { + util.testModule` + function func() { + using a = loggedDisposable("a"); + using b = loggedDisposable("b"); + + throw "test-induced exception"; + } + + try + { + func(); + } + catch (e) + { + logs.push(\`caught exception: \${e}\`); + } + ` + .setTsHeader(usingTestLib) + .expectToEqual({ + logs: [ + "Creating a", + "Creating b", + "Disposing b", + "Disposing a", + "caught exception: test-induced exception", + ], + }); +}); + +test("await using disposes object with await at end of function", () => { + util.testModule` + let disposeAsync; + + function loggedAsyncDisposable(id: string): AsyncDisposable { + logs.push(\`Creating \${id}\`); + + return { + [Symbol.asyncDispose]() { + logs.push(\`Disposing async \${id}\`); + return new Promise(resolve => { + disposeAsync = () => { + logs.push(\`Disposed \${id}\`); + resolve(); + }; + }); + } + } + } + + async function func() { + await using a = loggedAsyncDisposable("a"); + + logs.push("function content"); + return "function result"; + } + + const p = func().then(r => logs.push("promise resolved", r)); + + logs.push("function returned"); + + disposeAsync(); + ` + .setTsHeader(usingTestLib) + .setOptions({ luaLibImport: LuaLibImportKind.Inline }) + .expectToEqual({ + logs: [ + "Creating a", + "function content", + "Disposing async a", + "function returned", + "Disposed a", + "promise resolved", + "function result", + ], + }); +}); + +test("await using can handle non-async disposables", () => { + util.testModule` + async function func() { + await using a = loggedDisposable("a"); + + logs.push("function content"); + } + + func(); + ` + .setTsHeader(usingTestLib) + .expectToEqual({ logs: ["Creating a", "function content", "Disposing a"] }); +}); From 01c2cb65294e3ece348d123241ba0cc296e7c80a Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 31 Aug 2023 13:47:36 +0200 Subject: [PATCH 613/764] CHANGELOG.md 1.19.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9976e4a75..396a16896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.19.0 + +- Added support for the new TypeScript 5.2 `using` keyword for explicit resource management. See the [TypeScript release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management) for more information. +- Added support for the newly introduced 'copying array methods' `toReversed`, `toSorted`, `toSpliced` and `with`. These were also introduced in TypeScript 5.2, see [their release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#copying-array-methods) for more information. + ## 1.18.0 - Upgraded TypeScript to 5.2.2 From 8af8f253a48fe092f166bd6b98e61de994d4578f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 31 Aug 2023 15:14:57 +0200 Subject: [PATCH 614/764] 1.19.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7ee9ea46..effa9ed6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.18.0", + "version": "1.19.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.18.0", + "version": "1.19.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index edd533fc3..8cda09ba3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.18.0", + "version": "1.19.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From a2798eb55f1180e27984c010d9da15c26a5fb211 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 7 Sep 2023 21:42:34 +0200 Subject: [PATCH 615/764] Bump language extensions version --- language-extensions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/language-extensions/package.json b/language-extensions/package.json index 0772d6541..194ab1212 100644 --- a/language-extensions/package.json +++ b/language-extensions/package.json @@ -1,6 +1,6 @@ { "name": "@typescript-to-lua/language-extensions", - "version": "1.0.0", + "version": "1.19.0", "description": "Language extensions used by typescript-to-lua", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5e07eb8579da1cca16ef1d250f83c90a5289da5c Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 8 Sep 2023 20:46:46 +0200 Subject: [PATCH 616/764] Bump tstl language-extension dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8cda09ba3..27b203ab2 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "typescript": "5.2.2" }, "dependencies": { - "@typescript-to-lua/language-extensions": "1.0.0", + "@typescript-to-lua/language-extensions": "1.19.0", "enhanced-resolve": "^5.8.2", "picomatch": "^2.3.1", "resolve": "^1.15.1", From 32e0daf9ad0c84819be89ba1cd9d2d7267bfc1cd Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 8 Sep 2023 21:13:25 +0200 Subject: [PATCH 617/764] 1.19.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index effa9ed6e..a5ce9800c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.19.0", + "version": "1.19.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.19.0", + "version": "1.19.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 27b203ab2..3eaac5007 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.19.0", + "version": "1.19.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From cf79978a00c0f9b99ff22dad396f7a7c5d601328 Mon Sep 17 00:00:00 2001 From: Lorenz Junglas Date: Tue, 12 Sep 2023 20:58:21 +0200 Subject: [PATCH 618/764] Add Array.at(index) to lualib (#1484) --- src/LuaLib.ts | 1 + src/lualib/ArrayAt.ts | 13 ++++++++++++ src/transformation/builtins/array.ts | 2 ++ test/unit/builtins/array.spec.ts | 30 ++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 src/lualib/ArrayAt.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index cb63087e8..151309ea9 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -5,6 +5,7 @@ import { LuaTarget } from "./CompilerOptions"; import { getOrUpdate } from "./utils"; export enum LuaLibFeature { + ArrayAt = "ArrayAt", ArrayConcat = "ArrayConcat", ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", diff --git a/src/lualib/ArrayAt.ts b/src/lualib/ArrayAt.ts new file mode 100644 index 000000000..32e4ea2b4 --- /dev/null +++ b/src/lualib/ArrayAt.ts @@ -0,0 +1,13 @@ +// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.at +// Technically the specs also allow non-numeric types to be passed as index. +// However, TypeScript types the `Array.at` index param as number so we also expect only numbers +// This behaviour also matches the implementation of other Array functions in lualib. +export function __TS__ArrayAt(this: T[], relativeIndex: number): T | undefined { + const absoluteIndex = relativeIndex < 0 ? this.length + relativeIndex : relativeIndex; + + if (absoluteIndex >= 0 && absoluteIndex < this.length) { + return this[absoluteIndex]; + } + + return undefined; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 71dc042c8..53dbc653d 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -88,6 +88,8 @@ export function transformArrayPrototypeCall( const expressionName = calledMethod.name.text; switch (expressionName) { + case "at": + return transformLuaLibFunction(context, LuaLibFeature.ArrayAt, node, caller, ...params); case "concat": return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); case "entries": diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 4a70c6d6b..05d499395 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -272,6 +272,36 @@ test("tuple.forEach", () => { `.expectToMatchJsResult(); }); +describe("at", () => { + test("valid index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(2); + `.expectToMatchJsResult(); + }); + + test("invalid index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(10); + `.expectToMatchJsResult(); + }); + + test("valid negative index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(-2); + `.expectToMatchJsResult(); + }); + + test("invalid negative index", () => { + util.testFunction` + const array = [1, 2, 3, 4]; + return array.at(-10); + `.expectToMatchJsResult(); + }); +}); + test("array.forEach (%p)", () => { util.testFunction` const array = [0, 1, 2, 3]; From f03498456b5b8e59fdeb6091becfed92e1522794 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 12 Sep 2023 21:58:15 +0200 Subject: [PATCH 619/764] 1.19.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a5ce9800c..6cf89b419 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.19.1", + "version": "1.19.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.19.1", + "version": "1.19.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 3eaac5007..1b8f0de1d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.19.1", + "version": "1.19.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From df3adb795c23d259d2380699ea136e6fb5d04df8 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 23 Sep 2023 17:47:27 +0200 Subject: [PATCH 620/764] Do not cause unrelated exception when throwing Error object in environment without debug module (#1488) --- src/lualib/Error.ts | 7 +++++-- test/unit/error.spec.ts | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index fa1fa0bc0..ea9cba478 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -3,7 +3,10 @@ interface ErrorType { new (...args: any[]): Error; } -function getErrorStack(constructor: () => any): string { +function getErrorStack(constructor: () => any): string | undefined { + // If debug module is not available in this environment, don't bother trying to get stack trace + if (debug === undefined) return undefined; + let level = 1; while (true) { const info = debug.getinfo(level, "f"); @@ -49,7 +52,7 @@ function initErrorClass(Type: ErrorType, name: string): any { export const Error: ErrorConstructor = initErrorClass( class implements Error { public name = "Error"; - public stack: string; + public stack?: string; constructor(public message = "") { this.stack = getErrorStack((this.constructor as any).new); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 705ee77f0..388fee290 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -324,3 +324,22 @@ test.each([...builtinErrors, "CustomError"])("get stack from %s", errorType => { expect(stack).toMatch("innerFunction"); expect(stack).toMatch("outerFunction"); }); + +test("still works without debug module", () => { + util.testFunction` + try + { + throw new Error("hello, world"); + } + catch (e) + { + return e; + } + ` + .setLuaHeader("debug = nil") + .expectToEqual({ + message: "hello, world", + name: "Error", + stack: undefined, + }); +}); From 79f8d1b67bceb5de819bad08268c7ed9c7bdd976 Mon Sep 17 00:00:00 2001 From: Zerio Date: Sun, 24 Sep 2023 16:30:15 +0200 Subject: [PATCH 621/764] Add Number.parseInt + Number.parseFloat (#1491) * Add Number.parseInt + Number.parseFloat * Add test cases --- src/LuaLib.ts | 2 + src/transformation/builtins/number.ts | 4 ++ test/unit/builtins/numbers.spec.ts | 69 ++++++++++++++++++++------- 3 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 151309ea9..1e5332caa 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -63,6 +63,8 @@ export enum LuaLibFeature { Number = "Number", NumberIsFinite = "NumberIsFinite", NumberIsNaN = "NumberIsNaN", + NumberParseInt = "ParseInt", + NumberParseFloat = "ParseFloat", NumberToString = "NumberToString", NumberToFixed = "NumberToFixed", ObjectAssign = "ObjectAssign", diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index a5e7d4a1a..c8ca98503 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -39,6 +39,10 @@ export function transformNumberConstructorCall( return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, node, ...parameters); case "isFinite": return transformLuaLibFunction(context, LuaLibFeature.NumberIsFinite, node, ...parameters); + case "parseInt": + return transformLuaLibFunction(context, LuaLibFeature.NumberParseInt, node, ...parameters); + case "parseFloat": + return transformLuaLibFunction(context, LuaLibFeature.NumberParseFloat, node, ...parameters); default: context.diagnostics.push(unsupportedProperty(calledMethod.name, "Number", methodName)); } diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index c91d883cb..26b90d4e6 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -108,29 +108,32 @@ test("numbers overflowing the float limit become math.huge", () => { util.testExpression`1e309`.expectToMatchJsResult(); }); -describe.each(["parseInt", "parseFloat"])("parse numbers with %s", parseFunction => { - const numberStrings = ["3", "3.0", "9", "42", "239810241", "-20391", "3.1415", "2.7182", "-34910.3"]; +describe.each(["parseInt", "parseFloat", "Number.parseInt", "Number.parseFloat"])( + "parse numbers with %s", + parseFunction => { + const numberStrings = ["3", "3.0", "9", "42", "239810241", "-20391", "3.1415", "2.7182", "-34910.3"]; - test.each(numberStrings)("parses (%s)", numberString => { - util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); - }); + test.each(numberStrings)("parses (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); - test("empty string", () => { - util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); - }); + test("empty string", () => { + util.testExpression`${parseFunction}("")`.expectToMatchJsResult(); + }); - test("invalid string", () => { - util.testExpression`${parseFunction}("bla")`.expectToMatchJsResult(); - }); + test("invalid string", () => { + util.testExpression`${parseFunction}("bla")`.expectToMatchJsResult(); + }); - test.each(["1px", "2300m", "3,4", "452adkfl"])("trailing text (%s)", numberString => { - util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); - }); + test.each(["1px", "2300m", "3,4", "452adkfl"])("trailing text (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); - test.each([" 3", " 4", " -231", " 1px"])("leading whitespace (%s)", numberString => { - util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); - }); -}); + test.each([" 3", " 4", " -231", " 1px"])("leading whitespace (%s)", numberString => { + util.testExpression`${parseFunction}("${numberString}")`.expectToMatchJsResult(); + }); + } +); test.each(["Infinity", "-Infinity", " -Infinity"])("parseFloat handles Infinity", numberString => { util.testExpression`parseFloat("${numberString}")`.expectToMatchJsResult(); @@ -162,6 +165,36 @@ test.each([ util.testExpression`parseInt("${numberString}", ${base})`.expectToMatchJsResult(); }); +test.each(["Infinity", "-Infinity", " -Infinity"])("Number.parseFloat handles Infinity", numberString => { + util.testExpression`Number.parseFloat("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36", base: 8 }, + { numberString: "-36", base: 8 }, + { numberString: "100010101101", base: 2 }, + { numberString: "-100010101101", base: 2 }, + { numberString: "3F", base: 16 }, +])("Number.parseInt with base (%p)", ({ numberString, base }) => { + util.testExpression`Number.parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + +test.each(["0x4A", "-0x42", "0X42", " 0x391", " -0x8F"])("Number.parseInt detects hexadecimal", numberString => { + util.testExpression`Number.parseInt("${numberString}")`.expectToMatchJsResult(); +}); + +test.each([1, 37, -100])("Number.parseInt with invalid base (%p)", base => { + util.testExpression`Number.parseInt("11111", ${base})`.expectToMatchJsResult(); +}); + +test.each([ + { numberString: "36px", base: 8 }, + { numberString: "10001010110231", base: 2 }, + { numberString: "3Fcolor", base: 16 }, +])("Number.parseInt with base and trailing text (%p)", ({ numberString, base }) => { + util.testExpression`Number.parseInt("${numberString}", ${base})`.expectToMatchJsResult(); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(["42", "undefined"])("prototype call on nullable number (%p)", value => { util.testFunction` From f19f1e1e7152af4a49ceaa56479c7f9beeb94ddc Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 24 Sep 2023 18:30:18 +0200 Subject: [PATCH 622/764] 1.19.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6cf89b419..30495f122 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.19.2", + "version": "1.19.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.19.2", + "version": "1.19.3", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 1b8f0de1d..517e97fef 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.19.2", + "version": "1.19.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From c85001e463f7d9de46869ba4d17f7dee3ddb76c6 Mon Sep 17 00:00:00 2001 From: Zerio Date: Wed, 27 Sep 2023 21:51:14 +0200 Subject: [PATCH 623/764] Number static data properties (#1492) * Basic number literal structure * Setup `POSITIVE_INFINITY` * Better structure for number literals * Setup `NEGATIVE_INFINITY` * Add `NaN` * Setup `EPSILON` * Add `MIN_VALUE` * Setup `MAX_VALUE` * Setup `MAX_SAFE_INTEGER` * Setup `MIN_SAFE_INTEGER` * explenation * use unary expressions * add perry's tests * more correct? * fix failing test * fix tests * final number tests fix --- src/transformation/builtins/index.ts | 5 +- src/transformation/builtins/number.ts | 83 +++++++++++++++++++++++++++ test/unit/builtins/numbers.spec.ts | 14 +++++ 3 files changed, 100 insertions(+), 2 deletions(-) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 64f0d4228..b7528cf6e 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -11,7 +11,7 @@ import { transformConsoleCall } from "./console"; import { transformFunctionPrototypeCall, transformFunctionProperty } from "./function"; import { tryTransformBuiltinGlobalCall } from "./global"; import { transformMathCall, transformMathProperty } from "./math"; -import { transformNumberConstructorCall, transformNumberPrototypeCall } from "./number"; +import { transformNumberConstructorCall, transformNumberPrototypeCall, transformNumberProperty } from "./number"; import { transformObjectConstructorCall, tryTransformObjectPrototypeCall } from "./object"; import { transformPromiseConstructorCall } from "./promise"; import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; @@ -27,6 +27,8 @@ export function transformBuiltinPropertyAccessExpression( if (ts.isIdentifier(node.expression) && isStandardLibraryType(context, ownerType, undefined)) { switch (ownerType.symbol.name) { + case "NumberConstructor": + return transformNumberProperty(context, node); case "Math": return transformMathProperty(context, node); case "SymbolConstructor": @@ -162,7 +164,6 @@ export function transformBuiltinIdentifierExpression( const huge = lua.createStringLiteral("huge"); return lua.createTableIndexExpression(math, huge, node); } - case "globalThis": return lua.createIdentifier("_G", node, getIdentifierSymbolId(context, node, symbol), "globalThis"); } diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index c8ca98503..d07ef7066 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -1,9 +1,11 @@ import ts = require("typescript"); import * as lua from "../../LuaAST"; +import { createNaN } from "../utils/lua-ast"; import { TransformationContext } from "../context"; import { unsupportedProperty } from "../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformArguments } from "../visitors/call"; +import { LuaTarget } from "../../CompilerOptions"; export function transformNumberPrototypeCall( context: TransformationContext, @@ -27,6 +29,87 @@ export function transformNumberPrototypeCall( } } +export function transformNumberProperty( + context: TransformationContext, + node: ts.PropertyAccessExpression +): lua.Expression | undefined { + const name = node.name.text; + + /* + Read the docs on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number for further info about what these numbers entail. + Most of them should be fairly straight forward base on their name(s) though. + */ + + switch (name) { + case "POSITIVE_INFINITY": + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createTableIndexExpression(math, huge, node); + } + case "NEGATIVE_INFINITY": + if (context.luaTarget === LuaTarget.Lua50) { + const one = lua.createNumericLiteral(1); + const zero = lua.createNumericLiteral(0); + return lua.createUnaryExpression( + lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator), + lua.SyntaxKind.NegationOperator + ); + } else { + const math = lua.createIdentifier("math"); + const huge = lua.createStringLiteral("huge"); + return lua.createUnaryExpression( + lua.createTableIndexExpression(math, huge, node), + lua.SyntaxKind.NegationOperator + ); + } + case "NaN": + return createNaN(node); + case "EPSILON": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(-52), + lua.SyntaxKind.PowerOperator, + node + ); + case "MIN_VALUE": + return lua.createBinaryExpression( + lua.createNumericLiteral(-2), + lua.createNumericLiteral(1074), + lua.SyntaxKind.PowerOperator, + node + ); + case "MIN_SAFE_INTEGER": + return lua.createBinaryExpression( + lua.createNumericLiteral(-2), + lua.createNumericLiteral(1074), + lua.SyntaxKind.PowerOperator, + node + ); + case "MAX_SAFE_INTEGER": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(1024), + lua.SyntaxKind.PowerOperator, + node + ); + case "MAX_VALUE": + return lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(1024), + lua.SyntaxKind.PowerOperator, + node + ); + + default: + context.diagnostics.push(unsupportedProperty(node.name, "Number", name)); + } +} + export function transformNumberConstructorCall( context: TransformationContext, node: ts.CallExpression, diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index 26b90d4e6..c5f3b7d2b 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -206,3 +206,17 @@ test.each(["42", "undefined"])("prototype call on nullable number (%p)", value = .setOptions({ strictNullChecks: true }) .expectToMatchJsResult(); }); + +test.each([ + "Number.NEGATIVE_INFINITY <= Number.MIN_VALUE", + "Number.MIN_VALUE <= Number.MIN_SAFE_INTEGER", + + "Number.MAX_SAFE_INTEGER <= Number.MAX_VALUE", + "Number.MAX_VALUE <= Number.POSITIVE_INFINITY", + "Number.MIN_SAFE_INTEGER < 0", + + "0 < Number.EPSILON", + "Number.EPSILON < Number.MAX_SAFE_INTEGER", +])("Numer constants have correct relative sizes (%p)", comparison => { + util.testExpression(comparison).expectToEqual(true); +}); From 2d42025636601d9078aca2ccfd7b800c05349342 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 1 Oct 2023 16:00:34 +0200 Subject: [PATCH 624/764] Allow moduleresolution plugins to return an absolute path (#1496) --- src/transpilation/resolve.ts | 5 +++++ test/transpile/module-resolution.spec.ts | 20 +++++++------------ .../lua_sources/absolutebar.lua | 5 +++++ .../lua_sources/absolutefoo.d.ts | 1 + .../main.ts | 3 ++- .../tsconfig.json | 3 +-- test/transpile/plugins/moduleResolution.ts | 13 ++++++++++-- test/util.ts | 13 +++++++++--- 8 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua create mode 100644 test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index 803efb99a..bd16773e9 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -112,6 +112,11 @@ class ResolutionContext { this.emitHost ); if (pluginResolvedPath !== undefined) { + // If resolved path is absolute no need to further resolve it + if (path.isAbsolute(pluginResolvedPath)) { + return pluginResolvedPath; + } + // If lua file is in node_module if (requiredFromLuaFile && isNodeModulesFile(requiringFile.fileName)) { // If requiring file is in lua module, try to resolve sibling in that file first diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index e0b4429a6..ff29ac9b5 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -714,9 +714,9 @@ test("paths without baseUrl is error", () => { test("module resolution using plugin", () => { const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); - const mainFile = path.join(baseProjectPath, "src", "main.ts"); + const mainFile = path.join(baseProjectPath, "main.ts"); - const luaResult = util + const testBuilder = util .testProject(projectTsConfig) .setMainFileName(mainFile) .setOptions({ @@ -726,19 +726,13 @@ test("module resolution using plugin", () => { }, ], }) - .expectToHaveNoDiagnostics() - .getLuaResult(); + .expectToHaveNoDiagnostics(); - expect(luaResult.transpiledFiles).toHaveLength(2); - let hasResolvedFile = false; - for (const f of luaResult.transpiledFiles) { - hasResolvedFile = f.outPath.endsWith("bar.lua"); - if (hasResolvedFile) { - break; - } - } + const luaResult = testBuilder.getLuaResult(); + + expect(luaResult.transpiledFiles).toHaveLength(3); - expect(hasResolvedFile).toBe(true); + testBuilder.expectToEqual({ result: ["foo", "absolutefoo"] }); }); function snapshotPaths(files: tstl.TranspiledFile[]) { diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua new file mode 100644 index 000000000..35718ddea --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutebar.lua @@ -0,0 +1,5 @@ +local ____exports = {} +function ____exports.absolutefoo(self) + return "absolutefoo" +end +return ____exports \ No newline at end of file diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts new file mode 100644 index 000000000..9df109b2e --- /dev/null +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/lua_sources/absolutefoo.d.ts @@ -0,0 +1 @@ +export declare function absolutefoo(): string; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts index 59c17ab79..e3e6bc616 100644 --- a/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/main.ts @@ -1,2 +1,3 @@ import { foo } from "./lua_sources/foo"; -export const result = foo(); +import { absolutefoo } from "./lua_sources/absolutefoo"; +export const result = [foo(), absolutefoo()]; diff --git a/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json index 6d1f36cd6..06ed18c9f 100644 --- a/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json +++ b/test/transpile/module-resolution/project-with-module-resolution-plugin/tsconfig.json @@ -3,7 +3,6 @@ "strict": true, "target": "esnext", "lib": ["esnext"], - "types": [], - "outDir": "./dist" + "types": [] } } diff --git a/test/transpile/plugins/moduleResolution.ts b/test/transpile/plugins/moduleResolution.ts index 166626fbc..81b040080 100644 --- a/test/transpile/plugins/moduleResolution.ts +++ b/test/transpile/plugins/moduleResolution.ts @@ -3,9 +3,18 @@ import type * as tstl from "../../../src"; const plugin: tstl.Plugin = { moduleResolution(moduleIdentifier) { - const modulePath = moduleIdentifier.replace(/\./g, path.sep); + if (moduleIdentifier.includes("absolutefoo")) { + return path.join( + path.dirname(__dirname), + "module-resolution", + "project-with-module-resolution-plugin", + "lua_sources", + "absolutebar.lua" + ); + } + if (moduleIdentifier.includes("foo")) { - return modulePath.replace("foo", "bar"); + return moduleIdentifier.replace("foo", "bar"); } }, }; diff --git a/test/util.ts b/test/util.ts index 75b477849..73942a473 100644 --- a/test/util.ts +++ b/test/util.ts @@ -257,11 +257,18 @@ export abstract class TestBuilder { @memoize public getMainLuaFileResult(): ExecutableTranspiledFile { const { transpiledFiles } = this.getLuaResult(); + const mainFileName = normalizeSlashes(this.mainFileName); const mainFile = this.options.luaBundle ? transpiledFiles[0] - : transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => f.fileName === normalizeSlashes(this.mainFileName)) - ); + : transpiledFiles.find(({ sourceFiles }) => sourceFiles.some(f => f.fileName === mainFileName)); + + if (mainFile === undefined) { + throw new Error( + `No source file could be found matching main file: ${mainFileName}.\nSource files in test:\n${transpiledFiles + .flatMap(f => f.sourceFiles.map(sf => sf.fileName)) + .join("\n")}` + ); + } expect(mainFile).toMatchObject({ lua: expect.any(String), luaSourceMap: expect.any(String) }); return mainFile as ExecutableTranspiledFile; From c220e9f7006e8d80dee84506001ded0b456a094e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Oct 2023 16:24:29 +0200 Subject: [PATCH 625/764] CHANGELOG.md 1.20.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 396a16896..6df120df5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.20.0 + +- Added support for `Number.parseInt` and `Number.parseFloat` (mapped to same implementation as global `parseInt` and `parseFloat`) +- Added implementation for multiple `Number` constants like `Number.EPSILON` +- Added support for `Array.at` +- Fixed a bug when throwing an error object in a Lua environment without `debug` module +- Fixed a bug causing files not to be found when returning an absolute path from a `moduleResolution` plugin + ## 1.19.0 - Added support for the new TypeScript 5.2 `using` keyword for explicit resource management. See the [TypeScript release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-2/#using-declarations-and-explicit-resource-management) for more information. From b92cd0c538aebf798c0c06488ef0f312b1e583d7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 1 Oct 2023 16:26:40 +0200 Subject: [PATCH 626/764] 1.20.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30495f122..26d6c6159 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.19.3", + "version": "1.20.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.19.3", + "version": "1.20.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 517e97fef..a3b4dc4ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.19.3", + "version": "1.20.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 45f607828da469c042600f4082a0f0ec9be32b16 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 3 Oct 2023 20:41:58 +0200 Subject: [PATCH 627/764] Implement array.fill (#1497) --- src/LuaLib.ts | 1 + src/lualib/ArrayFill.ts | 19 +++++++++++++++++++ src/transformation/builtins/array.ts | 2 ++ test/unit/builtins/array.spec.ts | 27 +++++++++++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 src/lualib/ArrayFill.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 1e5332caa..8826abf95 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -9,6 +9,7 @@ export enum LuaLibFeature { ArrayConcat = "ArrayConcat", ArrayEntries = "ArrayEntries", ArrayEvery = "ArrayEvery", + ArrayFill = "ArrayFill", ArrayFilter = "ArrayFilter", ArrayForEach = "ArrayForEach", ArrayFind = "ArrayFind", diff --git a/src/lualib/ArrayFill.ts b/src/lualib/ArrayFill.ts new file mode 100644 index 000000000..a1654114a --- /dev/null +++ b/src/lualib/ArrayFill.ts @@ -0,0 +1,19 @@ +// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.fill +export function __TS__ArrayFill(this: T[], value: T, start?: number, end?: number): T[] { + let relativeStart = start ?? 0; + let relativeEnd = end ?? this.length; + + if (relativeStart < 0) { + relativeStart += this.length; + } + + if (relativeEnd < 0) { + relativeEnd += this.length; + } + + for (let i = relativeStart; i < relativeEnd; i++) { + this[i] = value; + } + + return this; +} diff --git a/src/transformation/builtins/array.ts b/src/transformation/builtins/array.ts index 53dbc653d..b22bff01d 100644 --- a/src/transformation/builtins/array.ts +++ b/src/transformation/builtins/array.ts @@ -94,6 +94,8 @@ export function transformArrayPrototypeCall( return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params); case "entries": return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller); + case "fill": + return transformLuaLibFunction(context, LuaLibFeature.ArrayFill, node, caller, ...params); case "push": if (node.arguments.length === 1) { const param = params[0] ?? lua.createNilLiteral(); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 05d499395..a59d1ee04 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -788,6 +788,33 @@ test.each([ util.testExpression(literal).expectToHaveNoDiagnostics(); }); +describe("array.fill", () => { + test.each(["[]", "[1]", "[1,2,3,4]"])("Fills full length of array without other parameters (%p)", arr => { + util.testExpression`${arr}.fill(5)`.expectToMatchJsResult(); + }); + + test.each(["[1,2,3]", "[1,2,3,4,5,6]"])("Fills starting from start parameter (%p)", arr => { + util.testExpression`${arr}.fill(5, 3)`.expectToMatchJsResult(); + }); + + test("handles negative start parameter", () => { + util.testExpression`[1,2,3,4,5,6,7].fill(8, -3)`.expectToMatchJsResult(); + }); + + test("handles negative end parameter", () => { + util.testExpression`[1,2,3,4,5,6,7].fill(8, -5, -2)`.expectToMatchJsResult(); + }); + + test("Fills starting from start parameter, up to ending parameter", () => { + util.testExpression`[1,2,3,4,5,6,7,8].fill(5, 2, 6)`.expectToMatchJsResult(); + }); + + // NOTE: This is different from the default ECMAScript specification for the behavior, but for Lua this is much more useful + test("Extends size of the array if ending size is larger than array", () => { + util.testExpression`[1,2,3].fill(5, 0, 6)`.expectToEqual([5, 5, 5, 5, 5, 5]); + }); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", value => { util.testFunction` From 4bb51781dfce914a9b357702285fe7233a9d3d33 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 3 Oct 2023 21:55:12 +0200 Subject: [PATCH 628/764] 1.20.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26d6c6159..f9250e566 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.20.0", + "version": "1.20.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.20.0", + "version": "1.20.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index a3b4dc4ad..46ecd4ebd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.20.0", + "version": "1.20.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e697c6e3bc852049e80c5d6bf388c6a103634ca6 Mon Sep 17 00:00:00 2001 From: Ryan Young Date: Tue, 17 Oct 2023 13:38:47 -0700 Subject: [PATCH 629/764] Support loop continue for 5.0, 5.1, and universal targets (#1500) * feat: support loop continue for 5.0, 5.1, and universal targets * test: test loops w/ continue against all lua versions --- src/transformation/utils/scope.ts | 7 +- src/transformation/visitors/break-continue.ts | 28 ++- src/transformation/visitors/loops/utils.ts | 32 +++- test/unit/__snapshots__/loops.spec.ts.snap | 177 ------------------ test/unit/loops.spec.ts | 71 ++++--- 5 files changed, 97 insertions(+), 218 deletions(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 9e89d3422..87f431162 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -22,6 +22,11 @@ interface FunctionDefinitionInfo { definition?: lua.VariableDeclarationStatement | lua.AssignmentStatement; } +export enum LoopContinued { + WithGoto, + WithRepeatBreak, +} + export interface Scope { type: ScopeType; id: number; @@ -30,7 +35,7 @@ export interface Scope { variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; importStatements?: lua.Statement[]; - loopContinued?: boolean; + loopContinued?: LoopContinued; functionReturned?: boolean; } diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 580abf73f..cfc411439 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -2,8 +2,7 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { unsupportedForTarget } from "../utils/diagnostics"; -import { findScope, ScopeType } from "../utils/scope"; +import { findScope, LoopContinued, ScopeType } from "../utils/scope"; export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { void context; @@ -11,19 +10,28 @@ export const transformBreakStatement: FunctionVisitor = (brea }; export const transformContinueStatement: FunctionVisitor = (statement, context) => { - if ( + const scope = findScope(context, ScopeType.Loop); + const continuedWith = context.luaTarget === LuaTarget.Universal || context.luaTarget === LuaTarget.Lua50 || context.luaTarget === LuaTarget.Lua51 - ) { - context.diagnostics.push(unsupportedForTarget(statement, "Continue statement", context.luaTarget)); - } - - const scope = findScope(context, ScopeType.Loop); + ? LoopContinued.WithRepeatBreak + : LoopContinued.WithGoto; if (scope) { - scope.loopContinued = true; + scope.loopContinued = continuedWith; } - return lua.createGotoStatement(`__continue${scope?.id ?? ""}`, statement); + const label = `__continue${scope?.id ?? ""}`; + + switch (continuedWith) { + case LoopContinued.WithGoto: + return lua.createGotoStatement(label, statement); + + case LoopContinued.WithRepeatBreak: + return [ + lua.createAssignmentStatement(lua.createIdentifier(label), lua.createBooleanLiteral(true), statement), + lua.createBreakStatement(statement), + ]; + } }; diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 7f522edb2..f34b35245 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; -import { performHoisting, ScopeType } from "../../utils/scope"; +import { LoopContinued, performHoisting, ScopeType } from "../../utils/scope"; import { isAssignmentPattern } from "../../utils/typescript"; import { transformAssignment } from "../binary-expression/assignments"; import { transformAssignmentPattern } from "../binary-expression/destructuring-assignments"; @@ -19,15 +19,31 @@ export function transformLoopBody( const scope = context.popScope(); const scopeId = scope.id; - if (!scope.loopContinued) { - return body; - } + switch (scope.loopContinued) { + case undefined: + return body; + + case LoopContinued.WithGoto: + return [lua.createDoStatement(body), lua.createLabelStatement(`__continue${scopeId}`)]; - const baseResult: lua.Statement[] = [lua.createDoStatement(body)]; - const continueLabel = lua.createLabelStatement(`__continue${scopeId}`); - baseResult.push(continueLabel); + case LoopContinued.WithRepeatBreak: + const identifier = lua.createIdentifier(`__continue${scopeId}`); + const literalTrue = lua.createBooleanLiteral(true); - return baseResult; + return [ + lua.createDoStatement([ + lua.createVariableDeclarationStatement(identifier), + lua.createRepeatStatement( + lua.createBlock([...body, lua.createAssignmentStatement(identifier, literalTrue)]), + literalTrue + ), + lua.createIfStatement( + lua.createUnaryExpression(identifier, lua.SyntaxKind.NotOperator), + lua.createBlock([lua.createBreakStatement()]) + ), + ]), + ]; + } } export function getVariableDeclarationBinding( diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap index 7b0c40ad2..29b609730 100644 --- a/test/unit/__snapshots__/loops.spec.ts.snap +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -11,180 +11,3 @@ return ____exports" `; exports[`forin[Array]: diagnostics 1`] = `"main.ts(3,9): error TSTL: Iterating over arrays with 'for ... in' is not allowed."`; - -exports[`loop continue (do { continue; } while (false)) [5.0]: code 1`] = ` -"repeat - do - do - goto __continue2 - end - ::__continue2:: - end -until not false" -`; - -exports[`loop continue (do { continue; } while (false)) [5.0]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; - -exports[`loop continue (do { continue; } while (false)) [5.1]: code 1`] = ` -"repeat - do - do - goto __continue2 - end - ::__continue2:: - end -until not false" -`; - -exports[`loop continue (do { continue; } while (false)) [5.1]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (do { continue; } while (false)) [universal]: code 1`] = ` -"repeat - do - do - goto __continue2 - end - ::__continue2:: - end -until not false" -`; - -exports[`loop continue (do { continue; } while (false)) [universal]: diagnostics 1`] = `"main.ts(1,6): error TSTL: Continue statement is/are not supported for target Lua universal."`; - -exports[`loop continue (for (;;) { continue; }) [5.0]: code 1`] = ` -"do - while true do - do - goto __continue2 - end - ::__continue2:: - end -end" -`; - -exports[`loop continue (for (;;) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; - -exports[`loop continue (for (;;) { continue; }) [5.1]: code 1`] = ` -"do - while true do - do - goto __continue2 - end - ::__continue2:: - end -end" -`; - -exports[`loop continue (for (;;) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (;;) { continue; }) [universal]: code 1`] = ` -"do - while true do - do - goto __continue2 - end - ::__continue2:: - end -end" -`; - -exports[`loop continue (for (;;) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,12): error TSTL: Continue statement is/are not supported for target Lua universal."`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.0]: code 1`] = ` -"for a in pairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.1]: code 1`] = ` -"for a in pairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a in {}) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a in {}) { continue; }) [universal]: code 1`] = ` -"for a in pairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a in {}) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua universal."`; - -exports[`loop continue (for (const a of []) { continue; }) [5.0]: code 1`] = ` -"for ____, a in ipairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a of []) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; - -exports[`loop continue (for (const a of []) { continue; }) [5.1]: code 1`] = ` -"for ____, a in ipairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a of []) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (for (const a of []) { continue; }) [universal]: code 1`] = ` -"for ____, a in ipairs({}) do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (for (const a of []) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,23): error TSTL: Continue statement is/are not supported for target Lua universal."`; - -exports[`loop continue (while (false) { continue; }) [5.0]: code 1`] = ` -"while false do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (while (false) { continue; }) [5.0]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.0."`; - -exports[`loop continue (while (false) { continue; }) [5.1]: code 1`] = ` -"while false do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (while (false) { continue; }) [5.1]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua 5.1."`; - -exports[`loop continue (while (false) { continue; }) [universal]: code 1`] = ` -"while false do - do - goto __continue2 - end - ::__continue2:: -end" -`; - -exports[`loop continue (while (false) { continue; }) [universal]: diagnostics 1`] = `"main.ts(1,17): error TSTL: Continue statement is/are not supported for target Lua universal."`; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 0fff55d9d..f2225c7f5 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -1,5 +1,6 @@ import * as tstl from "../../src"; -import { forbiddenForIn, unsupportedForTarget } from "../../src/transformation/utils/diagnostics"; +import { LuaTarget } from "../../src"; +import { forbiddenForIn } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; test("while", () => { @@ -14,8 +15,9 @@ test("while", () => { `.expectToMatchJsResult(); }); -test("while with continue", () => { - util.testFunction` +util.testEachVersion( + "while with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; let i = 0; while (i < arrTest.length) { @@ -36,11 +38,13 @@ test("while with continue", () => { i++; } return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); -test("dowhile with continue", () => { - util.testFunction` +util.testEachVersion( + "dowhile with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; let i = 0; do { @@ -61,8 +65,9 @@ test("dowhile with continue", () => { i++; } while (i < arrTest.length) return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("for", () => { util.testFunction` @@ -85,8 +90,9 @@ test("for with expression", () => { `.expectToMatchJsResult(); }); -test("for with continue", () => { - util.testFunction` +util.testEachVersion( + "for with continue", + () => util.testFunction` let arrTest = [0, 1, 2, 3, 4]; for (let i = 0; i < arrTest.length; i++) { if (i % 2 == 0) { @@ -101,8 +107,9 @@ test("for with continue", () => { } } return arrTest; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("forMirror", () => { util.testFunction` @@ -216,7 +223,20 @@ test("forin[Array]", () => { `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); -test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p)", ({ inp }) => { +const luaTargetsExceptJit = [ + LuaTarget.Lua50, + LuaTarget.Lua51, + LuaTarget.Lua52, + LuaTarget.Lua53, + LuaTarget.Lua54, + LuaTarget.Universal, +]; + +test.each( + luaTargetsExceptJit.flatMap(target => + [{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }].map(testCase => [target, testCase] as const) + ) +)("forin with continue (%s %p)", (luaTarget, { inp }) => { util.testFunctionTemplate` let obj = ${inp}; for (let i in obj) { @@ -227,7 +247,9 @@ test.each([{ inp: { a: 0, b: 1, c: 2, d: 3, e: 4 } }])("forin with continue (%p) obj[i] = 0; } return obj; - `.expectToMatchJsResult(); + ` + .setOptions({ luaTarget }) + .expectToMatchJsResult(); }); test.each([{ inp: [0, 1, 2] }])("forof (%p)", ({ inp }) => { @@ -331,8 +353,9 @@ test("forof destructing with existing variables", () => { `.expectToMatchJsResult(); }); -test("forof with continue", () => { - util.testFunction` +util.testEachVersion( + "forof with continue", + () => util.testFunction` let testArr = [0, 1, 2, 3, 4]; let a = 0; for (let i of testArr) { @@ -350,8 +373,9 @@ test("forof with continue", () => { a++; } return testArr; - `.expectToMatchJsResult(); -}); + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) +); test("forof with iterator", () => { util.testFunction` @@ -515,13 +539,16 @@ for (const testCase of [ "for (const a in {}) { continue; }", "for (const a of []) { continue; }", ]) { + const expectContinueVariable: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toMatch("local __continue2"); + const expectContinueGotoLabel: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { - [tstl.LuaTarget.Universal]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), - [tstl.LuaTarget.Lua50]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), - [tstl.LuaTarget.Lua51]: builder => builder.expectDiagnosticsToMatchSnapshot([unsupportedForTarget.code]), + [tstl.LuaTarget.Universal]: expectContinueVariable, + [tstl.LuaTarget.Lua50]: expectContinueVariable, + [tstl.LuaTarget.Lua51]: expectContinueVariable, [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, From 40e4c221e8c20e5da07a0b3e89ee86323465a013 Mon Sep 17 00:00:00 2001 From: Zerio Date: Sat, 21 Oct 2023 18:14:19 +0200 Subject: [PATCH 630/764] Setup custom name support (#1505) * Setup basic POC for customName param * remove & ignore lock files * Add CustomName annotation * Add customNames to tsconfig * Fix customNames in tsconfig schema * Setup functionality for customNames in tsconfig * Revert "remove & ignore lock files" This reverts commit 2a8e998981a070ca89f8ae5be9e5843d408d9663. * fix linting / run prettier lint fix * Setup tests for customName * Remove customNames from tsconfig * Change throw new error into expect in tests * Add more specific test name * Add further jest tests for customName * Add customName test for declared function * Fix namespace customName renaming * Make customName check more universal * Improve customName handling in call visitor * Move customname logic to `transformContextualCallExpression` * Use left instead of passing calledMethod * remove unneeded type specification Co-authored-by: Perry van Wesel --------- Co-authored-by: Perry van Wesel --- src/transformation/utils/annotations.ts | 1 + src/transformation/visitors/call.ts | 17 +-- src/transformation/visitors/identifier.ts | 34 +++++- test/unit/identifiers.spec.ts | 126 ++++++++++++++++++++++ 4 files changed, 169 insertions(+), 9 deletions(-) diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 0f25d8769..91ef6d531 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -5,6 +5,7 @@ export enum AnnotationKind { CompileMembersOnly = "compileMembersOnly", NoResolution = "noResolution", NoSelf = "noSelf", + CustomName = "customName", NoSelfInFile = "noSelfInFile", } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 679ae6dc1..bcc8602ff 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -15,6 +15,7 @@ import { transformInPrecedingStatementScope } from "../utils/preceding-statement import { getOptionalContinuationData, transformOptionalChain } from "./optional-chaining"; import { transformImportExpression } from "./modules/import"; import { transformLanguageExtensionCallExpression } from "./language-extensions/call-extension"; +import { getCustomNameFromSymbol } from "./identifier"; export function validateArguments( context: TransformationContext, @@ -135,12 +136,16 @@ export function transformContextualCallExpression( ) { // table:name() const table = context.transformExpression(left.expression); - return lua.createMethodCallExpression( - table, - lua.createIdentifier(left.name.text, left.name), - transformedArguments, - node - ); + let name = left.name.text; + + const symbol = context.checker.getSymbolAtLocation(left); + const customName = getCustomNameFromSymbol(symbol); + + if (customName) { + name = customName; + } + + return lua.createMethodCallExpression(table, lua.createIdentifier(name, left.name), transformedArguments, node); } else if (ts.isElementAccessExpression(left) || ts.isPropertyAccessExpression(left)) { if (isExpressionWithEvaluationEffect(left.expression)) { return transformElementAccessCall(context, left, transformedArguments, argPrecedingStatements); diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index 6262a316f..e5dd90e01 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -12,11 +12,38 @@ import { isStandardLibraryType } from "../utils/typescript"; import { getExtensionKindForNode, getExtensionKindForSymbol } from "../utils/language-extensions"; import { callExtensions } from "./language-extensions/call-extension"; import { isIdentifierExtensionValue, reportInvalidExtensionValue } from "./language-extensions/identifier"; +import { Annotation, AnnotationKind, getNodeAnnotations } from "../utils/annotations"; export function transformIdentifier(context: TransformationContext, identifier: ts.Identifier): lua.Identifier { return transformNonValueIdentifier(context, identifier, context.checker.getSymbolAtLocation(identifier)); } +export function getCustomNameFromSymbol(symbol?: ts.Symbol): undefined | string { + let retVal: undefined | string; + + if (symbol) { + const declarations = symbol.getDeclarations(); + if (declarations) { + let customNameAnnotation: undefined | Annotation = undefined; + for (const declaration of declarations) { + const nodeAnnotations = getNodeAnnotations(declaration); + const foundAnnotation = nodeAnnotations.get(AnnotationKind.CustomName); + + if (foundAnnotation) { + customNameAnnotation = foundAnnotation; + break; + } + } + + if (customNameAnnotation) { + retVal = customNameAnnotation.args[0]; + } + } + } + + return retVal; +} + function transformNonValueIdentifier( context: TransformationContext, identifier: ts.Identifier, @@ -53,9 +80,10 @@ function transformNonValueIdentifier( } } - const text = hasUnsafeIdentifierName(context, identifier, symbol) - ? createSafeName(identifier.text) - : identifier.text; + let text = hasUnsafeIdentifierName(context, identifier, symbol) ? createSafeName(identifier.text) : identifier.text; + + const customName = getCustomNameFromSymbol(symbol); + if (customName) text = customName; const symbolId = getIdentifierSymbolId(context, identifier, symbol); return lua.createIdentifier(text, identifier, symbolId, identifier.text); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 6e13a5e12..14f86fff8 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -845,3 +845,129 @@ test("lua built-in as in constructor assignment", () => { export const result = new A("42").error; `.expectToMatchJsResult(); }); + +test("customName rename function", () => { + const result = util.testModule` + /** @customName test2 **/ + function test(this: void): number { return 3; } + export const result: number = test(); + ` + .expectToEqual({ result: 3 }) + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("function test2()"); + expect(mainFile.lua).not.toContain("test()"); +}); + +test("customName rename variable", () => { + const result = util.testModule` + /** @customName result2 **/ + export const result: number = 3; + ` + .expectToEqual({ result2: 3 }) + .getLuaResult(); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("result2 ="); + expect(mainFile.lua).not.toContain("result ="); +}); + +test("customName rename classes", () => { + const testModule = util.testModule` + /** @customName Class2 **/ + class Class { + test: string; + + constructor(test: string) { + this.test = test; + } + } + + export const result = new Class("hello world"); + `; + + const executionResult = testModule.getLuaExecutionResult(); + expect(executionResult.result).toBeDefined(); + expect(executionResult.result).toMatchObject({ test: "hello world" }); + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("local Class2 ="); + expect(mainFile.lua).not.toContain("local Class ="); +}); + +test("customName rename namespace", () => { + const testModule = util.testModule` + /** @customName Test2 **/ + namespace Test { + /** @customName Func2 **/ + export function Func(): string { + return "hi"; + } + } + + export const result = Test.Func(); + `; + + testModule.expectToEqual({ result: "hi" }); + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2 ="); + expect(mainFile.lua).toContain("Test2.Func2"); + expect(mainFile.lua).not.toContain("Test ="); + expect(mainFile.lua).not.toContain("Func("); +}); + +test("customName rename declared function", () => { + const testModule = util.testModule` + /** @customName Test2 **/ + declare function Test(this: void): void; + + Test(); + `; + + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2("); + expect(mainFile.lua).not.toContain("Test("); +}); From dbcae83f34a89d7d4ca315652b000e57158fa400 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Oct 2023 18:14:44 +0200 Subject: [PATCH 631/764] Fix static super calls breaking with nil reference exception (#1511) * Fix static super calls breaking with nil reference exception * Fix prettier --- src/transformation/visitors/class/index.ts | 9 ++++++++- test/unit/classes/classes.spec.ts | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 9574d1efc..8c54afe12 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -21,6 +21,7 @@ import { createClassSetup } from "./setup"; import { LuaTarget } from "../../../CompilerOptions"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { createClassPropertyDecoratingExpression } from "./decorators"; +import { findFirstNodeAbove } from "../../utils/typescript"; export const transformClassDeclaration: FunctionVisitor = (declaration, context) => { // If declaration is a default export, transform to export variable assignment instead @@ -249,5 +250,11 @@ export const transformSuperExpression: FunctionVisitor = (ex baseClassName = lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression); } - return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); + const f = findFirstNodeAbove(expression, ts.isFunctionLike); + if (f && ts.canHaveModifiers(f) && isStaticNode(f)) { + // In static method, don't add prototype to super call + return baseClassName; + } else { + return lua.createTableIndexExpression(baseClassName, lua.createStringLiteral("prototype")); + } }; diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 93c7640cf..a93177c88 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -833,3 +833,22 @@ test("static member definition order (#1457)", () => { return A.a; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1504 +test("Calling static inherited functions works (#1504)", () => { + util.testFunction` + class A { + static Get() { + return "A"; + } + } + + class B extends A { + static Get() { + return super.Get() + "B"; + } + } + + return B.Get(); + `.expectToMatchJsResult(); +}); From 7a94e535058c5324c72b6fce35a8f2c8f218b451 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 29 Oct 2023 20:14:56 +0100 Subject: [PATCH 632/764] CHANGELOG 1.21.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6df120df5..e8bec8033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.21.0 + +- Added support for `continue` for Lua 5.0, 5.1 and universal targets. +- Added support for the new `/** @customName myCustomName **/` decorator, which allows renaming of variables and identifiers. + - This is useful to get around names that are reserved keywords in TypeScript, but are used in Lua API +- Fixed a bug that caused super calls in static methods to throw an error + ## 1.20.0 - Added support for `Number.parseInt` and `Number.parseFloat` (mapped to same implementation as global `parseInt` and `parseFloat`) From 7e89bc1d08682062a26aec08d1572b387bb0f4cf Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 29 Oct 2023 20:20:12 +0100 Subject: [PATCH 633/764] 1.21.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9250e566..5015440dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.20.1", + "version": "1.21.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.20.1", + "version": "1.21.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index 46ecd4ebd..c9477d1bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.20.1", + "version": "1.21.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e0e56fe3894289bbba164f4f4776bce8656a94cf Mon Sep 17 00:00:00 2001 From: scarf Date: Sat, 18 Nov 2023 23:27:15 +0900 Subject: [PATCH 634/764] feat: `Number.isInteger()` (#1518) --- src/LuaLib.ts | 1 + src/lualib/NumberIsInteger.ts | 6 ++++++ src/transformation/builtins/number.ts | 2 ++ test/unit/builtins/numbers.spec.ts | 4 ++++ 4 files changed, 13 insertions(+) create mode 100644 src/lualib/NumberIsInteger.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 8826abf95..f48f26b04 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -63,6 +63,7 @@ export enum LuaLibFeature { New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", + NumberIsInteger = "NumberIsInteger", NumberIsNaN = "NumberIsNaN", NumberParseInt = "ParseInt", NumberParseFloat = "ParseFloat", diff --git a/src/lualib/NumberIsInteger.ts b/src/lualib/NumberIsInteger.ts new file mode 100644 index 000000000..275fcae03 --- /dev/null +++ b/src/lualib/NumberIsInteger.ts @@ -0,0 +1,6 @@ +import { __TS__NumberIsFinite } from "./NumberIsFinite"; + +/// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-number.isinteger +export function __TS__NumberIsInteger(this: void, value: unknown): boolean { + return __TS__NumberIsFinite(value) && math.floor(value as number) === (value as number); +} diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index d07ef7066..17c44b6fd 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -118,6 +118,8 @@ export function transformNumberConstructorCall( const parameters = transformArguments(context, node.arguments); const methodName = calledMethod.name.text; switch (methodName) { + case "isInteger": + return transformLuaLibFunction(context, LuaLibFeature.NumberIsInteger, node, ...parameters); case "isNaN": return transformLuaLibFunction(context, LuaLibFeature.NumberIsNaN, node, ...parameters); case "isFinite": diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index c5f3b7d2b..0a8e0bf38 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -46,6 +46,10 @@ describe("Number", () => { test.each(cases)("isFinite(%p)", value => { util.testExpressionTemplate`Number.isFinite(${value} as any)`.expectToMatchJsResult(); }); + + test.each(cases)("isInteger(%p)", value => { + util.testExpressionTemplate`Number.isInteger(${value} as any)`.expectToMatchJsResult(); + }); }); const toStringRadixes = [undefined, 10, 2, 8, 9, 16, 17, 36, 36.9]; From bf879531c1daf003af6f91d7fe627157e549f48a Mon Sep 17 00:00:00 2001 From: Cheatoid Date: Sun, 19 Nov 2023 16:23:20 +0100 Subject: [PATCH 635/764] Add `afterEmit` plugin hook (#1353) * Add `afterEmit` plugin hook This function would run after Lua files have been written to disk (in order to allow plugins to perform post-build tasks such as optimizing/minifying/obfuscating/bytecode-compilation/etc). * Update plugins.ts * Create afterEmit.ts * Add test for plugin (cherry picked from commit ab6099c7334064dada1e6c539aae2e6a74b07970) --------- Co-authored-by: Perry van Wesel --- src/transpilation/plugins.ts | 14 ++++++++++++++ src/transpilation/transpiler.ts | 7 +++++++ test/transpile/plugins/afterEmit.ts | 24 ++++++++++++++++++++++++ test/transpile/plugins/plugins.spec.ts | 22 ++++++++++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 test/transpile/plugins/afterEmit.ts diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index f4c653e59..74e4e542e 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -46,6 +46,20 @@ export interface Plugin { result: EmitFile[] ) => ts.Diagnostic[] | void; + /** + * This function is called after translating the input program to Lua, after resolving dependencies, after bundling and writing files to disk. + */ + afterEmit?: ( + program: ts.Program, + options: CompilerOptions, + emitHost: EmitHost, + result: EmitFile[] + ) => ts.Diagnostic[] | void; + + /** + * This function is called when trying to resolve the .lua file corresponding to a Lua require statement. Allows you to provide + * your own module resolution logic. If return value is undefined, regular module resolution is done. + */ moduleResolution?: ( moduleIdentifier: string, requiringFile: string, diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 65545e455..1c0c28444 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -90,6 +90,13 @@ export class Transpiler { } } + for (const plugin of plugins) { + if (plugin.afterEmit) { + const afterEmitPluginDiagnostics = plugin.afterEmit(program, options, this.emitHost, emitPlan) ?? []; + diagnostics.push(...afterEmitPluginDiagnostics); + } + } + if (options.tstlVerbose) { console.log("Emit finished!"); } diff --git a/test/transpile/plugins/afterEmit.ts b/test/transpile/plugins/afterEmit.ts new file mode 100644 index 000000000..53741d2b7 --- /dev/null +++ b/test/transpile/plugins/afterEmit.ts @@ -0,0 +1,24 @@ +import * as ts from "typescript"; +import * as tstl from "../../../src"; + +const plugin: tstl.Plugin = { + afterEmit(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost, result: tstl.EmitFile[]) { + void program; + void options; + void emitHost; + void result; + + const diagnostic = { + category: ts.DiagnosticCategory.Message, + messageText: "After emit diagnostic message!", + code: 1234, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic; + return [diagnostic]; + }, +}; + +// eslint-disable-next-line import/no-default-export +export default plugin; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 3fc4b63cf..72c9e29a7 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -1,5 +1,6 @@ import * as path from "path"; import * as util from "../../util"; +import * as ts from "typescript"; test("printer", () => { util.testModule`` @@ -160,3 +161,24 @@ test("beforeEmit plugin bundle", () => { expect(f.lua).toContain("-- Comment added by beforeEmit plugin"); } }); + +test("afterEmit plugin", () => { + const { diagnostics } = util.testModule` + console.log("Hello, World!"); + [].push(1,2,3); // Use lualib code + ` + .addExtraFile( + "extrafile.ts", + ` + console.log("Hello, Mars!"); + ` + ) + .setOptions({ luaPlugins: [{ name: path.join(__dirname, "afterEmit.ts") }] }) + .getLuaResult(); + + // Expect to see the diagnostic returned by the plugin in the output + const diagnostic = diagnostics.find(d => d.code === 1234); + expect(diagnostic).toBeDefined(); + expect(diagnostic?.category).toBe(ts.DiagnosticCategory.Message); + expect(diagnostic?.messageText).toContain("After emit"); +}); From 5d63b1c920706e534cf8bb3307db08b7639e5dc2 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 20 Nov 2023 20:34:25 +0100 Subject: [PATCH 636/764] Reworked function context checking based on #1510 (#1519) * Cleanup code / make more readable * Further readability fix * Fix noSelfInFile check for call visitor * Fix/further rewrite of `isContextualCallExpression` * Further readability improvements * Change back returns in `isContextualCallExpression` * Add testcase for noSelfInFile over noImplicitSelf * Simplify testcase * Improve NoSelfInFile check * Further hasnoselfinfile fix * wrap declaration statement again * Add noSelfInFile check for func declared in other file * Remove accidentally commited debug logs * Rework function call context checking * Add back some caching that was removed in last commit --------- Co-authored-by: Zerio --- src/transformation/utils/function-context.ts | 55 +++++++++++++++++++- src/transformation/visitors/call.ts | 32 ++++-------- src/transformation/visitors/template.ts | 11 ++-- test/unit/functions/noSelfAnnotation.spec.ts | 55 ++++++++++++++++++++ 4 files changed, 123 insertions(+), 30 deletions(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 2cac26836..5ae64a1b5 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -35,9 +35,37 @@ function getExplicitThisParameter(signatureDeclaration: ts.SignatureDeclaration) } } +const callContextTypes = new WeakMap(); + +export function getCallContextType(context: TransformationContext, callExpression: ts.CallLikeExpression): ContextType { + const known = callContextTypes.get(callExpression); + if (known !== undefined) return known; + + const signature = context.checker.getResolvedSignature(callExpression); + const signatureDeclaration = signature?.getDeclaration(); + + let contextType = ContextType.None; + + if (signatureDeclaration) { + contextType = computeDeclarationContextType(context, signatureDeclaration); + } else { + // No signature declaration could be resolved, so instead try to see if the declaration is in a + // noSelfInFile file + const declarations = findRootDeclarations(context, callExpression); + contextType = declarations.some(d => getFileAnnotations(d.getSourceFile()).has(AnnotationKind.NoSelfInFile)) + ? ContextType.Void + : context.options.noImplicitSelf + ? ContextType.Void + : ContextType.NonVoid; + } + + callContextTypes.set(callExpression, contextType); + return contextType; +} + const signatureDeclarationContextTypes = new WeakMap(); -export function getDeclarationContextType( +function getSignatureContextType( context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration ): ContextType { @@ -48,6 +76,29 @@ export function getDeclarationContextType( return contextType; } +function findRootDeclarations(context: TransformationContext, callExpression: ts.CallLikeExpression): ts.Declaration[] { + const calledExpression = ts.isTaggedTemplateExpression(callExpression) + ? callExpression.tag + : ts.isJsxSelfClosingElement(callExpression) + ? callExpression.tagName + : ts.isJsxOpeningElement(callExpression) + ? callExpression.tagName + : callExpression.expression; + const calledSymbol = context.checker.getSymbolAtLocation(calledExpression); + if (calledSymbol === undefined) return []; + + return ( + calledSymbol.getDeclarations()?.flatMap(d => { + if (ts.isImportSpecifier(d)) { + const aliasSymbol = context.checker.getAliasedSymbol(calledSymbol); + return aliasSymbol.getDeclarations() ?? []; + } else { + return [d]; + } + }) ?? [] + ); +} + function computeDeclarationContextType(context: TransformationContext, signatureDeclaration: ts.SignatureDeclaration) { const thisParameter = getExplicitThisParameter(signatureDeclaration); if (thisParameter) { @@ -172,6 +223,6 @@ function computeFunctionContextType(context: TransformationContext, type: ts.Typ } return reduceContextTypes( - signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getDeclarationContextType(context, s)) + signatures.flatMap(s => getSignatureDeclarations(context, s)).map(s => getSignatureContextType(context, s)) ); } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index bcc8602ff..1f9fb521b 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { transformBuiltinCallExpression } from "../builtins"; import { FunctionVisitor, TransformationContext } from "../context"; import { validateAssignment } from "../utils/assignment-validation"; -import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { ContextType, getCallContextType } from "../utils/function-context"; import { wrapInTable } from "../utils/lua-ast"; import { isValidLuaIdentifier } from "../utils/safe-names"; import { isExpressionWithEvaluationEffect } from "../utils/typescript"; @@ -117,8 +117,7 @@ function transformElementAccessCall( export function transformContextualCallExpression( context: TransformationContext, node: ts.CallExpression | ts.TaggedTemplateExpression, - args: ts.Expression[] | ts.NodeArray, - signature?: ts.Signature + args: ts.Expression[] | ts.NodeArray ): lua.Expression { if (ts.isOptionalChain(node)) { return transformOptionalChain(context, node); @@ -126,7 +125,7 @@ export function transformContextualCallExpression( const left = ts.isCallExpression(node) ? getCalledExpression(node) : node.tag; let { precedingStatements: argPrecedingStatements, result: transformedArguments } = - transformInPrecedingStatementScope(context, () => transformArguments(context, args, signature)); + transformInPrecedingStatementScope(context, () => transformArguments(context, args)); if ( ts.isPropertyAccessExpression(left) && @@ -189,10 +188,9 @@ function transformPropertyCall( return lua.createCallExpression(context.transformExpression(node.expression), parameters, node); } - const signatureDeclaration = signature?.getDeclaration(); - if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + if (getCallContextType(context, node) !== ContextType.Void) { // table:name() - return transformContextualCallExpression(context, node, node.arguments, signature); + return transformContextualCallExpression(context, node, node.arguments); } else { // table.name() const [callPath, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); @@ -202,14 +200,12 @@ function transformPropertyCall( } function transformElementCall(context: TransformationContext, node: ts.CallExpression): lua.Expression { - const signature = context.checker.getResolvedSignature(node); - const signatureDeclaration = signature?.getDeclaration(); - if (!signatureDeclaration || getDeclarationContextType(context, signatureDeclaration) !== ContextType.Void) { + if (getCallContextType(context, node) !== ContextType.Void) { // A contextual parameter must be given to this call expression - return transformContextualCallExpression(context, node, node.arguments, signature); + return transformContextualCallExpression(context, node, node.arguments); } else { // No context - const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments, signature); + const [expression, parameters] = transformCallAndArguments(context, node.expression, node.arguments); return lua.createCallExpression(expression, parameters, node); } } @@ -267,7 +263,9 @@ export const transformCallExpression: FunctionVisitor = (node let callPath: lua.Expression; let parameters: lua.Expression[]; - const isContextualCall = isContextualCallExpression(context, signature); + + const isContextualCall = getCallContextType(context, node) !== ContextType.Void; + if (!isContextualCall) { [callPath, parameters] = transformCallAndArguments(context, calledExpression, node.arguments, signature); } else { @@ -290,14 +288,6 @@ export const transformCallExpression: FunctionVisitor = (node return wrapResultInTable ? wrapInTable(callExpression) : callExpression; }; -function isContextualCallExpression(context: TransformationContext, signature: ts.Signature | undefined): boolean { - const declaration = signature?.getDeclaration(); - if (!declaration) { - return !context.options.noImplicitSelf; - } - return getDeclarationContextType(context, declaration) !== ContextType.Void; -} - export function getCalledExpression(node: ts.CallExpression): ts.Expression { return ts.skipOuterExpressions(node.expression); } diff --git a/src/transformation/visitors/template.ts b/src/transformation/visitors/template.ts index bfad88057..291c703d5 100644 --- a/src/transformation/visitors/template.ts +++ b/src/transformation/visitors/template.ts @@ -1,7 +1,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { ContextType, getDeclarationContextType } from "../utils/function-context"; +import { ContextType, getCallContextType } from "../utils/function-context"; import { wrapInToStringForConcat } from "../utils/lua-ast"; import { isStringType } from "../utils/typescript"; import { transformArguments, transformContextualCallExpression } from "./call"; @@ -88,17 +88,14 @@ export const transformTaggedTemplateExpression: FunctionVisitor { export const result = foo(1); `.expectToMatchJsResult(); }); + +test("respect noSelfInFile over noImplicitSelf", () => { + const result = util.testModule` + /** @noSelfInFile **/ + const func: Function = () => 1; + export const result = func(1); + ` + .expectToMatchJsResult() + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("func(1)"); +}); + +test("respect noSelfInFile over noImplicitSelf (func declared in other file)", () => { + const result = util.testModule` + import { func, result } from "./functions"; + + export const result1 = result; + export const result2 = func(1); + ` + .addExtraFile( + "functions.ts", + ` + /** @noSelfInFile **/ + export const func: Function = () => 1; + export const result = func(2); + ` + ) + .expectToMatchJsResult() + .getLuaResult(); + + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath.includes("main.lua")); + expect(mainFile).toBeDefined(); + const functionFile = result.transpiledFiles.find(f => f.outPath.includes("functions.lua")); + expect(functionFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile || !functionFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("func(1)"); + expect(mainFile.lua).toBeDefined(); + expect(functionFile.lua).toContain("func(2)"); +}); From 6f339cca37a87b05ba337955ab4b82527f4cb54d Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 20 Nov 2023 20:40:59 +0100 Subject: [PATCH 637/764] CHANGELOG.md 1.22.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8bec8033..aa8a8965d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.22.0 + +- Added support for `Number.isInteger(n)` +- Added support for `afterEmit` plugin hook that can be used to post-process lua files after (possibly incremental) builds +- Fixed a bug causing `@noSelfInFile` sometimes to be ignored + ## 1.21.0 - Added support for `continue` for Lua 5.0, 5.1 and universal targets. From 200f20e24a819867438dcfca93f5e8d5cdf433cf Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 20 Nov 2023 20:43:19 +0100 Subject: [PATCH 638/764] 1.22.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5015440dc..f9c89ebfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.21.0", + "version": "1.22.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.21.0", + "version": "1.22.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.0.0", diff --git a/package.json b/package.json index c9477d1bf..315ba74bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.21.0", + "version": "1.22.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9288ddb3673ef89661e9ee7ccf9a32f7ad155762 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 28 Dec 2023 17:08:29 +0100 Subject: [PATCH 639/764] Upgrade TS to 5.3.3 (#1525) --- package-lock.json | 415 ++++++++++++------- package.json | 4 +- src/transformation/utils/function-context.ts | 7 +- test/unit/classes/instanceof.spec.ts | 2 +- 4 files changed, 283 insertions(+), 145 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9c89ebfa..8e3fdf4f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.22.0", "license": "MIT", "dependencies": { - "@typescript-to-lua/language-extensions": "1.0.0", + "@typescript-to-lua/language-extensions": "1.19.0", "enhanced-resolve": "^5.8.2", "picomatch": "^2.3.1", "resolve": "^1.15.1", @@ -39,13 +39,13 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.2.2" + "typescript": "^5.3.3" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.2.2" + "typescript": "5.3.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -71,17 +71,89 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/compat-data": { "version": "7.20.14", "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", @@ -131,13 +203,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "dependencies": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -187,34 +260,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -273,30 +346,30 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -326,13 +399,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -411,9 +484,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -600,34 +673,34 @@ } }, "node_modules/@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", - "debug": "^4.1.0", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -644,13 +717,13 @@ } }, "node_modules/@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -1692,9 +1765,9 @@ } }, "node_modules/@typescript-to-lua/language-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", - "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", + "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" }, "node_modules/acorn": { "version": "8.10.0", @@ -6099,9 +6172,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6368,12 +6441,71 @@ } }, "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", "dev": true, "requires": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/compat-data": { @@ -6414,13 +6546,14 @@ } }, "@babel/generator": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.14.tgz", - "integrity": "sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", "dev": true, "requires": { - "@babel/types": "^7.20.7", + "@babel/types": "^7.23.6", "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { @@ -6459,28 +6592,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { @@ -6524,24 +6657,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.22.5" } }, "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", "dev": true }, "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -6562,13 +6695,13 @@ } }, "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -6631,9 +6764,9 @@ } }, "@babel/parser": { - "version": "7.20.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.15.tgz", - "integrity": "sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -6763,31 +6896,31 @@ } }, "@babel/template": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", - "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" } }, "@babel/traverse": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", - "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-function-name": "^7.19.0", - "@babel/helper-hoist-variables": "^7.18.6", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.20.13", - "@babel/types": "^7.20.7", - "debug": "^4.1.0", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", + "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", "globals": "^11.1.0" }, "dependencies": { @@ -6800,13 +6933,13 @@ } }, "@babel/types": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", - "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -7621,9 +7754,9 @@ } }, "@typescript-to-lua/language-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.0.0.tgz", - "integrity": "sha512-GtmhFqyg+txpGgGLM3mlS3R6AEG9MQhKALxxcbr6SBzg9u7YAXcPKqUBaBYd6nH+Pi/eQLcWz4BNOLhz8v4TjQ==" + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", + "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" }, "acorn": { "version": "8.10.0", @@ -10842,9 +10975,9 @@ } }, "typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 315ba74bf..f2d4c7d30 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.2.2" + "typescript": "5.3.3" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -72,6 +72,6 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.2.2" + "typescript": "^5.3.3" } } diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 5ae64a1b5..3055c4f53 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -83,7 +83,12 @@ function findRootDeclarations(context: TransformationContext, callExpression: ts ? callExpression.tagName : ts.isJsxOpeningElement(callExpression) ? callExpression.tagName - : callExpression.expression; + : ts.isCallExpression(callExpression) + ? callExpression.expression + : undefined; + + if (!calledExpression) return []; + const calledSymbol = context.checker.getSymbolAtLocation(calledExpression); if (calledSymbol === undefined) return []; diff --git a/test/unit/classes/instanceof.spec.ts b/test/unit/classes/instanceof.spec.ts index 4e4000153..3869bfa1c 100644 --- a/test/unit/classes/instanceof.spec.ts +++ b/test/unit/classes/instanceof.spec.ts @@ -84,7 +84,7 @@ test("instanceof export", () => { test("instanceof Symbol.hasInstance", () => { util.testFunction` class myClass { - static [Symbol.hasInstance]() { + static [Symbol.hasInstance](instance: unknown) { return false; } } From 57b7be61593dff1d45deca90499bb9ae58f440f5 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 28 Dec 2023 17:10:24 +0100 Subject: [PATCH 640/764] CHANGELOG 1.23.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa8a8965d..6e97b5a90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.23.0 + +- Upgraded TypeScript to 5.3.3 + ## 1.22.0 - Added support for `Number.isInteger(n)` From ee3dfcf5a7cec52424e08bff02249564ed5c7358 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 28 Dec 2023 17:12:35 +0100 Subject: [PATCH 641/764] 1.23.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8e3fdf4f7..af93d23ec 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.22.0", + "version": "1.23.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.22.0", + "version": "1.23.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index f2d4c7d30..bd41a0436 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.22.0", + "version": "1.23.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 1cd16badbb307d1957c23d0c9d00d67462f69ac3 Mon Sep 17 00:00:00 2001 From: Ali Date: Sun, 4 Feb 2024 14:44:39 +0100 Subject: [PATCH 642/764] Support using super accessors (#1532) --- src/LuaLib.ts | 2 + src/lualib/DescriptorGet.ts | 25 +++++++++ src/lualib/DescriptorSet.ts | 28 ++++++++++ src/lualib/SetDescriptor.ts | 55 ++----------------- src/transformation/visitors/access.ts | 13 +++++ .../visitors/binary-expression/assignments.ts | 21 +++++++ test/unit/classes/accessors.spec.ts | 41 ++++++++++++++ 7 files changed, 136 insertions(+), 49 deletions(-) create mode 100644 src/lualib/DescriptorGet.ts create mode 100644 src/lualib/DescriptorSet.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index f48f26b04..a3d6d0f16 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -48,6 +48,8 @@ export enum LuaLibFeature { DecorateParam = "DecorateParam", Delete = "Delete", DelegatedYield = "DelegatedYield", + DescriptorGet = "DescriptorGet", + DescriptorSet = "DescriptorSet", Error = "Error", FunctionBind = "FunctionBind", Generator = "Generator", diff --git a/src/lualib/DescriptorGet.ts b/src/lualib/DescriptorGet.ts new file mode 100644 index 000000000..034a5825a --- /dev/null +++ b/src/lualib/DescriptorGet.ts @@ -0,0 +1,25 @@ +const getmetatable = _G.getmetatable; +const rawget = _G.rawget; + +export function __TS__DescriptorGet(this: any, metatable: any, key: string): void { + while (metatable) { + const rawResult = rawget(metatable, key as any); + if (rawResult !== undefined) { + return rawResult; + } + + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor !== undefined) { + if (descriptor.get) { + return descriptor.get.call(this); + } + + return descriptor.value; + } + } + + metatable = getmetatable(metatable); + } +} diff --git a/src/lualib/DescriptorSet.ts b/src/lualib/DescriptorSet.ts new file mode 100644 index 000000000..bb50ca4d3 --- /dev/null +++ b/src/lualib/DescriptorSet.ts @@ -0,0 +1,28 @@ +const getmetatable = _G.getmetatable; +const rawget = _G.rawget; +const rawset = _G.rawset; + +export function __TS__DescriptorSet(this: any, metatable: any, key: string, value: any): void { + while (metatable) { + const descriptors = rawget(metatable, "_descriptors"); + if (descriptors) { + const descriptor: PropertyDescriptor = descriptors[key]; + if (descriptor !== undefined) { + if (descriptor.set) { + descriptor.set.call(this, value); + } else { + if (descriptor.writable === false) { + throw `Cannot assign to read only property '${key}' of object '${this}'`; + } + + descriptor.value = value; + } + return; + } + } + + metatable = getmetatable(metatable); + } + + rawset(this, key, value); +} diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 389992c75..4339c8cc1 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -1,58 +1,15 @@ import { __TS__CloneDescriptor } from "./CloneDescriptor"; +import { __TS__DescriptorGet } from "./DescriptorGet"; +import { __TS__DescriptorSet } from "./DescriptorSet"; -function descriptorIndex(this: any, key: string): void { - const value = rawget(this, key); - if (value !== null) { - return value; - } - - let metatable = getmetatable(this); - while (metatable) { - const rawResult = rawget(metatable, key as any); - if (rawResult !== undefined) { - return rawResult; - } +const getmetatable = _G.getmetatable; - const descriptors = rawget(metatable, "_descriptors"); - if (descriptors) { - const descriptor: PropertyDescriptor = descriptors[key]; - if (descriptor !== undefined) { - if (descriptor.get) { - return descriptor.get.call(this); - } - - return descriptor.value; - } - } - - metatable = getmetatable(metatable); - } +function descriptorIndex(this: any, key: string): void { + return __TS__DescriptorGet.call(this, getmetatable(this), key); } function descriptorNewIndex(this: any, key: string, value: any): void { - let metatable = getmetatable(this); - while (metatable) { - const descriptors = rawget(metatable, "_descriptors"); - if (descriptors) { - const descriptor: PropertyDescriptor = descriptors[key]; - if (descriptor !== undefined) { - if (descriptor.set) { - descriptor.set.call(this, value); - } else { - if (descriptor.writable === false) { - throw `Cannot assign to read only property '${key}' of object '${this}'`; - } - - descriptor.value = value; - } - return; - } - } - - metatable = getmetatable(metatable); - } - - rawset(this, key, value); + return __TS__DescriptorSet.call(this, getmetatable(this), key, value); } // It's also used directly in class transform to add descriptors to the prototype diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 92955d15d..4071c715e 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -22,6 +22,7 @@ import { isOptionalContinuation, captureThisValue, } from "./optional-chaining"; +import { SyntaxKind } from "typescript"; function addOneToArrayAccessArgument( context: TransformationContext, @@ -173,6 +174,18 @@ export function transformPropertyAccessExpressionWithCapture( thisValue, }; } + if (node.expression.kind === SyntaxKind.SuperKeyword) { + return { + expression: transformLuaLibFunction( + context, + LuaLibFeature.DescriptorGet, + node, + lua.createIdentifier("self"), + table, + lua.createStringLiteral(property) + ), + }; + } return { expression: lua.createTableIndexExpression(table, lua.createStringLiteral(property), node) }; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index a138781dc..87b2ff4d4 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -1,4 +1,5 @@ import * as ts from "typescript"; +import { SyntaxKind } from "typescript"; import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { validateAssignment } from "../../utils/assignment-validation"; @@ -75,6 +76,26 @@ export function transformAssignment( return [arrayLengthAssignment]; } + if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { + if (lhs.expression.kind === SyntaxKind.SuperKeyword) { + return [ + lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.DescriptorSet, + parent, + lua.createIdentifier("self"), + context.transformExpression(lhs.expression), + ts.isPropertyAccessExpression(lhs) + ? lua.createStringLiteral(lhs.name.text) + : context.transformExpression(lhs.argumentExpression), + right + ) + ), + ]; + } + } + const symbol = lhs.parent && ts.isShorthandPropertyAssignment(lhs.parent) ? context.checker.getShorthandAssignmentValueSymbol(lhs.parent) diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 8a39fb21b..203fc1c9b 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -327,3 +327,44 @@ test("static get/set accessors in base class", () => { return fooOriginal + Bar.foo; `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1437 +test("super class get accessor (#1437)", () => { + util.testFunction` + class A { + get foo() { + return "A"; + } + } + + class B extends A { + override get foo() { + return super.foo + "B"; + } + } + + return new B().foo; + `.expectToMatchJsResult(); +}); + +test("super class set accessor", () => { + util.testFunction` + let result = "unset"; + + class A { + set result(value: string) { + result = "foo" + value; + } + } + + class B extends A { + override set result(value: string) { + super.result = "bar" + value; + } + } + + new B().result = "baz"; + + return result; + `.expectToMatchJsResult(); +}); From 223b49e51bfe25468c95c71d98a560f5b6bdfada Mon Sep 17 00:00:00 2001 From: Ali Date: Sun, 4 Feb 2024 16:34:00 +0100 Subject: [PATCH 643/764] Optimize Promise and Await (fixes #1499), fix Promise.resolve bug (#1530) * fix promise * remove unneeded adopt --- src/lualib/Await.ts | 51 +++--- src/lualib/Promise.ts | 226 ++++++++++++++----------- test/unit/builtins/async-await.spec.ts | 25 +++ test/unit/builtins/promise.spec.ts | 20 +++ 4 files changed, 202 insertions(+), 120 deletions(-) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index 7093a617f..f5c368619 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -16,44 +16,53 @@ import { __TS__Promise } from "./Promise"; +const cocreate = coroutine.create; +const coresume = coroutine.resume; +const costatus = coroutine.status; +const coyield = coroutine.yield; + +// Be extremely careful editing this function. A single non-tail function call may ruin chained awaits performance // eslint-disable-next-line @typescript-eslint/promise-function-async export function __TS__AsyncAwaiter(this: void, generator: (this: void) => void) { return new Promise((resolve, reject) => { let resolved = false; - const asyncCoroutine = coroutine.create(generator); + const asyncCoroutine = cocreate(generator); - // eslint-disable-next-line @typescript-eslint/promise-function-async - function adopt(value: unknown) { - return value instanceof __TS__Promise ? value : Promise.resolve(value); - } - function fulfilled(value: unknown) { - const [success, resultOrError] = coroutine.resume(asyncCoroutine, value); + function fulfilled(value: unknown): void { + const [success, resultOrError] = coresume(asyncCoroutine, value); if (success) { - step(resultOrError); - } else { - reject(resultOrError); + // `step` never throws. Tail call return is important! + return step(resultOrError); } + // `reject` should never throw. Tail call return is important! + return reject(resultOrError); } - function step(result: unknown) { - if (resolved) return; - if (coroutine.status(asyncCoroutine) === "dead") { - resolve(result); - } else { - adopt(result).then(fulfilled, reject); + + function step(this: void, result: unknown): void { + if (resolved) { + return; } + if (costatus(asyncCoroutine) === "dead") { + // `resolve` never throws. Tail call return is important! + return resolve(result); + } + // We cannot use `then` because we need to avoid calling `coroutine.resume` from inside `pcall` + // `fulfilled` and `reject` should never throw. Tail call return is important! + return __TS__Promise.resolve(result).addCallbacks(fulfilled, reject); } - const [success, resultOrError] = coroutine.resume(asyncCoroutine, (v: unknown) => { + + const [success, resultOrError] = coresume(asyncCoroutine, (v: unknown) => { resolved = true; - adopt(v).then(resolve, reject); + return __TS__Promise.resolve(v).addCallbacks(resolve, reject); }); if (success) { - step(resultOrError); + return step(resultOrError); } else { - reject(resultOrError); + return reject(resultOrError); } }); } export function __TS__Await(this: void, thing: unknown) { - return coroutine.yield(thing); + return coyield(thing); } diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index 3ba075326..c5b6aa2a5 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -9,111 +9,113 @@ export const enum PromiseState { Rejected, } -type FulfillCallback = (value: TData) => TResult | PromiseLike; -type RejectCallback = (reason: any) => TResult | PromiseLike; - -function promiseDeferred() { - let resolve: FulfillCallback; - let reject: RejectCallback; - const promise = new Promise((res, rej) => { +type PromiseExecutor = ConstructorParameters>[0]; +type PromiseResolve = Parameters>[0]; +type PromiseReject = Parameters>[1]; +type PromiseResolveCallback = (value: TValue) => TResult | PromiseLike; +type PromiseRejectCallback = (reason: any) => TResult | PromiseLike; + +function makeDeferredPromiseFactory(this: void) { + let resolve: PromiseResolve; + let reject: PromiseReject; + const executor: PromiseExecutor = (res, rej) => { resolve = res; reject = rej; - }); - - // @ts-ignore This is alright because TS doesnt understand the callback will immediately be called - return { promise, resolve, reject }; + }; + return function (this: void) { + const promise = new Promise(executor); + return $multi(promise, resolve, reject); + }; } -function isPromiseLike(thing: unknown): thing is PromiseLike { - return thing instanceof __TS__Promise; +const makeDeferredPromise = makeDeferredPromiseFactory(); + +function isPromiseLike(this: void, value: unknown): value is PromiseLike { + return value instanceof __TS__Promise; } +function doNothing(): void {} + +const pcall = _G.pcall; + export class __TS__Promise implements Promise { public state = PromiseState.Pending; public value?: T; public rejectionReason?: any; - private fulfilledCallbacks: Array> = []; - private rejectedCallbacks: Array> = []; + private fulfilledCallbacks: Array> = []; + private rejectedCallbacks: PromiseReject[] = []; private finallyCallbacks: Array<() => void> = []; // @ts-ignore public [Symbol.toStringTag]: string; // Required to implement interface, no output Lua // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve - public static resolve(this: void, data: TData): Promise { + public static resolve(this: void, value: T | PromiseLike): __TS__Promise> { + if (value instanceof __TS__Promise) { + return value; + } // Create and return a promise instance that is already resolved - const promise = new __TS__Promise(() => {}); + const promise = new __TS__Promise>(doNothing); promise.state = PromiseState.Fulfilled; - promise.value = data; + promise.value = value as Awaited; return promise; } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject - public static reject(this: void, reason: any): Promise { + public static reject(this: void, reason?: any): __TS__Promise { // Create and return a promise instance that is already rejected - const promise = new __TS__Promise(() => {}); + const promise = new __TS__Promise(doNothing); promise.state = PromiseState.Rejected; promise.rejectionReason = reason; return promise; } - constructor(executor: (resolve: (data: T) => void, reject: (reason: any) => void) => void) { - try { - executor(this.resolve.bind(this), this.reject.bind(this)); - } catch (e) { + constructor(executor: PromiseExecutor) { + // Avoid unnecessary local functions allocations by using `pcall` explicitly + const [success, error] = pcall( + executor, + undefined, + v => this.resolve(v), + err => this.reject(err) + ); + if (!success) { // When a promise executor throws, the promise should be rejected with the thrown object as reason - this.reject(e); + this.reject(error); } } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then public then( - onFulfilled?: FulfillCallback, - onRejected?: RejectCallback + onFulfilled?: PromiseResolveCallback, + onRejected?: PromiseRejectCallback ): Promise { - const { promise, resolve, reject } = promiseDeferred(); - - const isFulfilled = this.state === PromiseState.Fulfilled; - const isRejected = this.state === PromiseState.Rejected; - - if (onFulfilled) { - const internalCallback = this.createPromiseResolvingCallback(onFulfilled, resolve, reject); - this.fulfilledCallbacks.push(internalCallback); + const [promise, resolve, reject] = makeDeferredPromise(); - if (isFulfilled) { - // If promise already resolved, immediately call callback - internalCallback(this.value!); - } - } else { + this.addCallbacks( // We always want to resolve our child promise if this promise is resolved, even if we have no handler - this.fulfilledCallbacks.push(v => resolve(v)); - } - - if (onRejected) { - const internalCallback = this.createPromiseResolvingCallback(onRejected, resolve, reject); - this.rejectedCallbacks.push(internalCallback); - - if (isRejected) { - // If promise already rejected, immediately call callback - internalCallback(this.rejectionReason); - } - } else { + onFulfilled ? this.createPromiseResolvingCallback(onFulfilled, resolve, reject) : resolve, // We always want to reject our child promise if this promise is rejected, even if we have no handler - this.rejectedCallbacks.push(err => reject(err)); - } + onRejected ? this.createPromiseResolvingCallback(onRejected, resolve, reject) : reject + ); - if (isFulfilled) { - // If promise already resolved, also resolve returned promise - resolve(this.value!); - } + return promise as Promise; + } - if (isRejected) { - // If promise already rejected, also reject returned promise - reject(this.rejectionReason); + // Both callbacks should never throw! + public addCallbacks(fulfilledCallback: (value: T) => void, rejectedCallback: (rejectionReason: any) => void): void { + if (this.state === PromiseState.Fulfilled) { + // If promise already resolved, immediately call callback. We don't even need to store rejected callback + // Tail call return is important! + return fulfilledCallback(this.value!); + } + if (this.state === PromiseState.Rejected) { + // Similar thing + return rejectedCallback(this.rejectionReason); } - return promise as Promise; + this.fulfilledCallbacks.push(fulfilledCallback as any); + this.rejectedCallbacks.push(rejectedCallback); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch @@ -134,26 +136,22 @@ export class __TS__Promise implements Promise { return this; } - private resolve(data: T): void { - if (data instanceof __TS__Promise) { - data.then( + private resolve(value: T | PromiseLike): void { + if (isPromiseLike(value)) { + // Tail call return is important! + return (value as __TS__Promise).addCallbacks( v => this.resolve(v), err => this.reject(err) ); - return; } // Resolve this promise, if it is still pending. This function is passed to the constructor function. if (this.state === PromiseState.Pending) { this.state = PromiseState.Fulfilled; - this.value = data; + this.value = value; - for (const callback of this.fulfilledCallbacks) { - callback(data); - } - for (const callback of this.finallyCallbacks) { - callback(); - } + // Tail call return is important! + return this.invokeCallbacks(this.fulfilledCallbacks, value); } } @@ -163,55 +161,85 @@ export class __TS__Promise implements Promise { this.state = PromiseState.Rejected; this.rejectionReason = reason; - for (const callback of this.rejectedCallbacks) { - callback(reason); + // Tail call return is important! + return this.invokeCallbacks(this.rejectedCallbacks, reason); + } + } + + private invokeCallbacks(callbacks: ReadonlyArray<(value: T) => void>, value: T): void { + const callbacksLength = callbacks.length; + const finallyCallbacks = this.finallyCallbacks; + const finallyCallbacksLength = finallyCallbacks.length; + + if (callbacksLength !== 0) { + for (const i of $range(1, callbacksLength - 1)) { + callbacks[i - 1](value); } - for (const callback of this.finallyCallbacks) { - callback(); + // Tail call optimization for a common case. + if (finallyCallbacksLength === 0) { + return callbacks[callbacksLength - 1](value); } + callbacks[callbacksLength - 1](value); + } + + if (finallyCallbacksLength !== 0) { + for (const i of $range(1, finallyCallbacksLength - 1)) { + finallyCallbacks[i - 1](); + } + return finallyCallbacks[finallyCallbacksLength - 1](); } } private createPromiseResolvingCallback( - f: FulfillCallback | RejectCallback, - resolve: FulfillCallback, - reject: RejectCallback + f: PromiseResolveCallback | PromiseRejectCallback, + resolve: (data: TResult1 | TResult2) => void, + reject: (reason: any) => void ) { - return (value: T) => { - try { - this.handleCallbackData(f(value), resolve, reject); - } catch (e) { - // If a handler function throws an error, the promise returned by then gets rejected with the thrown error as its value - reject(e); + return (value: T): void => { + const [success, resultOrError] = pcall< + undefined, + [T], + TResult1 | PromiseLike | TResult2 | PromiseLike + >(f, undefined, value); + if (!success) { + // Tail call return is important! + return reject(resultOrError); } + // Tail call return is important! + return this.handleCallbackValue(resultOrError, resolve, reject); }; } - private handleCallbackData( - data: TResult | PromiseLike, - resolve: FulfillCallback, - reject: RejectCallback - ) { - if (isPromiseLike(data)) { - const nextpromise = data as __TS__Promise; + private handleCallbackValue( + value: TResult | PromiseLike, + resolve: (data: TResult1 | TResult2) => void, + reject: (reason: any) => void + ): void { + if (isPromiseLike(value)) { + const nextpromise = value as __TS__Promise; if (nextpromise.state === PromiseState.Fulfilled) { // If a handler function returns an already fulfilled promise, - // the promise returned by then gets fulfilled with that promise's value - resolve(nextpromise.value!); + // the promise returned by then gets fulfilled with that promise's value. + // Tail call return is important! + return resolve(nextpromise.value!); } else if (nextpromise.state === PromiseState.Rejected) { // If a handler function returns an already rejected promise, - // the promise returned by then gets fulfilled with that promise's value - reject(nextpromise.rejectionReason); + // the promise returned by then gets fulfilled with that promise's value. + // Tail call return is important! + return reject(nextpromise.rejectionReason); } else { // If a handler function returns another pending promise object, the resolution/rejection // of the promise returned by then will be subsequent to the resolution/rejection of // the promise returned by the handler. - data.then(resolve, reject); + // We cannot use `then` because we need to do tail call, and `then` returns a Promise. + // `resolve` and `reject` should never throw. + return nextpromise.addCallbacks(resolve, reject); } } else { // If a handler returns a value, the promise returned by then gets resolved with the returned value as its value // If a handler doesn't return anything, the promise returned by then gets resolved with undefined - resolve(data); + // Tail call return is important! + return resolve(value); } } } diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 3dbb77abe..45adb4518 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -24,6 +24,31 @@ function defer() { return { promise, resolve, reject }; }`; +test("high amount of chained awaits doesn't cause stack overflow", () => { + util.testFunction` + let result = "not executed"; + + async function delay() { + return; + } + + async function loop() { + try { + for (let i = 0; i < 500000; ++i) { + await delay(); + } + result = "success"; + } catch (e) { + result = e; + } + } + + loop(); + + return result; + `.expectToEqual("success"); +}); + test("can await already resolved promise", () => { util.testFunction` const result = []; diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index fa6f6cf0f..cb18db994 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -839,6 +839,26 @@ test("resolving promise with pending promise will keep pending until promise2 re .expectToEqual(["promise 2", "rejection", "promise 1", "rejection"]); }); +describe("Promise.resolve", () => { + test("returns the given resolved promise", () => { + util.testFunction` + let result = 0; + Promise.resolve(Promise.resolve(4)) + .then((value) => result = value); + return result; + `.expectToEqual(4); + }); + + test("returns the given rejected promise", () => { + util.testFunction` + let result = 0; + Promise.resolve(Promise.reject(4)) + .catch((value) => result = value); + return result; + `.expectToEqual(4); + }); +}); + describe("Promise.all", () => { test("resolves once all arguments are resolved", () => { util.testFunction` From a32d510b311c2c96b1530dc5c5b484262ce61312 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Feb 2024 18:20:51 +0100 Subject: [PATCH 644/764] CHANGELOG 1.24.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e97b5a90..01f48cfc4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.24.0 + +- Optimized promises and async/await to better handle long chains of promises, like for example using await in a loop +- Fixed a bug causing errors when accessing `super` properties + ## 1.23.0 - Upgraded TypeScript to 5.3.3 From f2052221d7491ce6dc0196be888fed135bc00cad Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 4 Feb 2024 18:23:08 +0100 Subject: [PATCH 645/764] 1.24.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index af93d23ec..d21875aa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.23.0", + "version": "1.24.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.23.0", + "version": "1.24.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index bd41a0436..efac5cc11 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.23.0", + "version": "1.24.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 414275026834a4c51bb4cc6228e72c099ea7af5f Mon Sep 17 00:00:00 2001 From: aabajyan <62068860+aabajyan@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:55:56 -0800 Subject: [PATCH 646/764] Fix tsconfig.spec.ts not working on MacOS (#1536) --- test/cli/tsconfig.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cli/tsconfig.spec.ts b/test/cli/tsconfig.spec.ts index b4df23e08..e5d1b946c 100644 --- a/test/cli/tsconfig.spec.ts +++ b/test/cli/tsconfig.spec.ts @@ -20,7 +20,7 @@ afterEach(async () => { const locate = (project: string | undefined, fileNames: string[] = []) => locateConfigFile({ errors: [], fileNames, options: { project } }); -const normalize = (name: string) => normalizeSlashes(path.resolve(temp, name)); +const normalize = (name: string) => normalizeSlashes(fs.realpathSync(path.resolve(temp, name))); describe("specified", () => { for (const separator of process.platform === "win32" ? ["/", "\\"] : ["/"]) { From 6de04ce2828293330601c0d1acc398b08d6f6b9e Mon Sep 17 00:00:00 2001 From: aabajyan <62068860+aabajyan@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:25:53 -0800 Subject: [PATCH 647/764] Add basic check for @customName in property access transform (#1534) --- src/transformation/visitors/access.ts | 9 ++++++++- .../__snapshots__/transformation.spec.ts.snap | 2 ++ test/translation/transformation/customNameWithNoSelf.ts | 7 +++++++ 3 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 test/translation/transformation/customNameWithNoSelf.ts diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 4071c715e..f0f33d871 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -23,6 +23,7 @@ import { captureThisValue, } from "./optional-chaining"; import { SyntaxKind } from "typescript"; +import { getCustomNameFromSymbol } from "./identifier"; function addOneToArrayAccessArgument( context: TransformationContext, @@ -108,10 +109,16 @@ export function transformPropertyAccessExpressionWithCapture( node: ts.PropertyAccessExpression, thisValueCapture: lua.Identifier | undefined ): ExpressionWithThisValue { - const property = node.name.text; const type = context.checker.getTypeAtLocation(node.expression); const isOptionalLeft = isOptionalContinuation(node.expression); + let property = node.name.text; + const symbol = context.checker.getSymbolAtLocation(node.name); + const customName = getCustomNameFromSymbol(symbol); + if (customName) { + property = customName; + } + const constEnumValue = tryGetConstEnumValue(context, node); if (constEnumValue) { return { expression: constEnumValue }; diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 48d2a7f9a..2832f2cd6 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -24,6 +24,8 @@ escapedCharsInTemplateString = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" nonEmptyTemplateString = ("Level 0: \\n\\t " .. ("Level 1: \\n\\t\\t " .. ("Level 3: \\n\\t\\t\\t " .. "Last level \\n --") .. " \\n --") .. " \\n --") .. " \\n --"" `; +exports[`Transformation (customNameWithNoSelf) 1`] = `"TestNamespace.pass()"`; + exports[`Transformation (exportStatement) 1`] = ` "local ____exports = {} local xyz = 4 diff --git a/test/translation/transformation/customNameWithNoSelf.ts b/test/translation/transformation/customNameWithNoSelf.ts new file mode 100644 index 000000000..73175ccdc --- /dev/null +++ b/test/translation/transformation/customNameWithNoSelf.ts @@ -0,0 +1,7 @@ +/** @noSelf */ +declare namespace TestNamespace { + /** @customName pass */ + function fail(): void; +} + +TestNamespace.fail(); From a91f4626c512b54271b8b1458a220ea50eee89ba Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Thu, 8 Feb 2024 22:44:53 +0100 Subject: [PATCH 648/764] Only use super descriptor functions when dealing with propery getters/setters (#1538) --- src/transformation/visitors/access.ts | 23 ++++++------ .../visitors/binary-expression/assignments.ts | 33 +++++++++-------- test/unit/classes/classes.spec.ts | 36 +++++++++++++++++++ 3 files changed, 67 insertions(+), 25 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index f0f33d871..8004d9f2d 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -182,16 +182,19 @@ export function transformPropertyAccessExpressionWithCapture( }; } if (node.expression.kind === SyntaxKind.SuperKeyword) { - return { - expression: transformLuaLibFunction( - context, - LuaLibFeature.DescriptorGet, - node, - lua.createIdentifier("self"), - table, - lua.createStringLiteral(property) - ), - }; + const symbol = context.checker.getSymbolAtLocation(node); + if (symbol && symbol.flags & ts.SymbolFlags.GetAccessor) { + return { + expression: transformLuaLibFunction( + context, + LuaLibFeature.DescriptorGet, + node, + lua.createIdentifier("self"), + table, + lua.createStringLiteral(property) + ), + }; + } } return { expression: lua.createTableIndexExpression(table, lua.createStringLiteral(property), node) }; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 87b2ff4d4..3e246c3f8 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -78,21 +78,24 @@ export function transformAssignment( if (ts.isPropertyAccessExpression(lhs) || ts.isElementAccessExpression(lhs)) { if (lhs.expression.kind === SyntaxKind.SuperKeyword) { - return [ - lua.createExpressionStatement( - transformLuaLibFunction( - context, - LuaLibFeature.DescriptorSet, - parent, - lua.createIdentifier("self"), - context.transformExpression(lhs.expression), - ts.isPropertyAccessExpression(lhs) - ? lua.createStringLiteral(lhs.name.text) - : context.transformExpression(lhs.argumentExpression), - right - ) - ), - ]; + const symbol = context.checker.getSymbolAtLocation(lhs); + if (symbol && symbol.flags & ts.SymbolFlags.SetAccessor) { + return [ + lua.createExpressionStatement( + transformLuaLibFunction( + context, + LuaLibFeature.DescriptorSet, + parent, + lua.createIdentifier("self"), + context.transformExpression(lhs.expression), + ts.isPropertyAccessExpression(lhs) + ? lua.createStringLiteral(lhs.name.text) + : context.transformExpression(lhs.argumentExpression), + right + ) + ), + ]; + } } } diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index a93177c88..25399c833 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -852,3 +852,39 @@ test("Calling static inherited functions works (#1504)", () => { return B.Get(); `.expectToMatchJsResult(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1537 +test("get inherted __index member from super (DotA 2 inheritance) (#1537)", () => { + util.testFunction` + // Inherit 'connected' class + class C extends Connected { + bar() { + return super.foo(); + } + } + + return new C().bar();` + .setTsHeader( + `interface I { + foo(): string; + } + + // Hacky interface/class merging + interface Connected extends I {} + class Connected {} + + declare function setmetatable(this: void, t: any, mt: any); + + const A = { + foo() { + return "foo"; + } + }; + + // Connect class 'Connected' to 'traditional' class A + setmetatable(Connected.prototype, { + __index: A + });` + ) + .expectToEqual("foo"); +}); From 91c05b58a40d0027cce106dad079fa904b21bf58 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 8 Feb 2024 22:47:37 +0100 Subject: [PATCH 649/764] 1.24.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d21875aa6..4f33cb9a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.24.0", + "version": "1.24.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.24.0", + "version": "1.24.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index efac5cc11..8bc97c863 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.24.0", + "version": "1.24.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From b6fce8d7c971476ca78cfb0fe1260e5514ffd62d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 1 Mar 2024 21:27:01 +0100 Subject: [PATCH 650/764] Fix bug outputting files to the wrong location in some cases (#1541) --- src/transpilation/transpiler.ts | 4 ++- .../module-resolution.spec.ts.snap | 2 +- test/transpile/paths.spec.ts | 34 ++++++++++++------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 1c0c28444..9bac1f5bf 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -203,7 +203,9 @@ export function getSourceDir(program: ts.Program): string { if (rootDir && rootDir.length > 0) { return path.isAbsolute(rootDir) ? rootDir : path.resolve(getProjectRoot(program), rootDir); } - return program.getCommonSourceDirectory(); + + // If no rootDir is given, source is relative to the project root + return getProjectRoot(program); } export function getEmitOutDir(program: ts.Program): string { diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap index e87569ded..c9f0be298 100644 --- a/test/transpile/__snapshots__/module-resolution.spec.ts.snap +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -10,8 +10,8 @@ exports[`supports complicated paths configuration 1`] = ` exports[`supports paths configuration 1`] = ` [ + "/paths-simple/myprogram/dist/main.lua", "/paths-simple/myprogram/dist/mypackage/bar.lua", "/paths-simple/myprogram/dist/mypackage/index.lua", - "/paths-simple/myprogram/dist/myprogram/main.lua", ] `; diff --git a/test/transpile/paths.spec.ts b/test/transpile/paths.spec.ts index 0917307b8..f98b6e635 100644 --- a/test/transpile/paths.spec.ts +++ b/test/transpile/paths.spec.ts @@ -1,6 +1,6 @@ import * as path from "path"; import * as ts from "typescript"; -import { getSourceDir } from "../../src"; +import { getEmitPath, getSourceDir } from "../../src"; import * as util from "../util"; const cwd = process.cwd(); @@ -12,31 +12,24 @@ describe("getSourceDir", () => { test("with rootDir", () => { const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath, rootDir: "src" }); - // getCommonSourceDirectory does not work right so mock it - jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); - + // If rootdir is specified, rootDir is the sourceDir expect(getSourceDir(program)).toBe(path.join(cwd, "src")); }); test("without rootDir", () => { const program = ts.createProgram(["main.ts", "src/otherfile.ts"], { configFilePath }); - // getCommonSourceDirectory does not work right so mock it - jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(cwd); - - // Common sources directory is project root + // If rootDir is not specified, root dir is where the config file is expect(normalize(getSourceDir(program))).toBe(cwd); }); - test("without rootDir in src dir", () => { - const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], { - configFilePath, - }); + test("without config file in src dir", () => { + const program = ts.createProgram([path.join(cwd, "src", "main.ts"), path.join(cwd, "src", "otherfile.ts")], {}); // getCommonSourceDirectory does not work right so mock it jest.spyOn(program, "getCommonSourceDirectory").mockReturnValue(path.join(cwd, "src")); - // Common sources directory is src + // If there is no config file, return the common source directory expect(normalize(getSourceDir(program))).toBe(path.join(cwd, "src")); }); }); @@ -145,6 +138,21 @@ describe("getEmitPath", () => { expect(fileNames).toHaveLength(1); expect(fileNames).toContain(path.join(cwd, "out1", "out2", "bundle.scar")); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1540 + test("puts files next to their source if no config is given (#1540)", () => { + const file1 = path.join("src", "main.ts"); + const file2 = path.join("src", "otherfile.ts"); + const file3 = path.join("src", "nested", "nestedfile.ts"); + const program = ts.createProgram([file1, file2, file3], { configFilePath }); + + // If rootDir is not specified, root dir is where the config file is + const configRoot = path.dirname(configFilePath); + const replaceExtension = (f: string) => f.replace(/\.ts$/, ".lua"); + expect(getEmitPath(file1, program)).toBe(replaceExtension(path.join(configRoot, file1))); + expect(getEmitPath(file2, program)).toBe(replaceExtension(path.join(configRoot, file2))); + expect(getEmitPath(file3, program)).toBe(replaceExtension(path.join(configRoot, file3))); + }); }); function normalize(path: string) { From 7bc58475fbe28c18c5ffe32b46adb378bc6ed8d7 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 17 Mar 2024 15:21:33 +0100 Subject: [PATCH 651/764] Properly read extended tsconfig for watcher (#1544) --- src/cli/tsconfig.ts | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/cli/tsconfig.ts b/src/cli/tsconfig.ts index 2bbe4eef7..33e469368 100644 --- a/src/cli/tsconfig.ts +++ b/src/cli/tsconfig.ts @@ -137,16 +137,7 @@ export function createConfigFileUpdater( if (!configFile || !configFilePath) return []; if (!configFileMap.has(configFile)) { - const parsedConfigFile = updateParsedConfigFile( - ts.parseJsonSourceFileConfigFileContent( - configFile, - ts.sys, - path.dirname(configFilePath), - optionsToExtend, - configFilePath - ) - ); - + const parsedConfigFile = parseConfigFileWithSystem(configFilePath, optionsToExtend, ts.sys); configFileMap.set(configFile, parsedConfigFile); } From 587711baf109ea0d1133c1d7b19d6b1b75f8f157 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 17 Mar 2024 15:39:00 +0100 Subject: [PATCH 652/764] Upgrade TypeScript to 5.4 (#1545) --- package-lock.json | 16 ++++++++-------- package.json | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f33cb9a2..dba498d72 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,13 +39,13 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.3.3" + "typescript": "^5.4.2" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.3.3" + "typescript": "5.4.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -6172,9 +6172,9 @@ } }, "node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -10975,9 +10975,9 @@ } }, "typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", + "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 8bc97c863..95bfcc7d3 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.3.3" + "typescript": "5.4.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -72,6 +72,6 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.3.3" + "typescript": "^5.4.2" } } From 90b378444167ec695a2ecc31bb6c315fb492437d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 17 Mar 2024 16:00:45 +0100 Subject: [PATCH 653/764] Implement Map.groupBy and Object.groupBy (#1546) * Add support for Object.groupBy * Implement Map.groupBy --- src/LuaLib.ts | 2 ++ src/lualib/MapGroupBy.ts | 22 ++++++++++++++ src/lualib/ObjectGroupBy.ts | 22 ++++++++++++++ src/transformation/builtins/index.ts | 4 +++ src/transformation/builtins/map.ts | 22 ++++++++++++++ src/transformation/builtins/object.ts | 2 ++ test/unit/builtins/map.spec.ts | 44 +++++++++++++++++++++++++++ test/unit/builtins/object.spec.ts | 38 +++++++++++++++++++++++ 8 files changed, 156 insertions(+) create mode 100644 src/lualib/MapGroupBy.ts create mode 100644 src/lualib/ObjectGroupBy.ts create mode 100644 src/transformation/builtins/map.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index a3d6d0f16..d051c60b4 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -58,6 +58,7 @@ export enum LuaLibFeature { Iterator = "Iterator", LuaIteratorSpread = "LuaIteratorSpread", Map = "Map", + MapGroupBy = "MapGroupBy", Match = "Match", MathAtan2 = "MathAtan2", MathModf = "MathModf", @@ -77,6 +78,7 @@ export enum LuaLibFeature { ObjectFromEntries = "ObjectFromEntries", ObjectGetOwnPropertyDescriptor = "ObjectGetOwnPropertyDescriptor", ObjectGetOwnPropertyDescriptors = "ObjectGetOwnPropertyDescriptors", + ObjectGroupBy = "ObjectGroupBy", ObjectKeys = "ObjectKeys", ObjectRest = "ObjectRest", ObjectValues = "ObjectValues", diff --git a/src/lualib/MapGroupBy.ts b/src/lualib/MapGroupBy.ts new file mode 100644 index 000000000..d3e079192 --- /dev/null +++ b/src/lualib/MapGroupBy.ts @@ -0,0 +1,22 @@ +export function __TS__MapGroupBy( + this: void, + items: Iterable, + keySelector: (item: T, index: number) => K +): Map { + const result = new Map(); + + let i = 0; + for (const item of items) { + const key = keySelector(item, i); + + if (result.has(key)) { + result.get(key)!.push(item); + } else { + result.set(key, [item]); + } + + i++; + } + + return result; +} diff --git a/src/lualib/ObjectGroupBy.ts b/src/lualib/ObjectGroupBy.ts new file mode 100644 index 000000000..6328ad2aa --- /dev/null +++ b/src/lualib/ObjectGroupBy.ts @@ -0,0 +1,22 @@ +export function __TS__ObjectGroupBy( + this: void, + items: Iterable, + keySelector: (item: T, index: number) => K +): Partial> { + const result: Partial> = {}; + + let i = 0; + for (const item of items) { + const key = keySelector(item, i); + + if (key in result) { + result[key]!.push(item); + } else { + result[key] = [item]; + } + + i++; + } + + return result; +} diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index b7528cf6e..867942064 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -18,6 +18,7 @@ import { transformStringConstructorCall, transformStringProperty, transformStrin import { transformSymbolConstructorCall } from "./symbol"; import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; import { LuaTarget } from "../../CompilerOptions"; +import { transformMapConstructorCall } from "./map"; export function transformBuiltinPropertyAccessExpression( context: TransformationContext, @@ -93,6 +94,9 @@ function tryTransformBuiltinGlobalMethodCall( case "Console": result = transformConsoleCall(context, node, calledMethod); break; + case "MapConstructor": + result = transformMapConstructorCall(context, node, calledMethod); + break; case "Math": result = transformMathCall(context, node, calledMethod); break; diff --git a/src/transformation/builtins/map.ts b/src/transformation/builtins/map.ts new file mode 100644 index 000000000..556578591 --- /dev/null +++ b/src/transformation/builtins/map.ts @@ -0,0 +1,22 @@ +import * as lua from "../../LuaAST"; +import * as ts from "typescript"; +import { TransformationContext } from "../context"; +import { unsupportedProperty } from "../utils/diagnostics"; +import { transformArguments } from "../visitors/call"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; + +export function transformMapConstructorCall( + context: TransformationContext, + node: ts.CallExpression, + calledMethod: ts.PropertyAccessExpression +): lua.Expression | undefined { + const args = transformArguments(context, node.arguments); + const methodName = calledMethod.name.text; + + switch (methodName) { + case "groupBy": + return transformLuaLibFunction(context, LuaLibFeature.MapGroupBy, node, ...args); + default: + context.diagnostics.push(unsupportedProperty(calledMethod.name, "Map", methodName)); + } +} diff --git a/src/transformation/builtins/object.ts b/src/transformation/builtins/object.ts index cd386ce19..43dd8a165 100644 --- a/src/transformation/builtins/object.ts +++ b/src/transformation/builtins/object.ts @@ -26,6 +26,8 @@ export function transformObjectConstructorCall( return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptor, node, ...args); case "getOwnPropertyDescriptors": return transformLuaLibFunction(context, LuaLibFeature.ObjectGetOwnPropertyDescriptors, node, ...args); + case "groupBy": + return transformLuaLibFunction(context, LuaLibFeature.ObjectGroupBy, node, ...args); case "keys": return transformLuaLibFunction(context, LuaLibFeature.ObjectKeys, node, ...args); case "values": diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index 7eec8844d..f2e1cbfbe 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -209,3 +209,47 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM `.expectToMatchJsResult(); }); }); + +describe("Map.groupBy", () => { + test("empty", () => { + util.testFunction` + const array = []; + + const map = Map.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual([]); + }); + + test("groupBy", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + const map = Map.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual({ + even: [0, 2, 4], + odd: [1, 3, 5], + }); + }); + + test("groupBy index", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + const map = Map.groupBy(array, (num, index) => { + return index < 3 ? "low": "high"; + }); + + return Object.fromEntries(map.entries()); + `.expectToEqual({ + low: [0, 1, 2], + high: [3, 4, 5], + }); + }); +}); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 9cb5f8de3..1edc8a9d6 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -264,3 +264,41 @@ describe("delete from object", () => { .expectToMatchJsResult(); }); }); + +describe("Object.groupBy", () => { + test("empty", () => { + util.testFunction` + const array = []; + + return Object.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + `.expectToEqual([]); + }); + + test("groupBy", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + return Object.groupBy(array, (num, index) => { + return num % 2 === 0 ? "even": "odd"; + }); + `.expectToEqual({ + even: [0, 2, 4], + odd: [1, 3, 5], + }); + }); + + test("groupBy index", () => { + util.testFunction` + const array = [0, 1, 2, 3, 4, 5]; + + return Object.groupBy(array, (num, index) => { + return index < 3 ? "low": "high"; + }); + `.expectToEqual({ + low: [0, 1, 2], + high: [3, 4, 5], + }); + }); +}); From 202f402e2ab941feb54b04596605ab56ee4b097e Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 17 Mar 2024 16:04:55 +0100 Subject: [PATCH 654/764] CHANGELOG.md 1.25.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01f48cfc4..cb53c4565 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.25.0 + +- Upgraded TypeScript to 5.4.2 +- Added support for new TypeScript 5.4 features `Map.groupBy` and `Object.groupBy` +- Fixed a bug causing files to not be emitted at the correct output path +- Fixed a bug causing `@customname` to not work together with `@noSelf` +- Fixed a bug causing extended tsconfigs to not be correctly read when using watch mode + ## 1.24.0 - Optimized promises and async/await to better handle long chains of promises, like for example using await in a loop From 7db98b3a5566b14d5b97a79a05d0887f3aad02e6 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 17 Mar 2024 16:06:55 +0100 Subject: [PATCH 655/764] 1.25.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index dba498d72..787345162 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.24.1", + "version": "1.25.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.24.1", + "version": "1.25.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 95bfcc7d3..8bd9ee3b0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.24.1", + "version": "1.25.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From f610b5f6fd4d11543902c30777e9f19202e97f91 Mon Sep 17 00:00:00 2001 From: Benjamin Ye <24237065+GlassBricks@users.noreply.github.com> Date: Thu, 21 Mar 2024 10:59:33 -0700 Subject: [PATCH 656/764] Fix crash when using lualib_bundle in an environment without coroutines (#1547) * Don't crash if coroutine not supported * Add test for environment without coroutine * Fix prettier --- src/lualib/Await.ts | 1 + test/unit/builtins/loading.spec.ts | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/src/lualib/Await.ts b/src/lualib/Await.ts index f5c368619..7f6a345ee 100644 --- a/src/lualib/Await.ts +++ b/src/lualib/Await.ts @@ -16,6 +16,7 @@ import { __TS__Promise } from "./Promise"; +const coroutine = _G.coroutine ?? {}; const cocreate = coroutine.create; const coresume = coroutine.resume; const costatus = coroutine.status; diff --git a/test/unit/builtins/loading.spec.ts b/test/unit/builtins/loading.spec.ts index e4363eb8c..563870f6d 100644 --- a/test/unit/builtins/loading.spec.ts +++ b/test/unit/builtins/loading.spec.ts @@ -67,6 +67,17 @@ test("lualib should not include tstl header", () => { ); }); +test("using lualib does not crash when coroutine is not defined", () => { + util.testModule` + declare const _G: any; + declare function require(this: void, name: string): any + + _G.coroutine = undefined; + require("lualib_bundle"); + export const result = 1 + `.expectToEqual({ result: 1 }); +}); + describe("Unknown builtin property", () => { test("access", () => { util.testExpression`Math.unknownProperty` From 16a8eb3a5aed582f31d5f2306d70d3801983deca Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 21 Mar 2024 19:02:02 +0100 Subject: [PATCH 657/764] 1.25.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 787345162..576ad4b30 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.25.0", + "version": "1.25.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.25.0", + "version": "1.25.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 8bd9ee3b0..5bd5a0407 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.25.0", + "version": "1.25.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5001dd81d5ba045203e74aeef011bd7208609255 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 14 Jun 2024 21:36:47 +0200 Subject: [PATCH 658/764] Fix bundle edge case (#1559) --- src/transpilation/bundle.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index c0b21b7d2..1e0436c35 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -15,8 +15,8 @@ const createModulePath = (pathToResolve: string, program: ts.Program) => function requireOverride(options: CompilerOptions) { const runModule = options.luaTarget === LuaTarget.Lua50 - ? "(table.getn(arg) > 0) and module(unpack(arg)) or module(file)" - : '(select("#", ...) > 0) and module(...) or module(file)'; + ? "if (table.getn(arg) > 0) then value = module(unpack(arg)) else value = module(file) end" + : 'if (select("#", ...) > 0) then value = module(...) else value = module(file) end'; return ` local ____modules = {} local ____moduleCache = {} @@ -27,8 +27,10 @@ local function require(file, ...) end if ____modules[file] then local module = ____modules[file] - ____moduleCache[file] = { value = ${runModule} } - return ____moduleCache[file].value + local value = nil + ${runModule} + ____moduleCache[file] = { value = value } + return value else if ____originalRequire then return ____originalRequire(file) From fd0dcf0fe09784fc84be64875e98f10afba8bf57 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 14 Jun 2024 21:39:55 +0200 Subject: [PATCH 659/764] 1.25.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 576ad4b30..e376b5d12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.25.1", + "version": "1.25.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.25.1", + "version": "1.25.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 5bd5a0407..42479a8ad 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.25.1", + "version": "1.25.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From e4afda0d86ee748237d0668077a34c2eb44d87c9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 23 Jun 2024 10:59:26 +0200 Subject: [PATCH 660/764] Upgrade to TypeScript 5.5 (#1562) --- package-lock.json | 2206 ++++++++++++----- package.json | 11 +- src/lualib-build/plugin.ts | 2 +- src/transformation/context/context.ts | 3 - src/transformation/visitors/class/index.ts | 19 +- src/transformation/visitors/modules/export.ts | 4 - 6 files changed, 1642 insertions(+), 603 deletions(-) diff --git a/package-lock.json b/package-lock.json index e376b5d12..af3e2de18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,10 +25,8 @@ "@types/node": "^13.7.7", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", - "eslint": "^8.47.0", - "eslint-plugin-import": "^2.27.5", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", @@ -39,13 +37,14 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.4.2" + "typescript": "^5.5.2", + "typescript-eslint": "^7.13.1" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.4.2" + "typescript": "5.5.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -759,9 +758,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", - "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" @@ -774,18 +773,18 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", - "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -806,22 +805,23 @@ } }, "node_modules/@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", "dev": true, "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { @@ -842,9 +842,10 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", "dev": true }, "node_modules/@istanbuljs/load-nyc-config": { @@ -1581,6 +1582,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -1615,6 +1618,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -1659,6 +1664,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "optional": true, + "peer": true, "dependencies": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -1769,6 +1776,12 @@ "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "node_modules/acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -1891,16 +1904,33 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" }, "engines": { @@ -1919,15 +1949,35 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -1938,14 +1988,14 @@ } }, "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" }, "engines": { @@ -1955,11 +2005,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, "engines": { "node": ">= 0.4" }, @@ -2075,12 +2150,12 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2142,13 +2217,19 @@ "dev": true }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2314,6 +2395,57 @@ "node": ">= 8" } }, + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -2352,12 +2484,30 @@ "node": ">=0.10.0" } }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -2465,44 +2615,57 @@ } }, "node_modules/es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.15" }, "engines": { "node": ">= 0.4" @@ -2511,27 +2674,60 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { "node": ">= 0.4" } }, "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "dependencies": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "node_modules/es-to-primitive": { @@ -2573,18 +2769,19 @@ } }, "node_modules/eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -2627,14 +2824,14 @@ } }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -2647,9 +2844,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "dependencies": { "debug": "^3.2.7" @@ -2673,26 +2870,28 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { "node": ">=4" @@ -3091,9 +3290,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "dependencies": { "to-regex-range": "^5.0.1" @@ -3181,20 +3380,23 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" }, "engines": { "node": ">= 0.4" @@ -3231,14 +3433,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3266,13 +3473,14 @@ } }, "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" }, "engines": { "node": ">= 0.4" @@ -3314,9 +3522,9 @@ } }, "node_modules/globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -3329,12 +3537,13 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3386,17 +3595,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -3416,21 +3614,21 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -3452,12 +3650,12 @@ } }, "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "dependencies": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -3466,6 +3664,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3482,9 +3691,9 @@ } }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -3551,13 +3760,13 @@ "dev": true }, "node_modules/internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "dependencies": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" }, "engines": { @@ -3565,14 +3774,16 @@ } }, "node_modules/is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "dependencies": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3625,11 +3836,26 @@ } }, "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, "dependencies": { - "has": "^1.0.3" + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3690,9 +3916,9 @@ } }, "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true, "engines": { "node": ">= 0.4" @@ -3751,12 +3977,15 @@ } }, "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3805,16 +4034,12 @@ } }, "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.14" }, "engines": { "node": ">= 0.4" @@ -3835,6 +4060,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -5080,7 +5311,9 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node_modules/node-int64": { "version": "0.4.0", @@ -5116,9 +5349,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5134,13 +5367,13 @@ } }, "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" }, @@ -5151,15 +5384,47 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -5409,6 +5674,15 @@ "node": ">=8" } }, + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5473,9 +5747,9 @@ } }, "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "engines": { "node": ">=6" @@ -5524,14 +5798,15 @@ "dev": true }, "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { "node": ">= 0.4" @@ -5550,11 +5825,11 @@ } }, "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "dependencies": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -5652,28 +5927,46 @@ "queue-microtask": "^1.2.2" } }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "dependencies": { - "lru-cache": "^6.0.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true, "bin": { "semver": "bin/semver.js" }, @@ -5681,23 +5974,37 @@ "node": ">=10" } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "dependencies": { - "yallist": "^4.0.0" + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" } }, - "node_modules/semver/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/shebang-command": { "version": "2.0.0", @@ -5721,14 +6028,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5836,29 +6147,50 @@ "node": ">=8" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5984,6 +6316,18 @@ "node": ">=8.0" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-jest": { "version": "29.1.0", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", @@ -6071,13 +6415,13 @@ } }, "node_modules/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "dependencies": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" } @@ -6157,24 +6501,83 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "dependencies": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -6184,6 +6587,241 @@ "node": ">=14.17" } }, + "node_modules/typescript-eslint": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", + "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "7.13.1", + "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/utils": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", + "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "dev": true, + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/type-utils": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", + "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", + "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", + "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -6304,17 +6942,16 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -6971,24 +7608,24 @@ } }, "@eslint-community/eslint-utils": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.3.0.tgz", - "integrity": "sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, "requires": { "eslint-visitor-keys": "^3.3.0" } }, "@eslint-community/regexpp": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.7.0.tgz", - "integrity": "sha512-+HencqxU7CFJnQb7IKtuNBqS6Yx3Tz4kOL8BJXo+JyeiBm5MEX6pO8onXDkjrkCRlfYXS1Axro15ZjVFe9YgsA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", "dev": true }, "@eslint/eslintrc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz", - "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -7003,19 +7640,19 @@ } }, "@eslint/js": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.47.0.tgz", - "integrity": "sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", "dev": true }, "@humanwhocodes/config-array": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", - "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", "dev": true, "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" } }, @@ -7026,9 +7663,9 @@ "dev": true }, "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", "dev": true }, "@istanbuljs/load-nyc-config": { @@ -7659,6 +8296,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", "dev": true, + "optional": true, + "peer": true, "requires": { "@eslint-community/regexpp": "^4.4.0", "@typescript-eslint/scope-manager": "5.62.0", @@ -7677,6 +8316,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -7699,6 +8340,8 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dev": true, + "optional": true, + "peer": true, "requires": { "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", @@ -7758,6 +8401,12 @@ "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true + }, "acorn": { "version": "8.10.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", @@ -7843,16 +8492,27 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "dev": true, + "requires": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + } + }, "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", "is-string": "^1.0.7" } }, @@ -7862,35 +8522,68 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + } + }, "array.prototype.flat": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", - "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", "es-shim-unscopables": "^1.0.0" } }, + "arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + } + }, "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "requires": { + "possible-typed-array-names": "^1.0.0" + } }, "babel-jest": { "version": "29.5.0", @@ -7979,12 +8672,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -8024,13 +8717,16 @@ "dev": true }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "callsites": { @@ -8146,6 +8842,39 @@ "which": "^2.0.1" } }, + "data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, + "data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "dev": true, + "requires": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -8173,12 +8902,24 @@ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true }, + "define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "define-properties": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz", - "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", "dev": true, "requires": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" } @@ -8256,64 +8997,101 @@ } }, "es-abstract": { - "version": "1.21.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.1.tgz", - "integrity": "sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-set-tostringtag": "^2.0.1", + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "dev": true, + "requires": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", "globalthis": "^1.0.3", "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-proto": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", "has-symbols": "^1.0.3", - "internal-slot": "^1.0.4", - "is-array-buffer": "^3.0.1", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", + "is-shared-array-buffer": "^1.0.3", "is-string": "^1.0.7", - "is-typed-array": "^1.1.10", + "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", + "object-inspect": "^1.13.1", "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "typed-array-length": "^1.0.4", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.9" + "which-typed-array": "^1.1.15" + } + }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, + "es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "dev": true, + "requires": { + "es-errors": "^1.3.0" } }, "es-set-tostringtag": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz", - "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", "dev": true, "requires": { - "get-intrinsic": "^1.1.3", - "has": "^1.0.3", - "has-tostringtag": "^1.0.0" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" } }, "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, "requires": { - "has": "^1.0.3" + "hasown": "^2.0.0" } }, "es-to-primitive": { @@ -8340,18 +9118,19 @@ "dev": true }, "eslint": { - "version": "8.47.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.47.0.tgz", - "integrity": "sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.2", - "@eslint/js": "^8.47.0", - "@humanwhocodes/config-array": "^0.11.10", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", + "@ungap/structured-clone": "^1.2.0", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -8403,14 +9182,14 @@ } }, "eslint-import-resolver-node": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz", - "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, "requires": { "debug": "^3.2.7", - "is-core-module": "^2.11.0", - "resolve": "^1.22.1" + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" }, "dependencies": { "debug": { @@ -8425,9 +9204,9 @@ } }, "eslint-module-utils": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", - "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, "requires": { "debug": "^3.2.7" @@ -8445,26 +9224,28 @@ } }, "eslint-plugin-import": { - "version": "2.27.5", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz", - "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", "dev": true, "requires": { - "array-includes": "^3.1.6", - "array.prototype.flat": "^1.3.1", - "array.prototype.flatmap": "^1.3.1", + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", "debug": "^3.2.7", "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.7", - "eslint-module-utils": "^2.7.4", - "has": "^1.0.3", - "is-core-module": "^2.11.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", - "object.values": "^1.1.6", - "resolve": "^1.22.1", - "semver": "^6.3.0", - "tsconfig-paths": "^3.14.1" + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "dependencies": { "debug": { @@ -8742,9 +9523,9 @@ } }, "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1" @@ -8810,20 +9591,20 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" } }, "functions-have-names": { @@ -8845,14 +9626,16 @@ "dev": true }, "get-intrinsic": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz", - "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-package-type": { @@ -8868,13 +9651,14 @@ "dev": true }, "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" } }, "glob": { @@ -8901,21 +9685,22 @@ } }, "globals": { - "version": "13.21.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", - "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", "dev": true, "requires": { "type-fest": "^0.20.2" } }, "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", "dev": true, "requires": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" } }, "globby": { @@ -8952,14 +9737,6 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, "has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -8973,18 +9750,18 @@ "dev": true }, "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "requires": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" } }, "has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true }, "has-symbols": { @@ -8994,12 +9771,20 @@ "dev": true }, "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "requires": { - "has-symbols": "^1.0.2" + "has-symbols": "^1.0.3" + } + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "requires": { + "function-bind": "^1.1.2" } }, "html-escaper": { @@ -9015,9 +9800,9 @@ "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true }, "import-fresh": { @@ -9063,25 +9848,24 @@ "dev": true }, "internal-slot": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz", - "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", "dev": true, "requires": { - "get-intrinsic": "^1.2.0", - "has": "^1.0.3", + "es-errors": "^1.3.0", + "hasown": "^2.0.0", "side-channel": "^1.0.4" } }, "is-array-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.1.tgz", - "integrity": "sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, "requires": { "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-typed-array": "^1.1.10" + "get-intrinsic": "^1.2.1" } }, "is-arrayish": { @@ -9116,11 +9900,20 @@ "dev": true }, "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "requires": { + "hasown": "^2.0.0" + } + }, + "is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "dev": true, "requires": { - "has": "^1.0.3" + "is-typed-array": "^1.1.13" } }, "is-date-object": { @@ -9160,9 +9953,9 @@ } }, "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", "dev": true }, "is-number": { @@ -9197,12 +9990,12 @@ } }, "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", "dev": true, "requires": { - "call-bind": "^1.0.2" + "call-bind": "^1.0.7" } }, "is-stream": { @@ -9230,16 +10023,12 @@ } }, "is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" + "which-typed-array": "^1.1.14" } }, "is-weakref": { @@ -9251,6 +10040,12 @@ "call-bind": "^1.0.2" } }, + "isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -10227,7 +11022,9 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true + "dev": true, + "optional": true, + "peer": true }, "node-int64": { "version": "0.4.0", @@ -10257,9 +11054,9 @@ } }, "object-inspect": { - "version": "1.12.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", - "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "object-keys": { @@ -10269,26 +11066,49 @@ "dev": true }, "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", "has-symbols": "^1.0.3", "object-keys": "^1.1.1" } }, + "object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + } + }, + "object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + } + }, "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "once": { @@ -10462,6 +11282,12 @@ } } }, + "possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "dev": true + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -10504,9 +11330,9 @@ } }, "punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true }, "pure-rand": { @@ -10528,14 +11354,15 @@ "dev": true }, "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" } }, "require-directory": { @@ -10545,11 +11372,11 @@ "dev": true }, "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", "requires": { - "is-core-module": "^2.9.0", + "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" } @@ -10607,41 +11434,59 @@ "queue-microtask": "^1.2.2" } }, + "safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + } + }, "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", "is-regex": "^1.1.4" } }, "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "dev": true + }, + "set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "requires": { - "lru-cache": "^6.0.0" - }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, + "set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" } }, "shebang-command": { @@ -10660,14 +11505,15 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { @@ -10755,26 +11601,38 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + } + }, "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", "dev": true, "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" } }, "strip-ansi": { @@ -10861,6 +11719,13 @@ "is-number": "^7.0.0" } }, + "ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "requires": {} + }, "ts-jest": { "version": "29.1.0", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", @@ -10899,13 +11764,13 @@ } }, "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", "dev": true, "requires": { "@types/json5": "^0.0.29", - "json5": "^1.0.1", + "json5": "^1.0.2", "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, @@ -10963,23 +11828,191 @@ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true }, + "typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "dev": true, + "requires": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, + "typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + } + }, "typed-array-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", - "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", "dev": true, "requires": { - "call-bind": "^1.0.2", + "call-bind": "^1.0.7", "for-each": "^0.3.3", - "is-typed-array": "^1.1.9" + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" } }, "typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", + "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", "dev": true }, + "typescript-eslint": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", + "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "7.13.1", + "@typescript-eslint/parser": "7.13.1", + "@typescript-eslint/utils": "7.13.1" + }, + "dependencies": { + "@typescript-eslint/eslint-plugin": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", + "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "dev": true, + "requires": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/type-utils": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/parser": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", + "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", + "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", + "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "7.13.1", + "@typescript-eslint/utils": "7.13.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", + "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/visitor-keys": "7.13.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" + } + }, + "@typescript-eslint/utils": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", + "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", + "dev": true, + "requires": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "7.13.1", + "@typescript-eslint/types": "7.13.1", + "@typescript-eslint/typescript-estree": "7.13.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", + "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "7.13.1", + "eslint-visitor-keys": "^3.4.3" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11066,17 +12099,16 @@ } }, "which-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz", - "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==", + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", "dev": true, "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", "for-each": "^0.3.3", "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.10" + "has-tostringtag": "^1.0.2" } }, "wrap-ansi": { diff --git a/package.json b/package.json index 42479a8ad..aa5637bb8 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.4.2" + "typescript": "5.5.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -58,10 +58,8 @@ "@types/node": "^13.7.7", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "@typescript-eslint/eslint-plugin": "^5.62.0", - "@typescript-eslint/parser": "^5.62.0", - "eslint": "^8.47.0", - "eslint-plugin-import": "^2.27.5", + "eslint": "^8.57.0", + "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^26.9.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", @@ -72,6 +70,7 @@ "prettier": "^2.8.4", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.4.2" + "typescript": "^5.5.2", + "typescript-eslint": "^7.13.1" } } diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index d301e657e..48f649fdb 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -121,7 +121,7 @@ class LuaLibPlugin implements tstl.Plugin { } return statement; }) - .filter(statement => statement !== undefined) as tstl.Statement[]; + .filter(statement => statement !== undefined); const exportNames = filteredStatements.filter(isExportAssignment).map(s => s.left[0].index.value); if (!filteredStatements.every(isExportAssignment)) { diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 4ee8c04a5..694e7e9a9 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -15,7 +15,6 @@ export const tempSymbolId = -1 as lua.SymbolId; export interface AllAccessorDeclarations { firstAccessor: ts.AccessorDeclaration; - secondAccessor: ts.AccessorDeclaration | undefined; getAccessor: ts.GetAccessorDeclaration | undefined; setAccessor: ts.SetAccessorDeclaration | undefined; } @@ -24,8 +23,6 @@ export interface EmitResolver { isValueAliasDeclaration(node: ts.Node): boolean; isReferencedAliasDeclaration(node: ts.Node, checkChildren?: boolean): boolean; isTopLevelValueImportEqualsWithEntityName(node: ts.ImportEqualsDeclaration): boolean; - moduleExportsSomeValue(moduleReferenceExpression: ts.Expression): boolean; - getAllAccessorDeclarations(declaration: ts.AccessorDeclaration): AllAccessorDeclarations; } export interface TypeCheckerWithEmitResolver extends ts.TypeChecker { diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 8c54afe12..23e354460 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; -import { FunctionVisitor, TransformationContext } from "../../context"; +import { AllAccessorDeclarations, FunctionVisitor, TransformationContext } from "../../context"; import { createDefaultExportExpression, createExportedIdentifier, @@ -175,7 +175,7 @@ function transformClassLikeDeclaration( for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { // Accessors - const accessors = context.resolver.getAllAccessorDeclarations(member); + const accessors = getAllAccessorDeclarations(classDeclaration); if (accessors.firstAccessor !== member) continue; const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); @@ -227,6 +227,21 @@ function transformClassLikeDeclaration( return { statements: result, name: className }; } +function getAllAccessorDeclarations(classDeclaration: ts.ClassLikeDeclaration): AllAccessorDeclarations { + const getAccessor = classDeclaration.members.find(ts.isGetAccessor); + const setAccessor = classDeclaration.members.find(ts.isSetAccessor); + + // Get the first of the two (that is not undefined) + const firstAccessor = + getAccessor && (!setAccessor || getAccessor.pos < setAccessor.pos) ? getAccessor : setAccessor!; + + return { + firstAccessor, + setAccessor, + getAccessor, + }; +} + export const transformSuperExpression: FunctionVisitor = (expression, context) => { const superInfos = context.classSuperInfos; const superInfo = superInfos[superInfos.length - 1]; diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index c32551aaf..6908a8727 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -39,10 +39,6 @@ export const transformExportAssignment: FunctionVisitor = ( function transformExportAll(context: TransformationContext, node: ts.ExportDeclaration): lua.Statement | undefined { assert(node.moduleSpecifier); - if (!context.resolver.moduleExportsSomeValue(node.moduleSpecifier)) { - return undefined; - } - const moduleRequire = createModuleRequire(context, node.moduleSpecifier); // export * as ns from "..."; From e766d1c103a8cf3d181bbd5d5f285b78613b24e3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 23 Jun 2024 17:29:06 +0200 Subject: [PATCH 661/764] Support for new ecmascript Set methods (#1563) --- src/lualib/Set.ts | 86 +++++++++++++ test/unit/builtins/set.spec.ts | 218 +++++++++++++++++++++++++++++++++ 2 files changed, 304 insertions(+) diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index 1f525ce3d..b46555edf 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -145,4 +145,90 @@ export class Set { }, }; } + + /** + * @returns a new Set containing all the elements in this Set and also all the elements in the argument. + */ + public union(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + result.add(item); + } + return result; + } + + /** + * @returns a new Set containing all the elements which are both in this Set and in the argument. + */ + public intersection(other: ReadonlySet) { + const result = new Set(); + for (const item of this) { + if (other.has(item)) { + result.add(item); + } + } + return result; + } + + /** + * @returns a new Set containing all the elements in this Set which are not also in the argument. + */ + public difference(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + result.delete(item); + } + return result; + } + + /** + * @returns a new Set containing all the elements which are in either this Set or in the argument, but not in both. + */ + public symmetricDifference(other: ReadonlySet): Set { + const result = new Set(this); + for (const item of other) { + if (this.has(item)) { + result.delete(item); + } else { + result.add(item); + } + } + return result; + } + + /** + * @returns a boolean indicating whether all the elements in this Set are also in the argument. + */ + public isSubsetOf(other: ReadonlySet): boolean { + for (const item of this) { + if (!other.has(item)) { + return false; + } + } + return true; + } + + /** + * @returns a boolean indicating whether all the elements in the argument are also in this Set. + */ + public isSupersetOf(other: ReadonlySet): boolean { + for (const item of other) { + if (!this.has(item as T)) { + return false; + } + } + return true; + } + + /** + * @returns a boolean indicating whether this Set has no elements in common with the argument. + */ + public isDisjointFrom(other: ReadonlySetLike): boolean { + for (const item of this) { + if (other.has(item)) { + return false; + } + } + return true; + } } diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index 93e23e98e..a03f27ab2 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -201,3 +201,221 @@ test("instanceof Set without creating set", () => { return myset instanceof Set; `.expectToMatchJsResult(); }); + +describe("new ECMAScript Set methods", () => { + test("union", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); + + test("union with empty sets", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 4, 5, 6]); + + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.union(set2); + return [...intersection]; + `.expectToEqual([4, 5, 6, 7, 8, 9]); + }); + + test("intersection", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([4, 5, 6]); + }); + + test("intersection with empty sets", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([]); + + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.intersection(set2); + return [...intersection]; + `.expectToEqual([]); + }); + + test("difference", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.difference(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3]); + }); + + test("symmetricDifference", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6]); + const set2 = new Set([4,5,6,7,8,9]); + + const intersection = set1.symmetricDifference(set2); + return [...intersection]; + `.expectToEqual([1, 2, 3, 7, 8, 9]); + }); + + test("isSubsetOf", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: false, + }); + }); + + test("isSubsetOf equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: true, + }); + }); + + test("isSubsetOf empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1SubsetOfSet2: set1.isSubsetOf(set2), + set2SubsetOfSet1: set2.isSubsetOf(set1), + }; + `.expectToEqual({ + set1SubsetOfSet2: true, + set2SubsetOfSet1: false, + }); + }); + + test("isSupersetOf", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: false, + set2SupersetOfSet1: true, + }); + }); + + test("isSupersetOf equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: true, + set2SupersetOfSet1: true, + }); + }); + + test("isSupersetOf empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1SupersetOfSet2: set1.isSupersetOf(set2), + set2SupersetOfSet1: set2.isSupersetOf(set1), + }; + `.expectToEqual({ + set1SupersetOfSet2: false, + set2SupersetOfSet1: true, + }); + }); + + test("isDisjointFrom", () => { + util.testFunction` + const set1 = new Set([3,4,5,6]); + const set2 = new Set([7,8,9]); + const set3 = new Set([1,2,3,4]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + set1DisjointFromSet3: set1.isDisjointFrom(set3), + set3DisjointFromSet1: set3.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: true, + set2DisjointFromSet1: true, + set1DisjointFromSet3: false, + set3DisjointFromSet1: false, + }); + }); + + test("isDisjointFrom equal", () => { + util.testFunction` + const set1 = new Set([1,2,3,4,5,6,7,8,9]); + const set2 = new Set([1,2,3,4,5,6,7,8,9]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: false, + set2DisjointFromSet1: false, + }); + }); + + test("isDisjointFrom empty", () => { + util.testFunction` + const set1 = new Set([]); + const set2 = new Set([1,2,3]); + + return { + set1DisjointFromSet2: set1.isDisjointFrom(set2), + set2DisjointFromSet1: set2.isDisjointFrom(set1), + }; + `.expectToEqual({ + set1DisjointFromSet2: true, + set2DisjointFromSet1: true, + }); + }); +}); From 00f42a037226009228df9945cdf26388141c3a65 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 23 Jun 2024 17:33:53 +0200 Subject: [PATCH 662/764] CHANGELOG.md 1.26.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb53c4565..041681d81 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.26.0 + +- Upgraded TypeScript to 5.5.2 +- Added support for the new proposed ECMAScript Set methods in ESNext: `intersection`, `union`, `difference`, `symmetricDifference`, `isSubsetOf`, `isSupersetOf`, `isDisjointFrom`. For more info see [the TypeScript release notes](https://devblogs.microsoft.com/typescript/announcing-typescript-5-5/#support-for-new-ecmascript-set-methods). +- Fixed a bug causing bundled code to be executed twice in some edge cases. +- Fixed a bug causing errors when using lualib in an environment without coroutines. + ## 1.25.0 - Upgraded TypeScript to 5.4.2 From d6f1bb0ac269653321df1a8371d14a90cdbe6435 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 23 Jun 2024 17:36:22 +0200 Subject: [PATCH 663/764] 1.26.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index af3e2de18..0ced24459 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.25.2", + "version": "1.26.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.25.2", + "version": "1.26.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index aa5637bb8..3dbacf4c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.25.2", + "version": "1.26.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5ba1facbebdd685b2852dbf10531bdf8dceb745b Mon Sep 17 00:00:00 2001 From: Lorenz Junglas <4759511+lolleko@users.noreply.github.com> Date: Tue, 9 Jul 2024 17:33:31 +0200 Subject: [PATCH 664/764] Add lualib support for Math.trunc (#1564) Also includes a small fix that makes `Math.sign` ECMA compliant Closes #1550 --- src/LuaLib.ts | 1 + src/lualib/MathSign.ts | 14 ++++++++++---- src/lualib/MathTrunc.ts | 10 ++++++++++ src/transformation/builtins/math.ts | 4 ++++ test/unit/builtins/math.spec.ts | 15 ++++++++++++++- 5 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 src/lualib/MathTrunc.ts diff --git a/src/LuaLib.ts b/src/LuaLib.ts index d051c60b4..6320bc99c 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -63,6 +63,7 @@ export enum LuaLibFeature { MathAtan2 = "MathAtan2", MathModf = "MathModf", MathSign = "MathSign", + MathTrunc = "MathTrunc", New = "New", Number = "Number", NumberIsFinite = "NumberIsFinite", diff --git a/src/lualib/MathSign.ts b/src/lualib/MathSign.ts index f3be69e8d..629895a11 100644 --- a/src/lualib/MathSign.ts +++ b/src/lualib/MathSign.ts @@ -1,9 +1,15 @@ +// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.sign + +import { __TS__NumberIsNaN } from "./NumberIsNaN"; + export function __TS__MathSign(this: void, val: number) { - if (val > 0) { - return 1; - } else if (val < 0) { + if (__TS__NumberIsNaN(val) || val === 0) { + return val; + } + + if (val < 0) { return -1; } - return 0; + return 1; } diff --git a/src/lualib/MathTrunc.ts b/src/lualib/MathTrunc.ts new file mode 100644 index 000000000..f244c2147 --- /dev/null +++ b/src/lualib/MathTrunc.ts @@ -0,0 +1,10 @@ +// https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-math.trunc + +import { __TS__NumberIsFinite } from "./NumberIsFinite"; +export function __TS__MathTrunc(this: void, val: number) { + if (!__TS__NumberIsFinite(val) || val === 0) { + return val; + } + + return val > 0 ? math.floor(val) : math.ceil(val); +} diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index 4be4e77cb..ab831d52f 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -100,6 +100,10 @@ export function transformMathCall( return transformLuaLibFunction(context, LuaLibFeature.MathSign, node, ...params); } + case "trunc": { + return transformLuaLibFunction(context, LuaLibFeature.MathTrunc, node, ...params); + } + case "abs": case "acos": case "asin": diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index 3126a85ca..aebaead4c 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -51,6 +51,12 @@ test.each([ // sqrt "Math.sqrt(2)", "Math.sqrt(-2)", + // trunc + "Math.trunc(42.42)", + "Math.trunc(-42.42)", + "Math.trunc(0)", + "Math.trunc(Infinity)", + "Math.trunc(-Infinity)", ])("%s", code => { util.testExpression(code).expectToMatchJsResult(); }); @@ -65,7 +71,14 @@ test.each(["E", "LN10", "LN2", "LOG10E", "LOG2E", "SQRT1_2", "SQRT2"])("Math.%s" }); // LuaLib MathSign -test.each(["Math.sign(-42)", "Math.sign(42)", "Math.sign(-4.2)", "Math.sign(4.2)", "Math.sign(0)"])("%s", code => { +test.each([ + "Math.sign(-42)", + "Math.sign(42)", + "Math.sign(-4.2)", + "Math.sign(4.2)", + "Math.sign(0)", + "Math.sign(-Infinity)", +])("%s", code => { util.testExpression(code).expectToMatchJsResult(); }); From b464bc45db81aaf18234e5970d76dcdf03715090 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 11 Jul 2024 21:53:16 +0200 Subject: [PATCH 665/764] 1.26.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0ced24459..e2b059090 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.26.0", + "version": "1.26.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.26.0", + "version": "1.26.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 3dbacf4c7..8a10bf94c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.26.0", + "version": "1.26.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 8ddfbc0a8915de34e6959d7e3bba13d8f1200fdb Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 29 Jul 2024 20:33:43 +0200 Subject: [PATCH 666/764] Fix multiple getters and setters (#1567) * Fix multiple getters and setters * Fix lint --- src/transformation/visitors/class/index.ts | 20 ++++++++++--- test/unit/classes/accessors.spec.ts | 33 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 23e354460..0edfce050 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -175,7 +175,9 @@ function transformClassLikeDeclaration( for (const member of classDeclaration.members) { if (ts.isAccessor(member)) { // Accessors - const accessors = getAllAccessorDeclarations(classDeclaration); + const symbol = context.checker.getSymbolAtLocation(member.name); + if (!symbol) continue; + const accessors = getAllAccessorDeclarations(classDeclaration, symbol, context); if (accessors.firstAccessor !== member) continue; const accessorsResult = transformAccessorDeclarations(context, accessors, localClassName); @@ -227,9 +229,19 @@ function transformClassLikeDeclaration( return { statements: result, name: className }; } -function getAllAccessorDeclarations(classDeclaration: ts.ClassLikeDeclaration): AllAccessorDeclarations { - const getAccessor = classDeclaration.members.find(ts.isGetAccessor); - const setAccessor = classDeclaration.members.find(ts.isSetAccessor); +function getAllAccessorDeclarations( + classDeclaration: ts.ClassLikeDeclaration, + symbol: ts.Symbol, + context: TransformationContext +): AllAccessorDeclarations { + const getAccessor = classDeclaration.members.find( + (m): m is ts.GetAccessorDeclaration => + ts.isGetAccessor(m) && context.checker.getSymbolAtLocation(m.name) === symbol + ); + const setAccessor = classDeclaration.members.find( + (m): m is ts.SetAccessorDeclaration => + ts.isSetAccessor(m) && context.checker.getSymbolAtLocation(m.name) === symbol + ); // Get the first of the two (that is not undefined) const firstAccessor = diff --git a/test/unit/classes/accessors.spec.ts b/test/unit/classes/accessors.spec.ts index 203fc1c9b..db17fe67d 100644 --- a/test/unit/classes/accessors.spec.ts +++ b/test/unit/classes/accessors.spec.ts @@ -11,6 +11,19 @@ test("get accessor", () => { `.expectToMatchJsResult(); }); +test("multiple get accessors", () => { + util.testFunction` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + _bar = "bar"; + get bar() { return this._bar; } + } + const f = new Foo(); + return f.foo + f.bar; + `.expectToMatchJsResult(); +}); + test("get accessor in base class", () => { util.testFunction` class Foo { @@ -142,6 +155,26 @@ test("get/set accessors", () => { `.expectToMatchJsResult(); }); +test("multiple get/set accessors", () => { + util.testFunction` + class Foo { + _foo = "foo"; + get foo() { return this._foo; } + set foo(val: string) { this._foo = val; } + + _bar = "bar"; + get bar() { return this._bar; } + set bar(val: string) { this._bar = val; } + } + const f = new Foo(); + const fooOriginal = f.foo; + f.foo = "fizz"; + const barOriginal = f.bar; + f.bar = "buzz"; + return [fooOriginal, f.foo, barOriginal, f.bar]; + `.expectToMatchJsResult(); +}); + test("get/set accessors in base class", () => { util.testFunction` class Foo { From da0774c3431a36b81dad162c5578392aaa18c12f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 29 Jul 2024 20:36:00 +0200 Subject: [PATCH 667/764] 1.26.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index e2b059090..a5e8d5c45 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.26.1", + "version": "1.26.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.26.1", + "version": "1.26.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 8a10bf94c..efe35e875 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.26.1", + "version": "1.26.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 920f3e56bba9df041c947410c095accdc1db88d0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 17:43:54 +0200 Subject: [PATCH 668/764] Upgrade to TypeScript 5.6 (#1581) * Upgrade to TypeScript 5.6 * Fix ts version * ignore prettier for test file --- .prettierignore | 1 + package-lock.json | 30 +++---- package.json | 6 +- src/transformation/visitors/modules/export.ts | 88 +++++++++++-------- .../__snapshots__/transformation.spec.ts.snap | 17 ++-- .../transformation/exportStatement.ts | 2 + test/unit/conditionals.spec.ts | 5 +- test/unit/language-extensions/table.spec.ts | 1 + test/unit/nullishCoalescing.spec.ts | 18 +++- test/unit/precedingStatements.spec.ts | 12 ++- test/unit/printer/semicolons.spec.ts | 1 + 11 files changed, 112 insertions(+), 69 deletions(-) diff --git a/.prettierignore b/.prettierignore index 656f1a4d6..fb6d91319 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,7 @@ /dist /coverage /test/translation/transformation/characterEscapeSequence.ts +/test/translation/transformation/exportStatement.ts /benchmark/dist /test/transpile/module-resolution/**/node_modules /test/transpile/module-resolution/**/dist diff --git a/package-lock.json b/package-lock.json index a5e8d5c45..0f6d42d97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,17 +34,17 @@ "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", - "prettier": "^2.8.4", + "prettier": "^2.8.8", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.5.2", + "typescript": "^5.6.2", "typescript-eslint": "^7.13.1" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.5.2" + "typescript": "5.6.2" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -5693,9 +5693,9 @@ } }, "node_modules/prettier": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", - "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -6575,9 +6575,9 @@ } }, "node_modules/typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -11295,9 +11295,9 @@ "dev": true }, "prettier": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.4.tgz", - "integrity": "sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "pretty-format": { @@ -11881,9 +11881,9 @@ } }, "typescript": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", - "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", + "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true }, "typescript-eslint": { diff --git a/package.json b/package.json index efe35e875..231eb7a50 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.5.2" + "typescript": "5.6.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -67,10 +67,10 @@ "jest-circus": "^29.5.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", - "prettier": "^2.8.4", + "prettier": "^2.8.8", "ts-jest": "^29.1.0", "ts-node": "^10.9.1", - "typescript": "^5.5.2", + "typescript": "^5.6.2", "typescript-eslint": "^7.13.1" } } diff --git a/src/transformation/visitors/modules/export.ts b/src/transformation/visitors/modules/export.ts index 6908a8727..c814b8257 100644 --- a/src/transformation/visitors/modules/export.ts +++ b/src/transformation/visitors/modules/export.ts @@ -2,17 +2,12 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { assert } from "../../../utils"; import { FunctionVisitor, TransformationContext } from "../../context"; -import { - createDefaultExportExpression, - createDefaultExportStringLiteral, - createExportedIdentifier, -} from "../../utils/export"; +import { createDefaultExportExpression, createDefaultExportStringLiteral } from "../../utils/export"; import { createExportsIdentifier } from "../../utils/lua-ast"; -import { ScopeType } from "../../utils/scope"; -import { transformScopeBlock } from "../block"; -import { transformIdentifier } from "../identifier"; -import { createShorthandIdentifier } from "../literal"; +import { createShorthandIdentifier, transformPropertyName } from "../literal"; import { createModuleRequire } from "./import"; +import { createSafeName } from "../../utils/safe-names"; +import * as path from "path"; export const transformExportAssignment: FunctionVisitor = (node, context) => { if (!context.resolver.isValueAliasDeclaration(node)) { @@ -101,20 +96,37 @@ function transformExportAll(context: TransformationContext, node: ts.ExportDecla } const isDefaultExportSpecifier = (node: ts.ExportSpecifier) => - (node.name && ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) || - (node.propertyName && ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword); + (node.name && + ts.isIdentifier(node.name) && + ts.identifierToKeywordKind(node.name) === ts.SyntaxKind.DefaultKeyword) || + (node.propertyName && + ts.isIdentifier(node.propertyName) && + ts.identifierToKeywordKind(node.propertyName) === ts.SyntaxKind.DefaultKeyword); function transformExportSpecifier(context: TransformationContext, node: ts.ExportSpecifier): lua.AssignmentStatement { - const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); - const exportedIdentifier = node.propertyName ? node.propertyName : node.name; - const exportedExpression = createShorthandIdentifier(context, exportedSymbol, exportedIdentifier); + const exportedName = node.name; + const exportedValue = node.propertyName ?? node.name; + let rhs: lua.Expression; + if (ts.isIdentifier(exportedValue)) { + const exportedSymbol = context.checker.getExportSpecifierLocalTargetSymbol(node); + rhs = createShorthandIdentifier(context, exportedSymbol, exportedValue); + } else { + rhs = lua.createStringLiteral(exportedName.text, exportedValue); + } - const isDefault = isDefaultExportSpecifier(node); - const exportAssignmentLeftHandSide = isDefault - ? createDefaultExportExpression(node) - : createExportedIdentifier(context, transformIdentifier(context, node.name)); + if (isDefaultExportSpecifier(node)) { + const lhs = createDefaultExportExpression(node); + return lua.createAssignmentStatement(lhs, rhs, node); + } else { + const exportsTable = createExportsIdentifier(); + const lhs = lua.createTableIndexExpression( + exportsTable, + lua.createStringLiteral(exportedName.text), + exportedName + ); - return lua.createAssignmentStatement(exportAssignmentLeftHandSide, exportedExpression, node); + return lua.createAssignmentStatement(lhs, rhs, node); + } } function transformExportSpecifiersFrom( @@ -123,32 +135,32 @@ function transformExportSpecifiersFrom( moduleSpecifier: ts.Expression, exportSpecifiers: ts.ExportSpecifier[] ): lua.Statement { - // First transpile as import clause - const importClause = ts.factory.createImportClause( - false, - undefined, - ts.factory.createNamedImports( - exportSpecifiers.map(s => ts.factory.createImportSpecifier(statement.isTypeOnly, s.propertyName, s.name)) - ) - ); + const result: lua.Statement[] = []; - const importDeclaration = ts.factory.createImportDeclaration(statement.modifiers, importClause, moduleSpecifier); + const importPath = ts.isStringLiteral(moduleSpecifier) ? moduleSpecifier.text.replace(/"/g, "") : "module"; - // Wrap in block to prevent imports from hoisting out of `do` statement - const [block] = transformScopeBlock(context, ts.factory.createBlock([importDeclaration]), ScopeType.Block); - const result = block.statements; + // Create the require statement to extract values. + // local ____module = require("module") + const importUniqueName = lua.createIdentifier(createSafeName(path.basename(importPath))); + const requireCall = createModuleRequire(context, moduleSpecifier); + result.push(lua.createVariableDeclarationStatement(importUniqueName, requireCall, statement)); - // Now the module is imported, add the imports to the export table for (const specifier of exportSpecifiers) { - result.push( - lua.createAssignmentStatement( - createExportedIdentifier(context, transformIdentifier(context, specifier.name)), - transformIdentifier(context, specifier.name) - ) + // Assign to exports table + const exportsTable = createExportsIdentifier(); + const exportedName = specifier.name; + const exportedNameTransformed = transformPropertyName(context, exportedName); + const lhs = lua.createTableIndexExpression(exportsTable, exportedNameTransformed, exportedName); + + const exportedValue = specifier.propertyName ?? specifier.name; + const rhs = lua.createTableIndexExpression( + lua.cloneIdentifier(importUniqueName), + transformPropertyName(context, exportedValue), + specifier ); + result.push(lua.createAssignmentStatement(lhs, rhs, specifier)); } - // Wrap this in a DoStatement to prevent polluting the scope. return lua.createDoStatement(result, statement); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 2832f2cd6..b0c7eea52 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -41,15 +41,20 @@ do end do local ____xyz = require("xyz") - local abc = ____xyz.abc - local def = ____xyz.def - ____exports.abc = abc - ____exports.def = def + ____exports.abc = ____xyz.abc + ____exports.def = ____xyz.def end do local ____xyz = require("xyz") - local def = ____xyz.abc - ____exports.def = def + ____exports.def = ____xyz.abc +end +do + local ____bla = require("bla") + ____exports.bar = ____bla["123"] +end +do + local ____bla = require("bla") + ____exports["123"] = ____bla.foo end return ____exports" `; diff --git a/test/translation/transformation/exportStatement.ts b/test/translation/transformation/exportStatement.ts index 7aa965422..cf227da3d 100644 --- a/test/translation/transformation/exportStatement.ts +++ b/test/translation/transformation/exportStatement.ts @@ -4,3 +4,5 @@ export { xyz as uwv }; export * from "xyz"; export { abc, def } from "xyz"; export { abc as def } from "xyz"; +export { "123" as bar } from "bla"; +export { foo as "123" } from "bla"; diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index 5508748bc..f862ca8a3 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -90,7 +90,10 @@ test.each([ { condition: 3, lhs: 4, rhs: 5 }, ])("Ternary Conditional (%p)", ({ condition, lhs, rhs }) => { util.testExpressionTemplate`${condition} ? ${lhs} : ${rhs}` - .ignoreDiagnostics([truthyOnlyConditionalValue.code]) + .ignoreDiagnostics([ + truthyOnlyConditionalValue.code, + 2872 /* TS2872: This kind of expression is always truthy. */, + ]) .expectToMatchJsResult(); }); diff --git a/test/unit/language-extensions/table.spec.ts b/test/unit/language-extensions/table.spec.ts index 40e46d61e..13af766fa 100644 --- a/test/unit/language-extensions/table.spec.ts +++ b/test/unit/language-extensions/table.spec.ts @@ -338,6 +338,7 @@ describe("Table extensions use as expression", () => { ` .withLanguageExtensions() .setReturnExport("result") + .ignoreDiagnostics([2872 /* TS2872: This kind of expression is always truthy. */]) .expectToEqual(value); }); diff --git a/test/unit/nullishCoalescing.spec.ts b/test/unit/nullishCoalescing.spec.ts index 3728f2815..56db55332 100644 --- a/test/unit/nullishCoalescing.spec.ts +++ b/test/unit/nullishCoalescing.spec.ts @@ -1,18 +1,26 @@ import * as util from "../util"; test.each(["null", "undefined"])("nullish-coalesing operator returns rhs", nullishValue => { - util.testExpression`${nullishValue} ?? "Hello, World!"`.expectToMatchJsResult(); + util.testExpression`${nullishValue} ?? "Hello, World!"` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test.each([3, "foo", {}, [], true, false])("nullish-coalesing operator returns lhs", value => { - util.testExpression`${util.formatCode(value)} ?? "Hello, World!"`.expectToMatchJsResult(); + util.testExpression`${util.formatCode(value)} ?? "Hello, World!"` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); test.each(["any", "unknown"])("nullish-coalesing operator with any/unknown type", type => { util.testFunction` const unknownType = false as ${type}; return unknownType ?? "This should not be returned!"; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test.each(["boolean | string", "number | false", "undefined | true"])( @@ -38,7 +46,9 @@ test("nullish-coalescing operator with side effect rhs", () => { let i = 0; const incI = () => ++i; return [i, undefined ?? incI(), i]; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([2871 /* TS2871: This expression is always nullish. */]) + .expectToMatchJsResult(); }); test("nullish-coalescing operator with vararg", () => { diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts index f27d26494..1ce24da19 100644 --- a/test/unit/precedingStatements.spec.ts +++ b/test/unit/precedingStatements.spec.ts @@ -633,7 +633,11 @@ test("class member initializers", () => { } const inst = new MyClass(); return [inst.myField, inst.foo]; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); test("class member initializers in extended class", () => { @@ -644,5 +648,9 @@ test("class member initializers in extended class", () => { } const inst = new MyClass(); return inst.myField; - `.expectToMatchJsResult(); + ` + .ignoreDiagnostics([ + 2869 /* TS2869: Right operand of ?? is unreachable because the left operand is never nullish. */, + ]) + .expectToMatchJsResult(); }); diff --git a/test/unit/printer/semicolons.spec.ts b/test/unit/printer/semicolons.spec.ts index addb66e53..7be461d0f 100644 --- a/test/unit/printer/semicolons.spec.ts +++ b/test/unit/printer/semicolons.spec.ts @@ -10,6 +10,7 @@ test.each(["const a = 1; const b = a;", "const a = 1; let b: number; b = a;", "{ (undefined || foo)(); return result; ` + .ignoreDiagnostics([2873 /* TS2873: This kind of expression is always falsy. */]) .expectToMatchJsResult() .expectLuaToMatchSnapshot(); } From a2d31c95122c24f6edc0c64d8d7633e0c3497a01 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 17:44:07 +0200 Subject: [PATCH 669/764] Fix bug in await using transformer (#1579) --- .../pre-transformers/using-transformer.ts | 7 ++++--- test/unit/using.spec.ts | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/transformation/pre-transformers/using-transformer.ts b/src/transformation/pre-transformers/using-transformer.ts index 51908a40a..d78f6206a 100644 --- a/src/transformation/pre-transformers/using-transformer.ts +++ b/src/transformation/pre-transformers/using-transformer.ts @@ -18,7 +18,7 @@ export function usingTransformer(context: TransformationContext): ts.Transformer ts.setParent(node2, parent[parent.length - 1]); parent.push(node2); ts.visitEachChild(node2, setParent, ctx); - parent.push(); + parent.pop(); return node2; } ts.visitEachChild(updatedBlock, setParent, ctx); @@ -74,12 +74,13 @@ function transformBlockWithUsing( ); const callback = ts.factory.createFunctionExpression( - undefined, + // Put async keyword in front of callback when we are in an async using + isAwaitUsing ? [ts.factory.createModifier(ts.SyntaxKind.AsyncKeyword)] : undefined, undefined, undefined, undefined, variableNames, - undefined, + ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword), // Required for TS to not freak out trying to infer the type of synthetic nodes callbackBody ); diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts index c43120bd6..5182b8928 100644 --- a/test/unit/using.spec.ts +++ b/test/unit/using.spec.ts @@ -175,3 +175,21 @@ test("await using can handle non-async disposables", () => { .setTsHeader(usingTestLib) .expectToEqual({ logs: ["Creating a", "function content", "Disposing a"] }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1571 +test("await using no extra diagnostics (#1571)", () => { + util.testModule` + async function getResource(): Promise { + return { + [Symbol.asyncDispose]: async () => {} + }; + } + + async function someOtherAsync() {} + + async function main() { + await using resource = await getResource(); + await someOtherAsync(); + } + `.expectToHaveNoDiagnostics(); +}); From a07fed5825bc137928f370d04c1379283068cc0e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 17:44:21 +0200 Subject: [PATCH 670/764] Fix bug when using Array.from with non-array iterable (#1577) --- src/lualib/ArrayFrom.ts | 5 +++-- test/unit/builtins/array.spec.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/lualib/ArrayFrom.ts b/src/lualib/ArrayFrom.ts index 67e78d914..3742d7949 100644 --- a/src/lualib/ArrayFrom.ts +++ b/src/lualib/ArrayFrom.ts @@ -28,8 +28,9 @@ export function __TS__ArrayFrom( result.push(v); } } else { - for (const [i, v] of arrayLikeIterator(arrayLike)) { - result.push(mapFn.call(thisArg, v, i - 1)); + let i = 0; + for (const [, v] of arrayLikeIterator(arrayLike)) { + result.push(mapFn.call(thisArg, v, i++)); } } return result; diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index a59d1ee04..1e952a162 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -753,6 +753,14 @@ test.each([ util.testExpression`Array.from(${valueString})`.expectToMatchJsResult(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1576 +test("array.from with non-array iterable (#1576)", () => { + util.testFunction` + const map = new Map().set(1, 2); + return Array.from(map, ([v,k]) => ({k,v})); + `.expectToMatchJsResult(); +}); + // Array.of test.each(["1, 2, 3", "", "...[1, 2, 3], 4, 5, 6"])("Array.of(%p)", valueString => { util.testExpression`Array.of(${valueString})`.expectToMatchJsResult(); From a93ac8be14c783ac27ee7970b0664d894910227a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 17:44:36 +0200 Subject: [PATCH 671/764] Fix use of exported compileMembersOnly enums causing syntax errors (#1573) * Fix use of exported compileMembersOnly enums causing syntax errors * fix test * fix prettier --- src/transformation/visitors/access.ts | 20 ++++++++++++++++++-- test/unit/modules/modules.spec.ts | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index 8004d9f2d..c97c0f4c7 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -9,7 +9,7 @@ import { unsupportedOptionalCompileMembersOnly, } from "../utils/diagnostics"; import { getExtensionKindForNode } from "../utils/language-extensions"; -import { addToNumericExpression } from "../utils/lua-ast"; +import { addToNumericExpression, createExportsIdentifier } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isArrayType, isNumberType, isStringType } from "../utils/typescript"; import { tryGetConstEnumValue } from "./enum"; @@ -24,6 +24,7 @@ import { } from "./optional-chaining"; import { SyntaxKind } from "typescript"; import { getCustomNameFromSymbol } from "./identifier"; +import { getSymbolExportScope, isSymbolExported } from "../utils/export"; function addOneToArrayAccessArgument( context: TransformationContext, @@ -138,6 +139,7 @@ export function transformPropertyAccessExpressionWithCapture( if (isOptionalLeft) { context.diagnostics.push(unsupportedOptionalCompileMembersOnly(node)); } + if (ts.isPropertyAccessExpression(node.expression)) { // in case of ...x.enum.y transform to ...x.y const expression = lua.createTableIndexExpression( @@ -147,7 +149,21 @@ export function transformPropertyAccessExpressionWithCapture( ); return { expression }; } else { - return { expression: lua.createIdentifier(property, node) }; + // Check if we need to account for enum being exported int his file + if ( + isSymbolExported(context, type.symbol) && + getSymbolExportScope(context, type.symbol) === node.expression.getSourceFile() + ) { + return { + expression: lua.createTableIndexExpression( + createExportsIdentifier(), + lua.createStringLiteral(property), + node + ), + }; + } else { + return { expression: lua.createIdentifier(property, node) }; + } } } diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index bbe978226..d15f18463 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -291,3 +291,25 @@ test("import expression", () => { .setOptions({ module: ts.ModuleKind.ESNext }) .expectToEqual({ result: "foo" }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1572 +test("correctly exports @compileMembersOnly enums (#1572)", () => { + util.testModule` + export { val } from "./otherfile"; + ` + .addExtraFile( + "otherfile.ts", + ` + // Would put this in the main file, but we cannot transfer enum types over lua/js boundary + // but we still need to have an exported enum, hence it is in another file + /** @compileMembersOnly */ + export enum MyEnum { + A = 0, + B = 1, + C = 2 + } + export const val = MyEnum.B | MyEnum.C; + ` + ) + .expectToEqual({ val: 3 }); +}); From 9e05143081db028aea73b4c92783d46bf16e35bd Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 20:18:02 +0200 Subject: [PATCH 672/764] Fix incorrect context passing when super is used in contextual call (#1587) --- .../visitors/optional-chaining.ts | 13 +++++++++++++ test/unit/optionalChaining.spec.ts | 19 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/transformation/visitors/optional-chaining.ts b/src/transformation/visitors/optional-chaining.ts index 893add0f0..6d6deeb8d 100644 --- a/src/transformation/visitors/optional-chaining.ts +++ b/src/transformation/visitors/optional-chaining.ts @@ -166,6 +166,19 @@ export function transformOptionalChainWithCapture( return result; } ); + + // handle super calls by passing self as context + function getLeftMostChainItem(node: ts.Node): ts.Node { + if (ts.isPropertyAccessExpression(node)) { + return getLeftMostChainItem(node.expression); + } else { + return node; + } + } + if (getLeftMostChainItem(tsLeftExpression).kind === ts.SyntaxKind.SuperKeyword) { + capturedThisValue = lua.createIdentifier("self"); + } + // handle context if (rightContextualCall) { if (capturedThisValue) { diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index 8a30e1647..d99f18be9 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -438,3 +438,22 @@ describe("Non-null chain", () => { `.expectToMatchJsResult(); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1585 +test("optional chaining of super call (#1585)", () => { + util.testFunction` + class Parent { + private name = "foo"; + M2() { return this.name; } + } + + class Child extends Parent { + M2() { + return super.M2?.(); + } + } + + const c = new Child(); + return c.M2(); + `.expectToMatchJsResult(); +}); From b40b43c2b7cb7f4f5de9080195ccbc171e5977ef Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 21 Sep 2024 20:18:12 +0200 Subject: [PATCH 673/764] Fix bug with using dispose when using disposable class (#1586) --- src/lualib/Using.ts | 2 +- test/unit/using.spec.ts | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/lualib/Using.ts b/src/lualib/Using.ts index c61d544eb..a720f6e60 100644 --- a/src/lualib/Using.ts +++ b/src/lualib/Using.ts @@ -1,6 +1,6 @@ export function __TS__Using( this: undefined, - cb: (...args: TArgs) => TReturn, + cb: (this: void, ...args: TArgs) => TReturn, ...args: TArgs ): TReturn { let thrownError; diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts index 5182b8928..34b4fef67 100644 --- a/test/unit/using.spec.ts +++ b/test/unit/using.spec.ts @@ -193,3 +193,27 @@ test("await using no extra diagnostics (#1571)", () => { } `.expectToHaveNoDiagnostics(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1584 +test("works with disposable classes (#1584)", () => { + util.testFunction` + const log = []; + + class Scoped { + action(): void { + log.push("action") + } + [Symbol.dispose]() { + log.push("cleanup") + } + } + + function TestScoped(): void { + using s = new Scoped(); + s.action(); + } + + TestScoped(); + return log; + `.expectToEqual(["action", "cleanup"]); +}); From fe2098c231455638cfb7567fff17004972b351db Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 24 Sep 2024 21:32:11 +0200 Subject: [PATCH 674/764] Resolve bug inferring context type from generic functions in type parameters (#1589) * Resolve bug inferring context type from generic functions in type parameters * remove previous fix * Fix false positive due to incorrect inference of generic function contraint --- src/transformation/utils/function-context.ts | 4 ++++ .../validation/validFunctionAssignments.spec.ts | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 3055c4f53..5b2c0cb4e 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -140,6 +140,10 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.NonVoid; } + if (signatureDeclaration.parent && ts.isTypeParameterDeclaration(signatureDeclaration.parent)) { + return ContextType.NonVoid; + } + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const program = context.program; const options = program.getCompilerOptions() as CompilerOptions; diff --git a/test/unit/functions/validation/validFunctionAssignments.spec.ts b/test/unit/functions/validation/validFunctionAssignments.spec.ts index 7a68d0ea6..525b95929 100644 --- a/test/unit/functions/validation/validFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/validFunctionAssignments.spec.ts @@ -248,3 +248,20 @@ test("Does not fail on union type signatures (#896)", () => { ) .expectToHaveNoDiagnostics(); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1568 +test("No false positives when using generic functions (#1568)", () => { + util.testModule` + /** @noSelf */ + declare namespace Test { + export function testCallback void>( + callback: T, + ): void; + } + + Test.testCallback(() => {}); + + const f = () => {}; + Test.testCallback(f); + `.expectToHaveNoDiagnostics(); +}); From fef961e8120bd98856d6d72f47a4913148df6290 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 24 Sep 2024 21:48:56 +0200 Subject: [PATCH 675/764] CHANGELOG.md 1.27.0 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 041681d81..ca1e46b07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.27.0 + +- Upgraded TypeScript to 5.6.2 +- Added support for `Math.trunc` (see [Math.trunc()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc)) +- Fixed a runtime error when disposing a disposable class +- Fixed the wrong `this` value being passed when using `?.` to call a `super` method +- Fixed a bug causing exported `/** @compileMembersOnly */` enums to break +- Fixed a bug in `Array.from` when calling it with a non-array iterable +- Fixed an incorrect diagnostic being shown for `await using` code +- Fixed a bug causing not all getters/setters to be transpiled + ## 1.26.0 - Upgraded TypeScript to 5.5.2 From e10839386c17b0900bfccb4ace9dc45f523f33f0 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 24 Sep 2024 21:51:11 +0200 Subject: [PATCH 676/764] 1.27.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0f6d42d97..27b3c7f57 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.26.2", + "version": "1.27.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.26.2", + "version": "1.27.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 231eb7a50..edee38100 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.26.2", + "version": "1.27.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d7a06745ad98ce76d16d467af01527464dba9e9a Mon Sep 17 00:00:00 2001 From: James <5511220+Zamiell@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:24:43 -0400 Subject: [PATCH 677/764] chore: update eslint to latest (#1588) * chore: update eslint to latest * update --- .eslintignore | 8 - .eslintrc.js | 239 - .github/workflows/ci.yml | 27 +- eslint.config.mjs | 230 + language-extensions/index.d.ts | 4 +- package-lock.json | 9830 ++++---------------- package.json | 11 +- src/lualib-build/plugin.ts | 1 - src/lualib/ObjectAssign.ts | 1 - src/lualib/ObjectDefineProperty.ts | 7 +- src/lualib/Spread.ts | 1 - src/transformation/context/context.ts | 1 + src/typescript-internal.d.ts | 2 - src/utils.ts | 2 - test/setup.ts | 1 - test/transpile/plugins/add-comments.ts | 1 - test/transpile/plugins/afterEmit.ts | 1 - test/transpile/plugins/afterPrint.ts | 1 - test/transpile/plugins/arguments.ts | 1 - test/transpile/plugins/beforeEmit.ts | 1 - test/transpile/plugins/beforeTransform.ts | 1 - test/transpile/plugins/moduleResolution.ts | 1 - test/transpile/plugins/printer.ts | 1 - test/transpile/plugins/visitor-super.ts | 1 - test/transpile/plugins/visitor.ts | 1 - test/transpile/resolve-plugin/ts.ts | 1 - 26 files changed, 2072 insertions(+), 8304 deletions(-) delete mode 100644 .eslintignore delete mode 100644 .eslintrc.js create mode 100644 eslint.config.mjs diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index a1a50129e..000000000 --- a/.eslintignore +++ /dev/null @@ -1,8 +0,0 @@ -/dist -/test/translation/transformation -/test/cli/errors -/test/cli/watch -/test/transpile/directories -/test/transpile/module-resolution/**/node_modules -/test/transpile/module-resolution/**/dist -/test/transpile/outFile diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 632294177..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,239 +0,0 @@ -module.exports = { - extends: ["plugin:jest/recommended", "plugin:jest/style"], - parserOptions: { - sourceType: "module", - project: [ - "test/tsconfig.json", - "src/lualib/tsconfig.json", - "src/lualib/tsconfig.lua50.json", - "benchmark/tsconfig.json", - "language-extensions/tsconfig.json", - ], - }, - env: { es6: true, node: true }, - plugins: ["import"], - rules: { - "arrow-body-style": "error", - curly: ["error", "multi-line"], - eqeqeq: ["error", "always", { null: "ignore" }], - "no-caller": "error", - "no-cond-assign": "error", - "no-debugger": "error", - "no-duplicate-case": "error", - "no-new-wrappers": "error", - "no-restricted-globals": ["error", "parseInt", "parseFloat"], - "no-unused-labels": "error", - "no-var": "error", - "object-shorthand": "error", - "prefer-const": ["error", { destructuring: "all" }], - radix: "error", - "use-isnan": "error", - "object-shorthand": [ - "error", - "always", - { avoidQuotes: true, ignoreConstructors: false, avoidExplicitReturnArrows: true }, - ], - "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "SequenceExpression"], - "spaced-comment": [ - "error", - "always", - { - line: { exceptions: ["-", "+"], markers: ["=", "!", "/"] }, - block: { exceptions: ["-", "+"], markers: ["=", "!", ":", "::"], balanced: true }, - }, - ], - "no-delete-var": ["error"], - "no-label-var": ["error"], - yoda: ["error"], - "prefer-numeric-literals": ["error"], - "prefer-rest-params": ["error"], - "prefer-spread": ["error"], - "no-useless-computed-key": ["error"], - "for-direction": ["error"], - "no-compare-neg-zero": ["error"], - "no-dupe-else-if": ["error"], - "no-empty": ["error", { allowEmptyCatch: true }], - "no-implicit-coercion": ["error", { boolean: true, number: true, string: true }], - "operator-assignment": ["error"], - "no-path-concat": ["error"], - "no-compare-neg-zero": ["error"], - "no-control-regex": ["error"], - "no-unneeded-ternary": ["error", { defaultAssignment: false }], - "one-var": ["error", "never"], - "prefer-exponentiation-operator": ["error"], - "prefer-object-spread": ["error"], - "no-useless-call": ["off"], - "no-useless-catch": ["error"], - "no-useless-concat": ["error"], - "no-useless-escape": ["error"], - "no-useless-return": ["error"], - - "import/no-default-export": "error", - // TODO currently only works for direct imports (useless for now) https://github.com/benmosher/eslint-plugin-import/issues/1729 - // "import/no-deprecated": "error", - - "jest/expect-expect": "off", - "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], - "jest/no-disabled-tests": "error", - "jest/no-identical-title": "off", - "jest/no-test-return-statement": "error", - "jest/prefer-spy-on": "error", - "jest/prefer-todo": "error", - "jest/valid-title": "error", - // TODO: - // "jest/lowercase-name": "error", - }, - overrides: [ - { - files: "**/*.ts", - extends: ["plugin:@typescript-eslint/base"], - rules: { - // https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js - "@typescript-eslint/adjacent-overload-signatures": "error", - "@typescript-eslint/array-type": "error", - "@typescript-eslint/await-thenable": "error", - "@typescript-eslint/ban-types": [ - "error", - { - types: { - Function: null, - CallableFunction: { fixWith: "(...args: any[]) => any" }, - NewableFunction: { fixWith: "new (...args: any[]) => any" }, - }, - }, - ], - camelcase: "off", - "@typescript-eslint/camelcase": ["error", { properties: "never", ignoreDestructuring: true }], - "@typescript-eslint/consistent-type-assertions": [ - "error", - { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, - ], - "@typescript-eslint/consistent-type-definitions": "error", - "@typescript-eslint/explicit-member-accessibility": [ - "error", - { overrides: { constructors: "no-public" } }, - ], - "no-array-constructor": "off", - "@typescript-eslint/no-array-constructor": "error", - "@typescript-eslint/no-empty-interface": "error", - "@typescript-eslint/no-extra-non-null-assertion": "error", - "@typescript-eslint/no-extraneous-class": "error", - "@typescript-eslint/no-floating-promises": "error", - "@typescript-eslint/no-for-in-array": "error", - "@typescript-eslint/no-inferrable-types": "error", - "@typescript-eslint/no-misused-new": "error", - "@typescript-eslint/no-misused-promises": "error", - "@typescript-eslint/no-namespace": "error", - "@typescript-eslint/no-require-imports": "error", - "@typescript-eslint/no-this-alias": "error", - "no-throw-literal": "off", - "@typescript-eslint/no-throw-literal": "error", - "no-constant-condition": "off", - "@typescript-eslint/no-unnecessary-condition": [ - "error", - { ignoreRhs: true, allowConstantLoopConditions: true }, - ], - "@typescript-eslint/no-unnecessary-qualifier": "error", - "@typescript-eslint/no-unnecessary-type-arguments": "error", - "@typescript-eslint/no-unnecessary-type-assertion": "error", - "no-unused-expressions": "off", - "@typescript-eslint/no-unused-expressions": "error", - "no-useless-constructor": "off", - "@typescript-eslint/no-useless-constructor": "error", - "@typescript-eslint/prefer-function-type": "error", - "@typescript-eslint/prefer-includes": "error", - "@typescript-eslint/prefer-optional-chain": "error", - "@typescript-eslint/prefer-namespace-keyword": "error", - "@typescript-eslint/prefer-readonly": "error", - "@typescript-eslint/prefer-string-starts-ends-with": "error", - "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], - quotes: "off", - "@typescript-eslint/quotes": ["error", "single", { avoidEscape: true, allowTemplateLiterals: false }], - "@typescript-eslint/require-array-sort-compare": "error", - "@typescript-eslint/require-await": "error", - "@typescript-eslint/restrict-plus-operands": ["error", { checkCompoundAssignments: true }], - "@typescript-eslint/return-await": "error", - "@typescript-eslint/triple-slash-reference": "error", - "@typescript-eslint/unified-signatures": "error", - // end of https://github.com/ark120202/eslint-config/blob/2c24f13fd99af7ccf29e56d5d936b3ab0f237db6/bases/typescript.js - "@typescript-eslint/array-type": ["error", { default: "array-simple" }], - "@typescript-eslint/ban-types": ["error", { types: { null: null } }], - "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], - "@typescript-eslint/no-require-imports": "off", - "@typescript-eslint/no-unnecessary-condition": "off", - "@typescript-eslint/prefer-for-of": "error", - "@typescript-eslint/prefer-nullish-coalescing": "error", - "@typescript-eslint/prefer-readonly": "off", - "@typescript-eslint/quotes": ["error", "double", { avoidEscape: true, allowTemplateLiterals: false }], - "@typescript-eslint/require-array-sort-compare": "off", - "@typescript-eslint/camelcase": "off", - - "@typescript-eslint/naming-convention": [ - "error", - { - selector: "default", - format: ["camelCase"], - leadingUnderscore: "allow", - }, - { - selector: "variable", - format: ["camelCase", "UPPER_CASE"], - leadingUnderscore: "allow", - }, - { - selector: "typeLike", - format: ["PascalCase"], - }, - { - selector: "enumMember", - format: ["PascalCase"], - }, - { - selector: "typeParameter", - format: ["PascalCase"], - prefix: ["T"], - filter: { - regex: "K|V", - match: false, - }, - }, - { - selector: "interface", - format: ["PascalCase"], - custom: { - regex: "^I[A-Z]", - match: false, - }, - }, - { - /* Ignore properties that require quotes */ - selector: "objectLiteralProperty", - modifiers: ["requiresQuotes"], - format: null, - }, - ], - }, - }, - { - files: "src/lualib/**/*.ts", - rules: { - "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], - "@typescript-eslint/no-throw-literal": "off", - "@typescript-eslint/prefer-optional-chain": "off", - "@typescript-eslint/naming-convention": "off", - }, - }, - { - files: "language-extensions/index.d.ts", - rules: { - "@typescript-eslint/naming-convention": "off", - }, - }, - { - files: "benchmark/src/*_benchmarks/**/*.ts", - rules: { - "import/no-default-export": "off", - }, - }, - ], -}; diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e49dbd30f..8353ca6d4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,16 +5,19 @@ on: branches: master pull_request: +env: + NODE_VERSION: 20.17.0 + jobs: lint: name: Lint runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} - run: npm ci - run: npm run lint env: @@ -28,18 +31,18 @@ jobs: os: [ubuntu-latest, windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Use Node.js 16.14.0 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} - run: npm ci - run: npm run build - run: npx jest --maxWorkers 2 --coverage env: CI: true - if: matrix.os == 'ubuntu-latest' - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v4 benchmark: name: Benchmark @@ -53,18 +56,18 @@ jobs: run: brew install glow # Checkout master & commit - name: Checkout master - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: ref: master path: master - name: Checkout commit - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: path: commit - name: Use Node.js 16.14.0 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: - node-version: 16.14.0 + node-version: ${{ env.NODE_VERSION }} # NPM # install and build master - name: npm ci master @@ -124,7 +127,7 @@ jobs: working-directory: commit/benchmark/dist - name: Combine benchmark results id: script-combine-results - uses: actions/github-script@v3 + uses: actions/github-script@v7 with: benchmark-result-path-lua: commit/benchmark/data/benchmark_master_vs_commit_53.json benchmark-result-path-jit: commit/benchmark/data/benchmark_master_vs_commit_jit.json diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 000000000..0ea4d78ca --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,230 @@ +// @ts-check + +import tseslint from "typescript-eslint"; +import eslintPluginJest from "eslint-plugin-jest"; + +export default tseslint.config( + // Enable linting on TypeScript file extensions. + { + files: ["**/*.ts", "**/*.tsx", "**/*.mts", "**/*.cts"], + }, + + // Base ESLint rules + { + rules: { + "arrow-body-style": "error", + curly: ["error", "multi-line"], + eqeqeq: ["error", "always", { null: "ignore" }], + "no-caller": "error", + "no-cond-assign": "error", + "no-debugger": "error", + "no-duplicate-case": "error", + "no-new-wrappers": "error", + "no-restricted-globals": ["error", "parseInt", "parseFloat"], + "no-unused-labels": "error", + "no-var": "error", + "prefer-const": ["error", { destructuring: "all" }], + radix: "error", + "use-isnan": "error", + "object-shorthand": [ + "error", + "always", + { avoidQuotes: true, ignoreConstructors: false, avoidExplicitReturnArrows: true }, + ], + "no-restricted-syntax": ["error", "ForInStatement", "LabeledStatement", "SequenceExpression"], + "spaced-comment": [ + "error", + "always", + { + line: { exceptions: ["-", "+"], markers: ["=", "!", "/"] }, + block: { exceptions: ["-", "+"], markers: ["=", "!", ":", "::"], balanced: true }, + }, + ], + "no-delete-var": ["error"], + "no-label-var": ["error"], + yoda: ["error"], + "prefer-numeric-literals": ["error"], + "prefer-rest-params": ["error"], + "prefer-spread": ["error"], + "no-useless-computed-key": ["error"], + "for-direction": ["error"], + "no-compare-neg-zero": ["error"], + "no-dupe-else-if": ["error"], + "no-empty": ["error", { allowEmptyCatch: true }], + "no-implicit-coercion": ["error", { boolean: true, number: true, string: true }], + "operator-assignment": ["error"], + "no-path-concat": ["error"], + "no-control-regex": ["error"], + "no-unneeded-ternary": ["error", { defaultAssignment: false }], + "one-var": ["error", "never"], + "prefer-exponentiation-operator": ["error"], + "prefer-object-spread": ["error"], + "no-useless-catch": ["error"], + "no-useless-concat": ["error"], + "no-useless-escape": ["error"], + "no-useless-return": ["error"], + }, + }, + + // typescript-eslint + { + plugins: { + "@typescript-eslint": tseslint.plugin, + }, + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: [ + "test/tsconfig.json", + "src/lualib/tsconfig.json", + "src/lualib/tsconfig.lua50.json", + "benchmark/tsconfig.json", + "language-extensions/tsconfig.json", + "tsconfig.eslint.json", + ], + tsconfigRootDir: import.meta.dirname, + }, + }, + }, + { + rules: { + "@typescript-eslint/adjacent-overload-signatures": "error", + "@typescript-eslint/array-type": ["error", { default: "array-simple" }], + "@typescript-eslint/await-thenable": "error", + "@typescript-eslint/consistent-type-assertions": [ + "error", + { assertionStyle: "as", objectLiteralTypeAssertions: "never" }, + ], + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/explicit-member-accessibility": ["error", { overrides: { constructors: "no-public" } }], + "@typescript-eslint/naming-convention": [ + "error", + { + selector: "default", + format: ["camelCase"], + leadingUnderscore: "allow", + }, + { + selector: "variable", + format: ["camelCase", "UPPER_CASE"], + leadingUnderscore: "allow", + }, + { + selector: "typeLike", + format: ["PascalCase"], + }, + { + selector: "enumMember", + format: ["PascalCase"], + }, + { + selector: "typeParameter", + format: ["PascalCase"], + prefix: ["T"], + filter: { + regex: "K|V", + match: false, + }, + }, + { + selector: "interface", + format: ["PascalCase"], + custom: { + regex: "^I[A-Z]", + match: false, + }, + }, + { + // Ignore properties that require quotes + selector: "objectLiteralProperty", + modifiers: ["requiresQuotes"], + format: null, + }, + ], + "no-array-constructor": "off", + "@typescript-eslint/no-array-constructor": "error", + "@typescript-eslint/no-empty-interface": "error", + "@typescript-eslint/no-empty-object-type": "error", + "@typescript-eslint/no-extra-non-null-assertion": "error", + "@typescript-eslint/no-extraneous-class": "error", + "@typescript-eslint/no-floating-promises": "error", + "@typescript-eslint/no-for-in-array": "error", + "@typescript-eslint/no-inferrable-types": "error", + "@typescript-eslint/no-misused-new": "error", + "@typescript-eslint/no-misused-promises": "error", + "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }], + "@typescript-eslint/no-this-alias": "error", + "@typescript-eslint/no-unnecessary-qualifier": "error", + "@typescript-eslint/no-unnecessary-type-arguments": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unsafe-function-type": "error", + "no-unused-expressions": "off", + "@typescript-eslint/no-unused-expressions": "error", + "no-useless-constructor": "off", + "@typescript-eslint/no-useless-constructor": "error", + "@typescript-eslint/no-wrapper-object-types": "error", + "no-throw-literal": "off", + "@typescript-eslint/only-throw-error": "error", // "no-throw-literal" was renamed to "only-throw-error". + "@typescript-eslint/prefer-for-of": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/prefer-includes": "error", + "@typescript-eslint/prefer-optional-chain": "error", + "@typescript-eslint/prefer-namespace-keyword": "error", + "@typescript-eslint/prefer-nullish-coalescing": "error", + "@typescript-eslint/prefer-string-starts-ends-with": "error", + "@typescript-eslint/promise-function-async": ["error", { checkArrowFunctions: false }], + "@typescript-eslint/require-await": "error", + "@typescript-eslint/restrict-plus-operands": ["error", { skipCompoundAssignments: false }], + "@typescript-eslint/return-await": "error", + "@typescript-eslint/triple-slash-reference": "error", + "@typescript-eslint/unified-signatures": "error", + }, + }, + + // eslint-plugin-jest + eslintPluginJest.configs["flat/recommended"], + eslintPluginJest.configs["flat/style"], + { + rules: { + "jest/expect-expect": "off", + "jest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }], + "jest/no-disabled-tests": "error", + "jest/no-identical-title": "off", + "jest/no-test-return-statement": "error", + "jest/prefer-spy-on": "error", + "jest/prefer-todo": "error", + "jest/valid-title": "error", + // TODO: + // "jest/lowercase-name": "error", + }, + }, + + // Exceptions for specific files/directories + { + files: ["src/lualib/**/*.ts"], + rules: { + "no-restricted-syntax": ["error", "LabeledStatement", "SequenceExpression"], + "@typescript-eslint/only-throw-error": "off", + "@typescript-eslint/prefer-optional-chain": "off", + "@typescript-eslint/naming-convention": "off", + }, + }, + + // Ignore some specific files and directories + { + ignores: [ + ".github/scripts/create_benchmark_check.js", + "dist/", + "eslint.config.mjs", + "jest.config.js", + "test/cli/errors/", + "test/cli/watch/", + "test/translation/transformation/", + "test/transpile/directories/", + "test/transpile/module-resolution/**/node_modules/", + "test/transpile/module-resolution/**/dist/", + "test/transpile/outFile/", + "test/transpile/resolve-plugin/", + ], + } +); diff --git a/language-extensions/index.d.ts b/language-extensions/index.d.ts index 1442e5aa3..6d805f189 100644 --- a/language-extensions/index.d.ts +++ b/language-extensions/index.d.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/naming-convention */ + type AnyTable = Record; -// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/consistent-type-definitions +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions,@typescript-eslint/no-empty-object-type type AnyNotNil = {}; /** diff --git a/package-lock.json b/package-lock.json index 27b3c7f57..f76e67fd3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "typescript-to-lua", - "version": "1.27.0", - "lockfileVersion": 2, + "version": "1.26.2", + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -10,7 +10,7 @@ "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", - "enhanced-resolve": "^5.8.2", + "enhanced-resolve": "5.8.2", "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" @@ -25,9 +25,8 @@ "@types/node": "^13.7.7", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^26.9.0", + "eslint": "^9.11.0", + "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^29.5.0", @@ -38,7 +37,7 @@ "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typescript": "^5.6.2", - "typescript-eslint": "^7.13.1" + "typescript-eslint": "^8.7.0" }, "engines": { "node": ">=16.10.0" @@ -47,142 +46,66 @@ "typescript": "5.6.2" } }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/code-frame/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/code-frame/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@babel/code-frame/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/code-frame/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/code-frame/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/compat-data": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", - "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.4.tgz", + "integrity": "sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.2.tgz", + "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, + "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.0", + "@babel/helper-compilation-targets": "^7.25.2", + "@babel/helper-module-transforms": "^7.25.2", + "@babel/helpers": "^7.25.0", + "@babel/parser": "^7.25.0", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.2", + "@babel/types": "^7.25.2", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -197,56 +120,42 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.6.tgz", + "integrity": "sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", + "@babel/types": "^7.25.6", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz", + "integrity": "sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", + "@babel/compat-data": "^7.25.2", + "@babel/helper-validator-option": "^7.24.8", + "browserslist": "^4.23.1", "lru-cache": "^5.1.1", - "semver": "^6.3.0" + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { @@ -254,158 +163,123 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "dependencies": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "node_modules/@babel/helper-module-imports": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.25.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz", + "integrity": "sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", + "@babel/traverse": "^7.25.2" }, "engines": { "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", + "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", + "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", + "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", + "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -416,6 +290,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -428,6 +303,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -442,6 +318,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -450,13 +327,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -466,6 +345,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -475,6 +355,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -483,10 +364,14 @@ } }, "node_modules/@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", + "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.6" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -499,6 +384,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -511,6 +397,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -523,6 +410,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -530,11 +418,44 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.6.tgz", + "integrity": "sha512-sXaDXaJN9SNLymBdlWFA+bjzBhFD617ZaFiY13dGt7TVslVvVgA6fkZOP7Ki3IGElC45lwHdOTrCtKZGVAWeLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.24.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -547,6 +468,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -555,12 +477,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -574,6 +497,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -586,6 +510,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -598,6 +523,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -610,6 +536,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -622,6 +549,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -634,6 +562,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -641,11 +570,28 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -657,12 +603,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "version": "7.25.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz", + "integrity": "sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.8" }, "engines": { "node": ">=6.9.0" @@ -672,33 +619,32 @@ } }, "node_modules/@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", + "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.25.0", + "@babel/types": "^7.25.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", - "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.6.tgz", + "integrity": "sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.25.6", + "@babel/parser": "^7.25.6", + "@babel/template": "^7.25.0", + "@babel/types": "^7.25.6", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -711,18 +657,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "version": "7.25.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", + "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-string-parser": "^7.24.8", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -733,13 +681,15 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -752,6 +702,7 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, + "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -762,6 +713,7 @@ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", "dev": true, + "license": "MIT", "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -772,25 +724,65 @@ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", + "espree": "^10.0.1", + "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -798,34 +790,43 @@ "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", + "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "deprecated": "Use @eslint/config-array instead", + "node_modules/@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" + "levn": "^0.4.1" }, "engines": { - "node": ">=10.10.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -833,6 +834,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -841,18 +843,26 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true + "node_modules/@humanwhocodes/retry": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", + "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -869,6 +879,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -878,6 +889,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -891,6 +903,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -904,6 +917,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -916,6 +930,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -931,6 +946,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -943,6 +959,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -952,21 +969,23 @@ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -974,37 +993,38 @@ } }, "node_modules/@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -1025,6 +1045,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -1033,12 +1054,13 @@ } }, "node_modules/@jest/core/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -1047,95 +1069,102 @@ } }, "node_modules/@jest/core/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0" + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.4.3" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1143,13 +1172,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1168,24 +1197,26 @@ } }, "node_modules/@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.25.16" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -1194,13 +1225,14 @@ } }, "node_modules/@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1209,14 +1241,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -1224,22 +1257,23 @@ } }, "node_modules/@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1249,19 +1283,14 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/@jest/transform/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - }, "node_modules/@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1273,50 +1302,56 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "dev": true, + "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -1324,6 +1359,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1337,6 +1373,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1346,6 +1383,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1355,58 +1393,66 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" }, "node_modules/@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^2.0.0" + "@sinonjs/commons": "^3.0.0" } }, "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", + "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", @@ -1416,38 +1462,49 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, + "license": "MIT", "dependencies": { "@babel/parser": "^7.1.0", "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.3.0" + "@babel/types": "^7.20.7" } }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", + "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } @@ -1457,40 +1514,45 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, + "license": "MIT", "dependencies": { "@types/minimatch": "*", "@types/node": "*" } }, "node_modules/@types/graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } @@ -1500,112 +1562,108 @@ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, + "license": "MIT", "dependencies": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/node": { "version": "13.13.52", "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@types/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g==", - "dev": true - }, - "node_modules/@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.4.tgz", + "integrity": "sha512-0so8lU8O5zatZS/2Fi4zrwks+vZv7e0dygrgEZXljODXBig97l4cPQD+9LabXfGJOWwoRkTVz6Q4edZvD12UOA==", + "dev": true, + "license": "MIT" }, "node_modules/@types/resolve": { "version": "1.14.0", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" }, "node_modules/@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", + "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/type-utils": "8.7.0", + "@typescript-eslint/utils": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1614,27 +1672,27 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", + "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", "dev": true, - "optional": true, - "peer": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", "debug": "^4.3.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" }, "peerDependenciesMeta": { "typescript": { @@ -1643,16 +1701,17 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", + "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1660,28 +1719,24 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz", + "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==", "dev": true, - "optional": true, - "peer": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", + "@typescript-eslint/typescript-estree": "8.7.0", + "@typescript-eslint/utils": "8.7.0", "debug": "^4.3.4", - "tsutils": "^3.21.0" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "*" - }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1689,12 +1744,13 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", + "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1702,21 +1758,23 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", + "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/visitor-keys": "8.7.0", "debug": "^4.3.4", - "globby": "^11.1.0", + "fast-glob": "^3.3.2", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", @@ -1728,65 +1786,98 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", + "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.7.0", + "@typescript-eslint/types": "8.7.0", + "@typescript-eslint/typescript-estree": "8.7.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + "eslint": "^8.57.0 || ^9.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", + "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "8.7.0", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-to-lua/language-extensions": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", - "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==", + "license": "MIT" }, "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", "dev": true, + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1799,15 +1890,20 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, "engines": { "node": ">=0.4.0" } @@ -1817,6 +1913,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1833,6 +1930,7 @@ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1843,23 +1941,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -1869,6 +1956,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1884,6 +1972,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1896,162 +1985,34 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "Python-2.0" }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "dev": true, - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^29.5.0", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -2068,6 +2029,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -2079,14 +2041,42 @@ "node": ">=8" } }, - "node_modules/babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", "@types/babel__core": "^7.1.14", "@types/babel__traverse": "^7.0.6" }, @@ -2095,35 +2085,40 @@ } }, "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz", + "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" }, "peerDependencies": { "@babel/core": "^7.0.0" } }, "node_modules/babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.5.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -2137,13 +2132,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2154,6 +2151,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { "fill-range": "^7.1.1" }, @@ -2162,9 +2160,9 @@ } }, "node_modules/browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", + "version": "4.23.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.3.tgz", + "integrity": "sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==", "dev": true, "funding": [ { @@ -2174,13 +2172,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" + "caniuse-lite": "^1.0.30001646", + "electron-to-chromium": "^1.5.4", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -2194,6 +2197,7 @@ "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, + "license": "MIT", "dependencies": { "fast-json-stable-stringify": "2.x" }, @@ -2206,6 +2210,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -2214,32 +2219,15 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2249,14 +2237,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/caniuse-lite": { - "version": "1.0.30001451", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", - "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", + "version": "1.0.30001663", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001663.tgz", + "integrity": "sha512-o9C3X27GLKbLeTYZ6HBOLU1tsAcBZsLis28wrVzddShCS16RujjHp9GDHKZqrB3meE0YjhawvMFsGb/igqiPzA==", "dev": true, "funding": [ { @@ -2266,14 +2255,20 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2290,14 +2285,15 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ { @@ -2305,21 +2301,24 @@ "url": "https://github.com/sponsors/sibiraj-s" } ], + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", + "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "dev": true, + "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, + "license": "ISC", "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", @@ -2334,22 +2333,25 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2361,31 +2363,58 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2395,64 +2424,14 @@ "node": ">= 8" } }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -2464,65 +2443,43 @@ } }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/deepmerge": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2532,6 +2489,7 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } @@ -2541,45 +2499,40 @@ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", "dev": true, + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "path-type": "^4.0.0" + "jake": "^10.8.5" }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" + "bin": { + "ejs": "bin/cli.js" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, "node_modules/electron-to-chromium": { - "version": "1.4.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", - "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", - "dev": true + "version": "1.5.27", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", + "integrity": "sha512-o37j1vZqCoEgBuWWXLHQgTN/KDKe7zwpiY5CPeq2RvUqOyJw9xnrULzZAEVQ5p4h+zjMk7hgtOoPdnLxr7m/jw==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2591,12 +2544,14 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz", + "integrity": "sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==", + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" @@ -2610,148 +2565,17 @@ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -2761,6 +2585,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -2769,43 +2594,43 @@ } }, "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "version": "9.11.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", + "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", "dev": true, + "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.11.1", + "@eslint/plugin-kit": "^0.2.0", "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.0", "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", - "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", + "eslint-scope": "^8.0.2", + "eslint-visitor-keys": "^4.0.0", + "espree": "^10.1.0", + "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", + "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", @@ -2817,205 +2642,89 @@ "eslint": "bin/eslint.js" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", + "node_modules/eslint-plugin-jest": { + "version": "28.8.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", + "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", "dev": true, + "license": "MIT", "dependencies": { - "debug": "^3.2.7" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0 || ^8.0.0" }, "engines": { - "node": ">=4" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0 || ^8.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" }, "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-jest": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", - "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.10.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { "optional": true } } }, "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", + "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.9.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" @@ -3026,6 +2735,7 @@ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, + "license": "BSD-2-Clause", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -3035,10 +2745,11 @@ } }, "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "estraverse": "^5.1.0" }, @@ -3046,20 +2757,12 @@ "node": ">=0.10" } }, - "node_modules/esquery/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -3067,20 +2770,12 @@ "node": ">=4.0" } }, - "node_modules/esrecurse/node_modules/estraverse": { + "node_modules/estraverse": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3090,6 +2785,7 @@ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true, + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -3099,6 +2795,7 @@ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -3127,16 +2824,17 @@ } }, "node_modules/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -3147,6 +2845,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3155,51 +2854,55 @@ } }, "node_modules/expect/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/expect/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -3208,22 +2911,25 @@ } }, "node_modules/expect/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3240,6 +2946,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3251,19 +2958,22 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3273,20 +2983,55 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", "dependencies": { - "flat-cache": "^3.0.4" + "brace-expansion": "^2.0.1" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=10" } }, "node_modules/fill-range": { @@ -3294,6 +3039,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3306,6 +3052,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -3318,38 +3065,32 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": ">=16" } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true, - "dependencies": { - "is-callable": "^1.1.3" - } + "license": "ISC" }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "dev": true, + "license": "MIT", "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -3363,14 +3104,16 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3383,33 +3126,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, + "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3419,6 +3136,7 @@ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3428,34 +3146,17 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } @@ -3465,6 +3166,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3472,28 +3174,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3514,6 +3201,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3522,179 +3210,76 @@ } }, "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0" + "function-bind": "^1.1.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "license": "MIT" }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4" } @@ -3704,6 +3289,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3716,10 +3302,11 @@ } }, "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -3739,6 +3326,7 @@ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -3747,7 +3335,9 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -3757,117 +3347,23 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "ISC" }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", + "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "license": "MIT", "dependencies": { - "has-tostringtag": "^1.0.0" + "hasown": "^2.0.2" }, "engines": { "node": ">= 0.4" @@ -3881,6 +3377,7 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -3890,6 +3387,7 @@ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -3899,6 +3397,7 @@ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -3908,6 +3407,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -3915,87 +3415,32 @@ "node": ">=0.10.0" } }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4003,121 +3448,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" + "node": ">=10" } }, "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -4125,6 +3502,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -4139,15 +3517,17 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4156,22 +3536,43 @@ "node": ">=8" } }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.5.0" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -4189,12 +3590,14 @@ } }, "node_modules/jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -4202,28 +3605,29 @@ } }, "node_modules/jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" @@ -4237,6 +3641,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4245,51 +3650,55 @@ } }, "node_modules/jest-circus/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-circus/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4298,28 +3707,29 @@ } }, "node_modules/jest-circus/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "bin": { @@ -4338,31 +3748,32 @@ } }, "node_modules/jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -4387,6 +3798,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4395,12 +3807,13 @@ } }, "node_modules/jest-config/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4409,16 +3822,18 @@ } }, "node_modules/jest-config/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-diff": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^27.5.1", @@ -4434,15 +3849,17 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -4451,16 +3868,17 @@ } }, "node_modules/jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4471,6 +3889,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4479,12 +3898,13 @@ } }, "node_modules/jest-each/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4493,52 +3913,56 @@ } }, "node_modules/jest-each/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4550,13 +3974,14 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4567,6 +3992,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4575,12 +4001,13 @@ } }, "node_modules/jest-leak-detector/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4589,16 +4016,18 @@ } }, "node_modules/jest-leak-detector/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-matcher-utils": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "jest-diff": "^27.5.1", @@ -4614,23 +4043,25 @@ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", "dev": true, + "license": "MIT", "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, "node_modules/jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4643,6 +4074,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4651,12 +4083,13 @@ } }, "node_modules/jest-message-util/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4665,20 +4098,22 @@ } }, "node_modules/jest-message-util/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.5.0" + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4689,6 +4124,7 @@ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" }, @@ -4702,26 +4138,28 @@ } }, "node_modules/jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" @@ -4731,43 +4169,45 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -4776,31 +4216,32 @@ } }, "node_modules/jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4809,34 +4250,32 @@ } }, "node_modules/jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.5.0", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4847,6 +4286,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4855,51 +4295,55 @@ } }, "node_modules/jest-snapshot/node_modules/diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-snapshot/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4908,18 +4352,20 @@ } }, "node_modules/jest-snapshot/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -4931,17 +4377,18 @@ } }, "node_modules/jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.5.0", + "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", + "jest-get-type": "^29.6.3", "leven": "^3.1.0", - "pretty-format": "^29.5.0" + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -4952,6 +4399,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4964,6 +4412,7 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4972,12 +4421,13 @@ } }, "node_modules/jest-validate/node_modules/pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.4.3", + "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" }, @@ -4986,24 +4436,26 @@ } }, "node_modules/jest-validate/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" }, "node_modules/jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { @@ -5011,13 +4463,14 @@ } }, "node_modules/jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.5.0", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -5030,6 +4483,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -5044,13 +4498,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -5063,6 +4519,7 @@ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, @@ -5070,29 +4527,40 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -5105,15 +4573,27 @@ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, + "license": "MIT", "optionalDependencies": { "graceful-fs": "^4.1.6" } }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5123,6 +4603,7 @@ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5132,6 +4613,7 @@ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -5144,13 +4626,15 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^5.0.0" }, @@ -5165,19 +4649,22 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { "yallist": "^3.0.2" } @@ -5186,53 +4673,49 @@ "version": "2.13.1", "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/lua-wasm-bindings": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", "dev": true, + "license": "MIT", "dependencies": { "@types/semver": "^7.3.9", "semver": "^7.3.7" } }, "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "semver": "^7.5.3" }, "engines": { - "node": ">=8" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "tmpl": "1.0.5" } @@ -5241,24 +4724,27 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -5270,6 +4756,7 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5279,6 +4766,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -5286,52 +4774,40 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", "dev": true, - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "dev": true, + "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5341,6 +4817,7 @@ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { "path-key": "^3.0.0" }, @@ -5348,96 +4825,12 @@ "node": ">=8" } }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, + "license": "ISC", "dependencies": { "wrappy": "1" } @@ -5447,6 +4840,7 @@ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", "dependencies": { "mimic-fn": "^2.1.0" }, @@ -5458,17 +4852,18 @@ } }, "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", "dev": true, + "license": "MIT", "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, "engines": { "node": ">= 0.8.0" @@ -5479,6 +4874,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, + "license": "MIT", "dependencies": { "yocto-queue": "^0.1.0" }, @@ -5494,6 +4890,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^3.0.2" }, @@ -5509,6 +4906,7 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5518,6 +4916,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -5530,6 +4929,7 @@ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", @@ -5548,6 +4948,7 @@ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5557,6 +4958,7 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5566,6 +4968,7 @@ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5573,27 +4976,21 @@ "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "engines": { - "node": ">=8" - } + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true, + "license": "ISC" }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { "node": ">=8.6" }, @@ -5602,10 +4999,11 @@ } }, "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 6" } @@ -5615,6 +5013,7 @@ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { "find-up": "^4.0.0" }, @@ -5627,6 +5026,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -5640,6 +5040,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -5652,6 +5053,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -5667,6 +5069,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -5674,20 +5077,12 @@ "node": ">=8" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } @@ -5697,6 +5092,7 @@ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin-prettier.js" }, @@ -5712,6 +5108,7 @@ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", @@ -5726,6 +5123,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -5738,6 +5136,7 @@ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, + "license": "MIT", "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" @@ -5751,14 +5150,15 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ { @@ -5769,7 +5169,8 @@ "type": "opencollective", "url": "https://opencollective.com/fast-check" } - ] + ], + "license": "MIT" }, "node_modules/queue-microtask": { "version": "1.2.3", @@ -5789,37 +5190,22 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } + "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5828,6 +5214,7 @@ "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", @@ -5845,6 +5232,7 @@ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { "resolve-from": "^5.0.0" }, @@ -5857,6 +5245,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -5866,6 +5255,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5875,6 +5265,7 @@ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } @@ -5884,26 +5275,12 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5923,50 +5300,17 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -5974,43 +5318,12 @@ "node": ">=10" } }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, + "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" }, @@ -6023,45 +5336,31 @@ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6070,6 +5369,7 @@ "version": "0.7.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "license": "BSD-3-Clause", "engines": { "node": ">= 8" } @@ -6079,6 +5379,7 @@ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -6089,6 +5390,7 @@ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } @@ -6097,13 +5399,15 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { "escape-string-regexp": "^2.0.0" }, @@ -6116,6 +5420,7 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6125,6 +5430,7 @@ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, + "license": "MIT", "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" @@ -6138,6 +5444,7 @@ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, + "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -6147,60 +5454,12 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -6213,6 +5472,7 @@ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -6222,6 +5482,7 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -6231,6 +5492,7 @@ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -6243,6 +5505,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -6254,6 +5517,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -6265,6 +5529,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -6274,6 +5539,7 @@ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, + "license": "ISC", "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", @@ -6287,19 +5553,22 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -6309,6 +5578,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -6321,6 +5591,7 @@ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=16" }, @@ -6329,28 +5600,31 @@ } }, "node_modules/ts-jest": { - "version": "29.1.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", - "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", + "version": "29.2.5", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", + "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", "dev": true, + "license": "MIT", "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", + "bs-logger": "^0.2.6", + "ejs": "^3.1.10", + "fast-json-stable-stringify": "^2.1.0", "jest-util": "^29.0.0", "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.6.3", + "yargs-parser": "^21.1.1" }, "bin": { "ts-jest": "cli.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0", "@jest/types": "^29.0.0", "babel-jest": "^29.0.0", "jest": "^29.0.0", @@ -6360,6 +5634,9 @@ "@babel/core": { "optional": true }, + "@jest/transform": { + "optional": true + }, "@jest/types": { "optional": true }, @@ -6372,10 +5649,11 @@ } }, "node_modules/ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -6414,65 +5692,12 @@ } } }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1" }, @@ -6485,15 +5710,17 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -6501,84 +5728,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/typescript": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -6588,376 +5743,136 @@ } }, "node_modules/typescript-eslint": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", - "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.7.0.tgz", + "integrity": "sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", - "@typescript-eslint/utils": "7.13.1" + "@typescript-eslint/eslint-plugin": "8.7.0", + "@typescript-eslint/parser": "8.7.0", + "@typescript-eslint/utils": "8.7.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependencies": { - "eslint": "^8.56.0" - }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, + "license": "MIT", "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">= 4.0.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", + "node_modules/update-browserslist-db": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", + "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" + "escalade": "^3.1.2", + "picocolors": "^1.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "bin": { + "update-browserslist-db": "cli.js" }, "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "browserslist": ">= 4.21.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "punycode": "^2.1.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, + "license": "ISC", "dependencies": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" }, "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "node": ">=10.12.0" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" } }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, + "license": "ISC", "dependencies": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" + "isexe": "^2.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.13.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "bin": { + "node-which": "bin/node-which" }, "engines": { "node": ">= 8" } }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=0.10.0" } }, "node_modules/wrap-ansi": { @@ -6965,6 +5880,7 @@ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -6981,13 +5897,15 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, + "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" @@ -7001,6 +5919,7 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, + "license": "ISC", "engines": { "node": ">=10" } @@ -7009,13 +5928,15 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true + "dev": true, + "license": "ISC" }, "node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, + "license": "MIT", "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", @@ -7034,6 +5955,7 @@ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, + "license": "ISC", "engines": { "node": ">=12" } @@ -7043,6 +5965,7 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -7052,6 +5975,7 @@ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -7059,5129 +5983,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true - }, - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@babel/code-frame": { - "version": "7.23.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", - "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", - "dev": true, - "requires": { - "@babel/highlight": "^7.23.4", - "chalk": "^2.4.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/compat-data": { - "version": "7.20.14", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.14.tgz", - "integrity": "sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw==", - "dev": true - }, - "@babel/core": { - "version": "7.20.12", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", - "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", - "dev": true, - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.7", - "@babel/helper-compilation-targets": "^7.20.7", - "@babel/helper-module-transforms": "^7.20.11", - "@babel/helpers": "^7.20.7", - "@babel/parser": "^7.20.7", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.12", - "@babel/types": "^7.20.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/generator": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", - "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", - "dev": true, - "requires": { - "@babel/types": "^7.23.6", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - }, - "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", - "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.20.5", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "lru-cache": "^5.1.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "@babel/helper-environment-visitor": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", - "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", - "dev": true - }, - "@babel/helper-function-name": { - "version": "7.23.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", - "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", - "dev": true, - "requires": { - "@babel/template": "^7.22.15", - "@babel/types": "^7.23.0" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.11", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", - "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", - "dev": true, - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.10", - "@babel/types": "^7.20.7" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "dev": true - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dev": true, - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dev": true, - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", - "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.22.20", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", - "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "dev": true - }, - "@babel/helpers": { - "version": "7.20.13", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", - "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", - "dev": true, - "requires": { - "@babel/template": "^7.20.7", - "@babel/traverse": "^7.20.13", - "@babel/types": "^7.20.7" - } - }, - "@babel/highlight": { - "version": "7.23.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", - "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.22.20", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", - "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", - "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.19.0" - } - }, - "@babel/template": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", - "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.22.13", - "@babel/parser": "^7.22.15", - "@babel/types": "^7.22.15" - } - }, - "@babel/traverse": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.6.tgz", - "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.23.5", - "@babel/generator": "^7.23.6", - "@babel/helper-environment-visitor": "^7.22.20", - "@babel/helper-function-name": "^7.23.0", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.23.6", - "@babel/types": "^7.23.6", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.23.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", - "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.23.4", - "@babel/helper-validator-identifier": "^7.22.20", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "dependencies": { - "@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - } - } - }, - "@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^3.3.0" - } - }, - "@eslint-community/regexpp": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", - "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", - "dev": true - }, - "@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true - }, - "@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.5.0.tgz", - "integrity": "sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.5.0.tgz", - "integrity": "sha512-28UzQc7ulUrOQw1IsN/kv1QES3q2kkbl/wGslyhAclqZ/8cMdB5M68BffkIdSJgKBUt50d3hbwJ92XESlE7LiQ==", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/reporters": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.5.0", - "jest-config": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-resolve-dependencies": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "jest-watcher": "^29.5.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "@jest/environment": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", - "integrity": "sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0" - } - }, - "@jest/expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-PueDR2HGihN3ciUNGr4uelropW7rqUfTiOn+8u0leg/42UhblPxHkfoh0Ruu3I9Y1962P3u2DY4+h7GVTSVU6g==", - "dev": true, - "requires": { - "expect": "^29.5.0", - "jest-snapshot": "^29.5.0" - } - }, - "@jest/expect-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.5.0.tgz", - "integrity": "sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg==", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3" - } - }, - "@jest/fake-timers": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.5.0.tgz", - "integrity": "sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@sinonjs/fake-timers": "^10.0.2", - "@types/node": "*", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "@jest/globals": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.5.0.tgz", - "integrity": "sha512-S02y0qMWGihdzNbUiqSAiKSpSozSuHX5UYc7QbnHP+D9Lyw8DgGGCinrN9uSuHPeKgSSzvPom2q1nAtBvUsvPQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/types": "^29.5.0", - "jest-mock": "^29.5.0" - } - }, - "@jest/reporters": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.5.0.tgz", - "integrity": "sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, - "@jest/schemas": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz", - "integrity": "sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.25.16" - } - }, - "@jest/source-map": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.4.3.tgz", - "integrity": "sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.5.0.tgz", - "integrity": "sha512-fGl4rfitnbfLsrfx1uUpDEESS7zM8JdgZgOCQuxQvL1Sn/I6ijeAVQWGfXI9zb1i9Mzo495cIpVZhA0yr60PkQ==", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.5.0.tgz", - "integrity": "sha512-yPafQEcKjkSfDXyvtgiV4pevSeyuA6MQr6ZIdVkWJly9vkqjnFfcfhRQqpD5whjoU8EORki752xQmjaqoFjzMQ==", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.5.0.tgz", - "integrity": "sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.5.0", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" - }, - "dependencies": { - "convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true - } - } - }, - "@jest/types": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz", - "integrity": "sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true - }, - "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinclair/typebox": { - "version": "0.25.24", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz", - "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", - "dev": true - }, - "@sinonjs/commons": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", - "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", - "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^2.0.0" - } - }, - "@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", - "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true - }, - "@types/babel__core": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", - "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", - "dev": true, - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", - "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/fs-extra": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.2.tgz", - "integrity": "sha512-SvSrYXfWSc7R4eqnOzbQF4TZmfpNSM9FrSWLU3EUnWBuyZqNBOrv1B1JA3byUDPUl9z4Ab3jeZG2eDdySlgNMg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@types/graceful-fs": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", - "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true - }, - "@types/minimatch": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true - }, - "@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "dev": true - }, - "@types/picomatch": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.0.tgz", - "integrity": "sha512-O397rnSS9iQI4OirieAtsDqvCj4+3eY1J+EPdNTKuHuRWIfUoGyzX294o8C4KJYaLqgSrd2o60c5EqCU8Zv02g==", - "dev": true - }, - "@types/prettier": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", - "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", - "dev": true - }, - "@types/resolve": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.14.0.tgz", - "integrity": "sha512-bmjNBW6tok+67iOsASeYSJxSgY++BIR35nGyGLORTDirhra9reJ0shgGL3U7KPDUbOBCx8JrlCjd4d/y5uiMRQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.22", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.22.tgz", - "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz", - "integrity": "sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@eslint-community/regexpp": "^4.4.0", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/type-utils": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/parser": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", - "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz", - "integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dev": true, - "optional": true, - "peer": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", - "integrity": "sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.62.0", - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/typescript-estree": "5.62.0", - "eslint-scope": "^5.1.1", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz", - "integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.62.0", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@typescript-to-lua/language-extensions": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", - "integrity": "sha512-Os5wOKwviTD4LeqI29N0btYOjokSJ97iCf45EOjIABlb5IwNQy7AE/AqZJobRw3ywHH8+KzJUMkEirWPzh2tUA==" - }, - "@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - } - }, - "array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - } - }, - "array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - } - }, - "arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - } - }, - "available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "requires": { - "possible-typed-array-names": "^1.0.0" - } - }, - "babel-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.5.0.tgz", - "integrity": "sha512-mA4eCDh5mSo2EcA9xQjVTpmbbNk32Zb3Q3QFQsNhaK56Q+yoXowzFodLux30HRgyOho5rsQ6B0P9QpMkvvnJ0Q==", - "dev": true, - "requires": { - "@jest/transform": "^29.5.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.5.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.5.0.tgz", - "integrity": "sha512-zSuuuAlTMT4mzLj2nPnUm6fsE6270vdOfnpbJ+RmruU75UhLFvL0N2NgI7xpeS7NaB6hGqmd5pVpGTDYvi4Q3w==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.5.0.tgz", - "integrity": "sha512-JOMloxOqdiBSxMAzjRaH023/vvcaSaec49zvg+2LmNsktC7ei39LTJGw02J+9uUtTZUq6xbLyJ4dxe9sSmIuAg==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.5.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "browserslist": { - "version": "4.21.5", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz", - "integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001449", - "electron-to-chromium": "^1.4.284", - "node-releases": "^2.0.8", - "update-browserslist-db": "^1.0.10" - } - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true - }, - "call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30001451", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz", - "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - } - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true - }, - "define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - } - }, - "define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "requires": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "requires": { - "path-type": "^4.0.0" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "electron-to-chromium": { - "version": "1.4.295", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.295.tgz", - "integrity": "sha512-lEO94zqf1bDA3aepxwnWoHUjA8sZ+2owgcSZjYQy0+uOSEclJX0VieZC+r+wLpSxUHRd6gG32znTWmr+5iGzFw==", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "enhanced-resolve": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz", - "integrity": "sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ==", - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "requires": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - } - }, - "es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4" - } - }, - "es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true - }, - "es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "requires": { - "es-errors": "^1.3.0" - } - }, - "es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "requires": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - } - }, - "es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "requires": { - "hasown": "^2.0.0" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "dependencies": { - "eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dev": true, - "requires": { - "debug": "^3.2.7" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "requires": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "eslint-plugin-jest": { - "version": "26.9.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz", - "integrity": "sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.10.0" - } - }, - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - }, - "dependencies": { - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - } - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.5.0.tgz", - "integrity": "sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true - }, - "jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", - "dev": true - }, - "for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "requires": { - "is-callable": "^1.1.3" - } - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" - }, - "function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - } - }, - "functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true - }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - }, - "get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "requires": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - } - }, - "globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "requires": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "requires": { - "es-define-property": "^1.0.0" - } - }, - "has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.3" - } - }, - "hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "requires": { - "function-bind": "^1.1.2" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "requires": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - } - }, - "is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "requires": { - "hasown": "^2.0.0" - } - }, - "is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "requires": { - "is-typed-array": "^1.1.13" - } - }, - "is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true - }, - "is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "requires": { - "which-typed-array": "^1.1.14" - } - }, - "is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "requires": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "javascript-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", - "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", - "dev": true - }, - "jest": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.5.0.tgz", - "integrity": "sha512-juMg3he2uru1QoXX078zTa7pO85QyB9xajZc6bU+d9yEGwrKX6+vGmJQ3UdVZsvTEUARIdObzH68QItim6OSSQ==", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/types": "^29.5.0", - "import-local": "^3.0.2", - "jest-cli": "^29.5.0" - } - }, - "jest-changed-files": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.5.0.tgz", - "integrity": "sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.5.0.tgz", - "integrity": "sha512-gq/ongqeQKAplVxqJmbeUOJJKkW3dDNPY8PjhJ5G0lBRvu0e3EWGxGy5cI4LAGA7gV2UHCtWBI4EMXK8c9nQKA==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/expect": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.5.0", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "p-limit": "^3.1.0", - "pretty-format": "^29.5.0", - "pure-rand": "^6.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true - }, - "jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-cli": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.5.0.tgz", - "integrity": "sha512-L1KcP1l4HtfwdxXNFCL5bmUbLQiKrakMUriBEcc1Vfz6gx31ORKdreuWvmQVBit+1ss9NNR3yxjwfwzZNdQXJw==", - "dev": true, - "requires": { - "@jest/core": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.5.0.tgz", - "integrity": "sha512-kvDUKBnNJPNBmFFOhDbm59iu1Fii1Q6SxyhXfvylq3UTHbg6o7j/g8k2dZyXWLvfdKB1vAPxNZnMgtKJcmu3kA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.5.0", - "@jest/types": "^29.5.0", - "babel-jest": "^29.5.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.5.0", - "jest-environment-node": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-runner": "^29.5.0", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - } - } - }, - "jest-docblock": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.4.3.tgz", - "integrity": "sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.5.0.tgz", - "integrity": "sha512-HM5kIJ1BTnVt+DQZ2ALp3rzXEl+g726csObrW/jpEGl+CDSSQpOJJX2KE/vEg8cxcMXdyEPu6U4QX5eruQv5hA==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "jest-util": "^29.5.0", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-environment-node": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz", - "integrity": "sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-mock": "^29.5.0", - "jest-util": "^29.5.0" - } - }, - "jest-get-type": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.4.3.tgz", - "integrity": "sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg==", - "dev": true - }, - "jest-haste-map": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.5.0.tgz", - "integrity": "sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/graceful-fs": "^4.1.3", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.4.3", - "jest-util": "^29.5.0", - "jest-worker": "^29.5.0", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.5.0.tgz", - "integrity": "sha512-u9YdeeVnghBUtpN5mVxjID7KbkKE1QU4f6uUwuxiY0vYRi9BUCLKlPEZfDGR67ofdFmDz9oPAy2G92Ujrntmow==", - "dev": true, - "requires": { - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "dependencies": { - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - } - } - }, - "jest-message-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.5.0.tgz", - "integrity": "sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.5.0", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.5.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-mock": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.5.0.tgz", - "integrity": "sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "jest-util": "^29.5.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.4.3.tgz", - "integrity": "sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==", - "dev": true - }, - "jest-resolve": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.5.0.tgz", - "integrity": "sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.5.0", - "jest-validate": "^29.5.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.5.0.tgz", - "integrity": "sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==", - "dev": true, - "requires": { - "jest-regex-util": "^29.4.3", - "jest-snapshot": "^29.5.0" - } - }, - "jest-runner": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.5.0.tgz", - "integrity": "sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==", - "dev": true, - "requires": { - "@jest/console": "^29.5.0", - "@jest/environment": "^29.5.0", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.4.3", - "jest-environment-node": "^29.5.0", - "jest-haste-map": "^29.5.0", - "jest-leak-detector": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-resolve": "^29.5.0", - "jest-runtime": "^29.5.0", - "jest-util": "^29.5.0", - "jest-watcher": "^29.5.0", - "jest-worker": "^29.5.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.5.0.tgz", - "integrity": "sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==", - "dev": true, - "requires": { - "@jest/environment": "^29.5.0", - "@jest/fake-timers": "^29.5.0", - "@jest/globals": "^29.5.0", - "@jest/source-map": "^29.4.3", - "@jest/test-result": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-mock": "^29.5.0", - "jest-regex-util": "^29.4.3", - "jest-resolve": "^29.5.0", - "jest-snapshot": "^29.5.0", - "jest-util": "^29.5.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.5.0.tgz", - "integrity": "sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.5.0", - "@jest/transform": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.5.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "jest-matcher-utils": "^29.5.0", - "jest-message-util": "^29.5.0", - "jest-util": "^29.5.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.5.0", - "semver": "^7.3.5" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "diff-sequences": { - "version": "29.4.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.4.3.tgz", - "integrity": "sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==", - "dev": true - }, - "jest-diff": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.5.0.tgz", - "integrity": "sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.4.3", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "jest-matcher-utils": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz", - "integrity": "sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.5.0", - "jest-get-type": "^29.4.3", - "pretty-format": "^29.5.0" - } - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-util": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.5.0.tgz", - "integrity": "sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.5.0.tgz", - "integrity": "sha512-pC26etNIi+y3HV8A+tUGr/lph9B18GnzSRAkPaaZJIE1eFdiYm6/CewuiJQ8/RlfHd1u/8Ioi8/sJ+CmbA+zAQ==", - "dev": true, - "requires": { - "@jest/types": "^29.5.0", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.4.3", - "leven": "^3.1.0", - "pretty-format": "^29.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "pretty-format": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.5.0.tgz", - "integrity": "sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.4.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.5.0.tgz", - "integrity": "sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==", - "dev": true, - "requires": { - "@jest/test-result": "^29.5.0", - "@jest/types": "^29.5.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.5.0", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.5.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.5.0.tgz", - "integrity": "sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.5.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "lua-types": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", - "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", - "dev": true - }, - "lua-wasm-bindings": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", - "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", - "dev": true, - "requires": { - "@types/semver": "^7.3.9", - "semver": "^7.3.7" - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true, - "optional": true, - "peer": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "node-releases": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz", - "integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==", - "dev": true - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - } - }, - "object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - } - }, - "object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "requires": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - } - } - }, - "possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - } - }, - "punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true - }, - "pure-rand": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.1.tgz", - "integrity": "sha512-t+x1zEHDjBwkDGY5v5ApnZ/utcd4XYDiJsaQQoptTXgUXX95sDg1elCdJghzicm7n2mbCBJ3uYWr6M22SO19rg==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true - }, - "regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "resolve.exports": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", - "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - } - }, - "safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "requires": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - } - }, - "semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "dev": true - }, - "set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - } - }, - "set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "requires": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - } - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } - } - }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "requires": {} - }, - "ts-jest": { - "version": "29.1.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.1.0.tgz", - "integrity": "sha512-ZhNr7Z4PcYa+JjMl62ir+zPiNJfXJN6E8hSLnaUKhOgqcn8vb3e537cpkd0FuAfRK3sR1LSqM1MOhliXNgOFPA==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^29.0.0", - "json5": "^2.2.3", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "^21.0.1" - } - }, - "ts-node": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", - "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - } - }, - "tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - } - } - }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - } - }, - "typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "requires": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - } - }, - "typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", - "dev": true - }, - "typescript-eslint": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-7.13.1.tgz", - "integrity": "sha512-pvLEuRs8iS9s3Cnp/Wt//hpK8nKc8hVa3cLljHqzaJJQYP8oys8GUyIFqtlev+2lT/fqMPcyQko+HJ6iYK3nFA==", - "dev": true, - "requires": { - "@typescript-eslint/eslint-plugin": "7.13.1", - "@typescript-eslint/parser": "7.13.1", - "@typescript-eslint/utils": "7.13.1" - }, - "dependencies": { - "@typescript-eslint/eslint-plugin": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.13.1.tgz", - "integrity": "sha512-kZqi+WZQaZfPKnsflLJQCz6Ze9FFSMfXrrIOcyargekQxG37ES7DJNpJUE9Q/X5n3yTIP/WPutVNzgknQ7biLg==", - "dev": true, - "requires": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/type-utils": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/parser": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.13.1.tgz", - "integrity": "sha512-1ELDPlnLvDQ5ybTSrMhRTFDfOQEOXNM+eP+3HT/Yq7ruWpciQw+Avi73pdEbA4SooCawEWo3dtYbF68gN7Ed1A==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.13.1.tgz", - "integrity": "sha512-adbXNVEs6GmbzaCpymHQ0MB6E4TqoiVbC0iqG3uijR8ZYfpAXMGttouQzF4Oat3P2GxDVIrg7bMI/P65LiQZdg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.13.1.tgz", - "integrity": "sha512-aWDbLu1s9bmgPGXSzNCxELu+0+HQOapV/y+60gPXafR8e2g1Bifxzevaa+4L2ytCWm+CHqpELq4CSoN9ELiwCg==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "7.13.1", - "@typescript-eslint/utils": "7.13.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/types": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", - "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.13.1.tgz", - "integrity": "sha512-uxNr51CMV7npU1BxZzYjoVz9iyjckBduFBP0S5sLlh1tXYzHzgZ3BR9SVsNed+LmwKrmnqN3Kdl5t7eZ5TS1Yw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/visitor-keys": "7.13.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - } - }, - "@typescript-eslint/utils": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.13.1.tgz", - "integrity": "sha512-h5MzFBD5a/Gh/fvNdp9pTfqJAbuQC4sCN2WzuXme71lqFJsZtLbjxfSk4r3p02WIArOF9N94pdsLiGutpDbrXQ==", - "dev": true, - "requires": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.13.1", - "@typescript-eslint/types": "7.13.1", - "@typescript-eslint/typescript-estree": "7.13.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "7.13.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.13.1.tgz", - "integrity": "sha512-k/Bfne7lrP7hcb7m9zSsgcBmo+8eicqqfNAJ7uUY+jkTFpKeH2FSkWpFRtimBxgkyvqfu9jTPRbYOvud6isdXA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "7.13.1", - "eslint-visitor-keys": "^3.4.3" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz", - "integrity": "sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - } - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - } - }, - "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } } diff --git a/package.json b/package.json index edee38100..a4af277b5 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "test": "jest", "lint": "npm run lint:eslint && npm run lint:prettier", "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", - "lint:eslint": "eslint . --ext .js,.ts", + "lint:eslint": "eslint .", "fix:prettier": "prettier --write .", "check:language-extensions": "tsc --strict language-extensions/index.d.ts", "preversion": "npm run build && npm test", @@ -46,7 +46,7 @@ }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", - "enhanced-resolve": "^5.8.2", + "enhanced-resolve": "5.8.2", "picomatch": "^2.3.1", "resolve": "^1.15.1", "source-map": "^0.7.3" @@ -58,9 +58,8 @@ "@types/node": "^13.7.7", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^8.57.0", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-jest": "^26.9.0", + "eslint": "^9.11.0", + "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^29.5.0", @@ -71,6 +70,6 @@ "ts-jest": "^29.1.0", "ts-node": "^10.9.1", "typescript": "^5.6.2", - "typescript-eslint": "^7.13.1" + "typescript-eslint": "^8.7.0" } } diff --git a/src/lualib-build/plugin.ts b/src/lualib-build/plugin.ts index 48f649fdb..79233f3df 100644 --- a/src/lualib-build/plugin.ts +++ b/src/lualib-build/plugin.ts @@ -185,5 +185,4 @@ class LuaLibPrinter extends tstl.LuaPrinter { } const pluginInstance = new LuaLibPlugin(); -// eslint-disable-next-line import/no-default-export export default pluginInstance; diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index 4fd4aff0d..a7f691433 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -1,5 +1,4 @@ // https://tc39.github.io/ecma262/#sec-object.assign -// eslint-disable-next-line @typescript-eslint/ban-types export function __TS__ObjectAssign(this: void, target: T, ...sources: T[]): T { for (const i of $range(1, sources.length)) { const source = sources[i - 1]; diff --git a/src/lualib/ObjectDefineProperty.ts b/src/lualib/ObjectDefineProperty.ts index 6b275bfa0..c0dc40a1f 100644 --- a/src/lualib/ObjectDefineProperty.ts +++ b/src/lualib/ObjectDefineProperty.ts @@ -1,6 +1,5 @@ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty -// eslint-disable-next-line @typescript-eslint/ban-types import { __TS__SetDescriptor } from "./SetDescriptor"; export function __TS__ObjectDefineProperty( @@ -26,9 +25,9 @@ export function __TS__ObjectDefineProperty( descriptor = { set: desc.set, get: desc.get, - configurable: desc.configurable !== undefined ? desc.configurable : valueExists, - enumerable: desc.enumerable !== undefined ? desc.enumerable : valueExists, - writable: desc.writable !== undefined ? desc.writable : valueExists, + configurable: desc.configurable ?? valueExists, + enumerable: desc.enumerable ?? valueExists, + writable: desc.writable ?? valueExists, value: desc.value !== undefined ? desc.value : value, }; } diff --git a/src/lualib/Spread.ts b/src/lualib/Spread.ts index 3abc66f42..3c736060d 100644 --- a/src/lualib/Spread.ts +++ b/src/lualib/Spread.ts @@ -1,7 +1,6 @@ export function __TS__Spread(this: void, iterable: string | Iterable): LuaMultiReturn { const arr: T[] = []; if (typeof iterable === "string") { - // eslint-disable-next-line @typescript-eslint/prefer-for-of for (const i of $range(0, iterable.length - 1)) { arr[i] = iterable[i] as T; } diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 694e7e9a9..79e385b2b 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -39,6 +39,7 @@ export class TransformationContext { public readonly luaTarget = this.options.luaTarget ?? LuaTarget.Universal; public readonly isModule = ts.isExternalModule(this.sourceFile); public readonly isStrict = + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing (this.options.alwaysStrict ?? this.options.strict) || (this.isModule && this.options.target !== undefined && this.options.target >= ts.ScriptTarget.ES2015); diff --git a/src/typescript-internal.d.ts b/src/typescript-internal.d.ts index 684be1292..5333df95a 100644 --- a/src/typescript-internal.d.ts +++ b/src/typescript-internal.d.ts @@ -30,8 +30,6 @@ declare module "typescript" { } interface Symbol { - // false positive - // eslint-disable-next-line @typescript-eslint/ban-types parent?: Symbol; } diff --git a/src/utils.ts b/src/utils.ts index 7e6cdf879..b1877e368 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -50,7 +50,6 @@ export function formatPathToLuaPath(filePath: string): string { type NoInfer = [T][T extends any ? 0 : never]; export function getOrUpdate( - // eslint-disable-next-line @typescript-eslint/ban-types map: Map | (K extends object ? WeakMap : never), key: K, getDefaultValue: () => NoInfer @@ -62,7 +61,6 @@ export function getOrUpdate( return map.get(key)!; } -// eslint-disable-next-line @typescript-eslint/ban-types export function isNonNull(value: T | null | undefined): value is T { return value != null; } diff --git a/test/setup.ts b/test/setup.ts index e468c5ab8..e431d8519 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -3,7 +3,6 @@ import * as ts from "typescript"; import * as tstl from "../src"; declare global { - // eslint-disable-next-line @typescript-eslint/no-namespace namespace jest { // eslint-disable-next-line @typescript-eslint/naming-convention interface Matchers { diff --git a/test/transpile/plugins/add-comments.ts b/test/transpile/plugins/add-comments.ts index 9beb01432..2e9c56a5f 100644 --- a/test/transpile/plugins/add-comments.ts +++ b/test/transpile/plugins/add-comments.ts @@ -58,5 +58,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/afterEmit.ts b/test/transpile/plugins/afterEmit.ts index 53741d2b7..277258f25 100644 --- a/test/transpile/plugins/afterEmit.ts +++ b/test/transpile/plugins/afterEmit.ts @@ -20,5 +20,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/afterPrint.ts b/test/transpile/plugins/afterPrint.ts index 1c2529361..cb548218b 100644 --- a/test/transpile/plugins/afterPrint.ts +++ b/test/transpile/plugins/afterPrint.ts @@ -18,5 +18,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/arguments.ts b/test/transpile/plugins/arguments.ts index f6aa2ba6e..e90afae3b 100644 --- a/test/transpile/plugins/arguments.ts +++ b/test/transpile/plugins/arguments.ts @@ -6,7 +6,6 @@ interface Options { option: boolean; } -// eslint-disable-next-line import/no-default-export export default function plugin(options: Options): tstl.Plugin { return { visitors: { diff --git a/test/transpile/plugins/beforeEmit.ts b/test/transpile/plugins/beforeEmit.ts index 973024ba4..2deb029e4 100644 --- a/test/transpile/plugins/beforeEmit.ts +++ b/test/transpile/plugins/beforeEmit.ts @@ -13,5 +13,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/beforeTransform.ts b/test/transpile/plugins/beforeTransform.ts index 947358fa2..c93c20f91 100644 --- a/test/transpile/plugins/beforeTransform.ts +++ b/test/transpile/plugins/beforeTransform.ts @@ -11,5 +11,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/moduleResolution.ts b/test/transpile/plugins/moduleResolution.ts index 81b040080..705345a5b 100644 --- a/test/transpile/plugins/moduleResolution.ts +++ b/test/transpile/plugins/moduleResolution.ts @@ -19,5 +19,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/printer.ts b/test/transpile/plugins/printer.ts index 47627e5b5..37b6d84f7 100644 --- a/test/transpile/plugins/printer.ts +++ b/test/transpile/plugins/printer.ts @@ -20,5 +20,4 @@ const plugin: tstl.Plugin = { printer: (program, emitHost, fileName, file) => new CustomPrinter(emitHost, program, fileName).print(file), }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor-super.ts b/test/transpile/plugins/visitor-super.ts index 9a8bee5f1..3ece9458b 100644 --- a/test/transpile/plugins/visitor-super.ts +++ b/test/transpile/plugins/visitor-super.ts @@ -15,5 +15,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/plugins/visitor.ts b/test/transpile/plugins/visitor.ts index 507b9fa3d..15da18ded 100644 --- a/test/transpile/plugins/visitor.ts +++ b/test/transpile/plugins/visitor.ts @@ -7,5 +7,4 @@ const plugin: tstl.Plugin = { }, }; -// eslint-disable-next-line import/no-default-export export default plugin; diff --git a/test/transpile/resolve-plugin/ts.ts b/test/transpile/resolve-plugin/ts.ts index 60757f0a4..ff3177bab 100644 --- a/test/transpile/resolve-plugin/ts.ts +++ b/test/transpile/resolve-plugin/ts.ts @@ -1,2 +1 @@ -// eslint-disable-next-line import/no-default-export export default true; From ce0b8a7ca7fa11c8ada34d97ff9e910a8568ce11 Mon Sep 17 00:00:00 2001 From: Gudine Date: Fri, 25 Oct 2024 06:12:40 -0300 Subject: [PATCH 678/764] Fixes handling of statements before super call in subclass constructors (#1592) * Fixes handling of statements before super call in subclass constructors * Adds test for previous addition --- .../visitors/class/members/constructor.ts | 23 +++++++++---------- test/unit/classes/classes.spec.ts | 21 +++++++++++++++++ 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 73aad20a8..039e705f7 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -45,23 +45,22 @@ export function transformConstructorDeclaration( const classInstanceFields = transformClassInstanceFields(context, instanceFields); - // If there are field initializers and the first statement is a super call, - // move super call between default assignments and initializers + // If there are field initializers and there is a super call somewhere, + // move super call and everything before it to between default assignments and initializers if ( (constructorFieldsDeclarations.length > 0 || classInstanceFields.length > 0) && statement.body && statement.body.statements.length > 0 ) { - const firstStatement = statement.body.statements[0]; - if ( - ts.isExpressionStatement(firstStatement) && - ts.isCallExpression(firstStatement.expression) && - firstStatement.expression.expression.kind === ts.SyntaxKind.SuperKeyword - ) { - const superCall = body.shift(); - if (superCall) { - bodyWithFieldInitializers.push(superCall); - } + const superIndex = statement.body.statements.findIndex( + s => + ts.isExpressionStatement(s) && + ts.isCallExpression(s.expression) && + s.expression.expression.kind === ts.SyntaxKind.SuperKeyword + ); + + if (superIndex !== -1) { + bodyWithFieldInitializers.push(...body.splice(0, superIndex + 1)); } } diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 25399c833..40eccc05a 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -181,6 +181,27 @@ test("SubclassConstructor", () => { `.expectToMatchJsResult(); }); +test("SubclassConstructorPropertyInitiailizationSuperOrder", () => { + util.testFunction` + class a { + field: number; + constructor(field: number) { + this.field = field; + } + } + class b extends a { + fieldDouble = this.field * 2; + constructor(field: number) { + const newField = field + 1; + super(newField); + } + } + + const result = new b(10); + return [result.field, result.fieldDouble]; + `.expectToMatchJsResult(); +}); + test("Subclass constructor across merged namespace", () => { util.testModule` namespace NS { From 43d827410f2053ab0d75f071ef2c018b84ebd9ac Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Fri, 8 Nov 2024 20:27:00 +0100 Subject: [PATCH 679/764] Fix LuaMultiReturn not being recognized inside more complicated iterables (#1595) * Fix LuaMultiReturn not being recognized inside more complicated iterable types * Fix it in a way that doesn't break other stuff --- package-lock.json | 2 +- .../visitors/language-extensions/iterable.ts | 9 ++++-- test/unit/language-extensions/multi.spec.ts | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f76e67fd3..bbb009d47 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.26.2", + "version": "1.27.0", "lockfileVersion": 3, "requires": true, "packages": { diff --git a/src/transformation/visitors/language-extensions/iterable.ts b/src/transformation/visitors/language-extensions/iterable.ts index 5d96f409e..ee1ded7be 100644 --- a/src/transformation/visitors/language-extensions/iterable.ts +++ b/src/transformation/visitors/language-extensions/iterable.ts @@ -62,8 +62,13 @@ export function transformForOfIterableStatement( statement: ts.ForOfStatement, block: lua.Block ): lua.Statement { - const type = context.checker.getTypeAtLocation(statement.expression); - if (type.aliasTypeArguments?.length === 2 && isMultiReturnType(type.aliasTypeArguments[0])) { + const iteratedExpressionType = context.checker.getTypeAtLocation(statement.expression); + const iterableType = + iteratedExpressionType.isIntersection() && + iteratedExpressionType.types.find(t => t.symbol.escapedName === "Iterable"); + const iterableTypeArguments = (iterableType as ts.TypeReference)?.typeArguments; + + if (iterableTypeArguments && iterableTypeArguments.length > 0 && isMultiReturnType(iterableTypeArguments[0])) { const luaIterator = context.transformExpression(statement.expression); return transformForOfMultiIterableStatement( context, diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 8282ef4fc..72b330887 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -373,3 +373,31 @@ describe("LuaMultiReturn returns all values even when indexed with [0] #1411", ( .expectToEqual(1); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1591 +test("LuaMultiReturn in LuaIterable (#1591)", () => { + const lua = util.testModule` + type IterableAlias = LuaIterable>; + + declare const iterable: IterableAlias; + + for (const [a, b] of iterable) {} + ` + .withLanguageExtensions() + .getMainLuaCodeChunk(); + + expect(lua).toContain("a, b"); +}); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1591 +test("LuaMultiReturn in LuaIterable intersection (#1591)", () => { + const lua = util.testModule` + declare function iterator(): { a: string } & LuaIterable>; + + for (const [a, b] of iterator()) {} + ` + .withLanguageExtensions() + .getMainLuaCodeChunk(); + + expect(lua).toContain("a, b"); +}); From 7c6c72987a4bfc9dee24cd43185fbd5fcd768066 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Fri, 8 Nov 2024 20:29:46 +0100 Subject: [PATCH 680/764] 1.27.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bbb009d47..14467201a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.27.0", + "version": "1.27.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.27.0", + "version": "1.27.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index a4af277b5..91b0e7e63 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.27.0", + "version": "1.27.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 3cced7dbec826c889091f92307c52df08074ec7e Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Nov 2024 21:22:26 +0100 Subject: [PATCH 681/764] Transform String(x) to tostring(x) (#1602) --- src/transformation/builtins/global.ts | 3 +++ src/transformation/builtins/index.ts | 4 ++-- src/transformation/builtins/string.ts | 10 +++++++++- test/unit/builtins/string.spec.ts | 15 +++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/transformation/builtins/global.ts b/src/transformation/builtins/global.ts index 4d882b293..288414a60 100644 --- a/src/transformation/builtins/global.ts +++ b/src/transformation/builtins/global.ts @@ -4,6 +4,7 @@ import { TransformationContext } from "../context"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { isNumberType } from "../utils/typescript"; import { transformArguments } from "../visitors/call"; +import { transformStringConstructorCall } from "./string"; export function tryTransformBuiltinGlobalCall( context: TransformationContext, @@ -21,6 +22,8 @@ export function tryTransformBuiltinGlobalCall( return transformLuaLibFunction(context, LuaLibFeature.Symbol, node, ...getParameters()); case "NumberConstructor": return transformLuaLibFunction(context, LuaLibFeature.Number, node, ...getParameters()); + case "StringConstructor": + return transformStringConstructorCall(node, ...getParameters()); case "isNaN": case "isFinite": const numberParameters = isNumberType(context, expressionType) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 867942064..85a4c9802 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -14,7 +14,7 @@ import { transformMathCall, transformMathProperty } from "./math"; import { transformNumberConstructorCall, transformNumberPrototypeCall, transformNumberProperty } from "./number"; import { transformObjectConstructorCall, tryTransformObjectPrototypeCall } from "./object"; import { transformPromiseConstructorCall } from "./promise"; -import { transformStringConstructorCall, transformStringProperty, transformStringPrototypeCall } from "./string"; +import { transformStringConstructorMethodCall, transformStringProperty, transformStringPrototypeCall } from "./string"; import { transformSymbolConstructorCall } from "./symbol"; import { unsupportedBuiltinOptionalCall } from "../utils/diagnostics"; import { LuaTarget } from "../../CompilerOptions"; @@ -101,7 +101,7 @@ function tryTransformBuiltinGlobalMethodCall( result = transformMathCall(context, node, calledMethod); break; case "StringConstructor": - result = transformStringConstructorCall(context, node, calledMethod); + result = transformStringConstructorMethodCall(context, node, calledMethod); break; case "ObjectConstructor": result = transformObjectConstructorCall(context, node, calledMethod); diff --git a/src/transformation/builtins/string.ts b/src/transformation/builtins/string.ts index b7c56a08c..98bd62303 100644 --- a/src/transformation/builtins/string.ts +++ b/src/transformation/builtins/string.ts @@ -160,7 +160,7 @@ export function transformStringPrototypeCall( } } -export function transformStringConstructorCall( +export function transformStringConstructorMethodCall( context: TransformationContext, node: ts.CallExpression, calledMethod: ts.PropertyAccessExpression @@ -202,3 +202,11 @@ export function transformStringProperty( context.diagnostics.push(unsupportedProperty(node.name, "string", node.name.text)); } } + +export function transformStringConstructorCall( + originalNode: ts.CallExpression, + ...args: lua.Expression[] +): lua.Expression | undefined { + const tostring = lua.createIdentifier("tostring", originalNode.expression); + return lua.createCallExpression(tostring, args, originalNode); +} diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index fecb0e466..977944e55 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -372,6 +372,21 @@ test("string intersected method", () => { `.expectToMatchJsResult(); }); +test("tostring number with String constructor", () => { + util.testFunction` + const n = 123 + return "abc:" + String(n); + `.expectToEqual("abc:123"); +}); + +test("tostring table with String constructor", () => { + const result = util.testFunction` + const t = {} + return "abc:" + String(t); + `.getLuaExecutionResult(); + expect(result).toContain("abc:table: 0x"); +}); + // Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218 test.each(['"foo"', "undefined"])("prototype call on nullable string (%p)", value => { util.testFunction` From fb43e4f85d16c698e85549d5e2aa550ddde258f3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 26 Nov 2024 21:55:35 +0100 Subject: [PATCH 682/764] Upgrade typescript to 5.7 (#1603) * Upgrade typescript to 5.7 * Fix breaking of new types --- package-lock.json | 201 +++++++++++++++++++++------------------------- package.json | 16 ++-- test/cli/run.ts | 2 +- 3 files changed, 101 insertions(+), 118 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14467201a..1b16faf4d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,9 @@ }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/glob": "^7.1.1", + "@types/glob": "^7.2.0", "@types/jest": "^27.5.2", - "@types/node": "^13.7.7", + "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", "eslint": "^9.11.0", @@ -30,20 +30,20 @@ "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^29.5.0", - "jest-circus": "^29.5.0", + "jest-circus": "^29.7.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.8.8", - "ts-jest": "^29.1.0", - "ts-node": "^10.9.1", - "typescript": "^5.6.2", - "typescript-eslint": "^8.7.0" + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", + "typescript": "5.7.2", + "typescript-eslint": "^8.16.0" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.6.2" + "typescript": "5.7.2" } }, "node_modules/@ampproject/remapping": { @@ -817,11 +817,10 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", + "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", "dev": true, - "license": "Apache-2.0", "dependencies": { "levn": "^0.4.1" }, @@ -1514,7 +1513,6 @@ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", "dev": true, - "license": "MIT", "dependencies": { "@types/minimatch": "*", "@types/node": "*" @@ -1562,7 +1560,6 @@ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", "dev": true, - "license": "MIT", "dependencies": { "jest-matcher-utils": "^27.0.0", "pretty-format": "^27.0.0" @@ -1583,11 +1580,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", + "version": "22.10.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", + "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", "dev": true, - "license": "MIT" + "dependencies": { + "undici-types": "~6.20.0" + } }, "node_modules/@types/picomatch": { "version": "2.3.4", @@ -1638,17 +1637,16 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.7.0.tgz", - "integrity": "sha512-RIHOoznhA3CCfSTFiB6kBGLQtB/sox+pJ6jeFu6FxJvqL8qRxq/FfGO/UhsGgQM9oGdXkV4xUgli+dt26biB6A==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", + "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/type-utils": "8.7.0", - "@typescript-eslint/utils": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/type-utils": "8.16.0", + "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", @@ -1672,16 +1670,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.7.0.tgz", - "integrity": "sha512-lN0btVpj2unxHlNYLI//BQ7nzbMJYBVQX5+pbNXvGYazdlgYonMn4AhhHifQ+J4fGRYA/m1DjaQjx+fDetqBOQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", + "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/typescript-estree": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "debug": "^4.3.4" }, "engines": { @@ -1701,14 +1698,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.7.0.tgz", - "integrity": "sha512-87rC0k3ZlDOuz82zzXRtQ7Akv3GKhHs0ti4YcbAJtaomllXoSO8hi7Ix3ccEvCd824dy9aIX+j3d2UMAfCtVpg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", + "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0" + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1719,14 +1715,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.7.0.tgz", - "integrity": "sha512-tl0N0Mj3hMSkEYhLkjREp54OSb/FI6qyCzfiiclvJvOqre6hsZTGSnHtmFLDU8TIM62G7ygEa1bI08lcuRwEnQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", + "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.7.0", - "@typescript-eslint/utils": "8.7.0", + "@typescript-eslint/typescript-estree": "8.16.0", + "@typescript-eslint/utils": "8.16.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1737,6 +1732,9 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true @@ -1744,11 +1742,10 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.7.0.tgz", - "integrity": "sha512-LLt4BLHFwSfASHSF2K29SZ+ZCsbQOM+LuarPjRUuHm+Qd09hSe3GCeaQbcCr+Mik+0QFRmep/FyZBO6fJ64U3w==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", + "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", "dev": true, - "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1758,14 +1755,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.7.0.tgz", - "integrity": "sha512-MC8nmcGHsmfAKxwnluTQpNqceniT8SteVwd2voYlmiSWGOtjvGXdPl17dYu2797GVscK30Z04WRM28CrKS9WOg==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", + "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/visitor-keys": "8.7.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/visitor-keys": "8.16.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -1791,7 +1787,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -1801,7 +1796,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1813,16 +1807,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.7.0.tgz", - "integrity": "sha512-ZbdUdwsl2X/s3CiyAu3gOlfQzpbuG3nTWKPoIvAu1pu5r8viiJvv2NPN2AqArL35NCYtw/lrPPfM4gxrMLNLPw==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", + "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.7.0", - "@typescript-eslint/types": "8.7.0", - "@typescript-eslint/typescript-estree": "8.7.0" + "@typescript-eslint/scope-manager": "8.16.0", + "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/typescript-estree": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1833,17 +1826,21 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.7.0.tgz", - "integrity": "sha512-b1tx0orFCCh/THWPQa2ZwWzvOeyzzp36vkJYOpVg0u8UVOIsfVrnuC9FqAw9gRKn+rG2VmWQ/zDJZzkxUnj/XQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", + "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.7.0", - "eslint-visitor-keys": "^3.4.3" + "@typescript-eslint/types": "8.16.0", + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1853,19 +1850,6 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@typescript-to-lua/language-extensions": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", @@ -2410,11 +2394,10 @@ "license": "MIT" }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, - "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2700,11 +2683,10 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", - "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2929,7 +2911,6 @@ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2946,7 +2927,6 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, - "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3609,7 +3589,6 @@ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, - "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -4732,7 +4711,6 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } @@ -5604,7 +5582,6 @@ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", "dev": true, - "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", "ejs": "^3.1.10", @@ -5653,7 +5630,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5729,11 +5705,10 @@ } }, "node_modules/typescript": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.2.tgz", - "integrity": "sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5743,15 +5718,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.7.0.tgz", - "integrity": "sha512-nEHbEYJyHwsuf7c3V3RS7Saq+1+la3i0ieR3qP0yjqWSzVmh8Drp47uOl9LjbPANac4S7EFSqvcYIKXUUwIfIQ==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.16.0.tgz", + "integrity": "sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==", "dev": true, - "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.7.0", - "@typescript-eslint/parser": "8.7.0", - "@typescript-eslint/utils": "8.7.0" + "@typescript-eslint/eslint-plugin": "8.16.0", + "@typescript-eslint/parser": "8.16.0", + "@typescript-eslint/utils": "8.16.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5760,12 +5734,21 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + }, "peerDependenciesMeta": { "typescript": { "optional": true } } }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true + }, "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", diff --git a/package.json b/package.json index 91b0e7e63..149b67c45 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.6.2" + "typescript": "5.7.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -53,9 +53,9 @@ }, "devDependencies": { "@types/fs-extra": "^8.1.0", - "@types/glob": "^7.1.1", + "@types/glob": "^7.2.0", "@types/jest": "^27.5.2", - "@types/node": "^13.7.7", + "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", "eslint": "^9.11.0", @@ -63,13 +63,13 @@ "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", "jest": "^29.5.0", - "jest-circus": "^29.5.0", + "jest-circus": "^29.7.0", "lua-types": "^2.13.0", "lua-wasm-bindings": "^0.3.1", "prettier": "^2.8.8", - "ts-jest": "^29.1.0", - "ts-node": "^10.9.1", - "typescript": "^5.6.2", - "typescript-eslint": "^8.7.0" + "ts-jest": "^29.2.5", + "ts-node": "^10.9.2", + "typescript": "5.7.2", + "typescript-eslint": "^8.16.0" } } diff --git a/test/cli/run.ts b/test/cli/run.ts index 652e03095..732d71bcb 100644 --- a/test/cli/run.ts +++ b/test/cli/run.ts @@ -26,6 +26,6 @@ export async function runCli(args: string[]): Promise { child.stderr!.on("data", (data: Buffer) => (output += data.toString())); return new Promise(resolve => { - child.on("close", exitCode => resolve({ exitCode, output })); + child.on("close", exitCode => resolve({ exitCode: exitCode ?? 1, output })); }); } From 93d35f46221dac6c403f2dd3f88baa0b85d26d12 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 26 Nov 2024 22:00:52 +0100 Subject: [PATCH 683/764] CHANGELOG.md 1.28.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca1e46b07..ee190091a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.28.0 + +- Upgraded TypeScript to 5.7.2 +- Support `String(x)` transforming it to `tostring(x)`. +- Fixed statements before class super call +- Fixed some bugs with `LuaMultiReturn` used in iterables + ## 1.27.0 - Upgraded TypeScript to 5.6.2 From 3a4a03776c567fd05d8345b841ec94d3de8dcfbe Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 26 Nov 2024 22:03:31 +0100 Subject: [PATCH 684/764] 1.28.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1b16faf4d..3296cd1d7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.27.1", + "version": "1.28.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.27.1", + "version": "1.28.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 149b67c45..5815c68d6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.27.1", + "version": "1.28.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 2963b01dc0f26adf23cb2e46a0aaa1a1916f6b20 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 26 Nov 2024 22:16:52 +0100 Subject: [PATCH 685/764] 1.28.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3296cd1d7..3772b95e8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.28.0", + "version": "1.28.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.28.0", + "version": "1.28.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 5815c68d6..58b5b17eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.28.0", + "version": "1.28.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 030bb2a80a5125681311f81c296491773fb3be05 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Wed, 25 Dec 2024 16:17:14 +0100 Subject: [PATCH 686/764] Fix missing index increment (#1606) --- src/transformation/utils/typescript/types.ts | 18 ++++++++++++++---- test/unit/builtins/array.spec.ts | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/transformation/utils/typescript/types.ts b/src/transformation/utils/typescript/types.ts index 5ba2a013c..4a356b972 100644 --- a/src/transformation/utils/typescript/types.ts +++ b/src/transformation/utils/typescript/types.ts @@ -56,6 +56,20 @@ export function isNumberType(context: TransformationContext, type: ts.Type): boo function isExplicitArrayType(context: TransformationContext, type: ts.Type): boolean { if (context.checker.isArrayType(type) || context.checker.isTupleType(type)) return true; + + if (type.isUnionOrIntersection()) { + if (type.types.some(t => isExplicitArrayType(context, t))) { + return true; + } + } + + const baseTypes = type.getBaseTypes(); + if (baseTypes) { + if (baseTypes.some(t => isExplicitArrayType(context, t))) { + return true; + } + } + if (type.symbol) { const baseConstraint = context.checker.getBaseConstraintOfType(type); if (baseConstraint && baseConstraint !== type) { @@ -63,10 +77,6 @@ function isExplicitArrayType(context: TransformationContext, type: ts.Type): boo } } - if (type.isUnionOrIntersection()) { - return type.types.some(t => isExplicitArrayType(context, t)); - } - return false; } diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 1e952a162..1784ed73b 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -884,3 +884,17 @@ describe("copying array methods", () => { }); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1605 +test("array indexing in optional chain (#1605)", () => { + util.testModule` + interface Foo extends Array {} + const b: {arr?: Foo} = {arr:[1,2]}; + export const t = b.arr?.[1]; + + const c: Foo | undefined = b.arr; + export const u = c?.[1]; + ` + .setOptions({ strict: true }) // crucial to reproducing for some reason + .expectToMatchJsResult(); +}); From 6dfe2526befa09555a3748781f82a75284d3b2eb Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 28 Dec 2024 12:27:50 +0100 Subject: [PATCH 687/764] Allow new Array() syntax for constructing lua tables (#1609) * allow newArray syntax for constructing arrays * Also support array constructor with arguments --- src/transformation/builtins/index.ts | 5 +++- src/transformation/utils/diagnostics.ts | 4 +++ src/transformation/visitors/class/new.ts | 28 +++++++++++++++++++- test/unit/builtins/array.spec.ts | 33 +++++++++++++++++++++++- 4 files changed, 67 insertions(+), 3 deletions(-) diff --git a/src/transformation/builtins/index.ts b/src/transformation/builtins/index.ts index 85a4c9802..3eefd64c9 100644 --- a/src/transformation/builtins/index.ts +++ b/src/transformation/builtins/index.ts @@ -221,7 +221,10 @@ export function checkForLuaLibType(context: TransformationContext, type: ts.Type } } -function tryGetStandardLibrarySymbolOfType(context: TransformationContext, type: ts.Type): ts.Symbol | undefined { +export function tryGetStandardLibrarySymbolOfType( + context: TransformationContext, + type: ts.Type +): ts.Symbol | undefined { if (type.isUnionOrIntersection()) { for (const subType of type.types) { const symbol = tryGetStandardLibrarySymbolOfType(context, subType); diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 137bd15b8..5fb1bf15e 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -172,3 +172,7 @@ export const cannotAssignToNodeOfKind = createErrorDiagnosticFactory( export const incompleteFieldDecoratorWarning = createWarningDiagnosticFactory( "You are using a class field decorator, note that tstl ignores returned value initializers!" ); + +export const unsupportedArrayWithLengthConstructor = createErrorDiagnosticFactory( + `Constructing new Array with length is not supported.` +); diff --git a/src/transformation/visitors/class/new.ts b/src/transformation/visitors/class/new.ts index 7c608bc65..0c5733451 100644 --- a/src/transformation/visitors/class/new.ts +++ b/src/transformation/visitors/class/new.ts @@ -2,16 +2,42 @@ import * as ts from "typescript"; import * as lua from "../../../LuaAST"; import { FunctionVisitor } from "../../context"; import { AnnotationKind, getTypeAnnotations } from "../../utils/annotations"; -import { annotationInvalidArgumentCount } from "../../utils/diagnostics"; +import { annotationInvalidArgumentCount, unsupportedArrayWithLengthConstructor } from "../../utils/diagnostics"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { transformArguments, transformCallAndArguments } from "../call"; import { isTableNewCall } from "../language-extensions/table"; +import { tryGetStandardLibrarySymbolOfType } from "../../builtins"; export const transformNewExpression: FunctionVisitor = (node, context) => { if (isTableNewCall(context, node)) { return lua.createTableExpression(undefined, node); } + const constructorType = context.checker.getTypeAtLocation(node.expression); + if (tryGetStandardLibrarySymbolOfType(context, constructorType)?.name === "ArrayConstructor") { + if (node.arguments === undefined || node.arguments.length === 0) { + // turn new Array<>() into a simple {} + return lua.createTableExpression([], node); + } else { + // More than one argument, check if items constructor + const signature = context.checker.getResolvedSignature(node); + const signatureDeclaration = signature?.getDeclaration(); + if ( + signatureDeclaration?.parameters.length === 1 && + signatureDeclaration.parameters[0].dotDotDotToken === undefined + ) { + context.diagnostics.push(unsupportedArrayWithLengthConstructor(node)); + return lua.createTableExpression([], node); + } else { + const callArguments = transformArguments(context, node.arguments, signature); + return lua.createTableExpression( + callArguments.map(e => lua.createTableFieldExpression(e)), + node + ); + } + } + } + const signature = context.checker.getResolvedSignature(node); const [name, params] = transformCallAndArguments(context, node.expression, node.arguments ?? [], signature); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 1784ed73b..3c6a3a7c7 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -1,4 +1,7 @@ -import { undefinedInArrayLiteral } from "../../../src/transformation/utils/diagnostics"; +import { + undefinedInArrayLiteral, + unsupportedArrayWithLengthConstructor, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; test("omitted expression", () => { @@ -898,3 +901,31 @@ test("array indexing in optional chain (#1605)", () => { .setOptions({ strict: true }) // crucial to reproducing for some reason .expectToMatchJsResult(); }); + +test("new Array()", () => { + util.testFunction` + const arr = new Array(); + arr.push(1,2,3); + return arr; + ` + .debug() + .expectToMatchJsResult(); +}); + +test("new Array()", () => { + util.testFunction` + const arr = new Array(); + arr.push(1,2,3); + return arr; + `.expectToMatchJsResult(); +}); + +test("new Array(length)", () => { + util.testFunction` + const arr = new Array(10); + `.expectToHaveDiagnostics([unsupportedArrayWithLengthConstructor.code]); +}); + +test("new Array(...items)", () => { + util.testExpression`new Array(1,2,3,4,5) `.expectToMatchJsResult(); +}); From 7cb97ad7233cfdd0346b9c7d302bbeaa3beb69be Mon Sep 17 00:00:00 2001 From: Vurv Date: Sun, 29 Dec 2024 06:44:37 -0800 Subject: [PATCH 688/764] Basic `Luau` target (#1608) * Initial Luau implementation * Add support for luau specific transformation fixtures Also fixed not providing Luau to the `expectEachVersionExceptJit` function. It seems to work properly in the test suite but I need to make sure that this is intended or if the function should be renamed to something else (like `expectOnlyPUC`) and exclude Luau as well. * Refactor target specific fixtures Now stored in separate folders. Future proof and doesn't feel gross. Also disabled Luau in expectEachVersionExceptJit. Ideally the function would be renamed but the change would be too large here (not necessary either). * Add remaining Luau test suite cases Luau supports both math.atan & math.atan2 so having a certain result isn't important. Same goes for table.unpack and unpack. Had to pass an empty function for the continue case where luau wouldn't make a label at all since it has a proper continue statement. * Fix eslint issue --- src/CompilerOptions.ts | 1 + src/LuaAST.ts | 37 +++++++++++++++++++ src/LuaPrinter.ts | 19 ++++++++++ src/transformation/utils/scope.ts | 1 + src/transformation/visitors/break-continue.ts | 20 +++++++--- src/transformation/visitors/conditional.ts | 11 ++++++ src/transformation/visitors/loops/utils.ts | 1 + test/cli/parse.spec.ts | 1 + .../__snapshots__/transformation.spec.ts.snap | 12 ++++++ test/translation/transformation.spec.ts | 36 +++++++++++------- .../luau/luauSpecificTransformations.ts | 9 +++++ test/unit/builtins/math.spec.ts | 1 + test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 2 + test/util.ts | 1 + tsconfig-schema.json | 2 +- 16 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 test/translation/transformation/luau/luauSpecificTransformations.ts diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 5f740123b..35004d25d 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -62,6 +62,7 @@ export enum LuaTarget { Lua53 = "5.3", Lua54 = "5.4", LuaJIT = "JIT", + Luau = "Luau", } export enum BuildMode { diff --git a/src/LuaAST.ts b/src/LuaAST.ts index 994755617..ad4a7e06b 100644 --- a/src/LuaAST.ts +++ b/src/LuaAST.ts @@ -25,6 +25,7 @@ export enum SyntaxKind { LabelStatement, ReturnStatement, BreakStatement, + ContinueStatement, // Luau only. ExpressionStatement, // Expression @@ -45,6 +46,7 @@ export enum SyntaxKind { Identifier, TableIndexExpression, ParenthesizedExpression, + ConditionalExpression, // Luau only // Operators @@ -488,6 +490,18 @@ export function createBreakStatement(tsOriginal?: ts.Node): BreakStatement { return createNode(SyntaxKind.BreakStatement, tsOriginal) as BreakStatement; } +export interface ContinueStatement extends Statement { + kind: SyntaxKind.ContinueStatement; +} + +export function isContinueStatement(node: Node): node is ContinueStatement { + return node.kind === SyntaxKind.ContinueStatement; +} + +export function createContinueStatement(tsOriginal?: ts.Node): ContinueStatement { + return createNode(SyntaxKind.ContinueStatement, tsOriginal) as ContinueStatement; +} + export interface ExpressionStatement extends Statement { kind: SyntaxKind.ExpressionStatement; expression: Expression; @@ -861,3 +875,26 @@ export function createParenthesizedExpression(expression: Expression, tsOriginal parenthesizedExpression.expression = expression; return parenthesizedExpression; } + +export type ConditionalExpression = Expression & { + condition: Expression; + whenTrue: Expression; + whenFalse: Expression; +}; + +export function isConditionalExpression(node: Node): node is ConditionalExpression { + return node.kind === SyntaxKind.ConditionalExpression; +} + +export function createConditionalExpression( + condition: Expression, + whenTrue: Expression, + whenFalse: Expression, + tsOriginal?: ts.Node +): ConditionalExpression { + const conditionalExpression = createNode(SyntaxKind.ConditionalExpression, tsOriginal) as ConditionalExpression; + conditionalExpression.condition = condition; + conditionalExpression.whenTrue = whenTrue; + conditionalExpression.whenFalse = whenFalse; + return conditionalExpression; +} diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 1f89dd4ec..26ea7cc06 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -396,6 +396,8 @@ export class LuaPrinter { return this.printReturnStatement(statement as lua.ReturnStatement); case lua.SyntaxKind.BreakStatement: return this.printBreakStatement(statement as lua.BreakStatement); + case lua.SyntaxKind.ContinueStatement: + return this.printContinueStatement(statement as lua.ContinueStatement); case lua.SyntaxKind.ExpressionStatement: return this.printExpressionStatement(statement as lua.ExpressionStatement); default: @@ -574,6 +576,10 @@ export class LuaPrinter { return this.createSourceNode(statement, this.indent("break")); } + public printContinueStatement(statement: lua.ContinueStatement): SourceNode { + return this.createSourceNode(statement, this.indent("continue")); + } + public printExpressionStatement(statement: lua.ExpressionStatement): SourceNode { return this.createSourceNode(statement, [this.indent(), this.printExpression(statement.expression)]); } @@ -614,6 +620,8 @@ export class LuaPrinter { return this.printTableIndexExpression(expression as lua.TableIndexExpression); case lua.SyntaxKind.ParenthesizedExpression: return this.printParenthesizedExpression(expression as lua.ParenthesizedExpression); + case lua.SyntaxKind.ConditionalExpression: + return this.printConditionalExpression(expression as lua.ConditionalExpression); default: throw new Error(`Tried to print unknown statement kind: ${lua.SyntaxKind[expression.kind]}`); } @@ -828,6 +836,17 @@ export class LuaPrinter { return this.createSourceNode(expression, ["(", this.printExpression(expression.expression), ")"]); } + public printConditionalExpression(expression: lua.ConditionalExpression): SourceNode { + return this.createSourceNode(expression, [ + "if ", + this.printExpression(expression.condition), + " then ", + this.printExpression(expression.whenTrue), + " else ", + this.printExpression(expression.whenFalse), + ]); + } + public printOperator(kind: lua.Operator): SourceNode { return new SourceNode(null, null, this.relativeSourcePath, LuaPrinter.operatorMap[kind]); } diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 87f431162..2b0351e4f 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -25,6 +25,7 @@ interface FunctionDefinitionInfo { export enum LoopContinued { WithGoto, WithRepeatBreak, + WithContinue, } export interface Scope { diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index cfc411439..87487475d 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -11,12 +11,17 @@ export const transformBreakStatement: FunctionVisitor = (brea export const transformContinueStatement: FunctionVisitor = (statement, context) => { const scope = findScope(context, ScopeType.Loop); - const continuedWith = - context.luaTarget === LuaTarget.Universal || - context.luaTarget === LuaTarget.Lua50 || - context.luaTarget === LuaTarget.Lua51 - ? LoopContinued.WithRepeatBreak - : LoopContinued.WithGoto; + + const continuedWith = { + [LuaTarget.Universal]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua50]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua51]: LoopContinued.WithRepeatBreak, + [LuaTarget.Lua52]: LoopContinued.WithGoto, + [LuaTarget.Lua53]: LoopContinued.WithGoto, + [LuaTarget.Lua54]: LoopContinued.WithGoto, + [LuaTarget.LuaJIT]: LoopContinued.WithGoto, + [LuaTarget.Luau]: LoopContinued.WithContinue, + }[context.luaTarget]; if (scope) { scope.loopContinued = continuedWith; @@ -28,6 +33,9 @@ export const transformContinueStatement: FunctionVisitor = case LoopContinued.WithGoto: return lua.createGotoStatement(label, statement); + case LoopContinued.WithContinue: + return lua.createContinueStatement(statement); + case LoopContinued.WithRepeatBreak: return [ lua.createAssignmentStatement(lua.createIdentifier(label), lua.createBooleanLiteral(true), statement), diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index 178f6ac2d..b90c7e2db 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -6,6 +6,7 @@ import { performHoisting, ScopeType } from "../utils/scope"; import { transformBlockOrStatement } from "./block"; import { canBeFalsy } from "../utils/typescript"; import { truthyOnlyConditionalValue } from "../utils/diagnostics"; +import { LuaTarget } from "../../CompilerOptions"; function transformProtectedConditionalExpression( context: TransformationContext, @@ -38,6 +39,16 @@ function transformProtectedConditionalExpression( } export const transformConditionalExpression: FunctionVisitor = (expression, context) => { + if (context.luaTarget === LuaTarget.Luau) { + // Luau's ternary operator doesn't have these issues + return lua.createConditionalExpression( + context.transformExpression(expression.condition), + context.transformExpression(expression.whenTrue), + context.transformExpression(expression.whenFalse), + expression + ); + } + // Check if we need to add diagnostic about Lua truthiness checkOnlyTruthyCondition(expression.condition, context); diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index f34b35245..01466b450 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -21,6 +21,7 @@ export function transformLoopBody( switch (scope.loopContinued) { case undefined: + case LoopContinued.WithContinue: return body; case LoopContinued.WithGoto: diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index 283b4095e..e06a8fafd 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -248,6 +248,7 @@ describe("tsconfig", () => { ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], ["luaTarget", "5.4", { luaTarget: tstl.LuaTarget.Lua54 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], + ["luaTarget", "luau", { luaTarget: tstl.LuaTarget.Luau }], ["luaBundle", "foo", { luaBundle: "foo" }], ["luaBundleEntry", "bar", { luaBundleEntry: "bar" }], diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index b0c7eea52..555092795 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Luau Transformation (luauSpecificTransformations) 1`] = ` +"t = if true then "is true" else "is false" +while false do + continue +end +repeat + do + continue + end +until not false" +`; + exports[`Transformation (blockScopeVariables) 1`] = ` "do local a = 1 diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index 42a4b4355..fc7d66e49 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -5,17 +5,27 @@ import { annotationDeprecated } from "../../src/transformation/utils/diagnostics import { couldNotResolveRequire } from "../../src/transpilation/diagnostics"; import * as util from "../util"; -const fixturesPath = path.join(__dirname, "./transformation"); -const fixtures = fs - .readdirSync(fixturesPath) - .filter(f => path.extname(f) === ".ts") - .sort() - .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); +const targetSpecs: Array<[string, tstl.LuaTarget | undefined, string]> = [ + ["", undefined, "./transformation"], + ["Luau ", tstl.LuaTarget.Luau, "./transformation/luau"], +]; -test.each(fixtures)("Transformation (%s)", (_name, content) => { - util.testModule(content) - .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) - .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) - .disableSemanticCheck() - .expectLuaToMatchSnapshot(); -}); +for (const [name, luaTarget, targetDir] of targetSpecs) { + const fixturesPath = path.join(__dirname, targetDir); + const fixtures = fs + .readdirSync(fixturesPath) + .filter(f => path.extname(f) === ".ts") + .sort() + .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); + + test.each(fixtures)(`${name}Transformation (%s)`, (_name, content) => { + util.testModule(content) + .setOptions({ + luaLibImport: tstl.LuaLibImportKind.Require, + luaTarget, + }) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); + }); +} diff --git a/test/translation/transformation/luau/luauSpecificTransformations.ts b/test/translation/transformation/luau/luauSpecificTransformations.ts new file mode 100644 index 000000000..b4c9fdec4 --- /dev/null +++ b/test/translation/transformation/luau/luauSpecificTransformations.ts @@ -0,0 +1,9 @@ +const t = true ? "is true" : "is false"; + +while (false) { + continue; +} + +do { + continue; +} while (false); diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index aebaead4c..b8f6b2cc3 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -96,6 +96,7 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectMathAtan2), }); util.testEachVersion( diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index f2225c7f5..7e13c6db4 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -553,6 +553,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, + [tstl.LuaTarget.Luau]: () => undefined, // TODO: This is N/A. }); } diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 04b1bd726..3a1add475 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -81,6 +81,7 @@ describe("in function call", () => { [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); }); @@ -94,6 +95,7 @@ describe("in array literal", () => { [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); test("of array literal /w OmittedExpression", () => { diff --git a/test/util.ts b/test/util.ts index 73942a473..7ebe1ccd3 100644 --- a/test/util.ts +++ b/test/util.ts @@ -87,6 +87,7 @@ export function expectEachVersionExceptJit( [tstl.LuaTarget.Lua53]: expectation, [tstl.LuaTarget.Lua54]: expectation, [tstl.LuaTarget.LuaJIT]: false, // Exclude JIT + [tstl.LuaTarget.Luau]: false, }; } diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 5af971b49..87366ea76 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -50,7 +50,7 @@ "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "JIT"] + "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "JIT", "Luau"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", From 1dba0603831b8b8d8f90d80fe3914eadc1ab76c8 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 29 Dec 2024 16:49:28 +0100 Subject: [PATCH 689/764] clean up tests --- .../__snapshots__/transformation.spec.ts.snap | 2 +- test/translation/transformation.spec.ts | 49 ++++++++++--------- test/unit/builtins/array.spec.ts | 4 +- test/unit/loops.spec.ts | 5 +- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 555092795..6753c66b1 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Luau Transformation (luauSpecificTransformations) 1`] = ` +exports[`Luau-specific Transformation (luauSpecificTransformations) 1`] = ` "t = if true then "is true" else "is false" while false do continue diff --git a/test/translation/transformation.spec.ts b/test/translation/transformation.spec.ts index fc7d66e49..5f9df58fe 100644 --- a/test/translation/transformation.spec.ts +++ b/test/translation/transformation.spec.ts @@ -5,27 +5,32 @@ import { annotationDeprecated } from "../../src/transformation/utils/diagnostics import { couldNotResolveRequire } from "../../src/transpilation/diagnostics"; import * as util from "../util"; -const targetSpecs: Array<[string, tstl.LuaTarget | undefined, string]> = [ - ["", undefined, "./transformation"], - ["Luau ", tstl.LuaTarget.Luau, "./transformation/luau"], -]; +const fixturesPath = path.join(__dirname, "./transformation"); +const fixtures = fs + .readdirSync(fixturesPath) + .filter(f => path.extname(f) === ".ts") + .sort() + .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); -for (const [name, luaTarget, targetDir] of targetSpecs) { - const fixturesPath = path.join(__dirname, targetDir); - const fixtures = fs - .readdirSync(fixturesPath) - .filter(f => path.extname(f) === ".ts") - .sort() - .map(f => [path.parse(f).name, fs.readFileSync(path.join(fixturesPath, f), "utf8")]); +test.each(fixtures)("Transformation (%s)", (_name, content) => { + util.testModule(content) + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require }) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); - test.each(fixtures)(`${name}Transformation (%s)`, (_name, content) => { - util.testModule(content) - .setOptions({ - luaLibImport: tstl.LuaLibImportKind.Require, - luaTarget, - }) - .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) - .disableSemanticCheck() - .expectLuaToMatchSnapshot(); - }); -} +const luauFixturesPath = path.join(fixturesPath, "luau"); +const luauFixtures = fs + .readdirSync(luauFixturesPath) + .filter(f => path.extname(f) === ".ts") + .sort() + .map(f => [path.parse(f).name, fs.readFileSync(path.join(luauFixturesPath, f), "utf8")]); + +test.each(luauFixtures)("Luau-specific Transformation (%s)", (_name, content) => { + util.testModule(content) + .setOptions({ luaLibImport: tstl.LuaLibImportKind.Require, luaTarget: tstl.LuaTarget.Luau }) + .ignoreDiagnostics([annotationDeprecated.code, couldNotResolveRequire.code]) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index 3c6a3a7c7..dfb6807ec 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -907,9 +907,7 @@ test("new Array()", () => { const arr = new Array(); arr.push(1,2,3); return arr; - ` - .debug() - .expectToMatchJsResult(); + `.expectToMatchJsResult(); }); test("new Array()", () => { diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 7e13c6db4..903cf6a1e 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -545,6 +545,9 @@ for (const testCase of [ const expectContinueGotoLabel: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); + const expectContinueStatement: util.TapCallback = builder => + expect(builder.getMainLuaCodeChunk()).toMatch("continue;"); + util.testEachVersion(`loop continue (${testCase})`, () => util.testModule(testCase), { [tstl.LuaTarget.Universal]: expectContinueVariable, [tstl.LuaTarget.Lua50]: expectContinueVariable, @@ -553,7 +556,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, - [tstl.LuaTarget.Luau]: () => undefined, // TODO: This is N/A. + [tstl.LuaTarget.Luau]: () => expectContinueStatement, }); } From f5d7d1ec6cf5d243bebc7d2e632e2ce555148492 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 30 Dec 2024 15:56:01 +0100 Subject: [PATCH 690/764] CHANGELOG.md 1.29.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee190091a..d860c18e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.29.0 + +- Added support for the `Luau` luaTarget. This will use Luau's `continue` statement and ternary conditional expression `if ... then ... else ...` where appropriate. +- Added support for `new Array()` syntax to construct arrays (constructing with a length argument is not allowed). +- Fixed a bug causing arrays to sometimes be indexed with a wrong index. + ## 1.28.0 - Upgraded TypeScript to 5.7.2 From e2e7578f55b621db80f82d8c0ae433e60d7115f7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Mon, 30 Dec 2024 15:58:31 +0100 Subject: [PATCH 691/764] 1.29.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3772b95e8..d08dac427 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.28.1", + "version": "1.29.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.28.1", + "version": "1.29.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 58b5b17eb..80380b85d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.28.1", + "version": "1.29.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From b706a850f6324e86e95f4092fcb25d452e4a567f Mon Sep 17 00:00:00 2001 From: Emma Date: Thu, 16 Jan 2025 12:14:28 -0800 Subject: [PATCH 692/764] Allow stacktraces in Lua 5.1 and LuaJIT and fix level in lualib (#1610) * Allow stacktraces in Lua 5.1 and LuaJIT * Fix the constructor passed when getting the stacktrace * Fix testEachVersion builder * Fix lint * Run prettier --- src/lualib/Error.ts | 11 +++++++++-- test/unit/error.spec.ts | 25 +++++++++++++++++++++++++ test/util.ts | 4 ++-- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/lualib/Error.ts b/src/lualib/Error.ts index ea9cba478..ae5deb05b 100644 --- a/src/lualib/Error.ts +++ b/src/lualib/Error.ts @@ -1,3 +1,5 @@ +import { __TS__New } from "./New"; + interface ErrorType { name: string; new (...args: any[]): Error; @@ -22,6 +24,11 @@ function getErrorStack(constructor: () => any): string | undefined { if (_VERSION.includes("Lua 5.0")) { return debug.traceback(`[Level ${level}]`); + // @ts-ignore Fails when compiled with Lua 5.0 types + } else if (_VERSION === "Lua 5.1") { + // Lua 5.1 and LuaJIT have a bug where it's not possible to specify the level without a message. + // @ts-ignore Fails when compiled with Lua 5.0 types + return string.sub(debug.traceback("", level), 2); } else { // @ts-ignore Fails when compiled with Lua 5.0 types return debug.traceback(undefined, level); @@ -33,7 +40,7 @@ function wrapErrorToString(getDescription: (this: T) => string) const description = getDescription.call(this as T); const caller = debug.getinfo(3, "f"); // @ts-ignore Fails when compiled with Lua 5.0 types - const isClassicLua = _VERSION.includes("Lua 5.0") || _VERSION === "Lua 5.1"; + const isClassicLua = _VERSION.includes("Lua 5.0"); if (isClassicLua || (caller && caller.func !== error)) { return description; } else { @@ -55,7 +62,7 @@ export const Error: ErrorConstructor = initErrorClass( public stack?: string; constructor(public message = "") { - this.stack = getErrorStack((this.constructor as any).new); + this.stack = getErrorStack(__TS__New as any); const metatable = getmetatable(this); if (metatable && !metatable.__errorToStringPatched) { metatable.__errorToStringPatched = true; diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 388fee290..05399d492 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -1,4 +1,5 @@ import * as util from "../util"; +import * as tstl from "../../src"; test("throwString", () => { util.testFunction` @@ -343,3 +344,27 @@ test("still works without debug module", () => { stack: undefined, }); }); + +util.testEachVersion( + "error stacktrace omits constructor and __TS_New", + () => util.testFunction` + const e = new Error(); + return e.stack; + `, + { + ...util.expectEachVersionExceptJit(builder => { + builder.expectToHaveNoDiagnostics(); + const luaResult = builder.getLuaExecutionResult(); + // eslint-disable-next-line jest/no-standalone-expect + expect(luaResult.split("\n")).toHaveLength(4); + }), + + // 5.0 debug.traceback doesn't support levels + [tstl.LuaTarget.Lua50](builder) { + builder.expectToHaveNoDiagnostics(); + const luaResult = builder.getLuaExecutionResult(); + // eslint-disable-next-line jest/no-standalone-expect + expect(luaResult).toContain("Level 4"); + }, + } +); diff --git a/test/util.ts b/test/util.ts index 7ebe1ccd3..501b24bfb 100644 --- a/test/util.ts +++ b/test/util.ts @@ -43,7 +43,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l return { lauxlib, lua, lualib }; } if (target === tstl.LuaTarget.LuaJIT) { - throw Error("Can't use executeLua() or expectToMatchJsResult() wit LuaJIT as target!"); + throw Error("Can't use executeLua() or expectToMatchJsResult() with LuaJIT as target!"); } const { lauxlib, lua, lualib } = require("lua-wasm-bindings/dist/lua.54"); @@ -63,7 +63,7 @@ export function testEachVersion( ): void { for (const version of Object.values(tstl.LuaTarget) as tstl.LuaTarget[]) { const specialBuilder = special?.[version]; - if (specialBuilder === false) return; + if (specialBuilder === false) continue; const testName = name === undefined ? version : `${name} [${version}]`; defineTest(testName, () => { From 7ebbff5a350215af32a99fab417759f229f889ca Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 16 Jan 2025 21:22:23 +0100 Subject: [PATCH 693/764] 1.29.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index d08dac427..14472b6b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.29.0", + "version": "1.29.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.29.0", + "version": "1.29.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 80380b85d..129d675e3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.29.0", + "version": "1.29.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From aa6593db6ad652683ea066d1d87cc13b4433634a Mon Sep 17 00:00:00 2001 From: "iced.wav" Date: Fri, 31 Jan 2025 16:31:32 +0100 Subject: [PATCH 694/764] Add in-memory plugins (#1614) --- src/CompilerOptions.ts | 8 +++- src/transpilation/plugins.ts | 26 ++++++++---- test/transpile/plugins/plugins.spec.ts | 59 ++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 35004d25d..7f5562c07 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; +import { Plugin } from "./transpilation/plugins"; type OmitIndexSignature = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; @@ -23,6 +24,11 @@ export interface LuaPluginImport { [option: string]: any; } +export interface InMemoryLuaPlugin { + plugin: Plugin | ((options: Record) => Plugin); + [option: string]: any; +} + export interface TypeScriptToLuaOptions { buildMode?: BuildMode; extension?: string; @@ -30,7 +36,7 @@ export interface TypeScriptToLuaOptions { luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; - luaPlugins?: LuaPluginImport[]; + luaPlugins?: Array; noImplicitGlobalVariables?: boolean; noImplicitSelf?: boolean; noHeader?: boolean; diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 74e4e542e..f84af2bc9 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -77,15 +77,23 @@ export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; for (const [index, pluginOption] of (options.luaPlugins ?? []).entries()) { const optionName = `tstl.luaPlugins[${index}]`; - const { error: resolveError, result: factory } = resolvePlugin( - "plugin", - `${optionName}.name`, - getConfigDirectory(options), - pluginOption.name, - pluginOption.import - ); - - if (resolveError) diagnostics.push(resolveError); + const factory = (() => { + if ("plugin" in pluginOption) { + return pluginOption.plugin; + } else { + const { error: resolveError, result: factory } = resolvePlugin( + "plugin", + `${optionName}.name`, + getConfigDirectory(options), + pluginOption.name, + pluginOption.import + ); + + if (resolveError) diagnostics.push(resolveError); + return factory; + } + })(); + if (factory === undefined) continue; const plugin = typeof factory === "function" ? factory(pluginOption) : factory; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 72c9e29a7..ed25ae748 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -1,5 +1,6 @@ import * as path from "path"; import * as util from "../../util"; +import { Plugin } from "../../../src/transpilation/plugins"; import * as ts from "typescript"; test("printer", () => { @@ -182,3 +183,61 @@ test("afterEmit plugin", () => { expect(diagnostic?.category).toBe(ts.DiagnosticCategory.Message); expect(diagnostic?.messageText).toContain("After emit"); }); + +test("in memory plugin", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + plugin: { + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: 1234, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin, + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +}); + +test("in memory plugin with factory", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + code: 1234, + plugin: options => + ({ + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: options.code, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin), + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +}); From 1562b4c413bff1930e39609bbb418d0c08193ab7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 2 Feb 2025 13:23:05 +0100 Subject: [PATCH 695/764] Changelog 1.30.0 --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d860c18e8..a769fff72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.30.0 + +- Allow passing in-memory plugins when using the tstl API, for more flexible integration into scripts +- Changed how stracktraces are handled for `Error` in Lua 5.1 and LuaJIT + ## 1.29.0 - Added support for the `Luau` luaTarget. This will use Luau's `continue` statement and ternary conditional expression `if ... then ... else ...` where appropriate. From 4dbe3112476dcb7a93151b94131c50ce2b7ca5bc Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 2 Feb 2025 13:26:53 +0100 Subject: [PATCH 696/764] 1.30.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 14472b6b9..96e5ba9ce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.29.1", + "version": "1.30.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.29.1", + "version": "1.30.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 129d675e3..42d3c464e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.29.1", + "version": "1.30.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 04f2cebe184b844d321ac04d55a388d38176eea1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 2 Feb 2025 13:28:17 +0100 Subject: [PATCH 697/764] fix typo in readme --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a769fff72..76d9bdd46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## 1.30.0 - Allow passing in-memory plugins when using the tstl API, for more flexible integration into scripts -- Changed how stracktraces are handled for `Error` in Lua 5.1 and LuaJIT +- Changed how stacktraces are handled for `Error` in Lua 5.1 and LuaJIT ## 1.29.0 From e6daa5f65595c7bb07725f471550582c75c246d9 Mon Sep 17 00:00:00 2001 From: Jesse Rosenthal Date: Sat, 8 Feb 2025 06:16:43 -0500 Subject: [PATCH 698/764] Add `bit` and `bit32` as lua keywords (#1617) If code uses bitwise operations, it will import `bit32` (for lua 5.2 target) or `bit` (for luajit target). Add these to the keywords list in safe-names.ts to make sure that they are not overwritten by a variable with the same name. Closes #1615 --- src/transformation/utils/safe-names.ts | 2 ++ test/unit/identifiers.spec.ts | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/transformation/utils/safe-names.ts b/src/transformation/utils/safe-names.ts index 538d77a91..0772d71a8 100644 --- a/src/transformation/utils/safe-names.ts +++ b/src/transformation/utils/safe-names.ts @@ -16,6 +16,8 @@ export const isValidLuaIdentifier = (name: string, options: CompilerOptions) => export const luaKeywords: ReadonlySet = new Set([ "and", + "bit", + "bit32", "break", "do", "else", diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 14f86fff8..4ef550c4e 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -577,6 +577,15 @@ describe("lua keyword as identifier doesn't interfere with lua's value", () => { expect(luaResult).toBe("foobar"); }); + test("variable (bit32)", () => { + util.testFunction` + const bit32 = 1; + return bit32 << 1; + ` + .setOptions({ luaTarget: LuaTarget.Lua52 }) + .expectToMatchJsResult(); + }); + test("variable (_G)", () => { util.testFunction` const _G = "bar"; From f3d4207ec506e2e46267c352aff46aff613ea695 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 8 Feb 2025 12:19:42 +0100 Subject: [PATCH 699/764] 1.30.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 96e5ba9ce..4afce7c7b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.30.0", + "version": "1.30.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.30.0", + "version": "1.30.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 42d3c464e..1b65f10dd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.30.0", + "version": "1.30.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 6fb39b622c79d624b3a3d49a2a81bb2d456cf4ba Mon Sep 17 00:00:00 2001 From: "iced.wav" Date: Sun, 16 Feb 2025 17:39:29 +0100 Subject: [PATCH 700/764] Change currentIndent to protected (#1620) Allows overriding `pushIndent` / `popIndent` to change indention style in plugins --- src/LuaPrinter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index 26ea7cc06..b0a02dfaf 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -157,7 +157,7 @@ export class LuaPrinter { }; private static rightAssociativeOperators = new Set([lua.SyntaxKind.ConcatOperator, lua.SyntaxKind.PowerOperator]); - private currentIndent = ""; + protected currentIndent = ""; protected luaFile: string; protected relativeSourcePath: string; protected options: CompilerOptions; From ad2f9f2504acc325313dd7bf4994c71c1c0160a3 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 9 Mar 2025 18:05:30 +0100 Subject: [PATCH 701/764] TypeScript 5.8.2 --- package-lock.json | 411 ++++++++---------- package.json | 8 +- src/transformation/visitors/modules/import.ts | 5 +- 3 files changed, 198 insertions(+), 226 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4afce7c7b..8c1e48927 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^9.11.0", + "eslint": "^9.22.0", "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", @@ -36,14 +36,14 @@ "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "5.7.2", - "typescript-eslint": "^8.16.0" + "typescript": "^5.8.2", + "typescript-eslint": "^8.26.0" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.7.2" + "typescript": "^5.8.2" } }, "node_modules/@ampproject/remapping": { @@ -738,23 +738,21 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", "dev": true, - "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", + "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", "dev": true, - "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.4", + "@eslint/object-schema": "^2.1.6", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -762,22 +760,32 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-helpers": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", + "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, "node_modules/@eslint/core": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", - "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", + "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", "dev": true, - "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", - "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", + "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", "dev": true, - "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -797,37 +805,71 @@ } }, "node_modules/@eslint/js": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.11.1.tgz", - "integrity": "sha512-/qu+TWz8WwPWc7/HcIJKi+c+MOm46GdVaSlTTQcaqaL53+GsoA6MxWp5PtTx48qbSP7ylM1Kn7nhvkugfJvRSA==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", + "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", "dev": true, - "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", + "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", "dev": true, - "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.3.tgz", - "integrity": "sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==", + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", + "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", "dev": true, "dependencies": { + "@eslint/core": "^0.12.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.6", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", + "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "dev": true, + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.3.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -843,11 +885,10 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.0.tgz", - "integrity": "sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz", + "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==", "dev": true, - "license": "Apache-2.0", "engines": { "node": ">=18.18" }, @@ -1358,7 +1399,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1372,7 +1412,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, - "license": "MIT", "engines": { "node": ">= 8" } @@ -1382,7 +1421,6 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, - "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1637,20 +1675,20 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.16.0.tgz", - "integrity": "sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", + "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.16.0", - "@typescript-eslint/type-utils": "8.16.0", - "@typescript-eslint/utils": "8.16.0", - "@typescript-eslint/visitor-keys": "8.16.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/type-utils": "8.26.0", + "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1661,24 +1699,20 @@ }, "peerDependencies": { "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.16.0.tgz", - "integrity": "sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", + "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.16.0", - "@typescript-eslint/types": "8.16.0", - "@typescript-eslint/typescript-estree": "8.16.0", - "@typescript-eslint/visitor-keys": "8.16.0", + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4" }, "engines": { @@ -1689,22 +1723,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.16.0.tgz", - "integrity": "sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", + "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.16.0", - "@typescript-eslint/visitor-keys": "8.16.0" + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1715,15 +1745,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.16.0.tgz", - "integrity": "sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", + "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "8.16.0", - "@typescript-eslint/utils": "8.16.0", + "@typescript-eslint/typescript-estree": "8.26.0", + "@typescript-eslint/utils": "8.26.0", "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1733,18 +1763,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.16.0.tgz", - "integrity": "sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", + "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", "dev": true, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1755,19 +1781,19 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.16.0.tgz", - "integrity": "sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", + "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.16.0", - "@typescript-eslint/visitor-keys": "8.16.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/visitor-keys": "8.26.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" + "ts-api-utils": "^2.0.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1776,10 +1802,8 @@ "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "peerDependencies": { + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { @@ -1807,15 +1831,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.16.0.tgz", - "integrity": "sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", + "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.16.0", - "@typescript-eslint/types": "8.16.0", - "@typescript-eslint/typescript-estree": "8.16.0" + "@typescript-eslint/scope-manager": "8.26.0", + "@typescript-eslint/types": "8.26.0", + "@typescript-eslint/typescript-estree": "8.26.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1825,21 +1849,17 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.16.0.tgz", - "integrity": "sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", + "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "8.16.0", + "@typescript-eslint/types": "8.26.0", "eslint-visitor-keys": "^4.2.0" }, "engines": { @@ -1857,11 +1877,10 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1874,7 +1893,6 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1897,7 +1915,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, - "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1976,8 +1993,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" + "dev": true }, "node_modules/async": { "version": "3.2.6", @@ -2577,32 +2593,32 @@ } }, "node_modules/eslint": { - "version": "9.11.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.11.1.tgz", - "integrity": "sha512-MobhYKIoAO1s1e4VUrgx1l1Sk2JBR/Gqjjgw8+mfgoLE2xwsHur4gdfTxyTgShrhvdVFTaJSgMiQBl1jv/AWxg==", + "version": "9.22.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", + "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", "dev": true, - "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/core": "^0.6.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.11.1", - "@eslint/plugin-kit": "^0.2.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.19.2", + "@eslint/config-helpers": "^0.1.0", + "@eslint/core": "^0.12.0", + "@eslint/eslintrc": "^3.3.0", + "@eslint/js": "9.22.0", + "@eslint/plugin-kit": "^0.2.7", + "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", + "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", + "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.0", + "eslint-scope": "^8.3.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2612,14 +2628,11 @@ "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" + "optionator": "^0.9.3" }, "bin": { "eslint": "bin/eslint.js" @@ -2666,11 +2679,10 @@ } }, "node_modules/eslint-scope": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.2.tgz", - "integrity": "sha512-6E4xmrTw5wtxnLA5wYL3WDfhZ/1bUBGOXV0zQvVRDOtrR8D0p6W7fs3JweNYhwRYeGvd/1CKX2se0/2s7Q/nJA==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", + "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2695,15 +2707,14 @@ } }, "node_modules/espree": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", - "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", + "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.12.0", + "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.0.0" + "eslint-visitor-keys": "^4.2.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2744,7 +2755,6 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2903,20 +2913,19 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -2949,11 +2958,10 @@ "license": "MIT" }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, - "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3194,7 +3202,6 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "license": "MIT", "engines": { "node": ">=18" }, @@ -3265,11 +3272,10 @@ } }, "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, - "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3405,16 +3411,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -4485,7 +4481,6 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, - "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4524,8 +4519,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" + "dev": true }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -4894,7 +4888,6 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, - "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -5128,7 +5121,6 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, - "license": "MIT", "engines": { "node": ">=6" } @@ -5168,8 +5160,7 @@ "type": "consulting", "url": "https://feross.org/support" } - ], - "license": "MIT" + ] }, "node_modules/react-is": { "version": "17.0.2", @@ -5233,7 +5224,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } @@ -5249,11 +5239,10 @@ } }, "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, - "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -5278,7 +5267,6 @@ "url": "https://feross.org/support" } ], - "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -5527,13 +5515,6 @@ "node": ">=8" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -5565,16 +5546,15 @@ } }, "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", + "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", "dev": true, - "license": "MIT", "engines": { - "node": ">=16" + "node": ">=18.12" }, "peerDependencies": { - "typescript": ">=4.2.0" + "typescript": ">=4.8.4" } }, "node_modules/ts-jest": { @@ -5705,9 +5685,9 @@ } }, "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", + "version": "5.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", + "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5718,14 +5698,14 @@ } }, "node_modules/typescript-eslint": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.16.0.tgz", - "integrity": "sha512-wDkVmlY6O2do4V+lZd0GtRfbtXbeD0q9WygwXXSJnC1xorE8eqyC2L1tJimqpSeFrOzRlYtWnUp/uzgHQOgfBQ==", + "version": "8.26.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", + "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", "dev": true, "dependencies": { - "@typescript-eslint/eslint-plugin": "8.16.0", - "@typescript-eslint/parser": "8.16.0", - "@typescript-eslint/utils": "8.16.0" + "@typescript-eslint/eslint-plugin": "8.26.0", + "@typescript-eslint/parser": "8.26.0", + "@typescript-eslint/utils": "8.26.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5735,12 +5715,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.9.0" } }, "node_modules/undici-types": { @@ -5795,7 +5771,6 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, - "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 1b65f10dd..ebc2962dc 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.7.2" + "typescript": "5.8.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -58,7 +58,7 @@ "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^9.11.0", + "eslint": "^9.22.0", "eslint-plugin-jest": "^28.8.3", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", @@ -69,7 +69,7 @@ "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "5.7.2", - "typescript-eslint": "^8.16.0" + "typescript": "5.8.2", + "typescript-eslint": "^8.26.0" } } diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index 66432fb44..b3a1d74a2 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -47,10 +47,7 @@ function transformImportSpecifier( moduleTableName: lua.Identifier ): lua.VariableDeclarationStatement { const leftIdentifier = transformIdentifier(context, importSpecifier.name); - const propertyName = transformPropertyName( - context, - importSpecifier.propertyName ? importSpecifier.propertyName : importSpecifier.name - ); + const propertyName = transformPropertyName(context, importSpecifier.propertyName ?? importSpecifier.name); return lua.createVariableDeclarationStatement( leftIdentifier, From f021c94193511cc95e79f6fb2f18689c7a8847f2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 9 Mar 2025 18:14:08 +0100 Subject: [PATCH 702/764] CHANGELOG 1.31.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76d9bdd46..b96eb944c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.31.0 + +- Upgraded TypeScript to 5.8.2 +- Changed `currentIndent` from private to protected in the `LuaPrinter` to allow custom printers with alternate indentation +- Added `bit` and `bit32` as reserved Lua keywords to avoid accidental naming clashes. + ## 1.30.0 - Allow passing in-memory plugins when using the tstl API, for more flexible integration into scripts From c836a365cadda992ca946e316b7851318e37c23b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 9 Mar 2025 18:16:42 +0100 Subject: [PATCH 703/764] 1.31.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8c1e48927..48f4978dd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.30.1", + "version": "1.31.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.30.1", + "version": "1.31.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index ebc2962dc..411987781 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.30.1", + "version": "1.31.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 54d7ac34efc66ab600f9eeb0405f7f0d0ce451a0 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 24 May 2025 12:28:57 +0200 Subject: [PATCH 704/764] Fix root level using statement not disposing object (#1633) --- .../pre-transformers/using-transformer.ts | 20 ++++++++++++++----- test/unit/using.spec.ts | 16 +++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/transformation/pre-transformers/using-transformer.ts b/src/transformation/pre-transformers/using-transformer.ts index d78f6206a..1229b71c2 100644 --- a/src/transformation/pre-transformers/using-transformer.ts +++ b/src/transformation/pre-transformers/using-transformer.ts @@ -5,11 +5,13 @@ import { LuaLibFeature, importLuaLibFeature } from "../utils/lualib"; export function usingTransformer(context: TransformationContext): ts.TransformerFactory { return ctx => sourceFile => { function visit(node: ts.Node): ts.Node { - if (ts.isBlock(node)) { + if (ts.isBlock(node) || ts.isSourceFile(node)) { const [hasUsings, newStatements] = transformBlockWithUsing(context, node.statements, node); if (hasUsings) { // Recurse visitor into updated block to find further usings - const updatedBlock = ts.factory.updateBlock(node, newStatements); + const updatedBlock = ts.isBlock(node) + ? ts.factory.updateBlock(node, newStatements) + : ts.factory.updateSourceFile(node, newStatements); const result = ts.visitEachChild(updatedBlock, visit, ctx); // Set all the synthetic node parents to something that makes sense @@ -29,7 +31,8 @@ export function usingTransformer(context: TransformationContext): ts.Transformer } return ts.visitEachChild(node, visit, ctx); } - return ts.visitEachChild(sourceFile, visit, ctx); + const transformedSourceFile = ts.visitEachChild(sourceFile, visit, ctx); + return visit(transformedSourceFile) as ts.SourceFile; }; } @@ -40,7 +43,7 @@ function isUsingDeclarationList(node: ts.Node): node is ts.VariableStatement { function transformBlockWithUsing( context: TransformationContext, statements: ts.NodeArray | ts.Statement[], - block: ts.Block + block: ts.Block | ts.SourceFile ): [true, ts.Statement[]] | [false] { const newStatements: ts.Statement[] = []; @@ -102,7 +105,14 @@ function transformBlockWithUsing( call = ts.factory.createAwaitExpression(call); } - if (ts.isBlock(block.parent) && block.parent.statements[block.parent.statements.length - 1] !== block) { + if (ts.isSourceFile(block)) { + // If block is a sourcefile, don't insert a return statement into root code + newStatements.push(ts.factory.createExpressionStatement(call)); + } else if ( + block.parent && + ts.isBlock(block.parent) && + block.parent.statements[block.parent.statements.length - 1] !== block + ) { // If this is a free-standing block in a function (not the last statement), dont return the value newStatements.push(ts.factory.createExpressionStatement(call)); } else { diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts index 34b4fef67..bfe5312b0 100644 --- a/test/unit/using.spec.ts +++ b/test/unit/using.spec.ts @@ -217,3 +217,19 @@ test("works with disposable classes (#1584)", () => { return log; `.expectToEqual(["action", "cleanup"]); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1632 +test("works on root level (#1632)", () => { + util.testModule` + export let disposed = false; + + class A { + [Symbol.dispose] = function (this: A) { + disposed = true; + } + } + using a = new A(); + `.expectToEqual({ + disposed: true, + }); +}); From ec84670c5366863fd9259b32d4d9516b89ad8ffa Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 24 May 2025 16:06:08 +0200 Subject: [PATCH 705/764] Convert unary + or - expressions to numbers (#1635) --- .../visitors/unary-expression.ts | 35 +++++++++++++------ .../__snapshots__/expressions.spec.ts.snap | 12 ++++--- test/unit/builtins/numbers.spec.ts | 15 ++++++++ 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/src/transformation/visitors/unary-expression.ts b/src/transformation/visitors/unary-expression.ts index 5960c2200..88b512757 100644 --- a/src/transformation/visitors/unary-expression.ts +++ b/src/transformation/visitors/unary-expression.ts @@ -7,6 +7,8 @@ import { transformCompoundAssignmentExpression, transformCompoundAssignmentStatement, } from "./binary-expression/compound"; +import { isNumberType } from "../utils/typescript"; +import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; export function transformUnaryExpressionStatement( context: TransformationContext, @@ -92,16 +94,29 @@ export const transformPrefixUnaryExpression: FunctionVisitor { util.testExpression(comparison).expectToEqual(true); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1629 +test("unary + casting to number (#1629)", () => { + util.testFunction` + let abc = "123"; + return [+abc, +"456"]; + `.expectToEqual([123, 456]); +}); + +test("unary - casting to number", () => { + util.testFunction` + let abc = "123"; + return [-abc, -"456"]; + `.expectToEqual([-123, -456]); +}); From 596a87a1cd75cfc22ae1281fe68070789b1c7ac3 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 24 May 2025 16:24:22 +0200 Subject: [PATCH 706/764] Fix decorator on class exported from namespace (#1636) --- src/transformation/utils/export.ts | 8 ++++++++ src/transformation/visitors/class/index.ts | 4 ++-- test/unit/classes/decorators.spec.ts | 24 +++++++++++++++++++++- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/transformation/utils/export.ts b/src/transformation/utils/export.ts index fa1c03649..f0ef437e5 100644 --- a/src/transformation/utils/export.ts +++ b/src/transformation/utils/export.ts @@ -20,6 +20,14 @@ export function hasExportModifier(node: ts.Node): boolean { ); } +export function shouldBeExported(node: ts.Node): boolean { + if (hasExportModifier(node)) { + // Don't export if we're inside a namespace (module declaration) + return ts.findAncestor(node, ts.isModuleDeclaration) === undefined; + } + return false; +} + export const createDefaultExportStringLiteral = (original?: ts.Node): lua.StringLiteral => lua.createStringLiteral("default", original); diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index 0edfce050..d4633995e 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -5,8 +5,8 @@ import { createDefaultExportExpression, createExportedIdentifier, hasDefaultExportModifier, - hasExportModifier, isSymbolExported, + shouldBeExported, } from "../../utils/export"; import { createSelfIdentifier } from "../../utils/lua-ast"; import { createSafeName, isUnsafeName } from "../../utils/safe-names"; @@ -214,7 +214,7 @@ function transformClassLikeDeclaration( const decoratingStatement = lua.createAssignmentStatement(localClassName, decoratingExpression); result.push(decoratingStatement); - if (hasExportModifier(classDeclaration)) { + if (shouldBeExported(classDeclaration)) { const exportExpression = hasDefaultExportModifier(classDeclaration) ? createDefaultExportExpression(classDeclaration) : createExportedIdentifier(context, className); diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index 1923f8b2b..4782746be 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -138,7 +138,7 @@ test("Exported class decorator", () => { }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1149 -test("exported class with decorator", () => { +test("exported class with decorator (#1149)", () => { util.testModule` import { MyClass } from "./other"; const inst = new MyClass(); @@ -164,6 +164,28 @@ test("exported class with decorator", () => { .expectToEqual({ result: "overridden" }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1634 +test("namespaced exported class with decorator (#1634)", () => { + util.testModule` + function myDecorator(target: {new(): any}, context: ClassDecoratorContext) { + return class extends target { + foo() { + return "overridden"; + } + } + } + + namespace ns { + @myDecorator + export class MyClass { + foo() { + return "foo"; + } + } + } + `.expectNoExecutionError(); +}); + test("default exported class with decorator", () => { util.testModule` import MyClass from "./other"; From 2bb9a4651cda8582e8a0ac22ca44fe3476042c03 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 24 May 2025 16:27:08 +0200 Subject: [PATCH 707/764] 1.31.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48f4978dd..4f4838c85 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.31.0", + "version": "1.31.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.31.0", + "version": "1.31.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 411987781..c1102a52c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.31.0", + "version": "1.31.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9795e996495ae0117ab7656138577416de51792a Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Jun 2025 16:22:44 +0200 Subject: [PATCH 708/764] Fix tagged template literals when the tag is returned from a function call (#1639) --- src/transformation/visitors/call.ts | 2 +- test/unit/templateLiterals.spec.ts | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index 1f9fb521b..d37561910 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -159,7 +159,7 @@ export function transformContextualCallExpression( ); return lua.createCallExpression(expression, transformedArguments, node); } - } else if (ts.isIdentifier(left)) { + } else if (ts.isIdentifier(left) || ts.isCallExpression(left)) { const callContext = context.isStrict ? ts.factory.createNull() : ts.factory.createIdentifier("_G"); let expression: lua.Expression; [expression, transformedArguments] = transformCallWithArguments( diff --git a/test/unit/templateLiterals.spec.ts b/test/unit/templateLiterals.spec.ts index d5dc519a5..318804ee9 100644 --- a/test/unit/templateLiterals.spec.ts +++ b/test/unit/templateLiterals.spec.ts @@ -83,3 +83,26 @@ test.each(["string", "'string literal type'", "string & unknown"])( .expectToMatchJsResult(); } ); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1637 +test("tagged template literal returned from function call (#1637)", () => { + util.testModule` + function templateFactory() { + return (template: TemplateStringsArray) => { + return "bar"; + } + } + export let result = templateFactory()\`foo\`; + `.expectToEqual({ result: "bar" }); +}); + +test("tagged template literal returned from function call, explicit no context (#1637)", () => { + util.testModule` + function templateFactory() { + return function(this: void, template: TemplateStringsArray) { + return "bar"; + } + } + export let result = templateFactory()\`foo\`; + `.expectToEqual({ result: "bar" }); +}); From 9a9817e2c89d92b15c74eaadf725a9d022145021 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Jun 2025 16:23:14 +0200 Subject: [PATCH 709/764] Fix continue in loops sometimes generating dead code (#1640) --- src/transformation/visitors/loops/utils.ts | 20 ++++++++++++++++---- test/unit/loops.spec.ts | 14 ++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 01466b450..0997c6583 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -31,13 +31,25 @@ export function transformLoopBody( const identifier = lua.createIdentifier(`__continue${scopeId}`); const literalTrue = lua.createBooleanLiteral(true); + // If there is a break in the body statements, do not include any code afterwards + const transformedBodyStatements = []; + let bodyBroken = false; + for (const statement of body) { + transformedBodyStatements.push(statement); + if (lua.isBreakStatement(statement)) { + bodyBroken = true; + break; + } + } + if (!bodyBroken) { + // Tell loop to continue if not broken + transformedBodyStatements.push(lua.createAssignmentStatement(identifier, literalTrue)); + } + return [ lua.createDoStatement([ lua.createVariableDeclarationStatement(identifier), - lua.createRepeatStatement( - lua.createBlock([...body, lua.createAssignmentStatement(identifier, literalTrue)]), - literalTrue - ), + lua.createRepeatStatement(lua.createBlock(transformedBodyStatements), literalTrue), lua.createIfStatement( lua.createUnaryExpression(identifier, lua.SyntaxKind.NotOperator), lua.createBlock([lua.createBreakStatement()]) diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 903cf6a1e..419f53c35 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -560,6 +560,20 @@ for (const testCase of [ }); } +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1638 +test.each([tstl.LuaTarget.Universal, tstl.LuaTarget.Lua50, tstl.LuaTarget.Lua51])( + "no unreachable code when using continue for target %s (#1638)", + target => { + util.testFunction` + let i = 0; + while(++i < 10) continue; + return i; + ` + .setOptions({ luaTarget: target }) + .expectToMatchJsResult(); + } +); + test("do...while", () => { util.testFunction` let result = 0; From 45fb7eb6e487b98885f0ffb56fd176164e2f6f18 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 8 Jun 2025 16:38:46 +0200 Subject: [PATCH 710/764] Fix loop variables incorrectly being made global (#1641) --- src/transformation/visitors/loops/for.ts | 5 +++++ test/unit/loops.spec.ts | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 3a82b5a24..0c272e225 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -4,10 +4,13 @@ import { FunctionVisitor } from "../../context"; import { transformInPrecedingStatementScope } from "../../utils/preceding-statements"; import { checkVariableDeclarationList, transformVariableDeclaration } from "../variable-declaration"; import { invertCondition, transformLoopBody } from "./utils"; +import { ScopeType } from "../../utils/scope"; export const transformForStatement: FunctionVisitor = (statement, context) => { const result: lua.Statement[] = []; + context.pushScope(ScopeType.Loop); + if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { checkVariableDeclarationList(context, statement.initializer); @@ -61,5 +64,7 @@ export const transformForStatement: FunctionVisitor = (statemen // while (condition) do ... end result.push(lua.createWhileStatement(lua.createBlock(body), condition, statement)); + context.popScope(); + return lua.createDoStatement(result, statement); }; diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 419f53c35..1591da181 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -540,10 +540,10 @@ for (const testCase of [ "for (const a of []) { continue; }", ]) { const expectContinueVariable: util.TapCallback = builder => - expect(builder.getMainLuaCodeChunk()).toMatch("local __continue2"); + expect(builder.getMainLuaCodeChunk()).toMatch(/local __continue\d+/); const expectContinueGotoLabel: util.TapCallback = builder => - expect(builder.getMainLuaCodeChunk()).toMatch("::__continue2::"); + expect(builder.getMainLuaCodeChunk()).toMatch(/::__continue\d+::/); const expectContinueStatement: util.TapCallback = builder => expect(builder.getMainLuaCodeChunk()).toMatch("continue;"); @@ -638,3 +638,12 @@ test("for...in with pre-defined variable keeps last value", () => { // Need custom matcher because order is not guaranteed in neither JS nor Lua expect([keyX, keyFoo]).toContain(result); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1631 +test("loop variables should not be global (#1631)", () => { + const code = util.testModule` + for (let val = 0; val < 2; ++val) {} + `.getMainLuaCodeChunk(); + + expect(code).toContain("local val"); +}); From 7fed67bbf8776ecd6f458dc3affb21741d2bc996 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Jun 2025 16:46:54 +0200 Subject: [PATCH 711/764] 1.31.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4f4838c85..b2fdb24d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.31.1", + "version": "1.31.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.31.1", + "version": "1.31.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index c1102a52c..3a1e7efe8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.31.1", + "version": "1.31.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From ecad13ff527b59ab27b43c32ee0222b5ab218d43 Mon Sep 17 00:00:00 2001 From: HanaTaka2137 <96463311+XiYang6666@users.noreply.github.com> Date: Sat, 12 Jul 2025 21:36:26 +0800 Subject: [PATCH 712/764] fix: resolve #1647 (#1648) * fix: resolve #1647 * test: add test --- src/transformation/utils/function-context.ts | 3 ++- .../__snapshots__/noSelfAnnotation.spec.ts.snap | 5 +++++ test/unit/functions/noSelfAnnotation.spec.ts | 13 +++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index 5b2c0cb4e..d61ffb5bf 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -124,7 +124,8 @@ function computeDeclarationContextType(context: TransformationContext, signature ts.isConstructSignatureDeclaration(signatureDeclaration) || ts.isConstructorDeclaration(signatureDeclaration) || (signatureDeclaration.parent && ts.isPropertyDeclaration(signatureDeclaration.parent)) || - (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) + (signatureDeclaration.parent && ts.isPropertySignature(signatureDeclaration.parent)) || + (signatureDeclaration.parent && ts.isIndexSignatureDeclaration(signatureDeclaration.parent)) ) { // Class/interface methods only respect @noSelf on their parent const scopeDeclaration = findFirstNodeAbove( diff --git a/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap b/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap index f4e5fdd6d..64eb65457 100644 --- a/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap +++ b/test/unit/functions/__snapshots__/noSelfAnnotation.spec.ts.snap @@ -13,3 +13,8 @@ exports[`@noSelf on parent class declaration removes context argument 1`] = `"ho exports[`@noSelf on parent interface declaration removes context argument 1`] = `"holder.myMethod()"`; exports[`@noSelf on parent namespace declaration removes context argument 1`] = `"MyNamespace.myMethod()"`; + +exports[`@noSelf on static class methods with string key access 1`] = ` +"TestClass.myMethod() +TestClass.myKey()" +`; diff --git a/test/unit/functions/noSelfAnnotation.spec.ts b/test/unit/functions/noSelfAnnotation.spec.ts index b25742a11..f8418fabd 100644 --- a/test/unit/functions/noSelfAnnotation.spec.ts +++ b/test/unit/functions/noSelfAnnotation.spec.ts @@ -52,6 +52,19 @@ test("@noSelf on parent namespace declaration removes context argument", () => { `.expectLuaToMatchSnapshot(); }); +test("@noSelf on static class methods with string key access", () => { + util.testModule` + /** @noSelf */ + declare class TestClass { + static [key: string]: () => void; + static myMethod(): void; + } + + TestClass.myMethod(); + TestClass.myKey(); + `.expectLuaToMatchSnapshot(); +}); + // additional coverage for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1292 test("explicit this parameter respected over @noSelf", () => { util.testModule` From bd799f436180426f1529184c99a6e43ab17fef93 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 12 Jul 2025 16:42:52 +0200 Subject: [PATCH 713/764] fix issue with unicode classnames and static initializer blocks (#1649) --- src/transformation/visitors/class/index.ts | 4 ++-- test/unit/__snapshots__/identifiers.spec.ts.snap | 15 +++++++++++++++ test/unit/identifiers.spec.ts | 11 +++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index d4633995e..b01617171 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -202,7 +202,7 @@ function transformClassLikeDeclaration( const iif = lua.createFunctionExpression(lua.createBlock(bodyStatements), [ lua.createIdentifier("self"), ]); - const iife = lua.createCallExpression(iif, [className]); + const iife = lua.createCallExpression(iif, [localClassName]); result.push(lua.createExpressionStatement(iife, member)); } } @@ -217,7 +217,7 @@ function transformClassLikeDeclaration( if (shouldBeExported(classDeclaration)) { const exportExpression = hasDefaultExportModifier(classDeclaration) ? createDefaultExportExpression(classDeclaration) - : createExportedIdentifier(context, className); + : createExportedIdentifier(context, localClassName); const classAssignment = lua.createAssignmentStatement(exportExpression, localClassName); result.push(classAssignment); diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index 4a8ddc751..b90b10398 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -427,3 +427,18 @@ function ____exports.__main(self) end return ____exports" `; + +exports[`unicode static initialization block (#1645) 1`] = ` +"local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local ____exports = {} +____exports.default = __TS__Class() +local _____81EA_5B9A_4E49_5F02_80FD = ____exports.default +_____81EA_5B9A_4E49_5F02_80FD.name = "自定义异能" +function _____81EA_5B9A_4E49_5F02_80FD.prototype.____constructor(self) +end; +(function(self) + local a = 1 +end)(_____81EA_5B9A_4E49_5F02_80FD) +return ____exports" +`; diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 4ef550c4e..4156e83ff 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -317,6 +317,17 @@ test("unicode export default class", () => { .expectToEqual({ result: "你好" }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1645 +test("unicode static initialization block (#1645)", () => { + util.testModule` + export default class 自定义异能 { + static { + let a = 1; + } + } + `.expectLuaToMatchSnapshot(); +}); + describe("lua keyword as identifier doesn't interfere with lua's value", () => { test("variable (nil)", () => { util.testFunction` From d541c9b44a05c59ad63481f5cffa77a1e685e8a7 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 12 Jul 2025 21:59:07 +0200 Subject: [PATCH 714/764] 1.31.3 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b2fdb24d8..af8f3323b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.31.2", + "version": "1.31.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.31.2", + "version": "1.31.3", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 3a1e7efe8..0a97056e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.31.2", + "version": "1.31.3", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 102a00a8b0989b9037f20b95b1d274bd6362f2a1 Mon Sep 17 00:00:00 2001 From: aabajyan <62068860+aabajyan@users.noreply.github.com> Date: Thu, 17 Jul 2025 22:39:26 +0400 Subject: [PATCH 715/764] fix: only parse arguments from first line of tag comment (#1650) --- src/transformation/utils/annotations.ts | 3 ++- .../__snapshots__/transformation.spec.ts.snap | 2 ++ .../transformation/customNameWithExtraComment.ts | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/translation/transformation/customNameWithExtraComment.ts diff --git a/src/transformation/utils/annotations.ts b/src/transformation/utils/annotations.ts index 91ef6d531..b66704c97 100644 --- a/src/transformation/utils/annotations.ts +++ b/src/transformation/utils/annotations.ts @@ -105,7 +105,8 @@ export function getFileAnnotations(sourceFile: ts.SourceFile): AnnotationsMap { function getTagArgsFromComment(tag: ts.JSDocTag): string[] { if (tag.comment) { if (typeof tag.comment === "string") { - return tag.comment.split(" "); + const firstLine = tag.comment.split("\n")[0]; + return firstLine.trim().split(" "); } else { return tag.comment.map(part => part.text); } diff --git a/test/translation/__snapshots__/transformation.spec.ts.snap b/test/translation/__snapshots__/transformation.spec.ts.snap index 6753c66b1..e9fccb4ae 100644 --- a/test/translation/__snapshots__/transformation.spec.ts.snap +++ b/test/translation/__snapshots__/transformation.spec.ts.snap @@ -36,6 +36,8 @@ escapedCharsInTemplateString = "\\\\ \\0 \\b \\t \\n \\v \\f \\" ' \`" nonEmptyTemplateString = ("Level 0: \\n\\t " .. ("Level 1: \\n\\t\\t " .. ("Level 3: \\n\\t\\t\\t " .. "Last level \\n --") .. " \\n --") .. " \\n --") .. " \\n --"" `; +exports[`Transformation (customNameWithExtraComment) 1`] = `"TestNamespace.pass()"`; + exports[`Transformation (customNameWithNoSelf) 1`] = `"TestNamespace.pass()"`; exports[`Transformation (exportStatement) 1`] = ` diff --git a/test/translation/transformation/customNameWithExtraComment.ts b/test/translation/transformation/customNameWithExtraComment.ts new file mode 100644 index 000000000..459512ded --- /dev/null +++ b/test/translation/transformation/customNameWithExtraComment.ts @@ -0,0 +1,10 @@ +/** @noSelf */ +declare namespace TestNamespace { + /** + * @customName pass + * The first word should not be included. + **/ + function fail(): void; +} + +TestNamespace.fail(); From 8a43f43337eca0eadaca9849f89ff36605ca6e02 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 17 Jul 2025 20:46:55 +0200 Subject: [PATCH 716/764] 1.31.4 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index af8f3323b..cdb77ea17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.31.3", + "version": "1.31.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.31.3", + "version": "1.31.4", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 0a97056e1..683c7e538 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.31.3", + "version": "1.31.4", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 5acd109e6769a8d6160badcb63112b1fab6233c9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 23 Aug 2025 20:21:31 +0200 Subject: [PATCH 717/764] Limit unpack call in destructuring assignments to only required elements (#1655) --- src/transformation/utils/lua-ast.ts | 29 +++++++++++++++++++ .../visitors/binary-expression/assignments.ts | 4 +-- .../visitors/variable-declaration.ts | 7 +++-- test/unit/destructuring.spec.ts | 11 +++++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/transformation/utils/lua-ast.ts b/src/transformation/utils/lua-ast.ts index b947e0bf6..59f6cffd7 100644 --- a/src/transformation/utils/lua-ast.ts +++ b/src/transformation/utils/lua-ast.ts @@ -81,6 +81,35 @@ export function createUnpackCall( return lua.setNodeFlags(lua.createCallExpression(unpack, [expression], tsOriginal), lua.NodeFlags.TableUnpackCall); } +export function createBoundedUnpackCall( + context: TransformationContext, + expression: lua.Expression, + maxUnpackItem: number, + tsOriginal?: ts.Node +): lua.Expression { + if (context.luaTarget === LuaTarget.Universal) { + return transformLuaLibFunction(context, LuaLibFeature.Unpack, tsOriginal, expression); + } + + // Lua 5.0 does not support this signature, so don't add the arguments there + const extraArgs = + context.luaTarget === LuaTarget.Lua50 + ? [] + : [lua.createNumericLiteral(1), lua.createNumericLiteral(maxUnpackItem)]; + + const unpack = + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.LuaJIT + ? lua.createIdentifier("unpack") + : lua.createTableIndexExpression(lua.createIdentifier("table"), lua.createStringLiteral("unpack")); + + return lua.setNodeFlags( + lua.createCallExpression(unpack, [expression, ...extraArgs], tsOriginal), + lua.NodeFlags.TableUnpackCall + ); +} + export function isUnpackCall(node: lua.Node): boolean { return lua.isCallExpression(node) && (node.flags & lua.NodeFlags.TableUnpackCall) !== 0; } diff --git a/src/transformation/visitors/binary-expression/assignments.ts b/src/transformation/visitors/binary-expression/assignments.ts index 3e246c3f8..73e6d9dd1 100644 --- a/src/transformation/visitors/binary-expression/assignments.ts +++ b/src/transformation/visitors/binary-expression/assignments.ts @@ -4,7 +4,7 @@ import * as lua from "../../../LuaAST"; import { TransformationContext } from "../../context"; import { validateAssignment } from "../../utils/assignment-validation"; import { createExportedIdentifier, getDependenciesOfSymbol, isSymbolExported } from "../../utils/export"; -import { createUnpackCall, wrapInTable } from "../../utils/lua-ast"; +import { createBoundedUnpackCall, wrapInTable } from "../../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../../utils/lualib"; import { isArrayType, isDestructuringAssignment } from "../../utils/typescript"; import { isArrayLength, transformDestructuringAssignment } from "./destructuring-assignments"; @@ -252,7 +252,7 @@ export function transformAssignmentStatement( } else { right = context.transformExpression(expression.right); if (!isMultiReturnCall(context, expression.right) && isArrayType(context, rightType)) { - right = createUnpackCall(context, right, expression.right); + right = createBoundedUnpackCall(context, right, expression.left.elements.length, expression.right); } } diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 082ef9a6b..f15ed0115 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -5,7 +5,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { validateAssignment } from "../utils/assignment-validation"; import { unsupportedVarDeclaration } from "../utils/diagnostics"; import { addExportToIdentifier } from "../utils/export"; -import { createLocalOrExportedOrGlobalDeclaration, createUnpackCall, wrapInTable } from "../utils/lua-ast"; +import { createBoundedUnpackCall, createLocalOrExportedOrGlobalDeclaration, wrapInTable } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { createCallableTable, isFunctionTypeWithProperties } from "./function"; @@ -209,10 +209,11 @@ export function transformBindingVariableDeclaration( : lua.createNilLiteral(); statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, values, initializer)); } else { - // local vars = this.transpileDestructingAssignmentValue(node.initializer); - const unpackedInitializer = createUnpackCall( + // use unpack(thing, 1, #bindingItems) to unpack + const unpackedInitializer = createBoundedUnpackCall( context, context.transformExpression(initializer), + bindingPattern.elements.length, initializer ); statements.push( diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 80d3d482c..65ecf95a3 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -195,6 +195,17 @@ describe("array destructuring optimization", () => { .expectToMatchJsResult(); }); + util.testEachVersion( + "array versions", + () => + util.testFunction` + const array = [3, 5, 1]; + const [a, b, c] = array; + return { a, b, c }; + `, + util.expectEachVersionExceptJit(builder => builder.expectToMatchJsResult()) + ); + test("array literal", () => { util.testFunction` const [a, b, c] = [3, 5, 1]; From 2dc28fb7d358e705fe48aab9b7f11601bbefbf3b Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 23 Aug 2025 20:21:45 +0200 Subject: [PATCH 718/764] fix broken customName interaction with import statements (#1654) --- src/transformation/visitors/access.ts | 2 +- src/transformation/visitors/call.ts | 2 +- src/transformation/visitors/identifier.ts | 16 ++++- src/transformation/visitors/modules/import.ts | 11 +++- test/unit/identifiers.spec.ts | 64 +++++++++++++++++++ 5 files changed, 89 insertions(+), 6 deletions(-) diff --git a/src/transformation/visitors/access.ts b/src/transformation/visitors/access.ts index c97c0f4c7..7c96bdcd8 100644 --- a/src/transformation/visitors/access.ts +++ b/src/transformation/visitors/access.ts @@ -115,7 +115,7 @@ export function transformPropertyAccessExpressionWithCapture( let property = node.name.text; const symbol = context.checker.getSymbolAtLocation(node.name); - const customName = getCustomNameFromSymbol(symbol); + const customName = getCustomNameFromSymbol(context, symbol); if (customName) { property = customName; } diff --git a/src/transformation/visitors/call.ts b/src/transformation/visitors/call.ts index d37561910..c4a74135c 100644 --- a/src/transformation/visitors/call.ts +++ b/src/transformation/visitors/call.ts @@ -138,7 +138,7 @@ export function transformContextualCallExpression( let name = left.name.text; const symbol = context.checker.getSymbolAtLocation(left); - const customName = getCustomNameFromSymbol(symbol); + const customName = getCustomNameFromSymbol(context, symbol); if (customName) { name = customName; diff --git a/src/transformation/visitors/identifier.ts b/src/transformation/visitors/identifier.ts index e5dd90e01..3b2e016e4 100644 --- a/src/transformation/visitors/identifier.ts +++ b/src/transformation/visitors/identifier.ts @@ -18,7 +18,7 @@ export function transformIdentifier(context: TransformationContext, identifier: return transformNonValueIdentifier(context, identifier, context.checker.getSymbolAtLocation(identifier)); } -export function getCustomNameFromSymbol(symbol?: ts.Symbol): undefined | string { +export function getCustomNameFromSymbol(context: TransformationContext, symbol?: ts.Symbol): undefined | string { let retVal: undefined | string; if (symbol) { @@ -33,6 +33,18 @@ export function getCustomNameFromSymbol(symbol?: ts.Symbol): undefined | string customNameAnnotation = foundAnnotation; break; } + + // If the symbol is an imported value, check the original declaration + // beware of declaration.propertyName, this is the import name alias and should not be renamed! + if (ts.isImportSpecifier(declaration) && !declaration.propertyName) { + const importedType = context.checker.getTypeAtLocation(declaration); + if (importedType.symbol) { + const importedCustomName = getCustomNameFromSymbol(context, importedType.symbol); + if (importedCustomName) { + return importedCustomName; + } + } + } } if (customNameAnnotation) { @@ -82,7 +94,7 @@ function transformNonValueIdentifier( let text = hasUnsafeIdentifierName(context, identifier, symbol) ? createSafeName(identifier.text) : identifier.text; - const customName = getCustomNameFromSymbol(symbol); + const customName = getCustomNameFromSymbol(context, symbol); if (customName) text = customName; const symbolId = getIdentifierSymbolId(context, identifier, symbol); diff --git a/src/transformation/visitors/modules/import.ts b/src/transformation/visitors/modules/import.ts index b3a1d74a2..1b561f0fa 100644 --- a/src/transformation/visitors/modules/import.ts +++ b/src/transformation/visitors/modules/import.ts @@ -9,7 +9,7 @@ import { createHoistableVariableDeclarationStatement } from "../../utils/lua-ast import { importLuaLibFeature, LuaLibFeature } from "../../utils/lualib"; import { createSafeName } from "../../utils/safe-names"; import { peekScope } from "../../utils/scope"; -import { transformIdentifier } from "../identifier"; +import { getCustomNameFromSymbol, transformIdentifier } from "../identifier"; import { transformPropertyName } from "../literal"; function isNoResolutionPath(context: TransformationContext, moduleSpecifier: ts.Expression): boolean { @@ -46,8 +46,15 @@ function transformImportSpecifier( importSpecifier: ts.ImportSpecifier, moduleTableName: lua.Identifier ): lua.VariableDeclarationStatement { + const type = context.checker.getTypeAtLocation(importSpecifier.name); + const leftIdentifier = transformIdentifier(context, importSpecifier.name); - const propertyName = transformPropertyName(context, importSpecifier.propertyName ?? importSpecifier.name); + + // If imported value has a customName annotation use that, otherwise use regular property + const customName = getCustomNameFromSymbol(context, type.getSymbol()); + const propertyName = customName + ? lua.createStringLiteral(customName, importSpecifier.propertyName ?? importSpecifier.name) + : transformPropertyName(context, importSpecifier.propertyName ?? importSpecifier.name); return lua.createVariableDeclarationStatement( leftIdentifier, diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index 4156e83ff..f148c3c72 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -991,3 +991,67 @@ test("customName rename declared function", () => { expect(mainFile.lua).toContain("Test2("); expect(mainFile.lua).not.toContain("Test("); }); + +test("customName rename import specifier", () => { + const testModule = util.testModule` + import { Test } from "./myimport"; + import { Test as Aliased } from "./myimport"; + Test(); + Aliased(); + `.addExtraFile( + "myimport.ts", + ` + /** @customName Test2 **/ + export function Test(this: void): void {} + ` + ); + + testModule.expectToHaveNoDiagnostics(); + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2("); + expect(mainFile.lua).toContain("myimport.Test2"); + expect(mainFile.lua).not.toContain("Test("); + + testModule.expectNoExecutionError(); +}); + +test("customName import specifier from declarations", () => { + const testModule = util.testModule` + import { Test } from "./myimport"; + import { Test as Aliased } from "./myimport"; + Test(); + Aliased(); + ` + .addExtraFile( + "myimport.d.ts", + ` + /** @customName Test2 **/ + export declare function Test(this: void): void; + ` + ) + .setOptions({ noResolvePaths: ["./myimport"] }); + + testModule.expectToHaveNoDiagnostics(); + const result = testModule.getLuaResult(); + expect(result.transpiledFiles).not.toHaveLength(0); + + const mainFile = result.transpiledFiles.find(f => f.outPath === "main.lua"); + expect(mainFile).toBeDefined(); + + // avoid ts error "not defined", even though toBeDefined is being checked above + if (!mainFile) return; + + expect(mainFile.lua).toBeDefined(); + expect(mainFile.lua).toContain("Test2("); + expect(mainFile.lua).toContain("myimport.Test2"); + expect(mainFile.lua).not.toContain("Test("); +}); From 18165f0f1b39daa06b206a313ced79ef45061e90 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 23 Aug 2025 20:52:48 +0200 Subject: [PATCH 719/764] CHANGELOG.md 1.32.0 --- CHANGELOG.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b96eb944c..7f8b3a9b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog +## 1.32.0 + +- Fixed a broken `@customName` interation with import statements +- Use `(table.)unpack(expression, from, to)` when using array destructing syntax `const [a,b] = array;` to avoid having to unpack the entire array +- Fixed compiler annotations also considering the next line as part of any possible arguments +- Fixed a bug with unicode classnames not being properly escaped in static initializer blocks +- Fixed a bug where `@noSelf` still was not respected for index signature methods +- Fixed a case where loop variables were incorrectly missing `local` +- Removed dead code that was sometimes generated using `continue` in a loop +- Fixed a bug with tagged template literals when the tag is a function call +- Fixed a bug with class decorators leading to invalid Lua code being generated +- A `-` or `+` prefix now converts expressions to numbers with `Number()` +- Fixed a bug with root level `using` statements not properly disposing objects + ## 1.31.0 - Upgraded TypeScript to 5.8.2 From 1ed3b4d5f9968e821d10c9e6742c3b1025561495 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 23 Aug 2025 20:55:13 +0200 Subject: [PATCH 720/764] 1.32.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdb77ea17..f46aa4c3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.31.4", + "version": "1.32.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.31.4", + "version": "1.32.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 683c7e538..6fb362d2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.31.4", + "version": "1.32.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 9e37de60af8d467a518d2fc097e1b09e46d10542 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sun, 9 Nov 2025 20:40:34 +0100 Subject: [PATCH 721/764] update TypeScript to 5.9.3 (#1669) --- package-lock.json | 569 +++++++++--------- package.json | 6 +- src/lualib/SourceMapTraceBack.ts | 1 - src/lualib/StringSplit.ts | 4 +- src/transformation/utils/scope.ts | 9 +- src/transformation/visitors/class/index.ts | 6 +- src/transformation/visitors/enum.ts | 4 +- src/transformation/visitors/function.ts | 4 +- src/transformation/visitors/modules/import.ts | 4 +- 9 files changed, 304 insertions(+), 303 deletions(-) diff --git a/package-lock.json b/package-lock.json index f46aa4c3e..4065b470f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,14 +36,14 @@ "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "^5.8.2", - "typescript-eslint": "^8.26.0" + "typescript": "5.9.3", + "typescript-eslint": "^8.46.3" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "^5.8.2" + "typescript": "5.9.3" } }, "node_modules/@ampproject/remapping": { @@ -61,14 +61,15 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" @@ -90,6 +91,7 @@ "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -226,9 +228,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", "engines": { @@ -236,9 +238,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -256,121 +258,27 @@ } }, "node_modules/@babel/helpers": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.6.tgz", - "integrity": "sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.0", - "@babel/types": "^7.25.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@babel/parser": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.6.tgz", - "integrity": "sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.25.6" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -619,15 +527,15 @@ } }, "node_modules/@babel/template": { - "version": "7.25.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.0.tgz", - "integrity": "sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==", + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.25.0", - "@babel/types": "^7.25.0" + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -663,15 +571,14 @@ } }, "node_modules/@babel/types": { - "version": "7.25.6", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.6.tgz", - "integrity": "sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -709,17 +616,20 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.3" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, + "funding": { + "url": "https://opencollective.com/eslint" + }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } @@ -747,12 +657,13 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz", - "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==", + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" }, @@ -761,19 +672,24 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz", - "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz", - "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@types/json-schema": "^7.0.15" }, @@ -782,10 +698,11 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz", - "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", + "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", "dev": true, + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -805,30 +722,36 @@ } }, "node_modules/@eslint/js": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz", - "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/plugin-kit": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz", - "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.12.0", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { @@ -1399,6 +1322,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1412,6 +1336,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -1421,6 +1346,7 @@ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1622,6 +1548,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -1675,20 +1602,22 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.0.tgz", - "integrity": "sha512-cLr1J6pe56zjKYajK6SSSre6nl1Gj6xDp1TY0trpgPzjVbgDwd09v2Ws37LABxzkicmUjhEeg/fAUjPJJB1v5Q==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz", + "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/type-utils": "8.26.0", - "@typescript-eslint/utils": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/type-utils": "8.46.3", + "@typescript-eslint/utils": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1698,21 +1627,33 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "@typescript-eslint/parser": "^8.46.3", "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.0.tgz", - "integrity": "sha512-mNtXP9LTVBy14ZF3o7JG69gRPBK/2QWtQd0j0oH26HcY/foyJJau6pNUez7QrM5UHnSvwlQcJXKsk0I99B9pOA==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", + "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/typescript-estree": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4" }, "engines": { @@ -1724,36 +1665,78 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.0.tgz", - "integrity": "sha512-E0ntLvsfPqnPwng8b8y4OGuzh/iIOm2z8U3S9zic2TeMLW61u5IH2Q1wu0oSTkfrSzwbDJIB/Lm8O3//8BWMPA==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0" + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", + "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.0.tgz", - "integrity": "sha512-ruk0RNChLKz3zKGn2LwXuVoeBcUMh+jaqzN461uMMdxy5H9epZqIBtYj7UiPXRuOpaALXGbmRuZQhmwHhaS04Q==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.3.tgz", + "integrity": "sha512-ZPCADbr+qfz3aiTTYNNkCbUt+cjNwI/5McyANNrFBpVxPt7GqpEYz5ZfdwuFyGUnJ9FdDXbGODUu6iRCI6XRXw==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.26.0", - "@typescript-eslint/utils": "8.26.0", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/utils": "8.46.3", "debug": "^4.3.4", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1764,14 +1747,15 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.0.tgz", - "integrity": "sha512-89B1eP3tnpr9A8L6PZlSjBvnJhWXtYfZhECqlBl1D9Lme9mHO6iWlsprBtVenQvY1HMhax1mWOjhtL3fh/u+pA==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", + "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -1781,19 +1765,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.0.tgz", - "integrity": "sha512-tiJ1Hvy/V/oMVRTbEOIeemA2XoylimlDQ03CgPPNaHYZbpsc78Hmngnt+WXZfJX1pjQ711V7g0H7cSJThGYfPQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", + "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/visitor-keys": "8.26.0", + "@typescript-eslint/project-service": "8.46.3", + "@typescript-eslint/tsconfig-utils": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.1" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1803,14 +1790,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -1820,6 +1808,7 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1831,15 +1820,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.0.tgz", - "integrity": "sha512-2L2tU3FVwhvU14LndnQCA2frYC8JnPDVKyQtWFPf8IYFMt/ykEN1bPolNhNbCVgOmdzTlWdusCTKA/9nKrf8Ig==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.3.tgz", + "integrity": "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==", "dev": true, + "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.26.0", - "@typescript-eslint/types": "8.26.0", - "@typescript-eslint/typescript-estree": "8.26.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1850,17 +1840,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.0.tgz", - "integrity": "sha512-2z8JQJWAzPdDd51dRQ/oqIJxe99/hoLIqmf8RMCAJQtYDc535W/Jt2+RTP4bP0aKeBG1F65yjIZuczOXCmbWwg==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", + "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.26.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.46.3", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1877,10 +1868,12 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", - "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, + "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1893,6 +1886,7 @@ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", "dev": true, + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -1915,6 +1909,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1993,7 +1988,8 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "dev": true, + "license": "Python-2.0" }, "node_modules/async": { "version": "3.2.6", @@ -2136,9 +2132,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -2179,6 +2175,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001646", "electron-to-chromium": "^1.5.4", @@ -2593,32 +2590,33 @@ } }, "node_modules/eslint": { - "version": "9.22.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz", - "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==", + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, + "license": "MIT", + "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.19.2", - "@eslint/config-helpers": "^0.1.0", - "@eslint/core": "^0.12.0", - "@eslint/eslintrc": "^3.3.0", - "@eslint/js": "9.22.0", - "@eslint/plugin-kit": "^0.2.7", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.3.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -2679,10 +2677,11 @@ } }, "node_modules/eslint-scope": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz", - "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -2695,10 +2694,11 @@ } }, "node_modules/eslint-visitor-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", - "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, + "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, @@ -2707,14 +2707,15 @@ } }, "node_modules/espree": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz", - "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.14.0", + "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.0" + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2755,6 +2756,7 @@ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -2913,13 +2915,15 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -2936,6 +2940,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -2962,6 +2967,7 @@ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", "dev": true, + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3000,9 +3006,9 @@ } }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -3202,6 +3208,7 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18" }, @@ -3276,6 +3283,7 @@ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3544,6 +3552,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4481,6 +4490,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -4519,7 +4529,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -4705,6 +4716,7 @@ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 8" } @@ -4888,6 +4900,7 @@ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, + "license": "MIT", "dependencies": { "callsites": "^3.0.0" }, @@ -4951,9 +4964,9 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, @@ -5121,6 +5134,7 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5160,7 +5174,8 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, "node_modules/react-is": { "version": "17.0.2", @@ -5224,6 +5239,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -5243,6 +5259,7 @@ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, + "license": "MIT", "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -5267,6 +5284,7 @@ "url": "https://feross.org/support" } ], + "license": "MIT", "dependencies": { "queue-microtask": "^1.2.2" } @@ -5522,16 +5540,6 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -5546,10 +5554,11 @@ } }, "node_modules/ts-api-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz", - "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=18.12" }, @@ -5610,6 +5619,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5685,10 +5695,12 @@ } }, "node_modules/typescript": { - "version": "5.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", - "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, + "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5698,14 +5710,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.0.tgz", - "integrity": "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.3.tgz", + "integrity": "sha512-bAfgMavTuGo+8n6/QQDVQz4tZ4f7Soqg53RbrlZQEoAltYop/XR4RAts/I0BrO3TTClTSTFJ0wYbla+P8cEWJA==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.26.0", - "@typescript-eslint/parser": "8.26.0", - "@typescript-eslint/utils": "8.26.0" + "@typescript-eslint/eslint-plugin": "8.46.3", + "@typescript-eslint/parser": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/utils": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5716,7 +5730,7 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/undici-types": { @@ -5771,6 +5785,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } diff --git a/package.json b/package.json index 6fb362d2d..08587fa86 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.8.2" + "typescript": "5.9.3" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -69,7 +69,7 @@ "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", - "typescript": "5.8.2", - "typescript-eslint": "^8.26.0" + "typescript": "5.9.3", + "typescript-eslint": "^8.46.3" } } diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index 47c2c8739..fe59a0f05 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -9,7 +9,6 @@ interface SourceMap { declare global { function __TS__originalTraceback(this: void, thread?: LuaThread, message?: string, level?: number): void; - // eslint-disable-next-line no-var var __TS__sourcemap: Record; } diff --git a/src/lualib/StringSplit.ts b/src/lualib/StringSplit.ts index 1d2dd6610..f89ffb57d 100644 --- a/src/lualib/StringSplit.ts +++ b/src/lualib/StringSplit.ts @@ -1,9 +1,7 @@ const sub = string.sub; const find = string.find; export function __TS__StringSplit(this: void, source: string, separator?: string, limit?: number): string[] { - if (limit === undefined) { - limit = 4294967295; - } + limit ??= 4294967295; if (limit === 0) { return []; diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 2b0351e4f..187504caf 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -60,9 +60,7 @@ export function markSymbolAsReferencedInCurrentScopes( identifier: ts.Identifier ): void { for (const scope of context.scopeStack) { - if (!scope.referencedSymbols) { - scope.referencedSymbols = new Map(); - } + scope.referencedSymbols ??= new Map(); const references = getOrUpdate(scope.referencedSymbols, symbolId, () => []); references.push(identifier); @@ -87,9 +85,8 @@ export function findScope(context: TransformationContext, scopeTypes: ScopeType) } export function addScopeVariableDeclaration(scope: Scope, declaration: lua.VariableDeclarationStatement) { - if (!scope.variableDeclarations) { - scope.variableDeclarations = []; - } + scope.variableDeclarations ??= []; + scope.variableDeclarations.push(declaration); } diff --git a/src/transformation/visitors/class/index.ts b/src/transformation/visitors/class/index.ts index b01617171..f2024babe 100644 --- a/src/transformation/visitors/class/index.ts +++ b/src/transformation/visitors/class/index.ts @@ -272,10 +272,8 @@ export const transformSuperExpression: FunctionVisitor = (ex } } - if (!baseClassName) { - // Use "className.____super" if the base is not a simple identifier - baseClassName = lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression); - } + // Use "className.____super" if the base is not a simple identifier + baseClassName ??= lua.createTableIndexExpression(className, lua.createStringLiteral("____super"), expression); const f = findFirstNodeAbove(expression, ts.isFunctionLike); if (f && ts.canHaveModifiers(f) && isStaticNode(f)) { diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index 918e685f6..3c496344e 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -60,9 +60,7 @@ export const transformEnumDeclaration: FunctionVisitor = (no } } - if (!valueExpression) { - valueExpression = context.transformExpression(member.initializer); - } + valueExpression ??= context.transformExpression(member.initializer); } else { valueExpression = lua.createNilLiteral(); } diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 506d4a6f1..5d39f8570 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -343,9 +343,7 @@ export const transformFunctionDeclaration: FunctionVisitor = (statement, context) => { const scope = peekScope(context); - if (!scope.importStatements) { - scope.importStatements = []; - } + scope.importStatements ??= []; const result: lua.Statement[] = []; const requireCall = createModuleRequire(context, statement.moduleSpecifier); From a6708e5844d3d3c0024a3fe1fdaf18f161ca3e09 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 9 Nov 2025 20:42:37 +0100 Subject: [PATCH 722/764] CHANGELOG.md 1.33.0 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f8b3a9b8..235cdc2c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.33.0 + +- Upgraded TypeScript to 5.9.3 + ## 1.32.0 - Fixed a broken `@customName` interation with import statements From bd00c15acf511ce4a4f59d39d15e250133e85f1b Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 9 Nov 2025 20:43:29 +0100 Subject: [PATCH 723/764] 1.33.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4065b470f..c731bfd48 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.32.0", + "version": "1.33.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.32.0", + "version": "1.33.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 08587fa86..ad0e29590 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.32.0", + "version": "1.33.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From a6230a75ed303214d3f8c1143c21c4f1be196ea9 Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Sat, 27 Dec 2025 11:47:12 +0100 Subject: [PATCH 724/764] Fix constructor scope breaking vararg spread optimization (#1675) * Fix constructor scope breaking vararg spread optimization * remove test debug * fix typo in test name --- package-lock.json | 12 ++++++------ src/transformation/context/context.ts | 4 ++-- src/transformation/utils/scope.ts | 8 ++------ src/transformation/visitors/block.ts | 4 ++-- .../visitors/class/members/accessors.ts | 2 +- .../visitors/class/members/constructor.ts | 2 +- src/transformation/visitors/conditional.ts | 4 ++-- src/transformation/visitors/function.ts | 11 +++++------ src/transformation/visitors/loops/for.ts | 2 +- src/transformation/visitors/loops/utils.ts | 4 ++-- src/transformation/visitors/namespace.ts | 2 +- src/transformation/visitors/sourceFile.ts | 2 +- src/transformation/visitors/spread.ts | 10 ++-------- src/transformation/visitors/switch.ts | 2 +- test/unit/classes/classes.spec.ts | 12 ++++++++++++ 15 files changed, 41 insertions(+), 40 deletions(-) diff --git a/package-lock.json b/package-lock.json index c731bfd48..f5ccdeac5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -862,9 +862,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -4486,9 +4486,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/src/transformation/context/context.ts b/src/transformation/context/context.ts index 79e385b2b..ad40d48c5 100644 --- a/src/transformation/context/context.ts +++ b/src/transformation/context/context.ts @@ -247,8 +247,8 @@ export class TransformationContext { public readonly scopeStack: Scope[] = []; private lastScopeId = 0; - public pushScope(type: ScopeType): Scope { - const scope = { type, id: ++this.lastScopeId }; + public pushScope(type: ScopeType, node: ts.Node): Scope { + const scope: Scope = { type, id: ++this.lastScopeId, node }; this.scopeStack.push(scope); return scope; } diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index 187504caf..fa66ee3e2 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -31,7 +31,7 @@ export enum LoopContinued { export interface Scope { type: ScopeType; id: number; - node?: ts.Node; + node: ts.Node; referencedSymbols?: Map; variableDeclarations?: lua.VariableDeclarationStatement[]; functionDefinitions?: Map; @@ -99,7 +99,7 @@ function isHoistableFunctionDeclaredInScope(symbol: ts.Symbol, scopeNode: ts.Nod // Checks for references to local functions which haven't been defined yet, // and thus will be hoisted above the current position. export function hasReferencedUndefinedLocalFunction(context: TransformationContext, scope: Scope) { - if (!scope.referencedSymbols || !scope.node) { + if (!scope.referencedSymbols) { return false; } for (const [symbolId, nodes] of scope.referencedSymbols) { @@ -127,10 +127,6 @@ export function hasReferencedSymbol(context: TransformationContext, scope: Scope return false; } -export function isFunctionScopeWithDefinition(scope: Scope): scope is Scope & { node: ts.SignatureDeclaration } { - return scope.node !== undefined && ts.isFunctionLike(scope.node); -} - export function separateHoistedStatements(context: TransformationContext, statements: lua.Statement[]): HoistingResult { const scope = peekScope(context); const allHoistedStatments: lua.Statement[] = []; diff --git a/src/transformation/visitors/block.ts b/src/transformation/visitors/block.ts index c0a2ad3a8..4eef4b6f8 100644 --- a/src/transformation/visitors/block.ts +++ b/src/transformation/visitors/block.ts @@ -12,14 +12,14 @@ export function transformScopeBlock( node: ts.Block, scopeType: ScopeType ): [lua.Block, Scope] { - context.pushScope(scopeType); + context.pushScope(scopeType, node); const statements = performHoisting(context, context.transformStatements(node.statements)); const scope = context.popScope(); return [lua.createBlock(statements, node), scope]; } export const transformBlock: FunctionVisitor = (node, context) => { - context.pushScope(ScopeType.Block); + context.pushScope(ScopeType.Block, node); const statements = performHoisting(context, context.transformStatements(node.statements)); context.popScope(); return lua.createDoStatement(statements, node); diff --git a/src/transformation/visitors/class/members/accessors.ts b/src/transformation/visitors/class/members/accessors.ts index 165d3fa88..017100056 100644 --- a/src/transformation/visitors/class/members/accessors.ts +++ b/src/transformation/visitors/class/members/accessors.ts @@ -15,7 +15,7 @@ function transformAccessor( className: lua.Identifier ): lua.Expression { const [params, dot, restParam] = transformParameters(context, node.parameters, createSelfIdentifier()); - const body = node.body ? transformFunctionBody(context, node.parameters, node.body, restParam)[0] : []; + const body = node.body ? transformFunctionBody(context, node.parameters, node.body, node, restParam)[0] : []; const accessorFunction = lua.createFunctionExpression( lua.createBlock(body), params, diff --git a/src/transformation/visitors/class/members/constructor.ts b/src/transformation/visitors/class/members/constructor.ts index 039e705f7..8bff2f4fc 100644 --- a/src/transformation/visitors/class/members/constructor.ts +++ b/src/transformation/visitors/class/members/constructor.ts @@ -28,7 +28,7 @@ export function transformConstructorDeclaration( } // Transform body - const scope = context.pushScope(ScopeType.Function); + const scope = context.pushScope(ScopeType.Function, statement); const body = transformFunctionBodyContent(context, statement.body); const [params, dotsLiteral, restParamName] = transformParameters( diff --git a/src/transformation/visitors/conditional.ts b/src/transformation/visitors/conditional.ts index b90c7e2db..6285a488d 100644 --- a/src/transformation/visitors/conditional.ts +++ b/src/transformation/visitors/conditional.ts @@ -76,7 +76,7 @@ export const transformConditionalExpression: FunctionVisitor, body: ts.ConciseBody, - spreadIdentifier?: lua.Identifier, - node?: ts.FunctionLikeDeclaration + node: ts.FunctionLikeDeclaration, + spreadIdentifier?: lua.Identifier ): [lua.Statement[], Scope] { - const scope = context.pushScope(ScopeType.Function); - scope.node = node; + const scope = context.pushScope(ScopeType.Function, node); let bodyStatements = transformFunctionBodyContent(context, body); if (node && isAsyncFunction(node)) { bodyStatements = [lua.createReturnStatement([wrapInAsyncAwaiter(context, bodyStatements)])]; @@ -258,8 +257,8 @@ export function transformFunctionToExpression( context, node.parameters, node.body, - spreadIdentifier, - node + node, + spreadIdentifier ); const functionExpression = lua.createFunctionExpression( diff --git a/src/transformation/visitors/loops/for.ts b/src/transformation/visitors/loops/for.ts index 0c272e225..5ae3bf0ea 100644 --- a/src/transformation/visitors/loops/for.ts +++ b/src/transformation/visitors/loops/for.ts @@ -9,7 +9,7 @@ import { ScopeType } from "../../utils/scope"; export const transformForStatement: FunctionVisitor = (statement, context) => { const result: lua.Statement[] = []; - context.pushScope(ScopeType.Loop); + context.pushScope(ScopeType.Loop, statement); if (statement.initializer) { if (ts.isVariableDeclarationList(statement.initializer)) { diff --git a/src/transformation/visitors/loops/utils.ts b/src/transformation/visitors/loops/utils.ts index 0997c6583..d7e4a3093 100644 --- a/src/transformation/visitors/loops/utils.ts +++ b/src/transformation/visitors/loops/utils.ts @@ -14,7 +14,7 @@ export function transformLoopBody( context: TransformationContext, loop: ts.WhileStatement | ts.DoStatement | ts.ForStatement | ts.ForOfStatement | ts.ForInOrOfStatement ): lua.Statement[] { - context.pushScope(ScopeType.Loop); + context.pushScope(ScopeType.Loop, loop); const body = performHoisting(context, transformBlockOrStatement(context, loop.statement)); const scope = context.popScope(); const scopeId = scope.id; @@ -79,7 +79,7 @@ export function transformForInitializer( ): lua.Identifier { const valueVariable = lua.createIdentifier("____value"); - context.pushScope(ScopeType.LoopInitializer); + context.pushScope(ScopeType.LoopInitializer, initializer); if (ts.isVariableDeclarationList(initializer)) { // Declaration of new variable diff --git a/src/transformation/visitors/namespace.ts b/src/transformation/visitors/namespace.ts index 743b52b62..49a3f2289 100644 --- a/src/transformation/visitors/namespace.ts +++ b/src/transformation/visitors/namespace.ts @@ -118,7 +118,7 @@ export const transformModuleDeclaration: FunctionVisitor = // Transform moduleblock to block and visit it if (moduleHasEmittedBody(node)) { - context.pushScope(ScopeType.Block); + context.pushScope(ScopeType.Block, node); const statements = performHoisting( context, context.transformStatements(ts.isModuleBlock(node.body) ? node.body.statements : node.body) diff --git a/src/transformation/visitors/sourceFile.ts b/src/transformation/visitors/sourceFile.ts index 4a0c62c6d..2fe860f53 100644 --- a/src/transformation/visitors/sourceFile.ts +++ b/src/transformation/visitors/sourceFile.ts @@ -26,7 +26,7 @@ export const transformSourceFileNode: FunctionVisitor = (node, co statements.push(lua.createExpressionStatement(errorCall)); } } else { - context.pushScope(ScopeType.File); + context.pushScope(ScopeType.File, node); statements = performHoisting(context, context.transformStatements(node.statements)); context.popScope(); diff --git a/src/transformation/visitors/spread.ts b/src/transformation/visitors/spread.ts index 9c8cb6feb..b10a0ae6e 100644 --- a/src/transformation/visitors/spread.ts +++ b/src/transformation/visitors/spread.ts @@ -6,13 +6,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { getIterableExtensionKindForNode, IterableExtensionKind } from "../utils/language-extensions"; import { createUnpackCall } from "../utils/lua-ast"; import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; -import { - findScope, - hasReferencedSymbol, - hasReferencedUndefinedLocalFunction, - isFunctionScopeWithDefinition, - ScopeType, -} from "../utils/scope"; +import { findScope, hasReferencedSymbol, hasReferencedUndefinedLocalFunction, ScopeType } from "../utils/scope"; import { findFirstNonOuterParent, isAlwaysArrayType } from "../utils/typescript"; import { isMultiReturnCall } from "./language-extensions/multi"; import { isGlobalVarargConstant } from "./language-extensions/vararg"; @@ -34,7 +28,7 @@ export function isOptimizedVarArgSpread(context: TransformationContext, symbol: } // Scope must be a function scope associated with a real ts function - if (!isFunctionScopeWithDefinition(scope)) { + if (!ts.isFunctionLike(scope.node)) { return false; } diff --git a/src/transformation/visitors/switch.ts b/src/transformation/visitors/switch.ts index 2ceaedb39..cee8b7f57 100644 --- a/src/transformation/visitors/switch.ts +++ b/src/transformation/visitors/switch.ts @@ -73,7 +73,7 @@ const coalesceCondition = ( }; export const transformSwitchStatement: FunctionVisitor = (statement, context) => { - const scope = context.pushScope(ScopeType.Switch); + const scope = context.pushScope(ScopeType.Switch, statement); // Give the switch and condition accumulator a unique name to prevent nested switches from acting up. const switchName = `____switch${scope.id}`; diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index 40eccc05a..f28c3b43d 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -909,3 +909,15 @@ test("get inherted __index member from super (DotA 2 inheritance) (#1537)", () = ) .expectToEqual("foo"); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1673 +test("vararg spread optimization in class constructor (#1673)", () => { + const lua = util.testModule` + class C { + constructor(...args: any[]) { + console.log(...args); + } + }`.getMainLuaCodeChunk(); + + expect(lua).not.toContain("table.unpack"); +}); From 171546b75f3729b4d2a9973330987c4333e467f0 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 30 Dec 2025 15:14:57 +0100 Subject: [PATCH 725/764] 1.33.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f5ccdeac5..b7c526761 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.33.0", + "version": "1.33.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.33.0", + "version": "1.33.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index ad0e29590..7af8fdaaf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.33.0", + "version": "1.33.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From bdd6f1dbfe12fe7073f7918377564a396c60821d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 30 Dec 2025 21:09:13 +0100 Subject: [PATCH 726/764] Publish to npm with trusted publishing --- .github/workflows/release.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 904eae1b0..f8146b8cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,10 @@ on: push: tags: "*" +permissions: + id-token: write + contents: read + jobs: release: name: Release @@ -11,13 +15,11 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Use Node.js 16.14.0 + - name: Use Node.js 24.12.0 uses: actions/setup-node@v1 with: - node-version: 16.14.0 + node-version: 24.12.0 registry-url: "https://registry.npmjs.org" - run: npm ci - run: npm run build - run: npm publish - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} From f15449fbc32ce5beff69c2054de62296230e1360 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 30 Dec 2025 21:11:15 +0100 Subject: [PATCH 727/764] 1.33.2 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b7c526761..0c7687fce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.33.1", + "version": "1.33.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.33.1", + "version": "1.33.2", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 7af8fdaaf..fa2670998 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.33.1", + "version": "1.33.2", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From 6fa24e863e4529131f2677b825bca25287d32dc7 Mon Sep 17 00:00:00 2001 From: Yaroslav <63865083+dnrovs@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:04:26 +0200 Subject: [PATCH 728/764] fix(bundle): prevent tail-call in entry module for proper stack trace (#1678) --- src/transpilation/bundle.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/transpilation/bundle.ts b/src/transpilation/bundle.ts index 1e0436c35..b030bddfe 100644 --- a/src/transpilation/bundle.ts +++ b/src/transpilation/bundle.ts @@ -110,7 +110,9 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t // return require("") const args = options.luaTarget === LuaTarget.Lua50 ? "unpack(arg == nil and {} or arg)" : "..."; - const entryPoint = `return require(${createModulePath(entryModuleFilePath ?? entryModule, program)}, ${args})\n`; + // Avoid producing a tail-call (which removes the bundle's stack frame) by assigning the `require` result to a local and returning it. + const entryPath = createModulePath(entryModuleFilePath ?? entryModule, program); + const entryPoint = `local ____entry = require(${entryPath}, ${args})\nreturn ____entry\n`; const footers: string[] = []; if (options.sourceMapTraceback) { From e1f5d4f911e29a0708203403cd1bbd72a8f66d94 Mon Sep 17 00:00:00 2001 From: Felix Hirt Date: Mon, 23 Feb 2026 21:45:24 +0100 Subject: [PATCH 729/764] Fix enum nested in namespace (#1682) * fix enum nested in namespace * use snapshot to test --- src/transformation/visitors/enum.ts | 4 ++-- test/unit/__snapshots__/enum.spec.ts.snap | 12 ++++++++++++ test/unit/enum.spec.ts | 11 +++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 test/unit/__snapshots__/enum.spec.ts.snap diff --git a/src/transformation/visitors/enum.ts b/src/transformation/visitors/enum.ts index 3c496344e..9de658a45 100644 --- a/src/transformation/visitors/enum.ts +++ b/src/transformation/visitors/enum.ts @@ -2,7 +2,7 @@ import * as ts from "typescript"; import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { AnnotationKind, getTypeAnnotations } from "../utils/annotations"; -import { getSymbolExportScope } from "../utils/export"; +import { addExportToIdentifier, getSymbolExportScope } from "../utils/export"; import { createLocalOrExportedOrGlobalDeclaration } from "../utils/lua-ast"; import { isFirstDeclaration } from "../utils/typescript"; import { transformIdentifier } from "./identifier"; @@ -32,7 +32,7 @@ export const transformEnumDeclaration: FunctionVisitor = (no if (!membersOnly && isFirstDeclaration(context, node)) { const name = transformIdentifier(context, node.name); const table = lua.createBinaryExpression( - lua.cloneIdentifier(name), + addExportToIdentifier(context, name), lua.createTableExpression(), lua.SyntaxKind.OrOperator ); diff --git a/test/unit/__snapshots__/enum.spec.ts.snap b/test/unit/__snapshots__/enum.spec.ts.snap new file mode 100644 index 000000000..181b66a45 --- /dev/null +++ b/test/unit/__snapshots__/enum.spec.ts.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`enum nested in namespace 1`] = ` +"A = A or ({}) +do + A.TestEnum = A.TestEnum or ({}) + A.TestEnum.B = 0 + A.TestEnum[A.TestEnum.B] = "B" + A.TestEnum.C = 1 + A.TestEnum[A.TestEnum.C] = "C" +end" +`; diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index f421be2c5..3ff4ce3fe 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -203,3 +203,14 @@ test("enum merging multiple files", () => { ) .expectToMatchJsResult(); }); + +test("enum nested in namespace", () => { + util.testModule` + namespace A { + export enum TestEnum { + B, + C + } + } + `.expectLuaToMatchSnapshot(); +}); From 8a0a85dfca508f2af9d4b3d1ee34c4ad8411abeb Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Mon, 23 Feb 2026 21:46:43 +0100 Subject: [PATCH 730/764] Add lua 5.5 target (#1680) * Add lua 5.5 target * Fix failing tests * Missed one more failing test --- package-lock.json | 14 ++-- package.json | 2 +- src/CompilerOptions.ts | 1 + src/transformation/visitors/break-continue.ts | 1 + test/cli/parse.spec.ts | 1 + .../__snapshots__/expressions.spec.ts.snap | 71 +++++++++++++++++++ test/unit/builtins/math.spec.ts | 1 + test/unit/expressions.spec.ts | 7 ++ test/unit/loops.spec.ts | 1 + test/unit/spread.spec.ts | 2 + test/util.ts | 5 +- tsconfig-schema.json | 2 +- 12 files changed, 97 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0c7687fce..cbe9690d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "jest": "^29.5.0", "jest-circus": "^29.7.0", "lua-types": "^2.13.0", - "lua-wasm-bindings": "^0.3.1", + "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", @@ -2481,9 +2481,9 @@ } }, "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", "dev": true, "license": "BSD-3-Clause", "engines": { @@ -4661,9 +4661,9 @@ "license": "MIT" }, "node_modules/lua-wasm-bindings": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.3.1.tgz", - "integrity": "sha512-QV5hqeCuBiY8NaIGgoqIXfYDNMLBJz+camshbj24N1etSC9Xl6NYYEcab2eQjoX05xhw09Apmr3C4K2V9QY+Mg==", + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/lua-wasm-bindings/-/lua-wasm-bindings-0.5.3.tgz", + "integrity": "sha512-GnGSkZmYA2VzkNV/xkwOSoxwNsqEk/EcX6uvRLKQw0pCAxCauTymRO2KmJUIrG/psV3cloaS4Cjsr39iCRkrpQ==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index fa2670998..e6a53fca5 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "jest": "^29.5.0", "jest-circus": "^29.7.0", "lua-types": "^2.13.0", - "lua-wasm-bindings": "^0.3.1", + "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", "ts-jest": "^29.2.5", "ts-node": "^10.9.2", diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 7f5562c07..47ada916e 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -67,6 +67,7 @@ export enum LuaTarget { Lua52 = "5.2", Lua53 = "5.3", Lua54 = "5.4", + Lua55 = "5.5", LuaJIT = "JIT", Luau = "Luau", } diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 87487475d..2e64a38eb 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -19,6 +19,7 @@ export const transformContinueStatement: FunctionVisitor = [LuaTarget.Lua52]: LoopContinued.WithGoto, [LuaTarget.Lua53]: LoopContinued.WithGoto, [LuaTarget.Lua54]: LoopContinued.WithGoto, + [LuaTarget.Lua55]: LoopContinued.WithGoto, [LuaTarget.LuaJIT]: LoopContinued.WithGoto, [LuaTarget.Luau]: LoopContinued.WithContinue, }[context.luaTarget]; diff --git a/test/cli/parse.spec.ts b/test/cli/parse.spec.ts index e06a8fafd..c33af1208 100644 --- a/test/cli/parse.spec.ts +++ b/test/cli/parse.spec.ts @@ -247,6 +247,7 @@ describe("tsconfig", () => { ["luaTarget", "5.2", { luaTarget: tstl.LuaTarget.Lua52 }], ["luaTarget", "5.3", { luaTarget: tstl.LuaTarget.Lua53 }], ["luaTarget", "5.4", { luaTarget: tstl.LuaTarget.Lua54 }], + ["luaTarget", "5.5", { luaTarget: tstl.LuaTarget.Lua55 }], ["luaTarget", "jit", { luaTarget: tstl.LuaTarget.LuaJIT }], ["luaTarget", "luau", { luaTarget: tstl.LuaTarget.Luau }], diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 7f41b8c0a..e2adff370 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -482,6 +482,77 @@ ____exports.__result = a | b return ____exports" `; +exports[`Bitop [5.5] ("~a") 1`] = ` +"local ____exports = {} +____exports.__result = ~a +return ____exports" +`; + +exports[`Bitop [5.5] ("a&=b") 1`] = ` +"local ____exports = {} +a = a & b +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.5] ("a&b") 1`] = ` +"local ____exports = {} +____exports.__result = a & b +return ____exports" +`; + +exports[`Bitop [5.5] ("a<<=b") 1`] = ` +"local ____exports = {} +a = a << b +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.5] ("a<>>=b") 1`] = ` +"local ____exports = {} +a = a >> b +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.5] ("a>>>b") 1`] = ` +"local ____exports = {} +____exports.__result = a >> b +return ____exports" +`; + +exports[`Bitop [5.5] ("a^=b") 1`] = ` +"local ____exports = {} +a = a ~ b +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.5] ("a^b") 1`] = ` +"local ____exports = {} +____exports.__result = a ~ b +return ____exports" +`; + +exports[`Bitop [5.5] ("a|=b") 1`] = ` +"local ____exports = {} +a = a | b +____exports.__result = a +return ____exports" +`; + +exports[`Bitop [5.5] ("a|b") 1`] = ` +"local ____exports = {} +____exports.__result = a | b +return ____exports" +`; + exports[`Bitop [JIT] ("~a") 1`] = ` "local ____exports = {} ____exports.__result = bit.bnot(a) diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index b8f6b2cc3..f3ff1f306 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -96,6 +96,7 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua55]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Luau]: builder => builder.tap(expectMathAtan2), }); diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index 46ca2f7bd..ee0eab5f4 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -96,6 +96,13 @@ test.each(supportedInAll)("Bitop [5.4] (%p)", input => { .expectLuaToMatchSnapshot(); }); +test.each(supportedInAll)("Bitop [5.5] (%p)", input => { + util.testExpression(input) + .setOptions({ luaTarget: tstl.LuaTarget.Lua55, luaLibImport: tstl.LuaLibImportKind.None }) + .disableSemanticCheck() + .expectLuaToMatchSnapshot(); +}); + test.each(unsupportedIn53And54)("Unsupported bitop 5.3 (%p)", input => { util.testExpression(input) .setOptions({ luaTarget: tstl.LuaTarget.Lua53, luaLibImport: tstl.LuaLibImportKind.None }) diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index 1591da181..b88e0dbeb 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -555,6 +555,7 @@ for (const testCase of [ [tstl.LuaTarget.Lua52]: expectContinueGotoLabel, [tstl.LuaTarget.Lua53]: expectContinueGotoLabel, [tstl.LuaTarget.Lua54]: expectContinueGotoLabel, + [tstl.LuaTarget.Lua55]: expectContinueGotoLabel, [tstl.LuaTarget.LuaJIT]: expectContinueGotoLabel, [tstl.LuaTarget.Luau]: () => expectContinueStatement, }); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 3a1add475..53898aae5 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -81,6 +81,7 @@ describe("in function call", () => { [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua55]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), } ); @@ -95,6 +96,7 @@ describe("in array literal", () => { [tstl.LuaTarget.Lua52]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Lua54]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), + [tstl.LuaTarget.Lua55]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), [tstl.LuaTarget.Luau]: builder => builder.tap(expectTableUnpack).expectToMatchJsResult(), }); diff --git a/test/util.ts b/test/util.ts index 501b24bfb..2871f6e5a 100644 --- a/test/util.ts +++ b/test/util.ts @@ -86,6 +86,7 @@ export function expectEachVersionExceptJit( [tstl.LuaTarget.Lua52]: expectation, [tstl.LuaTarget.Lua53]: expectation, [tstl.LuaTarget.Lua54]: expectation, + [tstl.LuaTarget.Lua55]: expectation, [tstl.LuaTarget.LuaJIT]: false, // Exclude JIT [tstl.LuaTarget.Luau]: false, }; @@ -157,7 +158,7 @@ export abstract class TestBuilder { } protected options: tstl.CompilerOptions = { - luaTarget: tstl.LuaTarget.Lua54, + luaTarget: tstl.LuaTarget.Lua55, noHeader: true, skipLibCheck: true, target: ts.ScriptTarget.ES2017, @@ -444,7 +445,7 @@ export abstract class TestBuilder { // Main file const mainFile = this.getMainLuaCodeChunk(); - const luaTarget = this.options.luaTarget ?? tstl.LuaTarget.Lua54; + const luaTarget = this.options.luaTarget ?? tstl.LuaTarget.Lua55; const { lauxlib, lua, lualib } = getLuaBindingsForVersion(luaTarget); const L = lauxlib.luaL_newstate(); diff --git a/tsconfig-schema.json b/tsconfig-schema.json index 87366ea76..6bffd5e46 100644 --- a/tsconfig-schema.json +++ b/tsconfig-schema.json @@ -50,7 +50,7 @@ "description": "Specifies the Lua version you want to generate code for.", "type": "string", "default": "universal", - "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "JIT", "Luau"] + "enum": ["5.0", "universal", "5.1", "5.2", "5.3", "5.4", "5.5", "JIT", "Luau"] }, "noImplicitGlobalVariables": { "description": "Always declare all root-level variables as local, even if the file is not a module and they would be global in TypeScript.", From 9bdb41d039c1c3349c0718548d2287010194b692 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2026 21:13:40 +0100 Subject: [PATCH 731/764] Bump minimatch (#1686) Bumps and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together. Updates `minimatch` from 3.1.2 to 3.1.5 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5) Updates `minimatch` from 9.0.5 to 9.0.9 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5) Updates `minimatch` from 5.1.6 to 5.1.9 - [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md) - [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.5) --- updated-dependencies: - dependency-name: minimatch dependency-version: 3.1.5 dependency-type: indirect - dependency-name: minimatch dependency-version: 9.0.9 dependency-type: indirect - dependency-name: minimatch dependency-version: 5.1.9 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/package-lock.json b/package-lock.json index cbe9690d2..0091f8103 100644 --- a/package-lock.json +++ b/package-lock.json @@ -91,7 +91,6 @@ "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -1548,7 +1547,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", "dev": true, - "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -1607,7 +1605,6 @@ "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.3", @@ -1648,7 +1645,6 @@ "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -1804,13 +1800,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -1873,7 +1869,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2175,7 +2170,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001646", "electron-to-chromium": "^1.5.4", @@ -2595,7 +2589,6 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3016,9 +3009,9 @@ } }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "dev": true, "license": "ISC", "dependencies": { @@ -3552,7 +3545,6 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4746,9 +4738,9 @@ } }, "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -5619,7 +5611,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5700,7 +5691,6 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" From a3f2eea75ac31a4622e086d18b255be77616eb5c Mon Sep 17 00:00:00 2001 From: ChouUn Date: Wed, 4 Mar 2026 04:46:49 +0800 Subject: [PATCH 732/764] fix `debug.traceback` failing on anonymous function (#1665) (#1666) * fix `debug.traceback` failing on anonymous function (#1665) * test: add regression test for anonymous function traceback mapping (#1665) Nested IIFEs produce notation in debug.traceback(). The old pattern (%S+) captured the "<" prefix, causing sourcemap lookup to fail for anonymous function definition locations. Co-Authored-By: Claude Opus 4.6 * test: address review feedback for anonymous function traceback test (#1665) Use distinct sourcemap values and explicit assertions per reviewer request. Co-Authored-By: Claude Opus 4.6 * style: extract setLuaHeader string to variable for prettier Co-Authored-By: Claude Opus 4.6 --------- Co-authored-by: Claude Opus 4.6 --- src/lualib/SourceMapTraceBack.ts | 7 ++++- test/unit/error.spec.ts | 50 ++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/lualib/SourceMapTraceBack.ts b/src/lualib/SourceMapTraceBack.ts index fe59a0f05..4597fa3dd 100644 --- a/src/lualib/SourceMapTraceBack.ts +++ b/src/lualib/SourceMapTraceBack.ts @@ -48,7 +48,12 @@ export function __TS__SourceMapTraceBack(this: void, fileName: string, sourceMap return `${file}:${line}`; }; - let [result] = string.gsub(trace, "(%S+)%.lua:(%d+)", (file, line) => + // Rewrite stack trace frames from "{PATH}.lua:{LINE}" to "{PATH}.ts:{ORIGINAL_LINE}". + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1665 + // Avoid matching anonymous function stack entries like `in function <...>` + // by excluding `<` before the file path. + // TODO: This will still fail for paths containing spaces. + let [result] = string.gsub(trace, "([^%s<]+)%.lua:(%d+)", (file, line) => replacer(`${file}.lua`, `${file}.ts`, line) ); diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 05399d492..af69d7e1d 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -345,6 +345,56 @@ test("still works without debug module", () => { }); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1665 +test("sourceMapTraceback maps anonymous function locations in .lua files (#1665)", () => { + // Nested IIFEs produce anonymous function notation in traceback. + // Old pattern (%S+)%.lua:(%d+) captures "", + // failing the sourcemap lookup. Fix: ([^%s<]+) excludes "<". + + // mapping is copied from the emitted Lua, not invented. + const mapping = `{["5"] = 1,["6"] = 2,["7"] = 3,["8"] = 4,["9"] = 3,["10"] = 2,["11"] = 1}`; + + // Test harness executes via luaL_dostring (chunk names are [string "..."]), so we mock a file-based traceback. + const fakeTraceback = [ + "stack traceback:", + "\tmain.lua:8: in function ", + "\tmain.lua:7: in function ", + "\t[C]: in ?", + ].join("\n"); + + // Inject sourcemap for "main.lua" and mock debug.traceback to return file-based frames. + const header = ` + __TS__sourcemap = { ["main.lua"] = ${mapping} }; + local __real_tb = debug.traceback + debug.traceback = function() return ${JSON.stringify(fakeTraceback)} end + `; + + const builder = util.testFunction` + return (() => { + return (() => { + return (debug.traceback as (this: void) => string)(); + })(); + })(); + ` + .setLuaHeader(header) + .setOptions({ sourceMapTraceback: true }); + + const lua = builder.getMainLuaCodeChunk(); + // Sanity check: emitted code registers the same mapping literal we inject above. + expect(lua).toContain(`__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapping});`); + + const result = builder.getLuaExecutionResult(); + expect(result).toEqual(expect.any(String)); + // Both `main.lua:N` and `` frames should be rewritten using the sourcemap. + expect(result).not.toContain("main.lua"); + // Regular line references + expect(result).toContain("\tmain.ts:4:"); + expect(result).toContain("\tmain.ts:3:"); + // Anonymous function references must keep <> format + expect(result).toContain(""); + expect(result).toContain(""); +}); + util.testEachVersion( "error stacktrace omits constructor and __TS_New", () => util.testFunction` From 5cd8abf9b0a5b30fa46c0064e33d17eb19c9b733 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Mar 2026 18:26:52 +0100 Subject: [PATCH 733/764] upgrade lua-types to support TS 5.5 --- package-lock.json | 18 ++++++++++++++---- package.json | 2 +- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0091f8103..b564bcfb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "javascript-stringify": "^2.0.1", "jest": "^29.5.0", "jest-circus": "^29.7.0", - "lua-types": "^2.13.0", + "lua-types": "^2.14.1", "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", "ts-jest": "^29.2.5", @@ -91,6 +91,7 @@ "integrity": "sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.24.7", @@ -1547,6 +1548,7 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz", "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==", "dev": true, + "peer": true, "dependencies": { "undici-types": "~6.20.0" } @@ -1605,6 +1607,7 @@ "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.3", @@ -1645,6 +1648,7 @@ "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", @@ -1869,6 +1873,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2170,6 +2175,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001646", "electron-to-chromium": "^1.5.4", @@ -2589,6 +2595,7 @@ "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -3545,6 +3552,7 @@ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", @@ -4646,9 +4654,9 @@ } }, "node_modules/lua-types": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.13.1.tgz", - "integrity": "sha512-rRwtvX6kS+5MpuO3xpvKsnYjdSDDI064Qq1OqX8gY+r+0l7m3dFLiZPDFoHqH22jaBpEvcHcPs6+WD7qkdmFsA==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.14.1.tgz", + "integrity": "sha512-+EbnTjF+Bbfp5xmpfT0O9AZgC5J6Oq6jRnZei3HLb0pbWuCRHmdnIVRPIgEpUncWvHq21DHB2qTHhA4xGceHHg==", "dev": true, "license": "MIT" }, @@ -5611,6 +5619,7 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5691,6 +5700,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index e6a53fca5..ccf7d452e 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "javascript-stringify": "^2.0.1", "jest": "^29.5.0", "jest-circus": "^29.7.0", - "lua-types": "^2.13.0", + "lua-types": "^2.14.1", "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", "ts-jest": "^29.2.5", From dfef9f45a00524618cc6499ce31b3f9fa64496be Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Mar 2026 18:36:50 +0100 Subject: [PATCH 734/764] CHANGELOG.md 1.34.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 235cdc2c2..0c8014962 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 1.34.0 + +- Added support for the Lua 5.5 target (it mostly does the same as the 5.4 target for now) +- Fixed a bug where enums in namespaces were not merged correctly +- Fixed an issue with sourcemap traceback that caused lines from anonymous functions not to be translated correctly. +- Fixed a small bug relating to the stacktraces produced by bundled lua + ## 1.33.0 - Upgraded TypeScript to 5.9.3 From 1bdbed854a3a4cd69a4a61f5ca7bfc29952e996f Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sun, 8 Mar 2026 18:52:59 +0100 Subject: [PATCH 735/764] 1.34.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b564bcfb7..1b482b466 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.33.2", + "version": "1.34.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.33.2", + "version": "1.34.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index ccf7d452e..fe6771138 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.33.2", + "version": "1.34.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From cfb6e2b388c854df2bb30f97c9cda8c4cd61595d Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 24 Mar 2026 21:29:17 +0000 Subject: [PATCH 736/764] fix try/finally not re-throwing errors when there is no catch clause (#1692) * fix try/finally not re-throwing errors when there is no catch clause (#1667) When a try block had a finally but no catch, pcall's error result was discarded, silently swallowing the exception. Now the error is captured and re-thrown after the finally block executes. * Nicer test return values --- src/transformation/visitors/errors.ts | 20 ++++++++++++++++++++ test/unit/error.spec.ts | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index f81519e4c..7233d709c 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -146,6 +146,10 @@ export const transformTryStatement: FunctionVisitor = (statemen returnedIdentifier, lua.SyntaxKind.AndOperator ); + } else if (statement.finallyBlock) { + // try without catch, but with finally — need to capture error for re-throw + const errorIdentifier = lua.createIdentifier("____error"); + result.push(lua.createVariableDeclarationStatement([tryResultIdentifier, errorIdentifier], tryCall)); } else { // try without return or catch result.push(lua.createExpressionStatement(tryCall)); @@ -155,6 +159,22 @@ export const transformTryStatement: FunctionVisitor = (statemen result.push(...context.transformStatements(statement.finallyBlock)); } + // Re-throw error if try had no catch but had a finally + if (!statement.catchClause && statement.finallyBlock) { + const notTryCondition = lua.createUnaryExpression( + lua.cloneIdentifier(tryResultIdentifier), + lua.SyntaxKind.NotOperator + ); + const errorIdentifier = lua.createIdentifier("____error"); + const rethrow = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("error"), [ + lua.cloneIdentifier(errorIdentifier), + lua.createNumericLiteral(0), + ]) + ); + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); + } + if (returnCondition && returnedIdentifier) { const returnValues: lua.Expression[] = []; diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index af69d7e1d..78444c60a 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -256,6 +256,28 @@ test("multi return from catch->finally", () => { .expectToMatchJsResult(); }); +test("throw propagates through finally to outer catch", () => { + util.testFunction` + function thrower() { + try { + throw "Error"; + } finally { + } + } + + function caller() { + try { + thrower(); + return "NoCatch"; + } catch (e) { + return e; + } + } + + return caller(); + `.expectToMatchJsResult(); +}); + test("return from nested finally", () => { util.testFunction` let x = ""; From c3dc829944358a793a566b2f5d4ea1653aea26dd Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Tue, 24 Mar 2026 21:40:14 +0000 Subject: [PATCH 737/764] fix Set iterator not reflecting mutations after creation (#1691) * fix Set iterator not reflecting mutations after creation (#1671) Set.values(), keys(), and entries() eagerly captured firstKey at iterator creation time. If the Set was mutated (e.g. via delete) before the iterator was consumed, the iterator still saw the stale firstKey. Read firstKey lazily on the first next() call instead. * Add tests for Set iterator mutation and exhaustion behavior * Fix Map iterator mutation and add tests for mutation and exhaustion behavior --- src/lualib/Map.ts | 42 ++++++++++++++++++++++++---------- src/lualib/Set.ts | 42 ++++++++++++++++++++++++---------- test/unit/builtins/map.spec.ts | 38 ++++++++++++++++++++++++++++++ test/unit/builtins/set.spec.ts | 42 ++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+), 24 deletions(-) diff --git a/src/lualib/Map.ts b/src/lualib/Map.ts index 16fa7e453..c2bcb43a4 100644 --- a/src/lualib/Map.ts +++ b/src/lualib/Map.ts @@ -113,46 +113,64 @@ export class Map { } public entries(): IterableIterator<[K, V]> { + const getFirstKey = () => this.firstKey; const { items, nextKey } = this; - let key = this.firstKey; + let key: K | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator<[K, V]> { return this; }, next(): IteratorResult<[K, V]> { - const result = { done: !key, value: [key, items.get(key!)] as [K, V] }; - key = nextKey.get(key!); - return result; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: [key!, items.get(key!)] as [K, V] }; }, }; } public keys(): IterableIterator { + const getFirstKey = () => this.firstKey; const nextKey = this.nextKey; - let key = this.firstKey; + let key: K | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - const result = { done: !key, value: key }; - key = nextKey.get(key!); - return result as IteratorResult; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: key! }; }, }; } public values(): IterableIterator { + const getFirstKey = () => this.firstKey; const { items, nextKey } = this; - let key = this.firstKey; + let key: K | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - const result = { done: !key, value: items.get(key!) }; - key = nextKey.get(key!); - return result; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: items.get(key!) }; }, }; } diff --git a/src/lualib/Set.ts b/src/lualib/Set.ts index b46555edf..e302e4094 100644 --- a/src/lualib/Set.ts +++ b/src/lualib/Set.ts @@ -102,46 +102,64 @@ export class Set { } public entries(): IterableIterator<[T, T]> { + const getFirstKey = () => this.firstKey; const nextKey = this.nextKey; - let key: T = this.firstKey!; + let key: T | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator<[T, T]> { return this; }, next(): IteratorResult<[T, T]> { - const result = { done: !key, value: [key, key] as [T, T] }; - key = nextKey.get(key); - return result; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: [key!, key!] as [T, T] }; }, }; } public keys(): IterableIterator { + const getFirstKey = () => this.firstKey; const nextKey = this.nextKey; - let key: T = this.firstKey!; + let key: T | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - const result = { done: !key, value: key }; - key = nextKey.get(key); - return result; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: key! }; }, }; } public values(): IterableIterator { + const getFirstKey = () => this.firstKey; const nextKey = this.nextKey; - let key: T = this.firstKey!; + let key: T | undefined; + let started = false; return { [Symbol.iterator](): IterableIterator { return this; }, next(): IteratorResult { - const result = { done: !key, value: key }; - key = nextKey.get(key); - return result; + if (!started) { + started = true; + key = getFirstKey(); + } else { + key = nextKey.get(key!); + } + return { done: !key, value: key! }; }, }; } diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index f2e1cbfbe..27b539589 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -210,6 +210,44 @@ describe.each(iterationMethods)("map.%s() preserves insertion order", iterationM }); }); +describe.each(iterationMethods)("map.%s() handles mutation", iterationMethod => { + test("iterator persists after delete", () => { + util.testFunction` + const map = new Map([[1, "a"], [2, "b"]]); + const iter = map.${iterationMethod}(); + map.delete(1); + return iter.next().value; + `.expectToMatchJsResult(); + }); + + test("iterator with delete and add between iterations", () => { + util.testFunction` + const map = new Map([[1, "a"], [2, "b"], [3, "c"]]); + const iter = map.${iterationMethod}(); + iter.next(); // 1 + map.delete(2); + map.set(4, "d"); + const results: IteratorResult[] = []; + let r = iter.next(); + while (!r.done) { results.push({ done: r.done, value: r.value }); r = iter.next(); } + return results; + `.expectToMatchJsResult(); + }); + + test("iterator does not restart after exhaustion", () => { + util.testFunction` + const map = new Map([[1, "a"], [2, "b"]]); + const iter = map.${iterationMethod}(); + const results: boolean[] = []; + results.push(iter.next().done!); + results.push(iter.next().done!); + results.push(iter.next().done!); // should be done + results.push(iter.next().done!); // should still be done, not restart + return results; + `.expectToMatchJsResult(); + }); +}); + describe("Map.groupBy", () => { test("empty", () => { util.testFunction` diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index a03f27ab2..65ee4aef0 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -195,6 +195,48 @@ describe.each(iterationMethods)("set.%s() preserves insertion order", iterationM }); }); +describe.each(iterationMethods)("set.%s() handles mutation", iterationMethod => { + test("iterator persists after delete", () => { + util.testFunction` + const set1 = new Set(); + set1.add(42); + set1.add("forty two"); + + const iterator1 = set1.${iterationMethod}(); + set1.delete(42); + + return iterator1.next().value; + `.expectToMatchJsResult(); + }); + + test("iterator with delete and add between iterations", () => { + util.testFunction` + const set = new Set([1, 2, 3]); + const iter = set.${iterationMethod}(); + iter.next(); // 1 + set.delete(2); + set.add(4); + const results: IteratorResult[] = []; + let r = iter.next(); + while (!r.done) { results.push({ done: r.done, value: r.value }); r = iter.next(); } + return results; + `.expectToMatchJsResult(); + }); + + test("iterator does not restart after exhaustion", () => { + util.testFunction` + const set = new Set([1, 2]); + const iter = set.${iterationMethod}(); + const results: boolean[] = []; + results.push(iter.next().done!); + results.push(iter.next().done!); + results.push(iter.next().done!); // should be done + results.push(iter.next().done!); // should still be done, not restart + return results; + `.expectToMatchJsResult(); + }); +}); + test("instanceof Set without creating set", () => { util.testFunction` const myset = 3 as any; From 2bb18e12b03570978e4c5373c953925d4e35cb09 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sat, 28 Mar 2026 12:55:05 +0000 Subject: [PATCH 738/764] Fix/dead code after break (#1694) * strip dead code after break in printer * change tests from translation to no execution error * remove unused expectAllVersions * improve break dead code tests: target affected versions, check output values --- src/LuaPrinter.ts | 2 +- test/unit/printer/deadCodeAfterBreak.spec.ts | 93 ++++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 test/unit/printer/deadCodeAfterBreak.spec.ts diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index b0a02dfaf..26b55421b 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -328,7 +328,7 @@ export class LuaPrinter { statementNodes.push(node); - if (lua.isReturnStatement(statement)) break; + if (lua.isReturnStatement(statement) || lua.isBreakStatement(statement)) break; } return statementNodes.length > 0 ? [...intersperse(statementNodes, "\n"), "\n"] : []; diff --git a/test/unit/printer/deadCodeAfterBreak.spec.ts b/test/unit/printer/deadCodeAfterBreak.spec.ts new file mode 100644 index 000000000..fe1b9073c --- /dev/null +++ b/test/unit/printer/deadCodeAfterBreak.spec.ts @@ -0,0 +1,93 @@ +import * as tstl from "../../../src"; +import * as util from "../../util"; + +// In Lua 5.0, 5.1, and LuaJIT, break must be the last statement in a block. +// Any code after break is a syntax error (e.g. `while true do break; local b = 8 end` +// fails with "'end' expected near 'local'"). Lua 5.2+ relaxed this restriction. +// TSTL should strip dead code after break on all targets to avoid these errors. + +function expectNoDeadCode(builder: util.TestBuilder) { + const lua = builder.getMainLuaCodeChunk(); + expect(lua).not.toContain("local b = 8"); +} + +const affectedVersions: Record void) | boolean> = { + [tstl.LuaTarget.Universal]: false, + [tstl.LuaTarget.Lua50]: builder => builder.tap(expectNoDeadCode).expectToMatchJsResult(), + [tstl.LuaTarget.Lua51]: builder => builder.tap(expectNoDeadCode).expectToMatchJsResult(), + [tstl.LuaTarget.Lua52]: false, + [tstl.LuaTarget.Lua53]: false, + [tstl.LuaTarget.Lua54]: false, + [tstl.LuaTarget.Lua55]: false, + [tstl.LuaTarget.LuaJIT]: builder => builder.tap(expectNoDeadCode), + [tstl.LuaTarget.Luau]: false, +}; + +util.testEachVersion( + "for dead code after break", + () => util.testFunction` + let result = 0; + for (let i = 0; i < 10; i++) { result = i; break; const b = 8; } + return result; + `, + affectedVersions +); + +util.testEachVersion( + "for..in dead code after break", + () => util.testFunction` + let result = ""; + for (let a in {"a": 5, "b": 8}) { result = a; break; const b = 8; } + return result; + `, + affectedVersions +); + +util.testEachVersion( + "for..of dead code after break", + () => util.testFunction` + let result = 0; + for (let a of [1,2,4]) { result = a; break; const b = 8; } + return result; + `, + affectedVersions +); + +util.testEachVersion( + "while dead code after break", + () => util.testFunction` + let result = "done"; + while (true) { break; const b = 8; } + return result; + `, + affectedVersions +); + +util.testEachVersion( + "switch dead code after break", + () => util.testFunction` + let result = "none"; + switch ("abc" as string) { + case "def": + result = "def"; + break; + let abc = 4; + case "abc": + result = "abc"; + break; + let def = 6; + } + return result; + `, + affectedVersions +); + +util.testEachVersion( + "do-while dead code after break", + () => util.testFunction` + let result = "done"; + do { break; const b = 8; } while (true); + return result; + `, + affectedVersions +); From 8c856f1d4f0c2c60bcb30718cf9c69bc70258b7e Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sat, 28 Mar 2026 12:58:01 +0000 Subject: [PATCH 739/764] fix Promise.finally() to return new promise via .then() (#1696) * fix Promise.finally() to return new promise via .then() * simplify Promise.finally test to use expectToMatchJsResult Remove redundant tests that relied on synchronous polyfill behavior differing from JS. Keep only the identity check which matches JS. * add tests for Promise.finally value preservation and rejection passthrough Fix issue reference (#1660, not #1659). --- src/lualib/Promise.ts | 40 +++++++++++-------------- test/unit/builtins/promise.spec.ts | 48 ++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 23 deletions(-) diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index c5b6aa2a5..187e5380d 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -45,7 +45,6 @@ export class __TS__Promise implements Promise { private fulfilledCallbacks: Array> = []; private rejectedCallbacks: PromiseReject[] = []; - private finallyCallbacks: Array<() => void> = []; // @ts-ignore public [Symbol.toStringTag]: string; // Required to implement interface, no output Lua @@ -124,16 +123,23 @@ export class __TS__Promise implements Promise { } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally + // Delegates to .then() so that a new Promise is returned (per ES spec §27.2.5.3) + // and the original fulfillment value / rejection reason is preserved. public finally(onFinally?: () => void): Promise { - if (onFinally) { - this.finallyCallbacks.push(onFinally); - - if (this.state !== PromiseState.Pending) { - // If promise already resolved or rejected, immediately fire finally callback - onFinally(); - } - } - return this; + return this.then( + onFinally + ? (value: T): T => { + onFinally(); + return value; + } + : undefined, + onFinally + ? (reason: any): never => { + onFinally(); + throw reason; + } + : undefined + ); } private resolve(value: T | PromiseLike): void { @@ -168,25 +174,13 @@ export class __TS__Promise implements Promise { private invokeCallbacks(callbacks: ReadonlyArray<(value: T) => void>, value: T): void { const callbacksLength = callbacks.length; - const finallyCallbacks = this.finallyCallbacks; - const finallyCallbacksLength = finallyCallbacks.length; if (callbacksLength !== 0) { for (const i of $range(1, callbacksLength - 1)) { callbacks[i - 1](value); } // Tail call optimization for a common case. - if (finallyCallbacksLength === 0) { - return callbacks[callbacksLength - 1](value); - } - callbacks[callbacksLength - 1](value); - } - - if (finallyCallbacksLength !== 0) { - for (const i of $range(1, finallyCallbacksLength - 1)) { - finallyCallbacks[i - 1](); - } - return finallyCallbacks[finallyCallbacksLength - 1](); + return callbacks[callbacksLength - 1](value); } } diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index cb18db994..f323b030f 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -1323,3 +1323,51 @@ describe("Promise.race", () => { }); }); }); + +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1660 +describe("Promise.finally", () => { + test("returns a different promise instance", () => { + util.testFunction` + const p1 = new Promise(() => {}); + const p2 = p1.finally(); + return p1 === p2; + `.expectToMatchJsResult(); + }); + + test("preserves fulfillment value", () => { + util.testFunction` + const result = Promise.resolve(42).finally(() => {}) as any; + return result.value; + `.expectToEqual(42); + }); + + test("preserves rejection reason", () => { + util.testFunction` + const result = Promise.reject("err").finally(() => {}) as any; + return result.rejectionReason; + `.expectToEqual("err"); + }); + + test("callback executes on fulfillment", () => { + util.testFunction` + let called = false; + Promise.resolve(1).finally(() => { called = true; }); + return called; + `.expectToEqual(true); + }); + + test("callback executes on rejection", () => { + util.testFunction` + let called = false; + Promise.reject("err").finally(() => { called = true; }); + return called; + `.expectToEqual(true); + }); + + test("finally with undefined callback", () => { + util.testFunction` + const result = Promise.resolve(99).finally(undefined) as any; + return result.value; + `.expectToEqual(99); + }); +}); From 57459c6e0f2077f8166a0302fc318afbf697517b Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sat, 28 Mar 2026 13:04:23 +0000 Subject: [PATCH 740/764] fix Object.defineProperty sharing values across instances (#1697) * fix Object.defineProperty sharing values across instances When Object.defineProperty is called on an instance (not a prototype), create a per-instance metatable if the shared metatable already has descriptors, so that each instance gets its own descriptor storage. Fixes #1625 * fix Object.defineProperty instance isolation for first instance Use a marker to always create per-instance metatables, not just when _descriptors already exists on the shared metatable. Add more thorough instance isolation tests. --- src/lualib/SetDescriptor.ts | 11 +++++ test/unit/builtins/object.spec.ts | 75 +++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) diff --git a/src/lualib/SetDescriptor.ts b/src/lualib/SetDescriptor.ts index 4339c8cc1..ccb4bf3f0 100644 --- a/src/lualib/SetDescriptor.ts +++ b/src/lualib/SetDescriptor.ts @@ -26,6 +26,17 @@ export function __TS__SetDescriptor( setmetatable(target, metatable); } + // When setting a descriptor on an instance (not a prototype), ensure it has + // its own metatable so descriptors are not shared across instances. + // See: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1625 + if (!isPrototype && !rawget(metatable, "_isOwnDescriptorMetatable")) { + const instanceMetatable: any = {}; + instanceMetatable._isOwnDescriptorMetatable = true; + setmetatable(instanceMetatable, metatable); + setmetatable(target, instanceMetatable); + metatable = instanceMetatable; + } + const value = rawget(target, key); if (value !== undefined) rawset(target, key, undefined); diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 1edc8a9d6..dfed73502 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -196,6 +196,81 @@ describe("Object.defineProperty", () => { return { prop: foo.bar, err }; `.expectToMatchJsResult(); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1625 + test("instance isolation", () => { + util.testFunction` + class Test { + declare obj: object; + constructor() { + Object.defineProperty(this, "obj", { value: {}, writable: true, configurable: true }); + } + } + const t1 = new Test(); + const t2 = new Test(); + return t1.obj === t2.obj; + `.expectToMatchJsResult(); + }); + + test("instance isolation with three instances", () => { + util.testFunction` + class Test { + declare obj: object; + constructor() { + Object.defineProperty(this, "obj", { value: {}, writable: true, configurable: true }); + } + } + const t1 = new Test(); + const t2 = new Test(); + const t3 = new Test(); + return [t1.obj === t2.obj, t1.obj === t3.obj, t2.obj === t3.obj]; + `.expectToMatchJsResult(); + }); + + test("instance isolation with mutation", () => { + util.testFunction` + class Test { + declare value: number; + constructor(v: number) { + Object.defineProperty(this, "value", { value: v, writable: true, configurable: true }); + } + } + const t1 = new Test(1); + const t2 = new Test(2); + return [t1.value, t2.value]; + `.expectToMatchJsResult(); + }); + + test("instance isolation with multiple properties", () => { + util.testFunction` + class Test { + declare a: string; + declare b: string; + constructor(a: string, b: string) { + Object.defineProperty(this, "a", { value: a, writable: true, configurable: true }); + Object.defineProperty(this, "b", { value: b, writable: true, configurable: true }); + } + } + const t1 = new Test("x", "y"); + const t2 = new Test("p", "q"); + return [t1.a, t1.b, t2.a, t2.b]; + `.expectToMatchJsResult(); + }); + + test("instance isolation preserves prototype methods", () => { + util.testFunction` + class Test { + declare val: number; + constructor(v: number) { + Object.defineProperty(this, "val", { value: v, writable: true, configurable: true }); + } + getVal() { return this.val; } + } + const t1 = new Test(10); + const t2 = new Test(20); + return [t1.getVal(), t2.getVal()]; + `.expectToMatchJsResult(); + }); }); describe("Object.getOwnPropertyDescriptor", () => { From ec26bdf4e15be9db6119e4ad3cb269aa45d7bab2 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sun, 29 Mar 2026 19:46:48 +0100 Subject: [PATCH 741/764] fix try/finally rethrow when try block has return paths (#1699) * fix try/finally rethrow when try block has return paths Fixes a regression from #1692 where try/finally (no catch) with both return and throw paths silently lost the error. The re-throw used an undeclared ____error variable; use ____hasReturned instead, which is where pcall places the error on failure. * add test for try/finally with return+throw and non-empty finally body --- src/transformation/visitors/errors.ts | 13 ++--- test/unit/error.spec.ts | 76 +++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 6 deletions(-) diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 7233d709c..b2c9d36d1 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -159,18 +159,19 @@ export const transformTryStatement: FunctionVisitor = (statemen result.push(...context.transformStatements(statement.finallyBlock)); } - // Re-throw error if try had no catch but had a finally + // Re-throw error if try had no catch but had a finally. + // On pcall failure the error is the second return value, which lands in + // ____hasReturned (when functionReturned) or ____error (otherwise). if (!statement.catchClause && statement.finallyBlock) { const notTryCondition = lua.createUnaryExpression( lua.cloneIdentifier(tryResultIdentifier), lua.SyntaxKind.NotOperator ); - const errorIdentifier = lua.createIdentifier("____error"); + const errorIdentifier = tryScope.functionReturned + ? lua.cloneIdentifier(returnedIdentifier) + : lua.createIdentifier("____error"); const rethrow = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("error"), [ - lua.cloneIdentifier(errorIdentifier), - lua.createNumericLiteral(0), - ]) + lua.createCallExpression(lua.createIdentifier("error"), [errorIdentifier, lua.createNumericLiteral(0)]) ); result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); } diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 78444c60a..89ceb49df 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -417,6 +417,82 @@ test("sourceMapTraceback maps anonymous function locations in .lua files (#1665) expect(result).toContain(""); }); +test("try/finally rethrow preserves error value", () => { + util.testFunction` + function foo() { + try { + throw "oops"; + } finally { + } + } + try { foo(); return "no error"; } catch(e) { return e; } + `.expectToMatchJsResult(); +}); + +test("try/finally with return and throw paths", () => { + util.testFunction` + function foo(shouldReturn: boolean) { + try { + if (shouldReturn) return "returned"; + throw "thrown"; + } finally { + } + } + const results: any[] = []; + results.push(foo(true)); + try { foo(false); } catch(e) { results.push(e); } + return results; + `.expectToMatchJsResult(); +}); + +test("try/finally runs finally side effect before rethrow", () => { + util.testFunction` + let sideEffect = false; + function foo() { + try { + throw "err"; + } finally { + sideEffect = true; + } + } + try { foo(); } catch(e) {} + return sideEffect; + `.expectToMatchJsResult(); +}); + +test("try/finally with return and throw paths and non-empty finally body", () => { + util.testFunction` + let sideEffect = false; + function foo(shouldReturn: boolean) { + try { + if (shouldReturn) return "ok"; + throw "err"; + } finally { + sideEffect = true; + } + } + const results: any[] = []; + results.push(foo(true)); + results.push(sideEffect); + sideEffect = false; + try { foo(false); } catch(e) { results.push(e); } + results.push(sideEffect); + return results; + `.expectToMatchJsResult(); +}); + +test("try/finally rethrow with non-string error", () => { + util.testFunction` + function foo() { + try { + throw 42; + } finally { + } + } + try { foo(); return "no error"; } catch(e) { return e; } + `.expectToMatchJsResult(); +}); + util.testEachVersion( "error stacktrace omits constructor and __TS_New", () => util.testFunction` From 84ef0b2d09b8ed1b1d91a9066db8819a4e13ff15 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Wed, 1 Apr 2026 19:50:15 +0100 Subject: [PATCH 742/764] fix Math.atan2 emitting math.atan2 instead of math.atan for Lua 5.4+ (#1700) * fix Math.atan2 emitting math.atan2 instead of math.atan for Lua 5.4+ math.atan2 was removed in Lua 5.3 (replaced by two-arg math.atan). The codegen only special-cased 5.3 but not 5.4 or 5.5, which also lack math.atan2 (5.4 has it behind a compat flag, 5.5 drops it). * invert atan2 condition to default future Lua targets to math.atan Enumerate the older targets that need math.atan2 instead of the newer ones that need math.atan, so any future Lua target (5.6+) defaults to the modern behavior rather than silently regressing. --- src/transformation/builtins/math.ts | 10 ++++++++-- test/unit/builtins/math.spec.ts | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/transformation/builtins/math.ts b/src/transformation/builtins/math.ts index ab831d52f..82a118ec1 100644 --- a/src/transformation/builtins/math.ts +++ b/src/transformation/builtins/math.ts @@ -42,14 +42,20 @@ export function transformMathCall( const expressionName = calledMethod.name.text; switch (expressionName) { - // Lua 5.3: math.atan(y, x) + // Lua 5.3+: math.atan(y, x) // Otherwise: math.atan2(y, x) case "atan2": { if (context.luaTarget === LuaTarget.Universal) { return transformLuaLibFunction(context, LuaLibFeature.MathAtan2, node, ...params); } - const method = lua.createStringLiteral(context.luaTarget === LuaTarget.Lua53 ? "atan" : "atan2"); + const useAtan2 = + context.luaTarget === LuaTarget.Lua50 || + context.luaTarget === LuaTarget.Lua51 || + context.luaTarget === LuaTarget.Lua52 || + context.luaTarget === LuaTarget.LuaJIT || + context.luaTarget === LuaTarget.Luau; + const method = lua.createStringLiteral(useAtan2 ? "atan2" : "atan"); return lua.createCallExpression(lua.createTableIndexExpression(math, method), params, node); } diff --git a/test/unit/builtins/math.spec.ts b/test/unit/builtins/math.spec.ts index f3ff1f306..d09b331cd 100644 --- a/test/unit/builtins/math.spec.ts +++ b/test/unit/builtins/math.spec.ts @@ -95,8 +95,8 @@ util.testEachVersion("Math.atan2", () => util.testExpression`Math.atan2(4, 5)`, [tstl.LuaTarget.Lua51]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua52]: builder => builder.tap(expectMathAtan2), [tstl.LuaTarget.Lua53]: builder => builder.tap(expectMathAtan), - [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan2), - [tstl.LuaTarget.Lua55]: builder => builder.tap(expectMathAtan2), + [tstl.LuaTarget.Lua54]: builder => builder.tap(expectMathAtan), + [tstl.LuaTarget.Lua55]: builder => builder.tap(expectMathAtan), [tstl.LuaTarget.Luau]: builder => builder.tap(expectMathAtan2), }); From c043cdcc68902924ae34b2015e64fe05e2a29cea Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Wed, 1 Apr 2026 19:52:25 +0100 Subject: [PATCH 743/764] fix Number.MAX_SAFE_INTEGER, MIN_SAFE_INTEGER, MIN_VALUE, MAX_VALUE emitting wrong Lua (#1698) All four constants evaluated to Infinity or -Infinity in Lua. Additionally, MIN_SAFE_INTEGER and MIN_VALUE emitted identical code, as did MAX_SAFE_INTEGER and MAX_VALUE. The existing test did not catch this because it only checked Lua-side results with comparisons that the wrong values accidentally satisfied. --- src/transformation/builtins/number.ts | 55 +++++++++++++++++++++------ test/unit/builtins/numbers.spec.ts | 24 +++++++----- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/transformation/builtins/number.ts b/src/transformation/builtins/number.ts index 17c44b6fd..ecb98da64 100644 --- a/src/transformation/builtins/number.ts +++ b/src/transformation/builtins/number.ts @@ -77,31 +77,62 @@ export function transformNumberProperty( node ); case "MIN_VALUE": + // 2 ^ -1074 = 5e-324 (smallest positive double) return lua.createBinaryExpression( - lua.createNumericLiteral(-2), - lua.createNumericLiteral(1074), + lua.createNumericLiteral(2), + lua.createNumericLiteral(-1074), lua.SyntaxKind.PowerOperator, node ); case "MIN_SAFE_INTEGER": - return lua.createBinaryExpression( - lua.createNumericLiteral(-2), - lua.createNumericLiteral(1074), - lua.SyntaxKind.PowerOperator, + // -(2 ^ 53 - 1) = -9007199254740991 + return lua.createUnaryExpression( + lua.createParenthesizedExpression( + lua.createBinaryExpression( + lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(53), + lua.SyntaxKind.PowerOperator + ), + lua.createNumericLiteral(1), + lua.SyntaxKind.SubtractionOperator + ) + ), + lua.SyntaxKind.NegationOperator, node ); case "MAX_SAFE_INTEGER": + // 2 ^ 53 - 1 = 9007199254740991 return lua.createBinaryExpression( - lua.createNumericLiteral(2), - lua.createNumericLiteral(1024), - lua.SyntaxKind.PowerOperator, + lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(53), + lua.SyntaxKind.PowerOperator + ), + lua.createNumericLiteral(1), + lua.SyntaxKind.SubtractionOperator, node ); case "MAX_VALUE": + // (2 - 2 ^ -52) * 2 ^ 1023 = 1.7976931348623157e+308 return lua.createBinaryExpression( - lua.createNumericLiteral(2), - lua.createNumericLiteral(1024), - lua.SyntaxKind.PowerOperator, + lua.createParenthesizedExpression( + lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(-52), + lua.SyntaxKind.PowerOperator + ), + lua.SyntaxKind.SubtractionOperator + ) + ), + lua.createBinaryExpression( + lua.createNumericLiteral(2), + lua.createNumericLiteral(1023), + lua.SyntaxKind.PowerOperator + ), + lua.SyntaxKind.MultiplicationOperator, node ); diff --git a/test/unit/builtins/numbers.spec.ts b/test/unit/builtins/numbers.spec.ts index aa3a8927d..9570e4af2 100644 --- a/test/unit/builtins/numbers.spec.ts +++ b/test/unit/builtins/numbers.spec.ts @@ -212,17 +212,23 @@ test.each(["42", "undefined"])("prototype call on nullable number (%p)", value = }); test.each([ - "Number.NEGATIVE_INFINITY <= Number.MIN_VALUE", - "Number.MIN_VALUE <= Number.MIN_SAFE_INTEGER", - - "Number.MAX_SAFE_INTEGER <= Number.MAX_VALUE", - "Number.MAX_VALUE <= Number.POSITIVE_INFINITY", + // Full ordering: NEG_INF < MIN_SAFE < 0 < MIN_VALUE < EPSILON < MAX_SAFE < MAX_VALUE < POS_INF + "Number.NEGATIVE_INFINITY < Number.MIN_SAFE_INTEGER", "Number.MIN_SAFE_INTEGER < 0", - - "0 < Number.EPSILON", + "0 < Number.MIN_VALUE", + "Number.MIN_VALUE < Number.EPSILON", "Number.EPSILON < Number.MAX_SAFE_INTEGER", -])("Numer constants have correct relative sizes (%p)", comparison => { - util.testExpression(comparison).expectToEqual(true); + "Number.MAX_SAFE_INTEGER < Number.MAX_VALUE", + "Number.MAX_VALUE < Number.POSITIVE_INFINITY", + + // Verify specific values + "Number.MIN_VALUE > 0", + "Number.MIN_SAFE_INTEGER === -(2**53 - 1)", + "Number.MAX_SAFE_INTEGER === 2**53 - 1", + "Number.MAX_SAFE_INTEGER + 1 !== Number.MAX_SAFE_INTEGER", + "Number.MIN_SAFE_INTEGER - 1 !== Number.MIN_SAFE_INTEGER", +])("Number constants have correct relative sizes (%p)", comparison => { + util.testExpression(comparison).expectToMatchJsResult(); }); // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1629 From 5176fcd3a9fa9ca90cdf765723e539398d410f73 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 3 Apr 2026 19:41:19 +0100 Subject: [PATCH 744/764] fix >>> (unsigned right shift) producing wrong results on Lua 5.3+ (#1703) * fix >>> (unsigned right shift) producing wrong results on Lua 5.3+ TS >>> is a logical right shift (zero-fills from the left), but TSTL was mapping it to Lua's >> which is arithmetic (sign-extends). This gave wrong results for negative numbers: e.g. -1 >>> 0 should be 4294967295 but produced -1. Fix by masking to unsigned 32-bit first: (left & 0xFFFFFFFF) >> right. The Lua 5.2 (bit32.rshift) and LuaJIT (bit.rshift) paths were already correct. * lint --- .../visitors/binary-expression/bit.ts | 16 ++++++++++ .../__snapshots__/expressions.spec.ts.snap | 12 ++++---- test/unit/expressions.spec.ts | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/transformation/visitors/binary-expression/bit.ts b/src/transformation/visitors/binary-expression/bit.ts index 79e9c1f3c..5ae876630 100644 --- a/src/transformation/visitors/binary-expression/bit.ts +++ b/src/transformation/visitors/binary-expression/bit.ts @@ -75,6 +75,22 @@ export function transformBinaryBitOperation( case LuaTarget.Lua52: return transformBinaryBitLibOperation(node, left, right, operator, "bit32"); default: + // Lua 5.3+ `>>` is arithmetic (sign-extending), but TS `>>>` is logical (zero-fill). + // Emit `(left & 0xFFFFFFFF) >> right` to convert to unsigned 32-bit first. + if (operator === ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken) { + const mask = lua.createBinaryExpression( + left, + lua.createNumericLiteral(0xffffffff, node), + lua.SyntaxKind.BitwiseAndOperator, + node + ); + return lua.createBinaryExpression( + lua.createParenthesizedExpression(mask, node), + right, + lua.SyntaxKind.BitwiseRightShiftOperator, + node + ); + } const luaOperator = transformBitOperatorToLuaOperator(context, node, operator); return lua.createBinaryExpression(left, right, luaOperator, node); } diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index e2adff370..720f7014e 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -374,14 +374,14 @@ return ____exports" exports[`Bitop [5.3] ("a>>>=b") 1`] = ` "local ____exports = {} -a = a >> b +a = (a & 4294967295) >> b ____exports.__result = a return ____exports" `; exports[`Bitop [5.3] ("a>>>b") 1`] = ` "local ____exports = {} -____exports.__result = a >> b +____exports.__result = (a & 4294967295) >> b return ____exports" `; @@ -445,14 +445,14 @@ return ____exports" exports[`Bitop [5.4] ("a>>>=b") 1`] = ` "local ____exports = {} -a = a >> b +a = (a & 4294967295) >> b ____exports.__result = a return ____exports" `; exports[`Bitop [5.4] ("a>>>b") 1`] = ` "local ____exports = {} -____exports.__result = a >> b +____exports.__result = (a & 4294967295) >> b return ____exports" `; @@ -516,14 +516,14 @@ return ____exports" exports[`Bitop [5.5] ("a>>>=b") 1`] = ` "local ____exports = {} -a = a >> b +a = (a & 4294967295) >> b ____exports.__result = a return ____exports" `; exports[`Bitop [5.5] ("a>>>b") 1`] = ` "local ____exports = {} -____exports.__result = a >> b +____exports.__result = (a & 4294967295) >> b return ____exports" `; diff --git a/test/unit/expressions.spec.ts b/test/unit/expressions.spec.ts index ee0eab5f4..12fd85be1 100644 --- a/test/unit/expressions.spec.ts +++ b/test/unit/expressions.spec.ts @@ -117,6 +117,35 @@ test.each(unsupportedIn53And54)("Unsupported bitop 5.4 (%p)", input => { .expectDiagnosticsToMatchSnapshot([unsupportedRightShiftOperator.code]); }); +// Execution tests: verify >>> produces correct results matching JS semantics +for (const expression of ["-5 >>> 0", "-1 >>> 0", "1 >>> 0", "-1 >>> 16", "255 >>> 4"]) { + util.testEachVersion(`Unsigned right shift execution (${expression})`, () => util.testExpression(expression), { + [tstl.LuaTarget.Universal]: false, + [tstl.LuaTarget.Lua50]: false, // No bit library in WASM runtime + [tstl.LuaTarget.Lua51]: false, // No bit library in WASM runtime + [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua55]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.LuaJIT]: false, // Can't execute LuaJIT in tests + [tstl.LuaTarget.Luau]: false, + }); +} + +for (const code of ["let a = -5; a >>>= 0; return a;", "let a = -1; a >>>= 16; return a;"]) { + util.testEachVersion(`Unsigned right shift assignment execution (${code})`, () => util.testFunction(code), { + [tstl.LuaTarget.Universal]: false, + [tstl.LuaTarget.Lua50]: false, // No bit library in WASM runtime + [tstl.LuaTarget.Lua51]: false, // No bit library in WASM runtime + [tstl.LuaTarget.Lua52]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua53]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua54]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.Lua55]: builder => builder.expectToMatchJsResult(), + [tstl.LuaTarget.LuaJIT]: false, // Can't execute LuaJIT in tests + [tstl.LuaTarget.Luau]: false, + }); +} + test.each(["1+1", "-1+1", "1*30+4", "1*(3+4)", "1*(3+4*2)", "10-(4+5)"])( "Binary expressions ordering parentheses (%p)", input => { From c3b3a8bb85ed93aeb4d32ed9b9eed790370ba659 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 17 Apr 2026 04:58:51 +0900 Subject: [PATCH 745/764] Fix/object assign non table source (#1642) (#1710) * fix Object.assign crashing when source is a non-table value `{ ...(cond && obj) }` short-circuits to `false` when `cond` is falsy. JS treats this as a no-op (Object.assign coerces primitives to wrapper objects with no own enumerable properties), but `__TS__ObjectAssign` was iterating every source unconditionally, so `pairs(false)` errored at runtime. Skip non-table sources, matching the spec for null/undefined/primitive args. * refactor __TS__ObjectAssign to emit cleaner Lua Invert the type guard so it nests the spread loop instead of using `continue`, which lowered to a `repeat ... until true` + `break` dance. Same behavior, the bundled helper now reads like the hand-written original. --- src/lualib/ObjectAssign.ts | 6 ++++-- test/unit/builtins/object.spec.ts | 10 ++++++++++ test/unit/spread.spec.ts | 9 +++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/lualib/ObjectAssign.ts b/src/lualib/ObjectAssign.ts index a7f691433..7d0a3a9b1 100644 --- a/src/lualib/ObjectAssign.ts +++ b/src/lualib/ObjectAssign.ts @@ -2,8 +2,10 @@ export function __TS__ObjectAssign(this: void, target: T, ...sources: T[]): T { for (const i of $range(1, sources.length)) { const source = sources[i - 1]; - for (const key in source) { - target[key] = source[key]; + if (type(source) === "table") { + for (const key in source) { + target[key] = source[key]; + } } } diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index dfed73502..192f17d9f 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -10,6 +10,16 @@ test.each([ util.testExpression`Object.assign(${util.formatCode(initial)}, ${argsString})`.expectToMatchJsResult(); }); +test.each([ + "Object.assign({}, false)", + "Object.assign({}, null)", + "Object.assign({}, undefined)", + "Object.assign({}, null, undefined)", + "Object.assign({ a: 1 }, false, { b: 2 })", +])("Object.assign skips non-object sources (%p)", expression => { + util.testExpression(expression).expectToMatchJsResult(); +}); + test.each([{}, { abc: 3 }, { abc: 3, def: "xyz" }])("Object.entries (%p)", obj => { const testBuilder = util.testExpressionTemplate`Object.entries(${obj})`; // Need custom matcher because order is not guaranteed in neither JS nor Lua diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 53898aae5..79262c185 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -119,6 +119,15 @@ describe("in object literal", () => { util.testExpression(expression).expectToMatchJsResult(); }); + test.each([ + "{ ...((false && { a: 1 }) as any) }", + "{ ...((true && { a: 1 }) as any) }", + "{ a: 1, ...((false && { b: 2 }) as any) }", + "{ ...(null as any), ...(undefined as any) }", + ])("of short-circuited operand (%p)", expression => { + util.testExpression(expression).expectToMatchJsResult(); + }); + test("of object reference", () => { util.testFunction` const object = { x: 0, y: 1 }; From 781db8421db0ec56880857e0569ae1c36d1391d9 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 17 Apr 2026 05:01:34 +0900 Subject: [PATCH 746/764] fix array destructuring prefix operator side effects (#1405) (#1708) * fix array destructuring not preserving evaluation order with side effects (#1405) * add more test cases for array destructuring side effects --- .../visitors/variable-declaration.ts | 4 +-- test/unit/destructuring.spec.ts | 27 +++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index f15ed0115..61d50cad4 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -12,7 +12,7 @@ import { createCallableTable, isFunctionTypeWithProperties } from "./function"; import { transformIdentifier } from "./identifier"; import { isMultiReturnCall } from "./language-extensions/multi"; import { transformPropertyName } from "./literal"; -import { moveToPrecedingTemp } from "./expression-list"; +import { moveToPrecedingTemp, transformExpressionList } from "./expression-list"; export function transformArrayBindingElement( context: TransformationContext, @@ -205,7 +205,7 @@ export function transformBindingVariableDeclaration( // Don't unpack array literals const values = initializer.elements.length > 0 - ? initializer.elements.map(e => context.transformExpression(e)) + ? transformExpressionList(context, initializer.elements) : lua.createNilLiteral(); statements.push(...createLocalOrExportedOrGlobalDeclaration(context, vars, values, initializer)); } else { diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 65ecf95a3..4820876a4 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -226,6 +226,33 @@ describe("array destructuring optimization", () => { .expectToMatchJsResult(); }); + test("array literal with side effects in elements", () => { + util.testFunction` + const arr = [1, 2]; + let i = 0; + let [v1, v2] = [arr[i], arr[++i]]; + return { v1, v2 }; + `.expectToMatchJsResult(); + }); + + test("array literal with many side effects in elements", () => { + util.testFunction` + const arr = [10, 20, 30, 40]; + let i = 0; + let [v1, v2, v3, v4] = [arr[i++], arr[i++], arr[i++], arr[i++]]; + return { v1, v2, v3, v4 }; + `.expectToMatchJsResult(); + }); + + test("array literal with mixed pure and impure elements", () => { + util.testFunction` + const arr = [10, 20, 30]; + let i = 0; + let [v1, v2, v3] = [1, arr[++i], 2]; + return { v1, v2, v3, i }; + `.expectToMatchJsResult(); + }); + test("array union", () => { util.testFunction` const array: [string] | [] = ["bar"]; From 5753d6cecbd1ae4ed0ae4f4ca0e231ae4020a95e Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 17 Apr 2026 05:04:08 +0900 Subject: [PATCH 747/764] fix return, break and continue inside try in async functions (#1706) (#1707) * fix return, break and continue inside try in async functions (#1706) * more tests * add multi-return test for async try * simplify * reorder functions --- src/transformation/utils/scope.ts | 20 ++ src/transformation/visitors/break-continue.ts | 29 ++- src/transformation/visitors/errors.ts | 90 ++++++-- src/transformation/visitors/return.ts | 74 ++++--- test/unit/builtins/async-await.spec.ts | 192 ++++++++++++++++++ 5 files changed, 364 insertions(+), 41 deletions(-) diff --git a/src/transformation/utils/scope.ts b/src/transformation/utils/scope.ts index fa66ee3e2..314f1d795 100644 --- a/src/transformation/utils/scope.ts +++ b/src/transformation/utils/scope.ts @@ -38,6 +38,9 @@ export interface Scope { importStatements?: lua.Statement[]; loopContinued?: LoopContinued; functionReturned?: boolean; + asyncTryHasReturn?: boolean; + asyncTryHasBreak?: boolean; + asyncTryHasContinue?: LoopContinued; } export interface HoistingResult { @@ -84,6 +87,23 @@ export function findScope(context: TransformationContext, scopeTypes: ScopeType) } } +export function findAsyncTryScopeInStack(context: TransformationContext): Scope | undefined { + for (const scope of walkScopesUp(context)) { + if (scope.type === ScopeType.Function) return undefined; + if (scope.type === ScopeType.Try || scope.type === ScopeType.Catch) return scope; + } + return undefined; +} + +/** Like findAsyncTryScopeInStack, but also stops at Loop boundaries. */ +export function findAsyncTryScopeBeforeLoop(context: TransformationContext): Scope | undefined { + for (const scope of walkScopesUp(context)) { + if (scope.type === ScopeType.Function || scope.type === ScopeType.Loop) return undefined; + if (scope.type === ScopeType.Try || scope.type === ScopeType.Catch) return scope; + } + return undefined; +} + export function addScopeVariableDeclaration(scope: Scope, declaration: lua.VariableDeclarationStatement) { scope.variableDeclarations ??= []; diff --git a/src/transformation/visitors/break-continue.ts b/src/transformation/visitors/break-continue.ts index 2e64a38eb..e41a7934b 100644 --- a/src/transformation/visitors/break-continue.ts +++ b/src/transformation/visitors/break-continue.ts @@ -2,10 +2,22 @@ import * as ts from "typescript"; import { LuaTarget } from "../../CompilerOptions"; import * as lua from "../../LuaAST"; import { FunctionVisitor } from "../context"; -import { findScope, LoopContinued, ScopeType } from "../utils/scope"; +import { findAsyncTryScopeBeforeLoop, findScope, LoopContinued, ScopeType } from "../utils/scope"; +import { isInAsyncFunction } from "../utils/typescript"; export const transformBreakStatement: FunctionVisitor = (breakStatement, context) => { - void context; + const tryScope = isInAsyncFunction(breakStatement) ? findAsyncTryScopeBeforeLoop(context) : undefined; + if (tryScope) { + tryScope.asyncTryHasBreak = true; + return [ + lua.createAssignmentStatement( + lua.createIdentifier("____hasBroken"), + lua.createBooleanLiteral(true), + breakStatement + ), + lua.createReturnStatement([], breakStatement), + ]; + } return lua.createBreakStatement(breakStatement); }; @@ -28,6 +40,19 @@ export const transformContinueStatement: FunctionVisitor = scope.loopContinued = continuedWith; } + const tryScope = isInAsyncFunction(statement) ? findAsyncTryScopeBeforeLoop(context) : undefined; + if (tryScope) { + tryScope.asyncTryHasContinue = continuedWith; + return [ + lua.createAssignmentStatement( + lua.createIdentifier("____hasContinued"), + lua.createBooleanLiteral(true), + statement + ), + lua.createReturnStatement([], statement), + ]; + } + const label = `__continue${scope?.id ?? ""}`; switch (continuedWith) { diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index b2c9d36d1..cc73b2ac0 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -5,7 +5,7 @@ import { FunctionVisitor, TransformationContext } from "../context"; import { unsupportedForTarget, unsupportedForTargetButOverrideAvailable } from "../utils/diagnostics"; import { createUnpackCall } from "../utils/lua-ast"; import { transformLuaLibFunction } from "../utils/lualib"; -import { Scope, ScopeType } from "../utils/scope"; +import { findScope, LoopContinued, Scope, ScopeType } from "../utils/scope"; import { isInAsyncFunction, isInGeneratorFunction } from "../utils/typescript"; import { wrapInAsyncAwaiter } from "./async-await"; import { transformScopeBlock } from "./block"; @@ -14,7 +14,7 @@ import { isInMultiReturnFunction } from "./language-extensions/multi"; import { createReturnStatement } from "./return"; const transformAsyncTry: FunctionVisitor = (statement, context) => { - const [tryBlock] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); + const [tryBlock, tryScope] = transformScopeBlock(context, statement.tryBlock, ScopeType.Try); if ( (context.options.luaTarget === LuaTarget.Lua50 || context.options.luaTarget === LuaTarget.Lua51) && @@ -31,13 +31,14 @@ const transformAsyncTry: FunctionVisitor = (statement, context) return tryBlock.statements; } - // __TS__AsyncAwaiter() + // __TS__AsyncAwaiter() const awaiter = wrapInAsyncAwaiter(context, tryBlock.statements, false); const awaiterIdentifier = lua.createIdentifier("____try"); const awaiterDefinition = lua.createVariableDeclarationStatement(awaiterIdentifier, awaiter); - // local ____try = __TS__AsyncAwaiter() - const result: lua.Statement[] = [awaiterDefinition]; + // Transform catch/finally and collect scope info before building the result + let catchScope: Scope | undefined; + const chainCalls: lua.Statement[] = []; if (statement.finallyBlock) { const awaiterFinally = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("finally")); @@ -49,27 +50,88 @@ const transformAsyncTry: FunctionVisitor = (statement, context) [awaiterIdentifier, finallyFunction], statement.finallyBlock ); - // ____try.finally() - result.push(lua.createExpressionStatement(finallyCall)); + chainCalls.push(lua.createExpressionStatement(finallyCall)); } if (statement.catchClause) { - // ____try.catch() - const [catchFunction] = transformCatchClause(context, statement.catchClause); + const [catchFunction, cScope] = transformCatchClause(context, statement.catchClause); + catchScope = cScope; if (catchFunction.params) { catchFunction.params.unshift(lua.createAnonymousIdentifier()); } const awaiterCatch = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("catch")); const catchCall = lua.createCallExpression(awaiterCatch, [awaiterIdentifier, catchFunction]); - - // await ____try.catch() const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, catchCall); - result.push(lua.createExpressionStatement(promiseAwait, statement)); + chainCalls.push(lua.createExpressionStatement(promiseAwait, statement)); } else { - // await ____try const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, awaiterIdentifier); - result.push(lua.createExpressionStatement(promiseAwait, statement)); + chainCalls.push(lua.createExpressionStatement(promiseAwait, statement)); + } + + const hasReturn = tryScope.asyncTryHasReturn ?? catchScope?.asyncTryHasReturn; + const hasBreak = tryScope.asyncTryHasBreak ?? catchScope?.asyncTryHasBreak; + const hasContinue = tryScope.asyncTryHasContinue ?? catchScope?.asyncTryHasContinue; + + // Build result in output order: flag declarations, awaiter, chain calls, post-checks + const result: lua.Statement[] = []; + + if (hasReturn || hasBreak || hasContinue !== undefined) { + const flagDecls: lua.Identifier[] = []; + if (hasReturn) { + flagDecls.push(lua.createIdentifier("____hasReturned")); + flagDecls.push(lua.createIdentifier("____returnValue")); + } + if (hasBreak) { + flagDecls.push(lua.createIdentifier("____hasBroken")); + } + if (hasContinue !== undefined) { + flagDecls.push(lua.createIdentifier("____hasContinued")); + } + result.push(lua.createVariableDeclarationStatement(flagDecls)); + } + + result.push(awaiterDefinition); + result.push(...chainCalls); + + if (hasReturn) { + result.push( + lua.createIfStatement( + lua.createIdentifier("____hasReturned"), + lua.createBlock([createReturnStatement(context, [lua.createIdentifier("____returnValue")], statement)]) + ) + ); + } + + if (hasBreak) { + result.push( + lua.createIfStatement(lua.createIdentifier("____hasBroken"), lua.createBlock([lua.createBreakStatement()])) + ); + } + + if (hasContinue !== undefined) { + const loopScope = findScope(context, ScopeType.Loop); + const label = `__continue${loopScope?.id ?? ""}`; + + const continueStatements: lua.Statement[] = []; + switch (hasContinue) { + case LoopContinued.WithGoto: + continueStatements.push(lua.createGotoStatement(label)); + break; + case LoopContinued.WithContinue: + continueStatements.push(lua.createContinueStatement()); + break; + case LoopContinued.WithRepeatBreak: + continueStatements.push( + lua.createAssignmentStatement(lua.createIdentifier(label), lua.createBooleanLiteral(true)) + ); + continueStatements.push(lua.createBreakStatement()); + break; + } + + result.push( + lua.createIfStatement(lua.createIdentifier("____hasContinued"), lua.createBlock(continueStatements)) + ); } return result; diff --git a/src/transformation/visitors/return.ts b/src/transformation/visitors/return.ts index 14d785166..3a61314ff 100644 --- a/src/transformation/visitors/return.ts +++ b/src/transformation/visitors/return.ts @@ -3,7 +3,7 @@ import * as lua from "../../LuaAST"; import { FunctionVisitor, TransformationContext } from "../context"; import { validateAssignment } from "../utils/assignment-validation"; import { createUnpackCall, wrapInTable } from "../utils/lua-ast"; -import { ScopeType, walkScopesUp } from "../utils/scope"; +import { findAsyncTryScopeInStack, ScopeType, walkScopesUp } from "../utils/scope"; import { transformArguments } from "./call"; import { returnsMultiType, @@ -16,11 +16,7 @@ import { import { invalidMultiFunctionReturnType } from "../utils/diagnostics"; import { isInAsyncFunction } from "../utils/typescript"; -function transformExpressionsInReturn( - context: TransformationContext, - node: ts.Expression, - insideTryCatch: boolean -): lua.Expression[] { +function transformExpressionsInReturn(context: TransformationContext, node: ts.Expression): lua.Expression[] { const expressionType = context.checker.getTypeAtLocation(node); // skip type assertions @@ -36,20 +32,7 @@ function transformExpressionsInReturn( context.diagnostics.push(invalidMultiFunctionReturnType(innerNode)); } - let returnValues = transformArguments(context, innerNode.arguments); - if (insideTryCatch) { - returnValues = [wrapInTable(...returnValues)]; // Wrap results when returning inside try/catch - } - return returnValues; - } - - // Force-wrap LuaMultiReturn when returning inside try/catch - if ( - insideTryCatch && - returnsMultiType(context, innerNode) && - !shouldMultiReturnCallBeWrapped(context, innerNode) - ) { - return [wrapInTable(context.transformExpression(node))]; + return transformArguments(context, innerNode.arguments); } } else if (isInMultiReturnFunction(context, innerNode) && isMultiReturnType(expressionType)) { // Unpack objects typed as LuaMultiReturn @@ -63,12 +46,32 @@ export function transformExpressionBodyToReturnStatement( context: TransformationContext, node: ts.Expression ): lua.Statement { - const expressions = transformExpressionsInReturn(context, node, false); + const expressions = transformExpressionsInReturn(context, node); return createReturnStatement(context, expressions, node); } +function transformReturnExpressionForTryCatch(context: TransformationContext, node: ts.Expression): lua.Expression { + const innerNode = ts.skipOuterExpressions(node, ts.OuterExpressionKinds.Assertions); + + if (ts.isCallExpression(innerNode)) { + if (isMultiFunctionCall(context, innerNode)) { + const type = context.checker.getContextualType(node); + if (type && !canBeMultiReturnType(type)) { + context.diagnostics.push(invalidMultiFunctionReturnType(innerNode)); + } + return wrapInTable(...transformArguments(context, innerNode.arguments)); + } + + if (returnsMultiType(context, innerNode) && !shouldMultiReturnCallBeWrapped(context, innerNode)) { + return wrapInTable(context.transformExpression(node)); + } + } + + return context.transformExpression(node); +} + export const transformReturnStatement: FunctionVisitor = (statement, context) => { - let results: lua.Expression[]; + const asyncTryScope = isInAsyncFunction(statement) ? findAsyncTryScopeInStack(context) : undefined; if (statement.expression) { const expressionType = context.checker.getTypeAtLocation(statement.expression); @@ -76,11 +79,32 @@ export const transformReturnStatement: FunctionVisitor = (st if (returnType) { validateAssignment(context, statement, expressionType, returnType); } + } - results = transformExpressionsInReturn(context, statement.expression, isInTryCatch(context)); - } else { - // Empty return + if (asyncTryScope) { + asyncTryScope.asyncTryHasReturn = true; + const stmts: lua.Statement[] = [ + lua.createAssignmentStatement( + lua.createIdentifier("____hasReturned"), + lua.createBooleanLiteral(true), + statement + ), + ]; + if (statement.expression) { + const returnValue = transformReturnExpressionForTryCatch(context, statement.expression); + stmts.push(lua.createAssignmentStatement(lua.createIdentifier("____returnValue"), returnValue, statement)); + } + stmts.push(lua.createReturnStatement([], statement)); + return stmts; + } + + let results: lua.Expression[]; + if (!statement.expression) { results = []; + } else if (isInTryCatch(context)) { + results = [transformReturnExpressionForTryCatch(context, statement.expression)]; + } else { + results = transformExpressionsInReturn(context, statement.expression); } return createReturnStatement(context, results, statement); diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 45adb4518..7a511d7b1 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -815,4 +815,196 @@ describe("try/catch in async function", () => { }, }); }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + test("return inside try with deferred promise (#1706)", () => { + util.testFunction` + let resolveLater!: (value: string) => void; + + function deferredPromise(): Promise { + return new Promise(resolve => { + resolveLater = (v) => resolve(v); + }); + } + + async function fn(): Promise { + try { + return await deferredPromise(); + } catch { + return 'caught'; + } + log('unreachable!'); + } + + const promise = fn(); + resolveLater('ok'); + promise.then(v => log(v)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["ok"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + test("return inside try in loop with deferred promise (#1706)", () => { + util.testFunction` + let resolveLater!: (value: string) => void; + + function deferredPromise(): Promise { + return new Promise(resolve => { + resolveLater = (v) => resolve(v); + }); + } + + async function fn(): Promise { + while (true) { + try { + return await deferredPromise(); + } catch { + return 'caught'; + } + log('unreachable!'); + } + } + + const promise = fn(); + resolveLater('ok'); + promise.then(v => log(v)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["ok"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + test("return from catch with deferred promise (#1706)", () => { + util.testFunction` + let rejectLater!: (reason: string) => void; + + function deferredPromise(): Promise { + return new Promise((_, reject) => { + rejectLater = (r) => reject(r); + }); + } + + async function fn(): Promise { + try { + return await deferredPromise(); + } catch (e) { + return 'caught: ' + e; + } + log('unreachable!'); + } + + const promise = fn(); + rejectLater('oops'); + promise.then(v => log(v)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["caught: oops"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + util.testEachVersion( + "break inside try in async loop (#1706)", + () => util.testModule` + export let result = "not set"; + async function fn(): Promise { + while (true) { + try { + await Promise.resolve(); + break; + } catch {} + } + result = "done"; + } + fn(); + `, + { + ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ result: "done" })), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), + [LuaTarget.Lua51]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), + } + ); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + util.testEachVersion( + "continue inside try in async loop (#1706)", + () => util.testModule` + export const results: number[] = []; + async function fn(): Promise { + for (let i = 0; i < 3; i++) { + try { + await Promise.resolve(); + if (i === 1) continue; + } catch {} + results.push(i); + } + } + fn(); + `, + { + ...util.expectEachVersionExceptJit(builder => builder.expectToEqual({ results: [0, 2] })), + [LuaTarget.Lua50]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), + [LuaTarget.Lua51]: builder => + builder.expectToHaveDiagnostics([unsupportedForTargetButOverrideAvailable.code]), + } + ); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + test("multi return from try in async function (#1706)", () => { + util.testFunction` + async function fn(): Promise> { + try { + await Promise.resolve(); + return $multi("foo", "bar"); + } catch { + return $multi("err", "err"); + } + } + + let result: string[] = []; + fn().then(v => { const [a, b] = v; result = [a, b]; }); + + return result; + ` + .withLanguageExtensions() + .expectToEqual(["foo", "bar"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 + test("return inside try with finally (#1706)", () => { + util.testFunction` + let resolveLater!: (value: string) => void; + + function deferredPromise(): Promise { + return new Promise(resolve => { + resolveLater = (v) => resolve(v); + }); + } + + async function fn(): Promise { + try { + return await deferredPromise(); + } finally { + log('finally'); + } + } + + const promise = fn(); + resolveLater('ok'); + promise.then(v => log(v)); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally", "ok"]); + }); }); From 2fc2e99680aada83ac3524166197760696ec08d2 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 17 Apr 2026 05:17:41 +0900 Subject: [PATCH 748/764] fix dots in file/directory names breaking Lua require resolution (#1445) (#1702) * fix dots in file/directory names breaking Lua require resolution (#1445) Lua's require() uses dots as path separators, so a file at Foo.Bar/index.lua is unreachable via require("Foo.Bar.index") since Lua looks for Foo/Bar/index.lua. Expand dotted path segments into nested directories in the emit output, and emit a diagnostic when this expansion causes output path collisions. * replace dots with underscores in output paths instead of expanding to nested directories * more tests --- src/transpilation/diagnostics.ts | 6 ++++ src/transpilation/transpiler.ts | 26 +++++++++++---- test/unit/modules/resolution.spec.ts | 49 +++++++++++++++++++++++++++- test/util.ts | 3 +- 4 files changed, 76 insertions(+), 8 deletions(-) diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index 348542ac5..b7282f0f2 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -59,3 +59,9 @@ export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only sup export const pathsWithoutBaseUrl = createDiagnosticFactory( () => "When configuring 'paths' in tsconfig.json, the option 'baseUrl' must also be provided." ); + +export const emitPathCollision = createDiagnosticFactory( + (outputPath: string, file1: string, file2: string) => + `Output path '${outputPath}' is used by both '${file1}' and '${file2}'. ` + + `Dots in file/directory names are replaced with underscores for Lua module resolution.` +); diff --git a/src/transpilation/transpiler.ts b/src/transpilation/transpiler.ts index 9bac1f5bf..7f79af35d 100644 --- a/src/transpilation/transpiler.ts +++ b/src/transpilation/transpiler.ts @@ -4,6 +4,7 @@ import { CompilerOptions, isBundleEnabled, LuaLibImportKind, LuaTarget } from ". import { buildMinimalLualibBundle, findUsedLualibFeatures, getLuaLibBundle } from "../LuaLib"; import { normalizeSlashes, trimExtension } from "../utils"; import { getBundleResult } from "./bundle"; +import { emitPathCollision } from "./diagnostics"; import { getPlugins, Plugin } from "./plugins"; import { resolveDependencies } from "./resolve"; import { getProgramTranspileResult, TranspileOptions } from "./transpile"; @@ -143,10 +144,17 @@ export class Transpiler { diagnostics.push(...bundleDiagnostics); emitPlan = [bundleFile]; } else { - emitPlan = resolutionResult.resolvedFiles.map(file => ({ - ...file, - outputPath: getEmitPath(file.fileName, program), - })); + const outputPathMap = new Map(); + emitPlan = resolutionResult.resolvedFiles.map(file => { + const outputPath = getEmitPath(file.fileName, program); + const existing = outputPathMap.get(outputPath); + if (existing) { + diagnostics.push(emitPathCollision(outputPath, existing, file.fileName)); + } else { + outputPathMap.set(outputPath, file.fileName); + } + return { ...file, outputPath }; + }); } performance.endSection("getEmitPlan"); @@ -189,11 +197,17 @@ export function getEmitPathRelativeToOutDir(fileName: string, program: ts.Progra emitPathSplits[0] = "lua_modules"; } + // Replace dots with underscores in path segments so that Lua's require() + // resolves correctly. Dots are path separators in Lua's module system, so + // "Foo.Bar/index.lua" would be unreachable via require("Foo.Bar.index") + // since Lua interprets it as "Foo/Bar/index.lua". + emitPathSplits[emitPathSplits.length - 1] = trimExtension(emitPathSplits[emitPathSplits.length - 1]); + emitPathSplits = emitPathSplits.map(segment => segment.replace(/\./g, "_")); + // Set extension const extension = ((program.getCompilerOptions() as CompilerOptions).extension ?? "lua").trim(); const trimmedExtension = extension.startsWith(".") ? extension.substring(1) : extension; - emitPathSplits[emitPathSplits.length - 1] = - trimExtension(emitPathSplits[emitPathSplits.length - 1]) + "." + trimmedExtension; + emitPathSplits[emitPathSplits.length - 1] += "." + trimmedExtension; return path.join(...emitPathSplits); } diff --git a/test/unit/modules/resolution.spec.ts b/test/unit/modules/resolution.spec.ts index 26c147c68..c6f97d5f9 100644 --- a/test/unit/modules/resolution.spec.ts +++ b/test/unit/modules/resolution.spec.ts @@ -1,5 +1,6 @@ +import * as path from "path"; import * as ts from "typescript"; -import { couldNotResolveRequire } from "../../../src/transpilation/diagnostics"; +import { couldNotResolveRequire, emitPathCollision } from "../../../src/transpilation/diagnostics"; import * as util from "../../util"; const requireRegex = /require\("(.*?)"\)/; @@ -166,6 +167,52 @@ test.each([ .tap(expectToRequire(expectedPath)); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1445 +// Can't test this via execution because the test harness uses package.preload +// instead of real filesystem resolution, so require() always finds the module +// regardless of output path. We check the output path directly instead. +test("dots in directory names are replaced with underscores in output", () => { + const { transpiledFiles } = util.testModule` + import { answer } from "./Foo.Bar"; + export const result = answer; + ` + .addExtraFile("Foo.Bar/index.ts", "export const answer = 42;") + .setOptions({ rootDir: "." }) + .getLuaResult(); + + const dottedFile = transpiledFiles.find(f => f.lua?.includes("answer = 42")); + expect(dottedFile).toBeDefined(); + expect(dottedFile!.outPath).toContain(path.join("Foo_Bar", "index.lua")); + expect(dottedFile!.outPath).not.toContain("Foo.Bar"); +}); + +test("dots in file names are replaced with underscores in output", () => { + const { transpiledFiles } = util.testModule` + import { answer } from "./foo.test"; + export const result = answer; + ` + .addExtraFile("foo.test.ts", "export const answer = 42;") + .setOptions({ rootDir: "." }) + .getLuaResult(); + + const dottedFile = transpiledFiles.find(f => f.lua?.includes("answer = 42")); + expect(dottedFile).toBeDefined(); + expect(dottedFile!.outPath).toContain("foo_test.lua"); + expect(dottedFile!.outPath).not.toContain("foo.test"); +}); + +test("dots in paths that collide with existing paths produce a diagnostic", () => { + util.testModule` + import { a } from "./Foo.Bar"; + import { b } from "./Foo_Bar"; + export const result = a + b; + ` + .addExtraFile("Foo.Bar/index.ts", "export const a = 1;") + .addExtraFile("Foo_Bar/index.ts", "export const b = 2;") + .setOptions({ rootDir: "." }) + .expectToHaveDiagnostics([emitPathCollision.code]); +}); + test("import = require", () => { util.testModule` import foo = require("./foo/bar"); diff --git a/test/util.ts b/test/util.ts index 2871f6e5a..8c5e69f8f 100644 --- a/test/util.ts +++ b/test/util.ts @@ -534,8 +534,9 @@ end)());`; const moduleExports = {}; globalContext.exports = moduleExports; globalContext.module = { exports: moduleExports }; + const baseName = fileName.replace("./", ""); const transpiledExtraFile = transpiledFiles.find(({ sourceFiles }) => - sourceFiles.some(f => f.fileName === fileName.replace("./", "") + ".ts") + sourceFiles.some(f => f.fileName === baseName + ".ts" || f.fileName === baseName + "/index.ts") ); if (transpiledExtraFile?.js) { From 3d14be87bb9c87c0f820b76938e09391bec67d8a Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sat, 18 Apr 2026 21:28:54 +0900 Subject: [PATCH 749/764] fix await inside catch/finally in async try (#1659) (#1709) * fix await inside catch/finally in async try * add test for awaited return value from catch in async try --- src/transformation/visitors/errors.ts | 45 ++++++---- test/unit/builtins/async-await.spec.ts | 114 +++++++++++++++++++++++++ 2 files changed, 141 insertions(+), 18 deletions(-) diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index cc73b2ac0..77067dda8 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -40,35 +40,44 @@ const transformAsyncTry: FunctionVisitor = (statement, context) let catchScope: Scope | undefined; const chainCalls: lua.Statement[] = []; - if (statement.finallyBlock) { - const awaiterFinally = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("finally")); - const finallyFunction = lua.createFunctionExpression( - lua.createBlock(context.transformStatements(statement.finallyBlock.statements)) - ); - const finallyCall = lua.createCallExpression( - awaiterFinally, - [awaiterIdentifier, finallyFunction], - statement.finallyBlock - ); - chainCalls.push(lua.createExpressionStatement(finallyCall)); - } - if (statement.catchClause) { + // ____try = ____try.catch() const [catchFunction, cScope] = transformCatchClause(context, statement.catchClause); catchScope = cScope; if (catchFunction.params) { catchFunction.params.unshift(lua.createAnonymousIdentifier()); } + const catchBodyStatements = catchFunction.body ? catchFunction.body.statements : []; + const asyncWrappedCatch = wrapInAsyncAwaiter(context, [...catchBodyStatements], false); + catchFunction.body = lua.createBlock([lua.createReturnStatement([asyncWrappedCatch])]); + const awaiterCatch = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("catch")); const catchCall = lua.createCallExpression(awaiterCatch, [awaiterIdentifier, catchFunction]); - const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, catchCall); - chainCalls.push(lua.createExpressionStatement(promiseAwait, statement)); - } else { - const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, awaiterIdentifier); - chainCalls.push(lua.createExpressionStatement(promiseAwait, statement)); + chainCalls.push(lua.createAssignmentStatement(lua.cloneIdentifier(awaiterIdentifier), catchCall)); } + if (statement.finallyBlock) { + // ____try = ____try.finally() + const finallyStatements = context.transformStatements(statement.finallyBlock.statements); + const asyncWrappedFinally = wrapInAsyncAwaiter(context, finallyStatements, false); + const finallyFunction = lua.createFunctionExpression( + lua.createBlock([lua.createReturnStatement([asyncWrappedFinally])]) + ); + + const awaiterFinally = lua.createTableIndexExpression(awaiterIdentifier, lua.createStringLiteral("finally")); + const finallyCall = lua.createCallExpression( + awaiterFinally, + [awaiterIdentifier, finallyFunction], + statement.finallyBlock + ); + chainCalls.push(lua.createAssignmentStatement(lua.cloneIdentifier(awaiterIdentifier), finallyCall)); + } + + // __TS__Await(____try) + const promiseAwait = transformLuaLibFunction(context, LuaLibFeature.Await, statement, awaiterIdentifier); + chainCalls.push(lua.createExpressionStatement(promiseAwait, statement)); + const hasReturn = tryScope.asyncTryHasReturn ?? catchScope?.asyncTryHasReturn; const hasBreak = tryScope.asyncTryHasBreak ?? catchScope?.asyncTryHasBreak; const hasContinue = tryScope.asyncTryHasContinue ?? catchScope?.asyncTryHasContinue; diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 7a511d7b1..546589355 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -816,6 +816,120 @@ describe("try/catch in async function", () => { }); }); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1659 + test("await inside catch handler resolves correctly (#1659)", () => { + util.testFunction` + let reject: (reason: string) => void = () => {}; + + async function failing() { + return new Promise((_, rej) => { reject = rej; }); + } + + async function run() { + try { + await failing(); + } catch (e) { + log("catch"); + const a = await Promise.resolve(true); + log("a", a); + } + } + + run(); + reject("error"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch", "a", true]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1659 + test("await inside finally handler resolves correctly (#1659)", () => { + util.testFunction` + let reject: (reason: string) => void = () => {}; + + async function failing() { + return new Promise((_, rej) => { reject = rej; }); + } + + async function run() { + try { + await failing(); + } finally { + log("finally"); + const a = await Promise.resolve(true); + log("a", a); + } + } + + run().catch(() => {}); + reject("error"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["finally", "a", true]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1659 + test("await inside both catch and finally handlers (#1659)", () => { + util.testFunction` + let reject: (reason: string) => void = () => {}; + + async function failing() { + return new Promise((_, rej) => { reject = rej; }); + } + + async function run() { + try { + await failing(); + } catch (e) { + log("catch"); + const a = await Promise.resolve("caught"); + log("a", a); + } finally { + log("finally"); + const b = await Promise.resolve("done"); + log("b", b); + } + } + + run(); + reject("error"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["catch", "a", "caught", "finally", "b", "done"]); + }); + + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1659 + test("awaited value in catch is returned from async function (#1659)", () => { + util.testFunction` + const failing = defer(); + const recovery = defer(); + + async function run() { + try { + await failing.promise; + return "succeeded"; + } catch (e) { + return await recovery.promise; + } + } + + run().then(value => log("result", value)); + + failing.reject("error"); + recovery.resolve("recovered"); + + return allLogs; + ` + .setTsHeader(promiseTestLib) + .expectToEqual(["result", "recovered"]); + }); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1706 test("return inside try with deferred promise (#1706)", () => { util.testFunction` From 843544dbf9e3b1a6780efbb626e5e6669a5be9a2 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sat, 18 Apr 2026 21:35:07 +0900 Subject: [PATCH 750/764] apply pilaoda's fix (#1711) --- src/transformation/utils/typescript/index.ts | 6 ++++-- test/unit/using.spec.ts | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/typescript/index.ts b/src/transformation/utils/typescript/index.ts index e5984b08f..f12bf4721 100644 --- a/src/transformation/utils/typescript/index.ts +++ b/src/transformation/utils/typescript/index.ts @@ -14,12 +14,14 @@ export function hasExportEquals(sourceFile: ts.SourceFile): boolean { * Search up until finding a node satisfying the callback */ export function findFirstNodeAbove(node: ts.Node, callback: (n: ts.Node) => n is T): T | undefined { - let current = node; + // Synthetic nodes (created by pre-transformers like usingTransformer) may have an unset .parent. + // Fall back to ts.getOriginalNode so we can still walk the source-parsed parent chain. + let current = ts.getOriginalNode(node); while (current.parent) { if (callback(current.parent)) { return current.parent; } else { - current = current.parent; + current = ts.getOriginalNode(current.parent); } } } diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts index bfe5312b0..60364f680 100644 --- a/test/unit/using.spec.ts +++ b/test/unit/using.spec.ts @@ -194,6 +194,26 @@ test("await using no extra diagnostics (#1571)", () => { `.expectToHaveNoDiagnostics(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1622 +test("await-using with nested async arrow that also has await-using (runtime divergence)", () => { + util.testFunction` + const logs: any[] = []; + async function getA(): Promise { + return { [Symbol.asyncDispose]: async () => {} }; + } + async function outer(): Promise { + await using a = await getA(); + const inner = async (): Promise => { + await using b = await getA(); + return 42; + }; + return inner(); + } + outer().then(v => logs.push(v)); + return logs; + `.expectToEqual([42]); +}); + // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1584 test("works with disposable classes (#1584)", () => { util.testFunction` From 591989b646e3cd459c45061f92df47679a6ac66d Mon Sep 17 00:00:00 2001 From: Perry van Wesel Date: Tue, 21 Apr 2026 22:02:57 +0200 Subject: [PATCH 751/764] Upgrade to TypeScript 6.0 (#1704) * Upgarde to TypeScript 6.0 * fix module-resolution tests * fix array tests except splice * fix more tests * update deps to ts6 support * fix more tests * updated snapshots * fix more tests * fix optional chaining tests * only module-resolution test failing * revert utils * fix last test * remove debug code from module-resolution.spec.ts * update benchmark to nodenext module --- benchmark/tsconfig.json | 3 +- package-lock.json | 729 ++++++++---------- package.json | 16 +- src/CompilerOptions.ts | 4 - src/transformation/utils/function-context.ts | 4 +- .../visitors/variable-declaration.ts | 2 +- src/transpilation/diagnostics.ts | 4 - src/transpilation/resolve.ts | 24 +- src/utils.ts | 2 +- test/setup.ts | 2 +- .../module-resolution.spec.ts.snap | 2 +- test/transpile/module-resolution.spec.ts | 8 +- .../paths-base-tsconfig/tsconfig.base.json | 1 + .../paths-simple/myprogram/tsconfig.json | 2 +- .../project-with-node-modules/tsconfig.json | 3 +- test/transpile/transformers/fixtures.ts | 2 +- .../__snapshots__/identifiers.spec.ts.snap | 8 +- test/unit/__snapshots__/loops.spec.ts.snap | 2 +- .../annotations/customConstructor.spec.ts | 4 +- test/unit/assignments.spec.ts | 6 +- test/unit/builtins/array.spec.ts | 41 +- test/unit/builtins/async-await.spec.ts | 9 +- test/unit/builtins/map.spec.ts | 2 +- test/unit/builtins/object.spec.ts | 8 +- test/unit/builtins/set.spec.ts | 2 +- test/unit/builtins/string.spec.ts | 2 +- test/unit/builtins/weakMap.spec.ts | 2 +- test/unit/classes/classes.spec.ts | 2 +- test/unit/classes/decorators.spec.ts | 86 +-- test/unit/conditionals.spec.ts | 2 +- test/unit/destructuring.spec.ts | 64 +- test/unit/enum.spec.ts | 2 +- test/unit/error.spec.ts | 6 +- .../unit/functions/functionProperties.spec.ts | 6 +- test/unit/functions/functions.spec.ts | 37 +- test/unit/functions/generators.spec.ts | 2 +- .../invalidFunctionAssignments.spec.ts.snap | 96 +-- .../functionExpressionTypeInference.spec.ts | 2 +- .../validation/functionPermutations.ts | 16 +- .../invalidFunctionAssignments.spec.ts | 8 +- test/unit/hoisting.spec.ts | 2 +- test/unit/identifiers.spec.ts | 3 +- .../__snapshots__/multi.spec.ts.snap | 42 +- test/unit/language-extensions/multi.spec.ts | 13 +- test/unit/loops.spec.ts | 6 +- test/unit/modules/modules.spec.ts | 3 +- test/unit/namespaces.spec.ts | 12 +- test/unit/optionalChaining.spec.ts | 45 +- test/unit/overloads.spec.ts | 8 +- test/unit/precedingStatements.spec.ts | 11 +- test/unit/spread.spec.ts | 4 +- test/unit/switch.spec.ts | 2 +- test/unit/using.spec.ts | 6 +- test/util.ts | 12 +- tsconfig.json | 1 - 55 files changed, 668 insertions(+), 725 deletions(-) diff --git a/benchmark/tsconfig.json b/benchmark/tsconfig.json index e1c9c2941..5422f1770 100644 --- a/benchmark/tsconfig.json +++ b/benchmark/tsconfig.json @@ -4,7 +4,8 @@ "lib": ["esnext"], // Dev types are JIT "types": ["lua-types/jit", "@typescript-to-lua/language-extensions"], - "moduleResolution": "node", + "module": "nodenext", + "moduleResolution": "nodenext", "outDir": "dist", "rootDir": "src", "strict": true, diff --git a/package-lock.json b/package-lock.json index 1b482b466..760133928 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,25 +25,25 @@ "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^9.22.0", - "eslint-plugin-jest": "^28.8.3", + "eslint": "^9.39.4", + "eslint-plugin-jest": "^28.14.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^29.5.0", + "jest": "^29.7.0", "jest-circus": "^29.7.0", "lua-types": "^2.14.1", "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", - "ts-jest": "^29.2.5", + "ts-jest": "^29.4.9", "ts-node": "^10.9.2", - "typescript": "5.9.3", - "typescript-eslint": "^8.46.3" + "typescript": "6.0.2", + "typescript-eslint": "^8.58.0" }, "engines": { "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.9.3" + "typescript": "6.0.2" } }, "node_modules/@ampproject/remapping": { @@ -616,9 +616,9 @@ } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -648,24 +648,25 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, + "license": "MIT", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -698,20 +699,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz", + "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -722,9 +723,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz", + "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==", "dev": true, "license": "MIT", "engines": { @@ -1317,44 +1318,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/@sinclair/typebox": { "version": "0.27.8", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", @@ -1602,22 +1565,21 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz", - "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.0.tgz", + "integrity": "sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.46.3", - "@typescript-eslint/type-utils": "8.46.3", - "@typescript-eslint/utils": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/type-utils": "8.58.0", + "@typescript-eslint/utils": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1627,9 +1589,9 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.46.3", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "@typescript-eslint/parser": "^8.58.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { @@ -1643,18 +1605,18 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", - "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.0.tgz", + "integrity": "sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA==", "dev": true, "license": "MIT", "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.46.3", - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/typescript-estree": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1664,20 +1626,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", - "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.0.tgz", + "integrity": "sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.46.3", - "@typescript-eslint/types": "^8.46.3", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.58.0", + "@typescript-eslint/types": "^8.58.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1687,18 +1649,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", - "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.0.tgz", + "integrity": "sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3" + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1709,9 +1671,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", - "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.0.tgz", + "integrity": "sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A==", "dev": true, "license": "MIT", "engines": { @@ -1722,21 +1684,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.3.tgz", - "integrity": "sha512-ZPCADbr+qfz3aiTTYNNkCbUt+cjNwI/5McyANNrFBpVxPt7GqpEYz5ZfdwuFyGUnJ9FdDXbGODUu6iRCI6XRXw==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.0.tgz", + "integrity": "sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/typescript-estree": "8.46.3", - "@typescript-eslint/utils": "8.46.3", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/utils": "8.58.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1746,14 +1708,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", - "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.0.tgz", + "integrity": "sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww==", "dev": true, "license": "MIT", "engines": { @@ -1765,22 +1727,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", - "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.0.tgz", + "integrity": "sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.46.3", - "@typescript-eslint/tsconfig-utils": "8.46.3", - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/visitor-keys": "8.46.3", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.58.0", + "@typescript-eslint/tsconfig-utils": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/visitor-keys": "8.58.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1790,46 +1751,59 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", + "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.3.tgz", - "integrity": "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.0.tgz", + "integrity": "sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.46.3", - "@typescript-eslint/types": "8.46.3", - "@typescript-eslint/typescript-estree": "8.46.3" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.58.0", + "@typescript-eslint/types": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1839,19 +1813,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", - "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.0.tgz", + "integrity": "sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.46.3", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.58.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1861,6 +1835,19 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-to-lua/language-extensions": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/@typescript-to-lua/language-extensions/-/language-extensions-1.19.0.tgz", @@ -1905,9 +1892,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "dev": true, "license": "MIT", "dependencies": { @@ -1991,13 +1978,6 @@ "dev": true, "license": "Python-2.0" }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -2132,9 +2112,9 @@ "license": "MIT" }, "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", "dev": true, "license": "MIT", "dependencies": { @@ -2421,9 +2401,9 @@ } }, "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -2500,22 +2480,6 @@ "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/electron-to-chromium": { "version": "1.5.27", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.27.tgz", @@ -2590,26 +2554,26 @@ } }, "node_modules/eslint": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", - "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "version": "9.39.4", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz", + "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==", "dev": true, "license": "MIT", "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", + "@eslint/config-array": "^0.21.2", "@eslint/config-helpers": "^0.4.2", "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.1", + "@eslint/eslintrc": "^3.3.5", + "@eslint/js": "9.39.4", "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -2628,7 +2592,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -2651,9 +2615,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "28.8.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.8.3.tgz", - "integrity": "sha512-HIQ3t9hASLKm2IhIOqnu+ifw7uLZkIlR7RYNv7fMcEi/p0CIiJmfriStQS2LDkgtY4nyLbIZAD+JL347Yc2ETQ==", + "version": "28.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.14.0.tgz", + "integrity": "sha512-P9s/qXSMTpRTerE2FQ0qJet2gKbcGyFTPAJipoKxmWqR6uuFqIqk8FuEfg5yBieOezVrEfAMZrEwJ6yEp+1MFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2918,36 +2882,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2962,16 +2896,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -2995,39 +2919,6 @@ "node": ">=16.0.0" } }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -3073,9 +2964,9 @@ } }, "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -3222,12 +3113,37 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } }, "node_modules/has-flag": { "version": "4.0.0", @@ -3520,25 +3436,6 @@ "node": ">=8" } }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -3594,6 +3491,7 @@ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", @@ -4711,16 +4609,6 @@ "dev": true, "license": "MIT" }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -4758,6 +4646,16 @@ "node": "*" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4772,6 +4670,13 @@ "dev": true, "license": "MIT" }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -4971,9 +4876,9 @@ "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", "license": "MIT", "engines": { "node": ">=8.6" @@ -5156,27 +5061,6 @@ ], "license": "MIT" }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", @@ -5254,45 +5138,10 @@ "node": ">=10" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", "bin": { @@ -5533,6 +5382,55 @@ "node": ">=8" } }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -5554,9 +5452,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -5567,19 +5465,20 @@ } }, "node_modules/ts-jest": { - "version": "29.2.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", - "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", + "version": "29.4.9", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.9.tgz", + "integrity": "sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==", "dev": true, + "license": "MIT", "dependencies": { "bs-logger": "^0.2.6", - "ejs": "^3.1.10", "fast-json-stable-stringify": "^2.1.0", - "jest-util": "^29.0.0", + "handlebars": "^4.7.9", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.6.3", + "semver": "^7.7.4", + "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "bin": { @@ -5590,11 +5489,12 @@ }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", - "@jest/transform": "^29.0.0", - "@jest/types": "^29.0.0", - "babel-jest": "^29.0.0", - "jest": "^29.0.0", - "typescript": ">=4.3 <6" + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <7" }, "peerDependenciesMeta": { "@babel/core": { @@ -5611,9 +5511,25 @@ }, "esbuild": { "optional": true + }, + "jest-util": { + "optional": true } } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", @@ -5695,9 +5611,9 @@ } }, "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.2.tgz", + "integrity": "sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==", "dev": true, "license": "Apache-2.0", "peer": true, @@ -5710,16 +5626,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.46.3", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.3.tgz", - "integrity": "sha512-bAfgMavTuGo+8n6/QQDVQz4tZ4f7Soqg53RbrlZQEoAltYop/XR4RAts/I0BrO3TTClTSTFJ0wYbla+P8cEWJA==", + "version": "8.58.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.0.tgz", + "integrity": "sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.46.3", - "@typescript-eslint/parser": "8.46.3", - "@typescript-eslint/typescript-estree": "8.46.3", - "@typescript-eslint/utils": "8.46.3" + "@typescript-eslint/eslint-plugin": "8.58.0", + "@typescript-eslint/parser": "8.58.0", + "@typescript-eslint/typescript-estree": "8.58.0", + "@typescript-eslint/utils": "8.58.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -5729,8 +5645,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" } }, "node_modules/undici-types": { @@ -5848,6 +5778,13 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, "node_modules/wrap-ansi": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", diff --git a/package.json b/package.json index fe6771138..412c08da7 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,7 @@ "lint:prettier": "prettier --check . || (echo 'Run `npm run fix:prettier` to fix it.' && exit 1)", "lint:eslint": "eslint .", "fix:prettier": "prettier --write .", - "check:language-extensions": "tsc --strict language-extensions/index.d.ts", + "check:language-extensions": "tsc --strict --ignoreConfig language-extensions/index.d.ts", "preversion": "npm run build && npm test", "postversion": "git push && git push --tags" }, @@ -42,7 +42,7 @@ "node": ">=16.10.0" }, "peerDependencies": { - "typescript": "5.9.3" + "typescript": "6.0.2" }, "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", @@ -58,18 +58,18 @@ "@types/node": "^22.10.0", "@types/picomatch": "^2.3.0", "@types/resolve": "1.14.0", - "eslint": "^9.22.0", - "eslint-plugin-jest": "^28.8.3", + "eslint": "^9.39.4", + "eslint-plugin-jest": "^28.14.0", "fs-extra": "^8.1.0", "javascript-stringify": "^2.0.1", - "jest": "^29.5.0", + "jest": "^29.7.0", "jest-circus": "^29.7.0", "lua-types": "^2.14.1", "lua-wasm-bindings": "^0.5.3", "prettier": "^2.8.8", - "ts-jest": "^29.2.5", + "ts-jest": "^29.4.9", "ts-node": "^10.9.2", - "typescript": "5.9.3", - "typescript-eslint": "^8.46.3" + "typescript": "6.0.2", + "typescript-eslint": "^8.58.0" } } diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 47ada916e..1a167e7c3 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -99,9 +99,5 @@ export function validateOptions(options: CompilerOptions): ts.Diagnostic[] { diagnostics.push(diagnosticFactories.unsupportedJsxEmit()); } - if (options.paths && !options.baseUrl) { - diagnostics.push(diagnosticFactories.pathsWithoutBaseUrl()); - } - return diagnostics; } diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index d61ffb5bf..e28950e2e 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -108,9 +108,7 @@ function computeDeclarationContextType(context: TransformationContext, signature const thisParameter = getExplicitThisParameter(signatureDeclaration); if (thisParameter) { // Explicit 'this' - return thisParameter.type && thisParameter.type.kind === ts.SyntaxKind.VoidKeyword - ? ContextType.Void - : ContextType.NonVoid; + return thisParameter.type?.kind === ts.SyntaxKind.VoidKeyword ? ContextType.Void : ContextType.NonVoid; } // noSelf declaration on function signature diff --git a/src/transformation/visitors/variable-declaration.ts b/src/transformation/visitors/variable-declaration.ts index 61d50cad4..9ed5ec553 100644 --- a/src/transformation/visitors/variable-declaration.ts +++ b/src/transformation/visitors/variable-declaration.ts @@ -62,7 +62,7 @@ export function transformBindingPattern( } // Build the path to the table - const tableExpression = propertyAccessStack.reduce( + const tableExpression = propertyAccessStack.reduce( (path, property) => lua.createTableIndexExpression(path, transformPropertyName(context, property)), table ); diff --git a/src/transpilation/diagnostics.ts b/src/transpilation/diagnostics.ts index b7282f0f2..1ee589708 100644 --- a/src/transpilation/diagnostics.ts +++ b/src/transpilation/diagnostics.ts @@ -56,10 +56,6 @@ export const cannotBundleLibrary = createDiagnosticFactory( export const unsupportedJsxEmit = createDiagnosticFactory(() => 'JSX is only supported with "react" jsx option.'); -export const pathsWithoutBaseUrl = createDiagnosticFactory( - () => "When configuring 'paths' in tsconfig.json, the option 'baseUrl' must also be provided." -); - export const emitPathCollision = createDiagnosticFactory( (outputPath: string, file1: string, file2: string) => `Output path '${outputPath}' is used by both '${file1}' and '${file2}'. ` + diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index bd16773e9..e011f4350 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -27,7 +27,7 @@ interface ResolutionResult { } class ResolutionContext { - private noResolvePaths: picomatch.Matcher[]; + private noResolvePaths: picomatch.Glob[]; public diagnostics: ts.Diagnostic[] = []; public resolvedFiles = new Map(); @@ -38,9 +38,7 @@ class ResolutionContext { private readonly emitHost: EmitHost, private readonly plugins: Plugin[] ) { - const unique = [...new Set(options.noResolvePaths)]; - const matchers = unique.map(x => picomatch(x)); - this.noResolvePaths = matchers; + this.noResolvePaths = [...new Set(options.noResolvePaths)]; } public addAndResolveDependencies(file: ProcessedFile): void { @@ -73,7 +71,7 @@ class ResolutionContext { return; } - if (this.noResolvePaths.find(isMatch => isMatch(required.requirePath))) { + if (this.noResolvePaths.find(glob => picomatch.isMatch(required.requirePath, glob))) { if (this.options.tstlVerbose) { console.log( `Skipping module resolution of ${required.requirePath} as it is in the tsconfig noResolvePaths.` @@ -215,14 +213,16 @@ class ResolutionContext { const fileFromPath = this.getFileFromPath(resolvedPath); if (fileFromPath) return fileFromPath; - if (this.options.paths && this.options.baseUrl) { + if (this.options.paths) { // If no file found yet and paths are present, try to find project file via paths mappings - const fileFromPaths = this.tryGetModuleNameFromPaths( - dependencyPath, - this.options.paths, - this.options.baseUrl - ); - if (fileFromPaths) return fileFromPaths; + // When baseUrl is not set, resolve paths relative to the tsconfig directory (TS 6.0+ behavior) + const pathsBase = + this.options.baseUrl ?? + (this.options.configFilePath ? path.dirname(this.options.configFilePath) : undefined); + if (pathsBase) { + const fileFromPaths = this.tryGetModuleNameFromPaths(dependencyPath, this.options.paths, pathsBase); + if (fileFromPaths) return fileFromPaths; + } } // Not a TS file in our project sources, use resolver to check if we can find dependency diff --git a/src/utils.ts b/src/utils.ts index b1877e368..70cdb2940 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -77,7 +77,7 @@ export function cast( } export function assert(value: any, message?: string | Error): asserts value { - nativeAssert(value, message); + nativeAssert.ok(value, message); } export function assertNever(_value: never): never { diff --git a/test/setup.ts b/test/setup.ts index e431d8519..704c59bed 100644 --- a/test/setup.ts +++ b/test/setup.ts @@ -13,7 +13,7 @@ declare global { expect.extend({ toHaveDiagnostics(diagnostics: ts.Diagnostic[], expected?: number[]): jest.CustomMatcherResult { - assert(Array.isArray(diagnostics)); + assert.ok(Array.isArray(diagnostics)); // @ts-ignore const matcherHint = this.utils.matcherHint("toHaveDiagnostics", undefined, "", this); diff --git a/test/transpile/__snapshots__/module-resolution.spec.ts.snap b/test/transpile/__snapshots__/module-resolution.spec.ts.snap index c9f0be298..e87569ded 100644 --- a/test/transpile/__snapshots__/module-resolution.spec.ts.snap +++ b/test/transpile/__snapshots__/module-resolution.spec.ts.snap @@ -10,8 +10,8 @@ exports[`supports complicated paths configuration 1`] = ` exports[`supports paths configuration 1`] = ` [ - "/paths-simple/myprogram/dist/main.lua", "/paths-simple/myprogram/dist/mypackage/bar.lua", "/paths-simple/myprogram/dist/mypackage/index.lua", + "/paths-simple/myprogram/dist/myprogram/main.lua", ] `; diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index ff29ac9b5..e6543df69 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -4,7 +4,6 @@ import * as util from "../util"; import * as ts from "typescript"; import { BuildMode } from "../../src"; import { normalizeSlashes } from "../../src/utils"; -import { pathsWithoutBaseUrl } from "../../src/transpilation/diagnostics"; describe("basic module resolution", () => { const projectPath = path.resolve(__dirname, "module-resolution", "project-with-node-modules"); @@ -457,6 +456,7 @@ describe("module resolution should not try to resolve modules in noResolvePaths" export const result = b.foo(); ` + .addExtraFile("preload.d.ts", `declare module "preload" {}`) .addExtraFile("preload.lua", 'package.preload["ignoreme"] = function() return nil end') .addExtraFile( "actualfile.ts", @@ -598,7 +598,7 @@ test("module resolution uses baseURL to resolve imported files", () => { return { baz = function() return "baz" end } ` ) - .setOptions({ baseUrl: "./myproject/mydeps" }) + .setOptions({ baseUrl: "./myproject/mydeps", ignoreDeprecations: "6.0" }) .expectToEqual({ fooResult: "foo", barResult: "bar", @@ -707,10 +707,6 @@ test("supports complicated paths configuration", () => { .expectToEqual({ foo: 314, bar: 271 }); }); -test("paths without baseUrl is error", () => { - util.testFunction``.setOptions({ paths: {} }).expectToHaveDiagnostics([pathsWithoutBaseUrl.code]); -}); - test("module resolution using plugin", () => { const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); diff --git a/test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json b/test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json index 3f961c78a..4d3934b0d 100644 --- a/test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json +++ b/test/transpile/module-resolution/paths-base-tsconfig/tsconfig.base.json @@ -2,6 +2,7 @@ "compilerOptions": { "rootDir": ".", "baseUrl": ".", + "ignoreDeprecations": "6.0", "paths": { "mypackage": ["packages/mypackage/src/index.ts"], "mypackage/*": ["packages/mypackage/src/*"] diff --git a/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json b/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json index f01271ac9..a21584fac 100644 --- a/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json +++ b/test/transpile/module-resolution/paths-simple/myprogram/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "baseUrl": ".", + "rootDir": "..", "outDir": "dist", "paths": { "myOtherPackage": ["../mypackage"], diff --git a/test/transpile/module-resolution/project-with-node-modules/tsconfig.json b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json index 935b64af6..faa93f0e3 100644 --- a/test/transpile/module-resolution/project-with-node-modules/tsconfig.json +++ b/test/transpile/module-resolution/project-with-node-modules/tsconfig.json @@ -7,6 +7,7 @@ "target": "esnext", "lib": ["esnext"], "types": [], - "rootDir": "." + "rootDir": ".", + "noUncheckedSideEffectImports": false } } diff --git a/test/transpile/transformers/fixtures.ts b/test/transpile/transformers/fixtures.ts index dff7667be..4bb890135 100644 --- a/test/transpile/transformers/fixtures.ts +++ b/test/transpile/transformers/fixtures.ts @@ -36,7 +36,7 @@ export const compilerOptions = (options: tstl.CompilerOptions): ts.TransformerFactory => context => file => { - assert(options.plugins?.length === 1); + assert.ok(options.plugins?.length === 1); return visitAndReplace(context, file, node => { if (!ts.isReturnStatement(node)) return; return ts.factory.updateReturnStatement(node, ts.factory.createTrue()); diff --git a/test/unit/__snapshots__/identifiers.spec.ts.snap b/test/unit/__snapshots__/identifiers.spec.ts.snap index b90b10398..cfd11a893 100644 --- a/test/unit/__snapshots__/identifiers.spec.ts.snap +++ b/test/unit/__snapshots__/identifiers.spec.ts.snap @@ -52,18 +52,14 @@ exports[`ambient identifier must be a valid lua identifier ("enum $$ {}"): code exports[`ambient identifier must be a valid lua identifier ("enum $$ {}"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier ("function $$();"): code 1`] = `"local ____ = _____24_24_24"`; +exports[`ambient identifier must be a valid lua identifier ("function $$(): void;"): code 1`] = `"local ____ = _____24_24_24"`; -exports[`ambient identifier must be a valid lua identifier ("function $$();"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; +exports[`ambient identifier must be a valid lua identifier ("function $$(): void;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; exports[`ambient identifier must be a valid lua identifier ("let $$: any;"): code 1`] = `"local ____ = _____24_24_24"`; exports[`ambient identifier must be a valid lua identifier ("let $$: any;"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; -exports[`ambient identifier must be a valid lua identifier ("module $$ { export const bar: any; }"): code 1`] = `"local ____ = _____24_24_24"`; - -exports[`ambient identifier must be a valid lua identifier ("module $$ { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; - exports[`ambient identifier must be a valid lua identifier ("namespace $$ { export const bar: any; }"): code 1`] = `"local ____ = _____24_24_24"`; exports[`ambient identifier must be a valid lua identifier ("namespace $$ { export const bar: any; }"): diagnostics 1`] = `"main.ts(3,9): error TSTL: Invalid ambient identifier name '$$$'. Ambient identifiers must be valid lua identifiers."`; diff --git a/test/unit/__snapshots__/loops.spec.ts.snap b/test/unit/__snapshots__/loops.spec.ts.snap index 29b609730..886964ebc 100644 --- a/test/unit/__snapshots__/loops.spec.ts.snap +++ b/test/unit/__snapshots__/loops.spec.ts.snap @@ -3,7 +3,7 @@ exports[`forin[Array]: code 1`] = ` "local ____exports = {} function ____exports.__main(self) - local array = {} + local array = {1, 2, 3} for key in pairs(array) do end end diff --git a/test/unit/annotations/customConstructor.spec.ts b/test/unit/annotations/customConstructor.spec.ts index 86858f700..c9ddcf739 100644 --- a/test/unit/annotations/customConstructor.spec.ts +++ b/test/unit/annotations/customConstructor.spec.ts @@ -11,8 +11,8 @@ test("CustomCreate", () => { const tsHeader = ` /** @customConstructor Point2DCreate */ class Point2D { - public x: number; - public y: number; + public x!: number; + public y!: number; constructor(x: number, y: number) { // No values assigned } diff --git a/test/unit/assignments.spec.ts b/test/unit/assignments.spec.ts index 53291f50f..3ad7da149 100644 --- a/test/unit/assignments.spec.ts +++ b/test/unit/assignments.spec.ts @@ -342,7 +342,7 @@ test.each([ test("local variable declaration referencing self indirectly", () => { util.testFunction` - let cb: () => void; + let cb: () => void = () => { throw "Expecting this to be overwritten"; }; function foo(newCb: () => void) { cb = newCb; @@ -360,7 +360,7 @@ test("local variable declaration referencing self indirectly", () => { test("local multiple variable declaration referencing self indirectly", () => { util.testFunction` - let cb: () => void; + let cb: () => void = () => { throw "Expecting this to be overwritten"; }; function foo(newCb: () => void) { cb = newCb; @@ -395,7 +395,7 @@ describe.each(["x &&= y", "x ||= y"])("boolean compound assignment (%p)", assign test.each([undefined, 3])("nullish coalescing compound assignment", initialValue => { util.testFunction` - let x: number = ${util.formatCode(initialValue)}; + let x: number | undefined = ${util.formatCode(initialValue)}; x ??= 5; return x; `.expectToMatchJsResult(); diff --git a/test/unit/builtins/array.spec.ts b/test/unit/builtins/array.spec.ts index dfb6807ec..5e3cd8887 100644 --- a/test/unit/builtins/array.spec.ts +++ b/test/unit/builtins/array.spec.ts @@ -325,7 +325,7 @@ test.each([ { array: [0, 2, 4, 8], predicate: "false" }, ])("array.find (%p)", ({ array, predicate }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: number[] = ${util.formatCode(array)}; return array.find((elem, index, arr) => ${predicate} && arr[index] === elem); `.expectToMatchJsResult(); }); @@ -337,7 +337,7 @@ test.each([ { array: [0, 2, 4, 8], searchElement: 8 }, ])("array.findIndex (%p)", ({ array, searchElement }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: number[] = ${util.formatCode(array)}; return array.findIndex((elem, index, arr) => elem === ${searchElement} && arr[index] === elem); `.expectToMatchJsResult(); }); @@ -421,9 +421,16 @@ test.each([ { array: [0, 1, 2, 3], start: 1, deleteCount: undefined }, { array: [0, 1, 2, 3], start: 1, deleteCount: null }, ])("array.splice (%p)", ({ array, start, deleteCount, newElements = [] }) => { + const deleteCountCode = + deleteCount === undefined + ? "undefined as any" + : deleteCount === null + ? "null as any" + : util.formatCode(deleteCount); + const newElementsCode = newElements.length > 0 ? ", " + util.formatCode(...newElements) : ""; util.testFunction` - const array = ${util.formatCode(array)}; - array.splice(${util.formatCode(start, deleteCount, ...newElements)}); + const array: number[] = ${util.formatCode(array)}; + array.splice(${util.formatCode(start)}, ${deleteCountCode}${newElementsCode}); return array; `.expectToMatchJsResult(); }); @@ -510,8 +517,11 @@ test("array.join without separator argument", () => { util.testExpression`["test1", "test2"].join()`.expectToMatchJsResult(); }); +test("array.indexOf empty array", () => { + util.testExpression`([] as string[]).indexOf("test1")`.expectToMatchJsResult(); +}); + test.each([ - { array: [], args: ["test1"] }, { array: ["test1"], args: ["test1"] }, { array: ["test1", "test2"], args: ["test2"] }, { array: ["test1", "test2", "test3"], args: ["test3", 1] }, @@ -571,7 +581,7 @@ test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { arra "array.reverse (%p)", ({ array }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: number[] = ${util.formatCode(array)}; array.reverse(); return array; `.expectToMatchJsResult(); @@ -580,7 +590,7 @@ test.each([{ array: [1, 2, 3] }, { array: [1, 2, 3, 4] }, { array: [1] }, { arra test.each([{ array: [1, 2, 3] }, { array: [1] }, { array: [] }])("array.shift (%p)", ({ array }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: number[] = ${util.formatCode(array)}; const value = array.shift(); return { array, value }; `.expectToMatchJsResult(); @@ -593,7 +603,7 @@ test.each([ { array: [], args: [1] }, ])("array.unshift (%p)", ({ array, args }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: number[] = ${util.formatCode(array)}; const value = array.unshift(${util.formatCode(...args)}); return { array, value }; `.expectToMatchJsResult(); @@ -601,7 +611,7 @@ test.each([ test.each([{ array: [4, 5, 3, 2, 1] }, { array: [1] }, { array: [] }])("array.sort (%p)", ({ array }) => { util.testFunctionTemplate` - const array = ${array}; + const array: number[] = ${array}; array.sort(); return array; `.expectToMatchJsResult(); @@ -659,7 +669,7 @@ describe.each(["reduce", "reduceRight"])("array.%s", reduce => { }); test("empty no initial", () => { - util.testExpression`[].${reduce}(() => {})`.expectToMatchJsResult(true); + util.testExpression`([] as any[]).${reduce}(() => {})`.expectToMatchJsResult(true); }); test("undefined returning callback", () => { @@ -675,7 +685,7 @@ test.each([{ array: [] }, { array: ["a", "b", "c"] }, { array: [{ foo: "foo" }, "array.entries (%p)", ({ array }) => { util.testFunction` - const array = ${util.formatCode(array)}; + const array: any[] = ${util.formatCode(array)}; const result = []; for (const [i, v] of array.entries()) { result.push([i, v]); @@ -800,9 +810,12 @@ test.each([ }); describe("array.fill", () => { - test.each(["[]", "[1]", "[1,2,3,4]"])("Fills full length of array without other parameters (%p)", arr => { - util.testExpression`${arr}.fill(5)`.expectToMatchJsResult(); - }); + test.each(["([] as number[])", "[1]", "[1,2,3,4]"])( + "Fills full length of array without other parameters (%p)", + arr => { + util.testExpression`${arr}.fill(5)`.expectToMatchJsResult(); + } + ); test.each(["[1,2,3]", "[1,2,3,4,5,6]"])("Fills starting from start parameter (%p)", arr => { util.testExpression`${arr}.fill(5, 3)`.expectToMatchJsResult(); diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 546589355..ad64f031d 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -38,7 +38,7 @@ test("high amount of chained awaits doesn't cause stack overflow", () => { await delay(); } result = "success"; - } catch (e) { + } catch (e: any) { result = e; } } @@ -51,7 +51,7 @@ test("high amount of chained awaits doesn't cause stack overflow", () => { test("can await already resolved promise", () => { util.testFunction` - const result = []; + const result: unknown[] = []; async function abc() { return await Promise.resolve(30); } @@ -63,7 +63,7 @@ test("can await already resolved promise", () => { test("can await already rejected promise", () => { util.testFunction` - const result = []; + const result: unknown[] = []; async function abc() { return await Promise.reject("test rejection"); } @@ -604,7 +604,7 @@ describe("try/catch in async function", () => { () => util.testModule` export let reason = ""; - let reject: (reason: string) => void; + let reject: (reason: string) => void = () => { throw "should be overridden!"; } async function foo(): Promise { try { @@ -675,6 +675,7 @@ describe("try/catch in async function", () => { } catch { + return "catch"; } } diff --git a/test/unit/builtins/map.spec.ts b/test/unit/builtins/map.spec.ts index 27b539589..c9f6c1a2b 100644 --- a/test/unit/builtins/map.spec.ts +++ b/test/unit/builtins/map.spec.ts @@ -251,7 +251,7 @@ describe.each(iterationMethods)("map.%s() handles mutation", iterationMethod => describe("Map.groupBy", () => { test("empty", () => { util.testFunction` - const array = []; + const array: number[] = []; const map = Map.groupBy(array, (num, index) => { return num % 2 === 0 ? "even": "odd"; diff --git a/test/unit/builtins/object.spec.ts b/test/unit/builtins/object.spec.ts index 192f17d9f..411da903b 100644 --- a/test/unit/builtins/object.spec.ts +++ b/test/unit/builtins/object.spec.ts @@ -157,7 +157,7 @@ describe("Object.defineProperty", () => { test.each(trueFalseTests)("configurable (%p)", value => { util.testFunction` - const foo = { bar: true }; + const foo: { bar?: boolean } = { bar: true }; Object.defineProperty(foo, "bar", { configurable: ${value} }); try { delete foo.bar } catch {}; return foo.bar; @@ -306,7 +306,7 @@ describe("Object.getOwnPropertyDescriptors", () => { describe("delete from object", () => { test("delete from object", () => { util.testFunction` - const obj = { foo: "bar", bar: "baz" }; + const obj: { foo?: string, bar: string } = { foo: "bar", bar: "baz" }; return [delete obj["foo"], obj]; `.expectToMatchJsResult(); }); @@ -321,7 +321,7 @@ describe("delete from object", () => { // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/993 test("delete from object with metatable", () => { util.testFunction` - const obj = { foo: "bar", bar: "baz" }; + const obj: { foo?: string, bar: string } = { foo: "bar", bar: "baz" }; setmetatable(obj, {}); return [delete obj["foo"], obj]; ` @@ -353,7 +353,7 @@ describe("delete from object", () => { describe("Object.groupBy", () => { test("empty", () => { util.testFunction` - const array = []; + const array: number[] = []; return Object.groupBy(array, (num, index) => { return num % 2 === 0 ? "even": "odd"; diff --git a/test/unit/builtins/set.spec.ts b/test/unit/builtins/set.spec.ts index 65ee4aef0..234be91a7 100644 --- a/test/unit/builtins/set.spec.ts +++ b/test/unit/builtins/set.spec.ts @@ -100,7 +100,7 @@ test("set has false", () => { test("set has null", () => { util.testFunction` - let myset = new Set(["a", "c"]); + let myset = new Set(["a", "c"]); return myset.has(null); `.expectToMatchJsResult(); }); diff --git a/test/unit/builtins/string.spec.ts b/test/unit/builtins/string.spec.ts index 977944e55..7f2ad312d 100644 --- a/test/unit/builtins/string.spec.ts +++ b/test/unit/builtins/string.spec.ts @@ -84,7 +84,7 @@ describe.each(["replace", "replaceAll"])("string.%s", method => { test.each(testCases)("function replacer %p", ({ inp, searchValue, replaceValue }) => { util.testFunction` const result = { - args: [], + args: [] as string[], string: "" } function replacer(...args: any[]): string { diff --git a/test/unit/builtins/weakMap.spec.ts b/test/unit/builtins/weakMap.spec.ts index 812e43622..8ff5d4c2e 100644 --- a/test/unit/builtins/weakMap.spec.ts +++ b/test/unit/builtins/weakMap.spec.ts @@ -74,7 +74,7 @@ test("weakMap has null", () => { util.testFunction` ${initRefsTs} let mymap = new WeakMap([[{}, true]]); - return mymap.has(null); + return mymap.has(null as any); `.expectToMatchJsResult(); }); diff --git a/test/unit/classes/classes.spec.ts b/test/unit/classes/classes.spec.ts index f28c3b43d..e7b8cc304 100644 --- a/test/unit/classes/classes.spec.ts +++ b/test/unit/classes/classes.spec.ts @@ -894,7 +894,7 @@ test("get inherted __index member from super (DotA 2 inheritance) (#1537)", () = interface Connected extends I {} class Connected {} - declare function setmetatable(this: void, t: any, mt: any); + declare function setmetatable(this: void, t: any, mt: any): void; const A = { foo() { diff --git a/test/unit/classes/decorators.spec.ts b/test/unit/classes/decorators.spec.ts index 4782746be..095bd8e3a 100644 --- a/test/unit/classes/decorators.spec.ts +++ b/test/unit/classes/decorators.spec.ts @@ -22,8 +22,8 @@ test("Class decorator with no parameters", () => { } return { decoratedClass: new TestClass(), context: { - kind: classDecoratorContext.kind, - name: classDecoratorContext.name, + kind: classDecoratorContext!.kind, + name: classDecoratorContext!.name, } }; `.expectToMatchJsResult(); }); @@ -40,7 +40,7 @@ test("Class decorator with parameters", () => { @setNum(420) class TestClass { - public decoratorNum; + public decoratorNum?: number; } return new TestClass(); @@ -64,8 +64,8 @@ test("Multiple class decorators", () => { @setTen @setNum class TestClass { - public decoratorTen; - public decoratorNum; + public decoratorTen?: number; + public decoratorNum?: number; } return new TestClass(); @@ -95,7 +95,7 @@ test("Class decorator with inheritance", () => { test("Class decorators are applied in order and executed in reverse order", () => { util.testFunction` - const order = []; + const order: string[] = []; function pushOrder(index: number) { order.push("eval " + index); @@ -232,10 +232,10 @@ test("class method decorator", () => { } return { result: new TestClass().myMethod(4), context: { - kind: methodDecoratorContext.kind, - name: methodDecoratorContext.name, - private: methodDecoratorContext.private, - static: methodDecoratorContext.static + kind: methodDecoratorContext!.kind, + name: methodDecoratorContext!.name, + private: methodDecoratorContext!.private, + static: methodDecoratorContext!.static } }; `.expectToMatchJsResult(); }); @@ -243,7 +243,7 @@ test("class method decorator", () => { test("this in decorator points to class being decorated", () => { util.testFunction` function methodDecorator(method: (v: number) => number, context: ClassMethodDecoratorContext) { - return function() { + return function(this: TestClass) { const thisCallTime = this.myInstanceVariable; return thisCallTime; }; @@ -280,10 +280,10 @@ test("class getter decorator", () => { } return { result: new TestClass().getterValue, context: { - kind: getterDecoratorContext.kind, - name: getterDecoratorContext.name, - private: getterDecoratorContext.private, - static: getterDecoratorContext.static + kind: getterDecoratorContext!.kind, + name: getterDecoratorContext!.name, + private: getterDecoratorContext!.private, + static: getterDecoratorContext!.static } }; `.expectToMatchJsResult(); }); @@ -295,13 +295,13 @@ test("class setter decorator", () => { function setterDecorator(setter: (v: number) => void, context: ClassSetterDecoratorContext) { setterDecoratorContext = context; - return function(v: number) { + return function(this: TestClass, v: number) { setter.call(this, v + 15); }; } class TestClass { - public value: number; + public value?: number; @setterDecorator set valueSetter(v: number) { this.value = v; } @@ -310,10 +310,10 @@ test("class setter decorator", () => { const instance = new TestClass(); instance.valueSetter = 23; return { result: instance.value, context: { - kind: setterDecoratorContext.kind, - name: setterDecoratorContext.name, - private: setterDecoratorContext.private, - static: setterDecoratorContext.static + kind: setterDecoratorContext!.kind, + name: setterDecoratorContext!.name, + private: setterDecoratorContext!.private, + static: setterDecoratorContext!.static } }; `.expectToMatchJsResult(); }); @@ -332,10 +332,10 @@ test("class field decorator", () => { } return { result: new TestClass(), context: { - kind: fieldDecoratorContext.kind, - name: fieldDecoratorContext.name, - private: fieldDecoratorContext.private, - static: fieldDecoratorContext.static, + kind: fieldDecoratorContext!.kind, + name: fieldDecoratorContext!.name, + private: fieldDecoratorContext!.private, + static: fieldDecoratorContext!.static, } }; `.expectToEqual({ result: { @@ -399,7 +399,7 @@ describe("legacy experimentalDecorators", () => { @setNum(420) class TestClass { - public decoratorNum; + public decoratorNum?: number; } return new TestClass(); @@ -425,8 +425,8 @@ describe("legacy experimentalDecorators", () => { @setTen @setNum class TestClass { - public decoratorTen; - public decoratorNum; + public decoratorTen?: number; + public decoratorNum?: number; } return new TestClass(); @@ -460,7 +460,7 @@ describe("legacy experimentalDecorators", () => { test("Class decorators are applied in order and executed in reverse order", () => { util.testFunction` - const order = []; + const order: string[] = []; function pushOrder(index: number) { order.push("eval " + index); @@ -509,25 +509,25 @@ describe("legacy experimentalDecorators", () => { test.each([ ["@decorator method() {}"], - ["@decorator property;"], + ["@decorator property: any;"], ["@decorator propertyWithInitializer = () => {};"], - ["@decorator ['evaluated property'];"], + ["@decorator ['evaluated property']: any;"], ["@decorator get getter() { return 5 }"], - ["@decorator set setter(value) {}"], + ["@decorator set setter(value: any) {}"], ["@decorator static method() {}"], - ["@decorator static property;"], + ["@decorator static property: any;"], ["@decorator static propertyWithInitializer = () => {}"], ["@decorator static get getter() { return 5 }"], - ["@decorator static set setter(value) {}"], - ["@decorator static ['evaluated property'];"], - ["method(@decorator a) {}"], - ["static method(@decorator a) {}"], - ["constructor(@decorator a) {}"], + ["@decorator static set setter(value: any) {}"], + ["@decorator static ['evaluated property']: any;"], + ["method(@decorator a: any) {}"], + ["static method(@decorator a: any) {}"], + ["constructor(@decorator a: any) {}"], ])("Decorate class member (%p)", classMember => { util.testFunction` let decoratorParameters: any; - const decorator = (target, key, index?) => { + const decorator = (target: any, key: any, index?: any) => { const targetKind = target === Foo ? "Foo" : target === Foo.prototype ? "Foo.prototype" : "unknown"; decoratorParameters = { targetKind, key, index: typeof index }; }; @@ -548,10 +548,10 @@ describe("legacy experimentalDecorators", () => { ["desc.writable = true", "return { configurable: true }"], ])("Combine decorators (%p + %p)", (decorateA, decorateB) => { util.testFunction` - const A = (target, key, desc): any => { ${decorateA} }; - const B = (target, key, desc): any => { ${decorateB} }; + const A = (target: any, key: any, desc: any): any => { ${decorateA} }; + const B = (target: any, key: any, desc: any): any => { ${decorateB} }; class Foo { @A @B static method() {} } - const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method"); + const { value, ...rest } = Object.getOwnPropertyDescriptor(Foo, "method")!; return rest; ` .setOptions({ experimentalDecorators: true }) @@ -562,7 +562,7 @@ describe("legacy experimentalDecorators", () => { "Use decorator to override method value %s", overrideStatement => { util.testFunction` - const decorator = (target, key, desc): any => { ${overrideStatement} }; + const decorator = (target: any, key: any, desc: any): any => { ${overrideStatement} }; class Foo { @decorator static method() {} } return Foo.method; ` diff --git a/test/unit/conditionals.spec.ts b/test/unit/conditionals.spec.ts index f862ca8a3..59ca587bc 100644 --- a/test/unit/conditionals.spec.ts +++ b/test/unit/conditionals.spec.ts @@ -75,7 +75,7 @@ test.each([ ])("Ternary operator (%p)", ({ input, options }) => { util.testFunction` const literalValue = "literal"; - let variableValue: string; + let variableValue: string = "variable"; let maybeBooleanValue: string | boolean = false; let maybeUndefinedValue: string | undefined; return ${input}; diff --git a/test/unit/destructuring.spec.ts b/test/unit/destructuring.spec.ts index 4820876a4..36b73daaf 100644 --- a/test/unit/destructuring.spec.ts +++ b/test/unit/destructuring.spec.ts @@ -3,40 +3,50 @@ import * as util from "../util"; const allBindings = "x, y, z, rest"; const testCases = [ - { binding: "{ x }", value: { x: true } }, - { binding: "{ x, y }", value: { x: false, y: true } }, - { binding: "{ x: z, y }", value: { x: true, y: false } }, - { binding: "{ x: { x, y }, z }", value: { x: { x: true, y: false }, z: false } }, - { binding: "{ x, y = true }", value: { x: false, y: false } }, - { binding: "{ x = true }", value: {} }, - { binding: "{ x, y = true }", value: { x: false } }, - { binding: "{ ...rest }", value: {} }, - { binding: "{ x, ...rest }", value: { x: "x" } }, - { binding: "{ x, ...rest }", value: { x: "x", y: "y", z: "z" } }, - { binding: "{ x, ...y }", value: { x: "x", y: "y", z: "z" } }, - { binding: "{ x: y, ...z }", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x }", type: "{ x: boolean }", value: { x: true } }, + { binding: "{ x, y }", type: "{ x: boolean, y: boolean }", value: { x: false, y: true } }, + { binding: "{ x: z, y }", type: "{ x: boolean, y?: boolean, z?: boolean }", value: { x: true, y: false } }, + { + binding: "{ x: { x, y }, z }", + type: "{ x: { x: boolean, y: boolean }, z: boolean }", + value: { x: { x: true, y: false }, z: false }, + }, + { binding: "{ x, y = true }", type: "{ x: boolean, y?: boolean }", value: { x: false, y: false } }, + { binding: "{ x = true }", type: "{ x?: boolean }", value: {} }, + { binding: "{ x, y = true }", type: "{ x: boolean, y?: boolean }", value: { x: false } }, + { binding: "{ ...rest }", type: "any", value: {} }, + { binding: "{ x, ...rest }", type: "any", value: { x: "x" } }, + { binding: "{ x, ...rest }", type: "any", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x, ...y }", type: "any", value: { x: "x", y: "y", z: "z" } }, + { binding: "{ x: y, ...z }", type: "any", value: { x: "x", y: "y", z: "z" } }, - { binding: "[]", value: [] }, - { binding: "[x, y]", value: ["x", "y"] }, - { binding: "[x, , y]", value: ["x", "", "y"] }, - { binding: "[x = true]", value: [false] }, - { binding: "[[x, y]]", value: [["x", "y"]] }, - { binding: "[x, ...rest]", value: ["x"] }, - { binding: "[x, ...rest]", value: ["x", "y", "z"] }, + { binding: "[]", type: "boolean[]", value: [] }, + { binding: "[x, y]", type: "[string, string]", value: ["x", "y"] }, + { binding: "[x, , y]", type: "string[]", value: ["x", "", "y"] }, + { binding: "[x = true]", type: "boolean[]", value: [false] }, + { binding: "[x = true]", type: "boolean[]", value: [] }, + { binding: "[[x, y]]", type: "Array", value: [["x", "y"]] }, + { binding: "[x, ...rest]", type: "string[]", value: ["x"] }, + { binding: "[x, ...rest]", type: "string[]", value: ["x", "y", "z"] }, - { binding: "{ y: [z = true] }", value: { y: [false] } }, - { binding: "{ x: [x, y] }", value: { x: ["x", "y"] } }, - { binding: "{ x: [{ y }] }", value: { x: [{ y: "y" }] } }, -].map(({ binding, value }) => ({ binding, value: util.formatCode(value) })); + { binding: "{ y: [z = true] }", type: "{ y: boolean[] }", value: { y: [false] } }, + { binding: "{ y: [z = true] }", type: "{ y: boolean[] }", value: { y: [] } }, + { binding: "{ x: [x, y] }", type: "{ x: [string, string] }", value: { x: ["x", "y"] } }, + { binding: "{ x: [{ y }] }", type: "{ x: [{ y: string }] }", value: { x: [{ y: "y" }] } }, +].map(({ binding, type, value }) => ({ binding, type, value: util.formatCode(value) })); test.each([ ...testCases, - { binding: "{ x, y }, z", value: "{ x: false, y: false }, true" }, - { binding: "{ x, y }, { z }", value: "{ x: false, y: false }, { z: true }" }, -])("in function parameter (%p)", ({ binding, value }) => { + { binding: "{ x, y }", type: "{ x: boolean, y: boolean }, z: boolean", value: "{ x: false, y: false }, true" }, + { + binding: "{ x, y }", + type: "{ x: boolean, y: boolean }, { z }: { z: boolean }", + value: "{ x: false, y: false }, { z: true }", + }, +])("in function parameter (%p)", ({ binding, type, value }) => { util.testFunction` let ${allBindings}; - function test(${binding}) { + function test(${binding}: ${type}) { return { ${allBindings} }; } diff --git a/test/unit/enum.spec.ts b/test/unit/enum.spec.ts index 3ff4ce3fe..ae552b9c1 100644 --- a/test/unit/enum.spec.ts +++ b/test/unit/enum.spec.ts @@ -4,7 +4,7 @@ import * as util from "../util"; const serializeEnum = (identifier: string) => `(() => { const mappedTestEnum: any = {}; for (const key in ${identifier}) { - mappedTestEnum[(key as any).toString()] = ${identifier}[key]; + mappedTestEnum[(key as any).toString()] = (${identifier} as any)[key]; } return mappedTestEnum; })()`; diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 89ceb49df..8204cc36a 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -88,7 +88,7 @@ test("multi return from try", () => { } catch { } } - const [foo, bar] = foobar(); + const [foo, bar] = foobar()!; return foo + bar; `.withLanguageExtensions(); expect(testBuilder.getMainLuaCodeChunk()).not.toMatch("unpack(foobar"); @@ -129,7 +129,7 @@ test("multi return from catch", () => { function foobar(): LuaMultiReturn<[string, string]> { try { throw "foobar"; - } catch (e) { + } catch (e: any) { return $multi(e.toString(), " catch"); } } @@ -243,7 +243,7 @@ test("multi return from catch->finally", () => { function foobar() { try { throw "foo"; - } catch (e) { + } catch (e: any) { return $multi(evaluate(e), "bar"); } finally { return $multi("final", "ly"); diff --git a/test/unit/functions/functionProperties.spec.ts b/test/unit/functions/functionProperties.spec.ts index 16b61ab46..85b3ec155 100644 --- a/test/unit/functions/functionProperties.spec.ts +++ b/test/unit/functions/functionProperties.spec.ts @@ -160,7 +160,7 @@ test("async arrow function with property assigned to variable", () => { test("call function with property using call method", () => { util.testFunction` - function foo(s: string) { return this + s; } + function foo(this: string, s: string) { return this + s; } foo.baz = "baz"; return foo.call("foo", "bar") + foo.baz; `.expectToMatchJsResult(); @@ -168,7 +168,7 @@ test("call function with property using call method", () => { test("call function with property using apply method", () => { util.testFunction` - function foo(s: string) { return this + s; } + function foo(this: string, s: string) { return this + s; } foo.baz = "baz"; return foo.apply("foo", ["bar"]) + foo.baz; `.expectToMatchJsResult(); @@ -176,7 +176,7 @@ test("call function with property using apply method", () => { test("call function with property using bind method", () => { util.testFunction` - function foo(s: string) { return this + s; } + function foo(this: string, s: string) { return this + s; } foo.baz = "baz"; return foo.bind("foo", "bar")() + foo.baz; `.expectToMatchJsResult(); diff --git a/test/unit/functions/functions.spec.ts b/test/unit/functions/functions.spec.ts index 7bdf6b040..27b48a1ee 100644 --- a/test/unit/functions/functions.spec.ts +++ b/test/unit/functions/functions.spec.ts @@ -5,7 +5,7 @@ import { unsupportedForTarget } from "../../../src/transformation/utils/diagnost test("Arrow Function Expression", () => { util.testFunction` - const add = (a, b) => a + b; + const add = (a: number, b: number) => a + b; return add(1, 2); `.expectToMatchJsResult(); }); @@ -25,17 +25,22 @@ test.each(["i++", "i--", "++i", "--i"])("Arrow function unary expression (%p)", `.expectToMatchJsResult(); }); -test.each(["b => a = b", "b => a += b", "b => a -= b", "b => a *= b", "b => a /= b", "b => a **= b", "b => a %= b"])( - "Arrow function assignment (%p)", - lambda => { - util.testFunction` +test.each([ + "(b: number) => a = b", + "(b: number) => a += b", + "(b: number) => a -= b", + "(b: number) => a *= b", + "(b: number) => a /= b", + "(b: number) => a **= b", + "(b: number) => a %= b", +])("Arrow function assignment (%p)", lambda => { + util.testFunction` let a = 10; let lambda = ${lambda}; lambda(5); return a; `.expectToMatchJsResult(); - } -); +}); test.each([{ args: [] }, { args: [1] }, { args: [1, 2] }])("Arrow default values (%p)", ({ args }) => { util.testFunction` @@ -46,7 +51,7 @@ test.each([{ args: [] }, { args: [1] }, { args: [1, 2] }])("Arrow default values test("Function Expression", () => { util.testFunction` - let add = function(a, b) {return a+b}; + let add = function(a: number, b: number) {return a+b}; return add(1,2); `.expectToMatchJsResult(); }); @@ -251,13 +256,13 @@ test.each(functionTypeDeclarations)("Function call (%s)", (_, type) => { }); test.each([ - "function fn() {}", - "function fn(x, y, z) {}", - "function fn(x, y, z, ...args) {}", - "function fn(...args) {}", - "function fn(this: void) {}", - "function fn(this: void, x, y, z) {}", - "function fnReference(x, y, z) {} const fn = fnReference;", + "function fn(): void {}", + "function fn(x: any, y: any, z: any): void {}", + "function fn(x: any, y: any, z: any, ...args: any[]): void {}", + "function fn(...args: any[]): void {}", + "function fn(this: void): void {}", + "function fn(this: void, x: any, y: any, z: any): void {}", + "function fnReference(x: any, y: any, z: any): void {} const fn = fnReference;", "const wrap = (fn: (...args: any[]) => any) => (...args: any[]) => fn(...args); const fn = wrap((x, y, z) => {});", ])("function.length (%p)", declaration => { util.testFunction` @@ -432,7 +437,7 @@ test("Complex element access call no args", () => { test("Complex element access call statement", () => { util.testFunction` - let foo: string; + let foo: string | undefined; class C { prop = "bar"; method(s: string) { foo = s + this.prop; } diff --git a/test/unit/functions/generators.spec.ts b/test/unit/functions/generators.spec.ts index aa62d719d..6cf935528 100644 --- a/test/unit/functions/generators.spec.ts +++ b/test/unit/functions/generators.spec.ts @@ -27,7 +27,7 @@ test(".next()", () => { test(".next() with parameters", () => { util.testFunction` - function* generator() { + function* generator(): Generator { return yield 0; } diff --git a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap index b7175df75..87cb07b9d 100644 --- a/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap +++ b/test/unit/functions/validation/__snapshots__/invalidFunctionAssignments.spec.ts.snap @@ -340,17 +340,17 @@ exports[`Invalid function argument ({"definition": "namespace NoSelfFuncNs { exports[`Invalid function argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function argument ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function argument ({"value": "(function(this: any, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function argument ({"value": "function(this: any, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function argument ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid function argument with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` "main.ts(4,23): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. @@ -732,17 +732,17 @@ exports[`Invalid function assignment ({"definition": "namespace NoSelfFuncNs { exports[`Invalid function assignment ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function assignment ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function assignment ({"value": "(function(this: any, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function assignment ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function assignment ({"value": "function(this: any, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function assignment ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function assignment ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function assignment ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 2`] = `"main.ts(4,18): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid function assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` "main.ts(4,14): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. @@ -1124,17 +1124,17 @@ exports[`Invalid function generic argument ({"definition": "namespace NoSelfFunc exports[`Invalid function generic argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function generic argument ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function generic argument ({"value": "(function(this: any, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function generic argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function generic argument ({"value": "function(this: any, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function generic argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function generic argument ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function generic argument ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 2`] = `"main.ts(4,27): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid function overload assignment ("(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(7,52): error TSTL: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'."`; @@ -1484,17 +1484,17 @@ exports[`Invalid function return ({"definition": "namespace NoSelfFuncNs { exports[`Invalid function return ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(5,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function return ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function return ({"value": "(function(this: any, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function return ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function return ({"value": "function(this: any, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function return ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function return ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function return ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 2`] = `"main.ts(4,17): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid function return with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}): diagnostics 1`] = ` "main.ts(4,17): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. @@ -1885,17 +1885,17 @@ exports[`Invalid function variable declaration ({"definition": "namespace NoSelf exports[`Invalid function variable declaration ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}): diagnostics 1`] = `"main.ts(4,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function variable declaration ({"value": "(function(this: any, s) { return s; })"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function variable declaration ({"value": "(function(this: any, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function variable declaration ({"value": "(function(this: void, s) { return s; })"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"value": "(function(this: void, s) { return s; })"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"value": "(function(this: void, s: string) { return s; })"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"value": "function(this: any, s) { return s; }"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid function variable declaration ({"value": "function(this: any, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(3,59): error TSTL: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid function variable declaration ({"value": "function(this: void, s) { return s; }"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 1`] = `"main.ts(3,47): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid function variable declaration ({"value": "function(this: void, s) { return s; }"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid function variable declaration ({"value": "function(this: void, s: string) { return s; }"}): diagnostics 2`] = `"main.ts(3,58): error TSTL: Unable to convert function with no 'this' parameter to function with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid interface method assignment: diagnostics 1`] = `"main.ts(5,22): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -2260,17 +2260,17 @@ exports[`Invalid object with method argument ({"definition": "namespace NoSelfFu exports[`Invalid object with method argument ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method argument ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method argument ({"value": "(function(this: any, s: string) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method argument ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method argument ({"value": "(function(this: void, s: string) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method argument ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method argument ({"value": "(function(this: void, s: string) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method argument ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method argument ({"value": "function(this: any, s: string) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with a 'this' parameter to function 'obj.fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method argument ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method argument ({"value": "function(this: void, s: string) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method argument ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method argument ({"value": "function(this: void, s: string) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,35): error TSTL: Unable to convert function with no 'this' parameter to function 'obj.fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid object with method assignment ({"definition": "/** @noSelf */ class AnonFuncNSMergedNoSelfClass { method(s: string): string { return s; } } namespace AnonFuncNSMergedNoSelfClass { export function nsFunc(s: string) { return s; } }", "value": "AnonFuncNSMergedNoSelfClass.nsFunc"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; @@ -2629,17 +2629,17 @@ exports[`Invalid object with method assignment ({"definition": "namespace NoSelf exports[`Invalid object with method assignment ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(5,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method assignment ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method assignment ({"value": "(function(this: any, s: string) { return s; })"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method assignment ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method assignment ({"value": "(function(this: void, s: string) { return s; })"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method assignment ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method assignment ({"value": "(function(this: void, s: string) { return s; })"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method assignment ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method assignment ({"value": "function(this: any, s: string) { return s; }"}, "(this: void, s: string) => string", false): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method assignment ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method assignment ({"value": "function(this: void, s: string) { return s; }"}, "(s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method assignment ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method assignment ({"value": "function(this: void, s: string) { return s; }"}, "(this: any, s: string) => string", true): diagnostics 1`] = `"main.ts(4,19): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; exports[`Invalid object with method assignment with cast ({"definition": "/** @noSelfInFile */ let noSelfInFileFunc: {(s: string): string} = function(s) { return s; };", "value": "noSelfInFileFunc"}, "(noSelfInFileFunc) as ((this: any, s: string) => string)", false): diagnostics 1`] = ` "main.ts(4,19): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'. @@ -3038,14 +3038,14 @@ exports[`Invalid object with method variable declaration ({"definition": "namesp exports[`Invalid object with method variable declaration ({"definition": "namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncSelf(s: string): string { return s; } } /** @noSelf */ namespace SelfAnonFuncNSMergedNoSelfNS { export function nsFuncNoSelf(s: string) { return s; } }", "value": "SelfAnonFuncNSMergedNoSelfNS.nsFuncSelf"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(4,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method variable declaration ({"value": "(function(this: any, s) { return s; })"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method variable declaration ({"value": "(function(this: any, s: string) { return s; })"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s) { return s; })"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s: string) { return s; })"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s) { return s; })"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method variable declaration ({"value": "(function(this: void, s: string) { return s; })"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method variable declaration ({"value": "function(this: any, s) { return s; }"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; +exports[`Invalid object with method variable declaration ({"value": "function(this: any, s: string) { return s; }"}, "(this: void, s: string) => string"): diagnostics 1`] = `"main.ts(3,68): error TSTL: Unable to convert function with a 'this' parameter to function 'fn' with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'."`; -exports[`Invalid object with method variable declaration ({"value": "function(this: void, s) { return s; }"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method variable declaration ({"value": "function(this: void, s: string) { return s; }"}, "(s: string) => string"): diagnostics 1`] = `"main.ts(3,56): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; -exports[`Invalid object with method variable declaration ({"value": "function(this: void, s) { return s; }"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; +exports[`Invalid object with method variable declaration ({"value": "function(this: void, s: string) { return s; }"}, "(this: any, s: string) => string"): diagnostics 1`] = `"main.ts(3,67): error TSTL: Unable to convert function with no 'this' parameter to function 'fn' with 'this'. To fix, wrap in an arrow function, or declare with 'this: any'."`; diff --git a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts index abac4e483..9220902b2 100644 --- a/test/unit/functions/validation/functionExpressionTypeInference.spec.ts +++ b/test/unit/functions/validation/functionExpressionTypeInference.spec.ts @@ -79,7 +79,7 @@ test.each([ test("Function expression type inference in object literal assigned to narrower type", () => { util.testFunction` - let foo: {} = {bar: s => s}; + let foo: {} = {bar: (s: string) => s}; return (foo as {bar: (a: any) => any}).bar("foobar"); `.expectToMatchJsResult(); }); diff --git a/test/unit/functions/validation/functionPermutations.ts b/test/unit/functions/validation/functionPermutations.ts index 14e478498..4947bc9a4 100644 --- a/test/unit/functions/validation/functionPermutations.ts +++ b/test/unit/functions/validation/functionPermutations.ts @@ -352,20 +352,20 @@ const noSelfInFileTestFunctions: TestFunction[] = [ ]; export const anonTestFunctionExpressions: TestFunction[] = [ - { value: "s => s" }, - { value: "(s => s)" }, - { value: "function(s) { return s; }" }, - { value: "(function(s) { return s; })" }, + { value: "(s: string) => s" }, + { value: "((s: string) => s)" }, + { value: "function(s: string) { return s; }" }, + { value: "(function(s: string) { return s; })" }, ]; export const selfTestFunctionExpressions: TestFunction[] = [ - { value: "function(this: any, s) { return s; }" }, - { value: "(function(this: any, s) { return s; })" }, + { value: "function(this: any, s: string) { return s; }" }, + { value: "(function(this: any, s: string) { return s; })" }, ]; export const noSelfTestFunctionExpressions: TestFunction[] = [ - { value: "function(this: void, s) { return s; }" }, - { value: "(function(this: void, s) { return s; })" }, + { value: "function(this: void, s: string) { return s; }" }, + { value: "(function(this: void, s: string) { return s; })" }, ]; export const anonTestFunctionType = "(s: string) => string"; diff --git a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts index 95b26b7d0..2b9fd61db 100644 --- a/test/unit/functions/validation/invalidFunctionAssignments.spec.ts +++ b/test/unit/functions/validation/invalidFunctionAssignments.spec.ts @@ -96,7 +96,7 @@ test.each(invalidTestFunctionAssignments)( (testFunction, functionType, isSelfConversion) => { util.testModule` ${testFunction.definition ?? ""} - declare function takesFunction(fn: ${functionType}); + declare function takesFunction(fn: ${functionType}): void; takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], @@ -110,7 +110,7 @@ test.each(invalidTestMethodAssignments)( (testFunction, functionType, isSelfConversion) => { util.testModule` ${testFunction.definition ?? ""} - declare function takesObjectWithMethod(obj: { fn: ${functionType} }); + declare function takesObjectWithMethod(obj: { fn: ${functionType} }): void; takesObjectWithMethod({fn: ${testFunction.value}}); `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], @@ -130,7 +130,7 @@ test("Invalid lua lib function argument", () => { test.each(invalidTestFunctionCasts)("Invalid function argument with cast (%p)", (testFunction, castedFunction) => { util.testModule` ${testFunction.definition ?? ""} - declare function takesFunction(fn: typeof ${testFunction.value}); + declare function takesFunction(fn: typeof ${testFunction.value}): void; takesFunction(${castedFunction}); `.expectDiagnosticsToMatchSnapshot( [unsupportedNoSelfFunctionConversion.code, unsupportedSelfFunctionConversion.code], @@ -143,7 +143,7 @@ test.each(invalidTestFunctionAssignments)( (testFunction, functionType, isSelfConversion) => { util.testModule` ${testFunction.definition ?? ""} - declare function takesFunction(fn: T); + declare function takesFunction(fn: T): void; takesFunction(${testFunction.value}); `.expectDiagnosticsToMatchSnapshot( [isSelfConversion ? unsupportedSelfFunctionConversion.code : unsupportedNoSelfFunctionConversion.code], diff --git a/test/unit/hoisting.spec.ts b/test/unit/hoisting.spec.ts index 144460067..e08a7c083 100644 --- a/test/unit/hoisting.spec.ts +++ b/test/unit/hoisting.spec.ts @@ -254,7 +254,7 @@ test("Hoisting variable without initializer", () => { function foo() { return x; } - let x: number; + let x: number | undefined; return foo(); `.expectToMatchJsResult(); }); diff --git a/test/unit/identifiers.spec.ts b/test/unit/identifiers.spec.ts index f148c3c72..ddac778fc 100644 --- a/test/unit/identifiers.spec.ts +++ b/test/unit/identifiers.spec.ts @@ -93,9 +93,8 @@ test.each([ "const foo: any, bar: any, $$$: any;", "class $$$ {}", "namespace $$$ { export const bar: any; }", - "module $$$ { export const bar: any; }", "enum $$$ {}", - "function $$$();", + "function $$$(): void;", ])("ambient identifier must be a valid lua identifier (%p)", statement => { util.testModule` declare ${statement} diff --git a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap index a3f6de381..4420b90e0 100644 --- a/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap +++ b/test/unit/language-extensions/__snapshots__/multi.spec.ts.snap @@ -160,22 +160,7 @@ return ____exports" exports[`invalid direct $multi function use (const ar = [1]; const [a] = $multi(...ar)): diagnostics 1`] = `"main.ts(7,37): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` -"local ____exports = {} -local function multi(self, ...) - return ... -end -local a -local ____temp_0 = {____(nil)} -a = ____temp_0[1] -____exports.a = a -____exports.a = a -return ____exports" -`; - -exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in a return statement."`; - -exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` +exports[`invalid direct $multi function use (let a: any; for ([a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) return ... @@ -193,9 +178,9 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,27): error TSTL: The $multi function must be called in a return statement."`; +exports[`invalid direct $multi function use (let a: any; for ([a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,32): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` +exports[`invalid direct $multi function use (let a: any; for (const [a] = $multi(1, 2); false; 1) {}): code 1`] = ` "local ____exports = {} local function multi(self, ...) return ... @@ -211,9 +196,9 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,33): error TSTL: The $multi function must be called in a return statement."`; +exports[`invalid direct $multi function use (let a: any; for (const [a] = $multi(1, 2); false; 1) {}): diagnostics 1`] = `"main.ts(7,38): error TSTL: The $multi function must be called in a return statement."`; -exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): code 1`] = ` +exports[`invalid direct $multi function use (let a: any; if ([a] = $multi(1)) { ++a; }): code 1`] = ` "local ____exports = {} local function multi(self, ...) return ... @@ -230,4 +215,19 @@ ____exports.a = a return ____exports" `; -exports[`invalid direct $multi function use (let a; if ([a] = $multi(1)) { ++a; }): diagnostics 1`] = `"main.ts(7,26): error TSTL: The $multi function must be called in a return statement."`; +exports[`invalid direct $multi function use (let a: any; if ([a] = $multi(1)) { ++a; }): diagnostics 1`] = `"main.ts(7,31): error TSTL: The $multi function must be called in a return statement."`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): code 1`] = ` +"local ____exports = {} +local function multi(self, ...) + return ... +end +local a +local ____temp_0 = {____(nil)} +a = ____temp_0[1] +____exports.a = a +____exports.a = a +return ____exports" +`; + +exports[`invalid direct $multi function use (let a; [a] = $multi()): diagnostics 1`] = `"main.ts(7,22): error TSTL: The $multi function must be called in a return statement."`; diff --git a/test/unit/language-extensions/multi.spec.ts b/test/unit/language-extensions/multi.spec.ts index 72b330887..90fc54200 100644 --- a/test/unit/language-extensions/multi.spec.ts +++ b/test/unit/language-extensions/multi.spec.ts @@ -42,6 +42,7 @@ test("Destructuring assignment of LuaMultiReturn returning nil", () => { export {a, b}; ` .withLanguageExtensions() + .setOptions({ strict: false }) .expectToEqual({ a: undefined, b: [] }); }); @@ -58,7 +59,7 @@ test.each<[string, any]>([ }); const multiFunction = ` -function multi(...args) { +function multi(...args: unknown[]) { return $multi(...args); } `; @@ -71,9 +72,9 @@ const createCasesThatCall = (name: string): Array<[string, any]> => [ [`const [a = 1] = ${name}(2)`, 2], [`const ar = [1]; const [a] = ${name}(...ar)`, 1], [`const _ = null, [a] = ${name}(1)`, 1], - [`let a; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], - [`let a; for ([a] = ${name}(1, 2); false; 1) {}`, 1], - [`let a; if ([a] = ${name}(1)) { ++a; }`, 2], + [`let a: any; for (const [a] = ${name}(1, 2); false; 1) {}`, undefined], + [`let a: any; for ([a] = ${name}(1, 2); false; 1) {}`, 1], + [`let a: any; if ([a] = ${name}(1)) { ++a; }`, 2], ]; test.each<[string, any]>(createCasesThatCall("$multi"))("invalid direct $multi function use (%s)", statement => { @@ -272,7 +273,7 @@ test("return $multi from try", () => { } catch { } } - const [_, a] = multiTest(); + const [_, a] = multiTest()!; return a; ` .withLanguageExtensions() @@ -304,7 +305,7 @@ test("return LuaMultiReturn from try", () => { } catch { } } - const [_, a] = multiTest(); + const [_, a] = multiTest()!; return a; ` .withLanguageExtensions() diff --git a/test/unit/loops.spec.ts b/test/unit/loops.spec.ts index b88e0dbeb..e6ceab5db 100644 --- a/test/unit/loops.spec.ts +++ b/test/unit/loops.spec.ts @@ -208,7 +208,7 @@ test.each([ }, ])("forin[Object] (%p)", ({ inp }) => { util.testFunctionTemplate` - let objTest = ${inp}; + let objTest: Record = ${inp}; for (let key in objTest) { objTest[key] = objTest[key] + 1; } @@ -218,7 +218,7 @@ test.each([ test("forin[Array]", () => { util.testFunction` - const array = []; + const array = [1,2,3]; for (const key in array) {} `.expectDiagnosticsToMatchSnapshot([forbiddenForIn.code]); }); @@ -238,7 +238,7 @@ test.each( ) )("forin with continue (%s %p)", (luaTarget, { inp }) => { util.testFunctionTemplate` - let obj = ${inp}; + let obj: Record = ${inp}; for (let i in obj) { if (obj[i] % 2 == 0) { continue; diff --git a/test/unit/modules/modules.spec.ts b/test/unit/modules/modules.spec.ts index d15f18463..1969806d0 100644 --- a/test/unit/modules/modules.spec.ts +++ b/test/unit/modules/modules.spec.ts @@ -94,8 +94,7 @@ test("Default Import and Export Expression", () => { test("Import and Export Assignment", () => { util.testModule` - // @ts-ignore - import * as m from "./module"; + import m = require("./module"); export const value = m; ` .setOptions({ module: ts.ModuleKind.CommonJS }) diff --git a/test/unit/namespaces.spec.ts b/test/unit/namespaces.spec.ts index 01b2e3f92..7c98e7ef9 100644 --- a/test/unit/namespaces.spec.ts +++ b/test/unit/namespaces.spec.ts @@ -1,15 +1,5 @@ import * as util from "../util"; -test("legacy internal module syntax", () => { - util.testModule` - module Foo { - export const foo = "bar"; - } - - export const foo = Foo.foo; - `.expectToMatchJsResult(); -}); - test("global scoping", () => { util.testFunction("return a.foo();") .setTsHeader('namespace a { export function foo() { return "bar"; } }') @@ -42,7 +32,7 @@ test("context in namespace function", () => { util.testModule` namespace a { export const foo = "foo"; - export function bar() { return this.foo + "bar"; } + export function bar(this: typeof a) { return this.foo + "bar"; } } export const result = a.bar(); diff --git a/test/unit/optionalChaining.spec.ts b/test/unit/optionalChaining.spec.ts index d99f18be9..10de7e792 100644 --- a/test/unit/optionalChaining.spec.ts +++ b/test/unit/optionalChaining.spec.ts @@ -1,10 +1,9 @@ import { notAllowedOptionalAssignment } from "../../src/transformation/utils/diagnostics"; import * as util from "../util"; -import { ScriptTarget } from "typescript"; test.each(["null", "undefined", '{ foo: "foo" }'])("optional chaining (%p)", value => { util.testFunction` - const obj: {foo: string} | null | undefined = ${value}; + const obj = ${value} as {foo: string} | null | undefined; return obj?.foo; ` .expectToMatchJsResult() @@ -24,7 +23,7 @@ test("long optional chain", () => { test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])("nested optional chaining (%p)", value => { util.testFunction` - const obj: { foo?: { bar?: string } } | undefined = ${value}; + const obj = ${value} as { foo?: { bar?: string } } | undefined; return obj?.foo?.bar; `.expectToMatchJsResult(); }); @@ -33,7 +32,7 @@ test.each(["undefined", "{}", "{ foo: {} }", "{ foo: {bar: 'baz'}}"])( "nested optional chaining combined with coalescing (%p)", value => { util.testFunction` - const obj: { foo?: { bar?: string } } | undefined = ${value}; + const obj = ${value} as { foo?: { bar?: string } } | undefined; return obj?.foo?.bar ?? "not found"; `.expectToMatchJsResult(); } @@ -108,7 +107,7 @@ test("unused call", () => { // should use if statement, as result is not used }); -test.each(["undefined", "{ foo: v=>v }"])("with preceding statements on right side", value => { +test.each(["undefined", "{ foo: (v: any)=>v }"])("with preceding statements on right side", value => { util.testFunction` let i = 0 const obj: any = ${value}; @@ -120,12 +119,12 @@ test.each(["undefined", "{ foo: v=>v }"])("with preceding statements on right si }); // unused, with preceding statements on right side -test.each(["undefined", "{ foo(val) {return val} }"])( +test.each(["undefined", "{ foo(val: any) {return val} }"])( "unused result with preceding statements on right side", value => { util.testFunction` let i = 0 - const obj = ${value}; + const obj = ${value} as any; obj?.foo(i++); return i ` @@ -135,8 +134,10 @@ test.each(["undefined", "{ foo(val) {return val} }"])( } ); -test.each(["undefined", "{ foo(v) { return v} }"])("with preceding statements on right side modifying left", value => { - util.testFunction` +test.each(["undefined", "{ foo(v: any) { return v} }"])( + "with preceding statements on right side modifying left", + value => { + util.testFunction` let i = 0 let obj: any = ${value}; function bar() { @@ -147,10 +148,11 @@ test.each(["undefined", "{ foo(v) { return v} }"])("with preceding statements on return {result: obj?.foo(bar(), i++), obj, i} ` - .expectToMatchJsResult() - .expectLuaToMatchSnapshot(); - // should use if statement, as there are preceding statements -}); + .expectToMatchJsResult() + .expectLuaToMatchSnapshot(); + // should use if statement, as there are preceding statements + } +); test("does not suppress error if left side is false", () => { const result = util.testFunction` @@ -233,7 +235,7 @@ test("does not crash when incorrectly used in assignment (#1044)", () => { describe("optional chaining function calls", () => { test.each(["() => 4", "undefined"])("stand-alone optional function (%p)", value => { util.testFunction` - const f: (() => number) | undefined = ${value}; + const f = (${value}) as (() => number) | undefined; return f?.(); `.expectToMatchJsResult(); }); @@ -255,7 +257,7 @@ describe("optional chaining function calls", () => { test("object with method can be undefined", () => { util.testFunction` - const objWithMethods: { foo: () => number, bar: (this: void) => number } | undefined = undefined; + const objWithMethods = undefined as { foo: () => number, bar: (this: void) => number } | undefined; return [objWithMethods?.foo() ?? "no foo", objWithMethods?.bar() ?? "no bar"]; `.expectToMatchJsResult(); }); @@ -326,8 +328,8 @@ describe("optional chaining function calls", () => { test.each([undefined, "[1, 2, 3, 4]"])("Array: %p", expr => { util.testFunction` - const value: any[] | undefined = ${expr} - return value?.map(x=>x+1) + const value = ${expr} as any[] | undefined; + return value?.map(x=>x+1); `.expectToMatchJsResult(); }); }); @@ -342,7 +344,6 @@ describe("optional chaining function calls", () => { ` .setOptions({ strict, - target: ScriptTarget.ES5, }) .expectToMatchJsResult(); }); @@ -397,7 +398,7 @@ describe("Unsupported optional chains", () => { describe("optional delete", () => { test("successful", () => { util.testFunction` - const table = { + const table: { bar?: number } = { bar: 3 } return [delete table?.bar, table] @@ -415,9 +416,9 @@ describe("optional delete", () => { test("delete on undefined", () => { util.testFunction` - const table : { - bar: number - } | undefined = undefined + const table = undefined as { + bar?: number + } | undefined; return [delete table?.bar, table ?? "nil"] `.expectToMatchJsResult(); }); diff --git a/test/unit/overloads.spec.ts b/test/unit/overloads.spec.ts index d18daa000..85752a64a 100644 --- a/test/unit/overloads.spec.ts +++ b/test/unit/overloads.spec.ts @@ -67,8 +67,8 @@ test("overload method2", () => { test("constructor1", () => { util.testFunction` class myclass { - num: number; - str: string; + num?: number; + str?: string; constructor(def: number); constructor(def: string); @@ -88,8 +88,8 @@ test("constructor1", () => { test("constructor2", () => { util.testFunction` class myclass { - num: number; - str: string; + num?: number; + str?: string; constructor(def: number); constructor(def: string); diff --git a/test/unit/precedingStatements.spec.ts b/test/unit/precedingStatements.spec.ts index 1ce24da19..6dd8c6473 100644 --- a/test/unit/precedingStatements.spec.ts +++ b/test/unit/precedingStatements.spec.ts @@ -101,13 +101,16 @@ describe("execution order", () => { util.testFunction` const o = {a: "A", b: "B", c: "C"}; let i = 0; - const literal = ${literal}; + const literal: Record = ${literal}; const result: Record = {}; (Object.keys(result) as Array).forEach( key => { result[key.toString()] = literal[key]; } ); return result; - `.expectToMatchJsResult(); + ` + // TS2783: duplicate property in spread — intentional, testing execution order + .ignoreDiagnostics([2783]) + .expectToMatchJsResult(); }); test("object literal with computed property names", () => { @@ -516,8 +519,8 @@ describe("assignment execution order", () => { test("function method call", () => { util.testFunction` let o = {val: 3}; - let a = function(x: number) { return this.val + x; }; - let b = function(x: number) { return (this.val + x) * 10; }; + let a = function(this: typeof o, x: number) { return this.val + x; }; + let b = function(this: typeof o, x: number) { return (this.val + x) * 10; }; function foo(x: number) { return (x > 0) ? b : a; } let i = 0; const result = foo(i).call(o, i++); diff --git a/test/unit/spread.spec.ts b/test/unit/spread.spec.ts index 79262c185..93936f29b 100644 --- a/test/unit/spread.spec.ts +++ b/test/unit/spread.spec.ts @@ -116,7 +116,9 @@ describe("in object literal", () => { "{ ...{ x: false }, x: true }", "{ ...{ x: false }, x: false, ...{ x: true } }", ])("of object literal (%p)", expression => { - util.testExpression(expression).expectToMatchJsResult(); + util.testExpression(expression) + .ignoreDiagnostics([2783]) // duplicate property in spread — intentional, testing spread override behavior + .expectToMatchJsResult(); }); test.each([ diff --git a/test/unit/switch.spec.ts b/test/unit/switch.spec.ts index 4fb72c40c..1b8410a68 100644 --- a/test/unit/switch.spec.ts +++ b/test/unit/switch.spec.ts @@ -137,7 +137,7 @@ test("switch using variable re-declared in cases", () => { let foo: number = 0; switch (foo) { case 0: - let foo = true; + let foo: boolean | undefined = true; case 1: return foo; } diff --git a/test/unit/using.spec.ts b/test/unit/using.spec.ts index 60364f680..33749cb37 100644 --- a/test/unit/using.spec.ts +++ b/test/unit/using.spec.ts @@ -116,7 +116,7 @@ test("using disposes even when error happens", () => { test("await using disposes object with await at end of function", () => { util.testModule` - let disposeAsync; + let disposeAsync: (() => void) | undefined; function loggedAsyncDisposable(id: string): AsyncDisposable { logs.push(\`Creating \${id}\`); @@ -145,7 +145,7 @@ test("await using disposes object with await at end of function", () => { logs.push("function returned"); - disposeAsync(); + disposeAsync!(); ` .setTsHeader(usingTestLib) .setOptions({ luaLibImport: LuaLibImportKind.Inline }) @@ -217,7 +217,7 @@ test("await-using with nested async arrow that also has await-using (runtime div // https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1584 test("works with disposable classes (#1584)", () => { util.testFunction` - const log = []; + const log: string[] = []; class Scoped { action(): void { diff --git a/test/util.ts b/test/util.ts index 8c5e69f8f..1e191fb28 100644 --- a/test/util.ts +++ b/test/util.ts @@ -51,7 +51,7 @@ function getLuaBindingsForVersion(target: tstl.LuaTarget): { lauxlib: LauxLib; l } export function assert(value: any, message?: string | Error): asserts value { - nativeAssert(value, message); + nativeAssert.ok(value, message); } export const formatCode = (...values: unknown[]) => values.map(e => stringify(e)).join(", "); @@ -92,17 +92,15 @@ export function expectEachVersionExceptJit( }; } -const memoize: MethodDecorator = (_target, _propertyKey, descriptor) => { - const originalFunction = descriptor.value as any; +const memoize = (originalFunction: any) => { const memoized = new WeakMap(); - descriptor.value = function (this: any, ...args: any[]): any { + return function (this: any, ...args: any[]): any { if (!memoized.has(this)) { memoized.set(this, originalFunction.apply(this, args)); } return memoized.get(this); - } as any; - return descriptor; + }; }; export class ExecutionError extends Error { @@ -163,7 +161,7 @@ export abstract class TestBuilder { skipLibCheck: true, target: ts.ScriptTarget.ES2017, lib: ["lib.esnext.d.ts"], - moduleResolution: ts.ModuleResolutionKind.Node10, + moduleResolution: ts.ModuleResolutionKind.Bundler, resolveJsonModule: true, sourceMap: true, }; diff --git a/tsconfig.json b/tsconfig.json index bf121bd20..1fcbb6d79 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,6 @@ "lib": ["es2019"], "types": ["node"], "module": "commonjs", - "experimentalDecorators": true, "rootDir": "src", "outDir": "dist", From 7f835eda4efeb988b9e7647204a3df855b53ec07 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 21 Apr 2026 22:25:31 +0200 Subject: [PATCH 752/764] CHANGELOG.md 1.35.0 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c8014962..abe5cf9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # Changelog +## 1.35.0 + +- **[Breaking]** Upgraded to TypeScript 6.0 + Thanks @RealColdFry for the following fixes: +- Fixed many bugs with try/catch/finally + - Also fixed some bugs with try/catch/finally in promises +- Fixed a bug where collection iterators would not correctly update when the collection updated +- No longer generate dead code after `break` statements +- Fixed a bug where math.atan2 was incorrectly used instead of math.atan for Lua 5.4 +- Fixed some inconsistencies with number constants (Number.MAX_SAFE_INTEGER, Number.MIN_VALUE, etc) +- Fixed a bug with the `>>>` operator for Lua 5.3 +- Fixed incorrect side effects for array destructors +- Fixed broken code when generating requires for files with `.` in the file name (e.g. `foo.tests.ts`), now the periods will be translated to `_` +- Fixed some incorrect handling of synthetic nodes +- Fixed a bug where object spread could lead to incorrect code being generated +- Fixed a bug with Object.defineProperty sharing values accross object instances + ## 1.34.0 - Added support for the Lua 5.5 target (it mostly does the same as the 5.4 target for now) From 06e4263d6119b5540708d9fd216988b6a2ea9452 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 21 Apr 2026 22:28:29 +0200 Subject: [PATCH 753/764] 1.35.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 760133928..bdad6125f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.34.0", + "version": "1.35.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.34.0", + "version": "1.35.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 412c08da7..331d32b72 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.34.0", + "version": "1.35.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From d3c33ac54d21d6803864ec1a39ae337a62c131a2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 21 Apr 2026 22:29:28 +0200 Subject: [PATCH 754/764] 1.36.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index bdad6125f..28a32847e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.35.0", + "version": "1.36.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.35.0", + "version": "1.36.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 331d32b72..aff9ba384 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.35.0", + "version": "1.36.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From ef946a353ea46192a1ba4b34c797407c1ec204a1 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Tue, 21 Apr 2026 22:31:54 +0200 Subject: [PATCH 755/764] CHANGELOG.md 1.36.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abe5cf9c8..f82157801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.35.0 +## 1.36.0 - **[Breaking]** Upgraded to TypeScript 6.0 Thanks @RealColdFry for the following fixes: From 979bebef272d61f28bdf0641300641a4125a459f Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sun, 3 May 2026 11:44:37 +0100 Subject: [PATCH 756/764] Fix/paths vs project file (#1715) * add failing test: paths mapping loses to sibling project file * add temporary TS <6.0 support * resolve paths mappings before sibling project files to match ts order * don't need ignoreDeprecations * remove redundant end-of-todo-block comment * drop baseUrl from paths-vs-project-file test fixture --- src/transpilation/resolve.ts | 15 ++++++++------- test/transpile/module-resolution.spec.ts | 12 ++++++++++++ .../paths-vs-project-file/other/alias.ts | 1 + .../paths-vs-project-file/program/alias.ts | 1 + .../paths-vs-project-file/program/main.ts | 3 +++ .../paths-vs-project-file/program/tsconfig.json | 9 +++++++++ 6 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 test/transpile/module-resolution/paths-vs-project-file/other/alias.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/alias.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/main.ts create mode 100644 test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json diff --git a/src/transpilation/resolve.ts b/src/transpilation/resolve.ts index e011f4350..af7981ffc 100644 --- a/src/transpilation/resolve.ts +++ b/src/transpilation/resolve.ts @@ -208,13 +208,9 @@ class ResolutionContext { if (resolvedNodeModulesFile) return resolvedNodeModulesFile; } - // Check if file is a file in the project - const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); - const fileFromPath = this.getFileFromPath(resolvedPath); - if (fileFromPath) return fileFromPath; - - if (this.options.paths) { - // If no file found yet and paths are present, try to find project file via paths mappings + // Bare specifiers: check paths mappings first, matching TypeScript's resolution order. + // TS never applies paths to relative imports, so skip for those. + if (!ts.isExternalModuleNameRelative(dependencyPath) && this.options.paths) { // When baseUrl is not set, resolve paths relative to the tsconfig directory (TS 6.0+ behavior) const pathsBase = this.options.baseUrl ?? @@ -225,6 +221,11 @@ class ResolutionContext { } } + // Check if file is a file in the project + const resolvedPath = this.formatPathToFile(dependencyPath, requiringFile); + const fileFromPath = this.getFileFromPath(resolvedPath); + if (fileFromPath) return fileFromPath; + // Not a TS file in our project sources, use resolver to check if we can find dependency try { const resolveResult = resolver.resolveSync({}, fileDirectory, dependencyPath); diff --git a/test/transpile/module-resolution.spec.ts b/test/transpile/module-resolution.spec.ts index e6543df69..35e79ed3d 100644 --- a/test/transpile/module-resolution.spec.ts +++ b/test/transpile/module-resolution.spec.ts @@ -707,6 +707,18 @@ test("supports complicated paths configuration", () => { .expectToEqual({ foo: 314, bar: 271 }); }); +test("paths mapping wins over sibling project file (TS resolution order)", () => { + const baseProjectPath = path.resolve(__dirname, "module-resolution", "paths-vs-project-file"); + const projectPath = path.join(baseProjectPath, "program"); + const projectTsConfig = path.join(projectPath, "tsconfig.json"); + const mainFile = path.join(projectPath, "main.ts"); + + util.testProject(projectTsConfig) + .setMainFileName(mainFile) + .setOptions({ luaBundle: "bundle.lua", luaBundleEntry: mainFile }) + .expectToEqual({ value: "paths-mapped" }); +}); + test("module resolution using plugin", () => { const baseProjectPath = path.resolve(__dirname, "module-resolution", "project-with-module-resolution-plugin"); const projectTsConfig = path.join(baseProjectPath, "tsconfig.json"); diff --git a/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts b/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts new file mode 100644 index 000000000..b09331910 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/other/alias.ts @@ -0,0 +1 @@ +export const value = "paths-mapped"; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts b/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts new file mode 100644 index 000000000..565154b68 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/alias.ts @@ -0,0 +1 @@ +export const value = "project-file"; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/main.ts b/test/transpile/module-resolution/paths-vs-project-file/program/main.ts new file mode 100644 index 000000000..7b4bc6587 --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/main.ts @@ -0,0 +1,3 @@ +import { value } from "alias"; + +export { value }; diff --git a/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json new file mode 100644 index 000000000..26c1a151f --- /dev/null +++ b/test/transpile/module-resolution/paths-vs-project-file/program/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "rootDir": "..", + "outDir": "dist", + "paths": { + "alias": ["../other/alias"] + } + } +} From 9158ace961331606a22e399d582328961a20842c Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sun, 3 May 2026 11:47:05 +0100 Subject: [PATCH 757/764] fix >> (signed right shift) on Lua 5.3+ (#1720) (#1721) * fix >> (signed right shift) producing wrong results on Lua 5.3+ * remove dead >> cases and add >>= execution tests * mask shift amount to 5 bits for >> on lua 5.3+ * Revert "fix >> (signed right shift) producing wrong results on Lua 5.3+" This reverts commit 2592ff279ac645a493cf0a3b45c8ad41e496769e. * reword unsupported >> diagnostic --- src/transformation/utils/diagnostics.ts | 2 +- test/unit/__snapshots__/expressions.spec.ts.snap | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 5fb1bf15e..1fb9547e6 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -82,7 +82,7 @@ export const unsupportedAccessorInObjectLiteral = createErrorDiagnosticFactory( ); export const unsupportedRightShiftOperator = createErrorDiagnosticFactory( - "Right shift operator is not supported for target Lua 5.3. Use `>>>` instead." + "Signed right shift `>>` is not supported on Lua 5.3+: Lua's native `>>` is logical (zero-fill) on 64-bit integers, with no built-in arithmetic shift. Use `>>>` if you don't need sign extension, or write your own helper." ); const getLuaTargetName = (version: LuaTarget) => (version === LuaTarget.LuaJIT ? "LuaJIT" : `Lua ${version}`); diff --git a/test/unit/__snapshots__/expressions.spec.ts.snap b/test/unit/__snapshots__/expressions.spec.ts.snap index 720f7014e..7eeb5961a 100644 --- a/test/unit/__snapshots__/expressions.spec.ts.snap +++ b/test/unit/__snapshots__/expressions.spec.ts.snap @@ -756,7 +756,7 @@ ____exports.__result = a return ____exports" `; -exports[`Unsupported bitop 5.3 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; +exports[`Unsupported bitop 5.3 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Signed right shift \`>>\` is not supported on Lua 5.3+: Lua's native \`>>\` is logical (zero-fill) on 64-bit integers, with no built-in arithmetic shift. Use \`>>>\` if you don't need sign extension, or write your own helper."`; exports[`Unsupported bitop 5.3 ("a>>b"): code 1`] = ` "local ____exports = {} @@ -764,7 +764,7 @@ ____exports.__result = a >> b return ____exports" `; -exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; +exports[`Unsupported bitop 5.3 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Signed right shift \`>>\` is not supported on Lua 5.3+: Lua's native \`>>\` is logical (zero-fill) on 64-bit integers, with no built-in arithmetic shift. Use \`>>>\` if you don't need sign extension, or write your own helper."`; exports[`Unsupported bitop 5.4 ("a>>=b"): code 1`] = ` "local ____exports = {} @@ -773,7 +773,7 @@ ____exports.__result = a return ____exports" `; -exports[`Unsupported bitop 5.4 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; +exports[`Unsupported bitop 5.4 ("a>>=b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Signed right shift \`>>\` is not supported on Lua 5.3+: Lua's native \`>>\` is logical (zero-fill) on 64-bit integers, with no built-in arithmetic shift. Use \`>>>\` if you don't need sign extension, or write your own helper."`; exports[`Unsupported bitop 5.4 ("a>>b"): code 1`] = ` "local ____exports = {} @@ -781,4 +781,4 @@ ____exports.__result = a >> b return ____exports" `; -exports[`Unsupported bitop 5.4 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Right shift operator is not supported for target Lua 5.3. Use \`>>>\` instead."`; +exports[`Unsupported bitop 5.4 ("a>>b"): diagnostics 1`] = `"main.ts(1,25): error TSTL: Signed right shift \`>>\` is not supported on Lua 5.3+: Lua's native \`>>\` is logical (zero-fill) on 64-bit integers, with no built-in arithmetic shift. Use \`>>>\` if you don't need sign extension, or write your own helper."`; From 4855d04758d40b730fad6e32e840d872d24d3e91 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Sun, 3 May 2026 11:50:44 +0100 Subject: [PATCH 758/764] diagnose unsupported async generators and for-await-of (#1717) * diagnose unsupported async generators and for-await-of * prettier --- src/transformation/utils/diagnostics.ts | 4 +++ src/transformation/visitors/function.ts | 5 ++++ src/transformation/visitors/loops/for-of.ts | 5 ++++ test/unit/builtins/async-await.spec.ts | 33 +++++++++++++++++++-- 4 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/transformation/utils/diagnostics.ts b/src/transformation/utils/diagnostics.ts index 1fb9547e6..e8d77c169 100644 --- a/src/transformation/utils/diagnostics.ts +++ b/src/transformation/utils/diagnostics.ts @@ -145,6 +145,10 @@ export const awaitMustBeInAsyncFunction = createErrorDiagnosticFactory( "Await can only be used inside async functions." ); +export const unsupportedAsyncGenerator = createErrorDiagnosticFactory("Async generator functions are not supported."); + +export const unsupportedForAwaitOf = createErrorDiagnosticFactory("'for await...of' loops are not supported."); + export const unsupportedBuiltinOptionalCall = createErrorDiagnosticFactory( "Optional calls are not supported for builtin or language extension functions." ); diff --git a/src/transformation/visitors/function.ts b/src/transformation/visitors/function.ts index 12b152353..115a1cd08 100644 --- a/src/transformation/visitors/function.ts +++ b/src/transformation/visitors/function.ts @@ -16,6 +16,7 @@ import { LuaLibFeature, transformLuaLibFunction } from "../utils/lualib"; import { transformInPrecedingStatementScope } from "../utils/preceding-statements"; import { peekScope, performHoisting, Scope, ScopeType } from "../utils/scope"; import { isFunctionType } from "../utils/typescript"; +import { unsupportedAsyncGenerator } from "../utils/diagnostics"; import { isAsyncFunction, wrapInAsyncAwaiter } from "./async-await"; import { transformIdentifier } from "./identifier"; import { transformExpressionBodyToReturnStatement } from "./return"; @@ -224,6 +225,10 @@ export function transformFunctionToExpression( ): [lua.Expression, Scope] { assert(node.body); + if (node.asteriskToken && isAsyncFunction(node)) { + context.diagnostics.push(unsupportedAsyncGenerator(node)); + } + const type = context.checker.getTypeAtLocation(node); let functionContext: lua.Identifier | undefined; diff --git a/src/transformation/visitors/loops/for-of.ts b/src/transformation/visitors/loops/for-of.ts index c2da717c5..5071623db 100644 --- a/src/transformation/visitors/loops/for-of.ts +++ b/src/transformation/visitors/loops/for-of.ts @@ -11,6 +11,7 @@ import { import { isRangeFunction, transformRangeStatement } from "../language-extensions/range"; import { transformForInitializer, transformLoopBody } from "./utils"; import { getIterableExtensionKindForNode, IterableExtensionKind } from "../../utils/language-extensions"; +import { unsupportedForAwaitOf } from "../../utils/diagnostics"; import { assertNever } from "../../../utils"; function transformForOfArrayStatement( @@ -43,6 +44,10 @@ function transformForOfIteratorStatement( } export const transformForOfStatement: FunctionVisitor = (node, context) => { + if (node.awaitModifier) { + context.diagnostics.push(unsupportedForAwaitOf(node.awaitModifier)); + } + const body = lua.createBlock(transformLoopBody(context, node)); if (ts.isCallExpression(node.expression) && isRangeFunction(context, node.expression)) { diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index ad64f031d..2929832eb 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -1,7 +1,11 @@ import { ModuleKind, ScriptTarget } from "typescript"; import { LuaTarget } from "../../../src"; -import { unsupportedForTargetButOverrideAvailable } from "../../../src/transformation/utils/diagnostics"; -import { awaitMustBeInAsyncFunction } from "../../../src/transformation/utils/diagnostics"; +import { + awaitMustBeInAsyncFunction, + unsupportedAsyncGenerator, + unsupportedForAwaitOf, + unsupportedForTargetButOverrideAvailable, +} from "../../../src/transformation/utils/diagnostics"; import * as util from "../../util"; const promiseTestLib = ` @@ -1123,3 +1127,28 @@ describe("try/catch in async function", () => { .expectToEqual(["finally", "ok"]); }); }); + +describe("async generators are unsupported", () => { + test.each([ + "async function* gen() { yield 1; }", + "const gen = async function*() { yield 1; };", + "const gen = { async *m() { yield 1; } };", + "class C { async *m() { yield 1; } }", + ])("diagnoses %p", source => { + util.testModule` + ${source} + export {} + `.expectToHaveDiagnostics([unsupportedAsyncGenerator.code]); + }); +}); + +test("for-await-of is unsupported", () => { + util.testModule` + async function run(items: AsyncIterable) { + for await (const x of items) { + void x; + } + } + export {} + `.expectToHaveDiagnostics([unsupportedForAwaitOf.code]); +}); From c40b6fa0af95bb36140b2a5f124cccbacdcbabf4 Mon Sep 17 00:00:00 2001 From: Cold Fry Date: Fri, 29 May 2026 20:56:57 +0100 Subject: [PATCH 759/764] respect @noSelf on interface containing call signature (#1724) * respect @noself on interface containing call signature * replace @noSelf call-signature snapshot tests with runtime argc probes --- src/transformation/utils/function-context.ts | 13 ++++++ test/unit/functions/noSelfAnnotation.spec.ts | 44 ++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/src/transformation/utils/function-context.ts b/src/transformation/utils/function-context.ts index e28950e2e..4fce80f49 100644 --- a/src/transformation/utils/function-context.ts +++ b/src/transformation/utils/function-context.ts @@ -143,6 +143,19 @@ function computeDeclarationContextType(context: TransformationContext, signature return ContextType.NonVoid; } + // Call signature inside a class or interface respects @noSelf on the enclosing class/interface + if (ts.isCallSignatureDeclaration(signatureDeclaration)) { + const scopeDeclaration = findFirstNodeAbove( + signatureDeclaration, + (n): n is ts.ClassLikeDeclaration | ts.InterfaceDeclaration => + ts.isClassDeclaration(n) || ts.isClassExpression(n) || ts.isInterfaceDeclaration(n) + ); + + if (scopeDeclaration !== undefined && getNodeAnnotations(scopeDeclaration).has(AnnotationKind.NoSelf)) { + return ContextType.Void; + } + } + // When using --noImplicitSelf and the signature is defined in a file targeted by the program apply the @noSelf rule. const program = context.program; const options = program.getCompilerOptions() as CompilerOptions; diff --git a/test/unit/functions/noSelfAnnotation.spec.ts b/test/unit/functions/noSelfAnnotation.spec.ts index f8418fabd..e9fbb853d 100644 --- a/test/unit/functions/noSelfAnnotation.spec.ts +++ b/test/unit/functions/noSelfAnnotation.spec.ts @@ -65,6 +65,50 @@ test("@noSelf on static class methods with string key access", () => { `.expectLuaToMatchSnapshot(); }); +// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1661 +// A Lua-side function observes the actual argc, so a missing @noSelf would +// surface as a phantom leading nil (argc 2 instead of 1). +const argcProbeHeader = ` + function probe(...) + return select("#", ...) + end +`; + +test("@noSelf on interface call signature: Lua probe sees correct argc", () => { + util.testModule` + /** @noSelf */ + interface Probe { (a: string): number; } + declare const probe: Probe; + export const result = probe("hi"); + ` + .setLuaHeader(argcProbeHeader) + .expectToEqual({ result: 1 }); +}); + +test("@noSelf parent interface, property typed by call-signature interface: Lua probe sees correct argc", () => { + util.testModule` + /** @noSelf */ + interface CallSignature { (a: string): number; } + /** @noSelf */ + interface Holder { fn: CallSignature; } + declare const holder: Holder; + export const result = holder.fn("hi"); + ` + .setLuaHeader(`${argcProbeHeader}\nholder = { fn = probe }`) + .expectToEqual({ result: 1 }); +}); + +test("@noSelf parent interface, property typed by type-literal call signature: Lua probe sees correct argc", () => { + util.testModule` + /** @noSelf */ + interface Holder { fn: { (a: string): number }; } + declare const holder: Holder; + export const result = holder.fn("hi"); + ` + .setLuaHeader(`${argcProbeHeader}\nholder = { fn = probe }`) + .expectToEqual({ result: 1 }); +}); + // additional coverage for https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1292 test("explicit this parameter respected over @noSelf", () => { util.testModule` From bc88c5806d5376b418ed837574608291d9622743 Mon Sep 17 00:00:00 2001 From: pilaoda <793493083@qq.com> Date: Mon, 1 Jun 2026 02:56:15 +0800 Subject: [PATCH 760/764] fix Promise.prototype.finally to correctly propagate onFinally errors (#1725) * (lualib): update Promise.prototype.finally to correctly handle onFinally errors and rejected * (test): add tests for async/await try-catch-finally re-throw cases --- src/lualib/Promise.ts | 21 +++--- test/unit/builtins/async-await.spec.ts | 98 ++++++++++++++++++++++++++ test/unit/builtins/promise.spec.ts | 40 +++++++++++ 3 files changed, 147 insertions(+), 12 deletions(-) diff --git a/src/lualib/Promise.ts b/src/lualib/Promise.ts index 187e5380d..e8121f1b3 100644 --- a/src/lualib/Promise.ts +++ b/src/lualib/Promise.ts @@ -125,20 +125,17 @@ export class __TS__Promise implements Promise { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally // Delegates to .then() so that a new Promise is returned (per ES spec §27.2.5.3) // and the original fulfillment value / rejection reason is preserved. + // reference: https://github.com/tc39/proposal-promise-finally/blob/fd934c0b42d59bf8d9446e737ba14d50a9067216/polyfill.js#L34-L41 public finally(onFinally?: () => void): Promise { + if (typeof onFinally !== "function") { + return this.then(onFinally, onFinally); + } return this.then( - onFinally - ? (value: T): T => { - onFinally(); - return value; - } - : undefined, - onFinally - ? (reason: any): never => { - onFinally(); - throw reason; - } - : undefined + x => new __TS__Promise(resolve => resolve(onFinally())).then(() => x), + e => + new __TS__Promise(resolve => resolve(onFinally())).then(() => { + throw e; + }) ); } diff --git a/test/unit/builtins/async-await.spec.ts b/test/unit/builtins/async-await.spec.ts index 2929832eb..1c5d23018 100644 --- a/test/unit/builtins/async-await.spec.ts +++ b/test/unit/builtins/async-await.spec.ts @@ -1126,6 +1126,104 @@ describe("try/catch in async function", () => { .setTsHeader(promiseTestLib) .expectToEqual(["finally", "ok"]); }); + + test.each([0, 1, 2])("async re-throw (%p)", i => { + util.testModule` + const i: number = ${i}; + async function foo() { + try { + try { + if (i === 0) { throw "z"; } + } catch (e) { + throw "a"; + } finally { + if (i === 1) { throw "b"; } + } + } catch (e) { + throw (e as string).toUpperCase(); + } finally { + throw "C"; + } + } + export let result: string = "x"; + async function run() { + try { + await foo(); + } catch (e) { + result = (e as string)[(e as string).length - 1]; + } + } + run(); + `.expectToEqual({ result: "C" }); + }); + + test("async: catch re-throws, finally still runs", () => { + util.testModule` + const foo = async () => { + throw "original"; + }; + + let finallyCalled = false; + let caughtError: any = false; + + const run = async () => { + try { + await foo(); + } catch (e) { + throw "re-thrown: " + e; + } finally { + finallyCalled = true; + } + }; + + run().catch(e => { caughtError = e; }); + + export const result = { finallyCalled, caughtError }; + `.expectToEqual({ + result: { + finallyCalled: true, + caughtError: "re-thrown: original", + }, + }); + }); + + test("async: finally throw overrides catch throw", () => { + util.testModule` + const run = async () => { + try { + throw "try-error"; + } catch (e) { + throw "catch-error"; + } finally { + throw "finally-error"; + } + }; + + let caughtError: any = false; + run().catch(e => { caughtError = e; }); + + export const result = caughtError; + `.expectToEqual({ result: "finally-error" }); + }); + + test("async: finally return overrides catch throw", () => { + util.testFunction` + async function run() { + try { + throw "try-error"; + } catch (e) { + throw "catch-error"; + } finally { + return "finally-return"; + } + } + + let result: any; + run().then(v => { result = v; }).catch(e => { result = "rejected: " + e; }); + + return result; + `.expectToEqual("finally-return"); + }); }); describe("async generators are unsupported", () => { diff --git a/test/unit/builtins/promise.spec.ts b/test/unit/builtins/promise.spec.ts index f323b030f..63272c8ab 100644 --- a/test/unit/builtins/promise.spec.ts +++ b/test/unit/builtins/promise.spec.ts @@ -1370,4 +1370,44 @@ describe("Promise.finally", () => { return result.value; `.expectToEqual(99); }); + + test("finally throw overrides fulfillment value", () => { + util.testModule` + let result: any; + Promise.resolve("ok") + .finally(() => { throw "finally-error"; }) + .then(v => { result = v; }, e => { result = e; }); + export const output = result; + `.expectToEqual({ output: "finally-error" }); + }); + + test("finally throw overrides rejection reason", () => { + util.testModule` + let result: any; + Promise.reject("original") + .finally(() => { throw "finally-error"; }) + .then(v => { result = v; }, e => { result = e; }); + export const output = result; + `.expectToEqual({ output: "finally-error" }); + }); + + test("finally returning rejected promise overrides fulfillment", () => { + util.testModule` + let result: any; + Promise.resolve("ok") + .finally(() => Promise.reject("finally-rejected") as any) + .then(v => { result = v; }, e => { result = e; }); + export const output = result; + `.expectToEqual({ output: "finally-rejected" }); + }); + + test("finally returning rejected promise overrides rejection", () => { + util.testModule` + let result: any; + Promise.reject("original") + .finally(() => Promise.reject("finally-rejected") as any) + .then(v => { result = v; }, e => { result = e; }); + export const output = result; + `.expectToEqual({ output: "finally-rejected" }); + }); }); From e57d6613e0734f89ec81f3878ca0860885b48c26 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 6 Jun 2026 12:15:51 +0200 Subject: [PATCH 761/764] CHANGELOG.md 1.37.0 --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f82157801..46b2daaed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.37.0 + +- Fixed a bug with where tsconfig paths were not correctly handled +- Improved error message for why >> is not allowed on Lua 5.3 and higher +- Added clearer diganostic for async generators and for-await-of not being supported +- Made @noSelf be respected on interfaces with call signatures +- Fixed promise.finally not being handled according to the javascript spec + ## 1.36.0 - **[Breaking]** Upgraded to TypeScript 6.0 From 60cb2e1029ce279d26a31193a9692879a40549c5 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Sat, 6 Jun 2026 12:16:53 +0200 Subject: [PATCH 762/764] 1.37.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 28a32847e..a1c9b5a76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.36.0", + "version": "1.37.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.36.0", + "version": "1.37.0", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index aff9ba384..504dad78f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.36.0", + "version": "1.37.0", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/", From b248e41ac841a39c1701be2ba29caf424f6d8a8a Mon Sep 17 00:00:00 2001 From: Aleksandr Krivoshchekov Date: Tue, 30 Jun 2026 20:29:09 +0100 Subject: [PATCH 763/764] Fix try/catch/finally flow (#1729) * Fix try/catch/finally flow Closes: #1137 * Fix comment * Run prettier --- src/transformation/visitors/errors.ts | 50 +++++++++++++++++++++------ test/unit/error.spec.ts | 29 ++++++++++------ 2 files changed, 59 insertions(+), 20 deletions(-) diff --git a/src/transformation/visitors/errors.ts b/src/transformation/visitors/errors.ts index 77067dda8..a070caac6 100644 --- a/src/transformation/visitors/errors.ts +++ b/src/transformation/visitors/errors.ts @@ -165,6 +165,7 @@ export const transformTryStatement: FunctionVisitor = (statemen const tryResultIdentifier = lua.createIdentifier("____try"); const returnValueIdentifier = lua.createIdentifier("____returnValue"); + const rethrowIdentifier = lua.createIdentifier("____rethrow"); const result: lua.Statement[] = []; @@ -191,6 +192,9 @@ export const transformTryStatement: FunctionVisitor = (statemen } } result.push(lua.createVariableDeclarationStatement(tryReturnIdentifiers, tryCall)); + if (statement.finallyBlock) { + result.push(lua.createVariableDeclarationStatement(rethrowIdentifier)); + } const catchCall = lua.createCallExpression( catchIdentifier, @@ -203,8 +207,22 @@ export const transformTryStatement: FunctionVisitor = (statemen ) : lua.createExpressionStatement(catchCall); + const catchCallFunction = lua.createFunctionExpression(lua.createBlock([catchCallStatement])); + + const tryCatchCall = lua.createCallExpression(pCall, [catchCallFunction]); + + const tryCatchCallStatement = lua.createAssignmentStatement( + [lua.cloneIdentifier(tryResultIdentifier), lua.cloneIdentifier(rethrowIdentifier)], + tryCatchCall + ); + const notTryCondition = lua.createUnaryExpression(tryResultIdentifier, lua.SyntaxKind.NotOperator); - result.push(lua.createIfStatement(notTryCondition, lua.createBlock([catchCallStatement]))); + result.push( + lua.createIfStatement( + notTryCondition, + lua.createBlock(statement.finallyBlock ? [tryCatchCallStatement] : [catchCallStatement]) + ) + ); } else if (tryScope.functionReturned) { // try with return, but no catch // returnedIdentifier = lua.createIdentifier("____returned"); @@ -230,21 +248,33 @@ export const transformTryStatement: FunctionVisitor = (statemen result.push(...context.transformStatements(statement.finallyBlock)); } - // Re-throw error if try had no catch but had a finally. + // Re-throw error if try had a finally. // On pcall failure the error is the second return value, which lands in // ____hasReturned (when functionReturned) or ____error (otherwise). - if (!statement.catchClause && statement.finallyBlock) { + if (statement.finallyBlock) { const notTryCondition = lua.createUnaryExpression( lua.cloneIdentifier(tryResultIdentifier), lua.SyntaxKind.NotOperator ); - const errorIdentifier = tryScope.functionReturned - ? lua.cloneIdentifier(returnedIdentifier) - : lua.createIdentifier("____error"); - const rethrow = lua.createExpressionStatement( - lua.createCallExpression(lua.createIdentifier("error"), [errorIdentifier, lua.createNumericLiteral(0)]) - ); - result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); + + if (!statement.catchClause) { + const errorIdentifier = tryScope.functionReturned + ? lua.cloneIdentifier(returnedIdentifier) + : lua.createIdentifier("____error"); + const rethrow = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("error"), [errorIdentifier, lua.createNumericLiteral(0)]) + ); + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); + } else if (statement.catchClause.block.statements.length > 0) { + // Re-throw is possible only from non-empty blocks. + const rethrow = lua.createExpressionStatement( + lua.createCallExpression(lua.createIdentifier("error"), [ + rethrowIdentifier, + lua.createNumericLiteral(0), + ]) + ); + result.push(lua.createIfStatement(notTryCondition, lua.createBlock([rethrow]))); + } } if (returnCondition && returnedIdentifier) { diff --git a/test/unit/error.spec.ts b/test/unit/error.spec.ts index 8204cc36a..f7056655f 100644 --- a/test/unit/error.spec.ts +++ b/test/unit/error.spec.ts @@ -7,31 +7,40 @@ test("throwString", () => { `.expectToEqual(new util.ExecutionError("Some Error")); }); -// TODO: Finally does not behave like it should, see #1137 -// eslint-disable-next-line jest/no-disabled-tests -test.skip.each([0, 1, 2])("re-throw (%p)", i => { +test.each([ + { innerTry: false, innerFinally: false, outerFinally: false }, + { innerTry: false, innerFinally: false, outerFinally: true }, + { innerTry: false, innerFinally: true, outerFinally: false }, + { innerTry: false, innerFinally: true, outerFinally: true }, + { innerTry: true, innerFinally: false, outerFinally: false }, + { innerTry: true, innerFinally: false, outerFinally: true }, + { innerTry: true, innerFinally: true, outerFinally: false }, + { innerTry: true, innerFinally: true, outerFinally: true }, +])("re-throw (%j)", o => { util.testFunction` - const i: number = ${i}; + const innerTry: boolean = ${o.innerTry}; + const innerFinally: boolean = ${o.innerFinally}; + const outerFinally: boolean = ${o.outerFinally}; function foo() { try { try { - if (i === 0) { throw "z"; } + if (innerTry) { throw "inner.try"; } } catch (e) { - throw "a"; + throw (e as string) + "->" + "inner.catch"; } finally { - if (i === 1) { throw "b"; } + if (innerFinally) { throw "inner.finally"; } } } catch (e) { - throw (e as string).toUpperCase(); + throw (e as string) + "->" + "outer.catch"; } finally { - throw "C"; + if (outerFinally) { throw "outer.finally"; } } } let result: string = "x"; try { foo(); } catch (e) { - result = (e as string)[(e as string).length - 1]; + result = e as string; } return result; `.expectToMatchJsResult(); From 0c3a141280d6796c1a1906210622bda8ea4180a2 Mon Sep 17 00:00:00 2001 From: Perryvw Date: Thu, 9 Jul 2026 21:34:08 +0200 Subject: [PATCH 764/764] 1.37.1 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index a1c9b5a76..31aafbbcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "typescript-to-lua", - "version": "1.37.0", + "version": "1.37.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "typescript-to-lua", - "version": "1.37.0", + "version": "1.37.1", "license": "MIT", "dependencies": { "@typescript-to-lua/language-extensions": "1.19.0", diff --git a/package.json b/package.json index 504dad78f..df63dfcf9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-to-lua", - "version": "1.37.0", + "version": "1.37.1", "description": "A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!", "repository": "https://github.com/TypeScriptToLua/TypeScriptToLua", "homepage": "https://typescripttolua.github.io/",

TypeScriptToLua

-
Build status - Build status - Coverage + Build status + Build status + Coverage Chat with us!